I need to obtain the network adapter GUID given the connection name as shown by Windows network manager. Powershell’s get-netadapter
does the job, but I’d like to do it in C/C++. I know that thare are two set of API function/methods:
- iphlpapi.h
- netlistmgr.h
Both seems to do part of the work. In particular, by IEnumNetworks
and related classes I managed to list some networks/adapters. E.G., this is the output of get-netadapter
:
Name InterfaceDescription ifIndex Status MacAddress LinkSpeed
---- -------------------- ------- ------ ---------- ---------
My Tunnel TAP-Windows Adapter V9 #2 40 Disconnected 00-FF-E6-0A-89-C6 1 Gbps
Ethernet 4 Intel(R) PRO/1000 MT Desktop Adapter #2 30 Up 08-00-27-95-74-A2 1 Gbps
Local Area Connection TAP-Windows Adapter V9 15 Disconnected 00-FF-CC-95-DA-46 1 Gbps
Ethernet 3 Intel(R) PRO/1000 MT Desktop Adapter 4 Up 08-00-27-AC-C1-5A 1 Gbps
My goal is to get “My Tunnel” adapter object (ifIndex or GUID, at least), but when the network is not “connected”, I don’t get any adapter. Here my “quick and dirty” test program (error checks, main and includes omitted for clarity):
CoInitializeEx(NULL, COINITBASE_MULTITHREADED);
// get a network list manager object
INetworkListManager *mgr;
CoCreateInstance(CLSID_NetworkListManager, NULL, CLSCTX_ALL, IID_INetworkListManager, (LPVOID*)&mgr);
// get the enumerator for existing networks
IEnumNetworks *enn;
mgr->GetNetworks(NLM_ENUM_NETWORK_ALL, &enn);
for (;;) { {
INetwork *net;
ULONG n = 0;
if (S_OK != enn->Next(1, &net, &n) || n < 1) {
break;
}
// print the name of current network object
BSTR str;
net->GetName(&str); printf(" Name: %wsn", str); SysFreeString(str);
// get the enumerator for network connections belonging to the current network
IEnumNetworkConnections *enc;
net->GetNetworkConnections(&enc);
INetworkConnection *nc;
for (;;) {
if (S_OK != enc->Next(1, &nc, &n)) {
break;
}
// explore the list of connections and print the adapter's GUID
nc->GetAdapterId(&g);
printf(" Adapter: {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}n",
g.Data1, g.Data2, g.Data3, g.Data4[0], g.Data4[1], g.Data4[2],
g.Data4[3], g.Data4[4], g.Data4[5], g.Data4[6], g.Data4[7]);
}
}
Here the output I get:
Name: Network
Name: Local Area Connection
Name: mygroup.net
Adapter: {e1b4e605-c6ee-4f03-b4c6-0d879a27669b}
Name: My Tunnel
Name: Unidentified network
Adapter: {12d9ae29-7863-414f-b195-e1230d8c697b}
“My Tunnel” doesn’t seem to have any adapter, although powershell is able to retrieve it.
The adapter appears only after I established a connection (a VPN in this case).
How can I get the adapters in the same way powershell does?
NOTE: what I need is the ability to get the network adapter given the network name. By iphlpapi
I can retreive other information (e.g. InterfaceDescription
), but not the network name. It seems that the “network name” is not part of the “core networking” of Windows, but of a sort of managing layer instead. So, the only solution I have found right now is CreateProcess("powershell.exe",...)
… uhm…
3