Skip to content

Instantly share code, notes, and snippets.

@leoschmitz
Last active August 23, 2018 16:46
Show Gist options
  • Save leoschmitz/b2638e8ea989b848af22bdb3a641aefd to your computer and use it in GitHub Desktop.
Save leoschmitz/b2638e8ea989b848af22bdb3a641aefd to your computer and use it in GitHub Desktop.
wmi checks
#pragma hdrstop
#include <iostream>
using namespace std;
#include <wbemcli.h>
#include <comdef.h>
#pragma argsused
#ifdef _WIN32
#include <tchar.h>
#else
typedef char _TCHAR;
#define _tmain main
#endif
#include <vector>
#include <sstream>
#include <stdio.h>
std::vector<std::wstring> queryWMI(const wchar_t* query, wchar_t* element, IWbemServices* pSvc)
{
HRESULT hres;
std::vector<std::wstring> attributes;
wchar_t wquery[1024];
wcsncpy(wquery, query, 1024);
// Use the IWbemServices pointer to make requests of WMI
IEnumWbemClassObject* pEnumerator = NULL;
hres = pSvc->ExecQuery( L"WQL", wquery,
//hres = pSvc->ExecQuery(L"WQL", L"ASSOCIATORS OF {Win32_DiskPartition.DeviceID=\"Disk #1, Partition #1\"} WHERE AssocClass = Win32_LogicalDiskToPartition",
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
if (FAILED(hres)){
cout << "ExecQuery failed" << " Error code = 0x" << hex << hres << endl;
cout << _com_error(hres).ErrorMessage() << endl;
pSvc->Release();
return std::vector<std::wstring>();
}
// Get the data from the WQL sentence
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
while (pEnumerator) {
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (uReturn == 0 || FAILED(hr)) {
break;
}
VARIANT vtProp;
hr = pclsObj->Get(element, 0, &vtProp, 0, 0);// String
if (!FAILED(hr)) {
if ((vtProp.vt==VT_NULL) || (vtProp.vt==VT_EMPTY)){
wcout << element << ": " << ((vtProp.vt==VT_NULL) ? "NULL" : "EMPTY") << endl;
}
else if ((vtProp.vt & VT_ARRAY)) {
wcout << element << ": " << "Array types not supported (yet)" << endl;
}
else {
attributes.push_back(vtProp.bstrVal);
wcout << element << ": " << vtProp.bstrVal << endl;
}
}
VariantClear(&vtProp);
pclsObj->Release();
pclsObj=NULL;
}
pEnumerator->Release();
if (pclsObj != NULL){
pclsObj->Release();
}
return attributes;
}
std::wstring findHDSerial(const wchar_t* partition){
BSTR strNetworkResource;
strNetworkResource = L"\\\\.\\root\\CIMV2";
// Initialize COM
HRESULT hres;
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres)) {
return std::wstring();
}
// 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)) {
CoUninitialize();
return std::wstring();
}
// Obtain the initial locator to WMI
IWbemLocator *pLoc = NULL;
hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *) &pLoc);
if (FAILED(hres)){
CoUninitialize();
return std::wstring();
}
// Connect to WMI through the IWbemLocator::ConnectServer method
IWbemServices *pSvc = NULL;
hres = pLoc->ConnectServer(
strNetworkResource, // 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)){
pLoc->Release();
CoUninitialize();
return std::wstring();
}
// Connected to root\\CIMV2 WMI namespace
// 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)){
pLoc->Release();
CoUninitialize();
return std::wstring();
}
std::wstring serial;
std::vector<std::wstring> devices = queryWMI(
L"SELECT * FROM Win32_DiskPartition", L"DeviceID", pSvc);
std::wstringstream query;
for (int i = 0; i < devices.size(); i++) {
query
<< L"ASSOCIATORS OF {Win32_DiskPartition.DeviceID=\""
<< devices[i]
<< L"\"} WHERE AssocClass = Win32_LogicalDiskToPartition";
std::vector<std::wstring> ids = queryWMI(
query.str().c_str(), L"DeviceID", pSvc);
query.str(std::wstring());
if (ids.size() <= 0 || wcscmp(ids[0].c_str(), partition) != 0){
continue;
}
query
<< L"ASSOCIATORS OF {Win32_DiskPartition.DeviceID=\""
<< devices[i]
<< L"\"} WHERE AssocClass = Win32_DiskDriveToDiskPartition";
std::vector<std::wstring> serials = queryWMI(
query.str().c_str(), L"SerialNumber", pSvc);
if (serials.size() <= 0){
return std::wstring();
}
serial = serials[0].c_str();
break;
}
// Cleanup
pSvc->Release();
pLoc->Release();
CoUninitialize();
cout << "press enter to exit" << endl;
cin.get();
return serial;
}
int _tmain(int argc, _TCHAR* argv[])
{
findHDSerial(L"C:");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment