當Wince使用了HIVE註冊表後,每次使用者的註冊表改動將得到儲存,但是在某些應用場合需要將註冊表還原成為出廠的預設設定,通常要求能夠通過一個跳線來標誌是否清除Hive註冊表。HIVE系統註冊表和HIVE使用者註冊表分別儲存在/HDD/Document and Setting/system.hv 中和 /HDD/Document and Setting/default/user.hv中,每次系統在啟動到載入HIVE系統註冊表之前都會先檢查儲存在/HDD中的檔案的存在和合法性,如果不滿足要求系統將會用binfs中的預設檔案建立新的system.hv和user.hv檔案於/HDD中,根據這個特性我先試圖在WinCE運行起來後刪除這兩個hv檔案,但是由於WinCE已經事先載入了它們,刪除被禁止,只有採用其他的方法。重新研究了基於HIVE註冊表的WinCE的啟動過程發現,系統在完成了第一階段也就是載入完了boot.hv+binfs之後和載入系統HIVE註冊表之前,filesys.exe都會調用OEMIoControl來查詢是否需要清除儲存在block裝置上的hv檔案,其CODE代碼為IOCTL_HAL_GET_HIVE_CLEAN_FLAG,它的輸入參數lpInBuf固定為HIVECLEANFLAG_SYSTEM或HIVECLEANFLAG_USERS,filesys.exe會分別用這兩種參數調用兩次IOCTL_HAL_GET_HIVE_CLEAN_FLAG,第一次用HIVECLEANFLAG_SYSTEM來問OEM是否需要清除system.hv,第二次用HIVECLEANFLAG_USERS做參數來查詢是否要清除user.hv,如果返回的lpOutBuf中的值為TRUE則做清除操作,如果為False則保留block裝置上的註冊表檔案。所以我們要做的就是實現和IOCTL_HAL_GET_HIVE_CLEAN_FLAG相對應的OEMIoControl源碼(假設由OALIoCtlBGetHiveCleanFlag()這個function來實現),加入對是否需要清除註冊表的判定條件並告知filesys.exe即可。提供相關代碼作為參考: //------------------------------------------------------------------------------
//
// Function: OALIoCtlBGetHiveCleanFlag
//
// This function is Get the Clean Hive Clean Flage
//
BOOL OALIoCtlBGetHiveCleanFlag(
UINT32 code, VOID *lpInBuf , UINT32 nInBufSize, VOID *lpOutBuf,
UINT32 nOutBufSize , UINT32 *pOutSize)
{
DWORD *pdwFlags;
BOOL *pfClean;
volatile XLLP_GPIO_T *pGPIORegs = (volatile XLLP_GPIO_T *) OALPAtoVA(BULVERDE_BASE_REG_PA_GPIO, FALSE);
BOOL Flage = 0;
if (!lpInBuf || (nInBufSize != sizeof(DWORD)) || !lpOutBuf || (nOutBufSize != sizeof(BOOL)))
{
NKSetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
pdwFlags = (DWORD *)lpInBuf;
pfClean = (BOOL*)lpOutBuf;
pGPIORegs->GAFR1_L &= ~(0X03<<26); // Config gp45 as GPIO
pGPIORegs->GPDR1 &= ~(0x01<<13); // dir in
if((pGPIORegs->GPLR1) & (0x01<<13))
Flage = 0;
else
Flage = 1;
if (*pdwFlags == HIVECLEANFLAG_SYSTEM)
{
if(Flage) //判斷是否清除system.hv
RETAILMSG(1, (TEXT("OEM: cleaning system hive/r/n")));
else
RETAILMSG(1, (TEXT("OEM: Not cleaning system hive/r/n")));
*pfClean = Flage;
}
else if (*pdwFlags == HIVECLEANFLAG_USERS) {
if(Flage) //判斷是否清除user.hv
RETAILMSG(1, (TEXT("OEM: cleaning user hive/r/n")));
else
RETAILMSG(1, (TEXT("OEM: Not cleaning user hive/r/n")));
*pfClean = Flage;
}
return TRUE;
}在ioctl_tab.h檔案中加入以下代碼{IOCTL_HAL_GET_HIVE_CLEAN_FLAG, 0, OALIoCtlBGetHiveCleanFlag },