Article ID: 128731
Article Last Modified on 11/21/2006
LONG SaveRegistrySubKey(
HKEY hKey, // handle of key to save
LPTSTR szSubKey, // pointer to subkey name to save
LPTSTR szSaveFileName // pointer to save path/filename
)
If the function succeeds, the return value is ERROR_SUCCESS.
If the function fails, the return value is an error value.
/* Save HKEY_LOCAL_MACHINE registry key, each subkey saved to a file of
* name subkey
*
* this allows us to get around security restrictions which prevent
* the use of RegSaveKey() on the root key
*
* the optional target machine name is specified in argv[1]
*
* v1.21
* Scott Field (sfield) 01-Apr-1995
*/
#define RTN_OK 0
#define RTN_USAGE 1
#define RTN_ERROR 13
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
LONG SaveRegistrySubKey(HKEY hKey, LPTSTR szSubKey, LPTSTR szSaveFileName);
void PERR(LPTSTR szAPI, DWORD dwLastError);
int main(int argc, char *argv[])
{
TOKEN_PRIVILEGES tp;
HANDLE hToken;
LUID luid;
LONG rc; // contains error value returned by Regxxx()
HKEY hKey; // handle to key we are interested in
LPTSTR MachineName=NULL; // pointer to machine name
DWORD dwSubKeyIndex=0; // index into key
char szSubKey[_MAX_FNAME]; // this should be dynamic.
// _MAX_FNAME is good because this
// is what we happen to save the
// subkey as
DWORD dwSubKeyLength=_MAX_FNAME; // length of SubKey buffer
/*
if (argc != 2) // usage
{
fprintf(stderr,"Usage: %s [<MachineName>]\n", argv[0]);
return RTN_USAGE;
}
*/
// set MachineName == argv[1], if appropriate
if (argc == 2) MachineName=argv[1];
//
// enable backup privilege
//
if(!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES,
&hToken ))
{
PERR("OpenProcessToken", GetLastError() );
return RTN_ERROR;
}
if(!LookupPrivilegeValue(MachineName, SE_BACKUP_NAME, &luid))
{
PERR("LookupPrivilegeValue", GetLastError() );
return RTN_ERROR;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
NULL, NULL );
if (GetLastError() != ERROR_SUCCESS)
{
PERR("AdjustTokenPrivileges", GetLastError() );
return RTN_ERROR;
}
// only connect if a machine name specified
if (MachineName != NULL)
{
if((rc=RegConnectRegistry(MachineName,
HKEY_LOCAL_MACHINE,
&hKey)) != ERROR_SUCCESS)
{
PERR("RegConnectRegistry", rc);
return RTN_ERROR;
}
}
else hKey=HKEY_LOCAL_MACHINE;
while((rc=RegEnumKeyEx(
hKey,
dwSubKeyIndex,
szSubKey,
&dwSubKeyLength,
NULL,
NULL,
NULL,
NULL)
) != ERROR_NO_MORE_ITEMS) { // are we done?
if(rc == ERROR_SUCCESS)
{
LONG lRetVal; // return value from SaveRegistrySubKey
#ifdef DEBUG
fprintf(stdout,"Saving %s\n", szSubKey);
#endif
// save registry subkey szSubKey to filename szSubKey
if( (lRetVal=SaveRegistrySubKey(hKey, szSubKey, szSubKey)
) != ERROR_SUCCESS)
{
PERR("SaveRegistrySubKey", lRetVal);
}
// increment index into the key
dwSubKeyIndex++;
// reset buffer size
dwSubKeyLength=_MAX_FNAME;
// Continue the festivities
continue;
}
else
{
//
// note: we need to watch for ERROR_MORE_DATA
// this indicates we need a bigger szSubKey buffer
//
PERR("RegEnumKeyEx", rc);
return RTN_ERROR;
}
} // RegEnumKeyEx
// close registry key we have been working with
RegCloseKey(hKey);
// Revoke all privileges this process holds (including backup)
AdjustTokenPrivileges( hToken, TRUE, NULL, 0, NULL, NULL);
// close handle to process token
CloseHandle(hToken);
return RTN_OK;
}
LONG SaveRegistrySubKey(
HKEY hKey, // handle of key to save
LPTSTR szSubKey, // pointer to subkey name to save
LPTSTR szSaveFileName // pointer to save path/filename
)
{
HKEY hKeyToSave; // Handle of subkey to save
LONG rc; // result code from RegXxx
DWORD dwDisposition;
if((rc=RegCreateKeyEx(hKey,
szSubKey, // Name of subkey to open
0,
NULL,
REG_OPTION_BACKUP_RESTORE, // in winnt.h
KEY_QUERY_VALUE, // minimal access
NULL,
&hKeyToSave,
&dwDisposition)
) == ERROR_SUCCESS)
{
// Save registry subkey. If the registry is remote, files will
// be saved on the remote machine
rc=RegSaveKey(hKeyToSave, szSaveFileName, NULL);
// close registry key we just tried to save
RegCloseKey(hKeyToSave);
}
// return the last registry result code
return rc;
}
void PERR(
LPTSTR szAPI, // pointer to failed API name
DWORD dwLastError // last error value associated with API
)
{
LPTSTR MessageBuffer;
DWORD dwBufferLength;
//
// TODO get this fprintf out of here!
//
fprintf(stderr,"%s error! (rc=%lu)\n", szAPI, dwLastError);
if(dwBufferLength=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwLastError,
LANG_NEUTRAL,
(LPTSTR) &MessageBuffer,
0,
NULL))
{
DWORD dwBytesWritten;
//
// Output message string on stderr
//
WriteFile(GetStdHandle(STD_ERROR_HANDLE),
MessageBuffer,
dwBufferLength,
&dwBytesWritten,
NULL);
//
// free the buffer allocated by the system
//
LocalFree(MessageBuffer);
}
}
Additional query words: 3.50
Keywords: kbhowto kbregistry kbapi kbkernbase kbcode KB128731