Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  

Показать сообщение отдельно

Аватара для Stealthmax

Новый участник


Сообщения: 46
Благодарности: 15

Профиль | Цитировать


Приветствую всех!
Подскажите решение с бэкапом ветки/веток реестра. Возможно ли добавить бэкап в {uninstallexe}, т.е. наподобие функции GetFromRes, но наоборот.
Дабы после установки содержимое бэкапа сохранилось в деинсталляторе для последующего восстановления при удалении.
Бэкап реестра
Код: Выделить весь код
[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\2345Pic', ExpandConstant('{tmp}\RegBackup.dat'), true);
RegRestorefromfile(HKEY_LOCAL_MACHINE, 'Software\2345Pic_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\2345Pic_BackUp', ExpandConstant('{tmp}\RegBackup.dat'), true);
RegRestorefromfile(HKEY_LOCAL_MACHINE, 'Software\2345Pic', ExpandConstant('{tmp}\RegBackup.dat'), true);
DeleteFile(ExpandConstant('{tmp}\RegBackup.dat'));
RegDeleteKeyIncludingSubkeys(HKLM, 'Software\2345Pic_BackUp'); end;
end;

Мой вариант
Код: Выделить весь код
[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 = ssInstall then 
  begin //бэкап непосредственно перед установкой
    RegBackupTofile(HKEY_LOCAL_MACHINE, 'SOFTWARE\2345Pic', ExpandConstant('{app}\RegBackup.dat'), true); //сохраняем ключ 1
    RegBackupTofile(HKEY_LOCAL_MACHINE, 'SOFTWARE\Google', ExpandConstant('{app}\RegBackup_1.dat'), true); //сохраняем ключ 2
  end;
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if CurUninstallStep = usPostUninstall then 
  begin
   RegRestorefromfile(HKEY_LOCAL_MACHINE, 'Software\2345Pic', ExpandConstant('{app}\RegBackup.dat'), true); //восстанавливаем ключ 1
   RegRestorefromfile(HKEY_LOCAL_MACHINE, 'Software\Google', ExpandConstant('{app}\RegBackup_1.dat'), true); //восстанавливаем ключ 2
   DeleteFile(ExpandConstant('{app}\RegBackup.dat'));
   DeleteFile(ExpandConstant('{app}\RegBackup_1.dat'));
  end;
end;

Восстановить из файла RegBackup.dat и RegBackup_1.dat ничто не мешает, но хотелось бы некой эстетики и не плодить множество файлов *.dat.

Цитата R.i.m.s.k.y.:
сделать кнопку проверки установщика по чексумме »
Т.е. зашифровать на основе MD5? Защита от распаковки?

Отправлено: 22:31, 16-10-2015 | #985