【问题标题】:SHGetValue returns 2 when querying UAC value查询 UAC 值时 SHGetValue 返回 2
【发布时间】:2019-04-17 16:17:59
【问题描述】:

我想检查 windows 的 UAC 配置设置。从而恢复注册表项中 UAC 的参数。

我使用了 windows SHGetValue 函数,但状态总是返回我 2 而没有任何信息。

我使用 C++11、MinGW 和 windows。

我的代码是:

DWORD dwStatus;
  LPCSTR pszSubKey= "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
  LPCSTR pszValue="";
  DWORD  pdwType=REG_SZ;
  PVOID  pvData[63];
  DWORD  pcbData;
  pcbData=sizeof(pvData);

  dwStatus=SHGetValueA(HKEY_LOCAL_MACHINE, pszSubKey, pszValue, &pdwType, pvData, &pcbData);

  //Here dwStatus = 2
  // pvData = 0x11fd0b2
  // pcbData = 504

【问题讨论】:

  • 不确定外壳抽象。也许试试Winreg.h API,看看哪个返回错误(RegOpenKeyRegQueryValueEx 等)以及是否更详细。
  • "...状态总是返回我 2 没有任何信息..." - SHGetValue 返回 LSTATUS。我相信是的。 ERROR_FILE_NOT_FOUND。我相信您要求的是不存在的键、子键或值。一位更了解 Win32 API 的人可能会说得更多。
  • HKLM 不是注册表项的名称,它是HKEY_LOCAL_MACHINE 的缩写,您已经将它作为第一个参数传递给SHGetValue
  • @jww 编译器 MinGW 的状态是 DWORD,我用乔纳森的回答纠正了我的错误,谢谢

标签: c++ windows winapi mingw uac


【解决方案1】:

您要读取的具体键是什么?我不是 win32 API 方面的专家,所以我不知道是否有办法一次读取一组密钥(编辑:我认为有RegEnumValue/RegEnumValueA 函数用于此目的)。下面是一个示例,展示了如何从该路径读取“EnableLUA”或任何其他键:

#include <windows.h>
#include <iostream>
#include <shlwapi.h>


bool ReadUACRegistryKey(char* key, DWORD &keyValue)
{
    LPCTSTR pszSubKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
    LPCTSTR pszValue = key;

    //  don't care
    DWORD dwType = 0;
    DWORD dwValue = 0;

    //  
    DWORD dwValueSize = sizeof(dwValue);

    int retval = SHGetValue( HKEY_LOCAL_MACHINE, pszSubKey, key, &dwType, &dwValue, &dwValueSize);
    if ( retval != ERROR_SUCCESS)
    {
        return false;
    }

    keyValue = dwValue;
    return true;
}

int main()
{
    DWORD keyValue;
    char* key = "EnableLUA";  //  "EnableSecureUIAPaths" etc..;
    if (ReadUACRegistryKey(key, keyValue))
    {
        std::cout << "Successfully readed key " << key << ", value:" << keyValue << std::endl;
    }
    else
    {
        std::cout << "Unable to read value of key " << key << std::endl;
    }


    return 0;
}

还要记住,读取键值的值存储在值参数中,而不是函数的返回值中。

编辑:操作员评论的回答“我想使用 FilterAdministratorToken 但默认情况下禁用如何将其重新启用.?”。请记住,您的进程需要具有管理员权限才能执行这些操作。

#include <windows.h>
#include <iostream>
#include <shlwapi.h>


bool ReadUACRegistryKey(char* key, DWORD &keyValue)
{
    LPCTSTR pszSubKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
    LPCTSTR pszValue = key;

    //  don't care
    DWORD dwType = 0;
    DWORD dwValue = 0;

    //  
    DWORD dwValueSize = sizeof(dwValue);

    int retval = SHGetValue( HKEY_LOCAL_MACHINE, pszSubKey, key, &dwType, &dwValue, &dwValueSize);
    if ( retval != ERROR_SUCCESS)
    {
        return false;
    }

    keyValue = dwValue;
    return true;
}

bool EnableFilterAdministratorToken()
{
    //  first check if its already enabled or not
    DWORD val;
    if (ReadUACRegistryKey("FilterAdministratorToken", val))
    {
        if (val == 1)
        {
            std::cout << "FilterAdministratorToken is already enabled" << std::endl;
            return true;
        }
    }
    else
    {
        std::cout << "Unable to read key" << std::endl;
        return false;
    }


    //  its not enabled, we need to enable it manually
    //  obtain a handle to reg key
    HKEY hKey;
    int retval = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", 0, KEY_SET_VALUE, &hKey);
    if (retval != ERROR_SUCCESS)
    {
        //  we are unable to obtain a handle to reg key
        std::cout << "Unable to obtain handle to reg key" << std::endl;
        return false;
    }


    DWORD enabledValue = 1;
    retval = RegSetValueExA(hKey, "FilterAdministratorToken", 0, REG_DWORD, (BYTE*) &enabledValue, sizeof(DWORD));
    if (retval != ERROR_SUCCESS)
    {
        //  some error occured
        std::cout << "Some error occured during setting the key value" << std::endl;
        RegCloseKey(hKey);
        return false;
    }

    std::cout << "Successfully changed key value" << std::endl;
    RegCloseKey(hKey);
    return true;
}

int main()
{
    if (EnableFilterAdministratorToken())
    {
        std::cout << "OK" << std::endl;
    }
    else
    {
        std::cout << "FAIL" << std::endl;
    }


    return 0;
}

【讨论】:

  • 我想使用 FilterAdministratorToken 但默认禁用如何将其重新启用。?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-23
  • 1970-01-01
相关资源
最近更新 更多