Reputation: 4438
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:
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: %ws\n", 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...
Upvotes: 1
Views: 157
Reputation: 4438
Thanks to @Jeaninez-MSFT, it turned out that the function GetAdaptersAddresses, in spite of its name, returns much more information. In particular, field "FriendlyName" contains the string that powershell's get-netadapter
shows in the "Name" column. MS documentation contains a working demo program.
Upvotes: 1