c++winapiregistrylpwstr

C++ Read values from the registry


I want to display these registry key values:

  1. MSSQL12.MSSQLSERVER
  2. MSSQL15.SQLEXPRESS
  3. MSSQL11.TEW_SQLEXPRESS

Registry

Code:

if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
        TEXT("SOFTWARE\\Microsoft\\Microsoft SQL Server\\Instance Names\\SQL"),
        0,
        KEY_READ | KEY_WOW64_64KEY,
        &hKey) == ERROR_SUCCESS){
    DWORD i, retCode, cchName, buflen;

    TCHAR    achKey[MAX_KEY_LENGTH];            // buffer for subkey name
    DWORD    cbName;                            // size of name string 
    TCHAR    achClass[MAX_PATH] = TEXT("");     // buffer for class name 
    DWORD    cchClassName = MAX_PATH;           // size of class string 
    DWORD    cSubKeys = 0;                      // number of subkeys 
    DWORD    cbMaxSubKey;                       // longest subkey size 
    DWORD    cchMaxClass;                       // longest class string 
    DWORD    cValues;                           // number of values for key 
    DWORD    cchMaxValue;                       // longest value name 
    DWORD    cbMaxValueData;                    // longest value data 
    DWORD    cbSecurityDescriptor;              // size of security descriptor 
    FILETIME ftLastWriteTime;                   // last write time 

    retCode = RegQueryInfoKey(
        hKey,                    // key handle 
        achClass,                // buffer for class name 
        &cchClassName,           // size of class string 
        NULL,                    // reserved 
        &cSubKeys,               // number of subkeys 
        &cbMaxSubKey,            // longest subkey size 
        &cchMaxClass,            // longest class string 
        &cValues,                // number of values for this key 
        &cchMaxValue,            // longest value name 
        &cbMaxValueData,         // longest value data 
        &cbSecurityDescriptor,   // security descriptor 
        &ftLastWriteTime);       // last write time 

   
    result = RegGetValue(
                hKey, NULL, L"MSSQLSERVER",                    
                RRF_RT_REG_SZ, 0, buf, &bufsz);
    if (result != ERROR_SUCCESS) {
                printf("Failed read value");
                _getch();
                return -1;
            }
    wprintf(L"%s\n", buf);
}

I need to replace L"MSSQLSERVER" with the variable keyName, but I don't understand how to do that. I'm trying to write the name of the key to a variable.

LPWSTR aResult;
LPSTR  keyName;
RegEnumKeyExA(hKey, i, keyName, &cchName, NULL, NULL, NULL, NULL);
MultiByteToWideChar(0, 0, keyName, -1, aResult, 0);
result = RegGetValue(
            hKey, NULL, aResult,                    
            RRF_RT_REG_SZ, 0, buf, &bufsz);

But I think it's wrong. Here keyName is NULL. And keyName is LPSTR, but RegGetValue() needs LPCWSTR.


Solution

  • It turned out that my task needed names, not values. And only SQL Express. Here is the code:

    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
            L"SOFTWARE\\Microsoft\\Microsoft SQL Server\\Instance Names\\SQL",
            0,
            KEY_READ | KEY_WOW64_64KEY,
            &hTestKey) == ERROR_SUCCESS
            )
    while (RegEnumValueW(hTestKey, index, (wchar_t*)valueName.c_str(), &lppchValueName, 0, 0, 0, 0) == ERROR_SUCCESS) 
            {
                lppchValueName = MAX_PATH;
                buffSize = MAX_PATH;
                if (RegQueryValueExW(hTestKey, valueName.c_str(), 0, 0, (LPBYTE)value.c_str(), &buffSize) == ERROR_SUCCESS)
                {
                    if (value.find(L"Express") != std::wstring::npos || value.find(L"EXPRESS") != std::wstring::npos || value.find(L"express") != std::wstring::npos)
                    {
                        // Here is an array entry.
                    }
                }
                index++;
                memset((void*)valueName.c_str(), 0, MAX_PATH);
                memset((void*)value.c_str(), 0, MAX_PATH);
            }