使用开源GCC编译微软WMI相关函数的示例代码

如下代码是使用国产RedPanda-Cpp的编译工具编译的,该工具使用简单;

该方式是调用微软的WMI接口相关函数

但是使用GCC编译会出现编译不过的问题,很多代码库的函数都不存在;

在编译时,需要添加这些库文件:

即使添加了,但是comutil.h文件里面的缺少对应的函数(例如:ConvertStringToBSTR),但GCC里面没有对应的库文件,于是使用修改了GCC里面的comutil.h的头文件,代码内容(改代码来自于reactos源码comsup.c)如下:

cpp 复制代码
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是否激活的代码

cpp 复制代码
#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;
}
相关推荐
洋仔20 分钟前
Git 底层原理系列 · 第8讲 — HEAD 与 detached HEAD
git·开源
洋仔21 分钟前
Git 底层原理系列 · 第4讲 — `git add` 与 `git commit` 底层做了什么
git·开源
Terrence Shen1 小时前
demo111
microsoft
心中有国也有家2 小时前
从零上手 CANN 学习中心:像逛技术便利店一样学昇腾
学习·算法·开源
互联圈运营观察3 小时前
布局先行、技术深耕:国内端侧AI企业抢滩机器人与具身智能赛道
人工智能·microsoft·机器人
openFuyao3 小时前
以开源之力,突破多样化算力困局——openFuyao开源一周年背后的故事
人工智能·云原生·开源·openfuyao·多样化算力·集群软件
500844 小时前
ATC 做了什么:从 ONNX 到 .om
分布式·架构·开源·wpf·开源鸿蒙
fuquxiaoguang4 小时前
微软Maia 200的“算力经济学”:推理时代的专用芯片如何改写游戏规则
人工智能·microsoft
糖果店的幽灵5 小时前
Part 2: Models(模型)
microsoft·langchain