如下代码是使用国产RedPanda-Cpp的编译工具编译的,该工具使用简单;
该方式是调用微软的WMI接口相关函数
但是使用GCC编译会出现编译不过的问题,很多代码库的函数都不存在;
在编译时,需要添加这些库文件:
即使添加了,但是comutil.h文件里面的缺少对应的函数(例如:ConvertStringToBSTR),但GCC里面没有对应的库文件,于是使用修改了GCC里面的comutil.h的头文件,代码内容(改代码来自于reactos源码comsup.c)如下:
namespace _com_util {BSTR WINAPI ConvertStringToBSTR(const char *pSrc);char *WINAPI ConvertBSTRToString(BSTR pSrc);BSTR WINAPI ConvertStringToBSTR(const char *pSrc){DWORD cwch;BSTR wsOut(NULL);if (!pSrc) return NULL;/* Compute the needed size with the NULL terminator */cwch = ::MultiByteToWideChar(CP_ACP, 0, pSrc, -1, NULL, 0);if (cwch == 0) return NULL;/* Allocate the BSTR (without the NULL terminator) */wsOut = ::SysAllocStringLen(NULL, cwch - 1);if (!wsOut){::_com_issue_error(HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY));return NULL;}/* Convert the string */if (::MultiByteToWideChar(CP_ACP, 0, pSrc, -1, wsOut, cwch) == 0){/* We failed, clean everything up */cwch = ::GetLastError();::SysFreeString(wsOut);wsOut = NULL;::_com_issue_error(!IS_ERROR(cwch) ? HRESULT_FROM_WIN32(cwch) : cwch);}return wsOut;}char* WINAPI ConvertBSTRToString(BSTR pSrc){DWORD cb, cwch;char *szOut = NULL;if (!pSrc) return NULL;/* Retrieve the size of the BSTR with the NULL terminator */cwch = ::SysStringLen(pSrc) + 1;/* Compute the needed size with the NULL terminator */cb = ::WideCharToMultiByte(CP_ACP, 0, pSrc, cwch, NULL, 0, NULL, NULL);if (cb == 0){cwch = ::GetLastError();::_com_issue_error(!IS_ERROR(cwch) ? HRESULT_FROM_WIN32(cwch) : cwch);return NULL;}/* Allocate the string */szOut = (char*)::operator new(cb * sizeof(char));if (!szOut){::_com_issue_error(HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY));return NULL;}/* Convert the string and NULL-terminate */szOut[cb - 1] = '\0';if (::WideCharToMultiByte(CP_ACP, 0, pSrc, cwch, szOut, cb, NULL, NULL) == 0){/* We failed, clean everything up */cwch = ::GetLastError();::operator delete(szOut);szOut = NULL;::_com_issue_error(!IS_ERROR(cwch) ? HRESULT_FROM_WIN32(cwch) : cwch);}return szOut;}
}
例如下面的代码是用来检查微软的OS是否激活的代码
#include <stdio.h>
#include <windows.h>
#include <Wbemidl.h>
#include <comutil.h>void CheckActivationStatus() {HRESULT hres;// 初始化COM库hres = CoInitializeEx(0, COINIT_MULTITHREADED);if (FAILED(hres)) {printf("Failed to initialize COM library. Error code = 0x%X\n", (unsigned int)hres);return;}// 初始化安全性hres = CoInitializeSecurity(NULL,-1, // COM negotiationNULL, // Authentication servicesNULL, // ReservedRPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation NULL, // Authentication infoEOAC_NONE, // Additional capabilities NULL // Reserved);if (FAILED(hres)) {printf("Failed to initialize security. Error code = 0x%X\n", (unsigned int)hres);CoUninitialize();return;}IWbemLocator *pLoc = NULL;// 获取IWbemLocator指针hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&pLoc);if (FAILED(hres)) {printf("Failed to create IWbemLocator object. Err code = 0x%X\n", (unsigned int)hres);CoUninitialize();return;}IWbemServices *pSvc = NULL;// 连接到WMI命名空间hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), // WMI命名空间NULL, // 用户名称NULL, // 用户密码0, // 本地安全0, // 安全标志0, // 权威0, // 上下文对象 &pSvc // IWbemServices代理);if (FAILED(hres)) {printf("Could not connect. Error code = 0x%X\n", (unsigned int)hres);pLoc->Release(); CoUninitialize();return;}// 设置代理安全级别hres = CoSetProxyBlanket(pSvc, // 设置代理RPC_C_AUTHN_WINNT, // NTLM认证RPC_C_AUTHZ_NONE, // 无授权NULL, // 服务器主体名称 RPC_C_AUTHN_LEVEL_CALL, // 调用认证级别RPC_C_IMP_LEVEL_IMPERSONATE, // 仿冒级别NULL, // 认证服务EOAC_NONE // 额外的能力 );if (FAILED(hres)) {printf("Could not set proxy blanket. Error code = 0x%X\n", (unsigned int)hres);pSvc->Release();pLoc->Release(); CoUninitialize();return;}IEnumWbemClassObject* pEnumerator = NULL;hres = pSvc->ExecQuery(bstr_t("WQL"), bstr_t("SELECT * FROM SoftwareLicensingProduct WHERE ApplicationId='55c92734-d682-4d71-983e-d6ec3f16059f' AND PartialProductKey IS NOT NULL"),WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL,&pEnumerator);if (FAILED(hres)) {printf("Query for products failed. Error code = 0x%X\n", (unsigned int)hres);pSvc->Release();pLoc->Release(); CoUninitialize();return;}IWbemClassObject *pclsObj = NULL;ULONG uReturn = 0;while (pEnumerator) {HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);if (SUCCEEDED(hr)) { if (0 == uReturn) {break;}VARIANT vtProp;hr = pclsObj->Get(L"LicenseStatus", 0, &vtProp, 0, 0);wprintf(L"LicenseStatus : %d\n", vtProp.iVal);VariantClear(&vtProp);pclsObj->Release();}}// 清理pSvc->Release();pLoc->Release();pEnumerator->Release();CoUninitialize();
}int main() {CheckActivationStatus();return 0;
}