实现思路如下:
开发语言:Visual C++
支持平台:Windows
实现功能:
下载地址:
WDK_MACAddress.zip
版本历史:
V1.0 2010年05月23日
- 完成正式版本。
接口函数:
WDK_MacAddress
源代码:
WDK_MacAddress.h
/* ---------------------------------------------------------- 文件名称:WDK_MacAddress.h 作者:秦建辉 MSN:[email protected] 版本历史: V1.0 2010年05月23日 完成正式版本。 功能描述: 通过WDK获取网卡原生MAC地址和当前MAC地址。 接口函数: WDK_MacAddress ------------------------------------------------------------ */ #pragma once #include <windows.h> #define MACADDRESS_BYTELEN 6 // MAC地址字节长度 typedef struct _T_MACADDRESS { BYTE PermanentAddress[MACADDRESS_BYTELEN]; // 原生MAC地址 BYTE MACAddress[MACADDRESS_BYTELEN]; // 当前MAC地址 } T_MACADDRESS; #ifdef __cplusplus extern "C" { #endif /* 功能:通过WDK获取网卡原生MAC地址和当前MAC地址 入口参数: iQueryType:需要获取的网卡类型 0:包括USB网卡 1:不包括USB网卡 pMacAddress:存储网卡MAC地址 uSize:可存储的最大网卡数目 返回值: -1:获取设备信息表失败 -2:不支持的查询类型 >=0:实际获取的设备数 */ INT WDK_MacAddress( INT iQueryType, T_MACADDRESS *pMacAddress, INT iSize ); #ifdef __cplusplus } #endif
WDK_MacAddress.cpp
#include "WDK_MacAddress.h" #include <tchar.h> #include <strsafe.h> #include <setupapi.h> #include <ntddndis.h> #include <algorithm> #ifdef __cplusplus extern "C" { #endif #include <hidsdi.h> #ifdef __cplusplus } #endif #pragma comment (lib, "Setupapi.lib") #pragma comment (lib, "hid.lib") const GUID GUID_QUERYSET[] = { // 网卡原生MAC地址(包含USB网卡) {0xAD498944, 0x762F, 0x11D0, 0x8D, 0xCB, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C}, // 网卡原生MAC地址(剔除USB网卡) {0xAD498944, 0x762F, 0x11D0, 0x8D, 0xCB, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C}, }; // 获取网卡原生MAC地址 static BOOL WDK_GetMacAddress( TCHAR* DevicePath, T_MACADDRESS *pMacAddress, INT iIndex, BOOL isIncludeUSB ) { HANDLE hDeviceFile; 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, 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_CURRENT_ADDRESS; isOK = DeviceIoControl( hDeviceFile, IOCTL_NDIS_QUERY_GLOBAL_STATS, &dwID, sizeof(dwID), ucData, sizeof(ucData), &dwByteRet, NULL ); if( isOK ) { memcpy( pMacAddress[iIndex].MACAddress, ucData, 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 ) { memcpy( pMacAddress[iIndex].PermanentAddress, ucData, dwByteRet ); } } CloseHandle( hDeviceFile ); } return isOK; } static BOOL WDK_GetProperty( TCHAR* DevicePath, INT iQueryType, T_MACADDRESS *pMacAddress, INT iIndex ) { BOOL isOK = FALSE; switch( iQueryType ) { case 0: // 网卡原生MAC地址(包含USB网卡) isOK = WDK_GetMacAddress( DevicePath, pMacAddress, iIndex, TRUE ); break; case 1: // 网卡原生MAC地址(剔除USB网卡) isOK = WDK_GetMacAddress( DevicePath, pMacAddress, iIndex, FALSE ); break; default: break; } return isOK; } INT WDK_MacAddress( INT iQueryType, T_MACADDRESS *pMacAddress, INT iSize ) { HDEVINFO hDevInfo; DWORD MemberIndex, RequiredSize; SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData; 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; ((pMacAddress == NULL) || (iTotal < iSize)); MemberIndex++ ) { // 获取设备接口 if( !SetupDiEnumDeviceInterfaces( hDevInfo, NULL, GUID_QUERYSET + iQueryType, MemberIndex, &DeviceInterfaceData ) ) { // 设备枚举完毕 break; } // 获取接收缓冲区大小,函数返回值为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( pMacAddress != NULL ) { if( WDK_GetProperty( DeviceInterfaceDetailData->DevicePath, iQueryType, pMacAddress, iTotal ) ) { iTotal++; } } else { iTotal++; } } free( DeviceInterfaceDetailData ); } SetupDiDestroyDeviceInfoList( hDevInfo ); return iTotal; }