使用开源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;
}
相关推荐
GoCoding5 小时前
开源好物 26/03
开源
Predestination王瀞潞11 小时前
4.3.1 存储->微软文件系统标准(微软,自有技术标准):exFAT(Extended File Allocation Table)扩展文件分配表系统
linux·运维·microsoft·exfat·ex4
Imagination官方博客12 小时前
PowerVR:推动开源 Zink 与 OpenGL ES 支持的发展路径
开源
视***间12 小时前
2026:AI算力元年的加冕与思辨
人工智能·microsoft·机器人·边缘计算·智能硬件·视程空间
Predestination王瀞潞13 小时前
4.3.3 存储->微软文件系统标准(微软,自有技术标准):VFAT(Virtual File Allocation Table)虚拟文件分配表系统
linux·microsoft·vfat
F_U_N_13 小时前
轻量化开源知识库落地路径研究:AI赋能、多端集成及合规管理指引
人工智能·开源
AI成长日志13 小时前
【datawhale】hello agents开源课程学习记录第4章:智能体经典范式构建
学习·开源
大雷神13 小时前
HarmonyOS APP<玩转React>开源教程十五:首页完整实现
react.js·开源·harmonyos
wAIxiSeu15 小时前
开源项目分享——CLI-Anything
开源·github
进击monkey15 小时前
2026 年 AI Wiki 推荐:PandaWiki——AI 原生+开源私有化,企业级知识库最优解
人工智能·开源·ai知识库