VC上获取MAC地址

参考资料

  • 中文版:Windows网络编程(第二版).pdf
  • 英文版:Network Programming for Windows[2Ed 2002 MS Press].CHM
  • MSDN 2005

准备工作

MSDN

在MSDN上查找 GetAdaptersAddresses ,可以得到这个函数的详细解释,另外有这个API的示例代码,拷贝过来:

PIP_ADAPTER_ADDRESSES pAddresses;
pAddresses = (IP_ADAPTER_ADDRESSES*) malloc(sizeof(IP_ADAPTER_ADDRESSES));
ULONG outBufLen = 0;
DWORD dwRetVal = 0;

// Make an initial call to GetAdaptersAddresses to get the 
// size needed into the outBufLen variable
if (GetAdaptersAddresses(AF_INET, 
  0, 
  NULL, 
  pAddresses, 
  &outBufLen) == ERROR_BUFFER_OVERFLOW) {
  GlobalFree(pAddresses);
  pAddresses = (IP_ADAPTER_ADDRESSES*) malloc(outBufLen);
}

// Make a second call to GetAdapters Addresses to get the
// actual data we want
if ((dwRetVal = GetAdaptersAddresses(AF_INET, 
  0, 
  NULL, 
  pAddresses, 
  &outBufLen)) == NO_ERROR) {
  // If successful, output some information from the data we received
  while (pAddresses) {
    printf("\tFriendly name: %S\n", pAddresses->FriendlyName);
    printf("\tDescription: %S\n", pAddresses->Description);
    pAddresses = pAddresses->Next;
  }
}
else { 
  printf("Call to GetAdaptersAddresses failed.\n");
  LPVOID lpMsgBuf;
  if (FormatMessage( 
    FORMAT_MESSAGE_ALLOCATE_BUFFER | 
    FORMAT_MESSAGE_FROM_SYSTEM | 
    FORMAT_MESSAGE_IGNORE_INSERTS,
    NULL,
    dwRetVal,
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    (LPTSTR) &lpMsgBuf,
    0,
    NULL )) {
    printf("\tError: %s", lpMsgBuf);
  }
  LocalFree( lpMsgBuf );
}

《网络编程》

在这本书中的IP Helper Functions一章,讲到ipconfig。也可以重点参考。不截图、不拷贝代码了。

VS版本问题

在新一些的VS版本上,是有api直接获取的。在MSDN2005上可以查到
对于那个的api,估计2005或以上都可以。——2003是否支持就不好说了,得实际验证一下。

至少 VC6上是没有这个api的。

VS2010

在以上参考资料的基础上,给出下面的示例代码。这是一个简单的MFC对话框,只给出主要的一些代码,其他的自然可以自己补充。

头文件&lib

#include <windows.h>
#include <iphlpapi.h>

#pragma comment(lib, "Iphlpapi.lib")

成员函数:

MSDN的示例代码有内存泄漏的问题,做了优化。另外,关心的是MAC地址,所以只对这一块的数据做了处理。

头文件声明部分:

private:
    void GetMacAddress();
    void OutputMacAddress(PIP_ADAPTER_ADDRESSES pAddresses);

实现代码:

void CGetMacAddressDlg::OnBnClickedOk()
{
    // TODO: 在此添加控件通知处理程序代码
    GetMacAddress();

    CDialogEx::OnOK();
}

void CGetMacAddressDlg::OutputMacAddress(PIP_ADAPTER_ADDRESSES pAddresses) 
{
    DWORD physicalAddressLength = pAddresses->PhysicalAddressLength;
    if (0 == physicalAddressLength) return;

    CString macAddress;
    CString sByte;
    for (DWORD i = 0; i < physicalAddressLength; i++) {
        sByte.Format(_T("%02X"), pAddresses->PhysicalAddress[i]);
        if (i > 0) macAddress += _T("-");
        macAddress += sByte;
    }

    MessageBox((LPCTSTR)macAddress, _T("Test"), MB_OK);
}

void CGetMacAddressDlg::GetMacAddress() 
{   
    PIP_ADAPTER_ADDRESSES pAddresses;
    PIP_ADAPTER_ADDRESSES orgAddresses;
    pAddresses = (IP_ADAPTER_ADDRESSES*) malloc(sizeof(IP_ADAPTER_ADDRESSES));
    orgAddresses = pAddresses;
    ULONG outBufLen = 0;
    DWORD dwRetVal = 0;

    // Make an initial call to GetAdaptersAddresses to get the 
    // size needed into the outBufLen variable
    if (GetAdaptersAddresses(AF_INET, 
        0, 
        NULL, 
        pAddresses, 
        &outBufLen) == ERROR_BUFFER_OVERFLOW) {

        free(pAddresses);
        pAddresses = (IP_ADAPTER_ADDRESSES*) malloc(outBufLen);
        orgAddresses = pAddresses;
    }

    // Make a second call to GetAdapters Addresses to get the
    // actual data we want
    if ((dwRetVal = GetAdaptersAddresses(AF_INET, 
        0, 
        NULL, 
        pAddresses, 
        &outBufLen)) == NO_ERROR) {

        // If successful, output some information from the data we received
        while (pAddresses) {
            OutputMacAddress(pAddresses);
            pAddresses = pAddresses->Next;
        }
    } else { 
        LPVOID lpMsgBuf;
        if (FormatMessage( 
            FORMAT_MESSAGE_ALLOCATE_BUFFER | 
            FORMAT_MESSAGE_FROM_SYSTEM | 
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            dwRetVal,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
            (LPTSTR) &lpMsgBuf,
            0,
            NULL )) {

            TRACE("\tError: %s", lpMsgBuf);
        }

        free( lpMsgBuf );
    }

    free(orgAddresses);

}

VC6

如前面所示,上面的api在vc6上是不支持的。所以vc6需要另外的方式,比如网上有提到安装对应sdk库的方法。另外简单描述后一种方法。

对于DOS命令的方法,包括如下两点:

DOS命令的执行结果示例:

C:\>ipconfig /all

Windows IP 配置

   主机名  . . . . . . . . . . . . . : the_computer_name
   主 DNS 后缀 . . . . . . . . . . . :
   节点类型  . . . . . . . . . . . . : 混合
   IP 路由已启用 . . . . . . . . . . : 否
   WINS 代理已启用 . . . . . . . . . : 否

以太网适配器 本地连接:

   连接特定的 DNS 后缀 . . . . . . . :
   描述. . . . . . . . . . . . . . . : ......
   物理地址. . . . . . . . . . . . . : 78-AF-35-C6-34-43
   DHCP 已启用 . . . . . . . . . . . : 是
   自动配置已启用. . . . . . . . . . : 是
   本地链接 IPv6 地址. . . . . . . . : ......
   IPv4 地址 . . . . . . . . . . . . : ......
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   获得租约的时间  . . . . . . . . . : ......
   租约过期的时间  . . . . . . . . . : ......
   默认网关. . . . . . . . . . . . . : ......
   DHCP 服务器 . . . . . . . . . . . : ......
   DHCPv6 IAID . . . . . . . . . . . : ......
   DHCPv6 客户端 DUID  . . . . . . . : ......
   DNS 服务器  . . . . . . . . . . . : ......
   TCPIP 上的 NetBIOS  . . . . . . . : 已启用

隧道适配器 . . . 

C:\>

可以只关心下面这个:

物理地址. . . . . . . . . . . . . : 78-AF-35-C6-34-43

对应的正则表达式语法:

"\\s([\\da-fA-F]{2}-[\\da-fA-F]{2}-[\\da-fA-F]{2}-[\\da-fA-F]{2}-[\\da-fA-F]{2}-[\\da-fA-F]{2})[\\s\\r]"

这里直接给出了C中的语法,即两个’\’。

C语言的一个正则表达式pcre中提到了多次匹配的概念,因此可以获取ipconfig /all中的所有MAC地址。在得到字符串的MAC地址之后,就可以再转换成字节流或其他需要的形式。

注:如果DOS命令执行完之后不能马上读到结果,可以Sleep()一会,然后再ReadFile()。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值