Do you ever need to put a Windows CE system to its factory state? I know that we do. Sometimes it is because the system has been used for testing or burn in. If the system doesn’t have any persistent store, this can easily be handled by resetting the device. But if the system uses the hive based registry on a persistent file system, returning the device to its factory state can be more difficult.
The following are ways that I know have been used to erase the hive registry:
1.       Reformat the persistent store. This can work, but can be time consuming.
2.       Erase the hive files from the persistent store. This can work, but it requires a reboot and if the time between erasing and rebooting is not short, the hive can be written again before the reset.
Microsoft does provide a way to erase the registry hive though. Before loading the persistent hives, filesys calls KernelIoControl with IOCTL_HAL_GET_HIVE_CLEAN_FLAG to ask the kernel if the registry hives should be deleted.   That means two things; it requires a reset and the OEM will need to implement handling of IOCTL_HAL_GET_HIVE_CLEAN_FLAG.
Writing the code to handle IOCTL_HAL_GET_HIVE_CLEAN_FLAG is relatively easy. There is even a sample in Platform Builder Help for the IOCTL_HAL_GET_HIVE_CLEAN_FLAG topic. The hard part is determining when to delete the registry hive. The challenges are that this is early in the boot process, there aren’t many ways to make the decision, you don’t want to accidently erase the registry hives and you need a way to “turn on” deleting the registry hive.
To solve the problems I recommend:
1.       Use some memory location shared by your bootloader and kernel. Depending on your BSP, this could be driver globals, BSP_ARGS or some other location and add a flag value to it.
2.       Be sure to initialize the flag in the bootloader, don’t let it accidentally become set
3.       Read the value in your IOCTL_HAL_GET_HIVE_CLEAN_FLAG handler
Now implement your IOCTL_HAL_GET_HIVE_CLEAN_FLAG handler. The following is for example purposes only (I haven’t compiled it or include any error handling):
DWORD *pdwFlags = (DWORD *)lpInBuf;
BOOL *pClean = (BOOL *)lpOutBuf;
 
*pClean = FALSE;
 
if((*pdwFlags == HIVECLEANFLAG_SYSTEM) || (*pdwFlags == HIVECLEANFLAG_USERS))
{
                if(CheckSharedMemoryHiveDeleteFlag())
                {
                                *pClean = TRUE;
                }
}
return TRUE;
I will leave it to you to implement the function CheckSharedMemoryHiveDeleteFlag(). 
You will also need to develop a way to set the shared memory flag. You could do this in many, many ways depending on your needs. One way would be to add something to the bootloader menu. Another way would be to add a KernelIoControl handler to set the flag and perform a soft reset, but you need to ensure the flag is not modified by the bootloader on a soft reset for this to work.
 
Copyright © 2009 – Bruce Eitman
All Rights Reserved