/*++ Copyright (C) 1996-2001 Microsoft Corporation Module Name: REGCRC.CPP Abstract: History: --*/ #include "precomp.h" #include "regcrc.h" #include "tchar.h" HRESULT CRegCRC::ComputeValueCRC(HKEY hKey, LPCTSTR szValueName, DWORD dwPrevCRC, DWORD& dwNewCRC) { dwNewCRC = dwPrevCRC; // Get the size of the value // ========================= DWORD dwSize = 0; long lRes = RegQueryValueEx(hKey, szValueName, NULL, NULL, NULL, &dwSize); if(lRes) { return S_FALSE; } // Get the actual value // ==================== BYTE* pBuffer = new BYTE[dwSize]; DWORD dwType; lRes = RegQueryValueEx(hKey, szValueName, NULL, &dwType, pBuffer, &dwSize); if(lRes) { return S_FALSE; } // Hash the type // ============= dwNewCRC = UpdateCRC32((BYTE*)&dwType, sizeof(DWORD), dwNewCRC); // Hash the data // ============= dwNewCRC = UpdateCRC32(pBuffer, dwSize, dwNewCRC); delete [] pBuffer; return S_OK; } HRESULT CRegCRC::ComputeKeyValuesCRC(HKEY hKey, DWORD dwPrevCRC, DWORD& dwNewCRC) { dwNewCRC = dwPrevCRC; // Get maximum value length // ======================== DWORD dwNumValues, dwMaxValueLen; long lRes = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwNumValues, &dwMaxValueLen, NULL, NULL, NULL); if(lRes && lRes != ERROR_INSUFFICIENT_BUFFER) { return E_FAIL; } // Enuremate all the values // ======================== for(DWORD dwIndex = 0; dwIndex < dwNumValues; dwIndex++) { TCHAR* szName = new TCHAR[dwMaxValueLen + 1]; DWORD dwLen = dwMaxValueLen + 1; long lRes = RegEnumValue(hKey, dwIndex, szName, &dwLen, NULL, NULL, NULL, NULL); if(lRes) { delete [] szName; continue; } // Hash the name // ============= dwNewCRC = UpdateCRC32((LPBYTE)szName, lstrlen(szName), dwNewCRC); // Hash the value // ============== ComputeValueCRC(hKey, szName, dwNewCRC, dwNewCRC); delete [] szName; } return S_OK; } HRESULT CRegCRC::ComputeKeyCRC(HKEY hKey, DWORD dwPrevCRC, DWORD& dwNewCRC) { HRESULT hres = ComputeKeyValuesCRC(hKey, dwPrevCRC, dwNewCRC); // Get maximum subkey length // ========================= DWORD dwNumKeys, dwMaxKeyLen; long lRes = RegQueryInfoKey(hKey, NULL, NULL, NULL, &dwNumKeys, &dwMaxKeyLen, NULL, NULL, NULL, NULL, NULL, NULL); if(lRes && lRes != ERROR_INSUFFICIENT_BUFFER) { return E_FAIL; } // Enuremate all the subkeys // ========================= for(DWORD dwIndex = 0; dwIndex < dwNumKeys; dwIndex++) { TCHAR* szName = new TCHAR[dwMaxKeyLen + 1]; DWORD dwLen = dwMaxKeyLen + 1; long lRes = RegEnumKeyEx(hKey, dwIndex, szName, &dwLen, NULL, NULL, NULL, NULL); if(lRes) { delete [] szName; continue; } // Hash the name // ============= dwNewCRC = UpdateCRC32((LPBYTE)szName, lstrlen(szName), dwNewCRC); delete [] szName; } return S_OK; } HRESULT CRegCRC::ComputeTreeCRC(HKEY hKey, DWORD dwPrevCRC, DWORD& dwNewCRC) { dwNewCRC = dwPrevCRC; // Compute this key's CRC // ====================== HRESULT hres = ComputeKeyValuesCRC(hKey, dwNewCRC, dwNewCRC); if(FAILED(hres)) return hres; // Get maximum subkey length // ========================= DWORD dwNumKeys, dwMaxKeyLen; long lRes = RegQueryInfoKey(hKey, NULL, NULL, NULL, &dwNumKeys, &dwMaxKeyLen, NULL, NULL, NULL, NULL, NULL, NULL); if(lRes && lRes != ERROR_INSUFFICIENT_BUFFER) { return E_FAIL; } // Enuremate all the subkeys // ========================= for(DWORD dwIndex = 0; dwIndex < dwNumKeys; dwIndex++) { TCHAR* szName = new TCHAR[dwMaxKeyLen + 1]; DWORD dwLen = dwMaxKeyLen + 1; long lRes = RegEnumKeyEx(hKey, dwIndex, szName, &dwLen, NULL, NULL, NULL, NULL); if(lRes) { delete [] szName; continue; } // Hash the name // ============= dwNewCRC = UpdateCRC32((LPBYTE)szName, lstrlen(szName), dwNewCRC); // Open the subkey // =============== HKEY hChild; lRes = RegOpenKeyEx(hKey, szName, 0, KEY_READ, &hChild); delete [] szName; if(lRes) { continue; } else { // Hash the value // ============== ComputeTreeCRC(hChild, dwNewCRC, dwNewCRC); RegCloseKey(hChild); } } return S_OK; }