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;
Последнее редактирование: