WMI C++ Application problem WmiMonitorDescriptorMethods WmiGetMonitorRawEEdidV1Block

Robins.Lee 21 Reputation points
2020-09-15T09:24:38.743+00:00

// ConsoleApplication1.cpp : Defines the entry point for the console application.
//

include "stdafx.h"

define _WIN32_DCOM

include <iostream>

using namespace std;

include <comdef.h>

include <Wbemidl.h>

pragma comment(lib, "wbemuuid.lib")

int main(int iArgCnt, char ** argv)
{
HRESULT hres;

// Step 1: --------------------------------------------------
// Initialize COM. ------------------------------------------

hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres))
{
    cout << "Failed to initialize COM library. Error code = 0x"
        << hex << hres << endl;
    return 1;                  // Program has failed.
}

// Step 2: --------------------------------------------------
// Set general COM security levels --------------------------

hres = CoInitializeSecurity(
    NULL,
    -1,                          // COM negotiates service
    NULL,                        // Authentication services
    NULL,                        // Reserved
    RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
    RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
    NULL,                        // Authentication info
    EOAC_NONE,                   // Additional capabilities 
    NULL                         // Reserved
);

//hr = CoInitializeSecurity(
//    NULL, 
//    -1, 
//    NULL,
//    NULL,
//    RPC_C_AUTHN_LEVEL_DEFAULT,
//    RPC_C_IMP_LEVEL_IMPERSONATE,
//    NULL,
//    EOAC_NONE,
//    NULL);

if (FAILED(hres))
{
    cout << "Failed to initialize security. Error code = 0x"
        << hex << hres << endl;
    CoUninitialize();
    return 1;                      // Program has failed.
}

// Step 3: ---------------------------------------------------
// Obtain the initial locator to WMI -------------------------

IWbemLocator *pLoc = NULL;

hres = CoCreateInstance(
    CLSID_WbemLocator,
    0,
    CLSCTX_INPROC_SERVER,
    IID_IWbemLocator, (LPVOID *)&pLoc);

// CoCreateInstance(
//  CLSID_WbemLocator,
//  0,
//  CLSCTX_INPROC_SERVER,
//  IID_IWbemLocator, (LPVOID *) &m_pWmiLoc);

if (FAILED(hres))
{
    cout << "Failed to create IWbemLocator object. "
        << "Err code = 0x"
        << hex << hres << endl;
    CoUninitialize();
    return 1;                 // Program has failed.
}

// Step 4: ---------------------------------------------------
// Connect to WMI through the IWbemLocator::ConnectServer method

IWbemServices *pSvc = NULL;

// Connect to the local root\cimv2 namespace
// and obtain pointer pSvc to make IWbemServices calls.
hres = pLoc->ConnectServer(
    //_bstr_t(L"ROOT\\CIMV2"),
    _bstr_t(L"ROOT\\WMI"),
    NULL,
    NULL,
    0,
    NULL,
    0,
    0,
    &pSvc
);
//hres = m_pWmiLoc->ConnectServer(
//     bstrNamespace,
//     NULL,
//     NULL,
//     0,
//     NULL,
//     0,
//     0,
//     &m_pWmiServ);

if (FAILED(hres))
{
    cout << "Could not connect. Error code = 0x"
        << hex << hres << endl;
    pLoc->Release();
    CoUninitialize();
    return 1;                // Program has failed.
}

//cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;
cout << "Connected to ROOT\\WMI WMI namespace" << endl;


// Step 5: --------------------------------------------------
// Set security levels for the proxy ------------------------

hres = CoSetProxyBlanket(
    pSvc,                        // Indicates the proxy to set
    RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx 
    RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx 
    NULL,                        // Server principal name 
    RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
    RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
    NULL,                        // client identity
    EOAC_NONE                    // proxy capabilities 
);

//hres = CoSetProxyBlanket(
//    m_pWmiServ, 
//    RPC_C_AUTHN_WINNT,
//    RPC_C_AUTHZ_NONE,
//    NULL,
//    RPC_C_AUTHN_LEVEL_CALL,
//    RPC_C_IMP_LEVEL_IMPERSONATE,
//    NULL,
//    EOAC_NONE);

if (FAILED(hres))
{
    cout << "Could not set proxy blanket. Error code = 0x"
        << hex << hres << endl;
    pSvc->Release();
    pLoc->Release();
    CoUninitialize();
    return 1;               // Program has failed.
}


// Step 6: --------------------------------------------------
printf("Step 6\n");
// Use the IWbemServices pointer to make requests of WMI ----

// set up to call the Win32_Process::Create method
//BSTR MethodName = SysAllocString(L"Create");
//BSTR ClassName = SysAllocString(L"Win32_Process"); 
BSTR MethodName = SysAllocString(L"WmiGetMonitorRawEEdidV1Block");
BSTR ClassName = SysAllocString(L"WmiMonitorDescriptorMethods");
IWbemClassObject *pClass = NULL;

if 0

//-------need Add------------------------------------------------
DWORD nReturned;
IEnumWbemClassObject* m_ppiWmiEnum = NULL;
/*
HRESULT CAccessWmi::EnumInstances(CString& csInstName, OUT IEnumWbemClassObject** ppiWmiEnum)
{
if (NULL == ppiWmiEnum)
return E_INVALIDARG;

BSTR    bstrObjectName = SysAllocString(csInstName.GetBuffer());
HRESULT hr =  m_pWmiServ->CreateInstanceEnum(    bstrObjectName,
WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
NULL,
ppiWmiEnum);
if (bstrObjectName)
SysFreeString(bstrObjectName);
return hr;
}
*/
hres = pSvc->CreateInstanceEnum(ClassName,
    WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
    NULL,
    &m_ppiWmiEnum);
if (FAILED(hres))
{
    pSvc->Release();
    pLoc->Release();
    CoUninitialize();
    printf("CreateInstanceEnum err\n");
}
else
{
    printf("CreateInstanceEnum OK\n");
}
hres = m_ppiWmiEnum->Next(WBEM_INFINITE, 1, &pClass, &nReturned);
if (hres != WBEM_S_NO_ERROR)
{
    printf("m_ppiWmiEnum->Next err\n");
}
else
{
    printf("m_ppiWmiEnum->Next ok\n");
}

//--------------------------------------------------------------

endif

hres = pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL);

IWbemClassObject* pInParamsDefinition = NULL;
hres = pClass->GetMethod(MethodName, 0,
    &pInParamsDefinition, NULL);
if (FAILED(hres))
{
    printf("pClass->GetMethod err\n");
}
else
{
    printf("pClass->GetMethod ok\n");
}

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

// Create the values for the in parameters
VARIANT varCommand;
//varCommand.vt = VT_BSTR;
//varCommand.bstrVal = _bstr_t(L"notepad.exe");

varCommand.vt = VT_UI1;
varCommand.bVal = 0;

// Store the value for the in parameters
//hres = pClassInstance->Put(L"CommandLine", 0, &varCommand, 0);
//wprintf(L"The command is: %s\n", V_BSTR(&varCommand));
hres = pClassInstance->Put(L"BlockId", 0, &varCommand, 0);
wprintf(L"The BlockId is: %d\n", V_UI1(&varCommand));

// Execute Method
IWbemClassObject* pOutParams = NULL;
hres = pSvc->ExecMethod(ClassName, MethodName, 0,
    NULL, pClassInstance, &pOutParams, NULL);
//hres = m_pWmiServ->ExecMethod(bstrObjectPath, bstrMethodName, 0, 
//  NULL, pInParam, ppiWmiOut, NULL);

//20200909
//WBEM_E_INVALID_METHOD_PARAMETERS; 2147749935 (0x8004102F). The parameters are invalid...
if (FAILED(hres))
{
    cout << "Could not execute method. Error code = 0x"
        << hex << hres << endl;
    VariantClear(&varCommand);
    SysFreeString(ClassName);
    SysFreeString(MethodName);
    pClass->Release();
    pClassInstance->Release();
    pInParamsDefinition->Release();
    pOutParams->Release();
    pSvc->Release();
    pLoc->Release();
    CoUninitialize();
    return 1;               // Program has failed.
}

// To see what the method returned,
// use the following code.  The return value will
// be in &varReturnValue
VARIANT varReturnValue;
//hres = pOutParams->Get(_bstr_t(L"ReturnValue"), 0, &varReturnValue, NULL, 0);
hres = pOutParams->Get(_bstr_t(L"BlockType"), 0, &varReturnValue, NULL, 0);
if (FAILED(hres))
{
    printf("BlockType err\n");
}
else
{
    printf("BlockType:%d\n", varReturnValue.bVal);
}


// Clean up
//--------------------------
VariantClear(&varCommand);
VariantClear(&varReturnValue);
SysFreeString(ClassName);
SysFreeString(MethodName);
pClass->Release();
pClassInstance->Release();
pInParamsDefinition->Release();
pOutParams->Release();
pLoc->Release();
pSvc->Release();
CoUninitialize();
return 0;

}

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,498 questions
0 comments No comments
{count} votes

Accepted answer
  1. Drake Wu - MSFT 991 Reputation points
    2020-09-16T02:38:54.07+00:00

    @Robins.Lee The ExecMethod alway return WBEM_E_INVALID_METHOD_PARAMETERS because you pass the class name for the first parameter, but it needs a valid the object path of the object for which the method is executed.
    You only obtained this class, not the object of this class. You can use "SELECT * FROM WmiMonitorDescriptorMethods" to get the pEnumerator of the class object, then get the path of each object, and then call WmiGetMonitorRawEEdidV1Block for each object.

        IEnumWbemClassObject* pEnumerator = NULL;  
        wstring strQuery = L"SELECT * FROM WmiMonitorDescriptorMethods";  
        hres = pSvc->ExecQuery(BSTR(L"WQL"), BSTR(strQuery.c_str()),  
            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);  
          
        ULONG uReturn = 0;  
        while (pEnumerator)  
        {  
            IWbemClassObject* pclsObj = NULL;  
            UINT32 bit = 0;  
            hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);  
      
            if (0 == uReturn || FAILED(hres))  
                break;  
            VARIANT var;  
            pclsObj->Get(L"__PATH", 0, &var, NULL, NULL);  
            ...  
            hres = pSvc->ExecMethod(var.bstrVal, MethodName, 0, NULL, pClassInstance, &pOutParams, NULL);  
            ...  
        }  
    

    The following sample works for me:

    #define _WIN32_DCOM  
      
    #include <iostream>  
    using namespace std;  
      
    #include <comdef.h>  
    #include <Wbemidl.h>  
      
    #pragma comment(lib, "wbemuuid.lib")  
    int main(int iArgCnt, char** argv)  
    {  
        HRESULT hres;  
        // Step 1: --------------------------------------------------  
     // Initialize COM. ------------------------------------------  
        hres = CoInitializeEx(0, COINIT_MULTITHREADED);  
        if (FAILED(hres))  
        {  
            cout << "Failed to initialize COM library. Error code = 0x"  
                << hex << hres << endl;  
            return 1;                  // Program has failed.  
        }  
        // Step 2: --------------------------------------------------  
        // Set general COM security levels --------------------------  
        hres = CoInitializeSecurity(  
            NULL,  
            -1,                          // COM negotiates service  
            NULL,                        // Authentication services  
            NULL,                        // Reserved  
            RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication   
            RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
            NULL,                        // Authentication info  
            EOAC_NONE,                   // Additional capabilities   
            NULL                         // Reserved  
        );  
        //hr = CoInitializeSecurity(  
        //    NULL,   
        //    -1,   
        //    NULL,  
        //    NULL,  
        //    RPC_C_AUTHN_LEVEL_DEFAULT,  
        //    RPC_C_IMP_LEVEL_IMPERSONATE,  
        //    NULL,  
        //    EOAC_NONE,  
        //    NULL);  
        if (FAILED(hres))  
        {  
            cout << "Failed to initialize security. Error code = 0x"  
                << hex << hres << endl;  
            CoUninitialize();  
            return 1;                      // Program has failed.  
        }  
        // Step 3: ---------------------------------------------------  
        // Obtain the initial locator to WMI -------------------------  
        IWbemLocator* pLoc = NULL;  
        hres = CoCreateInstance(  
            CLSID_WbemLocator,  
            0,  
            CLSCTX_INPROC_SERVER,  
            IID_IWbemLocator, (LPVOID*)&pLoc);  
        // CoCreateInstance(  
        //  CLSID_WbemLocator,  
        //  0,  
        //  CLSCTX_INPROC_SERVER,  
        //  IID_IWbemLocator, (LPVOID *) &m_pWmiLoc);  
        if (FAILED(hres))  
        {  
            cout << "Failed to create IWbemLocator object. "  
                << "Err code = 0x"  
                << hex << hres << endl;  
            CoUninitialize();  
            return 1;                 // Program has failed.  
        }  
        // Step 4: ---------------------------------------------------  
        // Connect to WMI through the IWbemLocator::ConnectServer method  
        IWbemServices* pSvc = NULL;  
        // Connect to the local root\cimv2 namespace  
        // and obtain pointer pSvc to make IWbemServices calls.  
        hres = pLoc->ConnectServer(  
            //_bstr_t(L"ROOT\\CIMV2"),  
            _bstr_t(L"ROOT\\WMI"),  
            NULL,  
            NULL,  
            0,  
            NULL,  
            0,  
            0,  
            &pSvc  
        );  
        //hres = m_pWmiLoc->ConnectServer(  
        //     bstrNamespace,  
        //     NULL,  
        //     NULL,  
        //     0,  
        //     NULL,  
        //     0,  
        //     0,  
        //     &m_pWmiServ);  
        if (FAILED(hres))  
        {  
            cout << "Could not connect. Error code = 0x"  
                << hex << hres << endl;  
            pLoc->Release();  
            CoUninitialize();  
            return 1;                // Program has failed.  
        }  
        //cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;  
        cout << "Connected to ROOT\\WMI WMI namespace" << endl;  
        // Step 5: --------------------------------------------------  
        // Set security levels for the proxy ------------------------  
        hres = CoSetProxyBlanket(  
            pSvc,                        // Indicates the proxy to set  
            RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx   
            RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx   
            NULL,                        // Server principal name   
            RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx   
            RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx  
            NULL,                        // client identity  
            EOAC_NONE                    // proxy capabilities   
        );  
        //hres = CoSetProxyBlanket(  
        //    m_pWmiServ,   
        //    RPC_C_AUTHN_WINNT,  
        //    RPC_C_AUTHZ_NONE,  
        //    NULL,  
        //    RPC_C_AUTHN_LEVEL_CALL,  
        //    RPC_C_IMP_LEVEL_IMPERSONATE,  
        //    NULL,  
        //    EOAC_NONE);  
        if (FAILED(hres))  
        {  
            cout << "Could not set proxy blanket. Error code = 0x"  
                << hex << hres << endl;  
            pSvc->Release();  
            pLoc->Release();  
            CoUninitialize();  
            return 1;               // Program has failed.  
        }  
        // Step 6: --------------------------------------------------  
        printf("Step 6\n");  
        // Use the IWbemServices pointer to make requests of WMI ----  
        // set up to call the Win32_Process::Create method  
        //BSTR MethodName = SysAllocString(L"Create");  
        //BSTR ClassName = SysAllocString(L"Win32_Process");   
        BSTR MethodName = SysAllocString(L"WmiGetMonitorRawEEdidV1Block");  
        BSTR ClassName = SysAllocString(L"WmiMonitorDescriptorMethods");  
          
    #if 0  
        //-------need Add------------------------------------------------  
        DWORD nReturned;  
        IEnumWbemClassObject* m_ppiWmiEnum = NULL;  
        /*  
        HRESULT    CAccessWmi::EnumInstances(CString& csInstName, OUT IEnumWbemClassObject** ppiWmiEnum)  
        {  
        if (NULL == ppiWmiEnum)  
        return E_INVALIDARG;  
        BSTR    bstrObjectName = SysAllocString(csInstName.GetBuffer());  
        HRESULT hr =  m_pWmiServ->CreateInstanceEnum(    bstrObjectName,  
        WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,  
        NULL,  
        ppiWmiEnum);  
        if (bstrObjectName)  
        SysFreeString(bstrObjectName);  
        return hr;  
        }  
        */  
        hres = pSvc->CreateInstanceEnum(ClassName,  
            WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,  
            NULL,  
            &m_ppiWmiEnum);  
        if (FAILED(hres))  
        {  
            pSvc->Release();  
            pLoc->Release();  
            CoUninitialize();  
            printf("CreateInstanceEnum err\n");  
        }  
        else  
        {  
            printf("CreateInstanceEnum OK\n");  
        }  
        hres = m_ppiWmiEnum->Next(WBEM_INFINITE, 1, &pClass, &nReturned);  
        if (hres != WBEM_S_NO_ERROR)  
        {  
            printf("m_ppiWmiEnum->Next err\n");  
        }  
        else  
        {  
            printf("m_ppiWmiEnum->Next ok\n");  
        }  
        //--------------------------------------------------------------  
      
    #endif  
        IEnumWbemClassObject* pEnumerator = NULL;  
        wstring strQuery = L"SELECT * FROM WmiMonitorDescriptorMethods";  
        hres = pSvc->ExecQuery(BSTR(L"WQL"), BSTR(strQuery.c_str()),  
            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);  
          
        ULONG uReturn = 0;  
        while (pEnumerator)  
        {  
            IWbemClassObject* pclsObj = NULL;  
            UINT32 bit = 0;  
            hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);  
      
            if (0 == uReturn || FAILED(hres))  
                break;  
      
            IWbemClassObject* pClass = NULL;  
            hres = pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL);  
            IWbemClassObject* pInParamsDefinition = NULL;  
            hres = pClass->GetMethod(MethodName, 0, &pInParamsDefinition, NULL);  
            IWbemClassObject* pClassInstance = NULL;  
            hres = pInParamsDefinition->SpawnInstance(0, &pClassInstance);  
      
      
            VARIANT var;  
            pclsObj->Get(L"__PATH", 0, &var, NULL, NULL);  
      
            VARIANT varCommand = { 0 };  
            //varCommand.vt = VT_BSTR;  
            //varCommand.bstrVal = _bstr_t(L"notepad.exe");  
            varCommand.vt = VT_UI1;  
            varCommand.bVal = 0;  
            // Store the value for the in parameters  
            //hres = pClassInstance->Put(L"CommandLine", 0, &varCommand, 0);  
            //wprintf(L"The command is: %s\n", V_BSTR(&varCommand));  
            hres = pClassInstance->Put(L"BlockId", 0, &varCommand, 0);  
            wprintf(L"The BlockId is: %d\n", V_UI1(&varCommand));  
            // Execute Method  
            IWbemClassObject* pOutParams = NULL;  
            hres = pSvc->ExecMethod(var.bstrVal, MethodName, 0,  
                NULL, pClassInstance, &pOutParams, NULL);  
            if (FAILED(hres))  
            {  
                cout << "Could not execute method. Error code = 0x"  
                    << hex << hres << endl;  
                VariantClear(&varCommand);  
                SysFreeString(ClassName);  
                SysFreeString(MethodName);  
                pClass->Release();  
                pClassInstance->Release();  
                pInParamsDefinition->Release();  
                pOutParams->Release();  
                pSvc->Release();  
                pLoc->Release();  
                CoUninitialize();  
                return 1;               // Program has failed.  
            }  
      
            VARIANT varReturnValue;  
            //hres = pOutParams->Get(_bstr_t(L"ReturnValue"), 0, &varReturnValue, NULL, 0);  
            hres = pOutParams->Get(_bstr_t(L"BlockType"), 0, &varReturnValue, NULL, 0);  
            if (FAILED(hres))  
            {  
                printf("BlockType err\n");  
            }  
            else  
            {  
                printf("BlockType:%d\n", varReturnValue.bVal);  
            }  
            // Clean up  
            //--------------------------  
            VariantClear(&var);  
            VariantClear(&varCommand);  
            VariantClear(&varReturnValue);  
            pClass->Release();  
            pClassInstance->Release();  
            pInParamsDefinition->Release();  
            pOutParams->Release();  
            pclsObj->Release();  
        }  
        if (FAILED(hres))  
        {  
            printf("pClass->GetMethod err\n");  
        }  
        else  
        {  
            printf("pClass->GetMethod ok\n");  
        }  
        //--------------------------  
        SysFreeString(ClassName);  
        SysFreeString(MethodName);  
      
        pLoc->Release();  
        pSvc->Release();  
        pEnumerator->Release();  
        CoUninitialize();  
        return 0;  
    }  
    

    If the answer is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Robins.Lee 21 Reputation points
    2020-09-15T09:25:43.267+00:00

    ExecMethod always return err

    0 comments No comments

  2. Robins.Lee 21 Reputation points
    2020-09-16T03:10:33.247+00:00

    @Drake Wu - MSFT

    Thanks for you help

    0 comments No comments