通过 RegQueryValueEx 和 RegGetValue 获取注册表值时的奇怪行为

Weird behavior when getting registry value via RegQueryValueEx and RegGetValue

我在 c++ 中遇到上述函数的一些问题。两者的行为方式完全相同。这是我看到的过程:

  1. 运行 获取注册表值的代码。仔细检查它是否找到了 10000,它应该有(10000 是每个进程对 GDI 对象的默认 windows 限制),确实如此。

  2. 使用 regedit 将注册表更改为 10000 以外的内容

  3. 运行 代码,但这次它再次找到 10000,而此时它应该找到新值。

无论我怎么尝试,它总是只能找到原始值,而不是 注册表的更新值。

我的东西 noticed/tried:

  1. 它对我看过的每个值都这样做,而不仅仅是 GDIProcessHandleQuota。 (它并不总是 return 10000,因为它特定于 GDI 值,它总是 return 任何给定值的预修改值)

  2. 即使我重新启动计算机并打开 regedit 来验证密钥,它也会这样做 实际上在 运行 宁步骤 3 之前改变了。

  3. 下面代码中的所有结果值(results、results2、results3)都是0,表示ERROR_SUCCESS(笑),这意味着他们没有遇到任何问题。

最后,这是我遇到问题的代码片段:

HKEY hKey;

//open the key for viewing in RegQueryValueEx, store opened handle in hkey
LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
    "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows",
        0,
        KEY_ALL_ACCESS,
        &hKey);


DWORD dwReturn;
DWORD dwBufSize = sizeof(DWORD);

//after this line executes, dwReturn should have the DWORD data of the specified registry key/valuename
LONG result2 = RegQueryValueEx(hKey,
    "GDIProcessHandleQuota",
    0,
    0, 
    reinterpret_cast<LPBYTE>(&dwReturn), 
    &dwBufSize);

DWORD value;
DWORD size = sizeof(DWORD);


//after this executes, value should contain the DWORD data of the specified  registry key/valuename
LONG result3 = RegGetValue(hKey,
    "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows",
    "GDIProcessHandleQuota",
    RRF_RT_ANY,
    NULL,
    &value,
    &size
    );

当 运行 在 64 位计算机上运行 32 位应用程序时,您的问题很可能是由 WOW64 模拟器引起的。有关详细信息,请参阅 MSDN 文档:

Registry Redirector

Registry Keys Affected by WOW64

32-bit and 64-bit Application Data in the Registry

Accessing an Alternate Registry View

要在 32 位应用程序中打开 64 位密钥,您需要在使用 RegOpenKeyEx() 打开密钥时包含 KEY_WOW64_64KEY 标志,或者在使用 RRF_SUBKEY_WOW6464KEY 打开密钥时包含 RRF_SUBKEY_WOW6464KEY 标志RegGetValue().

您还打开了具有过多权限的密钥(这可能会在 UAC 下启动 Registry Virtualization,但在本例中您正在访问的特定密钥被禁用,但您应该意识到这一点). KEY_ALL_ACCESS 仅适用于管理员用户。大多数用户没有对 HKLM 的写入权限,只有只读权限,因此使用 KEY_ALL_ACCESS 打开密钥对于非管理员来说将失败。始终请求您实际需要的 最小 权限。在这种情况下,打开 KEY_QUERY_VALUE 访问的密钥。

您也在调用 RegGetValue() 时使用了错误的参数值。

尝试更像这样的东西:

HKEY hKey;

//open the key for viewing in RegQueryValueEx, store opened handle in hkey
LONG result = RegOpenKeyEx(
    HKEY_LOCAL_MACHINE,
    "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows",
    0,
    KEY_QUERY_VALUE | KEY_WOW64_64KEY,
    &hKey);

if (result != ERROR_SUCCESS)
{
    ...
}
else
{
    DWORD value;
    DWORD size = sizeof(DWORD);

    //after this line executes, value should have the DWORD data of the specified registry key/valuename
    result = RegQueryValueEx(
        hKey,
        "GDIProcessHandleQuota",
        0,
        0, 
        reinterpret_cast<LPBYTE>(&value), 
        &size);

    if (result != ERROR_SUCCESS)
    {
        ...
    }

    size = sizeof(DWORD);

    //after this executes, value should contain the DWORD data of the specified registry key/valuename
    result = RegGetValue(
        hKey,
        NULL,
        "GDIProcessHandleQuota",
        RRF_RT_REG_DWORD,
        NULL,
        &value,
        &size);

    if (result != ERROR_SUCCESS)
    {
        ...
    }

    RegCloseKey(hKey);
}

或者:

DWORD value;
DWORD size = sizeof(DWORD);

//after this executes, value should contain the DWORD data of the specified registry key/valuename
LONG result = RegGetValue(
    HKEY_LOCAL_MACHINE,
    "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows",
    "GDIProcessHandleQuota",
    RRF_RT_REG_DWORD | RRF_SUBKEY_WOW6464KEY,
    NULL,
    &value,
    &size);

if (result != ERROR_SUCCESS)
{
    ...
}