RunOnceEx example

This post is a two-fer:

  • First, it shows how one might use the RunOnceEx registry keys to install software on boot.
  • Second, it shows how (not) to do subroutines in a batch script.

RunOnceEx

RunOnceEx is similar to the RunOnce key: it allows you to launch a program during boot, and deletes itself when done. However, unlike RunOnce, RunOnceEx shows a nice friendly window while it runs:

RunOnceEx example

The RunOnceEx key contains a number of subkeys; each has its own title and a set of commands to launch.

reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx" /v TITLE /d "Installing Software" /f

reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\0001" /ve /d "Microsoft Office 2003" /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\0001" /v "0001" /d "%SystemRoot%\System32\msiexec.exe /passive /i %SystemDrive%\Sources\Office2k7\O12Conv.msi" /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\0001" /v "0002" /d "%SystemRoot%\System32\msiexec.exe /passive /i %SystemDrive%\Sources\Office2k3\PRO11.msi" /f

reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\0002" /ve /d "Microsoft FrontPage 2003" /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\0002" /v "0002" /d "%SystemRoot%\System32\msiexec.exe /passive /i %SystemDrive%\Sources\FrontPage2k3\FP11.msi" /f

More info can be found here: http://support.microsoft.com/kb/310593

Batch Subroutines

Batch subroutines… let’s not kid ourselves. They are not subroutines. The are GOTOs pretending to be subroutines.

Here is how (not) to do a subroutine in batch:

call :Subroutine "Hello" "World"
call :Subroutine "foo" "bar"
goto :EOF

:Subroutine
@echo off
@setlocal enabledelayedexpansion

echo %~1 %~2

goto :EOF

The important bits:

  • call :Subroutine arg1 arg2 ...: shows how to call the subroutine. The call keyword is important, since it creates a subshell and skips forward to :Subroutine.
  • goto :EOF: this is needed to prevent the subroutine from running after it has been called. Remember: batch scripts do not support real subroutines, and will continue to execute after calling the subroutine! This GOTO causes execution to skip past any subroutine declarations.
  • :Subroutine: this defines the name of the subroutine.
  • echo %~1 %~2: this shows how to use arguments passed to the subroutine.
  • goto :EOF: as before, we need to tell the subroutine to quit. If you want to create any other subroutines, put them below this line. Remember, the subroutine is running in a subshell, so when it quits, the parent shell will continue on the next line.

Advanced example: a batch script which uses subroutine to create RunOnceEx keys:

When you put the two together, you get the following script:

@echo off
set /a KEYNUM=1000
@setlocal enabledelayedexpansion

reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx" /v TITLE /d "Installing Software" /f
call :RunOnceEx "Microsoft Office 2003" "%SystemRoot%\System32\msiexec.exe /passive /i %SystemDrive%\Sources\Office2k7\O12Conv.msi" "%SystemRoot%\System32\msiexec.exe /passive /i %SystemDrive%\Sources\Office2k3\PRO11.msi"
call :RunOnceEx "Microsoft FrontPage 2003" "%SystemRoot%\System32\msiexec.exe /passive /i %SystemDrive%\Sources\FrontPage2k3\FP11.msi"

:: Launch RunOnceEx immediately (uncomment to enable):
REM rundll32.exe iernonce.dll,RunOnceExProcess

goto :EOF

:RunOnceEx
@echo off
set /a KEYNUM=!KEYNUM!+1
@setlocal enabledelayedexpansion

set TITLE=%~1
set /a VALNUM=1000

echo "!KEYNUM!"

set KEY=HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\!KEYNUM!
reg add "!KEY!" /ve /d "!TITLE!" /f

:loop
shift
if "%~1"=="" (
  goto :EOF
)
reg add "!KEY!" /v "!KEYNUM!" /d "%~1" /f
set /a VALNUM=!VALNUM!+1
goto :loop

Update 2013-02-18: added a better description of how RunOnceEx works, a clearer example, and a link to the microsoft support page.

Injecting AHCI drivers into a live Windows XP System

The best way to install AHCI drivers in Windows XP is to press F6 during Windows Setup, and reinstall Windows. That said, it is possible to inject the drivers into a live installation of Windows XP.

The problem is that Intel’s installer only lets you install the AHCI drivers if it can find the AHCI controller. However, if the controller is running in ATA mode, then the AHCI controller is hidden from Windows, and the install fails.

So before running the Intel installer, you need to bootstrap the AHCI driver into Windows XP.

Before following these instructions, make your backups are up-to-date.

  1. Get the correct AHCI drivers from Intel.

  2. Extract the installer using uniextract.

  3. Copy Drivers\x32\iaStor.sys to C:\Windows\System32\drivers.

  4. Open Drivers\x32\TXTSETUP.OEM.

  5. Scroll down to the [Config.iaStor] section. This section is used to create the iaStor service. First, create a new key in the registry. Then use the information in the [Config.iaStor] section to create the relevant values.

    For example, if the [config.iaStor] section looks like this:

    [Config.iaStor]
    value = "", tag, REG_DWORD, 1b
    value = "", ErrorControl, REG_DWORD, 1
    value = "", Group, REG_SZ, "SCSI Miniport"
    value = "", Start, REG_DWORD, 0
    value = "", Type, REG_DWORD, 1
    

    … then you need to create a .reg file with the following contents:

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\iaStor]
    "tag"=dword:0000001b
    "ErrorControl"=dword:00000001
    "Group"="SCSI miniport"
    "Start"=dword:00000000
    "Type"=dword:00000001
    
  6. Add another entry for the driver to the service definition:

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\iaStor]
    "ImagePath"="system32\\drivers\\iaStor.sys"
    

    This tells Windows where to find the driver.

  7. Create and initialise the Enum key:

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\iaStor\Enum]
    "Count"=dword:00000000
    "NextInstance"=dword:00000000
    

    I’m not sure what this key does, but Windows appears to need it.

  8. Now for the tricky part. You need to add all the device instance IDs for the AHCI controllers to the Critical Device Database.

    In the TXTSETUP.OEM file, there are a whole heap of sections which look like this:

    [HardwareIds.scsi.iaAHCI_ESB2]
    id = "PCI\VEN_8086&DEV_2681&CC_0106","iaStor"
    

    For EVERY one of those lines, create a new key in the CriticalDeviceDatabase. The name of the key will be the first string, except converted to lowercase, and the backslash replaced with a hash. Inside each key, create the Service and ClassGUID items:

    [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\pci#ven_8086&dev_282a&cc_0104]
    "Service"="iaStor"
    "ClassGUID"="{4D36E96A-E325-11CE-BFC1-08002BE10318}"
    

    The Service is the second string in the id = ... line. The ClassGUID value is a bit of magic which tells Windows what kind of device it is (in this case, a storage device).

  9. Windows should now have enough information in the hardware database to be able to boot from an AHCI controller. Reboot into the BIOS and set the disk controller to ACHI mode.

  10. Boot into Windows.

If Windows boots, congratulations! You can now run the full Intel installer to complete the device installation. If there ware a problem, double‑check the instructions above. And if Windows bluescreens, then it should work fine after disabling AHCI mode in the BIOS.

Good luck!