zoukankan      html  css  js  c++  java
  • Visual C++ Tips: 用 IP Helper 获得网络接口的友好名称(Friendly Name)

    前面有篇文章:《用 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 }

    运行结果: 

    参考文章

    好的代码像粥一样,都是用时间熬出来的
  • 相关阅读:
    ANT安装
    MAVEN配置教程
    闲笔
    js系列
    微信小程序系列_require
    c++复习系列
    codeblocks系列
    mysql系列
    Google Developer Tools
    数学建模算法(三):神经网络
  • 原文地址:https://www.cnblogs.com/jijm123/p/14336101.html
Copyright © 2011-2022 走看看