mirror of https://github.com/lianthony/NT4.0
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.
603 lines
21 KiB
603 lines
21 KiB
|
|
// REGISTRY.CPP
|
|
#include "common.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Path to store the keys in the Registry
|
|
const TCHAR szRegistryPathDefault[] = _W"Software\\Microsoft\\"szAPPNAME;
|
|
const TCHAR szRegistryMachinePathDefault[] = _W"Software\\Microsoft\\"szAPPNAME"\\Parameters";
|
|
const TCHAR szRegistryPathTemplate[] = _W"Software\\Microsoft\\"szAPPNAME"\\%s";
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Keys to store into the registry
|
|
const TCHAR szRegWindowPosition[] = _W"WindowPosition";
|
|
const TCHAR szRpcBufferAlloc[] = _W"RpcBufferAlloc";
|
|
const TCHAR szRefreshThreads[] = _W"RefreshThreads";
|
|
const TCHAR szAutoRefreshEnabled[] = _W"AutoRefreshEnabled";
|
|
const TCHAR szRefreshInterval[] = _W"RefreshInterval";
|
|
const TCHAR szAllowDuplicates[] = _W"AllowDuplicates";
|
|
const TCHAR szExposeClass[] = _W"ExposeClass";
|
|
const TCHAR szExposeTTL[] = _W"ExposeTTL";
|
|
const TCHAR szShowAutoZones[] = _W"ShowAutoCreatedZones";
|
|
#ifdef DEBUG
|
|
const TCHAR szDbgShowAssertDialog[] = _W"DbgShowAssertDialog";
|
|
const TCHAR szDbgShowReportDialog[] = _W"DbgShowUnsualSituationDialog";
|
|
const TCHAR szDbgBeepOnFailure[] = _W"DbgBeepOnFailure";
|
|
const TCHAR szDbgTraceFlags[] = _W"DbgTraceFlags";
|
|
const TCHAR szDbgEnableSourceTracking[] = _W"DbgEnableSourceTracking";
|
|
const TCHAR szDbgExpandPathName[] = _W"DbgExpandPathName";
|
|
const TCHAR szDbgSendToDbWin[] = _W"DbgSendToDbWin";
|
|
const TCHAR szDbgSendToDebugger[] = _W"DbgSendToDebugger";
|
|
const TCHAR szDbgMemAllocSkip[] = _W"DbgMemAllocSkip";
|
|
const TCHAR szDbgMemAllocFail[] = _W"DbgMemAllocFail";
|
|
const TCHAR szDbgResourceLoadSkip[] = _W"DbgResourceLoadSkip";
|
|
const TCHAR szDbgResourceLoadFail[] = _W"DbgResourceLoadFail";
|
|
#endif // DEBUG
|
|
#ifdef DBWIN
|
|
const TCHAR szDbgDbWinInfo[] = _W"DbgDbWinInfo";
|
|
#endif // DBWIN
|
|
#ifdef STRESS
|
|
const TCHAR szDbgStressServerName[] = _W"DbgStressServerName";
|
|
#endif // STRESS
|
|
|
|
// Strictly Local Variables
|
|
static HKEY hkeyRegistry; // Primary Registry key
|
|
static HKEY hkeyTemp; // Cached Registry key
|
|
struct REGBINARYINFO // Binary Info Structure
|
|
{
|
|
DWORD dwCheckSum;
|
|
BYTE rgbData[128];
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Strictly Local Prototypes
|
|
static void FillRegBinaryInfo(REGBINARYINFO * pregbinaryinfo, const BYTE rgbData[], DWORD cbData);
|
|
static DWORD ComputeXorCheckSum(const BYTE rgbData[], DWORD cbData);
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// ReadIniFileInfo()
|
|
//
|
|
// Open the Registry (.ini file) and read the global settings
|
|
// If the Registry Path "Software\\Microsoft\\szAPPNAME" does
|
|
// not exists, function ReadIniFile will create it.
|
|
//
|
|
void ReadIniFileInfo(
|
|
const TCHAR pszSubKeyRoot[]) // IN: Allow a different key. pszSubKeyRoot may be NULL.
|
|
{
|
|
TCHAR szRegPath[256]; // Buffer to hold the a key in the Registry Path
|
|
DWORD dwDisposition;
|
|
LONG lRetCode; // Code returned by the Registry functions
|
|
|
|
Assert(hkeyRegistry == NULL); // Verify the Registry has not been opened yet
|
|
// pszSubKeyRoot allows the user to have multiple configurations
|
|
// The pszSubKeyRoot comes from the command line /R:[pszSubKeyRoot]
|
|
// Typically pszSubKeyRoot is NULL.
|
|
if (pszSubKeyRoot)
|
|
{
|
|
// Build the _RegistryPath_ "Software\\Microsoft\\szAPPNAME\\[pszSubKeyRoot]"
|
|
TCHAR szSubKeyT[64]; // Mazimum length of the SubKey
|
|
|
|
strncpy(szSubKeyT, pszSubKeyRoot, LENGTH(szSubKeyT)-1);
|
|
szSubKeyT[63]=0; // Put a Null-terminator at the end of the string
|
|
wsprintf(szRegPath, szRegistryPathTemplate, szSubKeyT);
|
|
}
|
|
|
|
lRetCode=RegCreateKeyEx(
|
|
HKEY_CURRENT_USER,
|
|
pszSubKeyRoot ? szRegPath : szRegistryPathDefault, // Key to open
|
|
0, // Reserved, must be zero
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL, // SecurityAttributes
|
|
&hkeyRegistry, // OUT: returned handle
|
|
&dwDisposition); // OUT: returned disposition
|
|
ReportFSz1(
|
|
lRetCode == ERROR_SUCCESS,
|
|
"Unable to create Registry key '%s'.",
|
|
pszSubKeyRoot ? szRegPath : szRegistryPathDefault);
|
|
if (hkeyRegistry == NULL) // This should *never* happen
|
|
{
|
|
ReportSz("hkeyRegistry == NULL");
|
|
return;
|
|
}
|
|
if (dwDisposition == REG_CREATED_NEW_KEY)
|
|
{
|
|
// If a new key has been created, there is no need to try to
|
|
// read information from the Registry because nothing has
|
|
// been saved into the registry.
|
|
goto SetDefaultStrings;
|
|
}
|
|
RegReadBinary(szRegWindowPosition, &mainwindowposition,
|
|
sizeof(mainwindowposition));
|
|
RegReadInt(szRpcBufferAlloc, OUT (int&)cbDnsRpcBufferAlloc,
|
|
1*1024, 1024*1024);
|
|
RegReadInt(szRefreshThreads, OUT ServerList.m_cRefreshThreads, 1, 100);
|
|
SetDefaultStrings:
|
|
;
|
|
|
|
hkeyTemp = hkeyRegistry;
|
|
lRetCode=RegCreateKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
szRegistryMachinePathDefault, // Key to open
|
|
0, // Reserved, must be zero
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL, // SecurityAttributes
|
|
&hkeyRegistry, // OUT: returned handle
|
|
&dwDisposition); // OUT: returned disposition
|
|
ReportFSz1(
|
|
lRetCode == ERROR_SUCCESS,
|
|
"Unable to create Registry key '%s'.",
|
|
szRegistryMachinePathDefault);
|
|
if (hkeyRegistry == NULL) // This should *never* happen
|
|
{
|
|
ReportSz("hkeyRegistry == NULL");
|
|
return;
|
|
}
|
|
if (dwDisposition == REG_CREATED_NEW_KEY)
|
|
{
|
|
// If a new key has been created, there is no need to try to
|
|
// read information from the Registry because nothing has
|
|
// been saved into the registry.
|
|
goto SetDefaultPrefs;
|
|
}
|
|
RegReadInt(szRefreshInterval, OUT (int &)dnsoptions.iRefreshInterval,
|
|
0,0); //no range checking
|
|
RegReadBool(szAutoRefreshEnabled, dnsoptions.fAutoRefreshEnabled);
|
|
RegReadBool(szAllowDuplicates, dnsoptions.fAllowDups);
|
|
RegReadBool(szExposeTTL, dnsoptions.fExposeTTL);
|
|
RegReadBool(szExposeClass, dnsoptions.fExposeClass);
|
|
RegReadBool(szShowAutoZones, dnsoptions.fShowAutoCreateZones);
|
|
|
|
SetDefaultPrefs:
|
|
;
|
|
|
|
HKEY x = hkeyRegistry;
|
|
hkeyRegistry = hkeyTemp;
|
|
hkeyTemp = x;
|
|
// NOTE: at this point hkeyRegistry points to the current user key,
|
|
// and hkeyTemp is the machine key. this must be the
|
|
// case when Write...() is called.
|
|
} // ReadIniFileInfo
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// WriteIniFileInfo()
|
|
//
|
|
// Save global settings in the Registry (.ini) file and
|
|
// close the Registry.
|
|
//
|
|
void WriteIniFileInfo()
|
|
{
|
|
RECT rc;
|
|
|
|
if (hkeyRegistry == NULL)
|
|
{
|
|
// Do something for retail build
|
|
ReportSz("Cannot write to Registry - Registry key not created");
|
|
return;
|
|
}
|
|
// The Registry has been opened
|
|
Assert(hkeyRegistry);
|
|
Assert(hkeyTemp);
|
|
|
|
if (!IsIconic(hwndMain)) {
|
|
GetWindowRect(hwndMain, &rc);
|
|
mainwindowposition.x = rc.left;
|
|
mainwindowposition.y = rc.top;
|
|
mainwindowposition.cx = rc.right - rc.left;
|
|
mainwindowposition.cy = rc.bottom - rc.top;
|
|
}
|
|
RegWriteBinary(szRegWindowPosition, &mainwindowposition, sizeof(mainwindowposition));
|
|
RegWriteInt(szRpcBufferAlloc, cbDnsRpcBufferAlloc);
|
|
RegWriteInt(szRefreshThreads, ServerList.m_cRefreshThreads);
|
|
ServerList.SaveConfig();
|
|
// Therefore it can be closed
|
|
SideAssert(RegCloseKey(hkeyRegistry) == ERROR_SUCCESS);
|
|
|
|
hkeyRegistry = hkeyTemp; // get back the cur. user key.
|
|
|
|
RegWriteInt(szRefreshInterval, dnsoptions.iRefreshInterval);
|
|
RegWriteInt(szAutoRefreshEnabled, dnsoptions.fAutoRefreshEnabled);
|
|
RegWriteInt(szAllowDuplicates, dnsoptions.fAllowDups);
|
|
RegWriteInt(szExposeTTL, dnsoptions.fExposeTTL);
|
|
RegWriteInt(szExposeClass, dnsoptions.fExposeClass);
|
|
RegWriteInt(szShowAutoZones, dnsoptions.fShowAutoCreateZones);
|
|
|
|
// done with the machine key, so close it
|
|
SideAssert(RegCloseKey(hkeyRegistry) == ERROR_SUCCESS);
|
|
|
|
// Set the handle to NULL to provoke an Assert if attempting to use it
|
|
DebugCode(hkeyRegistry=NULL);
|
|
DebugCode(hkeyTemp=NULL);
|
|
} // WriteIniFileInfo
|
|
|
|
|
|
#ifdef DEBUG
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// DbgReadIniFileInfo()
|
|
//
|
|
// Open the Registry (.ini file) and read the global debug settings.
|
|
// If the Registry Path "Software\\Microsoft\\szAPPNAME" does
|
|
// not exists, the function does nothing.
|
|
//
|
|
void DbgReadIniFileInfo(
|
|
const TCHAR pszSubKeyRoot[]) // IN: Allow a different key. pszSubKeyRoot may be NULL.
|
|
{
|
|
TCHAR szRegPath[256]; // Buffer to hold the a key in the Registry Path
|
|
LONG lRetCode; // Code returned by the Registry functions
|
|
|
|
Assert(hkeyRegistry == NULL); // Verify the Registry has not been opened yet
|
|
// pszSubKeyRoot allows the user to have multiple configurations
|
|
// The pszSubKeyRoot comes from the command line /R:[pszSubKeyRoot]
|
|
// Typically pszSubKeyRoot is NULL.
|
|
if (pszSubKeyRoot)
|
|
{
|
|
// Build the _RegistryPath_ "Software\\Microsoft\\szAPPNAME\\[pszSubKeyRoot]"
|
|
TCHAR szSubKeyT[64]; // Mazimum length of the SubKey
|
|
|
|
strncpy(szSubKeyT, pszSubKeyRoot, LENGTH(szSubKeyT)-1);
|
|
szSubKeyT[63]=0; // Put a Null-terminator at the end of the string
|
|
wsprintf(szRegPath, szRegistryPathTemplate, szSubKeyT);
|
|
}
|
|
|
|
lRetCode=RegOpenKeyEx(
|
|
HKEY_CURRENT_USER,
|
|
pszSubKeyRoot ? szRegPath : szRegistryPathDefault, // Key to open, // Key to open
|
|
0, // Reserved, must be zero
|
|
KEY_READ, // Access mask
|
|
&hkeyRegistry); // OUT: returned handle
|
|
if (lRetCode != ERROR_SUCCESS)
|
|
{
|
|
Assert(hkeyRegistry == NULL);
|
|
return;
|
|
}
|
|
|
|
RegReadInt(szDbgShowAssertDialog, OUT fShowAssertDialog);
|
|
RegReadInt(szDbgShowReportDialog, OUT fShowReportDialog);
|
|
RegReadBool(szDbgBeepOnFailure, OUT fBeepOnFailure);
|
|
RegReadInt(szDbgTraceFlags, OUT (int&)dwTraceFlags);
|
|
RegReadInt(szDbgEnableSourceTracking, OUT fEnableSourceTracking);
|
|
RegReadInt(szDbgExpandPathName, OUT fExpandPathName);
|
|
RegReadInt(szDbgSendToDbWin, OUT fSendSzToDbWinEdit);
|
|
RegReadInt(szDbgSendToDebugger, OUT fSendSzToDebugger);
|
|
|
|
RegReadInt(szDbgResourceLoadSkip, OUT cResourceLoadSkip);
|
|
RegReadInt(szDbgResourceLoadFail, OUT cResourceLoadFail);
|
|
#ifdef STRESS
|
|
RegReadSz(szDbgStressServerName, g_szDbgStressServer, sizeof(g_szDbgStressServer));
|
|
#endif // STRESS
|
|
#ifdef DBWIN
|
|
Assert(dbwinreginfo.wpl.length != wplMagicKey);
|
|
RegReadBinary(szDbgDbWinInfo, OUT &dbwinreginfo, sizeof(dbwinreginfo));
|
|
if (dbwinreginfo.wpl.length == wplMagicKey)
|
|
{
|
|
dbwinreginfo.wpl.length = sizeof(dbwinreginfo.wpl);
|
|
SetWindowPlacement(hwndDbWin, &dbwinreginfo.wpl);
|
|
SetWindowPos(hwndDbWin, (dbwinreginfo.fTopMost ? HWND_TOPMOST : HWND_NOTOPMOST),
|
|
0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
|
|
}
|
|
else
|
|
{
|
|
ShowWindow(hwndDbWin, SW_SHOWNORMAL);
|
|
}
|
|
#endif // DBWIN
|
|
|
|
// The Registry has been opened, therefore it can be closed.
|
|
SideAssert(RegCloseKey(hkeyRegistry) == ERROR_SUCCESS);
|
|
// Set the handle to NULL to provoke an Assert if attempting to use it
|
|
DebugCode(hkeyRegistry=NULL);
|
|
} // DbgReadIniFileInfo
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// DbgWriteIniFileInfo()
|
|
//
|
|
// Save global settings in the Registry (.ini) file and
|
|
// close the Registry.
|
|
//
|
|
void DbgWriteIniFileInfo()
|
|
{
|
|
ReportFSz(hkeyRegistry, "Registry not openned");
|
|
if (hkeyRegistry == NULL)
|
|
return;
|
|
#ifdef DBWIN
|
|
dbwinreginfo.wpl.length = sizeof(dbwinreginfo.wpl);
|
|
GetWindowPlacement(hwndDbWin, &dbwinreginfo.wpl);
|
|
dbwinreginfo.wpl.length = wplMagicKey;
|
|
if (!IsWindowVisible(hwndDbWin))
|
|
dbwinreginfo.wpl.showCmd = SW_HIDE;
|
|
RegWriteBinary(szDbgDbWinInfo, &dbwinreginfo, sizeof(dbwinreginfo));
|
|
#endif // DBWIN
|
|
#ifdef STRESS
|
|
RegWriteSz(szDbgStressServerName, g_szDbgStressServer);
|
|
#endif // STRESS
|
|
RegWriteInt(szDbgShowAssertDialog, fShowAssertDialog);
|
|
RegWriteInt(szDbgShowReportDialog, fShowReportDialog);
|
|
RegWriteInt(szDbgBeepOnFailure, fBeepOnFailure);
|
|
RegWriteInt(szDbgTraceFlags, (int)dwTraceFlags);
|
|
RegWriteInt(szDbgEnableSourceTracking, fEnableSourceTracking);
|
|
RegWriteInt(szDbgExpandPathName, fExpandPathName);
|
|
RegWriteInt(szDbgSendToDbWin, fSendSzToDbWinEdit);
|
|
RegWriteInt(szDbgSendToDebugger, fSendSzToDebugger);
|
|
|
|
RegWriteInt(szDbgResourceLoadSkip, cResourceLoadSkip);
|
|
RegWriteInt(szDbgResourceLoadFail, cResourceLoadFail);
|
|
|
|
} // DbgWriteIniFileInfo
|
|
#endif // DEBUG
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// RegReadInt()
|
|
//
|
|
// Get an integer from Registry (.INI file)
|
|
// Ensure that the value is in range nMin..nMax. If both nMin and nMost are zero, there is
|
|
// no range checking. nData may be positive or negative.
|
|
// If key is not found or the value is out of range, nData remains unmodified
|
|
//
|
|
void RegReadInt(
|
|
const TCHAR szKey[], // IN: Key being sought
|
|
int &nData, // OUT: Value returned (if found in .ini file)
|
|
int nMin, // IN: Minimum of allowable range
|
|
int nMost) // IN: Maximum of allowable range
|
|
{
|
|
LONG lRetCode; // Return code
|
|
DWORD dwType; // Data type returned by RegQueryValueEx
|
|
DWORD cbValue; // Number of bytes copied by RegQueryValueEx
|
|
int nDataT;
|
|
|
|
Assert(szKey);
|
|
Assert(nMin <= nMost); // Extra checking for consistency
|
|
Assert(hkeyRegistry != NULL); // Verify the Registry has been opened
|
|
cbValue = sizeof(nDataT);
|
|
lRetCode = RegQueryValueEx(hkeyRegistry, (TCHAR *)szKey, 0,
|
|
&dwType, (LPBYTE)&nDataT, &cbValue);
|
|
#ifdef DEBUG
|
|
ReportFSz(lRetCode != ERROR_MORE_DATA, "RegReadInt() - Buffer is too small");
|
|
if (lRetCode == ERROR_SUCCESS)
|
|
{
|
|
ReportFSz(dwType == REG_DWORD, "RegReadInt() - dwType should be REG_DWORD");
|
|
}
|
|
#endif // DEBUG
|
|
if (lRetCode == ERROR_SUCCESS && dwType == REG_DWORD)
|
|
{
|
|
Assert(cbValue == sizeof(nDataT));
|
|
if ((nDataT >= nMin && nDataT <= nMost) || (nMin == 0 && nMost == 0))
|
|
nData = nDataT;
|
|
}
|
|
} // RegReadInt
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// RegReadBool()
|
|
//
|
|
// Get a boolean value from Registry (.INI file)
|
|
// If key is not found or the value is out of range, fData remains unmodified
|
|
//
|
|
void RegReadBool(
|
|
const TCHAR szKey[], // IN: Key being sought
|
|
BOOL& fData) // OUT: Value returned (if found in .ini file)
|
|
{
|
|
RegReadInt(szKey, fData, 0, 1);
|
|
} // RegReadBool
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// RegReadSz()
|
|
//
|
|
// Get a string from the Registry (.INI file)
|
|
// To replace GetPrivateProfileString()
|
|
// Return TRUE iff content of szValue is valid (ie, key found in registry
|
|
// and dwType==REG_SZ); otherwise return FALSE
|
|
//
|
|
BOOL RegReadSz(
|
|
const TCHAR szKey[], // IN: Key to query
|
|
TCHAR szValue[], // OUT: Value of the key returned
|
|
DWORD cbValue) // IN: Size (in bytes) of the buffer szValue
|
|
{
|
|
LONG lRetCode; // Return code
|
|
DWORD dwType; // Data type returned by RegQueryValueEx
|
|
|
|
Assert(hkeyRegistry != NULL); // Verify the Registry has been opened
|
|
Assert(szKey);
|
|
Assert(szValue);
|
|
lRetCode=RegQueryValueEx(hkeyRegistry, (TCHAR *)szKey, 0, &dwType, (LPBYTE)szValue, &cbValue);
|
|
#ifdef DEBUG
|
|
ReportFSz(lRetCode != ERROR_MORE_DATA, "RegReadSz() - Buffer is too small");
|
|
if (lRetCode == ERROR_SUCCESS)
|
|
{
|
|
Assert((DWORD)lstrlen(szValue) == cbValue-1); // Consistency check
|
|
ReportFSz(dwType == REG_SZ, "RegReadSz() - dwType should be REG_SZ");
|
|
}
|
|
#endif // DEBUG
|
|
return ((lRetCode == ERROR_SUCCESS) && (dwType == REG_SZ));
|
|
} // RegReadSz
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// RegReadBinary()
|
|
//
|
|
// Read an array of bytes from the Registry.
|
|
// - If the key szKey is not found, pvData remain unchanged
|
|
// - Before copying the data into pvData, RegReadBinary computes
|
|
// the XOR checksum of the data read. If the checksum mismatch,
|
|
// pvData remain unchanged.
|
|
// - cbData must be divisible by 4
|
|
// Return TRUE iff pvData has been modified (ie, key found in registry
|
|
// and checksum valid); otherwise return FALSE.
|
|
//
|
|
BOOL RegReadBinary(
|
|
const TCHAR szKey[], // IN: Key to save
|
|
void * const pvData, // OUT: Data to read (if found in Registry)
|
|
DWORD cbData) // IN: Number of bytes to save (sizeof pvData)
|
|
{
|
|
REGBINARYINFO regbinaryinfo;
|
|
LONG lRetCode; // Return code
|
|
DWORD dwType; // Data type returned by RegQueryValueEx
|
|
DWORD cbDataRead = sizeof(regbinaryinfo.dwCheckSum) + cbData;
|
|
|
|
Assert(hkeyRegistry != NULL); // Verify the Registry has been opened
|
|
Assert(szKey);
|
|
Assert(pvData);
|
|
Assert(cbData < sizeof(regbinaryinfo.rgbData));
|
|
Assert((cbData & 0x0003) == 0);
|
|
lRetCode=RegQueryValueEx(hkeyRegistry, (TCHAR *)szKey, 0, &dwType,
|
|
(LPBYTE)®binaryinfo, &cbDataRead);
|
|
#ifdef DEBUG
|
|
ReportFSz(lRetCode != ERROR_MORE_DATA, "RegReadBinary() - Buffer is too small");
|
|
ReportFSz(cbDataRead == sizeof(regbinaryinfo.dwCheckSum) + cbData,
|
|
"RegReadBinary() - cbDataRead != cbDataRequested");
|
|
if (lRetCode == ERROR_SUCCESS)
|
|
{
|
|
ReportFSz(dwType == REG_BINARY, "RegReadBinary() - dwType should be REG_BINARY");
|
|
ReportFSz(regbinaryinfo.dwCheckSum == ComputeXorCheckSum(regbinaryinfo.rgbData, cbData),
|
|
"RegReadBinary() - Invalid CheckSum");
|
|
}
|
|
#endif // DEBUG
|
|
if (lRetCode == ERROR_SUCCESS &&
|
|
dwType == REG_BINARY &&
|
|
cbDataRead == sizeof(regbinaryinfo.dwCheckSum) + cbData &&
|
|
regbinaryinfo.dwCheckSum == ComputeXorCheckSum(regbinaryinfo.rgbData, cbData))
|
|
{
|
|
// Copy the information into rgbData
|
|
memcpy(pvData, regbinaryinfo.rgbData, cbData);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
} // RegReadBinary
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// RegWriteInt()
|
|
//
|
|
// Write an int into the Registry.
|
|
// Stores the integer in its binary format (ie, DWORD).
|
|
// nValue may be positive or negative.
|
|
// This function will throw an exception if an error occurs.
|
|
// Note: This function may also be used to write a bool
|
|
//
|
|
void RegWriteInt(
|
|
const TCHAR szKey[], // IN: Key to save
|
|
int nValue) // IN: Value of the key
|
|
{
|
|
LONG lRetCode; // Return code
|
|
|
|
Assert(szKey);
|
|
Assert(hkeyRegistry != NULL); // Verify the Registry has been opened
|
|
lRetCode=RegSetValueEx(hkeyRegistry, szKey, 0, REG_DWORD,
|
|
(LPBYTE)&nValue, sizeof(nValue));
|
|
// There should be no error writing in the Registry
|
|
ReportFSz(lRetCode == ERROR_SUCCESS, "RegWriteInt() - Error writing in Registry");
|
|
} // RegWriteInt
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// RegWriteSz()
|
|
//
|
|
// Write a string to the Registry (.INI file)
|
|
// To replace WritePrivateProfileString()
|
|
// This function will throw an exception if an error occurs.
|
|
// Return TRUE if key was found in registry (ie, pvData has been modified)
|
|
// otherwise return FALSE
|
|
//
|
|
void RegWriteSz(
|
|
const TCHAR szKey[], // IN: Key to save
|
|
const TCHAR szValue[]) // IN: Value of the key
|
|
{
|
|
LONG lRetCode; // Return code
|
|
|
|
Assert(hkeyRegistry != NULL); // Verify Registry has been opened
|
|
Assert(szKey);
|
|
Assert(szValue);
|
|
lRetCode=RegSetValueEx(hkeyRegistry, szKey, 0, REG_SZ,
|
|
(LPBYTE)szValue, lstrlen(szValue) + 1);
|
|
// There should be no error writing in the Registry
|
|
ReportFSz1(lRetCode == ERROR_SUCCESS, "RegWriteSz() - Error writing in Registry (err=%d)", lRetCode);
|
|
} // RegWriteSz
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// RegWriteBinary()
|
|
//
|
|
// Write an array of bytes to the Registry
|
|
// Before saving pvData, the XOR checksum of pvData is computed and
|
|
// written to the Registry. Then the array is saved. This XOR checksum
|
|
// is used to validate the data.
|
|
// NOTE: cbData must be divisible by 4
|
|
// This function will throw an exception if an error occurs.
|
|
//
|
|
void RegWriteBinary(
|
|
const TCHAR szKey[], // IN: Key to save
|
|
const void * const pvData, // IN: Data to save
|
|
DWORD cbData) // IN: Number of bytes to save (sizeof pvData)
|
|
{
|
|
REGBINARYINFO regbinaryinfo;
|
|
LONG lRetCode; // Return code
|
|
|
|
Assert(hkeyRegistry != NULL); // Verify the Registry has been opened
|
|
Assert(szKey);
|
|
Assert(cbData < sizeof(regbinaryinfo.rgbData));
|
|
Assert(pvData != NULL);
|
|
FillRegBinaryInfo(®binaryinfo, (BYTE*)pvData, cbData);
|
|
lRetCode=RegSetValueEx(hkeyRegistry, szKey, 0, REG_BINARY,
|
|
(LPBYTE)®binaryinfo, sizeof(regbinaryinfo.dwCheckSum) + cbData);
|
|
// There should be no error writing in the Registry
|
|
ReportFSz(lRetCode == ERROR_SUCCESS, "RegWriteBinary() - Error writing in Registry");
|
|
} // RegWriteBinary
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// ComputeXorCheckSum()
|
|
//
|
|
// Returns the XOR checksum of the array rgbData
|
|
// NOTE: cbData must be divisible by 4
|
|
//
|
|
static DWORD ComputeXorCheckSum(
|
|
const BYTE rgbData[], // IN: Array of the buffer
|
|
DWORD cbData) // IN: Sizeof (in bytes) of the buffer rgbData
|
|
{
|
|
DWORD dwCheckSum = 0;
|
|
DWORD * lpdw = (DWORD *)rgbData;
|
|
|
|
Assert(rgbData != NULL);
|
|
Assert((cbData & 0x0003) == 0); // Verify if cbData is a multiple of 4
|
|
cbData >>= 2; // Divide cbData by 4
|
|
while (cbData--)
|
|
dwCheckSum ^= *lpdw++;
|
|
return(dwCheckSum);
|
|
} // ComputeXorCheckSum
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// FillRegBinaryInfo()
|
|
//
|
|
// Computes the XOR checksum of array rgbData and copy rgbData into
|
|
// the structure REGBINARYINFO.
|
|
// NOTE: cbData must be divisible by 4
|
|
//
|
|
static void FillRegBinaryInfo(
|
|
REGBINARYINFO * pregbinaryinfo, // OUT: Binary info structure
|
|
const BYTE rgbData[], // IN: Array of the buffer
|
|
DWORD cbData) // IN: Sizeof (in bytes) of the buffer rgbData
|
|
{
|
|
Assert(pregbinaryinfo != NULL);
|
|
Assert(rgbData != NULL);
|
|
Assert((cbData & 0x0003)==0); // Verify if cbData is a multiple of 4
|
|
Assert(cbData < sizeof(pregbinaryinfo->rgbData));
|
|
|
|
DWORD * lpdwSrc = (DWORD *)rgbData;
|
|
DWORD * lpdwDest = (DWORD *)pregbinaryinfo->rgbData;
|
|
|
|
cbData >>= 2; // Divide cbData by 4
|
|
pregbinaryinfo->dwCheckSum = 0;
|
|
while (cbData--)
|
|
{
|
|
pregbinaryinfo->dwCheckSum ^= *lpdwSrc;
|
|
*lpdwDest++ = *lpdwSrc++;
|
|
}
|
|
} // FillRegBinaryInfo
|
|
|