Search code examples
c++windowswinapiregistry

SHGetValueW returns different value for x64 and x86


I am using SHGetValueW API to read a registry value.

WCHAR activePolicyCode[512UL] = { 0 };
DWORD dwSize = sizeof(activePolicyCode);
DWORD type;    

LSTATUS ret = SHGetValueW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DeviceAccess", L"ActivePolicyCode", &type, &activePolicyCode, &dwSize);

For x64, it's returning 0 - ERROR_SUCCESS

But for x86, it's returning 2 - ERROR_FILE_NOT_FOUND

Why is the difference in behavior? How to read the value from x86 application?


Solution

  • For 32-bit applications running on 64-bit systems, registry functions are redirected to WOW6432Node. So if you query HKEY_LOCAL_MACHINE hKey, you will actually get values from:

    HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node
    

    So in your case, this key probably does not exists in WOW6432Node. You can use KEY_WOW64_64KEY in RegOpenKeyExW:

    HKEY hKey=0;
    DWORD dwType=0;
    BYTE pbData[1024];
    DWORD dwDataSize = sizeof(pbData);
    
    LSTATUS lStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DeviceAccess", 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
    
    if (lStatus == ERROR_SUCCESS) {
       
        lStatus = SHGetValueW(hKey, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DeviceAccess", L"ActivePolicyCode", &dwType, pbData, &dwDataSize);
    
        // Close the registry key
        RegCloseKey(hKey);
     
    }
    

    More info about accessing alternate registry views: