レジストリのエクスポートについて

解決


famas  2005-12-18 09:03:44  No: 19303  IP: 192.*.*.*

APIの
func Windows.RegSaveKey: function(hKey: HKEY; lpFile: PChar; lpSecurityAttributes: PSecurityAttributes): Integer;
を使ってレジストリのエクスポート機能を実装したいのですが

RegSaveKey('HKEY_LOCAL_MACHINE\Software\hoge\test',PChar('backup'),NULL);
とすると
'HKEY' と 'String' には互換性がありません
'Variant' と 'PSecurityAttributes' には互換性がありません
と警告されます。

型変換をしなければいけないことは分かるのですが具体的にどうすればいいのかが分からないのです。
分かる方、助言をお願いします。

編集 削除
こんな感じ?  2005-12-18 10:28:50  No: 19304  IP: 192.*.*.*

型変換という問題ではありません。


var
  nHandle: HKEY;

RegOpenKeyEx(HKEY_LOCAL_MACHINE, 'Software\hoge\test', 0, KEY_READ, nHandle);
RegSaveKey(nHandle, 'c:\backup', nil);
RegCloseKey(nHandle);

編集 削除
famas  2005-12-18 12:52:37  No: 19305  IP: 192.*.*.*

返信ありがとうございます。
その方法で試してみましたが、書き出されるファイルは0kバイトでした。
レジストリエディタで書き出すと約10kバイト程になります。
読み込み又は書き出しに失敗しているのでしょうか。

編集 削除
ジョナサン・トースター  2005-12-19 08:46:43  No: 19306  IP: 192.*.*.*

1)RegOpenKeyExは成功し、nHandleに値は入っていますか?

2)実行したユーザーで、アクセス権限はありますか?
  レジストリエディタで保存できるユーザーであれば、アクセス権限に問題はないでしょう。

編集 削除
どやさ  2005-12-20 21:28:02  No: 19307  IP: 192.*.*.*

こんな感じかな

function GetBackupPrivileges: DWORD;
var
  hToken:        THandle;
  tp:            _TOKEN_PRIVILEGES;
  returnLength:  Cardinal;
begin
  if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken) then begin
    if LookupPrivilegeValue(nil, 'SeBackupPrivilege', tp.Privileges[0].Luid)  then begin
      tp.PrivilegeCount := 1;
      tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
      AdjustTokenPrivileges(hToken, false, tp, 0, nil, returnLength)
    end;
  end;
  Result := GetLastError;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  FName: String;
  KH: HKEY;
  Ret: DWord;
begin
  FName := 'D:\backup';
  if FileExists(FName) then DeleteFile(FName);
  Ret := RegOpenKeyEx(HKEY_CURRENT_USER,PChar'Software\MakeSeaquence'), 0, KEY_ALL_ACCESS, KH);
  if Ret = ERROR_SUCCESS then begin
    try
      Ret := GetBackupPrivileges;
      if Ret = ERROR_SUCCESS then begin
        if RegSaveKey(KH, PChar(FName), nil) = 0
          then ShowMessage('BACKUP OK!')
          else ShowMessage('BACKUP ERROR!');
      end;
    finally
      RegCloseKey(KH);
    end;
  end;
end;

編集 削除
famas  2005-12-24 06:56:02  No: 19308  IP: 192.*.*.*

関数が返すエラーコードを調べたところRegSaveKeyが1314を返したので調べたところ、
ERROR_PRIVILEGE_NOT_HELD 1314 0x00000522 クライアントは要求された特権を保有していません。
と、ありました。
RegGetKeySecurityを試したもののうまくいかないので悩んでおりましたが、
どやささんのコードのおかげで書き出すことが出来ました。

ただ、書き出したものをRegRestoreKeyで復元しようとしても1314が返されます。
(どやささんのコードのRet = ERROR_SUCCESS then beginの下に書いて試しました。)

RegRestoreKey(KH, PChar(FName), REG_REFRESH_HIVE);

この関数はmsdn(http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpsysinf/html/_win32_regsavekey.asp)には
LONG RegRestoreKey(
  HKEY hKey,      // 復元を開始するべきキーのハンドル
  LPCTSTR lpFile, // レジストリ情報を保持しているファイル
  DWORD dwFlags   // オプション
);
とありましたが、dwFlagsの
REG_FORCE_RESTORE,REG_NO_LAZY_FLUSH,REG_REFRESH_HIVE,REG_WHOLE_HIVE_VOLATILEのうち、
前半二つはdelphiでコンパイルすると定義されていない〜と警告され、
後半二つは問題なくコンパイルできましたがどちらも復元に失敗しました。
GetBackupPrivileges関数の方で何か修正する必要があるのでしょうか?

編集 削除
famas  2005-12-24 06:58:02  No: 19309  IP: 192.*.*.*

URLが違ってました><
http://www.microsoft.com/japan/msdn/library/ja/jpsysinf/html/_win32_regrestorekey.asp

編集 削除
famas  2005-12-24 17:55:04  No: 19310  IP: 192.*.*.*

LookupPrivilegeValue関数にてSE_RESTORE_PRIVILEGE特権のID取得をしたところ
GetLastErrorによってERROR_SUCCESSは返されましたが
RegRestoreKey関数がエラーコード87(ERROR_INVALID_PARAMETER)を返します。
第3引数の部分が怪しいとは思うのですがどうにもわかりません。

編集 削除
famas  2005-12-26 16:47:45  No: 19311  IP: 192.*.*.*

エクスポートについては解決したので終了させておきます

編集 削除