首先關於WMI 的基本使用
請參考:http://blog.csdn.net/breaksoftware/article/details/8439975
在那裏你可以找到系列連貫的文章,筆者寫的很好很細膩,就是代碼缺少了微量細節,其實這樣也好,讓你動動腦,杜絕“拿來主義”。
參考他的文章http://blog.csdn.net/breaksoftware/article/details/8821025,我們可以獲取到很多常用信息
但有時我們需要獲取SMBios中的一些OEM字段信息,而文章中並沒有提到。
比如一個公司的PC有多個子品牌,對於他們的區分通常會存在SMBios中的OEM數據段的標誌位裏,如何獲取這些信息呢?
於是我又爲代碼增加了幾個函數:
HRESULT CWMI::GetSMBiosDataBlock()
{
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 = ExcuteGetData(pSvc);
CHECKHR(hr);
} while (0);
return hr;
}
HRESULT CSynQuery::ExcuteGetData(CComPtr<IWbemServices> pSvc)
{
HRESULT hr = WBEM_S_FALSE;
do
{
CComPtr<IEnumWbemClassObject> pEnumerator = NULL;
hr = pSvc->CreateInstanceEnum(L"MSSMBios_RawSMBiosTables",
0,
NULL,
&pEnumerator);
CHECKWMIHR(hr);
ULONG uReturn = 0;
while (pEnumerator) {
CComPtr<IWbemClassObject> pclsObj = NULL;
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if ( 0 == uReturn) {
break;
}
DealWithIWbemClassObject_GetBiosData(pclsObj);
}
} while (0);
return hr;
}
HRESULT CSynQuery::DealWithIWbemClassObject_GetBiosData( CComPtr<IWbemClassObject> pclsObj )
{
HRESULT hr = WBEM_S_NO_ERROR;
VARIANT data;
CIMTYPE type;
VariantInit(&data);
do {
hr = pclsObj->Get(bstr_t("SmbiosMajorVersion"), 0, &data, &type, NULL);
CHECKWMIHR(hr);
m_EPS.SMBIOSMajorVersion = data.bVal;
hr = pclsObj->Get(bstr_t("SmbiosMinorVersion"), 0, &data, &type, NULL);
CHECKWMIHR(hr);
m_EPS.SMBIOSMinorVersion = data.bVal;
hr = pclsObj->Get(bstr_t("SMBiosData"), 0, &data, &type, NULL);
CHECKWMIHR(hr);
UCHAR HUGEP *u_TempHugep;
m_EPS.SmbiosData = data.parray;
m_EPS.Length = m_EPS.SmbiosData->rgsabound[0].cElements;
SafeArrayAccessData(data.parray, (void HUGEP *FAR *)&u_TempHugep);
for(UINT i=0; i < m_EPS.Length; i++)
{
m_BiosDataBlock[i] = u_TempHugep[i];
}
SafeArrayUnaccessData(data.parray);
VariantClear(&data);
} while (0);
if(SUCCEEDED(hr))
PrintfBiosDataBlock();
return hr;
}
VOID CSynQuery::PrintfBiosDataBlock()
{
int i = 0;
wprintf(L"---------SMBios data block---------\n---------Data Length %d---------\n---------Version:%d.%d---------\n",
m_EPS.Length,m_EPS.SMBIOSMajorVersion,m_EPS.SMBIOSMinorVersion);
system("pause");
for (i = 0; i < m_EPS.Length; i ++)
{
//8列
if(i% 8 == 0)
wprintf(L"\n");
if((47 < m_BiosDataBlock[i] && m_BiosDataBlock[i] < 58) ||
(64 < m_BiosDataBlock[i] && m_BiosDataBlock[i] < 91) ||
(96 < m_BiosDataBlock[i] && m_BiosDataBlock[i] < 123))
wprintf(L"%c", m_BiosDataBlock[i]);
else
wprintf(L"0x%0.2X", m_BiosDataBlock[i]);
wprintf(L"\t");
}
wprintf(L"\n");
}
CSynQueryData的函數被我移到CSynQuery中。
typedef struct StructEPS
{
UCHAR SMBIOSMajorVersion;
UCHAR SMBIOSMinorVersion;
UINT Length;
SAFEARRAY *SmbiosData;
}EPS;
使用時的區別
void GetBaseboardInfo()
{
CSynQuery tSynQuery(L"ROOT\\CIMV2",L"SELECT * FROM Win32_BaseBoard");
tSynQuery.ExcuteFun();
}
void GetSMBiosDataBlock()
{
CSynQuery tSynQuery(L"ROOT\\WMI",L"");
tSynQuery.GetSMBiosDataBlock();
}
可以看出我用的是DELL的機器,呵呵。