1

I'm trying to implement a QT app for WMI Query. However, I'm stuck at error:

C2440: 'default argument': cannot convert from 'const wchar_t [ 1 ]' in WbemDisp.h.

On doing some research, I came to know that it is due to some header not following the strictString rule and that I should add

win32: QMAKE_CXXFLAGS_RELEASE -= -Zc:strictStrings
win32: QMAKE_CFLAGS_RELEASE -= -Zc:strictStrings
win32: QMAKE_CFLAGS -= -Zc:strictStrings
win32: QMAKE_CXXFLAGS -= -Zc:strictStrings

in .pro file. (Reference:StackOverflow)

Please find the snippet from my project file below:

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = qt_Trial_Test
TEMPLATE = app


SOURCES += main.cpp\
     mainwindow.cpp

win32: QMAKE_CXXFLAGS_RELEASE -= -Zc:strictStrings
win32: QMAKE_CFLAGS_RELEASE -= -Zc:strictStrings
win32: QMAKE_CFLAGS -= -Zc:strictStrings
win32: QMAKE_CXXFLAGS -= -Zc:strictStrings


HEADERS  += mainwindow.h

FORMS    += mainwindow.ui 

But it's still not working. Please guide me towards the right solution.

Snippet of mainwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <comdef.h>
#include <comutil.h>
#include <Wbemidl.h>


#pragma comment(lib, "wbemuuid.lib")

// Typical WMI Query For C++

    void MainWindow::Wmic()
    {
    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 authentication
        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
    );


    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);

    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 root\cimv2 namespace with
    // the current user and obtain pointer pSvc
    // to make IWbemServices calls.
    hres = pLoc->ConnectServer(
        _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
        NULL,                    // User name. NULL = current user
        NULL,                    // User password. NULL = current
        0,                       // Locale. NULL indicates current
        NULL,                    // Security flags.
        0,                       // Authority (for example, Kerberos)
        0,                       // Context object
        &pSvc                    // pointer to IWbemServices proxy
    );

    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;


    // Step 5: --------------------------------------------------
    // Set security levels on 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
    );

    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: --------------------------------------------------
    // Use the IWbemServices pointer to make requests of WMI ----

    // For example, get the name of the operating system
    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(
        bstr_t("WQL"),
        bstr_t("SELECT * FROM Win32_DiskDrive WHERE InterfaceType != 'USB'"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
        NULL,
        &pEnumerator);

    if (FAILED(hres))
    {
        cout << "Query for operating system name failed."
            << " Error code = 0x"
            << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        //return 1;               // Program has failed.
    }

    // Step 7: -------------------------------------------------
    // Get the data from the query in step 6 -------------------

    IWbemClassObject *pclsObj = NULL;
    ULONG uReturn = 0;

    while (pEnumerator)
    {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
            &pclsObj, &uReturn);

        if (0 == uReturn)
        {
            break;
        }

        VARIANT vtProp;

        /************************************************/
        wchar_t temp[1024];
        /************************************************/

        // Get the value of the Name property
        hr = pclsObj->Get(L"InterfaceType", 0, &vtProp, 0, 0);
        //wcout << " Interface Type : " << vtProp.bstrVal << endl;
        VariantClear(&vtProp);
        hr = pclsObj->Get(L"Caption", 0, &vtProp, 0, 0);
        //wcout << " Caption : " << vtProp.bstrVal << endl;
        VariantClear(&vtProp);
        hr = pclsObj->Get(L"DeviceID", 0, &vtProp, 0, 0);
        //wcout << " Device ID : " << vtProp.bstrVal << endl;
        QString convertedBSTR((QChar*) vtProp.bstrVal, wcslen(vtProp.bstrVal));
        ui->textEdit_3->setText(convertedBSTR);
        //ui->textEdit_3->setText((const char*)_bstr_t(V_BSTR(&vtProp.bstrVal)));
        ui->textEdit_3->append(": \n");
        /***************************************************/
        wcscpy(temp, vtProp.bstrVal);
        /***************************************************/
        VariantClear(&vtProp);

        wstring ws(temp);
        // your new String
        string query(ws.begin(), ws.end());

        query = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + query + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition";

        IEnumWbemClassObject* pEnumerator1 = NULL;
        hres = pSvc->ExecQuery(bstr_t("WQL"),bstr_t(query.c_str()),
            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
            NULL, &pEnumerator1);

        if (FAILED(hres))
        {
            cout << "Query for Disk Partition failed."
                << " Error code = 0x"
                << hex << hres << endl;
            pSvc->Release();
            pLoc->Release();
            CoUninitialize();
            //return 1;               // Program has failed.
        }

        IWbemClassObject *pclsObj1;
        ULONG uReturn1 = 0;

        while (pEnumerator1)
        {
            HRESULT hr1 = pEnumerator1->Next(WBEM_INFINITE, 1, &pclsObj1, &uReturn1);
            if (0 == uReturn1)
            {
                break;
            }

            VARIANT vtProp1;
            wchar_t temp1[1024];

            hr1 = pclsObj1->Get(L"DeviceID", 0, &vtProp1, 0, 0);
            //wcout << " Device ID : " << vtProp1.bstrVal << endl;
            wcscpy(temp1, vtProp1.bstrVal);
            VariantClear(&vtProp1);
            wstring ws(temp1);
            // your new String
            string query1(ws.begin(), ws.end());

            query1 = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + query1 + "'} WHERE AssocClass = Win32_LogicalDiskToPartition";



            IEnumWbemClassObject* pEnumerator2 = NULL;

            hres = pSvc->ExecQuery(bstr_t("WQL"),
                bstr_t(query1.c_str()), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
                NULL, &pEnumerator2);
            if (FAILED(hres))
            {
                cout << "Query for Logical Disk failed."
                    << " Error code = 0x"
                    << hex << hres << endl;
                pSvc->Release();
                pLoc->Release();
                CoUninitialize();
                //return 1;               // Program has failed.
            }
            IWbemClassObject *pclsObj2;
            ULONG uReturn2 = 0;

            while (pEnumerator2)
            {
                HRESULT hr2 = pEnumerator2->Next(WBEM_INFINITE, 1,
                    &pclsObj2, &uReturn2);

                if (0 == uReturn2)
                {
                    break;
                }

                VARIANT vtProp2;
                wchar_t temp2[1024];

                hr2 = pclsObj2->Get(L"Caption", 0, &vtProp2, 0, 0);
                QString convertedBSTR((QChar*) vtProp2.bstrVal, wcslen(vtProp2.bstrVal));
                ui->textEdit_3->append(convertedBSTR);
                //ui->textEdit_3->append((const char*)_bstr_t(V_BSTR(&vtProp2.bstrVal)));
                ui->textEdit_3->append("\t");
                //wcout << " Caption : " << vtProp2.bstrVal << endl;
                wcscpy(temp2, vtProp2.bstrVal);
                VariantClear(&vtProp2);
                pclsObj2->Release();
            }
            pclsObj1->Release();
        }
    ui->textEdit_3->append("\n");
    pclsObj->Release();
}

// Cleanup
// ========

pSvc->Release();
pLoc->Release();
pEnumerator->Release();
CoUninitialize();
// Program successfully completed.
}


void MainWindow::on_pushButton_clicked()
{
   Wmic();
}
user9059547
  • 67
  • 1
  • 12
  • In case you require anything apart from the project file, Please let me know so that I can include snippet for it too. – user9059547 Oct 17 '18 at 12:33
  • 1
    [`BSTR` is not `wchar_t*`](https://learn.microsoft.com/en-us/cpp/atl-mfc-shared/allocating-and-releasing-memory-for-a-bstr?view=vs-2017) they are reference counted strings managed by COM. Any method taking a `BSTR` needs an actual `BSTR` not a `wchar_t*`, if you want a convienent way to do this there is the [`_bstr_t` class](https://learn.microsoft.com/en-us/cpp/cpp/bstr-t-class?view=vs-2017) – Mgetz Oct 17 '18 at 13:39
  • Possible duplicate of [error C2440: 'default argument': cannot convert from 'const wchar\_t \[1\]' to 'BSTR'](https://stackoverflow.com/questions/37204166/error-c2440-default-argument-cannot-convert-from-const-wchar-t-1-to-bst) – Mgetz Oct 17 '18 at 13:47
  • @Mgetz I have already gone through the above link and tried it but it doesn't work for me. I've mentioned it in my problem too. – user9059547 Oct 18 '18 at 04:31
  • @JanneKarila It has typical WMI query to list the partitions within the disks. I've included the Wmic Query code which is executed on button click from the QT based UI. The output is displayed in the textbox. – user9059547 Oct 18 '18 at 06:23
  • @JanneKarila It's native to QT and the error message C:\Program Files (x86)\Windows Kits\8.1\Include\um\WbemDisp.h: error: C2440: 'default argument': cannot convert from 'const wchar_t [1]' to 'BSTR' appears for header file WbemDisp.h which is required for executing Wmi Query in C++. So, it can't be compiled. – user9059547 Oct 18 '18 at 06:51
  • Do you get the error if your main.cpp contains nothing but `#include "WbemDisp.h"`? (I don't) – Janne Karila Oct 18 '18 at 07:00
  • 1
    @JanneKarila Do you require minimal code that can be compiled in VS?? – user9059547 Oct 18 '18 at 07:00
  • Yes, I do get an error (actually about 22 times) for wchar_t[1] and wchar_t[4] at different lines of the header file. And I've edited the code in mainwindow.cpp – user9059547 Oct 18 '18 at 07:12
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/182067/discussion-between-user9059547-and-janne-karila). – user9059547 Oct 18 '18 at 07:12
  • 1
    @user9059547 `_bstr_t` is a class you'll need to explicitly store those on the stack prior to your method calls and call [`.GetBSTR()`](https://learn.microsoft.com/en-us/cpp/cpp/bstr-t-getbstr?view=vs-2017) when passing them to methods. Otherwise they have an implicit (which is bad) conversion operator to `wchar_t*`. – Mgetz Oct 18 '18 at 12:37
  • @Mgetz You need me explicitly convert to BSTR before the calling a particular method/API using a different function. But, I have a doubt, why is it that I'm getting error messages just by including the header file or – user9059547 Oct 23 '18 at 05:32
  • @user9059547 without knowing the errors I can't say, you're able to always use `SysAllocString` and `SysFreeString` yourself if you wish but that introduces a level of possible leaks you can avoid. – Mgetz Oct 23 '18 at 11:20

0 Answers0