0

I am trying to read a registry value using WMI. Here is what I have now:

    BSTR methodName = SysAllocString(L"GetStringValue");
    BSTR className = SysAllocString(L"StdRegProv");
    IWbemClassObject* pInParamsDefinition = nullptr;

    std::wstring errStr = L"ERROR";

    HRESULT hRes = p_regWbemClassObj->GetMethod(methodName, 0, &pInParamsDefinition, NULL);

    IWbemClassObject* pClassInstance = NULL;
    hRes = pInParamsDefinition->SpawnInstance(0, &pClassInstance);

    // Create the values for the in parameters
    VARIANT sSubKeyName;
    sSubKeyName.vt = VT_BSTR;
    sSubKeyName.bstrVal = BSTR(path.c_str());
    VARIANT sValueName;
    sValueName.vt = VT_BSTR;
    sValueName.bstrVal = BSTR(key.c_str());


    // Store the value for the in parameters
    hRes = pClassInstance->Put(L"sSubKeyName", 0,
        &sSubKeyName, 0);
    hRes = pClassInstance->Put(L"sValueName", 0,
        &sSubKeyName, 0);

    // Execute Method
    IWbemClassObject* pOutParams = NULL;
    hRes = p_defWbemServices->ExecMethod(className, methodName, 0,
        NULL, pClassInstance, &pOutParams, NULL);

    if (FAILED(hRes))
    {
        VariantClear(&sSubKeyName);
        VariantClear(&sValueName);
        SysFreeString(className);
        SysFreeString(methodName);
        pInParamsDefinition->Release();
        pClassInstance->Release();
        pOutParams->Release();
        return errStr;
    }


    VARIANT varReturnValue;
    hRes = pOutParams->Get(BSTR(L"sValue"), 0, &varReturnValue, NULL, NULL);

    std::wstring result = varReturnValue.bstrVal;

For some reason I never get a correct varReturnValue. Here is the function: http://msdn.microsoft.com/en-us/library/aa390788(v=vs.85).aspx

black
  • 357
  • 3
  • 18

3 Answers3

0

Been a while but... have you called VariantInit on the Variant first. IIRC it needs to be initialised when calling COM methods.

gbjbaanb
  • 51,617
  • 12
  • 104
  • 148
0

Here is an example that will answer your question. In the example, I find out the name of the current document being printed.

using std::cout;
using std::cin;
using std::endl;

HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(hRes))
{
    cout << "Unable to launch COM: 0x" << std::hex << hRes << endl;
    return 1;
}

if ((FAILED(hRes = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0))))
{
    cout << "Unable to initialize security: 0x" << std::hex << hRes << endl;
    return 1;
}

IWbemLocator* pLocator = NULL;
if (FAILED(hRes = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator))))
{
    cout << "Unable to create a WbemLocator: " << std::hex << hRes << endl;
    return 1;
}

IWbemServices* pService = NULL;
if (FAILED(hRes = pLocator->ConnectServer(L"root\\CIMV2", NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pService)))
{
    pLocator->Release();
    cout << "Unable to connect to \"CIMV2\": " << std::hex << hRes << endl;
    return 1;
}

IEnumWbemClassObject* pEnumerator = NULL;
if (FAILED(hRes = pService->ExecQuery(L"WQL", L"SELECT Documents FROM Win32_PrintJob", WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))
{
    pLocator->Release();
    pService->Release();
    cout << "Unable to retrive desktop monitors: " << std::hex << hRes << endl;
    return 1;
}

IWbemClassObject* clsObj = NULL;
int numElems;
while ((hRes = pEnumerator->Next(WBEM_INFINITE, 1, &clsObj, (ULONG*)&numElems)) != WBEM_S_FALSE)
{
    if (FAILED(hRes))
        break;

    VARIANT vRet;
    VariantInit(&vRet);
    if (SUCCEEDED(clsObj->Get(L"Description", 0, &vRet, NULL, NULL)) && vRet.vt == VT_BSTR)
    {
        std::wcout << L"Description: " << vRet.bstrVal << endl;
        VariantClear(&vRet);
    }

    clsObj->Release();
}

pEnumerator->Release();
pService->Release();
pLocator->Release();
return 0;
Michael Haephrati
  • 3,660
  • 1
  • 33
  • 56
0

You put in "sSubKeyName" and "sValueName" the same value - &sSubKeyName.

// Store the value for the in parameters
    hRes = pClassInstance->Put(L"sSubKeyName", 0,
        &sSubKeyName, 0); // <-- sSubKeyName
    hRes = pClassInstance->Put(L"sValueName", 0,
        &sSubKeyName, 0); // <-- sSubKeyName

I think you meant to do this:

// Store the value for the in parameters
        hRes = pClassInstance->Put(L"sSubKeyName", 0,
            &sSubKeyName, 0); // <-- sSubKeyName
        hRes = pClassInstance->Put(L"sValueName", 0,
            &sValueName, 0); // <-- sValueName
Step_Ua
  • 1
  • 1