开发语言:C/C++

支持平台:Windows

实现功能:

  • 通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号

下载地址:

WMI_DeviceQuery.zip

版本历史:

V1.4 2010年05月17日

  • 修正了硬盘序列号处理中的错误。现在和EVEREST Ultimate Edition 5.5一致。

V1.3 2010年05月11日

  • 增加了对网卡原生MAC地址的查询。

V1.2 2010年05月05日

  • 增加对硬盘序列号的进一步处理。

V1.1 2010年04月30日

  • 修正微软MSDN例子错误,并增加对虚拟网卡的判断。

V1.0 2010年04月27日

  • 完成正式版本。

接口函数:

WMI_DeviceQuery

接口文件:WMI_DeviceQuery.h

/* ---------------------------------------------------------- 文件名称:WMI_DeviceQuery.h 作者:秦建辉 MSN:splashcn@msn.com 版本历史: V1.4 2010年05月17日 修正了硬盘序列号处理中的错误。现在和EVEREST Ultimate Edition 5.5一致。 V1.3 2010年05月11日 增加了对网卡原生MAC地址的查询。 V1.2 2010年05月05日 增加对硬盘序列号的进一步处理。 V1.1 2010年04月30日 修正微软MSDN例子错误,并增加对虚拟机网卡的判断。 V1.0 2010年04月27日 完成正式版本。 功能描述: 基于WMI获取设备属性: 0:网卡原生MAC地址 1:硬盘序列号 2:主板序列号 3:CPU ID 4:BIOS序列号 5:主板型号 6:网卡当前MAC地址 接口函数: WMI_DeviceQuery ------------------------------------------------------------ */ #pragma once #include <windows.h> #ifndef MACRO_T_DEVICE_PROPERTY #define MACRO_T_DEVICE_PROPERTY #define PROPERTY_MAX_LEN 128 // 属性字段最大长度 typedef struct _T_DEVICE_PROPERTY { TCHAR szProperty[PROPERTY_MAX_LEN]; } T_DEVICE_PROPERTY; #endif #define WMI_QUERY_TYPENUM 7 // WMI查询支持的类型数 #ifdef __cplusplus extern "C" { #endif /* 功能:通过WMI获取设备属性 参数说明: iQueryType:需要查询的设备属性 0:网卡原生MAC地址 1:硬盘序列号 2:主板序列号 3:CPU ID 4:BIOS序列号 5:主板型号 6:网卡当前MAC地址 properties:存储设备属性值 iSize:可存储的最大设备个数 返回值: -1:不支持的设备属性值 -2:WMI连接失败 -3:不正确的WQL查询语句 >=0:获取的设备个数 */ INT WMI_DeviceQuery( INT iQueryType, T_DEVICE_PROPERTY *properties, INT iSize ); #ifdef __cplusplus } #endif

实现文件:WMI_DeviceQuery.cpp

#include "WMI_DeviceQuery.h" #include <comutil.h> #include <Wbemidl.h> #include <tchar.h> #include <strsafe.h> #include <algorithm> #include <atlconv.h> #include <ntddndis.h> #pragma comment (lib, "comsuppw.lib") #pragma comment (lib, "wbemuuid.lib") typedef struct _T_WQL_QUERY { CHAR* szSelect; // SELECT语句 WCHAR* szProperty; // 属性字段 } T_WQL_QUERY; // WQL查询语句 const T_WQL_QUERY szWQLQuery[] = { // 网卡原生MAC地址 "SELECT * FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))", L"PNPDeviceID", // 硬盘序列号 "SELECT * FROM Win32_DiskDrive WHERE (SerialNumber IS NOT NULL) AND (MediaType LIKE 'Fixed hard disk%')", L"SerialNumber", // 主板序列号 "SELECT * FROM Win32_BaseBoard WHERE (SerialNumber IS NOT NULL)", L"SerialNumber", // 处理器ID "SELECT * FROM Win32_Processor WHERE (ProcessorId IS NOT NULL)", L"ProcessorId", // BIOS序列号 "SELECT * FROM Win32_BIOS WHERE (SerialNumber IS NOT NULL)", L"SerialNumber", // 主板型号 "SELECT * FROM Win32_BaseBoard WHERE (Product IS NOT NULL)", L"Product", // 网卡当前MAC地址 "SELECT * FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))", L"MACAddress", }; // 通过“PNPDeviceID”获取网卡原生MAC地址 static BOOL WMI_DoWithPNPDeviceID( const TCHAR *PNPDeviceID, TCHAR *MacAddress, UINT uSize ) { TCHAR DevicePath[MAX_PATH]; HANDLE hDeviceFile; BOOL isOK = FALSE; // 生成设备路径名 StringCchCopy( DevicePath, MAX_PATH, TEXT(".//") ); StringCchCat( DevicePath, MAX_PATH, PNPDeviceID ); StringCchCat( DevicePath, MAX_PATH, TEXT("#{ad498944-762f-11d0-8dcb-00c04fc3358c}") ); // 将“PNPDeviceID”中的“/”替换成“#”,以获得真正的设备路径名 std::replace( DevicePath + 4, DevicePath + 4 + _tcslen(PNPDeviceID), TEXT('//'), TEXT('#') ); // 获取设备句柄 hDeviceFile = CreateFile( DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if( hDeviceFile != INVALID_HANDLE_VALUE ) { ULONG dwID; BYTE ucData[8]; DWORD dwByteRet; // 获取网卡原生MAC地址 dwID = OID_802_3_PERMANENT_ADDRESS; isOK = DeviceIoControl( hDeviceFile, IOCTL_NDIS_QUERY_GLOBAL_STATS, &dwID, sizeof(dwID), ucData, sizeof(ucData), &dwByteRet, NULL ); if( isOK ) { // 将字节数组转换成16进制字符串 for( DWORD i = 0; i < dwByteRet; i++ ) { StringCchPrintf( MacAddress + (i << 1), uSize - (i << 1), TEXT("%02X"), ucData[i] ); } MacAddress[dwByteRet << 1] = TEXT('/0'); // 写入字符串结束标记 } CloseHandle( hDeviceFile ); } return isOK; } static BOOL WMI_DoWithHarddiskSerialNumber( TCHAR *SerialNumber, UINT uSize ) { UINT iLen; UINT i; iLen = _tcslen( SerialNumber ); if( iLen == 40 ) // InterfaceType = "IDE" { // 需要将16进制编码串转换为字符串 TCHAR ch, szBuf[32]; BYTE b; for( i = 0; i < 20; i++ ) { // 将16进制字符转换为高4位 ch = SerialNumber[i * 2]; if( (ch >= '0') && (ch <= '9') ) { b = ch - '0'; } else if( (ch >= 'A') && (ch <= 'F') ) { b = ch - 'A' + 10; } else if( (ch >= 'a') && (ch <= 'f') ) { b = ch - 'a' + 10; } else { // 非法字符 break; } b <<= 4; // 将16进制字符转换为低4位 ch = SerialNumber[i * 2 + 1]; if( (ch >= '0') && (ch <= '9') ) { b += ch - '0'; } else if( (ch >= 'A') && (ch <= 'F') ) { b += ch - 'A' + 10; } else if( (ch >= 'a') && (ch <= 'f') ) { b += ch - 'a' + 10; } else { // 非法字符 break; } szBuf[i] = b; } if( i == 20 ) { // 转换成功 szBuf[i] = L'/0'; StringCchCopy( SerialNumber, uSize, szBuf ); iLen = _tcslen( SerialNumber ); } } // 每2个字符互换位置 for( i = 0; i < iLen; i += 2 ) { std::swap( SerialNumber[i], SerialNumber[i+1] ); } // 去掉空格 std::remove( SerialNumber, SerialNumber + _tcslen(SerialNumber) + 1, L' ' ); return TRUE; } static BOOL WMI_DoWithProperty( INT iQueryType, TCHAR *szProperty, UINT uSize ) { BOOL isOK = TRUE; switch( iQueryType ) { case 0: // 网卡原生MAC地址 isOK = WMI_DoWithPNPDeviceID( szProperty, szProperty, uSize ); break; case 1: // 硬盘序列号 isOK = WMI_DoWithHarddiskSerialNumber( szProperty, uSize ); break; case 6: // 网卡当前MAC地址 // 去掉冒号 std::remove( szProperty, szProperty + _tcslen(szProperty) + 1, L':' ); break; default: // 去掉空格 std::remove( szProperty, szProperty + _tcslen(szProperty) + 1, L' ' ); } return isOK; } // 基于Windows Management Instrumentation(Windows管理规范) INT WMI_DeviceQuery( INT iQueryType, T_DEVICE_PROPERTY *properties, INT iSize ) { HRESULT hres; INT iTotal = 0; // 判断查询类型是否支持 if( (iQueryType < 0) || (iQueryType >= sizeof(szWQLQuery)/sizeof(T_WQL_QUERY)) ) { return -1; // 查询类型不支持 } // 初始化COM hres = CoInitializeEx( NULL, COINIT_MULTITHREADED ); if( FAILED(hres) ) { return -2; } // 设置COM的安全认证级别 hres = CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL ); if( FAILED(hres) ) { CoUninitialize(); return -2; } // 获得WMI连接COM接口 IWbemLocator *pLoc = NULL; hres = CoCreateInstance( CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, reinterpret_cast<LPVOID*>(&pLoc) ); if( FAILED(hres) ) { CoUninitialize(); return -2; } // 通过连接接口连接WMI的内核对象名"ROOT//CIMV2" IWbemServices *pSvc = NULL; hres = pLoc->ConnectServer( _bstr_t( L"ROOT//CIMV2" ), NULL, NULL, NULL, 0, NULL, NULL, &pSvc ); if( FAILED(hres) ) { pLoc->Release(); CoUninitialize(); return -2; } // 设置请求代理的安全级别 hres = CoSetProxyBlanket( pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE ); if( FAILED(hres) ) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return -2; } // 通过请求代理来向WMI发送请求 IEnumWbemClassObject *pEnumerator = NULL; hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t( szWQLQuery[iQueryType].szSelect ), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator ); if( FAILED(hres) ) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return -3; } // 循环枚举所有的结果对象 while( pEnumerator ) { IWbemClassObject *pclsObj = NULL; ULONG uReturn = 0; if( (properties != NULL) && (iTotal >= iSize) ) { break; } pEnumerator->Next( WBEM_INFINITE, 1, &pclsObj, &uReturn ); if( uReturn == 0 ) { break; } if( properties != NULL ) { // 获取属性值 VARIANT vtProperty; VariantInit( &vtProperty ); pclsObj->Get( szWQLQuery[iQueryType].szProperty, 0, &vtProperty, NULL, NULL ); StringCchCopy( properties[iTotal].szProperty, PROPERTY_MAX_LEN, W2T(vtProperty.bstrVal) ); VariantClear( &vtProperty ); // 对属性值做进一步的处理 if( WMI_DoWithProperty( iQueryType, properties[iTotal].szProperty, PROPERTY_MAX_LEN ) ) { iTotal++; } } else { iTotal++; } pclsObj->Release(); } // End While // 释放资源 pEnumerator->Release(); pSvc->Release(); pLoc->Release(); CoUninitialize(); return iTotal; }

通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号相关推荐

  1. 关于wmi获取网卡mac地址重复的分析

    现象:如图在部分电脑上获取ip和MAC地址对应关系时,界面显示部分电脑发现重复ip和mac 分析:用WMI Explorer查看时,有一个设备Microsoft TV/video connection ...

  2. 联想台式计算机的设备序列号,WMI获取硬件信息封装函数方法(联想台式机出厂编号 CPUID BIOS序列号 硬盘信息 显卡信息 MAC地址)...

    今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都是可以提取出来的,就自己把那些公共部分提出出来,以后如果要获取某部分的硬件信息就不用写一个一个的函数,比如获取MAC地址就写一个获取MAC地 ...

  3. Delphi自定义获取网卡MAC地址过程

    //获取网卡MAC地址=============================================================== procedure CvtInt; asm     ...

  4. Python 获取 网卡 MAC 地址

    /************************************************************************ Python 获取 网卡 MAC 地址* 说明:* ...

  5. php获取网卡mac地址吗,php获取网卡MAC地址步骤详解

    这次给大家带来php获取网卡MAC地址步骤详解,php获取网卡MAC地址的注意事项有哪些,下面就是实战案例,一起来看一下. php获取网卡的物理地址,即mac地址.<?php /** 获取网卡的 ...

  6. ioctl(sock, SIOCGIFHWADDR, ifr)获取网卡mac地址

    ioctl(sock, SIOCGIFHWADDR, &ifr) 获取网卡mac地址 ioctl(sock, SIOCGIFINDEX, &ifr)获取网卡接口地址 为什么我bind时 ...

  7. android 获取网卡mac_android获取网卡mac地址信息

    由于android版本不一样获取网卡mac地址的方式也不一样,比较麻烦,但是java sdk里面的函数是可以获取里面的网卡内容. 代码如下: /** * 获取网络的mac地址 * * @return ...

  8. python wmi读取网卡MAC地址、CPU序列号、硬盘序列号、主板序列号、BIOS序列号

    序列号相当于电脑的身份证号,是硬件出厂时,厂商写在硬件里的唯一识别码,具有唯一性和不可修改性.很多正版软件以此来识别用户电脑,限制安装. import uuid import wmi def get_ ...

  9. html文档php 取mac地址_cpu序列号_硬盘序列号,用vbs脚本获取网卡MAC,CPUID,硬盘序列号的实现代码...

    这里先给大家分享一个分配静态ip地址的代码 ' Assign a Static IP Address strComputer = "." Set objWMIService = G ...

最新文章

  1. 批量探测工具fpingping常用命令集合大学霸IT达人
  2. 程序员食品营养(1)-面包基础
  3. 统计代码行数_推荐一波代码量、行数、提交量、作者等全维度统计神器
  4. 每日一题之 MySQL
  5. 将Ehcache添加到Openxava应用程序
  6. NCRE四级网络工程师考题详解----LRU与LFU的区别
  7. 当前以太坊上DeFi协议总锁仓量为374.7亿美元
  8. [NHibernate]使用AttributeNHibernate.Mapping.Attributes
  9. pd怎么转成mysql_powerdesigner中实现PDM到MYSQl数据库的转换《转》
  10. 150万元重奖!阿里软件供应链安全大赛正式启动
  11. 如何把github上fork的项目修改过后再提交到github上
  12. win7下快捷方式关联错误的修复
  13. 计算机网络中速率、带宽、吞吐量的区别
  14. 如何做好数字化运营,打造战略落地的最佳武器?他们这么说|2021全球数字价值峰会...
  15. 什么是mysql主从同步
  16. bzoj4605: 崂山白花蛇草水(权值线段树套k-dtree)
  17. 字节跳动面试:从草根到百万年薪程序员的十年风雨之路,成功收获美团,小米安卓offer
  18. UE4 IOS打包详解
  19. dmx512如何帧同步_提供整体的DMX512-RDM解决方案
  20. loss损失不下降的原因

热门文章

  1. 编程资料 -C# 多线程 1
  2. Matlab求矩阵的最小多项式
  3. Python Matplotlib绘制多子图准备训练数据和GIF动画实践
  4. Kubernetes Krew简介
  5. (一)计算机基本组成
  6. 所有的 Boost 库文档的索引
  7. python入门指南by许半仙百度云-Python入门指南 作者:许半仙(4)
  8. mysql数据存储过程添加数据_Mysql 存储过程 自动插入数据
  9. 《HyVulDect: A hybrid semantic vulnerability mining system based ongraph neural network》阅读笔记
  10. 关于开机自启动qbo服务的讨论