通过WDK获取网卡原生MAC地址和当前MAC地址。

来源:互联网 发布:算法具有哪些重要特性 编辑:程序博客网 时间:2024/04/25 17:52
/* ---------------------------------------------------------- 
文件名称: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;  
}

0 0
原创粉丝点击