網卡可分為物理網卡與虛擬網卡,其中物理網卡又可分為有線網卡和無線網卡,還有藍牙設備的網卡。
概念理解:簡單的說,物理網卡就是硬件,虛擬網卡是軟件。詳細點說,物理網卡就是安裝在電腦主板上的有線或無線網卡,每塊物理網卡都有不同的且唯一的物理地址(MAC地址);虛擬網卡則是通過軟件模擬網絡環境,構建的虛擬網絡適配器,一般是Microsoft Loopback Adapter,通過VPN技術實現虛擬網卡間的局域網通信。
GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)可以獲得本機網卡的所有信息,我們可以通過它來過濾得到想要的信息。
pAdapter->Type == MIB_IF_TYPE_ETHERNET //以太網卡(有線、無線、藍牙)
pAdapter->Type == 71 //無線網卡
strstr(pAdapter->Description,"Bluetooth") >0 //藍牙設備的網卡(藍牙的網卡屬於以太網卡,但卻不屬於有線網卡和無線網卡)
strstr(pAdapter->Description,"PCI")>0 //物理網卡
這種方法基本達到識別的目的,但是也存在不能識別網卡類型的可能,這就要根據項目的需求來決定是否采用此種方法。
下面的例子是獲取本地有線物理網卡的mac地址:

1 #pragma once 2 #include "UserInfo.h" 3 #include <stdio.h> 4 #include <winsock2.h> 5 #include <iphlpapi.h> 6 #pragma comment(lib, "IPHLPAPI.lib") 7 8 int GetMac(char* mac) 9 { 10 ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); 11 PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO)); 12 if(pAdapterInfo == NULL) 13 return -1; 14 if(GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) 15 { 16 free(pAdapterInfo); 17 pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen); 18 if (pAdapterInfo == NULL) 19 return -2; 20 } 21 22 if(GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == NO_ERROR) 23 { 24 for(PIP_ADAPTER_INFO pAdapter = pAdapterInfo; pAdapter != NULL; pAdapter = pAdapter->Next) 25 { 26 // 確保是有線物理網卡 27 if(pAdapter->Type != MIB_IF_TYPE_ETHERNET || pAdapter->Type == 71 || strstr(pAdapter->Description,"Bluetooth") >0) 28 continue; 29 if(pAdapter->AddressLength != 6) 30 continue; 31 sprintf_s(mac, 18, "%02X:%02X:%02X:%02X:%02X:%02X", 32 int (pAdapter->Address[0]), 33 int (pAdapter->Address[1]), 34 int (pAdapter->Address[2]), 35 int (pAdapter->Address[3]), 36 int (pAdapter->Address[4]), 37 int (pAdapter->Address[5])); 38 break; 39 } 40 } 41 free(pAdapterInfo); 42 43 return 0; 44 }
我在網上看到有人分享另一個方法,那就是通過“Characteristics”這個值來確定網卡的類型是虛擬網卡還是物理網卡,據說更簡單而且100%准確。
雖然我自己還沒實踐過,不過也暫時將這種方法記錄下來~
Characteristics 值在注冊表HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Class/{4D36E972-E325-11CE-BFC1-08002bE10318}/數字下。
在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 說明組件有多個端口,每個端口作為單獨的設備安裝。
ox80 NCF_HAS_UI 說明組件支持用戶接口(例如,Advanced Page或Customer Properties Sheet)
ox400 NCF_FILTER 說明組件是一個過濾器
從上面可以看出來,只要用戶判斷“Characteristics ”的值就可以判斷網卡是虛擬網卡還是物理網卡。
如果是虛擬網卡:Characteristics & NCF_VIRTUAL ==NCF_VIRTUAL
如果是物理網卡:Characteristics & NCF_PHYSICAL ==NCF_PHYSICAL