windows-nt/Source/XPSP1/NT/base/fs/utils/reg/compare.c

1183 lines
33 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
//-----------------------------------------------------------------------//
//
// File: compare.cpp
// Created: April 1999
// By: Zeyong Xu
// Purpose: Compare two registry key
//
//------------------------------------------------------------------------//
#include "stdafx.h"
#include "reg.h"
#include "compare.h"
BOOL g_bHasDifference = FALSE;
//-----------------------------------------------------------------------//
//
// CompareRegistry()
//
//-----------------------------------------------------------------------//
LONG CompareRegistry(PAPPVARS pAppVars,
PAPPVARS pDstVars,
UINT argc,
TCHAR *argv[])
{
LONG nResult;
HKEY hLeftKey;
HKEY hRightKey;
//
// Parse the cmd-line
//
nResult = ParseCompareCmdLine(pAppVars, pDstVars, argc, argv);
if (nResult != ERROR_SUCCESS)
{
return nResult;
}
//
// Connect to the Remote Machine(s) - if applicable
//
nResult = RegConnectMachine(pAppVars);
if (nResult != ERROR_SUCCESS)
{
return nResult;
}
nResult = RegConnectMachine(pDstVars);
if (nResult != ERROR_SUCCESS)
{
return nResult;
}
//
// Now implement the body of the Compare Operation
//
nResult = RegOpenKeyEx(pAppVars->hRootKey,
pAppVars->szSubKey,
0,
KEY_READ,
&hLeftKey);
if (nResult != ERROR_SUCCESS)
{
return nResult;
}
nResult = RegOpenKeyEx(pDstVars->hRootKey,
pDstVars->szSubKey,
0,
KEY_READ,
&hRightKey);
if (nResult != ERROR_SUCCESS)
{
return nResult;
}
// if try to compare the same keys
if (pAppVars->hRootKey == pDstVars->hRootKey &&
_tcsicmp(pAppVars->szFullKey, pDstVars->szFullKey) == 0)
{
RegCloseKey(hLeftKey);
RegCloseKey(hRightKey);
return REG_STATUS_COMPARESELF;
}
//
// compare a single value if pAppVars->szValueName is not NULL
//
if(pAppVars->szValueName)
{
nResult = CompareValues(hLeftKey,
pAppVars->szFullKey,
hRightKey,
pDstVars->szFullKey,
pAppVars->szValueName,
pAppVars->nOutputType);
}
else
{
//
// Recursively compare if pAppVars->bRecurseSubKeys is true
//
nResult = CompareEnumerateKey(hLeftKey,
pAppVars->szFullKey,
hRightKey,
pDstVars->szFullKey,
pAppVars->nOutputType,
pAppVars->bRecurseSubKeys);
}
if(nResult == ERROR_SUCCESS)
{
pAppVars->bHasDifference = g_bHasDifference;
if(g_bHasDifference)
MyTPrintf(stdout,_T("\r\nResult Compared: Different\r\n"));
else
MyTPrintf(stdout,_T("\r\nResult Compared: Identical\r\n"));
}
//
// lets clean up
//
RegCloseKey(hLeftKey);
RegCloseKey(hRightKey);
return nResult;
}
REG_STATUS ParseCompareCmdLine(PAPPVARS pAppVars,
PAPPVARS pDstVars,
UINT argc,
TCHAR *argv[])
{
UINT i;
REG_STATUS nResult = ERROR_SUCCESS;
BOOL bInvalidParams = FALSE;
//
// Do we have a *valid* number of cmd-line params
//
if(argc < 4)
{
return REG_STATUS_TOFEWPARAMS;
}
else if(argc > 8)
{
return REG_STATUS_TOMANYPARAMS;
}
//
// Left Machine Name and Registry key
//
nResult = BreakDownKeyString(argv[2], pAppVars);
if(nResult != ERROR_SUCCESS)
return nResult;
//
// Right Machine Name and Registry key
//
nResult = BreakDownKeyString(argv[3], pDstVars);
if(nResult == REG_STATUS_NOKEYNAME)
{
// if no keyname for right side is specified,
// they are comparing the same key name
nResult = CopyKeyNameFromLeftToRight(pAppVars, pDstVars);
}
if( nResult != ERROR_SUCCESS)
return nResult;
// parsing
for(i=4; i<argc; i++)
{
if(!_tcsicmp(argv[i], _T("/v")))
{
if(bInvalidParams || pAppVars->bRecurseSubKeys)
return REG_STATUS_INVALIDPARAMS;
bInvalidParams = TRUE;
i++;
if(i<argc)
{
pAppVars->szValueName = (TCHAR*) calloc(_tcslen(argv[i]) + 1,
sizeof(TCHAR));
if (!pAppVars->szValueName) {
return ERROR_NOT_ENOUGH_MEMORY;
}
_tcscpy(pAppVars->szValueName, argv[i]);
}
else
return REG_STATUS_TOFEWPARAMS;
}
else if(!_tcsicmp(argv[i], _T("/ve")))
{
if(bInvalidParams || pAppVars->bRecurseSubKeys)
return REG_STATUS_INVALIDPARAMS;
bInvalidParams = TRUE;
pAppVars->szValueName = (TCHAR*) calloc(1, sizeof(TCHAR));
if (!pAppVars->szValueName) {
return ERROR_NOT_ENOUGH_MEMORY;
}
}
else if(!_tcsicmp(argv[i], _T("/oa")))
{
if(bInvalidParams)
return REG_STATUS_INVALIDPARAMS;
bInvalidParams = TRUE;
pAppVars->nOutputType = OUTPUTTYPE_ALL;
}
else if(!_tcsicmp(argv[i], _T("/od")))
{
if(bInvalidParams)
return REG_STATUS_INVALIDPARAMS;
bInvalidParams = TRUE;
pAppVars->nOutputType = OUTPUTTYPE_DIFF;
}
else if(!_tcsicmp(argv[i], _T("/os")))
{
if(bInvalidParams)
return REG_STATUS_INVALIDPARAMS;
bInvalidParams = TRUE;
pAppVars->nOutputType = OUTPUTTYPE_SAME;
}
else if(!_tcsicmp(argv[i], _T("/on")))
{
if(bInvalidParams)
return REG_STATUS_INVALIDPARAMS;
bInvalidParams = TRUE;
pAppVars->nOutputType = OUTPUTTYPE_NONE;
}
else if(!_tcsicmp(argv[i], _T("/s")))
{
if(pAppVars->szValueName)
return REG_STATUS_INVALIDPARAMS;
pAppVars->bRecurseSubKeys = TRUE;
}
else
{
nResult = REG_STATUS_INVALIDPARAMS;
}
}
return nResult;
}
REG_STATUS CopyKeyNameFromLeftToRight(APPVARS* pAppVars, APPVARS* pDstVars)
{
// check if rootkey is remotable for right side
if( pDstVars->bUseRemoteMachine &&
!(pAppVars->hRootKey == HKEY_USERS ||
pAppVars->hRootKey == HKEY_LOCAL_MACHINE) )
{
return REG_STATUS_NONREMOTABLEROOT;
}
pDstVars->szFullKey = (TCHAR*) calloc(_tcslen(pAppVars->szFullKey) + 1,
sizeof(TCHAR));
if (!pDstVars->szFullKey)
return ERROR_NOT_ENOUGH_MEMORY;
pDstVars->szSubKey = (TCHAR*) calloc(_tcslen(pAppVars->szSubKey) + 1,
sizeof(TCHAR));
if (!pDstVars->szSubKey) {
free (pDstVars->szFullKey);
return ERROR_NOT_ENOUGH_MEMORY;
}
_tcscpy(pDstVars->szFullKey, pAppVars->szFullKey);
pDstVars->hRootKey = pAppVars->hRootKey;
_tcscpy(pDstVars->szSubKey, pAppVars->szSubKey);
return ERROR_SUCCESS;
}
//-----------------------------------------------------------------------//
//
// EnumerateKey() - Recursive
//
//-----------------------------------------------------------------------//
LONG CompareEnumerateKey(HKEY hLeftKey,
TCHAR* szLeftFullKeyName,
HKEY hRightKey,
TCHAR* szRightFullKeyName,
int nOutputType,
BOOL bRecurseSubKeys)
{
DWORD nResult;
DWORD dwSize;
TCHAR* pszLeftNameBuf;
TCHAR* pszRightNameBuf;
TCHAR** pLeftArray;
TCHAR** pRightArray;
DWORD dwIndex;
DWORD dwNumOfLeftKeyName;
DWORD dwLenOfLeftKeyName;
DWORD dwNumOfRightKeyName;
DWORD dwLenOfRightKeyName;
DWORD dw;
HKEY hLeftSubKey;
HKEY hRightSubKey;
// enumerate all values under current key
nResult = CompareEnumerateValueName(hLeftKey,
szLeftFullKeyName,
hRightKey,
szRightFullKeyName,
nOutputType);
if(!bRecurseSubKeys || nResult != ERROR_SUCCESS)
return nResult;
// enum all subkeys
// query left key info
nResult = RegQueryInfoKey(hLeftKey,
NULL,
NULL,
NULL,
&dwNumOfLeftKeyName,
&dwLenOfLeftKeyName,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
if (nResult != ERROR_SUCCESS)
{
return nResult;
}
// query right key info
nResult = RegQueryInfoKey(hRightKey,
NULL,
NULL,
NULL,
&dwNumOfRightKeyName,
&dwLenOfRightKeyName,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
if (nResult != ERROR_SUCCESS)
{
return nResult;
}
#ifndef REG_FOR_WIN2000 // ansi version for win98
// fix API bugs: RegQueryInfoKey() returns non-correct length values
// on remote Win98
if(dwLenOfLeftKeyName < MAX_PATH)
dwLenOfLeftKeyName = MAX_PATH;
if(dwLenOfRightKeyName < MAX_PATH)
dwLenOfRightKeyName = MAX_PATH;
#endif
//
// enumerate all of the subkeys in left key
//
dwLenOfLeftKeyName++;
pszLeftNameBuf = (TCHAR*) calloc(dwNumOfLeftKeyName *
dwLenOfLeftKeyName,
sizeof(TCHAR));
if (!pszLeftNameBuf) {
nResult = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
// index array of name buffer for compare
pLeftArray = (TCHAR**) calloc(dwNumOfLeftKeyName, sizeof(TCHAR*));
if (!pLeftArray) {
nResult = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
dwIndex = 0;
while(dwIndex < dwNumOfLeftKeyName && nResult == ERROR_SUCCESS)
{
pLeftArray[dwIndex] = pszLeftNameBuf +
(dwIndex * dwLenOfLeftKeyName);
dwSize = dwLenOfLeftKeyName;
nResult = RegEnumKeyEx(hLeftKey,
dwIndex,
pLeftArray[dwIndex],
&dwSize,
NULL,
NULL,
NULL,
NULL);
dwIndex++;
}
if (nResult != ERROR_SUCCESS)
{
if(pszLeftNameBuf)
free(pszLeftNameBuf);
if(pLeftArray)
free(pLeftArray);
return nResult;
}
//
// enumerate all of the subkeys in right key
//
dwLenOfRightKeyName++;
pszRightNameBuf = (TCHAR*) calloc(dwNumOfRightKeyName *
dwLenOfRightKeyName,
sizeof(TCHAR));
if (!pszRightNameBuf) {
nResult = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
// index array of name buffer for compare
pRightArray = (TCHAR**) calloc(dwNumOfRightKeyName, sizeof(TCHAR*));
if (!pRightArray) {
nResult = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
dwIndex = 0;
while(dwIndex < dwNumOfRightKeyName && nResult == ERROR_SUCCESS)
{
pRightArray[dwIndex] = pszRightNameBuf +
(dwIndex * dwLenOfRightKeyName);
dwSize = dwLenOfRightKeyName;
nResult = RegEnumKeyEx(hRightKey,
dwIndex,
pRightArray[dwIndex],
&dwSize,
NULL,
NULL,
NULL,
NULL);
dwIndex++;
}
if (nResult != ERROR_SUCCESS)
{
if(pszLeftNameBuf)
free(pszLeftNameBuf);
if(pLeftArray)
free(pLeftArray);
if(pszRightNameBuf)
free(pszRightNameBuf);
if(pRightArray)
free(pRightArray);
return nResult;
}
// compare two subkey name array to find the same subkey
for(dwIndex = 0;
dwIndex < dwNumOfLeftKeyName && nResult == ERROR_SUCCESS;
dwIndex++)
{
if(pLeftArray[dwIndex] == NULL)
continue;
for(dw = 0;
dw < dwNumOfRightKeyName && nResult == ERROR_SUCCESS;
dw++)
{
if(pRightArray[dw] == NULL)
continue;
// if same subey name, recusive
if(_tcsicmp(pLeftArray[dwIndex], pRightArray[dw]) == 0)
{
TCHAR* szTempLeft;
TCHAR* szTempRight;
// print out key
if( nOutputType == OUTPUTTYPE_SAME ||
nOutputType == OUTPUTTYPE_ALL )
{
nResult = PrintKey(hLeftKey,
szLeftFullKeyName,
pLeftArray[dwIndex],
PRINTTYPE_SAME);
if(nResult != ERROR_SUCCESS)
break;
}
//
// Now implement the body of the Compare Operation
//
nResult = RegOpenKeyEx(hLeftKey,
pLeftArray[dwIndex],
0,
KEY_READ,
&hLeftSubKey);
if (nResult != ERROR_SUCCESS)
break;
nResult = RegOpenKeyEx(hRightKey,
pLeftArray[dwIndex],
0,
KEY_READ,
&hRightSubKey);
if (nResult != ERROR_SUCCESS)
break;
// create left full subkey
szTempLeft = (TCHAR*) calloc(_tcslen(szLeftFullKeyName) +
_tcslen(pLeftArray[dwIndex]) +
2,
sizeof(TCHAR));
if (!szTempLeft) {
nResult = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
_tcscpy(szTempLeft, szLeftFullKeyName);
_tcscat(szTempLeft, _T("\\"));
_tcscat(szTempLeft, pLeftArray[dwIndex]);
// create right full subkey
szTempRight = (TCHAR*) calloc(_tcslen(szRightFullKeyName) +
_tcslen(pLeftArray[dwIndex]) +
2,
sizeof(TCHAR));
if (!szTempRight) {
free (szTempLeft);
nResult = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
_tcscpy(szTempRight, szRightFullKeyName);
_tcscat(szTempRight, _T("\\"));
_tcscat(szTempRight, pLeftArray[dwIndex]);
// recursive to compare subkeys
nResult = CompareEnumerateKey(hLeftSubKey,
szLeftFullKeyName,
hRightSubKey,
szRightFullKeyName,
nOutputType,
bRecurseSubKeys);
if(szTempLeft) {
free(szTempLeft);
}
if(szTempRight) {
free(szTempRight);
}
RegCloseKey(hLeftSubKey);
RegCloseKey(hRightSubKey);
pLeftArray[dwIndex] = NULL;
pRightArray[dw] = NULL;
break;
}
}
}
// Output subkey name in left key
for(dwIndex = 0;
dwIndex < dwNumOfLeftKeyName && nResult == ERROR_SUCCESS;
dwIndex++)
{
if(pLeftArray[dwIndex] == NULL)
continue;
if( nOutputType == OUTPUTTYPE_DIFF ||
nOutputType == OUTPUTTYPE_ALL )
{
nResult = PrintKey(hLeftKey,
szLeftFullKeyName,
pLeftArray[dwIndex],
PRINTTYPE_LEFT);
}
g_bHasDifference = TRUE;
}
// Output subkey name in right key
for(dwIndex = 0;
dwIndex < dwNumOfRightKeyName && nResult == ERROR_SUCCESS;
dwIndex++)
{
if(pRightArray[dwIndex] == NULL)
continue;
if( nOutputType == OUTPUTTYPE_DIFF ||
nOutputType == OUTPUTTYPE_ALL )
{
nResult = PrintKey(hRightKey,
szRightFullKeyName,
pRightArray[dwIndex],
PRINTTYPE_RIGHT);
}
g_bHasDifference = TRUE;
}
Cleanup:
if(pszLeftNameBuf)
free(pszLeftNameBuf);
if(pLeftArray)
free(pLeftArray);
if(pszRightNameBuf)
free(pszRightNameBuf);
if(pRightArray)
free(pRightArray);
return nResult;
}
LONG CompareEnumerateValueName(HKEY hLeftKey,
TCHAR* szLeftFullKeyName,
HKEY hRightKey,
TCHAR* szRightFullKeyName,
int nOutputType)
{
DWORD nResult = ERROR_SUCCESS;
DWORD dwSize;
TCHAR* pszLeftNameBuf = NULL;
TCHAR* pszRightNameBuf = NULL;
TCHAR** pLeftArray = NULL;
TCHAR** pRightArray = NULL;
DWORD dwIndex;
DWORD dwNumOfRightValueName;
DWORD dwLenOfRightValueName;
DWORD dw;
// query left key info
DWORD dwNumOfLeftValueName;
DWORD dwLenOfLeftValueName;
nResult = RegQueryInfoKey(hLeftKey,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
&dwNumOfLeftValueName,
&dwLenOfLeftValueName,
NULL,
NULL,
NULL);
if (nResult != ERROR_SUCCESS)
{
return nResult;
}
// query right key info
nResult = RegQueryInfoKey(hRightKey,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
&dwNumOfRightValueName,
&dwLenOfRightValueName,
NULL,
NULL,
NULL);
if (nResult != ERROR_SUCCESS)
{
return nResult;
}
#ifndef REG_FOR_WIN2000 // ansi version for win98
// fix API bugs: RegQueryInfoKey() returns non-correct length values
// on remote Win98
if(dwLenOfLeftValueName < MAX_PATH)
dwLenOfLeftValueName = MAX_PATH;
if(dwLenOfRightValueName < MAX_PATH)
dwLenOfRightValueName = MAX_PATH;
#endif
//
// enumerate all of the values in left key
//
dwLenOfLeftValueName++;
pszLeftNameBuf = (TCHAR*) calloc(dwNumOfLeftValueName *
dwLenOfLeftValueName,
sizeof(TCHAR));
if (!pszLeftNameBuf) {
nResult = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
// index array of name buffer for compare
pLeftArray = (TCHAR**) calloc(dwNumOfLeftValueName, sizeof(TCHAR*));
if (!pLeftArray) {
nResult = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
dwIndex = 0;
while(dwIndex < dwNumOfLeftValueName && nResult == ERROR_SUCCESS)
{
pLeftArray[dwIndex] = pszLeftNameBuf +
(dwIndex * dwLenOfLeftValueName);
dwSize = dwLenOfLeftValueName;
nResult = RegEnumValue(hLeftKey,
dwIndex,
pLeftArray[dwIndex],
&dwSize,
NULL,
NULL,
NULL,
NULL);
dwIndex++;
}
if (nResult != ERROR_SUCCESS)
{
if(pszLeftNameBuf)
free(pszLeftNameBuf);
if(pLeftArray)
free(pLeftArray);
return nResult;
}
//
// enumerate all of the values in right key
//
dwLenOfRightValueName++;
pszRightNameBuf = (TCHAR*) calloc(dwNumOfRightValueName *
dwLenOfRightValueName,
sizeof(TCHAR));
if (!pszRightNameBuf) {
nResult = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
// index array of name buffer for compare
pRightArray = (TCHAR**) calloc(dwNumOfRightValueName, sizeof(TCHAR*));
if (!pRightArray) {
nResult = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
dwIndex = 0;
while(dwIndex < dwNumOfRightValueName && nResult == ERROR_SUCCESS)
{
pRightArray[dwIndex] = pszRightNameBuf +
(dwIndex * dwLenOfRightValueName);
dwSize = dwLenOfRightValueName;
nResult = RegEnumValue(hRightKey,
dwIndex,
pRightArray[dwIndex],
&dwSize,
NULL,
NULL,
NULL,
NULL);
dwIndex++;
}
if (nResult != ERROR_SUCCESS)
{
if(pszLeftNameBuf)
free(pszLeftNameBuf);
if(pLeftArray)
free(pLeftArray);
if(pszRightNameBuf)
free(pszRightNameBuf);
if(pRightArray)
free(pRightArray);
return nResult;
}
// compare two valuename array to find the same valuename
for(dwIndex = 0;
dwIndex < dwNumOfLeftValueName && nResult == ERROR_SUCCESS;
dwIndex++)
{
if(pLeftArray[dwIndex] == NULL)
continue;
for(dw = 0;
dw < dwNumOfRightValueName && nResult == ERROR_SUCCESS;
dw++)
{
if(pRightArray[dw] == NULL)
continue;
// same valuename
if(_tcsicmp(pLeftArray[dwIndex], pRightArray[dw]) == 0)
{
nResult = CompareValues(hLeftKey,
szLeftFullKeyName,
hRightKey,
szRightFullKeyName,
pLeftArray[dwIndex],
nOutputType);
pLeftArray[dwIndex] = NULL;
pRightArray[dw] = NULL;
break;
}
}
}
// Output different valuename in left key
for(dwIndex = 0;
dwIndex < dwNumOfLeftValueName && nResult == ERROR_SUCCESS;
dwIndex++)
{
if(pLeftArray[dwIndex] == NULL)
continue;
if( nOutputType == OUTPUTTYPE_DIFF ||
nOutputType == OUTPUTTYPE_ALL )
{
nResult = OutputValue(hLeftKey,
szLeftFullKeyName,
pLeftArray[dwIndex],
PRINTTYPE_LEFT);
}
g_bHasDifference = TRUE;
}
// Output different valuename in right key
for(dwIndex = 0;
dwIndex < dwNumOfRightValueName && nResult == ERROR_SUCCESS;
dwIndex++)
{
if(pRightArray[dwIndex] == NULL)
continue;
if( nOutputType == OUTPUTTYPE_DIFF ||
nOutputType == OUTPUTTYPE_ALL )
{
nResult = OutputValue(hRightKey,
szRightFullKeyName,
pRightArray[dwIndex],
PRINTTYPE_RIGHT);
}
g_bHasDifference = TRUE;
}
Cleanup:
if(pszLeftNameBuf)
free(pszLeftNameBuf);
if(pLeftArray)
free(pLeftArray);
if(pszRightNameBuf)
free(pszRightNameBuf);
if(pRightArray)
free(pRightArray);
return nResult;
}
//-----------------------------------------------------------------------//
//
// CompareValues()
//
//-----------------------------------------------------------------------//
LONG CompareValues(HKEY hLeftKey,
TCHAR* szLeftFullKeyName,
HKEY hRightKey,
TCHAR* szRightFullKeyName,
TCHAR* szValueName,
int nOutputType)
{
LONG nResult;
DWORD dwTypeLeft;
DWORD dwTypeRight;
DWORD dwSizeLeft;
DWORD dwSizeRight;
BYTE* pDataBuffLeft = NULL;
BYTE* pDataBuffRight = NULL;
//
// First find out how much memory to allocate
//
nResult = RegQueryValueEx(hLeftKey,
szValueName,
0,
&dwTypeLeft,
NULL,
&dwSizeLeft);
if (nResult != ERROR_SUCCESS)
{
return nResult;
}
nResult = RegQueryValueEx(hRightKey,
szValueName,
0,
&dwTypeRight,
NULL,
&dwSizeRight);
if (nResult != ERROR_SUCCESS)
{
return nResult;
}
pDataBuffLeft = (BYTE*) calloc(dwSizeLeft + 1, sizeof(BYTE));
if (!pDataBuffLeft) {
nResult = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
pDataBuffRight = (BYTE*) calloc(dwSizeRight + 1, sizeof(BYTE));
if (!pDataBuffRight) {
nResult = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
//
// Now get the data
//
nResult = RegQueryValueEx(hLeftKey,
szValueName,
0,
&dwTypeLeft,
(LPBYTE) pDataBuffLeft,
&dwSizeLeft);
if (nResult == ERROR_SUCCESS)
{
nResult = RegQueryValueEx(hRightKey,
szValueName,
0,
&dwTypeRight,
(LPBYTE) pDataBuffRight,
&dwSizeRight);
}
if(nResult != ERROR_SUCCESS)
{
if(pDataBuffLeft)
free(pDataBuffLeft);
if(pDataBuffRight)
free(pDataBuffRight);
return nResult;
}
if( dwTypeLeft != dwTypeRight ||
dwSizeLeft != dwSizeRight ||
CompareByteData(pDataBuffLeft, pDataBuffRight, dwSizeLeft) )
{
if( nOutputType == OUTPUTTYPE_DIFF ||
nOutputType == OUTPUTTYPE_ALL )
{
// print left and right
PrintValue(szLeftFullKeyName,
szValueName,
dwTypeLeft,
pDataBuffLeft,
dwSizeLeft,
PRINTTYPE_LEFT);
PrintValue(szRightFullKeyName,
szValueName,
dwTypeRight,
pDataBuffRight,
dwSizeRight,
PRINTTYPE_RIGHT);
}
g_bHasDifference = TRUE;
}
else // they are the same
{
if( nOutputType == OUTPUTTYPE_SAME ||
nOutputType == OUTPUTTYPE_ALL )
{
PrintValue(szLeftFullKeyName,
szValueName,
dwTypeLeft,
pDataBuffLeft,
dwSizeLeft,
PRINTTYPE_SAME);
}
}
Cleanup:
if(pDataBuffLeft)
free(pDataBuffLeft);
if(pDataBuffRight)
free(pDataBuffRight);
return nResult;
}
LONG PrintKey(HKEY hKey,
TCHAR* szFullKeyName,
TCHAR* szSubKeyName,
int nPrintType)
{
LONG nResult;
HKEY hSubKey;
// make sure key is there
nResult = RegOpenKeyEx(hKey,
szSubKeyName,
0,
KEY_READ,
&hSubKey);
if (nResult != ERROR_SUCCESS)
return nResult;
RegCloseKey(hSubKey);
// print type
if(nPrintType == PRINTTYPE_LEFT)
MyTPrintf(stdout,_T("< "));
else if(nPrintType == PRINTTYPE_RIGHT)
MyTPrintf(stdout,_T("> "));
else if(nPrintType == PRINTTYPE_SAME)
MyTPrintf(stdout,_T("= "));
MyTPrintf(stdout,_T("Key: %s\\%s\r\n"), szFullKeyName, szSubKeyName);
return nResult;
}
LONG OutputValue(HKEY hKey,
TCHAR* szFullKeyName,
TCHAR* szValueName,
int nPrintType)
{
LONG nResult = ERROR_SUCCESS;
DWORD dwType;
DWORD dwSize;
BYTE* pDataBuff;
//
// First find out how much memory to allocate
//
nResult = RegQueryValueEx(hKey,
szValueName,
0,
&dwType,
NULL,
&dwSize);
if (nResult != ERROR_SUCCESS)
{
return nResult;
}
pDataBuff = (BYTE*) calloc(dwSize + 1, sizeof(BYTE));
if (!pDataBuff) {
return ERROR_NOT_ENOUGH_MEMORY;
}
//
// Now get the data
//
nResult = RegQueryValueEx(hKey,
szValueName,
0,
&dwType,
(LPBYTE) pDataBuff,
&dwSize);
if(nResult == ERROR_SUCCESS)
{
PrintValue(szFullKeyName,
szValueName,
dwType,
pDataBuff,
dwSize,
nPrintType);
}
if(pDataBuff)
free(pDataBuff);
return nResult;
}
void PrintValue(TCHAR* szFullKeyName,
TCHAR* szValueName,
DWORD dwType,
BYTE* pData,
DWORD dwSize,
int nPrintType)
{
DWORD i;
TCHAR szTypeStr[25];
// print type
if(nPrintType == PRINTTYPE_LEFT)
MyTPrintf(stdout,_T("< "));
else if(nPrintType == PRINTTYPE_RIGHT)
MyTPrintf(stdout,_T("> "));
else if(nPrintType == PRINTTYPE_SAME)
MyTPrintf(stdout,_T("= "));
// first Print Key
MyTPrintf(stdout,_T("Value: %s"), szFullKeyName);
// then print ValueName Type Data
GetTypeStrFromType(szTypeStr, dwType);
if(_tcslen(szValueName) == 0) // no name
{
MyTPrintf(stdout,_T(" <NO NAME> %s "), szTypeStr);
}
else
{
MyTPrintf(stdout,_T(" %s %s "), szValueName, szTypeStr);
}
switch (dwType)
{
case REG_BINARY:
for(i=0; i<dwSize; i++)
{
MyTPrintf(stdout,_T("%02X"),pData[i]);
}
break;
case REG_DWORD:
case REG_DWORD_BIG_ENDIAN:
MyTPrintf(stdout,_T("0x%x"), *((DWORD*)pData) );
break;
case REG_MULTI_SZ:
{
//
// Replace '\0' with "\0" for MULTI_SZ
//
TCHAR* pEnd = (TCHAR*) pData;
while( (BYTE*)pEnd < pData + dwSize )
{
if(*pEnd == 0)
{
MyTPrintf(stdout,_T("\\0"));
pEnd++;
}
else
{
MyTPrintf(stdout,_T("%s"), pEnd);
pEnd += _tcslen(pEnd);
}
}
}
break;
default:
MyTPrintf(stdout,_T("%s"), (TCHAR*) pData);
break;
}
MyTPrintf(stdout,_T("\r\n"));
}
BOOL CompareByteData(BYTE* pDataBuffLeft, BYTE* pDataBuffRight, DWORD dwSize)
{
BOOL bDiff = FALSE;
DWORD dw;
for(dw=0; dw<dwSize; dw++)
{
if(pDataBuffLeft[dw] != pDataBuffRight[dw])
{
bDiff = TRUE;
break;
}
}
return bDiff;
}