HOWTO: Implement a RegRestoreKey() Function for Windows 95Last reviewed: October 20, 1997Article ID: Q175329 |
The information in this article applies to:
SUMMARYThis article demonstrates how to implement a RegRestoreKey() function under Windows 95. This process involves several steps that require that you delete both the descendant subkeys and their values before you add the new subkeys and values.
MORE INFORMATION
Step 1: InitializationTo avoid a conflict between two applications that are trying to restore to the same registry key, use a mutex to prevent a second restore from occurring before the first one is completed.
hMutex = CreateMutex( NULL, TRUE, REG_RESTORE); if ( !hMutex ) return GetLastError(); if (GetLastError() == ERROR_ALREADY_EXISTS) { if ((lRet=WaitForSingleObject(hMutex, INFINITE)) != WAIT_OBJECT_0) return lRet; } Step 2: Delete Key ValuesFirst you must delete the specified key's values. To do this, you must first enumerate the key values using RegEnumValue() and then delete them using RegDeleteValue().
for (;;) { cbValue = REGSTR_MAX_VALUE_LENGTH; // reset value length // remove this keys old values lRet = RegEnumValue(hStartKey, // handle of key to query 0, // index of value to query szValue, // address of buffer for value string &cbValue, // address for size of value buffer NULL, // reserved NULL, // address of buffer for type code NULL, // address of buffer for value data NULL // address for size of data buffer ); if ( ERROR_NO_MORE_ITEMS == lRet ) // all values deleted { lRet = ERROR_SUCCESS; break; } else if ( ERROR_SUCCESS == lRet ) { if ((lRet = RegDeleteValue( hStartKey, // handle of key szValue // address of value name )) != ERROR_SUCCESS) return lRet; } else return lRet; } // end for loop Step 3: Delete SubkeysAfter you have deleted the current values you must delete the specified key's subkeys. Do this by enumerating the subkeys using RegEnumKeyEx and then deleting them using RegDeleteKey. In Windows 95, this deletes the current subkeys and all descendant subkeys. After you have completed the deletion, you can add the new subkeys and values.
// delete all subkeys for(;;) { dwSubKeyLength = MAX_PATH; lRet=RegEnumKeyEx( hStartKey, 0, szSubKey, &dwSubKeyLength, NULL, NULL, NULL, NULL ); if(lRet == ERROR_NO_MORE_ITEMS) { lRet = ERROR_SUCCESS; break; } else if(lRet == ERROR_SUCCESS) { if((lRet = RegDeleteKey(hStartKey, szSubKey)) != ERROR_SUCCESS) return lRet; } else return lRet; } // end for loop Step 4: Restore New SubkeysTo add the new values and subkeys, use RegLoadKey to duplicate and load the registry hive into the registry. Once the hive has been loaded, all values and subkeys are enumerated and copied to the specified restore key.
// Load new hive lRet = RegLoadKey(HKEY_USERS, "TEMP_HIVE", szNewHive ); DWORD RegCreateTree(HKEY hTree, HKEY hReplacement) { DWORD cdwClass, dwSubKeyLength, dwDisposition, dwKeyIndex = 0; LPTSTR pSubKey = NULL; TCHAR szSubKey[REGSTR_MAX_VALUE_LENGTH]; // this should be dynamic. TCHAR szClass[REGSTR_MAX_VALUE_LENGTH]; // this should be dynamic. HKEY hNewKey, hKey; DWORD lRet; for(;;) { dwSubKeyLength = REGSTR_MAX_VALUE_LENGTH; cdwClass = REGSTR_MAX_VALUE_LENGTH; lRet=RegEnumKeyEx( hReplacement, dwKeyIndex, szSubKey, &dwSubKeyLength, NULL, szClass, &cdwClass, NULL ); if(lRet == ERROR_NO_MORE_ITEMS) { lRet = ERROR_SUCCESS; break; } else if(lRet == ERROR_SUCCESS) { if ((lRet=RegCreateKeyEx(hTree, szSubKey,0, szClass, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hNewKey, &dwDisposition)) != ERROR_SUCCESS ) break; else // add key values and recurse { if ((lRet=RegCreateValues( hReplacement, szSubKey, hNewKey)) != ERROR_SUCCESS) { CloseHandle(hNewKey); break; } if ( (lRet=RegOpenKeyEx(hReplacement, szSubKey, 0, KEY_ALL_ACCESS, &hKey )) == ERROR_SUCCESS ) { lRet=RegCreateTree(hNewKey, hKey); CloseHandle(hKey); CloseHandle(hNewKey); if ( lRet != ERROR_SUCCESS ) break; } else { CloseHandle(hNewKey); break; } } } else break; ++dwKeyIndex; } // end for loop return lRet; } // end RegCreateTree function DWORD RegCreateValues(HKEY hReplacement, LPCTSTR lpSubKey, HKEY hNewKey) { DWORD cbValue, dwSubKeyIndex=0, dwType, cdwBuf; DWORD dwValues, cbMaxValueData, i; LPTSTR pSubKey = NULL; TCHAR szValue[REGSTR_MAX_VALUE_LENGTH]; // this should be dynamic. HKEY hKey; DWORD lRet = ERROR_SUCCESS; LPBYTE pBuf; if ((lRet=RegOpenKeyEx(hReplacement, lpSubKey, 0, KEY_ALL_ACCESS, &hKey )) == ERROR_SUCCESS) { if ((lRet=RegQueryInfoKey (hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwValues,NULL, &cbMaxValueData, NULL, NULL)) == ERROR_SUCCESS) { if ( dwValues ) { if ((pBuf=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbMaxValueData ))) { for (i = 0; i < dwValues ; i++) { // get values to create cbValue = REGSTR_MAX_VALUE_LENGTH; cdwBuf = cbMaxValueData; lRet = RegEnumValue( hKey, // handle of key to query i, // index of value to query szValue, // buffer for value string &cbValue, // address for size of buffer NULL, // reserved &dwType, // buffer address for type code pBuf, // address of buffer for value data &cdwBuf // address for size of buffer ); if ( ERROR_SUCCESS == lRet ) { if( (lRet=RegSetValueEx(hNewKey, szValue, 0, dwType, (CONST BYTE *)pBuf, cdwBuf))!= ERROR_SUCCESS) break; } else break; } // for loop } HeapFree(GetProcessHeap(), 0, pBuf); } } CloseHandle(hKey); } return lRet; } // end of RegCreateValues function Step 5: Clean UpWhen all operations have been completed, the registry hive that was loaded is unloaded and the mutex is released to allow other restores to begin.
// UnLoad user hive lRet = RegUnLoadKey(HKEY_USERS, "TEMP_HIVE"); ReleaseMutex(hMutex); |
Additional query words: win95 regedit
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |