You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
788 lines
25 KiB
788 lines
25 KiB
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
regfind.c
|
|
|
|
Abstract:
|
|
|
|
Search registry and reset the specific value data.
|
|
|
|
Author:
|
|
|
|
Geoffrey Guo (geoffguo) 08-Oct-2001 Created
|
|
|
|
Revision History:
|
|
|
|
<alias> <date> <comments>
|
|
|
|
--*/
|
|
#include "StdAfx.h"
|
|
#include "clmt.h"
|
|
|
|
LONG QueryValue(HKEY, LPTSTR, LPTSTR, PREG_STRING_REPLACE, PVALLIST*, LPTSTR, DWORD, BOOL);
|
|
LONG QueryEnumerateKey(HKEY, LPTSTR,LPTSTR,PREG_STRING_REPLACE, LPTSTR, LPTSTR, DWORD, BOOL);
|
|
LONG SetRegValueChange (HKEY, LPTSTR, PVALLIST*, LPTSTR);
|
|
|
|
|
|
//-----------------------------------------------------------------------//
|
|
//
|
|
// RegistryAnalyze()
|
|
//
|
|
// hRootKey : Regsitry handle
|
|
// lpRegStr : Input parameter structure
|
|
// lpRegExclusionList: MultiSZ string tells a list of Keypath RegRepace should skip
|
|
//
|
|
//-----------------------------------------------------------------------//
|
|
HRESULT RegistryAnalyze(
|
|
HKEY hRootKey,
|
|
LPTSTR szUserName,
|
|
LPTSTR szUserSid,
|
|
PREG_STRING_REPLACE lpRegStr,
|
|
LPTSTR lpRegExclusionList,
|
|
DWORD TreatAsType,
|
|
LPTSTR lpRootKeyPath,
|
|
BOOL bStrChk)
|
|
{
|
|
TCHAR szRoot[MAX_PATH];
|
|
LPTSTR lpRoot = TEXT("\0");
|
|
HRESULT hResult = S_FALSE;
|
|
LONG lResult;
|
|
|
|
if (szUserName)
|
|
{
|
|
DPF(REGmsg, L"Enter RegistryAnalyze: szUserName=%s hKey=%d", szUserName, hRootKey);
|
|
}
|
|
else if (hRootKey == HKEY_CLASSES_ROOT)
|
|
{
|
|
DPF(REGmsg, L"Enter RegistryAnalyze: HKEY_CLASSES_ROOT");
|
|
}
|
|
else if (hRootKey == HKEY_LOCAL_MACHINE)
|
|
{
|
|
DPF(REGmsg, L"Enter RegistryAnalyze: HKEY_LOCAL_MACHINE");
|
|
}
|
|
else
|
|
{
|
|
DPF(REGmsg, L"Enter RegistryAnalyze: hKey=%d", hRootKey);
|
|
}
|
|
|
|
if (lpRegExclusionList)
|
|
{
|
|
hResult = ReplaceCurrentControlSet(lpRegExclusionList);
|
|
if (FAILED(hResult))
|
|
{
|
|
return hResult;
|
|
}
|
|
}
|
|
if (lpRegStr->lpSearchString && lpRegStr->lpReplaceString)
|
|
{
|
|
UpdateProgress();
|
|
|
|
lpRegStr->cchMaxStrLen = GetMaxStrLen (lpRegStr);
|
|
|
|
if (lpRootKeyPath)
|
|
{
|
|
lpRoot = lpRootKeyPath;
|
|
}
|
|
else
|
|
{
|
|
if (HKey2Str(hRootKey,szRoot,MAX_PATH))
|
|
{
|
|
lpRoot = szRoot;
|
|
}
|
|
}
|
|
|
|
lResult = QueryEnumerateKey(hRootKey, szUserName, szUserSid, lpRegStr,
|
|
lpRoot,lpRegExclusionList,TreatAsType, bStrChk);
|
|
hResult = HRESULT_FROM_WIN32(lResult);
|
|
}
|
|
DPF(REGmsg, L"Exit RegistryAnalyze:");
|
|
|
|
return hResult;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------//
|
|
//
|
|
// ReadValue()
|
|
//
|
|
// hKey: Registry key
|
|
// szValueName: Value name
|
|
// lpType: Value type
|
|
// lpBuf: Vaule data buffer
|
|
// lpSize: Value data size
|
|
// lpFullKey: Full sub-key path
|
|
//-----------------------------------------------------------------------//
|
|
LONG ReadValue (
|
|
HKEY hKey,
|
|
LPTSTR szValueName,
|
|
LPDWORD lpType,
|
|
LPBYTE *lpBuf,
|
|
LPDWORD lpSize,
|
|
LPTSTR lpFullKey)
|
|
{
|
|
LONG lResult;
|
|
|
|
//
|
|
// First find out how much memory to allocate.
|
|
//
|
|
lResult = My_QueryValueEx(hKey,
|
|
szValueName,
|
|
0,
|
|
lpType,
|
|
NULL,
|
|
lpSize);
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
{
|
|
DPF (REGerr, L"ReadValue1: RegQueryValueEx failed. lResult=%d", lResult);
|
|
return lResult;
|
|
}
|
|
|
|
//There is a bug in W2K HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\VideoUpgradeDisplaySettings".
|
|
//When the value name = Driver1, *lpSize will be 3. To cover Odd number of size, incease one byte for data buffer.
|
|
*lpBuf = (LPBYTE) calloc(*lpSize+sizeof(TCHAR)+1, sizeof(BYTE));
|
|
|
|
if (!(*lpBuf)) {
|
|
DPF (REGerr, L"ReadValue: No enough memory");
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
//
|
|
// Now get the data
|
|
//
|
|
lResult = My_QueryValueEx(hKey,
|
|
szValueName,
|
|
0,
|
|
lpType,
|
|
*lpBuf,
|
|
lpSize);
|
|
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
{
|
|
if (*lpBuf)
|
|
free(*lpBuf);
|
|
DPF (REGerr, L"ReadValue2: RegQueryValueEx fail. lResult=%d", lResult);
|
|
return lResult;
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------//
|
|
//
|
|
// SetRegValueChange()
|
|
//
|
|
// Set registry value based on the value list
|
|
//
|
|
// hKey: Registry key
|
|
// lpValList: Updated value list
|
|
// lpFullKey: Full sub-key path
|
|
//-----------------------------------------------------------------------//
|
|
LONG SetRegValueChange (
|
|
HKEY hKey,
|
|
LPTSTR szUserName,
|
|
PVALLIST *lpValList,
|
|
LPTSTR lpFullKey)
|
|
{
|
|
LONG lResult = ERROR_SUCCESS;
|
|
HRESULT hResult;
|
|
DWORD dwType;
|
|
DWORD dwOldValueSize = 1, dwNewValueSize;
|
|
LPBYTE lpBuf;
|
|
LPTSTR lpOldValueData, lpNewValueData, lpNewValueName;
|
|
PVALLIST lpVal;
|
|
|
|
if (*lpValList)
|
|
{
|
|
lpVal = *lpValList;
|
|
|
|
while (lpVal)
|
|
{
|
|
UpdateProgress();
|
|
|
|
//Read old value data
|
|
lResult = ReadValue(hKey,
|
|
lpVal->lpPre_valuename,
|
|
&dwType,
|
|
&lpBuf,
|
|
&dwOldValueSize,
|
|
lpFullKey);
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
{
|
|
DPF (REGerr, L"SetRegValueChange: ReadValue failed");
|
|
goto NextData;
|
|
}
|
|
|
|
/* //Set new value name or value data
|
|
lResult = RegSetValueEx (hKey,
|
|
lpVal->ve.ve_valuename,
|
|
0,
|
|
lpVal->ve.ve_type,
|
|
(LPBYTE)(lpVal->ve.ve_valueptr),
|
|
lpVal->ve.ve_valuelen);
|
|
*/
|
|
//Set old value name or value data
|
|
lResult = RegSetValueEx (hKey,
|
|
lpVal->lpPre_valuename,
|
|
0,
|
|
dwType,
|
|
lpBuf,
|
|
dwOldValueSize);
|
|
|
|
if (lResult == ERROR_SUCCESS)
|
|
{
|
|
if (lpVal->val_type & REG_CHANGE_VALUENAME)
|
|
{
|
|
//Delete old value if value name changed
|
|
// lResult = RegDeleteValue(hKey, lpVal->lpPre_valuename);
|
|
|
|
// if (lResult == ERROR_SUCCESS)
|
|
DPF (REGinf, L"SetRegValueChange: Rename value %s to %s Key=%s",
|
|
lpVal->lpPre_valuename, lpVal->ve.ve_valuename, lpFullKey);
|
|
// else
|
|
// DPF (REGerr, L"SetRegValueChange: RegDelValue failed. ValueName=%s Key=%s lResult=%d",
|
|
// lpVal->lpPre_valuename, lpFullKey, lResult);
|
|
}
|
|
else
|
|
DPF (REGinf, L"SetRegValueChange: Replace value data. Key=%s\\%s",
|
|
lpFullKey, lpVal->ve.ve_valuename);
|
|
} else
|
|
DPF (REGerr, L"SetRegValueChange: RegSetValueEx Failed. Error=%d", lResult);
|
|
|
|
if (lpVal->val_type & REG_CHANGE_VALUENAME)
|
|
lpNewValueName = lpVal->ve.ve_valuename;
|
|
else
|
|
lpNewValueName = NULL;
|
|
|
|
if (lpVal->val_type & REG_CHANGE_VALUEDATA)
|
|
{
|
|
lpOldValueData = (LPTSTR)lpBuf;
|
|
dwNewValueSize = lpVal->ve.ve_valuelen;
|
|
lpNewValueData = (LPTSTR)lpVal->ve.ve_valueptr;
|
|
} else
|
|
{
|
|
dwOldValueSize = 0;
|
|
lpOldValueData = NULL;
|
|
dwNewValueSize = 0;
|
|
lpNewValueData = NULL;
|
|
}
|
|
|
|
//Add registry value change information to INF file
|
|
hResult = AddRegValueRename(
|
|
lpFullKey,
|
|
lpVal->lpPre_valuename,
|
|
lpNewValueName,
|
|
lpOldValueData,
|
|
lpNewValueData,
|
|
lpVal->ve.ve_type,
|
|
lpVal->val_attrib,
|
|
szUserName);
|
|
|
|
lResult = HRESULT_CODE(hResult);
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
{
|
|
DPF (REGerr, L"SetRegValueChange: AddRegValueRename failed. Key = %s, error = %d", lpFullKey,lResult);
|
|
if(lpBuf)
|
|
{
|
|
free(lpBuf);
|
|
lpBuf = NULL;
|
|
}
|
|
break;
|
|
}
|
|
if(lpBuf)
|
|
{
|
|
free(lpBuf);
|
|
lpBuf = NULL;
|
|
}
|
|
|
|
NextData:
|
|
lpVal = lpVal->pvl_next;
|
|
|
|
}
|
|
RemoveValueList (lpValList);
|
|
}
|
|
|
|
return lResult;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------//
|
|
//
|
|
// QueryValue()
|
|
//
|
|
// hKey: Registry key
|
|
// szUserName: User name
|
|
// szValueName: Value name
|
|
// lpRegStr: Input parameter structure
|
|
// lpValList: Updated value list
|
|
// lpFullKey: Full sub-key path
|
|
//-----------------------------------------------------------------------//
|
|
LONG QueryValue(
|
|
HKEY hKey,
|
|
LPTSTR szUserName,
|
|
LPTSTR szValueName,
|
|
PREG_STRING_REPLACE lpRegStr,
|
|
PVALLIST *lpValList,
|
|
LPTSTR lpFullKey,
|
|
DWORD TreatAsType,
|
|
BOOL bStrChk)
|
|
{
|
|
LONG lResult;
|
|
HRESULT hResult;
|
|
DWORD dwType;
|
|
DWORD cbSize = 1;
|
|
LPBYTE lpBuf = NULL;
|
|
|
|
lResult = ReadValue(hKey,
|
|
szValueName,
|
|
&dwType,
|
|
&lpBuf,
|
|
&cbSize,
|
|
lpFullKey);
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
goto Exit;
|
|
|
|
switch (dwType)
|
|
{
|
|
case REG_MULTI_SZ:
|
|
case REG_EXPAND_SZ:
|
|
case REG_LINK:
|
|
case REG_SZ:
|
|
case REG_DWORD:
|
|
hResult = ReplaceValueSettings (
|
|
szUserName,
|
|
(LPTSTR)lpBuf,
|
|
cbSize,
|
|
szValueName,
|
|
dwType,
|
|
lpRegStr,
|
|
lpValList,
|
|
lpFullKey,
|
|
bStrChk);
|
|
lResult = HRESULT_CODE(hResult);
|
|
break;
|
|
|
|
default:
|
|
if ( TreatAsType )
|
|
{
|
|
dwType = dwType <<16;
|
|
dwType = dwType + TreatAsType;
|
|
hResult = ReplaceValueSettings (
|
|
szUserName,
|
|
(LPTSTR)lpBuf,
|
|
cbSize,
|
|
szValueName,
|
|
dwType,
|
|
lpRegStr,
|
|
lpValList,
|
|
lpFullKey,
|
|
bStrChk);
|
|
lResult = HRESULT_CODE(hResult);
|
|
}
|
|
break;
|
|
}
|
|
|
|
Exit:
|
|
if(lpBuf)
|
|
free(lpBuf);
|
|
|
|
return lResult;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------//
|
|
//
|
|
// QueryEnumerateKey() - Recursive
|
|
//
|
|
// hKey: Registry key
|
|
// szUserName: User name
|
|
// lpRegStr: Input parameter structure
|
|
// lpFullKey: Full sub-key path
|
|
// lpRegExclusionList: MultiSZ string tells a list of Keypath RegRepace should skip
|
|
//-----------------------------------------------------------------------//
|
|
LONG QueryEnumerateKey(
|
|
HKEY hKey,
|
|
LPTSTR szUserName,
|
|
LPTSTR szUserSid,
|
|
PREG_STRING_REPLACE lpRegStr,
|
|
LPTSTR szFullKey,
|
|
LPTSTR lpRegExclusionList,
|
|
DWORD TreatAsType,
|
|
BOOL bStrChk)
|
|
{
|
|
LONG lResult;
|
|
HRESULT hResult;
|
|
UINT i;
|
|
DWORD cchSize, cchLen;
|
|
DWORD dwNum;
|
|
BOOL dwAccessDenied;
|
|
HKEY hSubKey;
|
|
TCHAR* szNameBuf = NULL;
|
|
TCHAR* szKeyPath;
|
|
TCHAR* szNewKeyPath;
|
|
PVALLIST lpValList;
|
|
|
|
// query source key info
|
|
DWORD cchLenOfKeyName, cchLenOfValueName;
|
|
TCHAR szKeyName[2*MAX_PATH];
|
|
|
|
UpdateProgress();
|
|
|
|
if (lpRegExclusionList && IsStrInMultiSz(szFullKey,lpRegExclusionList))
|
|
{
|
|
lResult = S_OK;
|
|
goto Cleanup;
|
|
}
|
|
lResult = RegQueryInfoKey(hKey,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&cchLenOfKeyName,
|
|
NULL,
|
|
NULL,
|
|
&cchLenOfValueName,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
{
|
|
DPF (REGerr, L"QueryEnumerateKey1: RegQueryInfoKey failed. Key=%s lResult=%d", szFullKey, lResult);
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
// create buffer
|
|
cchLenOfValueName++;
|
|
szNameBuf = (TCHAR*) calloc(cchLenOfValueName, sizeof(TCHAR));
|
|
if (!szNameBuf)
|
|
{
|
|
DPF (REGerr, L"QueryEnumerateKey1: No enough memory");
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
//
|
|
// enumerate all of the values
|
|
//
|
|
i = 0;
|
|
lpValList = NULL;
|
|
do
|
|
{
|
|
UpdateProgress();
|
|
|
|
cchSize = cchLenOfValueName;
|
|
lResult = RegEnumValue(hKey,
|
|
i,
|
|
szNameBuf,
|
|
&cchSize,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
|
|
if (lResult == ERROR_MORE_DATA)
|
|
{
|
|
free(szNameBuf);
|
|
|
|
//RegQueryInfoKey has a bug. *lpcMaxValueNameLen return 1 when
|
|
//Key=HKLM\\SYSTEM\\ControlSet002\\Control\\Lsa\\SspiCache.
|
|
cchSize = MAX_PATH;
|
|
szNameBuf = (TCHAR*) calloc(cchSize+1, sizeof(TCHAR));
|
|
if (!szNameBuf)
|
|
{
|
|
DPF (REGerr, L"QueryEnumerateKey2: No enough memory");
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
cchLenOfValueName = cchSize+1;
|
|
lResult = RegEnumValue(hKey,
|
|
i,
|
|
szNameBuf,
|
|
&cchSize,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
}
|
|
|
|
if (lResult == ERROR_SUCCESS)
|
|
{
|
|
lResult = QueryValue(hKey, szUserName, szNameBuf, lpRegStr, &lpValList,
|
|
szFullKey, TreatAsType, bStrChk);
|
|
|
|
// continue to query
|
|
if(lResult == ERROR_ACCESS_DENIED)
|
|
{
|
|
DPF(REGerr, L"QueryEnumerateKey: Access denied ValueName=%s Key=%s", szNameBuf, szFullKey);
|
|
}
|
|
else if (lResult != ERROR_SUCCESS)
|
|
{
|
|
DPF(REGerr, L"QueryEnumerateKey: QueryValue failed. ValueName=%s Key=%s hResult=%d", szNameBuf, szFullKey, lResult);
|
|
}
|
|
lResult = ERROR_SUCCESS;
|
|
}
|
|
else if (lResult == ERROR_NO_MORE_ITEMS)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
DPF(REGerr, L"QueryEnumerateKey: RegEnumValue fails. Index=%d Key=%s Error=%d",
|
|
i, szFullKey, lResult);
|
|
}
|
|
i++;
|
|
} while (1);
|
|
|
|
lResult = SetRegValueChange (hKey, szUserName, &lpValList, szFullKey);
|
|
if (lResult != ERROR_SUCCESS)
|
|
{
|
|
DPF(REGerr, L"QueryEnumerateKey: SetRegValueChange failed ,error = %d",lResult);
|
|
goto Cleanup;
|
|
}
|
|
|
|
if(szNameBuf)
|
|
{
|
|
free(szNameBuf);
|
|
}
|
|
|
|
//
|
|
// Now Enumerate all of the keys
|
|
//
|
|
cchLenOfKeyName++;
|
|
szNameBuf = (TCHAR*) calloc(cchLenOfKeyName, sizeof(TCHAR));
|
|
if (!szNameBuf)
|
|
{
|
|
DPF (REGerr, L"QueryEnumerateKey4: No enough memory");
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
|
|
i = 0;
|
|
do
|
|
{
|
|
UpdateProgress();
|
|
|
|
cchSize = cchLenOfKeyName;
|
|
lResult = RegEnumKeyEx(hKey,
|
|
i,
|
|
szNameBuf,
|
|
&cchSize,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
|
|
if (lResult == ERROR_MORE_DATA)
|
|
{
|
|
free(szNameBuf);
|
|
|
|
//It should not get here except lpcMaxValueLen return wrong.
|
|
cchSize = MAX_PATH;
|
|
szNameBuf = (TCHAR*) calloc(cchSize+1, sizeof(TCHAR));
|
|
if (!szNameBuf)
|
|
{
|
|
DPF (REGerr, L"QueryEnumerateKey3: No enough memory");
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
cchLenOfKeyName = cchSize+1;
|
|
lResult = RegEnumKeyEx(hKey,
|
|
i,
|
|
szNameBuf,
|
|
&cchSize,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
}
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
{
|
|
if (lResult == ERROR_NO_MORE_ITEMS)
|
|
{
|
|
lResult = ERROR_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
DPF (REGerr, L"QueryEnumerateKey: RegEnumKeyEx failed. Key=%s Error=%d", szFullKey, lResult);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
//BUGBUG:XIAOZ following code is doubtful, why we need lpRegExclusionList != NULL
|
|
//to exclude current control set, we should always exlcude it for performace
|
|
//and it should be in lpRegExclusionList, we do not any special processing for this
|
|
|
|
dwAccessDenied = FALSE;
|
|
if (lpRegExclusionList)
|
|
{
|
|
//skip CurrentControlSet since it is a link to existing control set
|
|
if (MyStrCmpI(szFullKey, L"HKLM\\SYSTEM") == 0 &&
|
|
MyStrCmpI(szNameBuf, L"CurrentControlSet") == 0)
|
|
{
|
|
goto NextKey;
|
|
}
|
|
}
|
|
|
|
//skip exclusive registry keys
|
|
if (MyStrCmpI(szFullKey, TEXT("HKLM")) == 0 &&
|
|
(MyStrCmpI(szNameBuf, TEXT("SAM")) == 0 || MyStrCmpI(szNameBuf, TEXT("SECURITY")) == 0) ||
|
|
MyStrCmpI(szFullKey, TEXT("HKLM\\SYSTEM\\ControlSet001\\Enum\\PCI\\VEN_8086&DEV_7110&SUBSYS_00000000&REV_02\\2&ebb567f&0&38\\Device Parameters")) == 0 &&
|
|
MyStrCmpI(szNameBuf, TEXT("BiosConfig")) == 0 )
|
|
goto NextKey;
|
|
|
|
TryAgain:
|
|
|
|
//
|
|
// open up the subkey, and enumerate it
|
|
//
|
|
lResult = RegOpenKeyEx(hKey,
|
|
szNameBuf,
|
|
0,
|
|
KEY_ALL_ACCESS
|
|
// | ACCESS_SYSTEM_SECURITY
|
|
,
|
|
&hSubKey);
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
{
|
|
if(lResult == ERROR_ACCESS_DENIED) // Try Read_Only
|
|
{
|
|
lResult = RegOpenKeyEx(hKey,
|
|
szNameBuf,
|
|
0,
|
|
KEY_READ,
|
|
&hSubKey);
|
|
|
|
if (lResult == ERROR_SUCCESS)
|
|
{
|
|
DPF(REGwar, L"QueryEnumerateKey: RegOpenKeyEx: Key=%s\\%s Read Only", szFullKey, szNameBuf);
|
|
goto DoKey;
|
|
}
|
|
|
|
if (dwAccessDenied)
|
|
{
|
|
DPF(REGerr, L"QueryEnumerateKey: RegOpenKeyEx: Access Denied. Key=%s\\%s", szFullKey, szNameBuf);
|
|
goto NextKey;
|
|
}
|
|
|
|
hResult = RenameRegRoot(szFullKey, szKeyName, 2*MAX_PATH-1, szUserSid, szNameBuf);
|
|
AdjustObjectSecurity(szKeyName, SE_REGISTRY_KEY, TRUE);
|
|
dwAccessDenied = TRUE;
|
|
goto TryAgain;
|
|
}
|
|
|
|
DPF(REGerr, L"QueryEnumerateKey: RegOpenKeyEx failed. Key=%s\\%s Error=%d", szFullKey, szNameBuf, lResult);
|
|
//skip the current key since it cannot be opened.
|
|
goto NextKey;
|
|
}
|
|
DoKey:
|
|
//
|
|
// Build up the needed string and go down enumerating again
|
|
//
|
|
cchLen = lstrlen(szFullKey) + lstrlen(szNameBuf) + 2;
|
|
szKeyPath = (TCHAR*) calloc(cchLen, sizeof(TCHAR));
|
|
if (!szKeyPath)
|
|
{
|
|
lResult = ERROR_NOT_ENOUGH_MEMORY;
|
|
DPF (REGerr, L"QueryEnumerateKey5: No enough memory");
|
|
RegCloseKey(hSubKey);
|
|
goto Cleanup;
|
|
}
|
|
|
|
//We calculte the buffer for szKeyPath, so here StringCchCopy should be
|
|
//always success, assinging return value just make prefast happy
|
|
hResult = StringCchCopy(szKeyPath, cchLen, szFullKey);
|
|
hResult = StringCchCat(szKeyPath, cchLen, L"\\");
|
|
hResult = StringCchCat(szKeyPath, cchLen, szNameBuf);
|
|
|
|
dwNum = StrNumInMultiSZ(szNameBuf, lpRegStr->lpSearchString);
|
|
if (dwNum != 0xFFFFFFFF)
|
|
{
|
|
LPTSTR lpKeyName;
|
|
|
|
lpKeyName = GetStrInMultiSZ(dwNum, lpRegStr->lpReplaceString);
|
|
cchLen = lstrlen(szFullKey) + lstrlen(lpKeyName) + 2;
|
|
szNewKeyPath = (TCHAR*) calloc(cchLen, sizeof(TCHAR));
|
|
if (!szNewKeyPath) {
|
|
lResult = ERROR_NOT_ENOUGH_MEMORY;
|
|
DPF (REGerr, L"QueryEnumerateKey6: No enough memory");
|
|
RegCloseKey(hSubKey);
|
|
free(szKeyPath);
|
|
goto Cleanup;
|
|
}
|
|
|
|
if (szFullKey)
|
|
{
|
|
//We calculte the buffer for szNewKeyPath, so here StringCchCopy should be
|
|
//always success, assinging return value just make prefast happy
|
|
hResult = StringCchCopy(szNewKeyPath, cchLen, szFullKey);
|
|
}
|
|
|
|
//We calculte the buffer for szNewKeyPath, so here StringCchCopy should be
|
|
//always success, assinging return value just make prefast happy
|
|
hResult = StringCchCat(szNewKeyPath, cchLen, L"\\");
|
|
hResult = StringCchCat(szNewKeyPath, cchLen, lpKeyName);
|
|
|
|
hResult = AddRegKeyRename(szFullKey, szNameBuf, lpKeyName, szUserName);
|
|
|
|
if (FAILED(hResult))
|
|
{
|
|
DPF(REGerr, L"QueryEnumerateKey: AddRegKeyRename failed. Key=%s", szKeyPath);
|
|
}
|
|
else
|
|
{
|
|
DPF(REGinf, L"QueryEnumerateKey: AddRegKeyRename succeed. Key=%s", szKeyPath);
|
|
}
|
|
|
|
free (szNewKeyPath);
|
|
}
|
|
|
|
|
|
// recursive query
|
|
lResult = QueryEnumerateKey(hSubKey,
|
|
szUserName,
|
|
szUserSid,
|
|
lpRegStr,
|
|
szKeyPath,
|
|
lpRegExclusionList,
|
|
TreatAsType,
|
|
bStrChk);
|
|
|
|
if(lResult != ERROR_SUCCESS)
|
|
{
|
|
if (lResult == ERROR_NOT_ENOUGH_MEMORY)
|
|
{
|
|
if (szKeyPath)
|
|
free(szKeyPath);
|
|
|
|
RegCloseKey(hSubKey);
|
|
goto Cleanup;
|
|
} else
|
|
DPF(REGerr, L"QueryEnumerateKey: QueryEnumerateKey failed. Key=%s lResult=%d", szKeyPath, lResult);
|
|
}
|
|
|
|
RegCloseKey(hSubKey);
|
|
|
|
if(szKeyPath)
|
|
free(szKeyPath);
|
|
|
|
NextKey:
|
|
if (dwAccessDenied)
|
|
AdjustObjectSecurity(szKeyName, SE_REGISTRY_KEY, FALSE);
|
|
|
|
i++;
|
|
} while (1);
|
|
|
|
Cleanup:
|
|
if(szNameBuf)
|
|
free(szNameBuf);
|
|
|
|
return lResult;
|
|
}
|