如下代码是使用国产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 negotiation
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)) {
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;
}