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.
906 lines
33 KiB
906 lines
33 KiB
//Copyright (c) 1998 - 1999 Microsoft Corporation
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
*
|
|
* Module Name:
|
|
*
|
|
* Registry.cpp
|
|
*
|
|
* Abstract:
|
|
*
|
|
* Registry.cpp: implementation of the CRegistry class.
|
|
* This class helps with registry by allocating memory by itself
|
|
* As a result caller must copy the pointer returned by Get functions
|
|
* immediately.
|
|
*
|
|
*
|
|
*
|
|
* Author:
|
|
*
|
|
* Makarand Patwardhan - April 9, 1997
|
|
*
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
|
|
#include "stdafx.h"
|
|
#include "Registry.h"
|
|
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* Constructor
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
CRegistry::CRegistry()
|
|
{
|
|
m_pMemBlock = NULL;
|
|
m_hKey = NULL;
|
|
m_iEnumIndex = -1;
|
|
m_iEnumValueIndex = -1;
|
|
|
|
#ifdef DBG
|
|
m_dwSizeDebugOnly = 0;
|
|
#endif
|
|
}
|
|
|
|
|
|
CRegistry::CRegistry(HKEY hKey)
|
|
{
|
|
m_pMemBlock = NULL;
|
|
m_hKey = hKey;
|
|
m_iEnumIndex = -1;
|
|
m_iEnumValueIndex = -1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* Destructor
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
CRegistry::~CRegistry()
|
|
{
|
|
if (m_hKey != NULL)
|
|
{
|
|
RegCloseKey(m_hKey);
|
|
m_hKey = NULL;
|
|
}
|
|
Release();
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* void Allocate (DWORD dwSize)
|
|
* This private function is used for allocating the memory for
|
|
* reading registry
|
|
* returns the pointer to memory allocated.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
void *CRegistry::Allocate (DWORD dwSize)
|
|
{
|
|
if (m_pMemBlock)
|
|
Release();
|
|
|
|
m_pMemBlock = new BYTE[dwSize];
|
|
|
|
#ifdef DBG
|
|
// remember the size of the block to be allocated.
|
|
m_dwSizeDebugOnly = dwSize;
|
|
#endif
|
|
|
|
return m_pMemBlock;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* void Release ()
|
|
* This private function is used for releasing internal memory block
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
void CRegistry::Release ()
|
|
{
|
|
if (m_pMemBlock)
|
|
{
|
|
|
|
#ifdef DBG
|
|
// fistly fill up the block we allocated previously with garbage.
|
|
// so that if anybody is using this block, it is more lilely to
|
|
// catch the bug.
|
|
FillMemory(m_pMemBlock, m_dwSizeDebugOnly, 'c');
|
|
m_dwSizeDebugOnly = 0;
|
|
|
|
#endif
|
|
|
|
delete [] m_pMemBlock;
|
|
}
|
|
|
|
m_pMemBlock = 0;
|
|
}
|
|
|
|
|
|
///*--------------------------------------------------------------------------------------------------------
|
|
//* DWORD CRegistry::CreateKey(HKEY hKey, LPCTSTR lpSubKey, REGSAM access /*= KEY_ALL_ACCESS*/, DWORD *pDisposition /*= NULL*/, LPSECURITY_ATTRIBUTES lpSecAttr /* = NULL */)
|
|
//* opens/creates the key specified. before attempting any operation on any key/value. this function
|
|
//* must be called.
|
|
//* hKey - hive
|
|
//* lpSubKey - Path of the key in the format _T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server")
|
|
//* access - access desired. like REG_READ, REG_WRITE..
|
|
//* RETURNS error code.
|
|
//* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::CreateKey(HKEY hKey, LPCTSTR lpSubKey, REGSAM access /*= KEY_ALL_ACCESS*/, DWORD *pDisposition /*= NULL*/, LPSECURITY_ATTRIBUTES lpSecAttr /* = NULL */)
|
|
{
|
|
ASSERT(lpSubKey);
|
|
ASSERT(*lpSubKey != '\\');
|
|
|
|
// security descriptor should be null or it should be a valid one.
|
|
ASSERT(!lpSecAttr || IsValidSecurityDescriptor(lpSecAttr->lpSecurityDescriptor));
|
|
|
|
ASSERT(lpSubKey);
|
|
ASSERT(*lpSubKey != '\\');
|
|
|
|
if (m_hKey != NULL)
|
|
{
|
|
RegCloseKey(m_hKey);
|
|
m_hKey = NULL;
|
|
}
|
|
|
|
DWORD dwDisposition;
|
|
LONG lResult = RegCreateKeyEx(
|
|
hKey, // handle of an open key
|
|
lpSubKey, // address of subkey name
|
|
0, // reserved
|
|
NULL, // address of class string
|
|
REG_OPTION_NON_VOLATILE , // special options flag
|
|
access, // desired security access
|
|
lpSecAttr, // address of key security structure
|
|
&m_hKey, // address of buffer for opened handle
|
|
&dwDisposition // address of disposition value buffer
|
|
);
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
{
|
|
m_hKey = NULL;
|
|
}
|
|
|
|
if (pDisposition)
|
|
*pDisposition = dwDisposition;
|
|
|
|
return lResult;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD OpenKey(HKEY hKey, LPCTSTR lpSubKey, REGSAM access) ()
|
|
* opens the key specified. before attempting any operation on any key/value. this function
|
|
* must be called.
|
|
* hKey - hive
|
|
* lpSubKey - Path of the key in the format _T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server")
|
|
* access - access desired. like REG_READ, REG_WRITE..
|
|
* lpMachineName - machine name if registry is to be opened on remote machine.
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::OpenKey(HKEY hKey, LPCTSTR lpSubKey, REGSAM access /*= KEY_ALL_ACCESS*/, LPCTSTR lpMachineName /* = NULL */)
|
|
{
|
|
LONG lResult;
|
|
ASSERT(lpSubKey);
|
|
ASSERT(*lpSubKey != '\\');
|
|
LPTSTR szCompName = NULL;
|
|
|
|
|
|
if (lpMachineName)
|
|
{
|
|
// if remote name is specified, hkey must be one of following.
|
|
ASSERT(hKey == HKEY_LOCAL_MACHINE || hKey == HKEY_USERS || hKey == HKEY_PERFORMANCE_DATA);
|
|
|
|
szCompName = new TCHAR[_tcslen(lpMachineName) + 3];
|
|
if (!szCompName)
|
|
return ERROR_OUTOFMEMORY;
|
|
|
|
_tcscpy(szCompName, _T(""));
|
|
if (*lpMachineName != '\\')
|
|
{
|
|
ASSERT(*(lpMachineName + 1) != '\\');
|
|
_tcscpy(szCompName, _T("\\\\"));
|
|
}
|
|
|
|
_tcscat(szCompName, lpMachineName);
|
|
|
|
// now connect to the remote computer.
|
|
lResult = RegConnectRegistry (szCompName, hKey, &hKey);
|
|
if (ERROR_SUCCESS != lResult)
|
|
{
|
|
delete [] szCompName;
|
|
return lResult;
|
|
}
|
|
}
|
|
|
|
if (m_hKey != NULL)
|
|
{
|
|
RegCloseKey(m_hKey);
|
|
m_hKey = NULL;
|
|
}
|
|
|
|
lResult = RegOpenKeyEx(
|
|
hKey, // handle of open key
|
|
lpSubKey, // address of name of subkey to open
|
|
0 , // reserved
|
|
access, // security access mask
|
|
&m_hKey // address of handle of open key
|
|
);
|
|
|
|
if (lResult != ERROR_SUCCESS)
|
|
{
|
|
m_hKey = NULL;
|
|
}
|
|
|
|
// if we opened remote registry.. lets close the top level key
|
|
if (szCompName)
|
|
{
|
|
RegCloseKey(hKey);
|
|
delete [] szCompName;
|
|
}
|
|
|
|
return lResult;
|
|
}
|
|
|
|
DWORD CRegistry::DeleteValue (LPCTSTR lpValue)
|
|
{
|
|
ASSERT(lpValue);
|
|
ASSERT(m_hKey);
|
|
return RegDeleteValue(m_hKey, lpValue);
|
|
|
|
}
|
|
DWORD CRegistry::RecurseDeleteKey (LPCTSTR lpSubKey)
|
|
{
|
|
ASSERT(lpSubKey);
|
|
ASSERT(m_hKey);
|
|
|
|
CRegistry reg;
|
|
DWORD dwError = reg.OpenKey(m_hKey, lpSubKey);
|
|
if (dwError != ERROR_SUCCESS)
|
|
return dwError;
|
|
|
|
|
|
LPTSTR lpChildKey;
|
|
DWORD dwSize;
|
|
|
|
// we needn't/shouldn't use GetNextSubKey in this here
|
|
// as we are deleting the key during the loop.
|
|
while (ERROR_SUCCESS == reg.GetFirstSubKey(&lpChildKey, &dwSize))
|
|
{
|
|
VERIFY(reg.RecurseDeleteKey(lpChildKey) == ERROR_SUCCESS);
|
|
}
|
|
|
|
return RegDeleteKey(m_hKey, lpSubKey);
|
|
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD ReadReg(LPCTSTR lpValue, LPBYTE *lppbyte, DWORD *pdw, DWORD dwDatatype)
|
|
* Reads the registry used internally.
|
|
* LPCTSTR lpValue - value to be read.
|
|
* LPBYTE *lppbyte - address of the lpbyte at which to place the output buffer.
|
|
* DWORD *pdw - address of dword in which size of the buffer (in bytes) is returned.
|
|
* dword datatype - datatype you are expecting.
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::ReadReg(LPCTSTR lpValue, LPBYTE *lppbyte, DWORD *pdw, DWORD dwDatatype)
|
|
{
|
|
ASSERT(lpValue);
|
|
ASSERT(lppbyte);
|
|
ASSERT(pdw);
|
|
ASSERT(m_hKey != NULL);
|
|
*pdw = 0;
|
|
|
|
DWORD dwType;
|
|
DWORD lResult = RegQueryValueEx(
|
|
m_hKey, // handle of key to query
|
|
lpValue, // address of name of value to query
|
|
0, // reserved
|
|
&dwType, // address of buffer for value type
|
|
0, // address of data buffer
|
|
pdw // address of data buffer size
|
|
);
|
|
|
|
if (lResult == ERROR_SUCCESS)
|
|
{
|
|
ASSERT(dwType == dwDatatype || dwType == REG_EXPAND_SZ);
|
|
|
|
if (0 == Allocate(*pdw))
|
|
return ERROR_OUTOFMEMORY;
|
|
|
|
lResult = RegQueryValueEx(
|
|
m_hKey, // handle of key to query
|
|
lpValue, // address of name of value to query
|
|
0, // reserved
|
|
&dwType, // address of buffer for value type
|
|
m_pMemBlock, // address of data buffer
|
|
pdw // address of data buffer size
|
|
);
|
|
|
|
ASSERT (ERROR_MORE_DATA != lResult);
|
|
|
|
if (lResult == ERROR_SUCCESS)
|
|
*lppbyte = m_pMemBlock;
|
|
}
|
|
|
|
return lResult;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD ReadRegString(LPCTSTR lpValue, LPTSTR *lppStr, DWORD *pdw)
|
|
* Reads A string (REG_SZ) from the registry
|
|
* LPCTSTR lpValue value to be read.
|
|
* LPTSTR *lppStr - address of LPTSTR in which resultant buffer is returned. caller must copy
|
|
* the buffer to immediately. caller must not use this buffer except for copying it.
|
|
* caller must not write to this buffer.
|
|
* DWORD *pdw - address of dword in which size of the buffer (in bytes) is returned.
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::ReadRegString(LPCTSTR lpValue, LPTSTR *lppStr, DWORD *pdw)
|
|
{
|
|
return ReadReg(lpValue, (LPBYTE *)lppStr, pdw, REG_SZ);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD ReadRegDWord(LPCTSTR lpValue, DWORD *pdw)
|
|
* Reads A string (REG_SZ) from the registry
|
|
* LPCTSTR lpValue value to be read.
|
|
* DWORD *pdw - address of dword in which the read dword returned.
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::ReadRegDWord(LPCTSTR lpValue, DWORD *pdw)
|
|
{
|
|
ASSERT(pdw);
|
|
|
|
DWORD dwSize;
|
|
LPBYTE pByte;
|
|
DWORD dwReturn = ReadReg(lpValue, &pByte, &dwSize, REG_DWORD);
|
|
ASSERT(dwReturn != ERROR_SUCCESS || dwSize == sizeof(DWORD));
|
|
|
|
if (dwReturn == ERROR_SUCCESS)
|
|
*pdw = * LPDWORD(pByte);
|
|
|
|
return dwReturn;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD ReadRegMultiString(LPCTSTR lpValue, LPTSTR *lppStr, DWORD *pdw)
|
|
* Reads A string (REG_MULTI_SZ) from the registry
|
|
* LPCTSTR lpValue value to be read.
|
|
* LPTSTR *lppStr - address of LPTSTR in which resultant buffer is returned. caller must copy
|
|
* the buffer to immediately. caller must not use this buffer except for copying it.
|
|
* caller must not write to this buffer.
|
|
* DWORD *pdw - address of dword in which size of the buffer (in bytes) is returned.
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::ReadRegMultiString(LPCTSTR lpValue, LPTSTR *lppStr, DWORD *pdw)
|
|
{
|
|
return ReadReg(lpValue, (LPBYTE *)lppStr, pdw, REG_MULTI_SZ);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD ReadRegBinary(LPCTSTR lpValue, LPBYTE *lppByte, DWORD *pdw)
|
|
* Reads A string (REG_MULTI_SZ) from the registry
|
|
* LPCTSTR lpValue value to be read.
|
|
* LPBYTE *lppByte - address of LPBYTE in which resultant buffer is returned. caller must copy
|
|
* the buffer to immediately. caller must not use this buffer except for copying it.
|
|
* caller must not write to this buffer.
|
|
* DWORD *pdw - address of dword in which size of the buffer (in bytes) is returned.
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::ReadRegBinary(LPCTSTR lpValue, LPBYTE *lppByte, DWORD *pdw)
|
|
{
|
|
return ReadReg(lpValue, lppByte, pdw, REG_BINARY);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD GetFirstSubKey(LPTSTR *lppStr, DWORD *pdw)
|
|
* Reads a first subkey for the key
|
|
* LPTSTR *lppStr - address of LPTSTR in which resultant buffer is returned. caller must copy
|
|
* the buffer to immediately. caller must not use this buffer except for copying it.
|
|
* caller must not write to this buffer.
|
|
* used to enumerate the registry.
|
|
* DWORD *pdw - address of dword in which size of the buffer (in bytes) is returned.
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::GetFirstSubKey(LPTSTR *lppStr, DWORD *pdw)
|
|
{
|
|
ASSERT(lppStr);
|
|
ASSERT(pdw);
|
|
m_iEnumIndex = 0;
|
|
|
|
return GetNextSubKey(lppStr, pdw);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD GetNextSubKey(LPTSTR *lppStr, DWORD *pdw
|
|
* Reads the next subkey for the key
|
|
* LPTSTR *lppStr - address of LPTSTR in which resultant buffer is returned. caller must copy
|
|
* the buffer to immediately. caller must not use this buffer except for copying it.
|
|
* caller must not write to this buffer.
|
|
* used to enumerate the registry.
|
|
* DWORD *pdw - address of dword in which size of the buffer (in bytes) is returned.
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::GetNextSubKey(LPTSTR *lppStr, DWORD *pdw)
|
|
{
|
|
ASSERT(lppStr);
|
|
ASSERT(pdw);
|
|
ASSERT(m_hKey != NULL);
|
|
ASSERT(m_iEnumIndex >= 0); // must call GetFirstSubKey first.
|
|
|
|
*pdw = 1024;
|
|
if (0 == Allocate(*pdw * sizeof(TCHAR)))
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
LONG lResult = RegEnumKeyEx(
|
|
m_hKey, // handle of key to enumerate
|
|
m_iEnumIndex, // index of subkey to enumerate
|
|
(LPTSTR)m_pMemBlock, // address of buffer for subkey name
|
|
pdw, // address for size of subkey buffer
|
|
0, // reserved
|
|
NULL, // address of buffer for class string
|
|
NULL, // address for size of class buffer
|
|
NULL // address for time key last written to
|
|
);
|
|
|
|
(*pdw)++; // since null is not included in the size.
|
|
if (ERROR_NO_MORE_ITEMS == lResult)
|
|
return lResult;
|
|
|
|
m_iEnumIndex++;
|
|
|
|
if (lResult == ERROR_SUCCESS)
|
|
*lppStr = (LPTSTR)m_pMemBlock;
|
|
|
|
return lResult;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD GetFirstValue(LPTSTR *lppStr, DWORD *pdw, DWORD *pDataType)
|
|
* Reads a first value for the key
|
|
* LPTSTR *lppStr - address of LPTSTR in which resultant buffer is returned. caller must copy
|
|
* the buffer to immediately. caller must not use this buffer except for copying it.
|
|
* caller must not write to this buffer.
|
|
* used to enumerate the registry.
|
|
* DWORD *pdw - address of dword in which size of the buffer (in bytes) is returned.
|
|
* DWORD *pDataType - datatype of the value is returned in this one.
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::GetFirstValue(LPTSTR *lppStr, DWORD *pdw, DWORD *pDataType)
|
|
{
|
|
ASSERT(lppStr);
|
|
ASSERT(pdw);
|
|
ASSERT(pDataType);
|
|
|
|
m_iEnumValueIndex = 0;
|
|
return GetNextValue(lppStr, pdw, pDataType);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD GetNextValue(LPTSTR *lppStr, DWORD *pdw, DWORD *pDataType)
|
|
* Reads a next value for the key
|
|
* LPTSTR *lppStr - address of LPTSTR in which resultant buffer is returned. caller must copy
|
|
* the buffer to immediately. caller must not use this buffer except for copying it.
|
|
* caller must not write to this buffer.
|
|
* used to enumerate the registry.
|
|
* DWORD *pdw - address of dword in which size of the buffer (in bytes) is returned.
|
|
* DWORD *pDataType - datatype of the value is returned in this one.
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::GetNextValue(LPTSTR *lppStr, DWORD *pdw, DWORD *pDataType)
|
|
{
|
|
ASSERT(lppStr);
|
|
ASSERT(pdw);
|
|
ASSERT(pDataType);
|
|
ASSERT(m_hKey != NULL);
|
|
ASSERT(m_iEnumValueIndex >= 0); // must call GetFirstSubKey first.
|
|
|
|
*pdw = 1024;
|
|
if (0 == Allocate(*pdw * sizeof(TCHAR)))
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
LONG lResult = RegEnumValue(
|
|
m_hKey, // handle of key to query
|
|
m_iEnumValueIndex, // index of value to query
|
|
(LPTSTR)m_pMemBlock, // address of buffer for value string
|
|
pdw, // address for size of value buffer
|
|
0, // reserved
|
|
pDataType, // address of buffer for type code
|
|
NULL, // address of buffer for value data maks_todo : use this
|
|
NULL // address for size of data buffer
|
|
);
|
|
|
|
(*pdw)++; // since null is not included in the size.
|
|
|
|
if (ERROR_NO_MORE_ITEMS == lResult)
|
|
return lResult;
|
|
|
|
|
|
m_iEnumValueIndex++;
|
|
if (lResult == ERROR_SUCCESS)
|
|
*lppStr = (LPTSTR)m_pMemBlock;
|
|
|
|
return lResult;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD WriteRegString(LPCTSTR lpValueName, LPCTSTR lpStr)
|
|
* writes REG_SZ value into the registry
|
|
* LPCTSTR lpValueName - value name to be written to
|
|
* LPCTSTR lpStr - data to be written
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::WriteRegString(LPCTSTR lpValueName, LPCTSTR lpStr)
|
|
{
|
|
ASSERT(m_hKey != NULL); // call setkey before calling this function.
|
|
ASSERT(lpValueName);
|
|
ASSERT(lpStr);
|
|
|
|
DWORD dwSize = (_tcslen(lpStr) + 1) * sizeof(TCHAR) / sizeof(BYTE);
|
|
return RegSetValueEx(
|
|
m_hKey, // handle of key to set value for
|
|
lpValueName, // address of value to set
|
|
0, // Reserved
|
|
REG_SZ, // flag for value type
|
|
(LPBYTE)lpStr, // address of value data
|
|
dwSize // size of value data
|
|
);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD WriteRegExpString(LPCTSTR lpValueName, LPCTSTR lpStr)
|
|
* writes REG_EXPAND_SZ value into the registry
|
|
* LPCTSTR lpValueName - value name to be written to
|
|
* LPCTSTR lpStr - data to be written
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::WriteRegExpString(LPCTSTR lpValueName, LPCTSTR lpStr)
|
|
{
|
|
ASSERT(m_hKey != NULL); // call setkey before calling this function.
|
|
ASSERT(lpValueName);
|
|
ASSERT(lpStr);
|
|
|
|
DWORD dwSize = (_tcslen(lpStr) + 1) * sizeof(TCHAR) / sizeof(BYTE);
|
|
return RegSetValueEx(
|
|
m_hKey, // handle of key to set value for
|
|
lpValueName, // address of value to set
|
|
0, // Reserved
|
|
REG_EXPAND_SZ, // flag for value type
|
|
(LPBYTE)lpStr, // address of value data
|
|
dwSize // size of value data
|
|
);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD WriteRegMultiString(LPCTSTR lpValueName, LPCTSTR lpStr, DWORD dwSize)
|
|
* writes REG_MULTI_SZ value into the registry
|
|
* LPCTSTR lpValueName - value name to be written to
|
|
* LPCTSTR lpStr - data to be written
|
|
* DWORD dwSize - size of data.
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::WriteRegMultiString(LPCTSTR lpValueName, LPCTSTR lpStr, DWORD dwSize)
|
|
{
|
|
ASSERT(m_hKey != NULL); // call setkey before calling this function.
|
|
ASSERT(lpValueName);
|
|
ASSERT(lpStr);
|
|
|
|
#ifdef DBG
|
|
|
|
// lets make sure that the given size is right.
|
|
LPCTSTR lpTemp = lpStr;
|
|
DWORD rightsize = 0;
|
|
while (_tcslen(lpTemp) > 0)
|
|
{
|
|
rightsize += _tcslen(lpTemp) + 1;
|
|
lpTemp += _tcslen(lpTemp) + 1;
|
|
}
|
|
|
|
ASSERT(*lpTemp == 0); // final NULL.
|
|
rightsize++; // account for final terminating null
|
|
|
|
rightsize *= sizeof(TCHAR) / sizeof(BYTE); // size must be in bytes.
|
|
|
|
ASSERT(dwSize == rightsize);
|
|
|
|
#endif
|
|
|
|
return RegSetValueEx(
|
|
m_hKey, // handle of key to set value for
|
|
lpValueName, // address of value to set
|
|
0, // Reserved
|
|
REG_MULTI_SZ, // flag for value type
|
|
(LPBYTE)lpStr, // address of value data
|
|
dwSize // size of value data
|
|
);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD WriteRegBinary (LPCTSTR lpValueName, LPBYTE lpData, DWORD dwSize)
|
|
* writes REG_BINARY value into the registry
|
|
* LPCTSTR lpValueName - value name to be written to
|
|
* LPBYTE lpData - data to be written
|
|
* DWORD dwSize - size of data.
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::WriteRegBinary (LPCTSTR lpValueName, LPBYTE lpData, DWORD dwSize)
|
|
{
|
|
ASSERT(m_hKey != NULL); // call setkey before calling this function.
|
|
ASSERT(lpValueName);
|
|
ASSERT(lpData);
|
|
ASSERT(dwSize > 0);
|
|
|
|
return RegSetValueEx(
|
|
m_hKey, // handle of key to set value for
|
|
lpValueName, // address of value to set
|
|
0, // Reserved
|
|
REG_BINARY, // flag for value type
|
|
lpData, // address of value data
|
|
dwSize // size of value data
|
|
);
|
|
}
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD WriteRegDWord(LPCTSTR lpValueName, DWORD dwValue)
|
|
* writes REG_DWORD value into the registry
|
|
* LPCTSTR lpValueName - value name to be written to
|
|
* LPCTSTR dwValue - data to be written
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::WriteRegDWord(LPCTSTR lpValueName, DWORD dwValue)
|
|
{
|
|
ASSERT(m_hKey != NULL); // call setkey before calling this function.
|
|
ASSERT(lpValueName);
|
|
|
|
return RegSetValueEx(
|
|
m_hKey, // handle of key to set value for
|
|
lpValueName, // address of value to set
|
|
0, // Reserved
|
|
REG_DWORD, // flag for value type
|
|
(LPBYTE)&dwValue, // address of value data
|
|
sizeof(dwValue) // size of value data
|
|
);
|
|
}
|
|
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD WriteRegDWordNoOverWrite(LPCTSTR lpValueName, DWORD dwValue)
|
|
* writes REG_DWORD value into the registry if-and-only-if value does not already exist.
|
|
* LPCTSTR lpValueName - value name to be written to
|
|
* LPCTSTR dwValue - data to be written
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::WriteRegDWordNoOverWrite(LPCTSTR lpValueName, DWORD dwValue)
|
|
{
|
|
DWORD dwTmp, rc;
|
|
ASSERT(m_hKey != NULL); // call setkey before calling this function.
|
|
ASSERT(lpValueName);
|
|
|
|
rc = ReadRegDWord( lpValueName, &dwTmp);
|
|
|
|
if ( rc == ERROR_FILE_NOT_FOUND)
|
|
{
|
|
return RegSetValueEx(
|
|
m_hKey, // handle of key to set value for
|
|
lpValueName, // address of value to set
|
|
0, // Reserved
|
|
REG_DWORD, // flag for value type
|
|
(LPBYTE)&dwValue, // address of value data
|
|
sizeof(dwValue) // size of value data
|
|
);
|
|
}
|
|
|
|
ASSERT( rc == ERROR_SUCCESS );
|
|
return rc;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD ExistInMultiString (LPCTSTR lpValueName, LPCTSTR lpStr, BOOL *pbExists)
|
|
* checks if given null terminated string exists in a multi_sz value
|
|
* LPCTSTR lpValueName - value name to be checked
|
|
* LPCTSTR lpCheckForStr - the value to be checked for
|
|
* BOOL *pbExists - return. TRUE if exits.
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
/*
|
|
DWORD CRegistry::ExistInMultiString (LPCTSTR lpValueName, LPCTSTR lpCheckForStr, BOOL *pbExists)
|
|
{
|
|
ASSERT(m_hKey != NULL); // call setkey before calling this function.
|
|
ASSERT(lpValueName);
|
|
ASSERT(lpCheckForStr);
|
|
ASSERT(*lpCheckForStr);
|
|
ASSERT(pbExists);
|
|
|
|
|
|
|
|
|
|
DWORD dwError = ERROR_SUCCESS;
|
|
*pbExists = FALSE;
|
|
|
|
LPTSTR szValue;
|
|
DWORD dwSize;
|
|
dwError = ReadRegMultiString(lpValueName, &szValue, dwSize);
|
|
if (ERROR_SUCCESS == dwError)
|
|
{
|
|
LPCTSTR pTemp = szValue;
|
|
while(_tcslen(pTemp) > 0 )
|
|
{
|
|
if (_tcscmp(pTemp, lpCheckForStr) == 0)
|
|
{
|
|
*pbExists = TRUE;
|
|
break;
|
|
}
|
|
|
|
pTemp += _tcslen(pTemp) + 1; // point to the next string within the multistring.
|
|
if ( DWORD(pTemp - szSuiteValue) > (dwSize / sizeof(TCHAR)))
|
|
break; // temporary pointer passes the size of the szSuiteValue something is wrong with szSuiteValue.
|
|
}
|
|
}
|
|
|
|
return dwError;
|
|
|
|
|
|
ASSERT(FALSE);
|
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
*/
|
|
|
|
/*--------------------------------------------------------------------------------------------------------
|
|
* DWORD AppendToMultiString (LPCTSTR lpValueName, LPCTSTR lpStr)
|
|
* appends given string to a multistring value
|
|
* LPCTSTR lpValueName - value name to be appended to
|
|
* LPCTSTR lpStr - the value to be appended
|
|
* RETURNS error code.
|
|
* -------------------------------------------------------------------------------------------------------*/
|
|
DWORD CRegistry::AppendToMultiString (LPCTSTR lpValueName, LPCTSTR lpStr)
|
|
{
|
|
ASSERT(m_hKey != NULL); // call setkey before calling this function.
|
|
ASSERT(lpValueName);
|
|
ASSERT(lpStr);
|
|
ASSERT(*lpStr);
|
|
|
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
// copy the buffer immediately
|
|
DWORD CRegistry::GetSecurity(PSECURITY_DESCRIPTOR *ppSec, SECURITY_INFORMATION SecurityInformation, DWORD *pdwSize)
|
|
{
|
|
ASSERT(m_hKey != NULL); // call setkey before calling this function.
|
|
ASSERT(ppSec);
|
|
ASSERT(pdwSize);
|
|
DWORD dwError;
|
|
|
|
PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
|
|
*pdwSize = 0; // we just want to get the right size during the first call.
|
|
|
|
dwError = RegGetKeySecurity(
|
|
m_hKey, // open handle of key to set
|
|
SecurityInformation, // descriptor contents
|
|
&pSecurityDescriptor, // address of descriptor for key
|
|
pdwSize // address of size of buffer and descriptor
|
|
);
|
|
|
|
// this call can not succeed. as we have set the size = 0
|
|
ASSERT(dwError != ERROR_SUCCESS);
|
|
|
|
if (dwError != ERROR_INSUFFICIENT_BUFFER)
|
|
{
|
|
// something else has went wronng.
|
|
// return the error code
|
|
return dwError;
|
|
}
|
|
|
|
ASSERT(*pdwSize != 0);
|
|
|
|
// now we have got the right size, allocate it.
|
|
if (0 == Allocate(*pdwSize))
|
|
return ERROR_OUTOFMEMORY;
|
|
|
|
dwError = RegGetKeySecurity(
|
|
m_hKey, // open handle of key to set
|
|
SecurityInformation, // descriptor contents
|
|
m_pMemBlock, // address of descriptor for key
|
|
pdwSize // address of size of buffer and descriptor
|
|
);
|
|
|
|
ASSERT(dwError != ERROR_INSUFFICIENT_BUFFER);
|
|
|
|
if (dwError == ERROR_SUCCESS)
|
|
*ppSec = m_pMemBlock;
|
|
|
|
return dwError;
|
|
|
|
}
|
|
|
|
DWORD CRegistry::SetSecurity(PSECURITY_DESCRIPTOR pSec, SECURITY_INFORMATION SecurityInformation)
|
|
{
|
|
ASSERT(m_hKey != NULL); // call setkey before calling this function.
|
|
return RegSetKeySecurity(
|
|
m_hKey, // open handle of key to set
|
|
SecurityInformation, // descriptor contents
|
|
pSec // address of descriptor for key
|
|
);
|
|
}
|
|
|
|
|
|
// this function will fail miserably if the source and destination overlap.
|
|
DWORD CRegistry::CopyTree(CRegistry ®Src)
|
|
{
|
|
DWORD dwSize;
|
|
LPTSTR szKey;
|
|
LPTSTR szValue;
|
|
DWORD dwError;
|
|
|
|
if (ERROR_SUCCESS == (dwError = regSrc.GetFirstSubKey(&szKey, &dwSize)))
|
|
{
|
|
|
|
do
|
|
{
|
|
CRegistry regSrcKey;
|
|
CRegistry regDstKey;
|
|
if (ERROR_SUCCESS == (dwError = regSrcKey.OpenKey(regSrc, szKey)))
|
|
{
|
|
|
|
if (ERROR_SUCCESS == (dwError = regDstKey.CreateKey(m_hKey, szKey)))
|
|
{
|
|
regDstKey.CopyTree(regSrcKey);
|
|
}
|
|
}
|
|
|
|
}
|
|
while (ERROR_SUCCESS == (dwError = regSrc.GetNextSubKey(&szKey, &dwSize)));
|
|
|
|
}
|
|
|
|
//
|
|
// now copy values.
|
|
//
|
|
|
|
|
|
DWORD dwDataType;
|
|
if (ERROR_SUCCESS == (dwError = regSrc.GetFirstValue(&szValue, &dwSize, &dwDataType)))
|
|
{
|
|
do
|
|
{
|
|
TCHAR *szValueName = new TCHAR[dwSize];
|
|
if (!szValueName)
|
|
break;
|
|
|
|
_tcscpy(szValueName, szValue);
|
|
|
|
LPBYTE pData;
|
|
if (ERROR_SUCCESS == (dwError = regSrc.ReadReg(szValueName, &pData, &dwSize, dwDataType)))
|
|
{
|
|
dwError = RegSetValueEx(
|
|
m_hKey, // handle of key to set value for
|
|
szValueName, // address of value to set
|
|
0, // Reserved
|
|
dwDataType, // flag for value type
|
|
pData, // address of value data
|
|
dwSize // size of value data
|
|
);
|
|
|
|
}
|
|
}
|
|
while (ERROR_SUCCESS == regSrc.GetNextValue(&szValue, &dwSize, &dwDataType));
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
#ifdef _Maks_AutoTest_
|
|
|
|
//
|
|
// make sure that CRegistry does not support
|
|
// Copy constructor & assignment operator
|
|
//
|
|
|
|
void TestRegistry (CRegistry reg)
|
|
{
|
|
CRegistry reg2 = reg; // should get error for copy constructor
|
|
CRegistry reg3(reg); // should get error for copy constructor
|
|
CRegistry reg4;
|
|
reg4 = reg; // should get error for = operator.
|
|
TestRegistry(reg); // should get error for copy construtor
|
|
}
|
|
#endif // _Maks_AutoTest_
|
|
|
|
|
|
// EOF
|