在VC下获取原始MAC地址
本文参考Splash的博文,链接为:http://blog.youkuaiyun.com/jhqin/article/details/5618667
基本实现思路如下:
1、通过网卡接口类GUID获取物理网卡的设备路径名。
2、通过设备路径名,用CreateFile获取设备句柄。
3、通过设备句柄,用DeviceIoControl与驱动程序进行通信,获取网卡的原始MAC地址和当前MAC地址。
具体代码:
#include <windows.h>
#include <stdio.h>
#include <setupapi.h>
#pragma comment (lib,"Setupapi.lib")
#define MACADDRESS_BYTELEN 6 // MAC地址字节长度
#define OID_802_3_PERMANENT_ADDRESS 0x01010101 //The address of the NIC encoded in the hardware.
//#define OID_802_3_CURRENT_ADDRESS 0x01010102 //The address the NIC is currently using.
/* An application can use IOCTL_NDIS_QUERY_GLOBAL_STATS to obtain information from a network adapter.
* The application passes IOCTL_NDIS_QUERY_GLOBAL_STATS, along with an Object Identifier(OID),
* in the DeviceIoControl() function.*/
#define IOCTL_NDIS_QUERY_GLOBAL_STATS 0x00170002
// 初始化网卡原始MAC地址的GUID结构
GUID GUID_DEVCLASS_QUERY={0xAD498944, 0x762F, 0x11D0, 0x8D, 0xCB, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C};
static BOOL GetMacAddress()
{
HDEVINFO hDevInfo;
DWORD MemberIndex,RequiredSize;
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData;
BOOL isOK=FALSE;
// 获取设备信息集
hDevInfo = SetupDiGetClassDevs( &GUID_DEVCLASS_QUERY, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE );
if( INVALID_HANDLE_VALUE == hDevInfo )
{
return FALSE;
}
// 枚举设备信息集中所有设备
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
/*台式机一般只有以太网卡,的以用"MemberIndex < 1"条件循环一次得到的便是以太网卡的地址,
而对笔记本来说,使用条件"MemberIndex < 2"可以得到两条信息,第一条信息是以太网卡的地址,
第二条信息是无线网卡的地址,可以设置参数来实现打印相应的网卡地址*/
for( MemberIndex = 0; MemberIndex < 1; MemberIndex++ )
{
// 获取设备接口
if( !SetupDiEnumDeviceInterfaces( hDevInfo, NULL, &GUID_DEVCLASS_QUERY, 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 ) )
{
HANDLE hDeviceFile;
// 获取设备句柄
hDeviceFile = CreateFile(
DeviceInterfaceDetailData->DevicePath,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if( hDeviceFile != INVALID_HANDLE_VALUE )
{
ULONG dwID;
BYTE ucData[MACADDRESS_BYTELEN];
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 )
{
printf("%02X-%02X-%02X-%02X-%02X-%02X\n",
ucData[0],ucData[1],ucData[2],
ucData[3],ucData[4],ucData[5]);
} // if( isOK )
} // if( hDeviceFile != INVALID_HANDLE_VALUE )
} // if( SetupDiGetDeviceInterfaceDetail() )
free( DeviceInterfaceDetailData );
} // for( )
SetupDiDestroyDeviceInfoList( hDevInfo );
return TRUE;
}
int main()
{
BOOL ret;
ret=GetMacAddress();
printf("%d\n",ret);
return 0;
}