Microsoft KB Archive/175329: Difference between revisions

From BetaArchive Wiki
m (Text replacement - """ to """)
m (Text replacement - "&" to "&")
 
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
                 &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,
                       &dwSubKeyLength,
                         NULL,
                         NULL,
                         NULL,
                         NULL,
Line 140: Line 140:
                   dwKeyIndex,
                   dwKeyIndex,
                   szSubKey,
                   szSubKey,
                   &dwSubKeyLength,
                   &dwSubKeyLength,
                   NULL,
                   NULL,
                   szClass,
                   szClass,
                   &cdwClass,
                   &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 )
                       &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, &hKey )) == ERROR_SUCCESS )
                               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, &hKey )) == ERROR_SUCCESS)
                     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, &dwValues,NULL, &cbMaxValueData,
                       NULL, &dwValues,NULL, &cbMaxValueData,
                       NULL, NULL)) == ERROR_SUCCESS)
                       NULL, NULL)) == ERROR_SUCCESS)
         {
         {
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
                                 &cbValue, // address for size of buffer
                                 NULL,    // reserved
                                 NULL,    // reserved
                                 &dwType,  // buffer address for type code
                                 &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
                                 &cdwBuf  // address for size of buffer
                                 );
                                 );



Latest revision as of 11: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
© 2001 Microsoft Corporation. All rights reserved. Terms of Use.