Question

I have the following code that compiles for MBCS.

CString GetRegistry(LPCTSTR pszValueName)
{
    // Try open registry key
    HKEY hKey = NULL;
    LPCTSTR pszSubkey = _T("SOFTWARE\\Wow6432Node\\PAX");
    if ( RegOpenKey(HKEY_LOCAL_MACHINE, pszSubkey, &hKey) != ERROR_SUCCESS )
    {
        // Error:
        // throw an exception or something...
        //
        // (In production code a custom C++ exception 
        // derived from std::runtime_error could be used)
        AtlThrowLastWin32();
    }

    // Buffer to store string read from registry
    TCHAR szValue[1024];
    DWORD cbValueLength = sizeof(szValue);

    // Query string value
    if ( RegQueryValueEx(
            hKey,
            pszValueName, 
            NULL, 
            NULL, 
            reinterpret_cast<LPBYTE>(&szValue), 
            &cbValueLength) 
         != ERROR_SUCCESS )
    {
        // Error
        // throw an exception or something...
        AtlThrowLastWin32();
    }

    // Create a CString from the value buffer
    return CString(szValue);
}
  • How can I make the code work also for 32 bit computers?
  • How can I put the return in a simple string? ex; string namevalue = GetRegistry(_T("name"));
Was it helpful?

Solution

You need to use RegOpenKeyEx() with the KEY_WOW64_32KEY flag and let it handle the Wow6432 node for you, eg:

CString GetRegistry(LPCTSTR pszValueName)
{
    // WOW64 access
    REGSAM Wow64Flag;
    #ifdef _WIN64
    Wow64Flag = KEY_WOW64_32KEY;
    #else
    Wow64Flag = 0;
    #endif

    // Try open registry key
    HKEY hKey = NULL;

    LONG lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\PAX"), 0, KEY_QUERY_VALUE | Wow64Flag, &hKey);
    if ( lResult != ERROR_SUCCESS )
    {
        // Error:
        // throw an exception or something...
        //
        // (In production code a custom C++ exception 
        // derived from std::runtime_error could be used)
        SetLastError(lResult);
        AtlThrowLastWin32();
    }

    DWORD cbValueLength;

    // Query string value size
    lResult = RegQueryValueEx(
            hKey,
            pszValueName, 
            NULL, 
            NULL, 
            NULL, 
            &cbValueLength) 
         != ERROR_SUCCESS )
    {
        // Error
        RegCloseKey(hKey);
        // throw an exception or something...
        SetLastError(lResult);
        AtlThrowLastWin32();
    }

    // Buffer to return string read from registry
    CString sValue;

    if ( cbValueLength > 0 )
    {
        // Buffer to store string read from registry
        std::vector<TCHAR> szValue((cbValueLength / sizeof(TCHAR))+1);

        lResult = RegQueryValueEx(
                hKey,
                pszValueName, 
                NULL, 
                NULL, 
                reinterpret_cast<LPBYTE>(&szValue[0]), 
                &cbValueLength) 
             != ERROR_SUCCESS )
        {
            // Error
            RegCloseKey(hKey);
            // throw an exception or something...
            SetLastError(lResult);
            AtlThrowLastWin32();
        }

        szValue[cbValueLength / sizeof(TCHAR)] = 0;
        sValue = &szValue[0];
    }

    RegCloseKey(hKey);

    return sValue;
}

When a 64bit process specifies KEY_WOW64_32KEY, or a 32bit process does not specify any WOW64 flag, it will be accessing the 32bit Registry, and thus SOFTWARE\PAX will resolve to SOFTWARE\Wow6432Node\PAX on a 64bit system.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top