ID: Q175329
The information in this article applies to:
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.
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;
}
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
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
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
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 kbGrpKernBase
Platform : Win95
Issue type : kbhowto
Last Reviewed: October 22, 1997