|
|
//***************************************************************************
//
// Copyright � Microsoft Corporation. All rights reserved.
//
// cregcls.cpp
//
// Purpose: registry wrapper class
//
//***************************************************************************
#include "precomp.h"
#pragma warning( disable : 4290 )
#include <CHString.h>
#include <strsafe.h>
#include <stdio.h>
#include "CRegCls.h"
#include <malloc.h>
#include <cnvmacros.h>
DWORD CRegistry::s_dwPlatform = CRegistry::GetPlatformID () ;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ CRegistry::CRegistry() : m_fFromCurrentUser(false) { // Set the key to null so that if the caller does not open the key
// but still tries to use it we can return an error
hKey = (HKEY)NULL; hSubKey = (HKEY)NULL; hRootKey = (HKEY)NULL;
// To prevent garbage values being returned if they try to get
// some information before they open the class
SetDefaultValues(); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ CRegistry::~CRegistry() { Close(); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void CRegistry::SetDefaultValues() { // Information inited here rather than constructor so that this instance
// can be reused
ClassName[0] = '\0'; dwcClassLen = MAX_PATH; // Length of class string.
dwcSubKeys = NULL_DWORD; // Number of sub keys.
dwcMaxSubKey = NULL_DWORD; // Longest sub key size.
dwcMaxClass = NULL_DWORD; // Longest class string.
dwcValues = NULL_DWORD; // Number of values for this key.
dwcMaxValueName = NULL_DWORD; // Longest Value name.
dwcMaxValueData = NULL_DWORD; // Longest Value data.
RewindSubKeys(); // Rewind the index to zero
RootKeyPath.Empty(); }
////////////////////////////////////////////////////////////////
// Function: EnumerateAndGetValues
// Description: This function enumerates the values under the
// specified key and gets the value, keeps on
// going and going... until there aren't any more
// values to get. The first call must set the
// value index to 0, this indicates for the function
// to start over;
//
//
// NOTE!!!! The USER has the responsibility of deleting the
// allocated memory for pValueName and pValueData
//
//
// Arguments:
// Returns: Standard return value from registry open function
// Inputs:
// Outputs:
// Caveats:
// Raid:
////////////////////////////////////////////////////////////////
LONG CRegistry::EnumerateAndGetValues (
DWORD &dwIndexOfValue, WCHAR *&pValueName, BYTE *&pValueData ) { DWORD dwIndex = dwIndexOfValue, dwType; DWORD dwValueNameSize = dwcMaxValueName + 2; // add extra for null
DWORD dwValueDataSize = dwcMaxValueData + 2; // add extra for null
// If this is the first time we have come thru, then we
// need to get the max size of things.
pValueName = new WCHAR[dwValueNameSize + 2]; if ( ! pValueName ) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; }
// We have to use WCHAR's since for 9x, we'll be converting the
// data from chars to WCHARs.
pValueData = (LPBYTE) new WCHAR[dwValueDataSize + 2]; if ( ! pValueData ) { delete [] pValueName ; pValueName = NULL; throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; }
LONG lRc = ERROR_SUCCESS ;
try { lRc = myRegEnumValue (
hKey, // handle of key to query
dwIndex, // index of value to query
pValueName, // address of buffer for value string
&dwValueNameSize, // address for size of value buffer
0, // reserved
&dwType, // address of buffer for type code
pValueData, // address of buffer for value data
&dwValueDataSize ) ;
dwIndexOfValue = dwIndex;
if ( lRc != ERROR_SUCCESS ) { delete[] pValueName; pValueName = NULL ;
delete[] pValueData; pValueData = NULL ; } } catch ( ... ) { delete[] pValueName; pValueName = NULL ;
delete[] pValueData; pValueData = NULL ;
throw ; // throw the exception up
}
return lRc ; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: LONG CRegistry::OpenCurrentUser(LPCWSTR lpszSubKey, REGSAM samDesired) Description: Arguments: Returns: Standard return value from registry open function Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
DWORD CRegistry::OpenCurrentUser ( LPCWSTR lpszSubKey, // address of name of subkey to open
REGSAM samDesired) // Access mask
{ LONG RetValue = ERROR_SUCCESS;
// If we have a key value, we are open, so lets cleanup the previous
// use of this instance
PrepareToReOpen(); RetValue = ::RegOpenCurrentUser( samDesired, &hRootKey);
m_fFromCurrentUser = true; if(RetValue == ERROR_SUCCESS) { // Just return the value and the hKey value never gets changed from NULL
//======================================================================
RetValue = myRegOpenKeyEx (
hRootKey, lpszSubKey, // address of name of subkey to open
(DWORD) 0, // reserved
samDesired, // security access mask
(PHKEY)&hKey // address of handle of open key
);
// If we are not successful, then return the registry error
//=========================================================
if(RetValue == ERROR_SUCCESS) { dwcClassLen = sizeof(ClassName);
// Get the key information now, so it's available
// this is not critical, so we won't fail the open if this fails
//===============================================
myRegQueryInfoKey (
hKey, // Key handle.
ClassName, // Buffer for class name.
&dwcClassLen, // Length of class string.
NULL, // Reserved.
&dwcSubKeys, // Number of sub keys.
&dwcMaxSubKey, // Longest sub key size.
&dwcMaxClass, // Longest class string.
&dwcValues, // Number of values for this key.
&dwcMaxValueName, // Longest Value name.
&dwcMaxValueData, // Longest Value data.
&dwcSecDesc, // Security descriptor.
&ftLastWriteTime // Last write time.
); RootKeyPath = lpszSubKey; // Assign
} }
return RetValue; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: LONG CRegistry::Open(HKEY hKey, LPCWSTR lpszSubKey, REGSAM samDesired) Description: Arguments: Returns: Standard return value from registry open function Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ LONG CRegistry::Open(
HKEY hInRootKey, LPCWSTR lpszSubKey, REGSAM samDesired ) { LONG RetValue;
// If we have a key value, we are open, so lets cleanup the previous
// use of this instance
if(hKey != NULL) { PrepareToReOpen(); } hRootKey = hInRootKey;
// Just return the value and the hKey value never gets changed from NULL
//======================================================================
RetValue = myRegOpenKeyEx (
hRootKey, lpszSubKey, // address of name of subkey to open
(DWORD) 0, // reserved
samDesired, // security access mask
(PHKEY)&hKey // address of handle of open key
);
// If we are not successful, then return the registry error
//=========================================================
if(RetValue != ERROR_SUCCESS) { return RetValue; }
dwcClassLen = sizeof(ClassName);
// Get the key information now, so it's available
// this is not critical, so we won't fail the open if this fails
//===============================================
myRegQueryInfoKey (
hKey, // Key handle.
ClassName, // Buffer for class name.
&dwcClassLen, // Length of class string.
NULL, // Reserved.
&dwcSubKeys, // Number of sub keys.
&dwcMaxSubKey, // Longest sub key size.
&dwcMaxClass, // Longest class string.
&dwcValues, // Number of values for this key.
&dwcMaxValueName, // Longest Value name.
&dwcMaxValueData, // Longest Value data.
&dwcSecDesc, // Security descriptor.
&ftLastWriteTime // Last write time.
); RootKeyPath = lpszSubKey; // Assign
return RetValue; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: LONG CRegistry::CreateOpen(HKEY hInRootKey, LPCWSTR lpszSubKey, LPSTR lpClass = NULL, DWORD dwOptions = REG_OPTION_NON_VOLATILE, REGSAM samDesired = KEY_ALL_ACCESS, LPSECURITY_ATTRIBUTES lpSecurityAttrib = NULL LPDWORD pdwDisposition = NULL ); Description: Arguments: lpClass, dwOptions, samDesired and lpSecurityAttrib have signature defaults Returns: Standard return value from registry RegCreateKeyEx function Inputs: Outputs: Caveats: Raid: History: a-peterc 28-Jul-1998 Created * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ LONG CRegistry::CreateOpen (
HKEY hInRootKey, LPCWSTR lpszSubKey, LPWSTR lpClass, DWORD dwOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttrib, LPDWORD pdwDisposition ) { LONG RetValue; DWORD dwDisposition;
// If we have a key value, we are open, so lets cleanup the previous
// use of this instance
if(hKey != NULL) { PrepareToReOpen(); } hRootKey = hInRootKey;
// Just return the value and the hKey value never gets changed from NULL
//======================================================================
RetValue = myRegCreateKeyEx (
hRootKey, lpszSubKey, // address of name of subkey to open
(DWORD) 0, // reserved
lpClass, // address of the object class string
dwOptions, // special options flag
samDesired, // security access mask
lpSecurityAttrib, // address of the key security structure
(PHKEY)&hKey, // address of handle of open key
&dwDisposition // address of the disposition value buffer
); // If we are not successful, then return the registry error
//=========================================================
if(RetValue != ERROR_SUCCESS) { return RetValue; }
if( pdwDisposition ) { *pdwDisposition = dwDisposition; }
// Get the key information now, so it's available
// this is not critical, so we won't fail the open if this fails
//===============================================
myRegQueryInfoKey (
hKey, // Key handle.
ClassName, // Buffer for class name.
&dwcClassLen, // Length of class string.
NULL, // Reserved.
&dwcSubKeys, // Number of sub keys.
&dwcMaxSubKey, // Longest sub key size.
&dwcMaxClass, // Longest class string.
&dwcValues, // Number of values for this key.
&dwcMaxValueName, // Longest Value name.
&dwcMaxValueData, // Longest Value data.
&dwcSecDesc, // Security descriptor.
&ftLastWriteTime // Last write time.
); RootKeyPath = lpszSubKey; // Assign
return RetValue; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: DWORD CRegistry::DeleteKey( CHString* pchsSubKeyPath = NULL )
Description: deletes the specified subkey or the Rootkey specified in the open
Arguments: pchsSubKeyPath has signature default of NULL, specifying the RootKeyPath by default
Returns: Standard return value from registry RegDeleteKey function Inputs: Outputs: Caveats: A deleted key is not removed until the last handle to it has been closed. Subkeys and values cannot be created under a deleted key. Raid: History: a-peterc 28-Jul-1998 Created * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ LONG CRegistry::DeleteKey( CHString* pchsSubKeyPath ) { CHString* pSubKey = pchsSubKeyPath ? pchsSubKeyPath : &RootKeyPath;
return myRegDeleteKey( hKey, pSubKey->GetBuffer(0) ); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: DWORD CRegistry::DeleteValue( LPCWSTR pValueName )
Description: deletes the specified value in the createopen
Arguments: pValueName to be deleted
Returns: Standard return value from registry RegDeleteValue function Inputs: Outputs: Caveats: Raid: History: a-peterc 30-Sep-1998 Created * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ LONG CRegistry::DeleteValue( LPCWSTR pValueName ) { return myRegDeleteValue( hKey, pValueName ); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: LONG CRegistry::OpenAndEnumerateSubKeys(HKEY hKey, LPCWSTR lpszSubKey, REGSAM samDesired) Description: Arguments: Returns: Standard return value from registry open function Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ LONG CRegistry::OpenAndEnumerateSubKeys (
HKEY hInRootKey, LPCWSTR lpszSubKey, REGSAM samDesired ) { return (Open( hInRootKey, lpszSubKey, samDesired | KEY_ENUMERATE_SUB_KEYS)); }
/////////////////////////////////////////////////////////////////////
//
// This function opens and enumerates a key, then gets the requested
// value
//
/////////////////////////////////////////////////////////////////////
LONG CRegistry::OpenLocalMachineKeyAndReadValue(
LPCWSTR lpszSubKey, LPCWSTR pValueName, CHString &DestValue ) { LONG lRc;
//===============================================
// Open the key. Note, if it is already in use
// the current key will be closed and everything
// reinitilized by the Open call
//===============================================
lRc = Open( HKEY_LOCAL_MACHINE,lpszSubKey,KEY_READ ); if( lRc != ERROR_SUCCESS ) { return lRc; }
//===============================================
// Get the value
//===============================================
return( GetCurrentKeyValue( pValueName, DestValue )); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::GetCurrentRawKeyValue (
HKEY UseKey, LPCWSTR pValueName, void *pDestValue, LPDWORD pValueType, LPDWORD pSizeOfDestValue ) { DWORD RetValue;
// If subkey is open then get value
// ================================
RetValue = myRegQueryValueEx(
UseKey, // handle of key to query
pValueName, // address of name of value to query
NULL, // reserved
pValueType, // address of buffer for value type
(LPBYTE) pDestValue, // address of data buffer
(LPDWORD)pSizeOfDestValue // address of data buffer size
);
return RetValue; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::GetCurrentKeyValue (
HKEY UseKey, LPCWSTR pValueName, CHString &DestValue ) { DWORD SizeOfValue = 0L; DWORD TypeOfValue; LPBYTE pValue = NULL ; // Pointer to buffer for value
DestValue = L"";
LONG t_Status = myRegQueryValueEx(
UseKey, // handle of key to query
pValueName, // address of name of value to query
NULL, // reserved
(LPDWORD)&TypeOfValue, // address of buffer for value type
(LPBYTE) NULL, // address of data buffer NULL to force size being returned
(LPDWORD)&SizeOfValue // Get the size of the buffer we need
) ; if( t_Status != ERROR_SUCCESS ) { return (DWORD) REGDB_E_INVALIDVALUE; } /////////////////////////////////////////////////////////////
if( SizeOfValue <= 0 ) { return (DWORD) REGDB_E_INVALIDVALUE; }
// Allow extra room for strings -- query doesn't include room for NULLs
// a-jmoon 8/19/97
//=====================================================================
if(TypeOfValue == REG_SZ || TypeOfValue == REG_EXPAND_SZ || TypeOfValue == REG_MULTI_SZ) { SizeOfValue += 2 ; }
pValue = new BYTE[SizeOfValue]; if( ! pValue ) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; }
try { ///////////////////////////////////////////////////////////////////
// Get the value in its RAW format
///////////////////////////////////////////////////////////////////
if( GetCurrentRawKeyValue(UseKey, pValueName, pValue, (LPDWORD)&TypeOfValue, (LPDWORD)&SizeOfValue) != ERROR_SUCCESS ) { delete []pValue; pValue = NULL; return (DWORD) REGDB_E_INVALIDVALUE; }
// If the type is a null termiated string
// then assign it to the CHString
// ======================================
switch(TypeOfValue) { case REG_SZ: case REG_EXPAND_SZ: { DestValue = (LPCWSTR)pValue; // Move string in
} break;
case REG_MULTI_SZ: { WCHAR *ptemp = (WCHAR *) pValue; int stringlength; stringlength = wcslen((LPCWSTR)ptemp); while(stringlength) { DestValue += (LPCWSTR)ptemp; // Move string in
DestValue += L"\n"; // Linefeed as separator
ptemp += stringlength+1; stringlength = wcslen((LPCWSTR)ptemp); } } break;
case REG_DWORD: { LPWSTR pTemp = new WCHAR[MAX_SUBKEY_BUFFERSIZE]; if(pTemp) { try { StringCchPrintfW( pTemp, MAX_SUBKEY_BUFFERSIZE, L"%ld", *((DWORD*)pValue) ); DestValue = pTemp; delete []pTemp; pTemp = NULL; } catch ( ... ) { delete [] pTemp ; pTemp = NULL; throw ; } } else { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } } break;
case REG_BINARY: { DestValue.Empty(); // copy into DestValue, Creating a byte buffer wide enough.
// Note: SizeOfValue is in bytes, while GetBuffer() returns wide char allocation.
DWORD t_dwResidual = ( SizeOfValue % 2 ) ; DWORD t_dwWideSize = ( SizeOfValue / 2 ) + t_dwResidual ;
memcpy( DestValue.GetBuffer( t_dwWideSize ), pValue, SizeOfValue ); // cap the byte blob
if( t_dwResidual ) { *( (LPBYTE)((LPCWSTR) DestValue) + SizeOfValue ) = NULL; } DestValue.GetBufferSetLength( t_dwWideSize ) ; } break;
default: { delete []pValue; pValue = NULL; return (DWORD) REGDB_E_INVALIDVALUE; } } } catch ( ... ) { delete []pValue; pValue = NULL; throw; }
/////////////////////////////////////////////////////////////
delete []pValue;
return (DWORD)ERROR_SUCCESS; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::GetCurrentKeyValue(LPCWSTR pValueName, CHString &DestValue) { return( GetCurrentKeyValue(hKey, pValueName, DestValue)); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::GetCurrentKeyValue(HKEY UseKey, LPCWSTR pValueName, CHStringArray &DestValue) { DWORD SizeOfValue = 0L; DWORD TypeOfValue; LPBYTE pValue; // Pointer to buffer for value
DestValue.RemoveAll();
// Get the size of the buffer we need
LONG t_Status = myRegQueryValueEx(
UseKey, // handle of key to query
pValueName, // address of name of value to query
NULL, // reserved
(LPDWORD)&TypeOfValue, // address of buffer for value type
(LPBYTE) NULL, // address of data buffer NULL to force size being returned
(LPDWORD)&SizeOfValue ) ;
if( t_Status != ERROR_SUCCESS ) { return (DWORD) REGDB_E_INVALIDVALUE; } /////////////////////////////////////////////////////////////
if (( SizeOfValue <= 0 ) || (TypeOfValue != REG_MULTI_SZ)) { return (DWORD) REGDB_E_INVALIDVALUE; }
SizeOfValue += 2 ;
pValue = new BYTE[SizeOfValue]; if( !pValue ) { return (DWORD) REGDB_E_INVALIDVALUE; }
///////////////////////////////////////////////////////////////////
// Get the value in its RAW format
///////////////////////////////////////////////////////////////////
try {
if( GetCurrentRawKeyValue(UseKey, pValueName, pValue, (LPDWORD)&TypeOfValue, (LPDWORD)&SizeOfValue) != ERROR_SUCCESS ) { delete []pValue; pValue = NULL; return (DWORD) REGDB_E_INVALIDVALUE; }
// If the type is a null termiated string
// then assign it to the CHString
// ======================================
switch(TypeOfValue) { case REG_MULTI_SZ: { LPCWSTR ptemp = (LPCWSTR)pValue; int stringlength; stringlength = wcslen(ptemp); while(stringlength) { DestValue.Add(ptemp); // Move string in
ptemp += stringlength+1; stringlength = wcslen(ptemp); } } break;
default: { delete [] pValue; pValue = NULL; return (DWORD) REGDB_E_INVALIDVALUE; } } } catch ( ... ) { delete [] pValue ; pValue = NULL; throw ; } delete [] pValue; pValue = NULL; return (DWORD)ERROR_SUCCESS; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::GetCurrentKeyValue (
LPCWSTR pValueName, CHStringArray &DestValue ) { return GetCurrentKeyValue (
hKey, pValueName, DestValue ); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::GetCurrentKeyValue (
HKEY UseKey, LPCWSTR pValueName, DWORD &DestValue ) { DWORD SizeOfValue = MAX_SUBKEY_BUFFERSIZE; long RetValue; DWORD TypeOfValue; LPBYTE pValue; // Pointer to buffer for value
pValue = new BYTE[MAX_SUBKEY_BUFFERSIZE]; if(pValue) { try { // Get the value in its RAW format
// ===============================
RetValue = GetCurrentRawKeyValue (
UseKey, pValueName, pValue, (LPDWORD)&TypeOfValue, (LPDWORD)&SizeOfValue );
if( ERROR_SUCCESS == RetValue ) { // If the type is a null termiated string
// then assign it to the CHString
// ======================================
switch(TypeOfValue) { case REG_SZ: { DestValue = atol((LPSTR)pValue); } break;
case REG_DWORD: { DestValue = *((DWORD*)(pValue)); } break;
default: { DestValue = (DWORD)0L; RetValue = REGDB_E_INVALIDVALUE; // Invalid value
} break; } } delete[] pValue; pValue = NULL; } catch ( ... ) { delete [] pValue ; pValue = NULL; throw ; } } else { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; }
return RetValue; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::GetCurrentKeyValue (
LPCWSTR pValueName, DWORD &DestValue ) { return( GetCurrentKeyValue(hKey, pValueName, DestValue)); }
//////////////////////////////////////////////////////////////////////
// Added support for Binary Type
//////////////////////////////////////////////////////////////////////
DWORD CRegistry::GetCurrentBinaryKeyValue (
LPCWSTR pValueName, CHString &chsDest ) { DWORD dwType = REG_BINARY; DWORD dwRc; WCHAR szDest[_MAX_PATH+2], ByteBuf[_MAX_PATH]; BYTE bRevision[_MAX_PATH+2]; DWORD dwSize = _MAX_PATH;
dwRc = GetCurrentRawKeyValue (
hKey, pValueName, bRevision, &dwType, &dwSize );
if( dwRc != ERROR_SUCCESS ) { return dwRc; }
StringCchCopyW( szDest, sizeof( szDest ) / sizeof( WCHAR ), QUOTE );
for( DWORD i=0; i<dwSize; i++ ) { StringCchPrintfW( ByteBuf, sizeof( ByteBuf ) / sizeof( WCHAR ), L"%02x", bRevision[i] ); StringCchCatW( szDest, sizeof( szDest ) / sizeof( WCHAR ), ByteBuf ); }
StringCchCatW( szDest, sizeof( szDest ) / sizeof( WCHAR ), QUOTE ); chsDest = szDest;
return dwRc; }
DWORD CRegistry::GetCurrentBinaryKeyValue (
LPCWSTR pValueName, LPBYTE pbDest, LPDWORD pSizeOfDestValue ) { DWORD dwType = 0 ;
return GetCurrentRawKeyValue (
hKey, pValueName, pbDest, &dwType, &(*pSizeOfDestValue) ) ; }
DWORD CRegistry::GetCurrentBinaryKeyValue ( HKEY UseKey , LPCWSTR pValueName , LPBYTE pbDest , LPDWORD pSizeOfDestValue ) { DWORD dwType = 0 ;
return GetCurrentRawKeyValue (
UseKey, pValueName, pbDest, &dwType, &(*pSizeOfDestValue) ) ; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::GetCurrentSubKeyName (
CHString &DestSubKeyName ) { WCHAR KeyName[MAX_SUBKEY_BUFFERSIZE]; DWORD RetValue;
// and don't bother having RegEnumKey error out
if(CurrentSubKeyIndex >= dwcSubKeys) { // If we have exceeded the number of subkeys available tell the caller
return( ERROR_NO_MORE_ITEMS ); }
RetValue = myRegEnumKey (
hKey, CurrentSubKeyIndex, KeyName, MAX_SUBKEY_BUFFERSIZE );
// If we are successfull reading the name
//=======================================
if(ERROR_SUCCESS == RetValue) { DestSubKeyName = KeyName; } else { // Otherwise clear the string so we don't leave garbage
//=====================================================
DestSubKeyName.Empty(); }
return RetValue; // In either event, return the value RegEnumKey returned
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::GetCurrentSubKeyPath (
CHString &DestSubKeyPath ) { CHString TempName; DWORD dwRet;
dwRet = GetCurrentSubKeyName(TempName); if (dwRet == ERROR_SUCCESS) { DestSubKeyPath = RootKeyPath+"\\"; DestSubKeyPath += TempName; } else { DestSubKeyPath.Empty(); }
return dwRet; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void CRegistry::Close(void) { if(hSubKey != NULL) { RegCloseKey(hSubKey) ; hSubKey = NULL ; }
if(hKey != NULL) { RegCloseKey(hKey); hKey = NULL; }
if(hRootKey != NULL && m_fFromCurrentUser) { RegCloseKey(hRootKey); hRootKey = NULL; }
SetDefaultValues(); // Reset all the member vars for next
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::OpenSubKey(void) { CHString SubKeyPath; LONG RetValue;
// If they try and open the same subkey again then
// leave things alone, otherwise open the subkey
if(hSubKey) { return ERROR_SUCCESS; }
// Get the current subkey path
//============================
GetCurrentSubKeyPath(SubKeyPath);
// Just return the value and the hKey value never gets changed from NULL
//======================================================================
RetValue = myRegOpenKeyEx (
hRootKey, (LPCWSTR)SubKeyPath, // address of name of subkey to open
(DWORD) 0, // reserved
KEY_READ, // security access mask
(PHKEY)&hSubKey // address of handle of open key
);
return RetValue; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void CRegistry::RewindSubKeys(void) { CurrentSubKeyIndex = 0; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void CRegistry::CloseSubKey(void) { if(hSubKey != NULL) { RegCloseKey(hSubKey); }
hSubKey = NULL; // Only Close once
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::GetCurrentRawSubKeyValue (
LPCWSTR pValueName, void *pDestValue, LPDWORD pValueType, LPDWORD pSizeOfDestValue ) { // Try and open subkey
// and set hSubKey variable
// ========================
DWORD RetValue = OpenSubKey();
// If subkey is open then get value
// ================================
if(ERROR_SUCCESS == RetValue) { RetValue = GetCurrentRawKeyValue (
hSubKey, pValueName, pDestValue, pValueType, pSizeOfDestValue ); }
return RetValue; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::GetCurrentSubKeyValue (
LPCWSTR pValueName, void *pDestValue, LPDWORD pSizeOfDestValue ) { DWORD RetValue;
// Try and open subkey
// and set hSubKey variable
// ========================
RetValue = OpenSubKey();
// If subkey is open then get value
// ================================
if(ERROR_SUCCESS == RetValue) { RetValue = GetCurrentRawSubKeyValue (
pValueName, pDestValue, NULL, pSizeOfDestValue ); }
return RetValue; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::GetCurrentSubKeyValue (
LPCWSTR pValueName, CHString &DestValue ) { DWORD RetValue;
// Try and open subkey
// and set hSubKey variable
// ========================
RetValue = OpenSubKey();
// If subkey is open then get value
// ================================
if(ERROR_SUCCESS == RetValue) { RetValue = GetCurrentKeyValue (
hSubKey, pValueName, DestValue ); }
return RetValue; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::GetCurrentSubKeyValue (
LPCWSTR pValueName, DWORD &DestValue ) { DWORD RetValue;
// Try and open subkey
// and set hSubKey variable
// ========================
RetValue = OpenSubKey();
// If subkey is open then get value
// ================================
if(ERROR_SUCCESS == RetValue) { RetValue = GetCurrentKeyValue (
hSubKey, pValueName, DestValue ); }
return RetValue; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::NextSubKey(void) { if (CurrentSubKeyIndex >= dwcSubKeys) { return( ERROR_NO_MORE_ITEMS ); }
// Close the currently opened subkey
CloseSubKey();
if(++CurrentSubKeyIndex >= dwcSubKeys) { // CurrentSubKeyIndex is 0 based, dwcSubKeys is one based
return( ERROR_NO_MORE_ITEMS ); } else { return (ERROR_SUCCESS); } }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void CRegistry::PrepareToReOpen(void) { Close(); SetDefaultValues(); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: SetCurrentKeyValueString(LPCSTR pValueName, CHString &DestValue) Description: sets registry string using REG_SZ Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::SetCurrentKeyValue (
LPCWSTR pValueName, CHString &DestValue ) { DWORD dwResult; if(DestValue.Find(_T('%')) != -1) { dwResult = SetCurrentKeyValueExpand (
hKey, pValueName, DestValue ); } else { dwResult = SetCurrentKeyValue (
hKey, pValueName, DestValue ); } return dwResult ; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: Description: Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::SetCurrentKeyValue (
LPCWSTR pValueName, DWORD &DestValue ) { DWORD dwResult = SetCurrentKeyValue (
hKey, pValueName, DestValue );
return dwResult ; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: SetCurrentKeyValue(LPCSTR pValueName, CHStringArray &DestValue) Description: sets registry string using REG_MULIT_SZ Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::SetCurrentKeyValue (
LPCWSTR pValueName, CHStringArray &DestValue ) { DWORD dwResult = SetCurrentKeyValue (
hKey, pValueName, DestValue );
return dwResult ; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: SetCurrentKeyValue(HKEY UseKey, LPCSTR pValueName, CHString &DestValue) Description: sets registry string using REG_MULIT_SZ Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::SetCurrentKeyValue (
HKEY hUseKey, LPCWSTR pValueName, CHString &DestValue ) { DWORD dwResult = myRegSetValueEx (
hUseKey, // key handle
pValueName, // name of value
0, // reserved -- must be zero
REG_SZ, // data type
(const BYTE*)(LPCWSTR)DestValue, ( DestValue.GetLength() + 1 ) * sizeof ( WCHAR ) ); return dwResult ; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: SetCurrentKeyValue(HKEY UseKey, LPCSTR pValueName, DWORD &DestValue) Description: sets registry string using REG_MULIT_SZ Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::SetCurrentKeyValue (
HKEY hUseKey, LPCWSTR pValueName, DWORD &DestValue ) { DWORD dwResult = myRegSetValueEx (
hUseKey, // key handle
pValueName, // name of value
0, // reserved -- must be zero
REG_DWORD, // data type
(const BYTE*)&DestValue, sizeof(DWORD) ); return dwResult ; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: SetCurrentKeyValue(HKEY UseKey, LPCSTR pValueName, CHStringArray &DestValue) Description: sets registry string using REG_MULIT_SZ Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::SetCurrentKeyValue (
HKEY hUseKey, LPCWSTR pValueName, CHStringArray &DestValue ) { DWORD dwResult = ERROR_SUCCESS;
DWORD dwArrayChars = 0; for ( LONG Index = 0; Index < DestValue.GetSize(); Index++ ) { CHString chsTemp = DestValue.GetAt(Index); dwArrayChars += ( chsTemp.GetLength() + 1 ) * sizeof(WCHAR); }
// Add room for the trailing wide character null
dwArrayChars += 2; WCHAR* pValue = new WCHAR[dwArrayChars]; if( !pValue ) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } try { memset( pValue, 0, dwArrayChars*sizeof(WCHAR) ); DWORD dwCharCount = 0; for ( Index = 0; Index < DestValue.GetSize(); Index++ ) { CHString chsTemp = DestValue.GetAt(Index); StringCchCopyW(&pValue[dwCharCount], dwArrayChars - dwCharCount, chsTemp.GetBuffer(0));
dwCharCount += ( chsTemp.GetLength() + 1 ) ; }
dwResult = myRegSetValueEx (
hUseKey, // key handle
pValueName, // name of value
0, // reserved -- must be zero
REG_MULTI_SZ, // data type
(const BYTE *)pValue, dwArrayChars );
delete [] pValue; pValue = NULL; } catch ( ... ) { delete [] pValue; pValue = NULL; throw ; } return dwResult ; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: SetCurrentKeyValueExpand(HKEY UseKey, LPCSTR pValueName, CHString &DestValue) Description: sets registry string using REG_EXPAND_SZ, required when the string contains variables (e.g., %SystemRoot%) Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::SetCurrentKeyValueExpand (
HKEY hUseKey, LPCWSTR pValueName, CHString &DestValue ) { DWORD dwResult = myRegSetValueEx (
hUseKey, // key handle
pValueName, // name of value
0, // reserved -- must be zero
REG_EXPAND_SZ, // data type
(const BYTE*)(LPCWSTR)DestValue, ( DestValue.GetLength() + 1 ) * sizeof ( WCHAR ) ); return dwResult ; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: SetCurrentKeyValue(HKEY UseKey, LPCSTR pValueName, CHStringArray &DestValue) Description: sets registry string using REG_MULIT_SZ Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::DeleteCurrentKeyValue (
LPCWSTR pValueName ) { return myRegDeleteValue (
hKey, pValueName ); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Function: SetCurrentKeyValue(HKEY UseKey, LPCSTR pValueName, CHStringArray &DestValue) Description: sets registry string using REG_MULIT_SZ Arguments: Returns: Inputs: Outputs: Caveats: Raid: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DWORD CRegistry::DeleteCurrentKeyValue (
HKEY UseKey, LPCWSTR pValueName ) { return myRegDeleteValue (
UseKey, pValueName ); }
//*****************************************************************
///////////////////////////////////////////////////////////////////
//
// Class: CRegistrySearch
//
// This class searches through the registry for matching Values,
// Keys and Partial Keys
//
///////////////////////////////////////////////////////////////////
//*****************************************************************
CRegistrySearch::CRegistrySearch() { }
///////////////////////////////////////////////////////////////////
CRegistrySearch::~CRegistrySearch() { }
///////////////////////////////////////////////////////////////////
//
// void CRegistrySearch::CheckAndAddToList( CRegistry * pReg,
// CHString chsSubKey,
// CHString chsFullKey,
// CHPtrArray & chpaList,
// CHString chsSearchString,
// int nSearchType)
//
// Desc: This function performs the requested search on the
// current key and if it matches, then adds it to the
// CHPtrArray
//
// Parameters:
// pReg - The current registry class
// chsSubKey - The current Key
// chsFullKey - The complete key
// chpaList - The target CHPtrArray
// chsSearchString - The string to search for
// nSearchType - The type of search, the following are
// supported:
// KEY_FULL_MATCH_SEARCH
// Only keys that match the chsSearchString
// KEY_PARTIAL_MATCH_SEARCH
// Keys that have chsSearchString anywhere in them
// VALUE_SEARCH
// Values that match chsSearchString
//
// History
// Initial coding jennymc 10/10/96
//
///////////////////////////////////////////////////////////////////
void CRegistrySearch::CheckAndAddToList (
CRegistry * pReg, CHString chsSubKey, CHString chsFullKey, CHPtrArray & chpaList, CHString chsSearchString, CHString chsValue, int nSearchType ) { BOOL bFound = FALSE;
//====================================================
// We need to check out the current key to see if it
// matches any of our criteria.
//====================================================
if( nSearchType == VALUE_SEARCH ) { //====================================================
// If it is a Value search, then let us try to open
// the value.
//====================================================
CHString chsTmp ;
if( pReg->GetCurrentSubKeyValue(chsValue, chsTmp) == ERROR_SUCCESS) { if( chsSearchString.CompareNoCase(chsTmp) == 0 ) { bFound = TRUE; } } } else if( nSearchType == KEY_FULL_MATCH_SEARCH ) { if( chsSearchString == chsSubKey ) { bFound = TRUE; } } else { if( chsSubKey.Find(chsSearchString) ) { bFound = TRUE; } } //====================================================
// If it was found, then record the key location
//====================================================
if( bFound ) { CHString *pchsPtr = new CHString; if ( pchsPtr ) { try { *pchsPtr = chsFullKey; chpaList.Add( pchsPtr ); } catch ( ... ) { delete pchsPtr ; pchsPtr = NULL; throw ; } } else { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } } }
///////////////////////////////////////////////////////////////////
// Public function: Documented in cregcls.h
//
// History
// Initial coding jennymc 10/10/96
//
///////////////////////////////////////////////////////////////////
BOOL CRegistrySearch::SearchAndBuildList (
CHString chsRootKey, CHPtrArray & cpaList, CHString chsSearchString, CHString chsValue, int nSearchType, HKEY hkDefault ) { BOOL bRc;
//=======================================================
// Allocate a registry class to open and enumerate the
// requested key.
//=======================================================
CRegistry *pReg = new CRegistry; if( !pReg ) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; }
try { //=======================================================
// If the key cannot be opened, then cleanup and back
// out.
//=======================================================
if( pReg->OpenAndEnumerateSubKeys(hkDefault,chsRootKey, KEY_READ ) != ERROR_SUCCESS ) { delete pReg ; pReg = NULL; return FALSE; }
try { CHString chsSubKey ;
//=======================================================
// As long as there are subkeys under this key,
// let us open and enumerate each one, each time
// checking if it has the value or part of the
// string we want.
//
// The GetCurrentSubKeyName function only returns the
// current key, we have to add it to the end of the
// Parent key in order to get the full key name.
//=======================================================
while ( pReg->GetCurrentSubKeyName(chsSubKey) == ERROR_SUCCESS ) { CHString chsFullKey ; CHString chsSlash = L"\\";
chsFullKey = chsRootKey + chsSlash + chsSubKey;
CheckAndAddToList (
pReg, chsSubKey, chsFullKey, cpaList, chsSearchString, chsValue, nSearchType );
pReg->NextSubKey();
bRc = SearchAndBuildList (
chsFullKey, cpaList, chsSearchString, chsValue, nSearchType ); }
//=======================================================
// Close the current key and delete the registry pointer
//=======================================================
pReg->Close();
} catch ( ... ) { pReg->Close();
throw ; }
delete pReg; pReg = NULL; } catch ( ... ) { delete pReg ; pReg = NULL; throw ; }
return TRUE; }
///////////////////////////////////////////////////////////////////
BOOL CRegistrySearch::FreeSearchList (
int nType, CHPtrArray & cpaList ) { BOOL bRc; int i; int nNum = cpaList.GetSize();
switch( nType ) { case CSTRING_PTR: { CHString *pPtr; for ( i=0; i < nNum; i++ ) { pPtr = ( CHString * ) cpaList.GetAt(i); delete pPtr; pPtr = NULL; } bRc = TRUE; } break;
default: { bRc = FALSE; } break; }
if( bRc ) { cpaList.RemoveAll(); }
return bRc; }
//////////////////////////////////////////////////////////////////////////////
//
// FUNCTION : MOPropertySet_DevMem::LocateNTOwnerDevice
//
// DESCRIPTION : Helper function for locating a key of the specified
// name, or a key containg the specified value name.
//
// INPUTS : HKEY hKeyParent - Parent Key
// LPCWSTR pszKeyName - Name of Key to open
// LPCWSTR pszSubKeyName - Name of SubKey to Find
// LPCWSTR* ppszValueNames - Array of Value Names
// DWORD dwNumValueNames - Number of names in array
//
// OUTPUTS : CHString& strFoundKeyName - Storage for name of key if found.
// CHString& strFoundKeyPath - Storage for pathed key name
//
// RETURNS : nothing
//
// COMMENTS : Recursively Enumerates the registry from a specified
// starting point until it locates a subkey matching either
// a supplied subkey name or a value name matching one of
// the supplied names.
//
//////////////////////////////////////////////////////////////////////////////
BOOL CRegistrySearch::LocateKeyByNameOrValueName(
HKEY hKeyParent, LPCWSTR pszKeyName, LPCWSTR pszSubKeyName, LPCWSTR* ppszValueNames, DWORD dwNumValueNames, CHString& strFoundKeyName, CHString& strFoundKeyPath ) { CRegistry reg; BOOL fFound = FALSE;
// Get out of here if we got garbage parameters
if ( NULL == pszSubKeyName && NULL == ppszValueNames ) { return FALSE; }
// Open the key for enumeration and go through the sub keys.
LONG t_Status = reg.OpenAndEnumerateSubKeys (
hKeyParent, pszKeyName, KEY_READ ) ;
if ( ERROR_SUCCESS == t_Status ) { try { CHString strSubKeyName; DWORD dwValueBuffSize = 0;
// As long as we can get sub keys, we can try to find values.
while ( !fFound && ERROR_SUCCESS == reg.GetCurrentSubKeyName( strSubKeyName ) ) {
// First check if the specified sub key name matches the sub key name.
// If not, then check for the value names.
if ( NULL != pszSubKeyName && strSubKeyName == pszSubKeyName ) { fFound = TRUE; } else if ( NULL != ppszValueNames ) { // Enumerate the value names in the array until one is found.
for ( DWORD dwEnum = 0; !fFound && dwEnum < dwNumValueNames; dwEnum++ ) { t_Status = reg.GetCurrentSubKeyValue(
ppszValueNames[dwEnum], NULL, &dwValueBuffSize ) ;
if ( ERROR_SUCCESS == t_Status ) { fFound = TRUE; }
} // FOR dwEnum
} // IF NULL != ppszValueNames
// Check if one of the methods located the key. If so, store all
// the current values.
if ( !fFound ) { //
// No success, so recurse (WOOHOO!)
//
fFound = LocateKeyByNameOrValueName (
reg.GethKey(), strSubKeyName, pszSubKeyName, ppszValueNames, dwNumValueNames, strFoundKeyName, strFoundKeyPath ); } else { // Store the actual key name in both the single
// name and path. We will build the full path
// as we slide back up the recursive chain.
strFoundKeyName = strSubKeyName; strFoundKeyPath = strSubKeyName; }
// Lastly, since fFound may now have been set by recursion, we will
// want to attach the current key path to the key name we've opened
// so when we return out of here, we get the full path to the
// located key name stored correctly.
if ( fFound ) { CHString strSavePath( strFoundKeyPath ); strFoundKeyPath.Format(L"%s\\%s", (LPCWSTR) pszKeyName, (LPCWSTR) strSavePath ); } else { // Not found yet, so go to the next key.
reg.NextSubKey(); }
} // While !Found
reg.Close(); } catch ( ... ) { reg.Close () ;
throw ; }
} // If OpenAndEnumerateSubKeys
return fFound;
}
//========================================================================================
// These routines are for the multiplatform support
DWORD CRegistry::GetPlatformID(void) { OSVERSIONINFOA OsVersionInfoA;
OsVersionInfoA.dwOSVersionInfoSize = sizeof (OSVERSIONINFOA) ; GetVersionExA(&OsVersionInfoA);
return OsVersionInfoA.dwPlatformId; }
LONG CRegistry::myRegCreateKeyEx (
HKEY hKey, LPCWSTR lpwcsSubKey, DWORD Reserved, LPWSTR lpwcsClass, DWORD dwOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition ) { if (CRegistry::s_dwPlatform == VER_PLATFORM_WIN32_NT) { return RegCreateKeyExW (
hKey, lpwcsSubKey, Reserved, lpwcsClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition ); } else { char *szSubKey = NULL ; bool t_ConversionFailure = false ;
WCSTOANSISTRING ( lpwcsSubKey , szSubKey , t_ConversionFailure ) ; if (t_ConversionFailure) { return ERROR_NO_UNICODE_TRANSLATION; }
char *lpClass = NULL ; t_ConversionFailure = false ;
WCSTOANSISTRING ( lpwcsClass , lpClass , t_ConversionFailure ); if (t_ConversionFailure) { return ERROR_NO_UNICODE_TRANSLATION; } return RegCreateKeyExA (
hKey, szSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition ); } return ERROR_NO_UNICODE_TRANSLATION; }
LONG CRegistry::myRegSetValueEx (
HKEY hKey, LPCWSTR lpwcsSubKey, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData ) { LONG lRet;
if ( CRegistry::s_dwPlatform == VER_PLATFORM_WIN32_NT ) { lRet = RegSetValueExW (
hKey, lpwcsSubKey, Reserved, dwType, lpData, cbData ); } else { // First convert the key name
bool t_ConversionFailure = false ; char *pName = NULL ;
if ( lpwcsSubKey != NULL ) { WCSTOANSISTRING ( lpwcsSubKey , pName , t_ConversionFailure ) ; if ( ! t_ConversionFailure ) { if ( ! pName ) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } } else { return ERROR_NO_UNICODE_TRANSLATION ; } }
// Now, we may need to convert the data
BYTE *pMyData = NULL ;
try { DWORD dwMySize = 0 ;
bool bDoit = false ;
switch ( dwType ) { case REG_EXPAND_SZ: case REG_SZ: { // If it's a simple string, convert it
t_ConversionFailure = false ;
WCHAR *pStrUnicode = ( WCHAR * ) lpData ; char *pStrAnsi = NULL ;
WCSTOANSISTRING ( pStrUnicode , pStrAnsi , t_ConversionFailure ) ;
if ( ! t_ConversionFailure ) { if ( pStrAnsi != NULL ) { pMyData = ( BYTE * ) pStrAnsi ; dwMySize = strlen ( pStrAnsi ) ;
bDoit = true ; } else { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } } else { return ERROR_NO_UNICODE_TRANSLATION ; } } break ;
case REG_MULTI_SZ: { // If it's a multi-sz, it take a little more
int nLen = ::WideCharToMultiByte (
CP_ACP , 0 , ( const WCHAR *) lpData , cbData , NULL , 0 , NULL , NULL );
if ( nLen > 0 ) { pMyData = new BYTE [ nLen ] ; if ( pMyData != NULL ) { dwMySize = WideCharToMultiByte (
CP_ACP , 0, ( const WCHAR * ) lpData , cbData , ( char * )pMyData , nLen , NULL , NULL ) ;
bDoit = true; } else { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } } else { lRet = ERROR_NO_UNICODE_TRANSLATION ; } } break ;
default: { // All other types, just write it
pMyData = ( BYTE * ) lpData ; dwMySize = cbData ; bDoit = true; } break ; }
if ( bDoit ) { lRet = RegSetValueExA (
hKey, pName, Reserved, dwType, pMyData, dwMySize ); }
if ( ( dwType == REG_MULTI_SZ ) && ( pMyData != NULL ) ) { delete [] pMyData ; pMyData = NULL; } } catch ( ... ) { if ( ( dwType == REG_MULTI_SZ ) && ( pMyData != NULL ) ) { delete [] pMyData ; pMyData = NULL; }
throw ; } }
return lRet; }
LONG CRegistry::myRegQueryValueEx (
HKEY hKey, LPCWSTR lpwcsSubKey, LPDWORD Reserved, LPDWORD dwType, LPBYTE lpData, LPDWORD cbData ) { LONG lRet;
if ( CRegistry::s_dwPlatform == VER_PLATFORM_WIN32_NT ) { lRet = RegQueryValueExW (
hKey, lpwcsSubKey, Reserved, dwType, lpData, cbData ); } else { bool t_ConversionFailure = false ; char *pName = NULL ;
if ( lpwcsSubKey != NULL ) { WCSTOANSISTRING ( lpwcsSubKey , pName , t_ConversionFailure ) ; if ( ! t_ConversionFailure ) { if ( ! pName ) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } } else { return ERROR_NO_UNICODE_TRANSLATION ; } }
BYTE *pMyData = NULL ;
try { if ( lpData != NULL ) { pMyData = new BYTE [ *cbData ] ; if ( ! pMyData ) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } }
if ( ( pMyData != NULL ) || (lpData == NULL)) { DWORD dwMySize = *cbData;
lRet = RegQueryValueExA (
hKey, pName, Reserved, dwType, pMyData, & dwMySize ) ;
// If it worked, we may need to convert the strings
if ( lRet == ERROR_SUCCESS ) { switch ( *dwType ) { case REG_EXPAND_SZ: case REG_SZ: { // If lpData is null, there isn't any way to say for sure how long the target string needs
// to be. However, it can't be more than twice as long (it can be less).
if (lpData == NULL) { *cbData = dwMySize * 2; } else { int nLen = ::MultiByteToWideChar (
CP_ACP, 0, (const char *)pMyData, -1, (WCHAR *)lpData, *cbData ); // Convert to bytes
*cbData = nLen * 2; } } break ;
case REG_MULTI_SZ: { // If lpData is null, there isn't any way to say for sure how long the target string needs
// to be. However, it can't be more than twice as long (it can be less).
if (lpData == NULL) { *cbData = dwMySize * 2; } else { DWORD dwConverted = MultiByteToWideChar (
CP_ACP, 0, (const char *)pMyData, dwMySize, (WCHAR *)lpData, *cbData ); } } break ;
default: { // All other types are handled in RegQueryValue
*cbData = dwMySize ;
if( NULL != lpData ) { memcpy ( lpData , pMyData , *cbData ) ; } } break ; } }
delete [] pMyData; pMyData = NULL; } } catch ( ... ) { delete [] pMyData ; pMyData = NULL; throw ; } }
return lRet; }
LONG CRegistry::myRegEnumKey (
HKEY hKey, DWORD dwIndex, LPWSTR lpwcsName, DWORD cbData // number of characters in the lpwcsName buffer
) { if (CRegistry::s_dwPlatform == VER_PLATFORM_WIN32_NT) { return RegEnumKeyW (
hKey, dwIndex, lpwcsName, cbData ); } else { char szName[MAX_SUBKEY_BUFFERSIZE];
LONG lRet = RegEnumKeyA (
hKey, dwIndex, szName, sizeof(szName)/sizeof(szName[0]) );
if (lRet == ERROR_SUCCESS) { bool t_ConversionFailure = false ; WCHAR *pName = NULL ; // MAX_SUBKEY_BUFFERSIZE <= _MAX_PATH
ANSISTRINGTOWCS ( szName , pName , t_ConversionFailure ) ; if ( ! t_ConversionFailure ) { if ( pName ) { StringCchCopyW(lpwcsName, cbData, pName); } else { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } } else { return ERROR_NO_UNICODE_TRANSLATION ; } }
return lRet; } }
LONG CRegistry::myRegDeleteValue (
HKEY hKey, LPCWSTR lpwcsName ) { if ( CRegistry::s_dwPlatform == VER_PLATFORM_WIN32_NT ) { return RegDeleteValueW (
hKey, lpwcsName ); } else { bool t_ConversionFailure = false ; char *pName = NULL ; WCSTOANSISTRING ( lpwcsName, pName , t_ConversionFailure ) ;
if ( ! t_ConversionFailure ) { if ( pName ) { return RegDeleteValueA (
hKey, pName ); } else { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } } else { return ERROR_NO_UNICODE_TRANSLATION ; } } return ERROR_NO_UNICODE_TRANSLATION; }
LONG CRegistry::myRegDeleteKey (
HKEY hKey, LPCWSTR lpwcsName ) { if ( CRegistry::s_dwPlatform == VER_PLATFORM_WIN32_NT ) { return RegDeleteKeyW (
hKey, lpwcsName ); } else { bool t_ConversionFailure = false ; char *pName = NULL ; WCSTOANSISTRING ( lpwcsName, pName , t_ConversionFailure ) ;
if ( ! t_ConversionFailure ) { if ( pName ) { return RegDeleteKeyA (
hKey, pName ); } else { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } } else { return ERROR_NO_UNICODE_TRANSLATION ; } } return ERROR_NO_UNICODE_TRANSLATION; }
LONG CRegistry::myRegOpenKeyEx (
HKEY hKey, LPCWSTR lpwcsSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult ) { if (CRegistry::s_dwPlatform == VER_PLATFORM_WIN32_NT) { return RegOpenKeyExW (
hKey, lpwcsSubKey, ulOptions, samDesired, phkResult ); }
char *pName = NULL ; bool t_ConversionFailure = false ;
WCSTOANSISTRING ( lpwcsSubKey, pName , t_ConversionFailure ); if ( ! t_ConversionFailure ) { if ( pName ) { return RegOpenKeyExA (
hKey, pName, ulOptions, samDesired, phkResult ); } else { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } }
return ERROR_NO_UNICODE_TRANSLATION; }
LONG CRegistry::myRegQueryInfoKey (
HKEY hKey, LPWSTR lpwstrClass, LPDWORD lpcbClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcbMaxSubKeyLen, LPDWORD lpcbMaxClassLen, LPDWORD lpcValues, LPDWORD lpcbMaxValueNameLen, LPDWORD lpcbMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime ) { if ( CRegistry::s_dwPlatform == VER_PLATFORM_WIN32_NT ) { return RegQueryInfoKeyW (
hKey, lpwstrClass, lpcbClass, lpReserved, lpcSubKeys, lpcbMaxSubKeyLen, lpcbMaxClassLen, lpcValues, lpcbMaxValueNameLen, lpcbMaxValueLen, lpcbSecurityDescriptor, lpftLastWriteTime ); } else { bool t_ConversionFailure = false ; char *pName = NULL ; WCSTOANSISTRING ( lpwstrClass, pName, t_ConversionFailure );
if ( ! t_ConversionFailure ) { if ( pName ) {
return RegQueryInfoKeyA (
hKey, pName, lpcbClass, lpReserved, lpcSubKeys, lpcbMaxSubKeyLen, lpcbMaxClassLen, lpcValues, lpcbMaxValueNameLen, lpcbMaxValueLen, lpcbSecurityDescriptor, lpftLastWriteTime ) ; } else { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } } else { return ERROR_NO_UNICODE_TRANSLATION; } } return ERROR_NO_UNICODE_TRANSLATION; }
LONG CRegistry::myRegEnumValue (
HKEY hKey, DWORD dwIndex, LPWSTR lpValueName, LPDWORD lpcbValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData ) { if (CRegistry::s_dwPlatform == VER_PLATFORM_WIN32_NT) { return RegEnumValueW (
hKey, dwIndex, lpValueName, lpcbValueName, lpReserved, lpType, lpData, lpcbData ); } else { char szData[MAX_PATH * 2];
LONG lRet = RegEnumValueA (
hKey, dwIndex, szData, lpcbValueName, lpReserved, lpType, lpData, lpcbData );
if (lRet == ERROR_SUCCESS) { // Get the name.
mbstowcs(lpValueName, szData, lstrlenA(szData) + 1);
// Get the value if the data is a string.
if (*lpType == REG_SZ || *lpType == REG_MULTI_SZ) { StringCchCopyA(szData, sizeof(szData)/sizeof(char), (LPSTR) lpData); mbstowcs((LPWSTR) lpData, szData, lstrlenA(szData) + 1); *lpcbData = (lstrlenW((LPWSTR) lpData) + 1) * sizeof(WCHAR); } }
return lRet; } }
|