Snoopak96
Старожил
В: Как сделать бэкап ветки реестра и потом восстановить из бэкапа?
О: Так
	
	
		
			
	
	
	
		
		
	
				
			О: Так
		Код:
	
	[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={pf}\My Application
[code]
#define A = (Defined UNICODE) ? "W" : "A"
const
  SE_BACKUP_NAME = 'SeBackupPrivilege';
  SE_RESTORE_NAME = 'SeRestorePrivilege';
  TOKEN_QUERY = $8;
  TOKEN_ADJUST_PRIVILEGES = $20;
  SE_PRIVILEGE_ENABLED = $2;
  ERROR_SUCCESS = 0;
  KEY_WOW64_64KEY  =  $0100;
  MAXIMUM_ALLOWED = $02000000;
  REG_FORCE_RESTORE = $00000008;
type
  LUID = record
  LowPart: DWORD;
  HighPart: Longint;
  end;
  LUID_AND_ATTRIBUTES = record
  Luid: LUID;
  Attributes: DWORD;
  end;
  TOKEN_PRIVILEGES = record
  PrivilegeCount: DWORD;
  Privileges: array [0..0] of LUID_AND_ATTRIBUTES;
  end;
  REGSAM = DWORD;
  HKEY = LongWord;
function RegSaveKey(hKey: HKEY; lpFile: String; lpSecurityAttributes: Longint):longint; external 'RegSaveKey{#A}@advapi32.dll stdcall';
function RegOpenKeyEx(hKey: HKEY; lpSubKey: String; ulOptions: DWORD; samDesired: REGSAM; var phkResult: HKEY): Longint; external 'RegOpenKeyEx{#A}@advapi32.dll stdcall';
function RegCreateKeyEx(hKey: HKEY; lpSubKey: String; Reserved: DWORD; lpClass: String; dwOptions: DWORD; samDesired: REGSAM; lpSecurityAttributes: Longint; var phkResult: HKEY; var lpdwDisposition: DWORD): Longint; external 'RegCreateKeyEx{#A}@advapi32.dll stdcall';
function RegCloseKey(hKey: HKEY): Longint; external 'RegCloseKey@advapi32.dll stdcall';
function RegRestoreKey(hKey: HKEY; lpFile: String; lpSecurityAttributes: Longint):longint; external 'RegRestoreKey{#A}@advapi32.dll stdcall';
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function OpenProcessToken(ProcessHandle: THandle; DesiredAccess: DWORD; var TokenHandle: THandle): BOOL; external 'OpenProcessToken@advapi32.dll stdcall';
function GetCurrentProcess(): THandle; external 'GetCurrentProcess@kernel32.dll stdcall';
function LookupPrivilegeValue(lpSystemName, lpName: String; var lpLuid: LUID): BOOL; external 'LookupPrivilegeValue{#A}@advapi32.dll stdcall';
function AdjustTokenPrivileges(TokenHandle: THandle; DisableAllPrivileges: BOOL; NewState: TOKEN_PRIVILEGES; BufferLength: DWORD; var PreviousState: TOKEN_PRIVILEGES; var ReturnLength: Longint): BOOL; external 'AdjustTokenPrivileges@advapi32.dll stdcall';
function CloseHandle(hObject: THandle): BOOL; external 'CloseHandle@kernel32.dll stdcall';
function GetLastError(): DWORD; external 'GetLastError@Kernel32 stdcall';
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function NTSetPrivilege(sPrivilege: string; bEnabled: Boolean): Boolean;
var
  hToken: THandle;
  TokenPriv: TOKEN_PRIVILEGES;
  PrevTokenPriv: TOKEN_PRIVILEGES;
  ReturnLength: Cardinal;
  Version: TWindowsVersion;
  ret: Longint;
begin
  GetWindowsVersionEx(Version);
  if not Version.NTPlatform then Exit;
  if OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
  begin
  try
  if LookupPrivilegeValue('', PAnsiChar(sPrivilege), TokenPriv.Privileges[0].Luid) then
  begin
  TokenPriv.PrivilegeCount := 1;
  case bEnabled of
  True: TokenPriv.Privileges[0].Attributes  := SE_PRIVILEGE_ENABLED;
  False: TokenPriv.Privileges[0].Attributes := 0;
  end;
  ReturnLength := 0;
  PrevTokenPriv := TokenPriv;
  AdjustTokenPrivileges(hToken, False, TokenPriv, SizeOf(PrevTokenPriv), PrevTokenPriv, ret);
  end;
  finally
  CloseHandle(hToken);
  end;
  end;
  Result := GetLastError = ERROR_SUCCESS;
  if not Result then MsgBox(SysErrorMessage(GetLastError), mbInformation, MB_OK);
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure RegBackupTofile(intKey: HKEY; intSubKey, outfile: string; Wow32: BOOL);  //Процедура бэкапа ветки реестра в файл
//intKey - корневой раздел
//intSubKey - Путь к ветке реестра
//outfile - Имя бэкапа
//Wow32 - если true то вкл перенаправление Wow3264Node
var
  phkResult: HKEY;
begin
if not NTSetPrivilege(SE_BACKUP_NAME, true) then if MsgBox('Ошибка прав доступа!', mbInformation, MB_OK) = IDOK then Exit;
  if Wow32 then begin
  if RegOpenKeyEx(intKey, intSubKey, 0, MAXIMUM_ALLOWED, phkResult) > ERROR_SUCCESS then begin MsgBox('Ошибка чтения реестра!', mbInformation, MB_OK); Exit; end;
  end else if RegOpenKeyEx(intKey, intSubKey, 0, MAXIMUM_ALLOWED or KEY_WOW64_64KEY, phkResult) > ERROR_SUCCESS then begin MsgBox('Ошибка чтения реестра!', mbInformation, MB_OK); Exit; end;
  if RegSaveKey(phkResult, outfile, 0) > ERROR_SUCCESS then begin MsgBox('Ошибка сохранения файла!', mbInformation, MB_OK); Exit; end;
RegCloseKey(phkResult);
end;
procedure RegRestorefromfile(outKey: HKEY; outSubKey, infile: string; Wow32: BOOL);  //Процедура востановление реестра из файла, параметры по аналогии
var
  phkResult: HKEY;
  lpdwDisposition: DWORD;
begin
  if not FileExists(infile) then begin MsgBox('Файл не найден!', mbInformation, MB_OK); Exit; end;
  NTSetPrivilege(SE_BACKUP_NAME, true);
  NTSetPrivilege(SE_RESTORE_NAME, true);
  if Wow32 then begin
  if RegCreateKeyEx(outKey, outSubKey, 0, '', 0, MAXIMUM_ALLOWED, 0, phkResult, lpdwDisposition) > ERROR_SUCCESS then begin MsgBox('Ошибка записи в реестр!', mbInformation, MB_OK); Exit; end;
  end else if RegCreateKeyEx(outKey, outSubKey, 0, '', 0, MAXIMUM_ALLOWED or KEY_WOW64_64KEY, 0, phkResult, lpdwDisposition) > ERROR_SUCCESS then begin MsgBox('Ошибка записи в реестр!', mbInformation, MB_OK); Exit; end;
  if RegRestoreKey(phkResult, infile, REG_FORCE_RESTORE) > ERROR_SUCCESS then begin MsgBox('Ошибка доступа к реестру!', mbInformation, MB_OK); Exit; end;
  RegCloseKey(phkResult);
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then begin
RegBackupTofile(HKEY_LOCAL_MACHINE, 'Software\Valve', ExpandConstant('{tmp}\RegBackup.dat'), true);
RegRestorefromfile(HKEY_LOCAL_MACHINE, 'Software\Valve_BackUp', ExpandConstant('{tmp}\RegBackup.dat'), true);
DeleteFile(ExpandConstant('{tmp}\RegBackup.dat')); end;
end;
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if CurUninstallStep = usPostUninstall then begin
RegBackupTofile(HKEY_LOCAL_MACHINE, 'Software\Valve_BackUp', ExpandConstant('{tmp}\RegBackup.dat'), true);
RegRestorefromfile(HKEY_LOCAL_MACHINE, 'Software\Valve', ExpandConstant('{tmp}\RegBackup.dat'), true);
DeleteFile(ExpandConstant('{tmp}\RegBackup.dat'));
RegDeleteKeyIncludingSubkeys(HKLM, 'Software\Valve_BackUp'); end;
end;
	
			
				Последнее редактирование: