Enumerate Windows Network Adapters

  • 查询网卡的状态

Return values:

* 0: Connected
* 1: Disconnected
* -1: Not available
int QueryNetworkAdapterStatus(string guidName) 
{ 
    string str = "\\\\.\\"; 
    str += guidName;
 
    HANDLE m_hNetworkCardHandle = ::CreateFileA( 
        str.c_str(), 
        0, 
        FILE_SHARE_READ, 
        NULL, 
        OPEN_EXISTING, 
        0, 
        INVALID_HANDLE_VALUE 
    );
 
    if (m_hNetworkCardHandle == INVALID_HANDLE_VALUE) 
        return -1;
 
    ULONG ConnectedState = 0; 
    ULONG BytesWritten = 0; 
    ULONG OidCode = OID_GEN_MEDIA_CONNECT_STATUS;
 
    if (0 != ::DeviceIoControl(m_hNetworkCardHandle, 
        IOCTL_NDIS_QUERY_GLOBAL_STATS, 
        &OidCode, 
        sizeof(OidCode), 
        &ConnectedState, 
        sizeof(ConnectedState), 
        &BytesWritten, 
        NULL)) 
    { 
        ::CloseHandle(m_hNetworkCardHandle); 
        return ConnectedState; 
    } 
    else { 
        ::CloseHandle(m_hNetworkCardHandle); 
        return -1; 
    } 
}
  • 列出所有的物理网卡(WMI的方式)
public static IEnumerable<NetworkAdapter> GetAllPhysicalInterfaces()
{
	var list = new List<NetworkAdapter>();
    var queryString = @"SELECT * FROM Win32_NetworkAdapter WHERE (PhysicalAdapter = TRUE) AND (NOT PNPDeviceID LIKE 'ROOT\\%') AND (NOT Name LIKE 'WAN%') AND (NOT Name LIKE 'Bluetooth%')";
	ManagementObjectSearcher mos = new ManagementObjectSearcher(queryString);
	ManagementObjectCollection moc = mos.Get();

	foreach (ManagementObject mo in moc) {
		bool enabled = Convert.ToBoolean(mo["NetEnabled"] ?? false);
		var connectionId = (mo["NetConnectionID"] ?? "").ToString();
		var name = (mo["Name"] ?? "").ToString();
		var manufacturer = (mo["Manufacturer"] ?? "").ToString();
		var macAddress = (mo["MacAddress"] ?? "").ToString().ToUpper().Replace(":", "");
		var adapter = new NetworkAdapter() {
			ConnectionId = connectionId,
			Name = name,
			Enabled = enabled,
			Manufacturer = manufacturer,
			MacAddress = macAddress
		};
		list.Add(adapter);
	}
	return list;
}
  • 列出所有的物理网卡(C++)
DWORD EnumNetworkAdapters() 
{ 
    IP_ADAPTER_INFO* pAdapterList = NULL; 
    IP_ADAPTER_INFO* pAdapter = NULL; 
    ULONG ulBufLen = 0; 
    DWORD err;
 
    err = ::GetAdaptersInfo(pAdapterList, &ulBufLen); 
    if (err == ERROR_BUFFER_OVERFLOW) 
    { 
        pAdapterList = (IP_ADAPTER_INFO*) ::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, ulBufLen); 
        err = ::GetAdaptersInfo(pAdapterList, &ulBufLen); 
    } 
    else if (err != ERROR_SUCCESS) 
    { 
        return err; 
    }
 
    if (pAdapterList == NULL) 
    { 
        return ERROR_BAD_ARGUMENTS; 
    }
 
    pAdapter = pAdapterList; 
    while (pAdapter != NULL) { 
        cout << "-----------------------------------------------" << endl; 
        cout << pAdapter->AdapterName << endl; 
        cout << pAdapter->Description << endl; 
        IP_ADDR_STRING *ipAddrString = &pAdapter->IpAddressList; 
        while (ipAddrString != NULL) { 
            cout << ipAddrString->IpAddress.String << endl; 
            ipAddrString = ipAddrString->Next; 
        }
 
        pAdapter = pAdapter->Next; 
    }
 
    ::HeapFree(::GetProcessHeap(), 0, pAdapterList); 
    return 0; 
}
  • 测试程序
#include <winsock2.h>
#include <iphlpapi.h>
#include <iostream>

#pragma comment(lib, "IPHLPAPI.lib")

using namespace std;

int main()
{
    IP_ADAPTER_INFO* pAdapterList = NULL;
    IP_ADAPTER_INFO* pAdapter = NULL;
    ULONG ulBufLen = 0;
    DWORD err;

    err = ::GetAdaptersInfo(pAdapterList, &ulBufLen);
    if (err == ERROR_BUFFER_OVERFLOW) {
        pAdapterList = (IP_ADAPTER_INFO*) ::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, ulBufLen);
        err = ::GetAdaptersInfo(pAdapterList, &ulBufLen);
    }
    else if (err != ERROR_SUCCESS) {
        return err;
    }

    if (pAdapterList == NULL) {
        return ERROR_BAD_ARGUMENTS;
    }

    pAdapter = pAdapterList;
    while (pAdapter != NULL) {
        cout << "-----------------------------------------------" << endl;
        cout << pAdapter->AdapterName << endl;
        cout << pAdapter->Description << endl;
        IP_ADDR_STRING *ipAddrString = &pAdapter->IpAddressList;
        while (ipAddrString != NULL) {
            cout << ipAddrString->IpAddress.String << endl;
            ipAddrString = ipAddrString->Next;
        }
        pAdapter = pAdapter->Next;
    }
    ::HeapFree(::GetProcessHeap(), 0, pAdapterList);
}
  • 运行结果
-----------------------------------------------
{58B429BA-AE91-4BB9-AFA2-2B0C9737A1A4}
Realtek Gaming GBE Family Controller
0.0.0.0
-----------------------------------------------
{E8F67081-3211-4C27-AD36-8AA570E3107E}
Hyper-V Virtual Ethernet Adapter
172.17.37.33
-----------------------------------------------
{78CC71FC-5DCC-4826-A718-F614F593AD21}
Npcap Loopback Adapter
169.254.27.222
-----------------------------------------------
{A901092D-7854-4932-AC6B-2A7363F32B41}
Hyper-V Virtual Ethernet Adapter #5
192.168.100.1