/*++ Copyright (c) 1996 Microsoft Corporation Module Name: registry.c Abstract: This module provides a generic table driven access to the registry. Author: Wesley Witt (wesw) 9-June-1996 Revision History: --*/ #include #include #include #include #include "fxsapip.h" #include "faxutil.h" #include "faxreg.h" HKEY OpenRegistryKey( HKEY hKey, LPCTSTR KeyName, BOOL CreateNewKey, REGSAM SamDesired ) { LONG Rslt; HKEY hKeyNew = NULL; DWORD Disposition; if (CreateNewKey) { Rslt = RegCreateKeyEx( hKey, KeyName, 0, NULL, REG_OPTION_NON_VOLATILE, SamDesired == 0 ? (KEY_READ | KEY_WRITE) : SamDesired, NULL, &hKeyNew, &Disposition ); if (Rslt != ERROR_SUCCESS) { // // could not open the registry key // DebugPrint(( TEXT("RegCreateKeyEx() failed, ec=%d"), Rslt )); SetLastError (Rslt); return NULL; } if (Disposition == REG_CREATED_NEW_KEY) { DebugPrint(( TEXT("Created new fax registry key, ec=%d"), Rslt )); } } else { Rslt = RegOpenKeyEx( hKey, KeyName, 0, SamDesired == 0 ? (KEY_READ | KEY_WRITE) : SamDesired, &hKeyNew ); if (Rslt != ERROR_SUCCESS) { // // could not open the registry key // DebugPrint(( TEXT("RegOpenKeyEx() failed, ec=%d"), Rslt )); SetLastError (Rslt); return NULL; } } Assert (hKeyNew); SetLastError (ERROR_SUCCESS); return hKeyNew; } LPTSTR GetRegistryStringValue( HKEY hKey, DWORD RegType, LPCTSTR ValueName, LPCTSTR DefaultValue, LPDWORD StringSize ) { BOOL Success = FALSE; DWORD Size; LONG Rslt; DWORD Type; LPBYTE Buffer = NULL; LPBYTE ExpandBuffer = NULL; LPTSTR ReturnBuff = NULL; Rslt = RegQueryValueEx( hKey, ValueName, NULL, &Type, NULL, &Size ); if (Rslt != ERROR_SUCCESS) { if (Rslt == ERROR_FILE_NOT_FOUND) { if (DefaultValue) { Size = (RegType==REG_MULTI_SZ) ? MultiStringSize(DefaultValue) : StringSize( DefaultValue ); } else { DebugPrint(( TEXT("RegQueryValueEx() failed, ec=%d - and no default value was specified"), Rslt )); goto exit; } } else { DebugPrint(( TEXT("RegQueryValueEx() failed, ec=%d"), Rslt )); goto exit; } } else { if (Type != RegType) { return NULL; } } if (Size == 0) { Size = 32; } Buffer = (LPBYTE) MemAlloc( Size ); if (!Buffer) { goto exit; } Rslt = RegQueryValueEx( hKey, ValueName, NULL, &Type, Buffer, &Size ); if (Rslt != ERROR_SUCCESS) { if (Rslt != ERROR_FILE_NOT_FOUND) { DebugPrint(( TEXT("RegQueryValueEx() failed, ec=%d"), Rslt )); goto exit; } // // create the value since it doesn't exist // if (DefaultValue) { if ( RegType == REG_MULTI_SZ ) { Assert(Size>=MultiStringSize(DefaultValue)); memcpy ( (LPVOID) Buffer, (LPVOID)DefaultValue, MultiStringSize(DefaultValue) ); } else { _tcscpy( (LPTSTR) Buffer, DefaultValue ); } } else { DebugPrint((TEXT("Can't create DefaultValue since it's NULL"))); goto exit; } Rslt = RegSetValueEx( hKey, ValueName, 0, RegType, Buffer, Size ); if (Rslt != ERROR_SUCCESS) { // // could not set the registry value // DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), ValueName, Rslt )); goto exit; } } if (RegType == REG_EXPAND_SZ) { Rslt = ExpandEnvironmentStrings( (LPTSTR) Buffer, NULL, 0 ); if (!Rslt) { goto exit; } Size = (Rslt + 1) * sizeof(WCHAR); ExpandBuffer = (LPBYTE) MemAlloc( Size ); if (!ExpandBuffer) { goto exit; } Rslt = ExpandEnvironmentStrings( (LPTSTR) Buffer, (LPTSTR) ExpandBuffer, Rslt ); if (Rslt == 0) { MemFree( ExpandBuffer ); ExpandBuffer = NULL; DebugPrint(( TEXT("ExpandEnvironmentStrings() failed, ec=%d"), GetLastError() )); goto exit; } MemFree( Buffer ); Buffer = ExpandBuffer; } Success = TRUE; if (StringSize) { *StringSize = Size; } exit: if (!Success) { MemFree( Buffer ); if (StringSize) { *StringSize = 0; } if (DefaultValue) { Size = (RegType==REG_MULTI_SZ) ? MultiStringSize(DefaultValue) : StringSize( DefaultValue ); ReturnBuff = (LPTSTR) MemAlloc( Size ); if ( !ReturnBuff ) return NULL; if ( RegType == REG_MULTI_SZ ) memcpy ( (LPVOID)ReturnBuff, (LPVOID)DefaultValue, Size ); else _tcscpy( ReturnBuff, DefaultValue ); if (StringSize) { *StringSize = Size; } return ReturnBuff; } else { return NULL; } } return (LPTSTR) Buffer; } LPTSTR GetRegistryString( HKEY hKey, LPCTSTR ValueName, LPCTSTR DefaultValue ) { return GetRegistryStringValue( hKey, REG_SZ, ValueName, DefaultValue, NULL ); } LPTSTR GetRegistryStringExpand( HKEY hKey, LPCTSTR ValueName, LPCTSTR DefaultValue ) { return GetRegistryStringValue( hKey, REG_EXPAND_SZ, ValueName, DefaultValue, NULL ); } LPTSTR GetRegistryStringMultiSz( HKEY hKey, LPCTSTR ValueName, LPCTSTR DefaultValue, LPDWORD StringSize ) { return GetRegistryStringValue( hKey, REG_MULTI_SZ, ValueName, DefaultValue, StringSize ); } /*++ Routine Description: Reads a REG_DWORD value from the registry. If the value doesn't exist, creates the value with the default value provided. Arguments: hKey [in] - Handle to an open registry key lpszValueName [in] - Registry value name lpdwDest [out] - Pointer to DWORD that will accept the value dwDefault [in] - Default value to use if value doesn't exist Return Value: TRUE if success FALSE if failed to read/create the value, error in LastError --*/ BOOL GetRegistryDwordDefault(HKEY hKey, LPCTSTR lpszValueName, LPDWORD lpdwDest, DWORD dwDefault) { LONG lError; DWORD dwSize = sizeof(DWORD); DWORD dwType; if (!lpdwDest) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } lError = RegQueryValueEx( hKey, lpszValueName, 0, &dwType, (LPBYTE)lpdwDest, &dwSize); if (lError==ERROR_FILE_NOT_FOUND) { // Not found - create with default value *lpdwDest = dwDefault; lError = RegSetValueEx( hKey, lpszValueName, 0, REG_DWORD, (LPBYTE)lpdwDest, sizeof(DWORD)); if (lError != ERROR_SUCCESS) { DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), lpszValueName, lError )); SetLastError(lError); return FALSE; } return TRUE; } if ((lError!=ERROR_SUCCESS) || (dwType!=REG_DWORD)) { DebugPrint(( TEXT("RegQueryValueEx() failed[%s], ec=%d"), lpszValueName, lError )); SetLastError(lError); return FALSE; } return TRUE; } DWORD GetRegistryDword( HKEY hKey, LPCTSTR ValueName ) { DWORD Value=0; if (!GetRegistryDwordDefault(hKey, ValueName, &Value, 0)) { return 0; } return Value; } LPBYTE GetRegistryBinary( HKEY hKey, LPCTSTR ValueName, LPDWORD DataSize ) { BOOL Success = FALSE; DWORD Size = 0; LONG Rslt; DWORD Type = REG_BINARY; LPBYTE Buffer = NULL; Rslt = RegQueryValueEx( hKey, ValueName, NULL, &Type, NULL, &Size ); if (Rslt != ERROR_SUCCESS) { if (Rslt == ERROR_FILE_NOT_FOUND) { Size = 1; } else { DebugPrint(( TEXT("RegQueryValueEx() failed, ec=%d"), Rslt )); goto exit; } } else { if (Type != REG_BINARY) { return NULL; } } if (Size == 0) { Size = 1; } Buffer = (LPBYTE) MemAlloc( Size ); if (!Buffer) { goto exit; } Rslt = RegQueryValueEx( hKey, ValueName, NULL, &Type, Buffer, &Size ); if (Rslt != ERROR_SUCCESS) { if (Rslt != ERROR_FILE_NOT_FOUND) { DebugPrint(( TEXT("RegQueryValueEx() failed, ec=%d"), Rslt )); goto exit; } // // create the value since it doesn't exist // Rslt = RegSetValueEx( hKey, ValueName, 0, REG_BINARY, Buffer, Size ); if (Rslt != ERROR_SUCCESS) { // // could not set the registry value // DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), ValueName, Rslt )); goto exit; } } Success = TRUE; if (DataSize) { *DataSize = Size; } exit: if (!Success) { MemFree( Buffer ); return NULL; } return Buffer; } DWORD GetSubKeyCount( HKEY hKey ) { DWORD KeyCount = 0; LONG Rval; Rval = RegQueryInfoKey( hKey, NULL, NULL, NULL, &KeyCount, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); if (Rval != ERROR_SUCCESS) { return 0; } return KeyCount; } DWORD GetMaxSubKeyLen( HKEY hKey ) { DWORD MaxSubKeyLen = 0; LONG Rval; Rval = RegQueryInfoKey( hKey, NULL, NULL, NULL, NULL, &MaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL ); if (Rval != ERROR_SUCCESS) { return 0; } return MaxSubKeyLen; } BOOL SetRegistryDword( HKEY hKey, LPCTSTR ValueName, DWORD Value ) { LONG Rslt; Rslt = RegSetValueEx( hKey, ValueName, 0, REG_DWORD, (LPBYTE) &Value, sizeof(DWORD) ); if (Rslt != ERROR_SUCCESS) { DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), ValueName, Rslt )); SetLastError (Rslt); return FALSE; } return TRUE; } BOOL SetRegistryBinary( HKEY hKey, LPCTSTR ValueName, const LPBYTE Value, LONG Length ) { LONG Rslt; Rslt = RegSetValueEx( hKey, ValueName, 0, REG_BINARY, (LPBYTE) Value, Length ); if (Rslt != ERROR_SUCCESS) { DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), ValueName, Rslt )); return FALSE; } return TRUE; } BOOL SetRegistryStringValue( HKEY hKey, DWORD RegType, LPCTSTR ValueName, LPCTSTR Value, LONG Length ) { LONG Rslt; Rslt = RegSetValueEx( hKey, ValueName, 0, RegType, (LPBYTE) Value, Length == -1 ? StringSize( Value ) : Length ); if (Rslt != ERROR_SUCCESS) { DebugPrint(( TEXT("RegSetValueEx() failed[%s], ec=%d"), ValueName, Rslt )); return FALSE; } return TRUE; } BOOL SetRegistryString( HKEY hKey, LPCTSTR ValueName, LPCTSTR Value ) { return SetRegistryStringValue( hKey, REG_SZ, ValueName, Value, -1 ); } BOOL SetRegistryStringExpand( HKEY hKey, LPCTSTR ValueName, LPCTSTR Value ) { return SetRegistryStringValue( hKey, REG_EXPAND_SZ, ValueName, Value, -1 ); } BOOL SetRegistryStringMultiSz( HKEY hKey, LPCTSTR ValueName, LPCTSTR Value, DWORD Length ) { return SetRegistryStringValue( hKey, REG_MULTI_SZ, ValueName, Value, Length ); } DWORD EnumerateRegistryKeys( HKEY hKey, LPCTSTR KeyName, BOOL ChangeValues, PREGENUMCALLBACK EnumCallback, LPVOID ContextData ) { LONG Rslt; HKEY hSubKey = NULL; HKEY hKeyEnum = NULL; DWORD Index = 0; DWORD MaxSubKeyLen; DWORD SubKeyCount; LPTSTR SubKeyName = NULL; hSubKey = OpenRegistryKey( hKey, KeyName, ChangeValues, ChangeValues ? (KEY_READ | KEY_WRITE) : KEY_READ ); if (!hSubKey) { goto exit; } Rslt = RegQueryInfoKey( hSubKey, NULL, NULL, NULL, &SubKeyCount, &MaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL ); if (Rslt != ERROR_SUCCESS) { // // could not open the registry key // DebugPrint(( TEXT("RegQueryInfoKey() failed, ec=%d"), Rslt )); goto exit; } if (!EnumCallback( hSubKey, NULL, SubKeyCount, ContextData )) { goto exit; } MaxSubKeyLen += 4; SubKeyName = (LPTSTR) MemAlloc( (MaxSubKeyLen+1) * sizeof(WCHAR) ); if (!SubKeyName) { goto exit; } while( TRUE ) { Rslt = RegEnumKey( hSubKey, Index, (LPTSTR) SubKeyName, MaxSubKeyLen ); if (Rslt != ERROR_SUCCESS) { if (Rslt == ERROR_NO_MORE_ITEMS) { break; } DebugPrint(( TEXT("RegEnumKey() failed, ec=%d"), Rslt )); goto exit; } hKeyEnum = OpenRegistryKey( hSubKey, SubKeyName, ChangeValues, ChangeValues ? (KEY_READ | KEY_WRITE) : KEY_READ ); if (!hKeyEnum) { continue; } if (!EnumCallback( hKeyEnum, SubKeyName, Index, ContextData )) { RegCloseKey( hKeyEnum ); break; } RegCloseKey( hKeyEnum ); Index += 1; } exit: if (hSubKey) { RegCloseKey( hSubKey ); } MemFree( SubKeyName ); return Index; } BOOL DeleteRegistryKey( HKEY hKey, LPCTSTR SubKey ) { HKEY hKeyCurrent=NULL; TCHAR szName[MAX_PATH]; DWORD dwName; long lResult; DEBUG_FUNCTION_NAME(TEXT("DeleteRegistryKey")); lResult = RegOpenKeyEx(hKey,SubKey,0,KEY_READ | KEY_WRITE | DELETE, &hKeyCurrent); if (lResult != ERROR_SUCCESS) { DebugPrintEx( DEBUG_ERR, TEXT("RegOpenKeyEx failed with %ld"), lResult); SetLastError (lResult); return FALSE; } for (;;) { dwName = sizeof(szName)/sizeof(TCHAR); lResult = RegEnumKeyEx(hKeyCurrent, 0, szName, &dwName, NULL, NULL, NULL, NULL); if (lResult == ERROR_SUCCESS) { if (!DeleteRegistryKey(hKeyCurrent,szName)) { // // Some sons a NOT deleted. You can stop trying to remove stuff now. // return FALSE; } } else if (lResult == ERROR_NO_MORE_ITEMS) { // // No more sons, can delete father key // break; } else { // // other error // DebugPrintEx( DEBUG_ERR, TEXT("RegEnumKeyExKey failed with %ld"), lResult); RegCloseKey(hKeyCurrent); SetLastError (lResult); return FALSE; } } RegCloseKey(hKeyCurrent); lResult = RegDeleteKey(hKey, SubKey); if (ERROR_SUCCESS != lResult) { DebugPrintEx( DEBUG_ERR, TEXT("RegDeleteKey failed with %ld"), lResult); SetLastError (lResult); return FALSE; } return TRUE; } DWORD GetRegistryDwordEx( HKEY hKey, LPCTSTR ValueName, LPDWORD lpdwValue ) /*++ Routine name : GetRegistryDwordEx Routine description: Retrieves a dword from the registry. Author: Oded Sacher (OdedS), Dec, 1999 Arguments: hKey [in ] - Handle to the open key ValueName [in ] - The value name lpdwValue [out ] - Pointer to a DWORD to recieve the value Return Value: Standard win 32 error code --*/ { DWORD dwRes = ERROR_SUCCESS; DWORD dwType= REG_DWORD; DWORD dwSize=0; DEBUG_FUNCTION_NAME(TEXT("GetRegistryDwordEx")); Assert (ValueName && lpdwValue); dwRes = RegQueryValueEx( hKey, ValueName, NULL, &dwType, NULL, &dwSize ); if (ERROR_SUCCESS != dwRes) { DebugPrintEx( DEBUG_ERR, TEXT("RegQueryValueEx failed with %ld"), dwRes); goto exit; } if (REG_DWORD != dwType) { // We expect only DWORD data here DebugPrintEx( DEBUG_ERR, TEXT("Error not a DWORD type")); dwRes = ERROR_BADDB; // The configuration registry database is corrupt. goto exit; } dwRes = RegQueryValueEx( hKey, ValueName, NULL, &dwType, (LPBYTE)lpdwValue, &dwSize ); if (ERROR_SUCCESS != dwRes) { DebugPrintEx( DEBUG_ERR, TEXT("RegQueryValueEx failed with %ld"), dwRes); goto exit; } Assert (ERROR_SUCCESS == dwRes); exit: return dwRes; } /*++ Routine name : DeleteDeviceEntry Routine description: Delete service device entry from devices. Author: Caliv Nir (t-nicali), Apr, 2001 Arguments: serverPermanentID [in] - service device ID to be deleted Return Value: Win32 error code --*/ DWORD DeleteDeviceEntry(DWORD serverPermanentID) { DWORD ec = ERROR_SUCCESS; // LastError for this function. HKEY hKeyDevices; TCHAR DevicesKeyName[MAX_PATH]; DEBUG_FUNCTION_NAME(TEXT("DeleteDeviceEntry")); // // open - "fax\Devices\serverPermanentID" Registry Key // _stprintf( DevicesKeyName, TEXT("%s\\%010lu"), REGKEY_FAX_DEVICES, serverPermanentID ); hKeyDevices = OpenRegistryKey( HKEY_LOCAL_MACHINE, DevicesKeyName, FALSE, KEY_READ | KEY_WRITE ); if (!hKeyDevices) { ec = GetLastError(); DebugPrintEx( DEBUG_WRN, TEXT("OpenRegistryKey failed with [%ld] the device entry might be missing."), ec ); return ec; } // // delete our servers data (under GUID and "Permanent Lineid" value) // if (!DeleteRegistryKey( hKeyDevices, REGKEY_FAXSVC_DEVICE_GUID)) { DebugPrintEx( DEBUG_WRN, TEXT("DeleteRegistryKey failed, the device GUID might be missing.") ); } if (ERROR_SUCCESS != RegDeleteValue( hKeyDevices, REGVAL_PERMANENT_LINEID)) { DebugPrintEx( DEBUG_WRN, TEXT("RegDeleteValue failed, the device \"PermanentLineID\" might be missing.") ); } // // check to see wheter the key is now empty // DWORD dwcSubKeys = 0; DWORD dwcValues = 0; ec=RegQueryInfoKey( hKeyDevices, // handle to key NULL, NULL, NULL, &dwcSubKeys, // number of subkeys NULL, NULL, &dwcValues, // number of value entries NULL, NULL, NULL, NULL ); if ( ERROR_SUCCESS != ec ) { DebugPrintEx( DEBUG_WRN, TEXT("RegQueryInfoKey Abort deleteion.") ); RegCloseKey(hKeyDevices); return ec; } RegCloseKey(hKeyDevices); if ( (0 == dwcSubKeys) && (0 == dwcValues) ) { // // key is empty delete it // hKeyDevices = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_FAX_DEVICES, FALSE, KEY_WRITE | DELETE); if (!hKeyDevices) { ec = GetLastError(); DebugPrintEx( DEBUG_ERR, TEXT("OpenRegistryKey failed with [%lu], Can't delete key."), ec ); return ec; } DWORD dwLen = _tcslen( REGKEY_FAX_DEVICES ) + 1; Assert((DevicesKeyName + dwLen)); Assert(*(DevicesKeyName + dwLen)); DebugPrintEx( DEBUG_WRN, TEXT("Deleting Device entry %s"), (DevicesKeyName + dwLen) ); ec = RegDeleteKey( hKeyDevices, (DevicesKeyName + dwLen)); if ( ERROR_SUCCESS != ec ) { DebugPrintEx( DEBUG_ERR, TEXT("RegDeleteKey failed, Can't delete key.") ); } RegCloseKey(hKeyDevices); } return ec; } /*++ Routine name : DeleteCacheEntry Routine description: Delete cache entry for a given Tapi ID Author: Caliv Nir (t-nicali), Apr, 2001 Arguments: dwTapiPermanentLineID [in] - device Tapi permament ID Return Value: Win32 Error code (ERROR_SUCCESS on success) --*/ DWORD DeleteCacheEntry(DWORD dwTapiPermanentLineID) { DWORD ec = ERROR_SUCCESS; // LastError for this function. HKEY hKey; TCHAR strTapiPermanentLineID[10]; DEBUG_FUNCTION_NAME(TEXT("DeleteCacheEntry")); // // open - "fax\Device Cache" Registry Key // hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_FAX_DEVICES_CACHE, FALSE, KEY_READ | KEY_WRITE ); if (!hKey) { ec = GetLastError(); DebugPrintEx( DEBUG_ERR, TEXT("OpenRegistryKey failed, Can't delete key.") ); return ec; } _stprintf( strTapiPermanentLineID, TEXT("%08lx"),dwTapiPermanentLineID ); if (!DeleteRegistryKey(hKey, strTapiPermanentLineID)) { ec = GetLastError(); DebugPrintEx( DEBUG_ERR, TEXT("DeleteRegistryKey failed with (%ld), Can't delete key."), ec); } RegCloseKey(hKey); return ec; } /*++ Routine name : DeleteTapiEntry Routine description: Delete Tapi entry when caching from TapiDevices, for a give Tapi ID Author: Caliv Nir (t-nicali), Apr, 2001 Arguments: dwTapiPermanentLineID [in] - device Tapi permament ID Return Value: Win32 Error code (ERROR_SUCCESS on success) --*/ DWORD DeleteTapiEntry(DWORD dwTapiPermanentLineID) { DWORD ec = ERROR_SUCCESS; // LastError for this function. HKEY hKey; TCHAR strTapiPermanentLineID[10]; DEBUG_FUNCTION_NAME(TEXT("DeleteTapiEntry")); // // open - "fax\TAPIDevices" Registry Key // hKey = OpenRegistryKey( HKEY_LOCAL_MACHINE, REGKEY_TAPIDEVICES, FALSE, KEY_READ | KEY_WRITE ); if (!hKey) { DebugPrintEx( DEBUG_ERR, TEXT("OpenRegistryKey failed, Can't delete key.") ); return ERROR_OPEN_FAILED; } _stprintf( strTapiPermanentLineID, TEXT("%08lx"),dwTapiPermanentLineID ); if (!DeleteRegistryKey(hKey, strTapiPermanentLineID)) { ec = GetLastError(); DebugPrintEx( DEBUG_ERR, TEXT("DeleteRegistryKey failed with (%ld), Can't delete key."), ec); } RegCloseKey(hKey); return ec; } /*++ Routine name : CopyRegistrySubkeysByHandle Routine description: Copy a content of one registry key into another Author: Caliv Nir (t-nicali), Apr, 2001 Arguments: hkeyDest [in] - handle for destination registry key hkeySrc [in] - handle for source registry key fForceRestore [in] - do we force restore of this hive? Return Value: Win32 Error code --*/ DWORD CopyRegistrySubkeysByHandle( HKEY hkeyDest, HKEY hkeySrc, BOOL fForceRestore ) { LPTSTR TempPath = NULL; DWORD dwTempPathLength = 0; LPCTSTR strFileName = TEXT("tempCacheFile"); DWORD ec = ERROR_SUCCESS; // LastError for this function. DEBUG_FUNCTION_NAME(TEXT("CopyRegistrySubkeysByHandle")); dwTempPathLength = GetTempPath(0,NULL) + 1; // find out temp path size dwTempPathLength += _tcslen( strFileName ) + 1; // add the length of file name dwTempPathLength += 2; // just to be sure TempPath = (LPTSTR) MemAlloc( dwTempPathLength * sizeof(TCHAR) ); if (!TempPath ) { DebugPrintEx( DEBUG_ERR, TEXT("MemAlloc failed. Can't continue") ); ec = ERROR_NOT_ENOUGH_MEMORY; goto Exit; } if (!GetTempPath( dwTempPathLength, TempPath )) { ec = GetLastError(); DebugPrintEx( DEBUG_ERR, TEXT("GetTempPath failed with [%ld]. Can't continue"), ec); goto Exit; } _tcscat(TempPath,strFileName); // // store hKeySrc in a file // HANDLE hOldPrivilege = EnablePrivilege(SE_BACKUP_NAME); if (INVALID_HANDLE_VALUE != hOldPrivilege) // set proper previlege { ec = RegSaveKey( hkeySrc, // handle to key TempPath, // data file NULL); if (ec != ERROR_SUCCESS) { DebugPrintEx( DEBUG_ERR, TEXT("RegSaveKey failed with [%lu]. Can't continue"), ec ); ReleasePrivilege(hOldPrivilege); goto Exit; } ReleasePrivilege(hOldPrivilege); } else { ec = GetLastError(); DebugPrintEx( DEBUG_ERR, TEXT("EnablePrivilege(SE_BACKUP_NAME) failed with [%lu]. Can't continue"), ec ); goto Exit; } // // restore the registry values from the file into hkeyDest // hOldPrivilege = EnablePrivilege(SE_RESTORE_NAME); if (INVALID_HANDLE_VALUE != hOldPrivilege) // set proper previlege { ec = RegRestoreKey( hkeyDest, // handle to key where restore begins TempPath, // registry file fForceRestore ? REG_FORCE_RESTORE : 0); // options if ( ec != ERROR_SUCCESS) { DebugPrintEx( DEBUG_ERR, TEXT("RegRestoreKey failed. Can't continue") ); ReleasePrivilege(hOldPrivilege); goto Exit; } ReleasePrivilege(hOldPrivilege); } else { ec = GetLastError(); DebugPrintEx( DEBUG_ERR, TEXT("EnablePrivilege(SE_RESTORE_NAME) failed with [%lu]. Can't continue") ); goto Exit; } Exit: if (TempPath) { if (!DeleteFile(TempPath)) { DebugPrintEx( DEBUG_ERR, TEXT("DeleteFile failed. file: %s. (ec=%ld)"), TempPath, GetLastError()); } MemFree(TempPath); } return ec; } /*++ Routine name : CopyRegistrySubkeys Routine description: Copy a content of one registry key into another Author: Caliv Nir (t-nicali), Apr, 2001 Arguments: strDest [in] - string of destination registry key name strSrc [in] - string of source registry key name fForceRestore [in] - do we force restore of the hive? Return Value: Win32 Error Code --*/ DWORD CopyRegistrySubkeys( LPCTSTR strDest, LPCTSTR strSrc, BOOL fForceRestore ) { DWORD ec = ERROR_SUCCESS; // LastError for this function. HKEY hKeyDest; HKEY hKeySrc; DEBUG_FUNCTION_NAME(TEXT("CopyRegistrySubkeys")); // // open source Key // hKeySrc = OpenRegistryKey( HKEY_LOCAL_MACHINE, strSrc, FALSE, KEY_READ ); if (!hKeySrc) { ec = GetLastError(); DebugPrintEx( DEBUG_ERR, TEXT("OpenRegistryKey failed with [%lu], Can't copy keys."), ec ); return ec; } // // open destination Key // hKeyDest = OpenRegistryKey( HKEY_LOCAL_MACHINE, strDest, TRUE, KEY_READ | KEY_WRITE); if (!hKeyDest) { ec = GetLastError(); RegCloseKey (hKeySrc); DebugPrintEx( DEBUG_ERR, TEXT("OpenRegistryKey failed [%lu], Can't copy keys."), ec ); return ec; } // // copy the keys using the registry Keys // ec = CopyRegistrySubkeysByHandle(hKeyDest,hKeySrc,fForceRestore); if ( ERROR_SUCCESS != ec ) { DebugPrintEx( DEBUG_ERR, TEXT("CopyRegistrySubkeysHkey failed with [%lu], Can't copy keys."), ec ); } RegCloseKey (hKeyDest); RegCloseKey (hKeySrc); return ec; }