As we went through the dogfood process for Longhorn Server we understood that once we hit RC0 the Windows Firewall would be enabled by default, blocking all unsolicited inbound connections. This particular situation posed a small problem for our group due to the fact that we have a number of servers hosting a number of instances of our server application that clients communicate with via TCP. I decided that the best way to address this problem was to develop an application that could be used to enumerate running server instances obtaining the process ID and map it to the local port then open the port on the firewall. I can't publish the entire implementation but you should be able to get the idea.
To accomplish this task I used C# to p/Invoke GetExtendedTcpTable which returns a MIB_TCPTABLE_OWNER_PID structure to be used for the lookup; but first I needed to import iphlpapi.dll and prototype the target function.
[DllImport("iphlpapi.dll", SetLastError = true)]
public static extern uint GetExtendedTcpTable(IntPtr tcpTable, ref int tcpTableLength, bool sort, int ipVersion, TcpTableType tcpTableType, int reserved);
public static class ManagedWrapper
{
public static TcpTable GetExtendedTcpTable(bool sorted)
List<TcpRow> tcpRows = new List<TcpRow>();
IntPtr tcpTable = IntPtr.Zero;
int tcpTableLength = 0;
if (IpHelper.GetExtendedTcpTable(tcpTable, ref tcpTableLength, sorted, IpHelper.AfInet, IpHelper.TcpTableType.OwnerPidAll, 0) != 0)
try
tcpTable = Marshal.AllocHGlobal(tcpTableLength);
if (IpHelper.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, IpHelper.AfInet, IpHelper.TcpTableType.OwnerPidAll, 0) == 0)
IpHelper.TcpTable table = (IpHelper.TcpTable)Marshal.PtrToStructure(tcpTable, typeof(IpHelper.TcpTable));
IntPtr rowPtr = (IntPtr)((long)tcpTable + Marshal.SizeOf(table.Length));
for (int i = 0; i < table.Length; ++i)
tcpRows.Add(new TcpRow((IpHelper.TcpRow)Marshal.PtrToStructure(rowPtr, typeof(IpHelper.TcpRow))));
rowPtr = (IntPtr)((long)rowPtr + Marshal.SizeOf(typeof(IpHelper.TcpRow)));
}
finally
if (tcpTable != IntPtr.Zero)
Marshal.FreeHGlobal(tcpTable);
return new TcpTable(tcpRows);
A quick query to WMI returned the service display name and PIDs for the target processes which I stored in a System.Collections.ArrayList.
foreach (ManagementObject service in colServices)
int pid = Convert.ToInt32(service["ProcessId"].ToString());
string displayname = service["DisplayName"].ToString();
foreach (MyApp.IPHelperAPI.TcpRow tcpRow in MyApp.IPHelperAPI.ManagedWrapper.GetExtendedTcpTable(true))
if (tcpRow.ProcessId == pid)
if (tcpRow.RemoteEndPoint.Port != 389)
Console.WriteLine("\tDiscovered " + displayname + " running under process id " + pid.ToString());
serviceinfo.Add(displayname.ToUpper().Trim() + ";" + tcpRow.LocalEndPoint.Port.ToString());
In order to modify the firewall properties you will need a reference to NetFwTypeLib (hnetcfg.dll) in your Visual Studio project. Once you have that you can implement a method to give the process back its port. For example...
private static void ConfigurePorts(ArrayList serviceinfo)
INetFwMgr icfMgr = null;
Type TicfMgr = Type.GetTypeFromProgID("HNetCfg.FwMgr");
icfMgr = (INetFwMgr)Activator.CreateInstance(TicfMgr);
catch (Exception ex)
Trace.WriteLine(ex.ToString());
return;
Console.WriteLine("Editing FW policy...");
char[] delims = { ';' };
foreach (string info in serviceinfo)
string[] splitinfo = info.Trim().Split(delims);
string servicename = splitinfo[0];
int serviceport = Convert.ToInt32(splitinfo[1]);
INetFwProfile profile;
INetFwOpenPort portClass;
Type TportClass = Type.GetTypeFromProgID("HNetCfg.FWOpenPort");
portClass = (INetFwOpenPort)Activator.CreateInstance(TportClass);
profile = icfMgr.LocalPolicy.CurrentProfile;
portClass.Scope = NetFwTypeLib.NET_FW_SCOPE_.NET_FW_SCOPE_ALL;
portClass.Enabled = true;
portClass.Name = servicename + ":" + serviceport.ToString();
portClass.Port = serviceport;
portClass.Protocol = NetFwTypeLib.NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP;
Console.WriteLine("\tOpened port " + serviceport + " for " + servicename);
profile.GloballyOpenPorts.Add(portClass);
Console.WriteLine("FW policy edit is complete.");
In the end your applications will thank you!