Thursday, March 8, 2018

WinAPI: How to determine when a network is identifying?

Leave a Comment

When a connect some devices via ethernet I can see the adapter status in the Network Connections panel change to "Identifying Network". I want to query for this status using c++ Windows API.

I'm implementing somewhat of a dynamic ipconfig /all listing in my project. When a network on a network interface is identifying I'll want to display "Identifying Network".

I'm aware of the INetwork interface, but it annoyingly is only accessible through COM. Is there another way? Maybe from the information about the Network Interface itself?

1 Answers

Answers 1

How does INetwork know?

If you would search for the relevant property bag key L"NA_NetworkClass" in system files and you would have some reverse engineering skills and a bit of luck, you could find that the relevant implementation of the INetwork interface apparently lies in C:\Windows\System32\netprofmsvc.dll.

The code implementing IPropertyBag::Read() for NA_NetworkClass seems to determine the state by looking at some other GUID property of the network. Apparently, both the unidentified and identifying states are signaled by one of two hardcoded values there, while any other value means the connection is fully identified.

So far so good. If you could determine this GUID by some other means (e.g. through some "vanilla" Win32 API that you would be comfortable with) and compare it yourself, you should be able to determine the identification state as well. But here comes the catch: the exact GUID values for unidentified and identifying are dynamically generated at a different place in netprofmsvc.dll, so they will be different every time!

At this point you should stop trying. This is one of the techniques that can be deliberately used by OS authors to tell you that messing with system internals in this way is discouraged, error-prone and dangerous.

So just use the intended interface as everybody else. Come on, compared to some of the other horrible things out there, COM is not bad at all!

How was this done before Windows Vista?

The answer is it wasn't done at all.

The GUID I wrote about above actually happens to be a "network profile GUID", calculated from many network parameters like domain authentication state, gateway's MAC address etc., and later associated with one of the access profiles like Domain/Work/Home/Public.

All this got introduced only in Vista, together with the whole new "Network and Sharing Center" and other improvements in firewall and network management. See this document "Exploring The Windows Firewall" from 2007 and search for a chapter called "Network Profiles" for more information.

Are there any alternative solutions?

If you insist on avoiding INetwork, you might never be able to match the Windows network identification state 100%.

As explained in the article above, the Network Location Awareness (NLA) service apparently goes through a lot of work to reliably identify the network, considering many other parameters than just assigned IP addresses or enabled protocols. Replicating all that yourself (to determine when you know everything necessary to say a network is identified) would be challenging, especially because the exact details of the process are undocumented.

That said, checking for a valid received DHCP configuration (valid host and gateway IP addresses) might be a good enough approximation in most cases. Good luck!

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment