windows-nt/Source/XPSP1/NT/admin/wmi/wbem/winmgmt/stdprov/regcrc.cpp
2020-09-26 16:20:57 +08:00

217 lines
5 KiB
C++

/*++
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;
}