Search code examples
c++windowswinapimingwuac

SHGetValue returns 2 when querying UAC value


I would like to check the UAC configuration settings of windows. And thus recover the parameters of the UAC in the registry keys.

I used the windows SHGetValue function but the status always returns me 2 without any information.

I use C++11, MinGW and windows.

My code is :

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

Solution

  • What specific key you are trying to read? I am not an expert on win32 API so I don't know whether there is a way to read a set of keys at once (Edit: I think there areRegEnumValue/RegEnumValueA functions for this purpose). Here is an example that shows how you can read "EnableLUA" or any other key from that path:

    #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;
    }
    

    Also keep in mind that value of read key value is stored in value parameter, not in the return value of the function.

    Edit: Answer of the the op's comment "I want use FilterAdministratorToken but is disable by default how give it back enable .?". Keep in mind that your process need to have admin rights to perform these operation.

    #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;
    }