文件名称:WDK_MacAddress.h
作者:秦建辉
MSN:splashcn@msn.com
版本历史:
V1.0 2010年05月23日
完成正式版本。
功能描述:
通过WDK获取网卡原生MAC地址和当前MAC地址。
接口函数:
WDK_MacAddress
------------------------------------------------------------ */
#pragma once
#include <windows.h>
#define MACADDRESS_BYTELEN 32 // 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
#include "stdafx.h"
#include "WDK_MacAddress.h"
#include <stdlib.h>
#include <tchar.h>
#include <strsafe.h>
#include <setupapi.h>
#include <ntddndis.h>
#include <algorithm>
#pragma comment (lib, "Setupapi.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] = {0};
char szBuffer[32] = {0};
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 )
{
sprintf_s((char*)pMacAddress[iIndex].MACAddress,32,"%02X-%02X-%02X-%02X-%02X-%02X",
ucData[0],ucData[1],ucData[2],ucData[3],ucData[4],ucData[5]);
//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 );
sprintf_s((char*)pMacAddress[iIndex].PermanentAddress,32,"%02X-%02X-%02X-%02X-%02X-%02X",
ucData[0],ucData[1],ucData[2],ucData[3],ucData[4],ucData[5]);
}
}
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;
}