使用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

 

改进后的代码仍存在不能获取到主板序列号的可能性问题,目前没找到较好的解决办法。

转载于:https://www.cnblogs.com/annie-fun/p/6409542.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值