如何查看网卡mac地址通过setupAPI得到网卡的mac地址

通过WDK获取设备的VID-PID、网卡原生MAC地址、硬盘序列号 - CSDN博客
通过WDK获取设备的VID-PID、网卡原生MAC地址、硬盘序列号
开发语言:C/C++
开发工具:
Visual Studio 2010
Windows Driver Kit Version .1
支持平台:Windows
实现功能:
通过WDK获取设备的VID-PID、网卡原生MAC地址、硬盘序列号
下载地址:
版本历史:
增加获取硬盘序列号(需要系统管理员权限)。
更新接口函数。
增加获取网卡原生MAC地址。
优化代码。
完成正式版本。获取设备的VID-PID。
接口函数:
WDK_DeviceQuery_Property
WDK_DeviceQuery_VIDPID
接口文件:WDK_DeviceQuery.h
&/* ----------------------------------------------------------
文件名称:WDK_DeviceQuery.h
作者:秦建辉
版本历史:
增加获取硬盘序列号(需要系统管理员权限)。
更新接口函数。
增加获取网卡原生MAC地址。
优化代码。
完成正式版本。获取设备的VID-PID。
功能描述:
基于WDK获取设备属性值。
接口函数:
WDK_DeviceQuery_Property
WDK_DeviceQuery_VIDPID
------------------------------------------------------------ */
#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;
#define WDK_QUERY_TYPENUM 4 // WDK查询支持的类型数
#ifndef MACRO_HIDD_VIDPID
#define MACRO_HIDD_VIDPID
typedef struct _HIDD_VIDPID
USHORT VendorID;
USHORT ProductID;
} HIDD_VIDPID;
#ifdef __cplusplus
extern "C"
功能:基于WDK获取设备属性值
参数说明:
iQueryType:需要查询的设备属性
0:人机交互设备的VID-PID
1:网卡原生MAC地址(包含USB网卡)
2:网卡原生MAC地址(剔除USB网卡)
3:硬盘序列号(需要系统管理员权限)
properties:存储设备属性值
iSize:可存储的最大设备数
-1:获取设备信息表失败
-2:不支持的查询类型
&=0:实际获取的设备数
INT WDK_DeviceQuery_Property( INT iQueryType, T_DEVICE_PROPERTY *properties, INT iSize );
功能:获取指定设备接口类相关设备的VID和PID
参数说明:
pGuid:指向设备接口类GUID
pVIDPID:存储设备的VID和PID
iSize:可存储的最大设备数
-1:获取设备信息表失败
&=0:实际获取的设备数
INT WDK_DeviceQuery_VIDPID( const GUID* pGuid, HIDD_VIDPID* pVIDPID, INT iSize );
#ifdef __cplusplus
实现代码:WDK_DeviceQuery.cpp
#include "WDK_DeviceQuery.h"
#include &tchar.h&
#include &strsafe.h&
#include &setupapi.h&
#include &ntddndis.h&
#include &ntdddisk.h&
#include &algorithm&
#ifdef __cplusplus
extern "C"
#include &hidsdi.h&
#ifdef __cplusplus
#pragma comment (lib, "Setupapi.lib")
#pragma comment (lib, "hid.lib")
const GUID GUID_QUERYSET[] = {
// 人机交互设备VID-PID
{0x4D1E55B2, 0xF16F, 0x11CF, 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30},
// 网卡原生MAC地址(包含USB网卡)
{0xADx762F, 0x11D0, 0x8D, 0xCB, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C},
// 网卡原生MAC地址(剔除USB网卡)
{0xADx762F, 0x11D0, 0x8D, 0xCB, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C},
// 硬盘序列号
{0x53F5BF, 0x11D0, 0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B},
// 获取设备的VID-PID
static BOOL WDK_GetVIDPID( TCHAR* DevicePath, TCHAR* szProperty, UINT uSize )
HANDLE hDeviceF
BOOL isOK = FALSE;
// 获取设备句柄
hDeviceFile = CreateFile( DevicePath,
FILE_SHARE_READ | FILE_SHARE_WRITE,
OPEN_EXISTING,
if( hDeviceFile != INVALID_HANDLE_VALUE )
{ // 获取设备属性
HIDD_ATTRIBUTES A
Attributes.Size = sizeof(HIDD_ATTRIBUTES);
isOK = HidD_GetAttributes( hDeviceFile, &Attributes );
if( isOK )
if( szProperty != NULL )
StringCchPrintf( szProperty, uSize, TEXT("%04X-%04X"), Attributes.VendorID, Attributes.ProductID );
CloseHandle( hDeviceFile );
return isOK;
// 获取网卡原生MAC地址
static BOOL WDK_GetMacAddress( TCHAR* DevicePath, TCHAR* szProperty, UINT uSize, BOOL isIncludeUSB )
HANDLE hDeviceF
BOOL isOK = FALSE;
// 剔除虚拟网卡
if( _tcsnicmp( DevicePath + 4, TEXT("root"), 4 ) == 0 )
return FALSE;
if( !isIncludeUSB )
{ // 剔除USB网卡
if( _tcsnicmp( DevicePath + 4, TEXT("usb"), 4 ) == 0 )
return FALSE;
// 获取设备句柄
hDeviceFile = CreateFile( DevicePath,
FILE_SHARE_READ | FILE_SHARE_WRITE,
OPEN_EXISTING,
if( hDeviceFile != INVALID_HANDLE_VALUE )
ULONG dwID;
BYTE ucData[8];
DWORD dwByteR
// 获取原生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 )
if( szProperty != NULL )
{ // 将字节数组转换成16进制字符串
for( DWORD i = 0; i & dwByteR i++ )
StringCchPrintf( szProperty + (i && 1), uSize - (i && 1), TEXT("%02X"), ucData[i] );
CloseHandle( hDeviceFile );
return isOK;
// 获取硬盘序列号(需要系统管理员权限)
static BOOL WDK_GetHarddiskSerialNumberWithAdminRights( TCHAR* DevicePath, TCHAR* szProperty, UINT uSize )
HANDLE hDeviceF
BOOL isOK = FALSE;
// 获取设备句柄
hDeviceFile = CreateFile( DevicePath,
GENERIC_READ | GENERIC_WRITE, // 注意:需要系统管理员权限才能执行读写操作
FILE_SHARE_READ | FILE_SHARE_WRITE,
OPEN_EXISTING,
if( hDeviceFile != INVALID_HANDLE_VALUE )
GETVERSIONINPARAMS VersionInP
DWORD dwByteR
// 获取硬盘属性
isOK = DeviceIoControl( hDeviceFile, SMART_GET_VERSION, NULL, 0, &VersionInParams, sizeof(GETVERSIONINPARAMS), &dwByteRet, NULL );
if( isOK )
isOK = FALSE;
if( VersionInParams.fCapabilities & CAP_ATA_ID_CMD )
BYTE abSCIP[sizeof(SENDCMDINPARAMS) - 1] = {0};
BYTE abSCOP[sizeof(SENDCMDOUTPARAMS) - 1 + 512] = {0};
SENDCMDINPARAMS
*scip = reinterpret_cast&SENDCMDINPARAMS*&(abSCIP);
SENDCMDOUTPARAMS *scop = reinterpret_cast&SENDCMDOUTPARAMS*&(abSCOP);
// 设置输入参数
scip-&irDriveRegs.bCommandReg = ID_CMD;
// 设置输出参数
scop-&cBufferSize = 512;
// 获取硬盘详细信息
isOK = DeviceIoControl( hDeviceFile, SMART_RCV_DRIVE_DATA, scip, sizeof(abSCIP), scop, sizeof(abSCOP), &dwByteRet, NULL );
if( isOK )
if( szProperty != NULL )
{ // 提取硬盘序列号
for( UINT i = 0; i & 20; i += 2 )
{ // 颠倒高低位字节
szProperty[i] = scop-&bBuffer[i+21];
szProperty[i + 1] = scop-&bBuffer[i+20];
szProperty[20] = TEXT('/0');
// 去掉空格
std::remove( szProperty, szProperty + _tcslen(szProperty) + 1, L' ' );
CloseHandle( hDeviceFile );
return isOK;
static BOOL WDK_GetProperty( TCHAR* DevicePath, INT iQueryType, TCHAR* szProperty, UINT uSize )
BOOL isOK = FALSE;
switch( iQueryType )
// 获取设备的VID-PID
isOK = WDK_GetVIDPID( DevicePath, szProperty, uSize );
// 网卡原生MAC地址(包含USB网卡)
isOK = WDK_GetMacAddress( DevicePath, szProperty, uSize, TRUE );
// 网卡原生MAC地址(剔除USB网卡)
isOK = WDK_GetMacAddress( DevicePath, szProperty, uSize, FALSE );
// 硬盘序列号(需要系统管理员权限)
isOK = WDK_GetHarddiskSerialNumberWithAdminRights( DevicePath, szProperty, uSize );
return isOK;
INT WDK_DeviceQuery_Property( INT iQueryType, T_DEVICE_PROPERTY *properties, INT iSize )
HDEVINFO hDevI
MemberIndex, RequiredS
SP_DEVICE_INTERFACE_DATA
DeviceInterfaceD
PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailD
INT iTotal = 0;
// 判断查询类型是否支持
if( (iQueryType & 0) || (iQueryType &= sizeof(GUID_QUERYSET)/sizeof(GUID)) )
return -2; // 查询类型不支持
// 获取设备信息集
hDevInfo = SetupDiGetClassDevs( GUID_QUERYSET + iQueryType, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE );
if( hDevInfo == INVALID_HANDLE_VALUE )
return -1;
// 枚举设备信息集中所有设备
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
for( MemberIndex = 0; ((properties == NULL) || (iTotal & iSize)); MemberIndex++ )
{ // 获取设备接口
if( !SetupDiEnumDeviceInterfaces( hDevInfo, NULL, GUID_QUERYSET + iQueryType, MemberIndex, &DeviceInterfaceData ) )
{ // 设备枚举完毕
// 获取接收缓冲区大小,函数返回值为FALSE,GetLastError()=ERROR_INSUFFICIENT_BUFFER
SetupDiGetDeviceInterfaceDetail( hDevInfo, &DeviceInterfaceData, NULL, 0, &RequiredSize, NULL );
// 申请接收缓冲区
DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc( RequiredSize );
DeviceInterfaceDetailData-&cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
// 获取设备细节信息
if( SetupDiGetDeviceInterfaceDetail( hDevInfo, &DeviceInterfaceData, DeviceInterfaceDetailData, RequiredSize, NULL, NULL ) )
if( properties != NULL )
if( WDK_GetProperty( DeviceInterfaceDetailData-&DevicePath, iQueryType, properties[iTotal].szProperty, PROPERTY_MAX_LEN ) )
if( iTotal & 0 )
{ // 剔除重复设备
if( _tcscmp( properties[iTotal].szProperty, properties[iTotal - 1].szProperty ) != 0 )
free( DeviceInterfaceDetailData );
SetupDiDestroyDeviceInfoList( hDevInfo );
INT WDK_DeviceQuery_VIDPID( const GUID* pGuid, HIDD_VIDPID* pVIDPID, INT iSize )
HDEVINFO hDevI
MemberIndex, RequiredS
SP_DEVICE_INTERFACE_DATA
DeviceInterfaceD
PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailD
INT iTotal = 0;
// 获取设备信息集
hDevInfo = SetupDiGetClassDevs( pGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE );
if( hDevInfo == INVALID_HANDLE_VALUE )
return -1;
// 枚举设备信息集中所有设备
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
for( MemberIndex = 0; ((pVIDPID == NULL) || (iTotal & iSize)); MemberIndex++ )
{ // 获取设备接口
if( !SetupDiEnumDeviceInterfaces( hDevInfo, NULL, pGuid, MemberIndex, &DeviceInterfaceData ) )
{ // 设备枚举完毕
// 获取接收缓冲区大小,函数返回值为FALSE,GetLastError()=ERROR_INSUFFICIENT_BUFFER
SetupDiGetDeviceInterfaceDetail( hDevInfo, &DeviceInterfaceData, NULL, 0, &RequiredSize, NULL );
// 申请接收缓冲区
DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc( RequiredSize );
DeviceInterfaceDetailData-&cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
// 获取设备细节信息
if( SetupDiGetDeviceInterfaceDetail( hDevInfo, &DeviceInterfaceData, DeviceInterfaceDetailData, RequiredSize, NULL, NULL ) )
{ // 获取设备句柄
HANDLE hDeviceF
hDeviceFile = CreateFile( DeviceInterfaceDetailData-&DevicePath,
FILE_SHARE_READ | FILE_SHARE_WRITE,
OPEN_EXISTING,
if( hDeviceFile != INVALID_HANDLE_VALUE )
{ // 获取设备属性
HIDD_ATTRIBUTES A
Attributes.Size = sizeof(HIDD_ATTRIBUTES);
if( HidD_GetAttributes( hDeviceFile, &Attributes ) )
if( pVIDPID != NULL )
pVIDPID[iTotal].VendorID = Attributes.VendorID;
pVIDPID[iTotal].ProductID = Attributes.ProductID;
if( iTotal & 0 )
{ // 剔除重复设备
if( (pVIDPID[iTotal].VendorID != pVIDPID[iTotal - 1].VendorID) || (pVIDPID[iTotal].ProductID != pVIDPID[iTotal - 1].ProductID) )
CloseHandle( hDeviceFile );
free( DeviceInterfaceDetailData );
SetupDiDestroyDeviceInfoList( hDevInfo );
本文已收录于以下专栏:
相关文章推荐
本文方法通过注册表可以的获取当前插入计算机的U盘、移动硬盘和USB读卡器等设备的PID、VID和序列号,这些信息可以用于标识设备和对设备进行下一步动作,如弹出设备需要PID和VID。...
通过Windows注册表获取U盘、移动硬盘和USB读卡器等设备的PID、VID和序列号
http://blog.csdn.net/trustbo/article/details/...
默认情况下在VM里就看不到USB鼠标键盘的PID/VID,只能看到虚拟的PID/VID,如果要在VM里看到真实的PID/VID,
需要在虚拟机的配置文件.vmx 里增加如下:
开发语言:C/C++支持平台:Windows实现功能:通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号下载地址:WMI_DeviceQuery.zip版本历史:V1....
虽然Win32_NetworkAdapter包含了属性PermanentAddress,但是在当前的WMI里只是个空值,微软目前还没有实现这个属性值。但是我们仍可以通过结合WMI和DeviceIoCo...
1,添加头文件和宏定义
#pragma comment(lib,"setupapi.lib")
DEFINE_GUID (UsbClassGuid, 0x...
前段时间由于项目需要,要求做一个服务器的实时性能监控(CPU、内存、网络利用率等)和读取服务器的硬件配置参数的接口供项目组使用,就是一个类似于鲁大师之类的东东吧...
当然第一想法肯定是利...
同系列文章:
/wordpress/?p=1361" target="_blank">VC:基于WDK和WMI获取机器指纹
他的最新文章
讲师:何宇健
讲师:董岩
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)修改MAC地址_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
修改MAC地址
阅读已结束,下载文档到电脑
想免费下载更多文档?
定制HR最喜欢的简历
你可能喜欢

我要回帖

更多关于 查看网卡mac地址 的文章

 

随机推荐