Is there a way to verify if a Windows registry key

2019-01-15 20:56发布

问题:

In Windows registry the keys can be created as volatile - meaning that a volatile key is not going to survive a PC reboot. After the reboot no trace of such key will be found in registry. This is specified by the option REG_OPTION_VOLATILE of API RegCreateKeyEx.

I need to verify if a certain Windows registry key is volatile or not (created with REG_OPTION_VOLATILE).

For example, the key may be located under (HKLM\Software\MyCompany\MyProgram\KeyToBeChecked).

There seem to be no direct WIN API-s that allow making this sort of check.

Does anyone know how this could be checked?

回答1:

One way is to try creating a non-volatile subkey under the key that's being verified, using RegCreateKeyEx. If the key is indeed volatile, then it would fail with error ERROR_CHILD_MUST_BE_VOLATILE. Even ShSetValue returns ERROR_CHILD_MUST_BE_VOLATILE while trying to set a value in a volatile key.



回答2:

begin from win7 exist undocumented way - need call ZwQueryKey with KeyFlagsInformation. with this we can query are key volatile or not, also - are key is symbolic link to another key. code can look like:

struct KEY_CONTROL_FLAGS_INFO_W7  // KeyFlagsInformation for Win7
{
    ULONG ControlFlags[3];
};

#define KEY_CTRL_FL_W7_01__IS_VOLATILE                                 0x01
#define KEY_CTRL_FL_W7_01__SYM_LINK                                    0x02


    HKEY hKey;
    LSTATUS r = RegOpenKeyEx(HKEY_CURRENT_USER, 
        L"Volatile Environment", REG_OPTION_OPEN_LINK, KEY_READ, &hKey);
    if (r == NOERROR)
    {
        ULONG cb;
        KEY_CONTROL_FLAGS_INFO_W7 kcf;

        if (0 <= ZwQueryKey(hKey, KeyFlagsInformation, &kcf, sizeof(kcf), &cb))
        {
            if (kcf.ControlFlags[1] & KEY_CTRL_FL_W7_01__IS_VOLATILE)
            {
                DbgPrint("key is volatile\n");
            }

            if (kcf.ControlFlags[1] & KEY_CTRL_FL_W7_01__SYM_LINK)
            {
                DbgPrint("key is link\n");
            }
        }
        RegCloseKey(hKey);
    }