471 lines
12 KiB
C
471 lines
12 KiB
C
//-----------------------------------------------------------------------//
|
|
//
|
|
// 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;
|
|
}
|