目标描述:
在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<<