您的位置:首页 > 其它

Windows客户端开发--获取系统mac地址(使用GetAdaptersInfo和GetAdaptersAddresses)

2016-11-21 15:35 696 查看
使用WMI可以获取本地计算机的mac信息,现在就用另外两种方法获取mac地址:

GetAdaptersInfo 和 GetAdaptersAddresses

GetAdaptersInfo

功能:

The GetAdaptersInfo function retrieves adapter information for the local computer.

原型:

DWORD GetAdaptersInfo(
_Out_   PIP_ADAPTER_INFO pAdapterInfo,
_Inout_ PULONG           pOutBufLen
);


其中参数有PIP_ADAPTER_INFO:

typedef struct _IP_ADAPTER_INFO {
struct _IP_ADAPTER_INFO* Next;
DWORD ComboIndex;
char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];
UINT AddressLength;
BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];
DWORD Index;
UINT Type;
UINT DhcpEnabled;
PIP_ADDR_STRING CurrentIpAddress;
IP_ADDR_STRING IpAddressList;
IP_ADDR_STRING GatewayList;
IP_ADDR_STRING DhcpServer;
BOOL HaveWins;
IP_ADDR_STRING PrimaryWinsServer;
IP_ADDR_STRING SecondaryWinsServer;
time_t LeaseObtained;
time_t LeaseExpires;
} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;


上面的结构体中,我们注意关注Type、AddressLength、Address

Type:

#define MIB_IF_TYPE_OTHER               1
#define MIB_IF_TYPE_ETHERNET            6
#define MIB_IF_TYPE_TOKENRING           9
#define MIB_IF_TYPE_FDDI                15
#define MIB_IF_TYPE_PPP                 23
#define MIB_IF_TYPE_LOOPBACK            24
#define MIB_IF_TYPE_SLIP                28


上代码:

bool GetMacAddressByAdaptersInfo(std::string &mac_address)
{
bool ret = false;

ULONG out_buf_len = sizeof(IP_ADAPTER_INFO);
PIP_ADAPTER_INFO adapter_info = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));
if (adapter_info == NULL)
return false;
// Make an initial call to GetAdaptersInfo to get the necessary size into the out_buf_len variable
if (GetAdaptersInfo(adapter_info, &out_buf_len) == ERROR_BUFFER_OVERFLOW)
{
free(adapter_info);
adapter_info = (IP_ADAPTER_INFO *)malloc(out_buf_len);
if (adapter_info == NULL)
return false;
}

if (GetAdaptersInfo(adapter_info, &out_buf_len) == NO_ERROR)
{
PIP_ADAPTER_INFO adapter = adapter_info;
for (; adapter != NULL; adapter = adapter->Next)
{
// 确保是以太网
if (adapter->Type != MIB_IF_TYPE_ETHERNET)
continue;
// 确保MAC地址的长度为 00-00-00-00-00-00
if (adapter->AddressLength != 6)
continue;

std::cout << "GetMacAddressByAdaptersInfo: " <<std::hex << int(adapter->Address[0]) <<" "
<< int(adapter->Address[1]) << " "
<< int(adapter->Address[2]) << " "
<< int(adapter->Address[3]) << " "
<< int(adapter->Address[4]) << " "
<< int(adapter->Address[5]) << std::endl;

ret = true;
break;
}
}

free(adapter_info);
return ret;
}


注意:

On Windows XP and later: Use the GetAdaptersAddresses function instead of GetAdaptersInfo.

所以稍后会介绍GetAdaptersAddresses。

GetAdaptersAddresses

功能:

The GetAdaptersAddresses function retrieves the addresses associated with the adapters on the local computer.

原型:

“`cpp

ULONG WINAPI GetAdaptersAddresses(

In ULONG Family,

In ULONG Flags,

In PVOID Reserved,

Inout PIP_ADAPTER_ADDRESSES AdapterAddresses,

Inout PULONG SizePointer

);

第一个参数Family我们设置为AF_UNSPEC:
Return both IPv4 and IPv6 addresses associated with adapters with IPv4 or IPv6 enabled.

其中参数PIP_ADAPTER_ADDRESSES:
```cpp
typedef struct _IP_ADAPTER_ADDRESSES {
union {
ULONGLONG Alignment;
struct {
ULONG Length;
DWORD IfIndex;
};
};
struct _IP_ADAPTER_ADDRESSES  *Next;
PCHAR                              AdapterName;
PIP_ADAPTER_UNICAST_ADDRESS        FirstUnicastAddress;
PIP_ADAPTER_ANYCAST_ADDRESS        FirstAnycastAddress;
PIP_ADAPTER_MULTICAST_ADDRESS      FirstMulticastAddress;
PIP_ADAPTER_DNS_SERVER_ADDRESS     FirstDnsServerAddress;
PWCHAR                             DnsSuffix;
PWCHAR                             Description;
PWCHAR                             FriendlyName;
BYTE                               PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH];
DWORD                              PhysicalAddressLength;
DWORD                              Flags;
DWORD                              Mtu;
DWORD                              IfType;
IF_OPER_STATUS                     OperStatus;
DWORD                              Ipv6IfIndex;
DWORD                              ZoneIndices[16];
PIP_ADAPTER_PREFIX                 FirstPrefix;
ULONG64                            TransmitLinkSpeed;
ULONG64                            ReceiveLinkSpeed;
PIP_ADAPTER_WINS_SERVER_ADDRESS_LH FirstWinsServerAddress;
PIP_ADAPTER_GATEWAY_ADDRESS_LH     FirstGatewayAddress;
ULONG                              Ipv4Metric;
ULONG                              Ipv6Metric;
IF_LUID                            Luid;
SOCKET_ADDRESS                     Dhcpv4Server;
NET_IF_COMPARTMENT_ID              CompartmentId;
NET_IF_NETWORK_GUID                NetworkGuid;
NET_IF_CONNECTION_TYPE             ConnectionType;
TUNNEL_TYPE                        TunnelType;
SOCKET_ADDRESS                     Dhcpv6Server;
BYTE                               Dhcpv6ClientDuid[MAX_DHCPV6_DUID_LENGTH];
ULONG                              Dhcpv6ClientDuidLength;
ULONG                              Dhcpv6Iaid;
PIP_ADAPTER_DNS_SUFFIX             FirstDnsSuffix;
} IP_ADAPTER_ADDRESSES, *PIP_ADAPTER_ADDRESSES;

<div class="se-preview-section-delimiter"></div>


上面结构体中我们关注:PhysicalAddressLength、PhysicalAddress

上代码:

bool GetMacAddressByAdaptersAddresses(std::string &mac_address)
{
bool ret = false;

ULONG out_buf_len = sizeof(IP_ADAPTER_ADDRESSES);
PIP_ADAPTER_ADDRESSES addresses = (IP_ADAPTER_ADDRESSES*)malloc(out_buf_len);
if (addresses == NULL)
return false;
// Make an initial call to GetAdaptersAddresses to get the necessary size into the ulOutBufLen variable
if (GetAdaptersAddresses(AF_UNSPEC, 0, NULL, addresses, &out_buf_len) == ERROR_BUFFER_OVERFLOW)
{
free(addresses);
addresses = (IP_ADAPTER_ADDRESSES*)malloc(out_buf_len);
if (addresses == NULL)
return false;
}

if (GetAdaptersAddresses(AF_UNSPEC, 0, NULL, addresses, &out_buf_len) == NO_ERROR)
{
// If successful, output some information from the data we received
PIP_ADAPTER_ADDRESSES curr_addresses = addresses;
for (; curr_addresses != NULL; curr_addresses = curr_addresses->Next)
{
// 确保MAC地址的长度为 00-00-00-00-00-00
if (curr_addresses->PhysicalAddressLength != 6)
continue;

std::cout << "GetMacAddressByAdaptersAddresses: " << std::hex << int(curr_addresses->PhysicalAddress[0]) << " "
<< int(curr_addresses->PhysicalAddress[1]) << " "
<< int(curr_addresses->PhysicalAddress[2]) << " "
<< int(curr_addresses->PhysicalAddress[3]) << " "
<< int(curr_addresses->PhysicalAddress[4]) << " "
<< int(curr_addresses->PhysicalAddress[5]) << std::endl;

ret = true;
break;
}
}

free(addresses);
return ret;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: