PDA

View Full Version : QCroreApplication QApplication with WMI



newb
5th June 2010, 06:07
Dear all,

I have serached for using WMI with Qt.

I found some WMI C++ Application Examples in MSDN website.

I have tried the code form the below link

http://msdn.microsoft.com/en-us/library/aa390423%28v=VS.85%29.aspx

when i copied and run the application as win32 console application it worked well.

the same code i ut into the Qt application ,

When i use QApplication anApplication ( argc, argv ); in my code it is not working

But if i use QCroreApplication anApplication ( argc, argv ); it is working

Any suggestions or help

tbscope
5th June 2010, 09:17
Post your source code

squidge
5th June 2010, 10:25
and please use [ code ] tags this time :)

newb
11th June 2010, 10:40
when i change QCroreApplication to QApplication The below source code not works and gives me errror like " Failed to initialize COM library. Error code = 0x80010106 "


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

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

// Qt Includes
#include <QtCore>
#include <QtGui>


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

// Main Function
int main( int a_argc, char *a_argv[] )
//************************************
{
// initialize the application
QApplication anapplication( a_argc, a_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 --------------------------
// Note: If you are using Windows 2000, you need to specify -
// the default authentication credentials for a user by using
// a SOLE_AUTHENTICATION_LIST structure in the pAuthList ----
// parameter of CoInitializeSecurity ------------------------

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 (e.g. 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_USBControllerDevice"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);

//ExecQuery(L"WQL", L"SELECT * FROM Win32_LogicalDisk", WBEM_FLAG_FORWARD_ONLY, NULL, &iter);

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;
ULONG uReturn = 0;

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

if(FAILED(hr)||0 == uReturn)
{
break;
}

VARIANT vtProp;

// Get the value of the Name property
/*hr = pclsObj->Get(L"VolumeName", 0, &vtProp, 0, 0);
wcout << " VolumeName : " << vtProp.bstrVal << endl;
VariantClear(&vtProp);*/


if (FAILED(pclsObj->Get(L"Antecedent", 0, &vtProp, 0, 0)))
{
cout<<"The specified property is not found."<<endl;
}
else
{
wcout <<vtProp.bstrVal << endl;
}

pclsObj->Release();
}

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

pSvc->Release();
pLoc->Release();
pEnumerator->Release();
// pclsObj->Release();
CoUninitialize();


// return 0; // Program successfully completed.

//execute the application
int anInt = anapplication.exec();

return anInt;
}
//-----------------------------------------------------------------------------

high_flyer
11th June 2010, 10:52
Do you have the code for CoInitializeEx()?
What happens if you initialize your QApplication object after CoInitializeEx()?

newb
11th June 2010, 11:08
Thank you

now i don get this error

but in my console it shows like Qt: Could not initialize OLE (error 80010106)

Any help

high_flyer
11th June 2010, 11:22
Which libs do you link to in your project?
EDIT:
I see now, at the top.
Try delay loading wbemuuid.dll.

newb
11th June 2010, 12:43
Thnaks for the reply..

i get the vid and pid of the usb devices plugged into my system using WMI.

Now i want to get the drive letter corresponding to the device vid and pid i retrievd.

code

hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT * FROM Win32_USBControllerDevice"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);

if (FAILED(pclsObj->Get(L"Dependent", 0, &vtProp, 0, 0)))
{
cout<<"The specified property is not found."<<endl;

}
else
{
wcout <<vtProp.bstrVal << endl;

}

i get like below

\NJ96\root\cimv2:Win32_PnPEntity.DeviceID="USB\VID_1A8D&PID_1000\35809402 0874450"

how can i map DRIVE LETTER to my above output using the WMI

please help me out

high_flyer
11th June 2010, 13:10
This is not a Qt question, and I am not really familiar with WMI.
You might get more help with this issue in forums dedicated to WMI development.

newb
11th June 2010, 13:52
Can any body help me out

chesterx
2nd February 2011, 22:15
Hi.
Using WMI and WMI Query Language is not an easy thing, but if you read carefully and look at the examples on MSDN I'm sure you'll get the picture, for I also use WMI to get PIDs and VIDs for plugged devices.
http://msdn.microsoft.com/en-us/library/aa389276(v=VS.85).aspx

But , about the CoInitializeEx , I had the very same problem as you... CoInitializeEx is not returning S_OK.. But's that an OK thing, according to MSDN :)
As long as CoInitializeEx doesn't return RPC_E_CHANGED_MODE you should be ok, and you should call CoUninitialize in both cases where CoInitializeEx return S_OK or S_FALSE

Now, the issue with the QApplication object, that I also ran into, is that somewhere very deep in the initialization of an QApp object a call to CoInitialize is being made with parameters that we can't control.. I know that coz I used an API spy that tell me wich api calls a process is making.

The problem with CoInitialize is that is the same as CoInitializeEx(0, COINIT_APARTMENTTHREADED) and a later call (after the QApplication's instantiation) fails if we try CoInitializeEx(0, COINIT_APARTMENTTHREADED) with a RPC_E_CHANGED_MODE error.

So it's ok if you call CoInitializeEx(0, COINIT_APARTMENTTHREADED) with a S_FALSE returned.. and then even with an S_FALSE returned you should call CoUninitialize;

I know that QAxBase calls CoInitializeEx but, does anybody out there know why CoInitialize is called by the QApplication's constructor?

Tks

Hernan

Added after 6 minutes:

Lol, I just found the villain myself looking for the Could not initialize OLE string within the Qt source
Lines 754-758 on qapplication_win.cpp... OleInitialize() is called but then we are stuck with a Single-Threaded model for using COM.. that's bad news.
If one reads the remarks on http://msdn.microsoft.com/en-us/library/ms690134(v=vs.85).aspx one can guess that OleInitialize is called for Drag'n'Drop to work.