Q&A

  • 레지스트리 저장 및 복원
안녕하세요~

특정 레지스트리의 특정 키 이하에 딸린 식솔들을 모두 파일로 저장하려고 합니다.
기본 레지스트리 에디터가 저장하는 파일 형식과 동일한 파일로요
여기 저기 자료를 찾던중 델파이 에선 TRegistry.SaveKey 가 있고
윈도 API에는 RegSaveKey 가 있더군요 테스트를 위해서 두 함수 모두
사용을 해봤는디 둘다 저장할 파일을 생성은 하지만 내용은 암것도 없더군요
별다른 에러도 없는디 이상해서리 디버깅을 하던중 마지막 에러 메세지값을 호출해서
살펴본 결과 접근 권한에 대한 문제가 있다는군요 ^^;

할수 없이 생 노가다로 레지스트리 값을 읽어다가 파일을에 한바이트씩 날려 쓰는 작업에
들어갔는디 문제가 이만 저만이 아니더군요.... 델파이에선 레지스트리의 데이터 형식을
5가지로 분류해 뒀는디 레지스트리 에디터에서 보면 알수 있듯이 실제 형식은
Multi String 하나가 더 추가 되어야 되구 처리 방식 또한 삐리릭 입니다.
실제 레지스트리에는 3가지의 스트링 형식이 존재하지만 델파이에선 모두 같은 것으로
취급을 해설 저장/복구에 사소한 문제가 생길 수 있더군요...

여차저차 생 노가다 삽질 후에야 겨우겨우 허접하지만 완벽한 저장 루틴을 만들었는디
문제는 효율성이 너무 떨어진다는 겁니다. 레지스트리 에디터로 CurrentUser 루트를 저장
하면 1-2초면 가능 하던것이 허접 루틴으로 돌리면 10초 이상 지루하게 돌아가는군요

윈도우 API로 손쉽게 저장/복구 하는 방법이 없는지 알고 싶습니다.
아시는분 정보좀 주셔요~
2  COMMENTS
  • Profile
    최용일 2005.04.26 20:08
    안녕하세요. 최용일입니다.

    아래코드를 이용해서 Privilege를 설정해보세요.

    참고로 복원(Restore)할때는 Privilege 이름이 SeRestorePrivilege입니다.

    <!--CodeS-->
    var
        OSVI: TOSVersionInfo;
        PrivilegeName: string;
        TokenHandle: THandle;
        TokenPrivileges: TTokenPrivileges;
        LUID: Int64;
        ReturnLength: Cardinal;
        LastErrorCode: Integer;
    begin
        // find out if it's NT/2000
        FillChar(OSVI, SizeOf(OSVI), 0);
        OSVI.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
        GetVersionEx(OSVI);

        //  if so, obtain the required priviledges
        if (OSVI.dwPlatformId = VER_PLATFORM_WIN32_NT) then
        begin
            PrivilegeName :=  'SeBackupPrivilege';
            if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, TokenHandle) then
            begin
                if LookupPrivilegeValue(nil, PChar(PrivilegeName), LUID) then
                begin
                    TokenPrivileges.PrivilegeCount := 1;
                    TokenPrivileges.Privileges[0].Luid := LUID;
                    TokenPrivileges.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
                    AdjustTokenPrivileges(TokenHandle, False, TokenPrivileges, 0, nil, ReturnLength);
                    LastErrorCode := GetLastError();
                    if (LastErrorCode <> ERROR_SUCCESS) then
                    begin
                        ShowMessage('Can''t get Registry''s SaveKey Privilege.');
                        Exit
                    end
                end
            end;
        end;

        .... // Save to file from registry.

    end;

    <!--CodeE-->

    ^^ 항상 즐코하세요...

  • Profile
    전상현 2005.04.28 03:58
    안녕하세요

    오호~ 좀 늦게서야 확인을 했는디 재미있는 코드군요...
    녀석을 적용 했더니 한방에 해결 되었네요... 감사함다~

    TRegistry.SaveKey 라는 녀석 알려주신 코드 없이는 아무런 동작이 없군요
    알려주신 코드를 추가해 몇몇 키값들을 저장해 봤는디 잘 동작하는디
    제가 의도했던 유니코드형의 파일로 키값이 저장되지 않고 하이브 파일로 저장
    되는군요 TT

    할수 없이 꽁수를 좀 썼답니다.
    System32 에 있는 Reg.exe 파일을 리소스에 추가해서


    실행 후 프로세스가 종료될때 0,1 의 리턴값을 체킹하였는디...
    ^^; 원하는 결과를 얻었지만 이거 역쉬 문제가 있더군요...
    바이너리 데이터가 대용량일 경우 지나쳐 버리는군요... 아마도 65535 Byte 가
    한계가 아닐까 예상되요...

    좀더 여기저기 동냥 다녀야될듯....

    즐거운 하루~