251 lines
7.9 KiB
C++
251 lines
7.9 KiB
C++
/****************************************************************************
|
|
*
|
|
* File: reginfo.cpp
|
|
* Project: DxDiag (DirectX Diagnostic Tool)
|
|
* Author: Mike Anderson (manders@microsoft.com)
|
|
* Purpose: Gather and hold registry information
|
|
*
|
|
* (C) Copyright 1998 Microsoft Corp. All rights reserved.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include <Windows.h>
|
|
#include <tchar.h>
|
|
#include "reginfo.h"
|
|
|
|
static HRESULT AddError(RegError** ppRegErrorFirst, RegError* pRegErrorNew);
|
|
static BOOL EqualMemory(BYTE* pb1, BYTE* pb2, DWORD numBytes);
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* CheckRegDword
|
|
*
|
|
****************************************************************************/
|
|
HRESULT CheckRegDword(RegError** ppRegErrorFirst, HKEY hkeyRoot, TCHAR* pszKey,
|
|
TCHAR* pszValue, DWORD dwExpected)
|
|
{
|
|
HKEY hkey = NULL;
|
|
RegError regErrorNew;
|
|
|
|
ZeroMemory(®ErrorNew, sizeof(RegError));
|
|
regErrorNew.m_hkeyRoot = hkeyRoot;
|
|
lstrcpy(regErrorNew.m_szKey, pszKey);
|
|
lstrcpy(regErrorNew.m_szValue, pszValue);
|
|
regErrorNew.m_dwTypeExpected = REG_DWORD;
|
|
regErrorNew.m_dwExpected = dwExpected;
|
|
|
|
if (ERROR_SUCCESS != RegOpenKeyEx(hkeyRoot, pszKey, 0, KEY_READ, &hkey))
|
|
{
|
|
regErrorNew.m_ret = RET_MISSINGKEY;
|
|
}
|
|
else
|
|
{
|
|
regErrorNew.m_dwExpectedSize = sizeof(DWORD);
|
|
regErrorNew.m_dwActualSize = regErrorNew.m_dwExpectedSize; // RegQueryValueEx will change this
|
|
if (ERROR_SUCCESS != RegQueryValueEx(hkey, pszValue, 0, ®ErrorNew.m_dwTypeActual,
|
|
(LPBYTE)®ErrorNew.m_dwActual, ®ErrorNew.m_dwActualSize))
|
|
{
|
|
regErrorNew.m_ret = RET_MISSINGVALUE;
|
|
}
|
|
else if (regErrorNew.m_dwTypeActual != regErrorNew.m_dwTypeExpected)
|
|
{
|
|
regErrorNew.m_ret = RET_VALUEWRONGTYPE;
|
|
}
|
|
else if (regErrorNew.m_dwActual != dwExpected)
|
|
{
|
|
regErrorNew.m_ret = RET_VALUEWRONGDATA;
|
|
}
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
if (regErrorNew.m_ret == RET_NOERROR)
|
|
return S_OK;
|
|
else
|
|
return AddError(ppRegErrorFirst, ®ErrorNew);
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* CheckRegString
|
|
*
|
|
****************************************************************************/
|
|
HRESULT CheckRegString(RegError** ppRegErrorFirst, HKEY hkeyRoot, TCHAR* pszKey,
|
|
TCHAR* pszValue, TCHAR* pszExpected, CheckRegFlags crf,
|
|
HRESULT* phrError )
|
|
{
|
|
HKEY hkey = NULL;
|
|
RegError regErrorNew;
|
|
|
|
ZeroMemory(®ErrorNew, sizeof(RegError));
|
|
regErrorNew.m_hkeyRoot = hkeyRoot;
|
|
lstrcpy(regErrorNew.m_szKey, pszKey);
|
|
lstrcpy(regErrorNew.m_szValue, pszValue);
|
|
regErrorNew.m_dwTypeExpected = REG_SZ;
|
|
lstrcpy(regErrorNew.m_szExpected, pszExpected);
|
|
|
|
if (ERROR_SUCCESS != RegOpenKeyEx(hkeyRoot, pszKey, 0, KEY_READ, &hkey))
|
|
{
|
|
regErrorNew.m_ret = RET_MISSINGKEY;
|
|
}
|
|
else
|
|
{
|
|
regErrorNew.m_dwExpectedSize = lstrlen(pszExpected) + 1;
|
|
regErrorNew.m_dwActualSize = sizeof(regErrorNew.m_szActual); // RegQueryValueEx will change this
|
|
if (ERROR_SUCCESS != RegQueryValueEx(hkey, pszValue, 0, ®ErrorNew.m_dwTypeActual,
|
|
(LPBYTE)®ErrorNew.m_szActual, ®ErrorNew.m_dwActualSize))
|
|
{
|
|
regErrorNew.m_ret = RET_MISSINGVALUE;
|
|
}
|
|
else if (regErrorNew.m_dwTypeActual != regErrorNew.m_dwTypeExpected)
|
|
{
|
|
regErrorNew.m_ret = RET_VALUEWRONGTYPE;
|
|
}
|
|
else if (lstrcmp(regErrorNew.m_szExpected, TEXT("*")) != 0)
|
|
{
|
|
TCHAR* pszCompare = regErrorNew.m_szActual;
|
|
if (crf & CRF_LEAF)
|
|
{
|
|
pszCompare = _tcsrchr(regErrorNew.m_szActual, TEXT('\\'));
|
|
if (pszCompare == NULL)
|
|
pszCompare = regErrorNew.m_szActual;
|
|
else
|
|
pszCompare++; // skip past backslash
|
|
}
|
|
if (lstrcmpi(regErrorNew.m_szExpected, pszCompare) != 0)
|
|
{
|
|
regErrorNew.m_ret = RET_VALUEWRONGDATA;
|
|
}
|
|
}
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
if( phrError )
|
|
*phrError = regErrorNew.m_ret;
|
|
|
|
if (regErrorNew.m_ret == RET_NOERROR)
|
|
return S_OK;
|
|
else
|
|
return AddError(ppRegErrorFirst, ®ErrorNew);
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* CheckRegBinary
|
|
*
|
|
****************************************************************************/
|
|
HRESULT CheckRegBinary(RegError** ppRegErrorFirst, HKEY hkeyRoot, TCHAR* pszKey,
|
|
TCHAR* pszValue, BYTE* pbDataExpected, DWORD dwSizeExpected)
|
|
{
|
|
HKEY hkey = NULL;
|
|
RegError regErrorNew;
|
|
|
|
if (dwSizeExpected > sizeof(regErrorNew.m_bExpected))
|
|
return E_INVALIDARG;
|
|
|
|
ZeroMemory(®ErrorNew, sizeof(RegError));
|
|
regErrorNew.m_hkeyRoot = hkeyRoot;
|
|
lstrcpy(regErrorNew.m_szKey, pszKey);
|
|
lstrcpy(regErrorNew.m_szValue, pszValue);
|
|
regErrorNew.m_dwTypeExpected = REG_BINARY;
|
|
CopyMemory(regErrorNew.m_bExpected, pbDataExpected, dwSizeExpected);
|
|
|
|
if (ERROR_SUCCESS != RegOpenKeyEx(hkeyRoot, pszKey, 0, KEY_READ, &hkey))
|
|
{
|
|
regErrorNew.m_ret = RET_MISSINGKEY;
|
|
}
|
|
else
|
|
{
|
|
regErrorNew.m_dwExpectedSize = dwSizeExpected;
|
|
regErrorNew.m_dwActualSize = sizeof(regErrorNew.m_bExpected); // RegQueryValueEx will change this
|
|
if (ERROR_SUCCESS != RegQueryValueEx(hkey, pszValue, 0, ®ErrorNew.m_dwTypeActual,
|
|
(LPBYTE)®ErrorNew.m_bActual, ®ErrorNew.m_dwActualSize))
|
|
{
|
|
regErrorNew.m_ret = RET_MISSINGVALUE;
|
|
}
|
|
else if (regErrorNew.m_dwTypeActual != regErrorNew.m_dwTypeExpected)
|
|
{
|
|
regErrorNew.m_ret = RET_VALUEWRONGTYPE;
|
|
}
|
|
else if (regErrorNew.m_dwActualSize != regErrorNew.m_dwExpectedSize)
|
|
{
|
|
regErrorNew.m_ret = RET_VALUEWRONGDATA;
|
|
}
|
|
else if (!EqualMemory(regErrorNew.m_bExpected, regErrorNew.m_bActual, regErrorNew.m_dwActualSize))
|
|
{
|
|
regErrorNew.m_ret = RET_VALUEWRONGDATA;
|
|
}
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
if (regErrorNew.m_ret == RET_NOERROR)
|
|
return S_OK;
|
|
else
|
|
return AddError(ppRegErrorFirst, ®ErrorNew);
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* AddError - Allocate a RegError node, copy data from pRegErrorNew, and
|
|
* insert the node at the beginning of the ppRegErrorFirst linked list.
|
|
*
|
|
****************************************************************************/
|
|
HRESULT AddError(RegError** ppRegErrorFirst, RegError* pRegErrorNew)
|
|
{
|
|
RegError* pRegErrorInsert;
|
|
|
|
pRegErrorInsert = new RegError;
|
|
if (pRegErrorInsert == NULL)
|
|
return E_OUTOFMEMORY;
|
|
*pRegErrorInsert = *pRegErrorNew;
|
|
pRegErrorInsert->m_pRegErrorNext = *ppRegErrorFirst;
|
|
*ppRegErrorFirst = pRegErrorInsert;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* EqualMemory
|
|
*
|
|
****************************************************************************/
|
|
BOOL EqualMemory(BYTE* pb1, BYTE* pb2, DWORD numBytes)
|
|
{
|
|
while (numBytes > 0)
|
|
{
|
|
if (*pb1 != *pb2)
|
|
return FALSE;
|
|
pb1++;
|
|
pb2++;
|
|
numBytes--;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* DestroyReg
|
|
*
|
|
****************************************************************************/
|
|
VOID DestroyReg( RegError** ppRegErrorFirst )
|
|
{
|
|
if( ppRegErrorFirst && *ppRegErrorFirst )
|
|
{
|
|
RegError* pRegError;
|
|
RegError* pRegErrorNext;
|
|
|
|
for (pRegError = *ppRegErrorFirst; pRegError != NULL;
|
|
pRegError = pRegErrorNext)
|
|
{
|
|
pRegErrorNext = pRegError->m_pRegErrorNext;
|
|
delete pRegError;
|
|
}
|
|
|
|
*ppRegErrorFirst = NULL;
|
|
}
|
|
}
|