vrad
vrad

Reputation: 836

How do I use RegReplaceKey()?

I'm trying to replace registry hive file by using RegReplaceKey() (new file is created with RegSaveKey() API), but it returns with "file already exists" error. If I try to delete original hive file first, it fails with an error "file is in use".

I've assigned proper privileges (SeBackupPrivilege and SeRestorePrivilege), user is an administrator, but no luck.

Does anyone have an idea what could be wrong? Here's the code:

...

// Setting privileges here, everything goes okay

nret := RegOpenKey(HKEY_LOCAL_MACHINE, 'system', hk);

if nret = 0 then
begin
  RegFlushKey(hk);
  if FileExists('C:\WINDOWS\system32\config\testhive') then
    DeleteFile('C:\WINDOWS\system32\config\testhive');
  nret := RegSaveKey(hk, 'C:\WINDOWS\system32\config\testhive', nil);
  if nret <> 0 then
    MessageBox(0, pchar(SysErrorMessage(nret)), '', 0);

  // no errors so far, new file is created

  SeqNr := StartRestore('Before Registry Optimization');
  if FileExists('C:\WINDOWS\system32\config\system') then
  begin
    FileSetAttr('C:\WINDOWS\system32\config\system', 0);
    if not DeleteFile('C:\WINDOWS\system32\config\system') then
      MessageBox(0, pchar(SysErrorMessage(GetLastError)), '', 0);
      // error: file is in use
  end;

  nret := RegReplaceKey(hk, nil, 'C:\WINDOWS\system32\config\testhive', 'C:\WINDOWS\system32\config\system');
  if nret <> 0 then
    MessageBox(0, pchar(SysErrorMessage(nret)), '', 0);
    // error: file already exists
  if SeqNr <> 0 then
    EndRestore(SeqNr);

  RegCloseKey(hk);
end;

Upvotes: 0

Views: 907

Answers (2)

vrad
vrad

Reputation: 836

In case someone has similar problem, I'll answer my own question.

The mistake was in last RegReplaceKey() parameter: it shouldn't point to actual and current hive registry file, but to another temp file:

  nret := RegReplaceKey(hk, nil, 'C:\WINDOWS\system32\config\testhive',
            'C:\WINDOWS\system32\config\testhive1');

Consequently, prior to this line, we don't need to delete hive file itself, but the second temp file (to ensure it doesn't exist):

  if FileExists('C:\WINDOWS\system32\config\testhive1') then
  begin
    if not DeleteFile('C:\WINDOWS\system32\config\testhive1') then
      MessageBox(0, pchar(SysErrorMessage(GetLastError)), '', 0);
  end;

If done this way, everything works ok, and Windows replaces key determined by hk, which was received from RegOpenKey().

Upvotes: 1

Tony Hopkinson
Tony Hopkinson

Reputation: 20320

RegReplaceKey sets up windows to use the file backing the registry on restarting windows. You call it and provide a file. On restart it will use it. So I suspect it's not what you want.

Upvotes: 0

Related Questions