前面有篇文章:《用 WinPcap 获取网络接口列表》,是通过 WinPcap 库来获得网络接口列表,但是拿到的网络接口名称对于人(Human Being)来说毫无意义,如下图:
实际上我们在 Windows 控制面板(Control Panel)中看到的是网络接口的“友好名称”(Friendly Name),如下:
为了拿到网络接口的“友好名称”,我遍查 MSDN,终于找到了答案。以下是我写的程序示例:
NetworkInformation.h
1 #ifndef _NetworkInformation_H 2 #define _NetworkInformation_H 3 4 #include <vector> 5 #include <winsock2.h> 6 #include <iphlpapi.h> 7 8 // https://communities.ca.com/thread/241732865 9 #define MAX_ADAPTER_FriendlyName_LENGTH 65 10 11 typedef struct 12 { 13 TCHAR AdapterName[MAX_ADAPTER_NAME_LENGTH + 4] = { 0 }; 14 TCHAR Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4] = { 0 }; 15 TCHAR FriendlyName[MAX_ADAPTER_FriendlyName_LENGTH + 4] = { 0 }; 16 GUID NetworkGuid = { 0 }; 17 BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH] = { 0 }; 18 DWORD PhysicalAddressLength = 0; 19 union { 20 ULONG Flags; 21 struct { 22 ULONG DdnsEnabled : 1; 23 ULONG RegisterAdapterSuffix : 1; 24 ULONG Dhcpv4Enabled : 1; 25 ULONG ReceiveOnly : 1; 26 ULONG NoMulticast : 1; 27 ULONG Ipv6OtherStatefulConfig : 1; 28 ULONG NetbiosOverTcpipEnabled : 1; 29 ULONG Ipv4Enabled : 1; 30 ULONG Ipv6Enabled : 1; 31 ULONG Ipv6ManagedAddressConfigurationSupported : 1; 32 }; 33 }; 34 DWORD Mtu = 0; 35 DWORD IfType = 0; 36 IF_OPER_STATUS OperStatus = IfOperStatusUnknown; 37 NET_IF_CONNECTION_TYPE ConnectionType; 38 TUNNEL_TYPE TunnelType= TUNNEL_TYPE_NONE; 39 40 } IP_AdaptersAddresses; 41 42 DWORD GetAdaptersAddressesInfo(std::vector<IP_AdaptersAddresses> & adapters_collection); 43 44 #endif // _NetworkInformation_H
NetworkInformation.cpp
1 #include "NetworkInformation.h" 2 3 #include <tchar.h> 4 #include <Windows.h> 5 6 #include <winsock2.h> 7 #include <iphlpapi.h> 8 9 #pragma comment(lib, "IPHLPAPI.lib") 10 11 #define WORKING_BUFFER_SIZE 81920 12 13 DWORD GetAdaptersAddressesInfo(std::vector<IP_AdaptersAddresses> & adapters_collection) 14 { 15 DWORD return_code = NO_ERROR; 16 adapters_collection.clear(); 17 18 // A pointer to a buffer that contains a linked list of IP_ADAPTER_ADDRESSES structures on successful return. 19 IP_ADAPTER_ADDRESSES * pAdapterAddresses = nullptr; 20 IP_ADAPTER_ADDRESSES * pCurrAddresses = nullptr; 21 22 // specifies the size of the buffer pointed to by AdapterAddresses. 23 ULONG sizeOfAdapterAddresses = WORKING_BUFFER_SIZE; 24 25 // Return both IPv4 and IPv6 addresses associated with adapters with IPv4 or IPv6 enabled. 26 ULONG family = AF_UNSPEC; 27 28 // Return addresses for all NDIS interfaces. 29 ULONG flags = GAA_FLAG_INCLUDE_PREFIX; 30 31 // This parameter is not currently used, but is reserved for future system use. 32 PVOID reserved = NULL; 33 34 pAdapterAddresses = (IP_ADAPTER_ADDRESSES *)HeapAlloc(GetProcessHeap(), 0, sizeOfAdapterAddresses); 35 if (pAdapterAddresses == NULL) 36 { 37 return_code = 0xFFFFFFFF; 38 } 39 40 memset(pAdapterAddresses, 0, sizeOfAdapterAddresses); 41 42 ULONG dwRetVal = GetAdaptersAddresses(family, flags, reserved, pAdapterAddresses, &sizeOfAdapterAddresses); 43 if (dwRetVal == NO_ERROR) 44 { 45 // If successful, output some information from the data we received. 46 pCurrAddresses = pAdapterAddresses; 47 while (pCurrAddresses) 48 { 49 IP_AdaptersAddresses adapter; 50 51 size_t adapter_name_length = strlen(pCurrAddresses->AdapterName); 52 for (size_t i = 0; i < adapter_name_length; i++) 53 { 54 adapter.AdapterName[i] = pCurrAddresses->AdapterName[i]; 55 } 56 57 _tcscpy_s(adapter.Description, pCurrAddresses->Description); 58 _tcscpy_s(adapter.FriendlyName, pCurrAddresses->FriendlyName); 59 adapter.NetworkGuid = pCurrAddresses->NetworkGuid; 60 61 adapter.PhysicalAddressLength = pCurrAddresses->PhysicalAddressLength; 62 for (size_t i = 0; i < adapter.PhysicalAddressLength; i++) 63 { 64 adapter.PhysicalAddress[i] = pCurrAddresses->PhysicalAddress[i]; 65 } 66 67 adapter.Flags = pCurrAddresses->Flags; 68 adapter.Mtu = pCurrAddresses->Mtu; 69 adapter.IfType = pCurrAddresses->IfType; 70 adapter.OperStatus = pCurrAddresses->OperStatus; 71 adapter.ConnectionType = pCurrAddresses->ConnectionType; 72 adapter.TunnelType = pCurrAddresses->TunnelType; 73 74 adapters_collection.push_back(adapter); 75 pCurrAddresses = pCurrAddresses->Next; 76 } 77 } 78 else 79 { 80 switch (dwRetVal) 81 { 82 case ERROR_ADDRESS_NOT_ASSOCIATED: 83 // An address has not yet been associated with the network endpoint. 84 // DHCP lease information was available. 85 break; 86 case ERROR_BUFFER_OVERFLOW: 87 // The buffer size indicated by the SizePointer parameter is too small to hold the adapter information or 88 // AdapterAddresses parameter is NULL. 89 // The SizePointer parameter returned points to the required size of the buffer to hold the adapter information. 90 break; 91 case ERROR_INVALID_PARAMETER: 92 // One of the parameters is invalid. This error is returned for any of the following conditions: 93 // the SizePointer parameter is NULL, the Address parameter is not AF_INET, AF_INET6, or AF_UNSPEC, 94 // or the address information for the parameters requested is greater than ULONG_MAX. 95 break; 96 case ERROR_NOT_ENOUGH_MEMORY: 97 // Insufficient memory resources are available to complete the operation. 98 break; 99 case ERROR_NO_DATA: 100 // No addresses were found for the requested parameters. 101 break; 102 default: 103 // Use FormatMessage to obtain the message string for the returned error. 104 break; 105 } 106 107 return_code = dwRetVal; 108 } 109 110 if (pAdapterAddresses) 111 { 112 HeapFree(GetProcessHeap(), 0, pAdapterAddresses); 113 pAdapterAddresses = nullptr; 114 } 115 116 return return_code; 117 }
GetNetworkInformation.cpp
1 // GetNetworkInformation.cpp : Defines the entry point for the console application. 2 // 3 4 #include <io.h> 5 #include "NetworkInformation.h" 6 7 int main() 8 { 9 std::vector<IP_AdaptersAddresses> adapters_collection; 10 DWORD return_code = GetAdaptersAddressesInfo(adapters_collection); 11 if (return_code == NO_ERROR) 12 { 13 size_t count = adapters_collection.size(); 14 for (size_t i = 0; i < count; i++) 15 { 16 _tprintf(_T("%d. FriendlyName: %wS "), i + 1, adapters_collection[i].FriendlyName); 17 _tprintf(_T(" AdapterName : %wS "), adapters_collection[i].AdapterName); 18 _tprintf(_T(" Description : %wS "), adapters_collection[i].Description); 19 } 20 } 21 22 return 0; 23 }
运行结果: