VC WMI應用獲取SMBios中的信息

 

首先關於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的機器,呵呵。

 

 

 

發佈了47 篇原創文章 · 獲贊 44 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章