日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

WMI技术介绍和应用——VC开发WMI应用的基本步骤

發(fā)布時(shí)間:2023/11/27 生活经验 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WMI技术介绍和应用——VC开发WMI应用的基本步骤 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

? ? ? ? 在《WMI技術(shù)介紹和應(yīng)用——WMI概述》中介紹了我們可以使用C++、.net或者支持ActiveX技術(shù)的腳本語(yǔ)言來(lái)使用WMI。但是各種語(yǔ)言對(duì)WMI的控制能力是不同的,比如腳本語(yǔ)言只能用來(lái)從WMI獲取數(shù)據(jù)或者接收事件通知。而C++還可以編寫WMI提供者和發(fā)送消息。和腳本語(yǔ)言相比,C++對(duì)WMI有強(qiáng)大的控制和定制性,當(dāng)然也具有更大的復(fù)雜性。本文將主要講述使用VC如何搭建一個(gè)使用WMI的框架。(轉(zhuǎn)載請(qǐng)指明出于breaksoftware的csdn博客)

? ? ? ? 為了方便使用,我將該搭建步驟封轉(zhuǎn)到了一個(gè)類中

class CWMI
{
public:CWMI();~CWMI(void);
public:HRESULT ExcuteFun();
protected:VOID SetNamespace(wstring wstrNamespace);
private:HRESULT InitialCom();HRESULT SetComSecLevels();HRESULT ObtainLocator2WMI(CComPtr<IWbemLocator>& pLoc);HRESULT Connect2WMI(CComPtr<IWbemLocator> pLoc,CComPtr<IWbemServices>& pSvc);HRESULT SetProxySecLevels(CComPtr<IWbemServices> pSvc);virtual HRESULT Excute(CComPtr<IWbemServices> pSvc) = 0;
private:wstring m_wstrNamespace;
};

? ? ? ? SetNamespace用于設(shè)置命名空間。在《WMI技術(shù)介紹和應(yīng)用——WMI概述》中我們提到,WMI中存在諸如root\default、root\cimv2等WMI命令空間。因?yàn)槲覀円褂玫腤MI功能和命名空間有很大的關(guān)聯(lián),所以該類將提供這個(gè)設(shè)置命令空間的函數(shù)。

VOID CWMI::SetNamespace(wstring wstrNamespace)
{m_wstrNamespace = wstrNamespace;
}

? ? ? ? 剩下的函數(shù)就承載著了使用WMI步驟的邏輯和流程。

? ? ? ? 初始化COM庫(kù)

? ? ? ? 我們還要將之前的WMI框架圖列出來(lái)

? ? ? ? WMI是基于COM技術(shù)的。在WMI Consumers層,我們發(fā)現(xiàn),C++程序是直接和WMI COM API進(jìn)行交互。所以我們要先初始化COM組件庫(kù)。

HRESULT CWMI::InitialCom()
{HRESULT hr = E_FAIL;do {hr = CoInitializeEx(0, COINIT_MULTITHREADED);CHECKHR(hr);} while (0);return hr;
}

? ? ? ? 設(shè)置進(jìn)程COM安全信息

? ? ? ? 因?yàn)閃MI是基于COM技術(shù)的,所以我們可以使用CoInitializeSecurity設(shè)置我們應(yīng)用的認(rèn)證信息和扮演等級(jí)(Impersonation Levels)。如果我們不調(diào)用該函數(shù),COM將通過(guò)讀取注冊(cè)表中的相關(guān)鍵值去決定我們應(yīng)用的認(rèn)證信息和扮演等級(jí)。然而,往往注冊(cè)表中記錄的認(rèn)證信息和扮演等級(jí)是非常低的。一般來(lái)說(shuō),注冊(cè)表記錄的扮演等級(jí)是RPC_C_IMP_LEVEL_IDENTIFY,而絕大部分WMI提供者至少需要RPC_C_IMP_LEVEL_IMPERSONATE等級(jí)。對(duì)于認(rèn)證信息,在特殊場(chǎng)景下,我們可能需要用其他用戶身份去使用COM。但是目前,我在管理員權(quán)限下運(yùn)行程序,權(quán)限基本上是夠得,所以設(shè)置也很簡(jiǎn)單。

HRESULT CWMI::SetComSecLevels()
{// Set general COM security levels --------------------------// Note: If you are using Windows 2000, you must specify -// the default authentication credentials for a user by using// a SOLE_AUTHENTICATION_LIST structure in the pAuthList ----// parameter of CoInitializeSecurity ------------------------HRESULT hr = E_FAIL;do {hr = CoInitializeSecurity(NULL, -1,                          // COM negotiates serviceNULL,                        // Authentication servicesNULL,                        // ReservedRPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  NULL,                        // Authentication infoEOAC_NONE,                   // Additional capabilities NULL                         // Reserved);CHECKHR(hr);} while (0);return hr;
}

? ? ? ? 創(chuàng)建進(jìn)程內(nèi)COM服務(wù)器

? ? ? ? 我們應(yīng)用中使用WMI完成相關(guān)功能,比如查詢硬盤ID,實(shí)際執(zhí)行查詢的操作是在WMI服務(wù)中執(zhí)行的,而不是我們的應(yīng)用。比如,在XP上,svchost.exe服務(wù)是WMI服務(wù)的載體。我們應(yīng)用通過(guò)COM告訴svchost.exe我們的請(qǐng)求,svchost.exe將我們請(qǐng)求執(zhí)行后,會(huì)將結(jié)果通過(guò)COM傳遞給我們的應(yīng)用。這樣就要求我們應(yīng)用和WMI服務(wù)進(jìn)程有通信。在我們應(yīng)用這邊,就需要?jiǎng)?chuàng)建一個(gè)進(jìn)程內(nèi)COM服務(wù)器用于接發(fā)數(shù)據(jù)。

HRESULT CWMI::ObtainLocator2WMI(CComPtr<IWbemLocator>& pLoc)
{HRESULT hr = E_FAIL;do {hr = CoCreateInstance(CLSID_WbemLocator,             0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);CHECKHR(hr);} while (0);return hr;
}

? ? ? ? 連接WMI命名空間

? ? ? ? 這步是使用WMI的關(guān)鍵一步。我們使用上一步創(chuàng)建的IWbemLocator實(shí)例的ConnectServer函數(shù)連接本地或者遠(yuǎn)程的WMI命名空間。我們看一下函數(shù)聲明

HRESULT ConnectServer([in]   const BSTR strNetworkResource,[in]   const BSTR strUser,[in]   const BSTR strPassword,[in]   const BSTR strLocale,[in]   LONG lSecurityFlags,[in]   const BSTR strAuthority,[in]   IWbemContext *pCtx,[out]  IWbemServices **ppNamespace
);

? ? ? ? 第一個(gè)參數(shù)strNetworkResource是命名空間的名字,比如"root\default"或者"\\.\root\default"。第二三個(gè)是用戶名和密碼,如果是遠(yuǎn)程計(jì)算機(jī),則這兩個(gè)參數(shù)非常有用。最后一個(gè)參數(shù)返回了IWbemServices結(jié)構(gòu)的代理。我們可以通過(guò)該代理訪問(wèn)WMI服務(wù)。

HRESULT CWMI::Connect2WMI( CComPtr<IWbemLocator> pLoc,CComPtr<IWbemServices>& pSvc )
{HRESULT hr = E_FAIL;do {hr = pLoc->ConnectServer(CComBSTR(m_wstrNamespace.c_str()), NULL, NULL, NULL, NULL, NULL, NULL, &pSvc );CHECKHR(hr);} while (0);return hr;
}

? ? ? ? 設(shè)置WMI連接的安全等級(jí)

? ? ? ? 一般來(lái)說(shuō),如果沒(méi)有設(shè)置正確的安全屬性,COM是不允許一個(gè)進(jìn)程去訪問(wèn)另一個(gè)進(jìn)程的中的對(duì)象。我們上步獲得的IWbemServices接口代理就需要訪問(wèn)WMI服務(wù)進(jìn)程中的對(duì)象,所以我們要對(duì)該代理設(shè)置安全等級(jí)。

HRESULT CWMI::SetProxySecLevels( CComPtr<IWbemServices> pSvc )
{HRESULT hr = E_FAIL;do {hr = CoSetProxyBlanket(pSvc,                        // Indicates the proxy to setRPC_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_xxxNULL,                        // client identityEOAC_NONE                    // proxy capabilities );CHECKHR(hr);} while (0);return hr;
}

? ? ? ? 發(fā)起WMI請(qǐng)求

? ? ? ? 通過(guò)以上一系列過(guò)程,我們終于可以開始使用WMI了。在我定義的類中,我將該步驟封裝成一個(gè)純虛函數(shù)Excute,繼承CWMI的類將實(shí)現(xiàn)具體的工作。

? ? ? ? 清理?
? ? ? ? 我們?cè)谑褂猛暌陨系拇砗蛯?shí)例后,我們要釋放它們,并且最后要釋放COM庫(kù)。

CWMI::~CWMI(void)
{CoUninitialize();
}

? ? ? ? 總體來(lái)說(shuō)執(zhí)行的流程用代碼可以描述為

HRESULT CWMI::ExcuteFun()
{HRESULT hr = E_FAIL;CComPtr<IWbemLocator> pLoc = NULL;CComPtr<IWbemServices> pSvc = NULL;do {hr = InitialCom();CHECKHR(hr);hr = SetComSecLevels();CHECKHR(hr);hr = ObtainLocator2WMI(pLoc);CHECKHR(hr);hr = Connect2WMI(pLoc, pSvc);CHECKHR(hr);hr = SetProxySecLevels(pSvc);CHECKHR(hr);hr = Excute(pSvc);CHECKHR(hr);} while (0);return hr;
}

? ? ? ? 下一節(jié),我將講解一個(gè)簡(jiǎn)單的對(duì)CWMI的封裝類。

? ? ? ? 工程源碼見(jiàn)《WMI技術(shù)介紹和應(yīng)用——WMI概述》結(jié)尾。

總結(jié)

以上是生活随笔為你收集整理的WMI技术介绍和应用——VC开发WMI应用的基本步骤的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。