C++ Win32 Getting a registry key

const char* Launcher::GetProjectName()
{
    PVOID data;
    LPDWORD pcbData;
    HKEY OpenResult;
    LSTATUS status = RegOpenKeyEx(HKEY_CURRENT_USER, L"Environment", NULL, KEY_READ, &OpenResult);
    if (status != ERROR_SUCCESS) 
    {
        LOG(ERROR) << "Could not found registry key 'Environment'";
    }
    else
    {
        LPCWSTR project_name_key = L"project_name";
        DWORD data_type;
        WCHAR value[255];
        PVOID pvData = value;
        DWORD size = sizeof(value);
        status = RegGetValue(OpenResult, NULL, project_name_key, RRF_RT_ANY, &data_type, pvData, &size);
        if (status != ERROR_SUCCESS)
        {
            LOG(ERROR) << "Could not found registry value 'project_name'";
        }
        else
        {
            switch (data_type)
            {
            case REG_DWORD:
                wprintf(L"Value data: %x\n", *(DWORD*)pvData);
                break;
            case REG_SZ:
                wprintf(L"Value data: %s\n", (PWSTR)pvData);
            }

        }
        RegCloseKey(OpenResult);
    }

    return 0;
}

I'm trying to get this registry key I made named "project_name" and return it as a char* or a std::string. However, I'm getting garbage data in pvData. What am I doing wrong here? I've seen some other stackoverflow posts and tried to replicate their setup as well but nothing is working. My entire goal here is to retrieve an environment variable using the windows registry.


I think there's a mismatch of ANSI and Unicode expectations. Your code is likely compiling for ANSI, but you're passing a wide-char buffer. Let's just explicitly call the A version of the Registry functions so you can stay in the ANSI string space.

Instead of this:

WCHAR value[255];
PVOID pvData = value;
DWORD size = sizeof(value);
status = RegGetValue(OpenResult, NULL, project_name_key, RRF_RT_ANY, &data_type, pvData, &size);

Use this:

char value[255];
DWORD size = sizeof(value);
status = RegGetValueA(OpenResult, NULL, project_name_key, RRF_RT_ANY, &data_type, value, &size);

Then, return a std::string as follows:

Declare your function to return a string, not a pointer:

const std::string Launcher::GetProjectName()

Then simply return value as a string;

return std::string(value);