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

Weird behavior when getting registry value via RegQueryValueEx and RegGetValue

本文关键字:RegQueryValueEx RegGetValue 获取 注册表 通过      更新时间:2023-10-16

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

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

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

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

无论我尝试什么,它总是只找到最初的价值,而不是注册表的更新值。

我注意到/尝试过的事情:

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

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

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

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

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文档:

注册表重定向器

受WOW64 影响的注册表项

注册表中的32位和64位应用程序数据

访问备用注册表视图

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

您也使用过多的权限打开了密钥(这可能会在UAC下启动注册表虚拟化,但在本例中,您正在访问的特定密钥禁用了该权限,但您应该注意这一点)。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)
{
    ...
}