首先关于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的机器,呵呵。