C++编码获取本地主机的MAC地址

本文介绍了如何使用C++在Windows系统中通过编程获取网络适配器的MAC地址,并区分虚拟网卡和物理网卡,以及有线和无线网卡。通过调用GetAdaptersInfo函数和解析注册表信息来实现这一目标,具体涉及注册表的HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlClass{4D36E972-E325-11CE-BFC1-08002BE10318}路径下的Characteristics值来判断网卡类型。
摘要由CSDN通过智能技术生成

目标描述

    在Windows平台下,通过编码获取网络适配器(网卡)的MAC地址,要区分出是虚拟网卡还是真实网

卡,在该前提下,再一次区分是有线网卡还是无线网卡。

原理以及解决方案

GetAdaptersInfo函数可以获取本地主机的适配器信息(包括:Adapter Name,Mac,Ip,NetMask,NetGate)。

对于Windows平台下,所有的软硬件信息都会在注册表中注册。在HKEY_LOCAL_MACH HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class目录下是硬件设备(比如声卡、网卡、端口、IDE控制器、内存控制器等等)的代码,包括隐藏设备和虚拟设备。HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}目录下找到每一项的Characteristics的值,通过该值来确定网卡的类型是虚拟网卡还是物理网卡。

在Windows中,Characteristics的取值如下,Characteristics项可以有1个或多个如下的值(多值应计算总和):

十六进制值     名字                              描述

ox1            NCF_VIRTUAL                      组件是个虚拟适配器

ox2            NCF_SOFTWARE_ENUMERATED       组件是一个软件模拟的适配器

ox4            NCF_PHYSICAL                     组件是一个物理适配器

ox8            NCF_HIDDEN                      组件不显示用户接口

ox10           NCF_NO_SERVICE                  组件没有相关的服务(设备驱动程序)

ox20           NCF_NOT_USER_REMOVABLE         不能被用户删除(例如,通过控制面板或设备管理器)

ox40           NCF_MULTIPORT_INSTANCED_ADAPTER 说明组件有多个端口,每个端

口作为单独的设备安装。每个端口有自己的hw_id(组件ID)并可被单独安装,这只适合于

EISA适配器

ox80           NCF_HAS_UI                        说明组件支持用户接口(例如,AdvancedPage或Customer Properties Sheet)

ox400          NCF_FILTER                        说明组件是一个过滤器

从上面可以看出来,只要用户判断“Characteristics”的值就可以判断网卡是虚拟网卡还是物理网卡。

如果是虚拟网卡:Characteristics& NCF_VIRTUAL ==NCF_VIRTUAL

如果是物理网卡:Characteristics& NCF_PHYSICAL ==NCF_PHYSICAL

在注册表中Interfaces子项中,查询键值LowerRange的值,一般有线网卡字符是”ethernet”,无线网卡的” wlan ,ethernet”,虚拟无线网卡的是” ethernet,wlan,vwifi”,这一部分是通过比较字符串”ethernet”和各子项Characteristics的值,如果相同则为有线网卡,否则为无线网卡。

(这一部分的判断依据不知道是不是100%可靠,但是我的能检测,了解的可以补充下)。

代码示例及讲解

PIP_ADAPTER_INFOpIpAdapterInfo = new IP_ADAPTER_INFO();

         unsignedlong stSize = sizeof(IP_ADAPTER_INFO);

                   intnRel = GetAdaptersInfo(pIpAdapterInfo,&stSize);

                   intnetCardNum = 0;

                   intIPnumPerNetCard = 0;

         if(ERROR_BUFFER_OVERFLOW == nRel)

         {

                   deletepIpAdapterInfo;

                   pIpAdapterInfo =(PIP_ADAPTER_INFO)new BYTE[stSize];

                   nRel=GetAdaptersInfo(pIpAdapterInfo,&stSize);   

         }

         if(ERROR_SUCCESS == nRel)

         {

                   while(pIpAdapterInfo)

                   {

                            cout<<"网卡数量:"<<++netCardNum<<endl;

                            cout<<"网卡名称"<<pIpAdapterInfo->AdapterName<<endl;

                            cout<<

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值