|
|
//-----------------------------------------------------------------------//
//
// File: save.cpp
// Created: March 1997
// By: Martin Holladay (a-martih)
// Purpose: Registry Save Support for REG.CPP
// Modification History:
// Copied from Copy.cpp and modificd - May 1997 (a-martih)
// Aug 1997 - MartinHo
// Fixed bug which didn't allow you to specify a ROOT key.
// Example REG SAVE HKLM\Software didn't work - but should have
// April 1999 Zeyong Xu: re-design, revision -> version 2.0
//
//------------------------------------------------------------------------//
#include "stdafx.h"
#include "reg.h"
//-----------------------------------------------------------------------//
//
// SaveHive()
//
//-----------------------------------------------------------------------//
LONG SaveHive(PAPPVARS pAppVars, UINT argc, TCHAR *argv[]) { LONG nResult; HKEY hKey;
//
// Parse the cmd-line
//
nResult = ParseSaveCmdLine(pAppVars, argc, argv); if (nResult != ERROR_SUCCESS) { return nResult; }
#ifndef REG_FOR_WIN2000 // ANSI version for Win98
// because RegLoadKey() failed on remote Win98,
// works local only on Win98, cancel SAVE for remote
if(pAppVars->bUseRemoteMachine) return REG_STATUS_NONREMOTABLE; #endif
//
// Connect to the Remote Machine - if applicable
//
nResult = RegConnectMachine(pAppVars); if (nResult != ERROR_SUCCESS) { return nResult; }
//
// Open the key
//
if ((nResult = RegOpenKeyEx(pAppVars->hRootKey, pAppVars->szSubKey, 0, KEY_READ, &hKey)) == ERROR_SUCCESS) { //
// Acquire the necessary privilages and call the API
//
nResult = RegAdjustTokenPrivileges(pAppVars->szMachineName, SE_BACKUP_NAME, SE_PRIVILEGE_ENABLED); if (nResult == ERROR_SUCCESS) { nResult = RegSaveKey(hKey, pAppVars->szValueName, NULL); }
RegCloseKey(hKey); }
#ifndef REG_FOR_WIN2000
// since the newly created file has the hidden attibute on win98,
// remove this hidden attribute (work for local machine only)
if (nResult == ERROR_SUCCESS) SetFileAttributes(pAppVars->szValueName, FILE_ATTRIBUTE_ARCHIVE); #endif
return nResult; }
//-----------------------------------------------------------------------//
//
// RestoreHive()
//
//-----------------------------------------------------------------------//
LONG RestoreHive(PAPPVARS pAppVars, UINT argc, TCHAR *argv[]) { LONG nResult; HKEY hKey;
//
// Parse the cmd-line
//
nResult = ParseSaveCmdLine(pAppVars, argc, argv); if (nResult != ERROR_SUCCESS) { return nResult; }
#ifndef REG_FOR_WIN2000 // ANSI version for Win98
// because RegLoadKey() failed on remote Win98,
// works local only on Win98
if(pAppVars->bUseRemoteMachine) return REG_STATUS_NONREMOTABLE; #endif
//
// Connect to the Remote Machine(s) - if applicable
//
nResult = RegConnectMachine(pAppVars); if (nResult != ERROR_SUCCESS) { return nResult; }
//
// Open the Key
//
if ((nResult = RegOpenKeyEx(pAppVars->hRootKey, pAppVars->szSubKey, 0, KEY_ALL_ACCESS, &hKey)) == ERROR_SUCCESS) {
#ifdef REG_FOR_WIN2000 // works on Win2000(unicode) only, not Win98(ansi)
// Acquire the necessary privilages and call the API
nResult = RegAdjustTokenPrivileges(pAppVars->szMachineName, SE_RESTORE_NAME, SE_PRIVILEGE_ENABLED); if (nResult == ERROR_SUCCESS) { nResult = RegRestoreKey(hKey, pAppVars->szValueName, 0); } RegCloseKey(hKey);
#else // works on Win98(ansi) only, not Win2000(unicode)
RegCloseKey(hKey); nResult = RegRestoreKeyWin98(pAppVars->hRootKey, pAppVars->szSubKey, pAppVars->szValueName);
#endif
}
return nResult; }
//-----------------------------------------------------------------------//
//
// LoadHive()
//
//-----------------------------------------------------------------------//
LONG LoadHive(PAPPVARS pAppVars, UINT argc, TCHAR *argv[]) { LONG nResult;
//
// Parse the cmd-line
//
nResult = ParseSaveCmdLine(pAppVars, argc, argv); if (nResult != ERROR_SUCCESS) { return nResult; }
#ifndef REG_FOR_WIN2000 // ANSI version for Win98
// because RegLoadKey() failed on remote Win98,
// works local only on Win98
if(pAppVars->bUseRemoteMachine) return REG_STATUS_NONREMOTABLE; #endif
//
// Connect to the Remote Machine(s) - if applicable
//
nResult = RegConnectMachine(pAppVars); if (nResult != ERROR_SUCCESS) { return nResult; }
//
// Acquire the necessary privilages and call the API
//
nResult = RegAdjustTokenPrivileges(pAppVars->szMachineName, SE_RESTORE_NAME, SE_PRIVILEGE_ENABLED); if (nResult == ERROR_SUCCESS) { nResult = RegLoadKey(pAppVars->hRootKey, pAppVars->szSubKey, pAppVars->szValueName); }
return nResult; }
//-----------------------------------------------------------------------//
//
// UnLoadHive()
//
//-----------------------------------------------------------------------//
LONG UnLoadHive(PAPPVARS pAppVars, UINT argc, TCHAR *argv[]) { LONG nResult;
//
// Parse the cmd-line
//
nResult = ParseUnLoadCmdLine(pAppVars, argc, argv); if (nResult != ERROR_SUCCESS) { return nResult; }
#ifndef REG_FOR_WIN2000 // ANSI version for Win98
// because RegUnLoadKey() failed on remote Win98,
// works local only on Win98
if(pAppVars->bUseRemoteMachine) return REG_STATUS_NONREMOTABLE; #endif
//
// Connect to the Remote Machine(s) - if applicable
//
nResult = RegConnectMachine(pAppVars); if (nResult != ERROR_SUCCESS) { return nResult; }
//
// Acquire the necessary privilages and call the API
//
nResult = RegAdjustTokenPrivileges(pAppVars->szMachineName, SE_RESTORE_NAME, SE_PRIVILEGE_ENABLED); if (nResult == ERROR_SUCCESS) { nResult = RegUnLoadKey(pAppVars->hRootKey, pAppVars->szSubKey); }
return nResult; }
//------------------------------------------------------------------------//
//
// ParseSaveCmdLine()
//
//------------------------------------------------------------------------//
REG_STATUS ParseSaveCmdLine(PAPPVARS pAppVars, UINT argc, TCHAR *argv[]) { REG_STATUS nResult = ERROR_SUCCESS;
//
// Do we have a *valid* number of cmd-line params
//
if (argc < 4) { return REG_STATUS_TOFEWPARAMS; } else if (argc > 4) { return REG_STATUS_TOMANYPARAMS; }
// Machine Name and Registry key
//
nResult = BreakDownKeyString(argv[2], pAppVars); if(nResult != ERROR_SUCCESS) return nResult;
//
// Get the FileName - using the szValueName string field to hold it
//
pAppVars->szValueName = (TCHAR*) calloc(_tcslen(argv[3]) + 1, sizeof(TCHAR)); if (!pAppVars->szValueName) { return ERROR_NOT_ENOUGH_MEMORY; } _tcscpy(pAppVars->szValueName, argv[3]);
return nResult; }
//------------------------------------------------------------------------//
//
// ParseUnLoadCmdLine()
//
//------------------------------------------------------------------------//
REG_STATUS ParseUnLoadCmdLine(PAPPVARS pAppVars, UINT argc, TCHAR *argv[]) { REG_STATUS nResult = ERROR_SUCCESS;
//
// Do we have a *valid* number of cmd-line params
//
if (argc < 3) { return REG_STATUS_TOFEWPARAMS; } else if (argc > 3) { return REG_STATUS_TOMANYPARAMS; }
// Machine Name and Registry key
//
nResult = BreakDownKeyString(argv[2], pAppVars);
return nResult; }
//------------------------------------------------------------------------//
//
// AdjustTokenPrivileges()
//
//------------------------------------------------------------------------//
LONG RegAdjustTokenPrivileges(TCHAR *szMachine, TCHAR *szPrivilege, LONG nAttribute) { // works on Win2000(unicode) only, not Win98(ansi)
#ifdef REG_FOR_WIN2000
HANDLE hToken; TOKEN_PRIVILEGES tkp;
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { return GetLastError(); }
if(!LookupPrivilegeValue(szMachine, szPrivilege, &tkp.Privileges[0].Luid)) { return GetLastError(); }
tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = nAttribute;
if(!AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, NULL)) { return GetLastError(); }
#endif
return ERROR_SUCCESS; }
//-----------------------------------------------------------------------//
// RegRestoreKeyWin98() for Win98 only (ANSI version)
// because RegRestoreKey() does not work on Win98
//-----------------------------------------------------------------------//
LONG RegRestoreKeyWin98(HKEY hRootKey, // handle to a root key
TCHAR* szSubKey, // name of subkey
TCHAR* szFile) // hive filename
{ LONG nResult; HKEY hKey; HKEY hTempKey; TCHAR szTempHive[50]; LONG nRetUnload;
// avoid key name conflict, reduce failed possibility
_tcscpy(szTempHive, _T("TEMP_HIVE_FOR_RESTORE_0000")); if(_tcsicmp(szSubKey, szTempHive) == 0) _tcscpy(szTempHive, _T("TEMP_HIVE_FOR_RESTORE_1111")); nResult = RegOpenKeyEx(hRootKey, szTempHive, 0, KEY_READ, &hTempKey); if(nResult == ERROR_SUCCESS) { RegCloseKey(hTempKey); _tcscpy(szTempHive, _T("TEMP_HIVE_FOR_RESTORE_RETRY_0000")); }
// load hive file to szTempHive key
nResult = RegLoadKey(hRootKey, szTempHive, szFile); if(nResult != ERROR_SUCCESS) return nResult;
nResult = RecursiveDeleteKey(hRootKey, szSubKey);
if(nResult == ERROR_SUCCESS) { // Create the Key
nResult = RegCreateKeyEx(hRootKey, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
if(nResult == ERROR_SUCCESS) { // Now open TempHive key
nResult = RegOpenKeyEx(hRootKey, szTempHive, 0, KEY_READ, &hTempKey);
if (nResult == ERROR_SUCCESS) { // Recursively copy the entire hive
BOOL bOverWriteAll = TRUE; nResult = CopyEnumerateKey(hTempKey, szTempHive, hKey, szSubKey, &bOverWriteAll, TRUE); RegCloseKey(hTempKey); }
RegCloseKey(hKey); } }
// unload the temphive key
nRetUnload = RegUnLoadKey(hRootKey, szTempHive); if(nResult == ERROR_SUCCESS) nResult = nRetUnload;
return nResult; }
|