How do I open ports in the Windows Firewall, part 3

This is the 3rd and final article in my discussion of how the WMC product opened holes in the Windows firewall to enable the WMC clients to access the WMC HTTP server.

In my last article, I had found an INetConnection object, which had a “guidId” property that I thought might be useful when trying to associate an INetConnection object with an IP address.

I dug a bit deeper through the SDK, and I discovered that the IP_ADAPTER_ADDRESSES structure contained a string “AdapterName”.  It turns out that the “AdapterName” field is a string-ized representation of the GUID used in the INetConnection!  And, since the IP_ADAPTER_ADDRESSES structure contains the IP address of the connection, I can use that to see if the adapter is associated with the right API.

Once I’d found the right IP_ADAPTER_ADDRESSES entry, all I’d need to do is to call CLSIDFromString on the AdapterName field of the IP_ADAPTER_ADDRESSES field and I’d have the GUID I needed. 

Well, to get an IP_ADAPTER_ADDRESSES structure, I need to call the GetAdaptersAddresses API, which returns an array of IP_ADAPTER_ADDRESSES structures.  Now I had all the pieces I needed to pull all of this together.

For a given IP address, I called into a routine GetAdapterGuid which calls GetAdapterAddresses.  It then matched the FirstUnicastAddress field in the IP_ADAPTER_ADDRESSES structure with the IP address specified, and if they matched, returned the GUID in the “AdapterName” field of the IP_ADAPTER_ADDRESSES structure.

Now that I had the adapter GUID, I called into the INetSharingManager object to enumerate all the connections, and found the connection that corresponded to the adapter GUID I was looking for.

And once I had the INetConnection that matched my IP address, I asked the sharing manager for the INetSharingConfiguration that corresponded to that INetConnection object, and added the port mapping for my port to that IP address.

And I was done!  A whole lot of work, and a pretty squirrelly API but it got the job done.

Please note: If I were using the INetFW APIs that was added for XP SP2, this process would have been much easier.  The new firewall API is documented here.  Using the new API, I could just CoCreateInstance of an INetFwOpenPort, set the IP address for our local subnets (see the initial post for a list of the local subnets) as the remote addresses, set the port and service, and add the INetFwOpenPort to the INetFwOpenPorts collection.  And I’d be done.  The new API also lets you have significantly more control over opening ports in the firewall than the old one did, and it appears to be a far more pleasant API to use.  There’s even an example of opening ports in the “Exercising the firewall” C++ sample.  You can download the firewall SDK here.