Microsoft KB Archive/175329

{|
 * width="100%"|

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.

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