Search code examples
c++registryvoid-pointers

Can't cast void pointer returned by RegGetValueA


I'm trying to access the registry using the RegGetValueA function, but I can't cast the void pointer passed to the function. I just get the (value?) of the pointer itself.

Here's my code:

    LSTATUS res;
    LPCSTR lpSubKey = "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{071c9b48-7c32-4621-a0ac-3f809523288f}";
    LPCSTR lpValue = "InstallSource";
    PVOID pvData = new PVOID;
    LPDWORD pcbData = new DWORD;

    res = RegGetValueA(
        HKEY_LOCAL_MACHINE,
        lpSubKey,
        lpValue,
        RRF_RT_ANY,
        NULL,
        pvData,
        pcbData);

    string* data = static_cast<string*>(pvData);
    cout << data << "\n";
    cout << pvData;

output:

000000000045A240
000000000045A240

Any help would be much appreciated.

link to documentation: https://learn.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-reggetvaluea


Solution

  • You are using the function incorrectly.

    First off, you shouldn't be accessing Wow6432Node directly at all. The function has flags for accessing 32bit and 64bit keys when dealing with WOW64.

    More importantly, you are giving the function a void* pointer that doesn't point at valid memory for your purpose. When reading a string value from the Registry, you must pre-allocate a character buffer of sufficient size, then pass the address of that buffer to the function. You can ask the function for the necessary buffer size.

    The code should look more like the following instead:

    LSTATUS res;
    LPCSTR lpSubKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{071c9b48-7c32-4621-a0ac-3f809523288f}";
    LPCSTR lpValue = "InstallSource";
    char *pszData = NULL;
    DWORD cbData = 0;
    
    res = RegGetValueA( HKEY_LOCAL_MACHINE, lpSubKey, lpValue, RRF_RT_REG_SZ | RRF_SUBKEY_WOW6432KEY, NULL, NULL, &cbData);
    if (res != ERROR_SUCCESS) ...
    
    pszData = new char[cbData];
    res = RegGetValueA( HKEY_LOCAL_MACHINE, lpSubKey, lpValue, RRF_RT_REG_SZ | RRF_SUBKEY_WOW6432KEY, NULL, pszData, &cbData);
    if (res != ERROR_SUCCESS) ...
    
    cout << pszData << "\n";
    delete[] pszData;