Last week I needed to write an application for my Electrical Engineer to run at boot up to test some hardware changes. He needed to run this test every time the system booted, and needed to have the system reboot often. Of course I don’t expect an EE to be able to set up the test so that it automatically starts when the system boots, and I don’t want to do it for him so I decided to have the application set itself up to run again on the next boot.
void StartAutorun()
{
HKEY regKey=NULL;
DWORD Disposition ;
UINT32 status;
TCHAR Launc52Val[] = TEXT("BootTest.exe");
BYTE Depend52Val[] = { 0x14, 0x00, 0x1E, 0x00 };
TCHAR *SystemPathVal;
TCHAR NewSystemPath[] = TEXT("\\NOR Flash\\Test\\" );
DWORD NumBytes = 0;
DWORD Type;
status = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
TEXT("Init"),
0,
0,
REG_OPTION_NON_VOLATILE,
0,
NULL,
®Key,
&Disposition
);
if( status == ERROR_SUCCESS )
{
status = RegQueryValueEx( regKey, TEXT("Launch52"), NULL, &Type, NULL, &NumBytes );
// if this launch value already exists, then do nothing
if( status != ERROR_SUCCESS )
RegFlushKey( regKey );
else
{
// The value doesn't exist, so add it and change the system path
RegSetValueEx( regKey,
TEXT("Launch52"),
0,
REG_SZ,
(const BYTE*)Launc52Val,
(wcslen(Launc52Val)+1)*sizeof( TCHAR)
);
RegSetValueEx( regKey,
TEXT("Depend52"),
0,
REG_BINARY,
(const BYTE*)Depend52Val,
4
);
// Persist the registry, then close the key
RegFlushKey( regKey );
RegCloseKey( regKey );
status = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
TEXT("Loader"),
0,
0,
REG_OPTION_NON_VOLATILE,
0,
NULL,
®Key,
&Disposition
);
if( status == ERROR_SUCCESS )
{
// This is a fake read, all it does is fill in NumBytes with the number of
// bytes in the string value plus the null character.
status = RegQueryValueEx( regKey, TEXT("SystemPath"), NULL, &Type, NULL, &NumBytes );
if( NumBytes > 0 )
{
// Now we know how big the string is allocate and read it
SystemPathVal = (TCHAR *)malloc( NumBytes + (wcslen(NewSystemPath)+1)*sizeof( TCHAR));
if( SystemPathVal != NULL )
{
status = RegQueryValueEx( regKey, TEXT("SystemPath"), NULL, &Type,
(LPBYTE)SystemPathVal, &NumBytes );
// Make the math easier, convert to number of characters
NumBytes /= sizeof( TCHAR );
// Concatinate the new path on, which overwrites the last null, leaving one
wsprintf( &SystemPathVal[ NumBytes - 1 ], NewSystemPath );
NumBytes += wcslen(NewSystemPath);
// Tack on the second null
SystemPathVal[ NumBytes ] = '\0';
NumBytes += 1;
RegSetValueEx( regKey,
TEXT("SystemPath"),
0,
REG_MULTI_SZ,
(const BYTE*)SystemPathVal,
(NumBytes * sizeof( TCHAR))
);
free( SystemPathVal );
}
}
// Persist the registry, then close the key
RegFlushKey( regKey );
RegCloseKey( regKey );
}
}
}
}
This code sets up the system to run the application again on boot by setting up the registry and persisting the changes to the registry. Which of course means that the system that you are using must be able to perist the registry, that is a choice for your OEM to make and implement.