Microsoft KB Archive/175329: Difference between revisions
m (1 revision imported: importing part 2) |
m (Text replacement - "&" to "&") |
||
(2 intermediate revisions by the same user not shown) | |||
Line 58: | Line 58: | ||
0, // index of value to query | 0, // index of value to query | ||
szValue, // address of buffer for value string | szValue, // address of buffer for value string | ||
& | &cbValue, // address for size of value buffer | ||
NULL, // reserved | NULL, // reserved | ||
NULL, // address of buffer for type code | NULL, // address of buffer for type code | ||
Line 95: | Line 95: | ||
0, | 0, | ||
szSubKey, | szSubKey, | ||
& | &dwSubKeyLength, | ||
NULL, | NULL, | ||
NULL, | NULL, | ||
Line 120: | Line 120: | ||
<pre class="CODESAMP"> // Load new hive | <pre class="CODESAMP"> // Load new hive | ||
lRet = RegLoadKey(HKEY_USERS, | lRet = RegLoadKey(HKEY_USERS, "TEMP_HIVE", szNewHive ); | ||
DWORD RegCreateTree(HKEY hTree, HKEY hReplacement) | DWORD RegCreateTree(HKEY hTree, HKEY hReplacement) | ||
Line 140: | Line 140: | ||
dwKeyIndex, | dwKeyIndex, | ||
szSubKey, | szSubKey, | ||
& | &dwSubKeyLength, | ||
NULL, | NULL, | ||
szClass, | szClass, | ||
& | &cdwClass, | ||
NULL | NULL | ||
); | ); | ||
Line 155: | Line 155: | ||
if ((lRet=RegCreateKeyEx(hTree, szSubKey,0, szClass, | if ((lRet=RegCreateKeyEx(hTree, szSubKey,0, szClass, | ||
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, | REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, | ||
& | &hNewKey, &dwDisposition)) != ERROR_SUCCESS ) | ||
break; | break; | ||
else // add key values and recurse | else // add key values and recurse | ||
Line 166: | Line 166: | ||
} | } | ||
if ( (lRet=RegOpenKeyEx(hReplacement, szSubKey, 0, | if ( (lRet=RegOpenKeyEx(hReplacement, szSubKey, 0, | ||
KEY_ALL_ACCESS, & | KEY_ALL_ACCESS, &hKey )) == ERROR_SUCCESS ) | ||
{ | { | ||
lRet=RegCreateTree(hNewKey, hKey); | lRet=RegCreateTree(hNewKey, hKey); | ||
Line 201: | Line 201: | ||
if ((lRet=RegOpenKeyEx(hReplacement, lpSubKey, 0, | if ((lRet=RegOpenKeyEx(hReplacement, lpSubKey, 0, | ||
KEY_ALL_ACCESS, & | KEY_ALL_ACCESS, &hKey )) == ERROR_SUCCESS) | ||
{ | { | ||
if ((lRet=RegQueryInfoKey (hKey, NULL, NULL, NULL, NULL, NULL, | if ((lRet=RegQueryInfoKey (hKey, NULL, NULL, NULL, NULL, NULL, | ||
NULL, & | NULL, &dwValues,NULL, &cbMaxValueData, | ||
NULL, NULL)) == ERROR_SUCCESS) | NULL, NULL)) == ERROR_SUCCESS) | ||
{ | { | ||
Line 212: | Line 212: | ||
cbMaxValueData ))) | cbMaxValueData ))) | ||
{ | { | ||
for (i = 0; i | for (i = 0; i < dwValues ; i++) | ||
{ | { | ||
// get values to create | // get values to create | ||
Line 221: | Line 221: | ||
i, // index of value to query | i, // index of value to query | ||
szValue, // buffer for value string | szValue, // buffer for value string | ||
& | &cbValue, // address for size of buffer | ||
NULL, // reserved | NULL, // reserved | ||
& | &dwType, // buffer address for type code | ||
pBuf, // address of buffer for value data | pBuf, // address of buffer for value data | ||
& | &cdwBuf // address for size of buffer | ||
); | ); | ||
Line 253: | Line 253: | ||
<pre class="CODESAMP"> // UnLoad user hive | <pre class="CODESAMP"> // UnLoad user hive | ||
lRet = RegUnLoadKey(HKEY_USERS, | lRet = RegUnLoadKey(HKEY_USERS, "TEMP_HIVE"); | ||
ReleaseMutex(hMutex); </pre> | ReleaseMutex(hMutex); </pre> | ||
Additional query words: win95 regedit | Additional query words: win95 regedit |
Latest revision as of 12:30, 21 July 2020
HOWTO: Implement a RegRestoreKey() Function for Windows 95 |
Q175329
The information in this article applies to:
- Microsoft Win32 Application Programming Interface (API), included with:
- Microsoft Windows 95
SUMMARY
This 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: Initialization
To 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 Values
First 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 Subkeys
After 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 Subkeys
To 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 Up
When 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
Keywords : kbKernBase kbRegistry kbGrpDSKernBase
Issue type : kbhowto
Technology : kbAudDeveloper kbWin32sSearch kbWin32API
Last Reviewed: December 16, 2000 |