最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

registry - C++Builder - How to save and restore key values from HKEY_LOCAL_MACHINE using TRegistry? - Stack Overflow

programmeradmin4浏览0评论

Using C++ Builder 11.1.5. This is for a Windows VCL 64-bit application.

I am trying to write a key from the registry (and all subkeys and values) to a backup file so it can be restored at a later time. The key values are under HKEY_LOCAL_MACHINE\Software.

So far, I have successfully created the backup using the TRegistry::SaveKey() method, and it works so long as I call SetPrivilege() and specify SE_BACKUP_NAME.

Here is the routine I use for saving the registry key to a backup file:

void SaveRegistryKeyToFile(const UnicodeString& key, const UnicodeString& fileName)
{
    TRegistry *reg=new TRegistry(KEY_READ);
    HANDLE ProcessToken;

    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &ProcessToken)) {
        SetPrivilege(ProcessToken, SE_BACKUP_NAME, TRUE);
        TRegistry *reg=new TRegistry(KEY_READ);
        reg->RootKey=HKEY_LOCAL_MACHINE;
        reg->SaveKey(key,fileName);
        delete reg;
    }
}

Now I am trying to restore the keys to the registry using the TRegistry::LoadKey() method. I am first setting the privilege for SE_BACKUP_NAME, and then trying to load the key, but it does not work. Every time I call LoadKey(), it returns false (failure to work).

Here is the code I am using to do this:

void LoadRegistryKeyFromFile(const UnicodeString& key, const UnicodeString& fileName)
{
    TRegistry *reg;
    HANDLE ProcessToken;
    bool Result;

    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &ProcessToken)) {
        SetPrivilege(ProcessToken, SE_BACKUP_NAME, TRUE);
        reg = new TRegistry(KEY_WRITE)
        reg->RootKey=HKEY_LOCAL_MACHINE;
        if(FileExists(fileName)) {
            Result = reg->LoadKey(key,fileName);
        }
        delete reg;
    }
}

If anyone could assist in pointing me in the right direction on the restoring procedure, it would be greatly appreciated.

Using C++ Builder 11.1.5. This is for a Windows VCL 64-bit application.

I am trying to write a key from the registry (and all subkeys and values) to a backup file so it can be restored at a later time. The key values are under HKEY_LOCAL_MACHINE\Software.

So far, I have successfully created the backup using the TRegistry::SaveKey() method, and it works so long as I call SetPrivilege() and specify SE_BACKUP_NAME.

Here is the routine I use for saving the registry key to a backup file:

void SaveRegistryKeyToFile(const UnicodeString& key, const UnicodeString& fileName)
{
    TRegistry *reg=new TRegistry(KEY_READ);
    HANDLE ProcessToken;

    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &ProcessToken)) {
        SetPrivilege(ProcessToken, SE_BACKUP_NAME, TRUE);
        TRegistry *reg=new TRegistry(KEY_READ);
        reg->RootKey=HKEY_LOCAL_MACHINE;
        reg->SaveKey(key,fileName);
        delete reg;
    }
}

Now I am trying to restore the keys to the registry using the TRegistry::LoadKey() method. I am first setting the privilege for SE_BACKUP_NAME, and then trying to load the key, but it does not work. Every time I call LoadKey(), it returns false (failure to work).

Here is the code I am using to do this:

void LoadRegistryKeyFromFile(const UnicodeString& key, const UnicodeString& fileName)
{
    TRegistry *reg;
    HANDLE ProcessToken;
    bool Result;

    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &ProcessToken)) {
        SetPrivilege(ProcessToken, SE_BACKUP_NAME, TRUE);
        reg = new TRegistry(KEY_WRITE)
        reg->RootKey=HKEY_LOCAL_MACHINE;
        if(FileExists(fileName)) {
            Result = reg->LoadKey(key,fileName);
        }
        delete reg;
    }
}

If anyone could assist in pointing me in the right direction on the restoring procedure, it would be greatly appreciated.

Share Improve this question edited 11 hours ago Remy Lebeau 597k36 gold badges500 silver badges844 bronze badges asked 23 hours ago Andrew LeggettAndrew Leggett 1
Add a comment  | 

1 Answer 1

Reset to default 0

TRegistry::SaveKey() simply calls the Win32 RegSaveKey() function, and TRegistry::LoadKey() calls RegLoadKey(). Per the RegLoadKey documentation:

If the function fails, the return value is a nonzero error code defined in Winerror.h. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

You can get that error code from the TRegistry::LastError property, and the formatted message from the TRegistry::LastErrorMsg property, eg:

if (!reg->LoadKey(key, fileName)) {
    ShowMessage(_D("CANT LOAD KEY!\nError: (") + String(reg->LastError) + _D(") ") + reg->LastErrorMsg);
}

Note, the RegLoadKey() documentation also says:

The calling process must have the SE_RESTORE_NAME and SE_BACKUP_NAME privileges on the computer in which the registry resides. For more information, see Running with Special Privileges. To load a hive without requiring these special privileges, use the RegLoadAppKey function.

You are not enabling the SE_RESTORE_NAME privilege when loading the key, so RegLoadKey() is likely failing with an ERROR_PRIVILEGE_NOT_HELD (1314) error.

Try adding that privlege, eg:

SetPrivilege(ProcessToken, SE_RESTORE_NAME, TRUE); // <-- ADD THIS
SetPrivilege(ProcessToken, SE_BACKUP_NAME, TRUE);
Result = reg->LoadKey(key, fileName);

On a side note: Both of your functions are leaking memory. SaveRegistryKeyToFile() leaks an unused TRegistry object, and leaks the opened HANDLE from OpenProcessToken(). LoadRegistryKeyFromFile() leaks the opened HANDLE from OpenProcessToken(). So, you need to fix that, eg:

bool SaveRegistryKeyToFile(const String& key, const String& fileName)
{
    HANDLE ProcessToken;
    bool Result = false;

    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &ProcessToken)) {
        SetPrivilege(ProcessToken, SE_BACKUP_NAME, TRUE);
        TRegistry *reg = new TRegistry(KEY_READ);
        reg->RootKey = HKEY_LOCAL_MACHINE;
        Result = reg->SaveKey(key, fileName);
        delete reg;
        CloseHandle(ProcessToken);
    }

    return Result;
}

bool LoadRegistryKeyFromFile(const String& key, const String& fileName)
{
    HANDLE ProcessToken;
    bool Result = false;

    if (FileExists(fileName)) {
        if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &ProcessToken)) {
            SetPrivilege(ProcessToken, SE_RESTORE_NAME, TRUE);
            SetPrivilege(ProcessToken, SE_BACKUP_NAME, TRUE);
            TRegistry *reg = new TRegistry(KEY_WRITE);
            reg->RootKey = HKEY_LOCAL_MACHINE;
            Result = reg->LoadKey(key, fileName);
            delete reg;
            CloseHandle(ProcessToken);
        }
    }

    return Result;
}
发布评论

评论列表(0)

  1. 暂无评论