Search code examples
c++wmi

C++ WMI Set registry value


WMI method SetStringValue returns error code 6 - INVALID_HANDLE_VALUE. There are no other errors in this code. The new value is not added to the registry. What is the problem?

#define CHECK_HR(hr) if (FAILED(hr)) goto Exit;
#define COM_RELEASE(p) if (p) p->Release();

BOOLEAN WmiAddToAutorun()
{
    IWbemLocator* pLocator = nullptr;
    IWbemServices* pServices = nullptr;
    IWbemClassObject* pClassObject = nullptr;
    IWbemClassObject* pClassInstance = nullptr;
    IWbemClassObject* pInParamsDefinition = nullptr;
    IWbemClassObject* pOutParams = nullptr;
    IWbemContext* pContext = nullptr;

    VARIANT providerArchVar;
    VARIANT requiredArchVar;

    _variant_t var1(HKEY_CURRENT_USER);
    _variant_t var2(L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
    _variant_t var3(L"<Name>");
    _variant_t var4(L"<Path>");
    _variant_t varReturnValue = 1;

    if (FAILED(CoInitializeEx(0, COINIT_MULTITHREADED)))
    {
        return FALSE;
    }

    CHECK_HR(CoInitializeSecurity(NULL, -1, NULL, NULL,
        RPC_C_AUTHN_LEVEL_DEFAULT,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL, EOAC_NONE, NULL));

    CHECK_HR(CoCreateInstance(CLSID_WbemLocator, 0,
        CLSCTX_INPROC_SERVER, IID_IWbemLocator,
        (LPVOID*)&pLocator));

    CHECK_HR(CoCreateInstance(CLSID_WbemContext, 0, CLSCTX_INPROC_SERVER, IID_IWbemContext, (LPVOID*)&pContext));

    VariantInit(&providerArchVar);
    providerArchVar.vt = VT_I4;
    providerArchVar.iVal = 64;
    CHECK_HR(pContext->SetValue(L"__ProviderArchitecture", 0, &providerArchVar));

    VariantInit(&requiredArchVar);
    requiredArchVar.vt = VT_BOOL;
    requiredArchVar.boolVal = TRUE;
    CHECK_HR(pContext->SetValue(L"__RequiredArchitecture", 0, &requiredArchVar));

    CHECK_HR(pLocator->ConnectServer(_bstr_t(L"\\\\<PC-Name>\\root\\cimv2"),
        NULL, NULL, 0, NULL, 0, pContext, &pServices));

    CHECK_HR(CoSetProxyBlanket(pServices, RPC_C_AUTHN_WINNT,
        RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL, EOAC_NONE));

    CHECK_HR(pServices->GetObject(_bstr_t(L"StdRegProv"), 0, NULL, &pClassObject, NULL));

    CHECK_HR(pClassObject->GetMethod(_bstr_t(L"SetStringValue"), 0, &pInParamsDefinition, NULL));

    CHECK_HR(pInParamsDefinition->SpawnInstance(0, &pClassInstance));

    CHECK_HR(pClassInstance->Put(L"hDefKey", 0, &var1, CIM_UINT32));
    CHECK_HR(pClassInstance->Put(L"sSubKeyName", 0, &var2, CIM_STRING));
    CHECK_HR(pClassInstance->Put(L"sValueName", 0, &var3, CIM_STRING));
    CHECK_HR(pClassInstance->Put(L"sValue", 0, &var4, CIM_STRING));

    CHECK_HR(pServices->ExecMethod(_bstr_t(L"StdRegProv"), _bstr_t(L"SetStringValue"),
        0, pContext, pClassInstance, &pOutParams, NULL));

    CHECK_HR(pOutParams->Get(_bstr_t(L"ReturnValue"), 0, &varReturnValue, NULL, NULL));

    char buf[100];
    sprintf_s(buf, 100, "RETVAL = %d\n", (uint32_t)varReturnValue);
    OutputDebugStringA(buf);

Exit:
    COM_RELEASE(pLocator);
    COM_RELEASE(pServices);
    COM_RELEASE(pClassObject);
    COM_RELEASE(pClassInstance);
    COM_RELEASE(pInParamsDefinition);
    COM_RELEASE(pOutParams);
    COM_RELEASE(pContext);
    CoUninitialize();
    return (uint32_t)varReturnValue == 0;
}

Solution

  • Replace _variant_t var1(HKEY_CURRENT_USER); with _variant_t var1("2147483649");.