使用WMI編程獲取主機硬件信息(續)


在之前的隨筆http://www.cnblogs.com/annie-fun/p/6393149.html中,存在一些問題。本篇隨筆是為了糾正之前隨筆中的問題而寫的。

代碼改進之處有兩點:
第一、某一次WMI查詢失敗后,繼續執行查詢下一個字段,而不是直接返回;

第二、采用GetAdaptersInfo()函數查詢有線物理網卡的mac地址。

話不多說,直接看代碼~.~
頭文件UserInfo.h:

 1 #pragma once 
 2 #include "stdafx.h"
 3 #define _WIN32_DCOM
 4 #include <comdef.h>
 5 #include <Wbemidl.h>
 6 # pragma comment(lib, "wbemuuid.lib")
 7 #include <iphlpapi.h>
 8 #pragma comment(lib, "IPHLPAPI.lib")
 9 #include <stdio.h>
10 #include <windows.h>
11 using namespace std;
12 
13 typedef struct UserInfo_t
14 {
15     char CpuID[20];                    //CPU序列號
16     char BaseBoardID[256];         //主板ID
17     char SystemDiskID[256];        //系統所在硬盤的序列號
18     char BIOSID[20];                   //BIOS序列號
19     char MacAddress[20];            //MAC地址
20 }UserInfo;
21 
22 int GetUserInfo(UserInfo &info);
View Code

源代碼GetUerInfo.cpp:

  1 #include "UserInfo.h"
  2 
  3 void Trims(char* data)           //去掉字符串中的空格
  4 {
  5     int i=-1,j=0;
  6     int ch = ' ';
  7 
  8     while(data[++i] != '\0')
  9     {
 10         if(data[i] != ch)
 11         {
 12             data[j++] = data[i];
 13         }
 14     }
 15     data[j] = '\0';
 16 }
 17 
 18 int GetUserInfo(UserInfo &info)
 19 {
 20     HRESULT hres;
 21     memset(&info,0x00,sizeof(UserInfo));
 22     
 23     CoUninitialize();
 24     hres =  CoInitializeEx(0, COINIT_MULTITHREADED);   //第二個參數設置當前線程的並發模式為多線程
 25     //hres =  CoInitializeEx(0,COINIT_APARTMENTTHREADED);  //並發模式為單線程(即只能在單線程函數中調用GetUserInfo())
 26     if (FAILED(hres))
 27     {
 28         return -1;                  
 29     }
 30     hres =  CoInitializeSecurity(
 31         NULL, 
 32         -1,                          
 33         NULL,                        
 34         NULL,                        
 35         RPC_C_AUTHN_LEVEL_DEFAULT,   
 36         RPC_C_IMP_LEVEL_IMPERSONATE, 
 37         NULL,                        
 38         EOAC_NONE,                   
 39         NULL                         
 40         );
 41     if (FAILED(hres))
 42     {
 43         CoUninitialize();
 44         return -2;                 
 45     }
 46     IWbemLocator *pLoc = NULL;
 47     hres = CoCreateInstance(
 48         CLSID_WbemLocator,             
 49         0, 
 50         CLSCTX_INPROC_SERVER, 
 51         IID_IWbemLocator, (LPVOID *) &pLoc);
 52     if (FAILED(hres))
 53     {
 54         CoUninitialize();
 55         return -3;    
 56     }
 57     IWbemServices *pSvc = NULL;
 58     hres = pLoc->ConnectServer(
 59         _bstr_t(L"ROOT\\CIMV2"), 
 60         NULL,                    
 61         NULL,                    
 62         0,                       
 63         NULL,                    
 64         0,                       
 65         0,                       
 66         &pSvc                    
 67         );
 68     if (FAILED(hres))
 69     {
 70         pLoc->Release();     
 71         CoUninitialize();
 72         return -4;                
 73     }
 74     hres = CoSetProxyBlanket(
 75         pSvc,                       
 76         RPC_C_AUTHN_WINNT,           
 77         RPC_C_AUTHZ_NONE,            
 78         NULL,                            
 79         RPC_C_AUTHN_LEVEL_CALL,      
 80         RPC_C_IMP_LEVEL_IMPERSONATE, 
 81         NULL,                        
 82         EOAC_NONE                    
 83         );
 84     if (FAILED(hres))
 85     {
 86         pSvc->Release();
 87         pLoc->Release();     
 88         CoUninitialize();
 89         return -5;              
 90     }
 91     
 92     IEnumWbemClassObject* pEnumerator = NULL;
 93     IWbemClassObject *pclsObj;
 94     ULONG uReturn = 0;
 95     //獲取CPUID
 96     hres = pSvc->ExecQuery(
 97         bstr_t("WQL"), 
 98         bstr_t("SELECT * FROM win32_Processor"),
 99         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
100         NULL,
101         &pEnumerator);
102     if ( !FAILED(hres))
103     {
104         while (pEnumerator)
105         {
106             HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
107             if(0 == uReturn)
108             {
109                 break;
110             }
111             VARIANT vtProp;
112             hr = pclsObj->Get(L"ProcessorId", 0, &vtProp, 0, 0);  
113             wcstombs(info.CpuID,vtProp.bstrVal,20);
114             VariantClear(&vtProp);
115             pclsObj->Release();
116         }
117     }
118     
119     //獲取主板序列號---在某些電腦上獲取不到,則UserInfo結構體中該字段為空
120     pEnumerator->Release();
121     pEnumerator=NULL;
122     hres = pSvc->ExecQuery(
123         bstr_t("WQL"),
124         bstr_t("SELECT * FROM Win32_BaseBoard"),   
125         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
126         NULL,
127         &pEnumerator);
128     if (!FAILED(hres))
129     {
130         while (pEnumerator)
131         {
132             HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
133             if(0 == uReturn)
134             {
135                 break;
136             }
137             VARIANT vtProp;
138             hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);   
139             wcstombs(info.BaseBoardID,vtProp.bstrVal,256);
140             VariantClear(&vtProp);
141             pclsObj->Release();    
142         }         
143     }
144 
145     //獲取系統所在硬盤的索引號
146     int diskIndex = 0;
147     pEnumerator->Release();
148     pEnumerator=NULL;
149     hres = pSvc->ExecQuery(
150         bstr_t("WQL"),
151         bstr_t("SELECT * FROM Win32_DiskPartition WHERE Bootable = TRUE"),     //查找啟動盤
152         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
153         NULL,
154         &pEnumerator);
155     if (!FAILED(hres))
156     {
157         while (pEnumerator)
158         {
159             HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
160             if(0 == uReturn)
161             {
162                 break;
163             }
164             VARIANT vtProp;
165             hr = pclsObj->Get(L"DiskIndex", 0, &vtProp, 0, 0); 
166             diskIndex = vtProp.intVal;
167             VariantClear(&vtProp);
168             pclsObj->Release();
169         } 
170 
171         //根據系統所在硬盤的索引號查詢硬盤序列號
172         char index[10];
173         string strQuery = "SELECT * FROM Win32_DiskDrive WHERE Index = ";
174         itoa(diskIndex,index,10);
175         string indexStr(index);
176         strQuery += indexStr;
177         pEnumerator->Release();
178         pEnumerator=NULL;
179         hres = pSvc->ExecQuery(
180             bstr_t("WQL"),
181             bstr_t(strQuery.c_str()),  
182             WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
183             NULL,
184             &pEnumerator);
185         if (!FAILED(hres))
186         {
187             while (pEnumerator)
188             {
189                 HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
190                 if(0 == uReturn)
191                 {
192                     break;
193                 }
194                 VARIANT vtProp;
195                 hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0); 
196                 wcstombs(info.SystemDiskID,vtProp.bstrVal,256);
197                 Trims(info.SystemDiskID);
198                 VariantClear(&vtProp);
199                 pclsObj->Release();
200             }          
201         }
202     }  
203 
204     //獲取BIOS序列號
205     pEnumerator->Release();
206     pEnumerator=NULL;
207     hres = pSvc->ExecQuery(
208         bstr_t("WQL"),
209         bstr_t("SELECT * FROM Win32_BIOS"),
210         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
211         NULL,
212         &pEnumerator);
213     if (!FAILED(hres))
214     {
215         while (pEnumerator)
216         {
217             HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
218             if(0 == uReturn)
219             {
220                 break;
221             }
222             VARIANT vtProp;
223             hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0); 
224             wcstombs(info.BIOSID,vtProp.bstrVal,20);
225             VariantClear(&vtProp);
226             pclsObj->Release();
227         }             
228     }
229     
230     //使用GetAdaptersInfo()函數獲得網卡信息,從而獲取本地連接的MAC地址
231     ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
232     PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));
233     if(pAdapterInfo == NULL)
234         return -1;
235     if(GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) 
236     {
237         free(pAdapterInfo);
238         pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
239         if (pAdapterInfo == NULL) 
240             return -2;
241     }
242     if(GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == NO_ERROR)
243     {
244         for(PIP_ADAPTER_INFO pAdapter = pAdapterInfo; pAdapter != NULL; pAdapter = pAdapter->Next)
245         {
246             // 如果不是有線物理網卡,直接跳過   
247             if(pAdapter->Type != MIB_IF_TYPE_ETHERNET || pAdapter->Type == 71 ||strstr(pAdapter->Description,"Bluetooth") >0 )
248                 continue;
249             if(pAdapter->AddressLength != 6)
250                 continue;
251             sprintf_s(info.MacAddress, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
252                 int (pAdapter->Address[0]),
253                 int (pAdapter->Address[1]),
254                 int (pAdapter->Address[2]),
255                 int (pAdapter->Address[3]),
256                 int (pAdapter->Address[4]),
257                 int (pAdapter->Address[5]));
258             break;
259         }
260     }
261     free(pAdapterInfo);
262 
263     pSvc->Release();
264     pLoc->Release();
265     pEnumerator->Release();
266     CoUninitialize();
267 
268     return 0;   
269 }
View Code

 

改進后的代碼仍存在不能獲取到主板序列號的可能性問題,目前沒找到較好的解決辦法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM