Working with windows firewall from code

Quite recently I did some automation for an installation program that was changing the firewalls rules. So to be able to test that the installation was working as expected I need a way to access information about the firewall from code and also a way to change the information to verify that the installer was able to repair the rules. I found a lot of smaller code snippets mostly in VB on the net with random quality. Since I’m big fan of C# I did decide to create my one snippet’s in C#

The basic functionality is found in the COM object hnetcfg.dll. So the first thing to-do is to get a firewall manager.

private const string CLSIDFireWallManager = "{304CE942-6E39-40D8-943A-B913C40C9CD4}";
private static NetFwTypeLib.INetFwMgr GetFirewallManager()
{
    Type objectType = Type.GetTypeFromCLSID(new Guid(CLSIDFireWallManager));
    INetFwMgr manager = Activator.CreateInstance(objectType) as NetFwTypeLib.INetFwMgr;
    if (manager == null)
    {
        throw new NotSupportedException("Could not load firewall manager");
    }
 
    return manager;
}

Getting the current profile The profile is used for all firewall rules interactions.

private static INetFwProfile GetCurrentProfile()
{
    INetFwProfile profile;
    try
    {
        profile = GetFirewallManager().LocalPolicy.CurrentProfile;
    }
    catch (System.Runtime.InteropServices.COMException e)
    {
        throw new NotSupportedException("Could not get the current profile (COMException)", e);
    }
    catch (System.Runtime.InteropServices.InvalidComObjectException e)
    {
        throw new NotSupportedException("Could not get the current profile (InvalidComObjectException)", e);
    }
 
    return profile;
}

Is firewall on or of?

public static bool IsWindowsFirewallOn
{
    get
    {
        return GetCurrentProfile().FirewallEnabled;                
    }
 
    set
    {
        GetCurrentProfile().FirewallEnabled = value;
    }
}


Remove port

public static bool RemovePort(int portNumber, NET_FW_IP_PROTOCOL_ protocol)
{
    if (IsPortEnabled(portNumber, protocol))
    {
        try
        {
            GetCurrentProfile().GloballyOpenPorts.Remove(portNumber, protocol);
        }
        catch (Exception)
        {
            return false;
        }                
    }
 
    return true;
}

Add port

private const string ProgramIDOpenPort = "HNetCfg.FWOpenPort";
public static bool AddPort(string title, int portNumber, NET_FW_SCOPE_ scope, NET_FW_IP_PROTOCOL_ protocol, NET_FW_IP_VERSION_ ipversion)
{
    if (string.IsNullOrEmpty(title))
    {
        throw new ArgumentNullException("title");
    }
 
    if (!IsPortEnabled(portNumber, protocol))
    {
        // Get the type based on program ID
        Type type = Type.GetTypeFromProgID(ProgramIDOpenPort);
        INetFwOpenPort port = Activator.CreateInstance(type) as INetFwOpenPort;
 
        port.Name = title;
        port.Port = portNumber;
        port.Scope = scope;
        port.Protocol = protocol;
        port.IpVersion = ipversion;
 
        try
        {
            GetCurrentProfile().GloballyOpenPorts.Add(port);
        }
        catch (Exception)
        {
            return false;
        }
    }
 
    return true;
}

Check if the port is already open

public static bool IsPortEnabled(int portNumber, NET_FW_IP_PROTOCOL_ protocol)
{           
    // Retrieve the open ports collection
    INetFwOpenPorts openPorts = GetCurrentProfile().GloballyOpenPorts;
    if (openPorts == null)
    {
        return false;
    }
 
    // Get the open port
    try
    {
        INetFwOpenPort openPort = openPorts.Item(portNumber, protocol);
        if (openPort == null)
        {
            return false;
        }
    }
    catch (System.IO.FileNotFoundException)
    {
       return false;
    }
 
    return true;
}

Add application

private const string ProgramIDAuthorizedApplication = "HNetCfg.FwAuthorizedApplication";
public static bool AddApplication(string title, string applicationPath, NET_FW_SCOPE_ scope, NET_FW_IP_VERSION_ ipversion)
{
    if (String.IsNullOrEmpty(title))
    {
        throw new ArgumentNullException("title");
    }
 
    if (String.IsNullOrEmpty(applicationPath))
    {
        throw new ArgumentNullException("applicationPath");
    }
 
    if (!IsApplicationEnabled(applicationPath))
    { 
        // Get the type based on program ID
        Type type = Type.GetTypeFromProgID(ProgramIDAuthorizedApplication);
        INetFwAuthorizedApplication auth = Activator.CreateInstance(type) as INetFwAuthorizedApplication;
 
        auth.Name = title;
        auth.ProcessImageFileName = applicationPath;
        auth.Scope = scope;
        auth.IpVersion = ipversion;
        auth.Enabled = true;
 
        try
        {
            GetCurrentProfile().AuthorizedApplications.Add(auth);
        }
        catch (Exception)
        {
            return false;
        }
    }
 
    return true;
}

Does it exist any rule allready for application

public static bool IsApplicationEnabled(string applicationPath)
{
    if (String.IsNullOrEmpty(applicationPath))
    {
        throw new ArgumentNullException("applicationPath");
    }
 
    try
    {
        INetFwAuthorizedApplication application = GetCurrentProfile().AuthorizedApplications.Item(applicationPath);
 
        if (application == null)
        {
            return false;
        }
    }
    catch (System.IO.FileNotFoundException)
    {
        return false;
    }
 
    return true;
}
0.00 avg. rating (0% score) - 0 votes

About Peter Wibeck

Comments

3 Responses to “Working with windows firewall from code”
  1. Raphael Amorminio says:

    Hi,

    I´m about to try your code. I need to test an open port on the windows firewall.

    I just don´t understand the line:
    private const string CLSIDFireWallManager = “{304CE942-6E39-40D8-943A-B913C40C9CD4}”;

    I just checked my windows registry and I found an entry …
    This is the same for every windows version ?

    Sorry about he lousy english, not my native language,
    And thank you ! Helped a lot !

    • Peter Wibeck says:

      This code was developed long time ago and was tested on Windows XP and Windows server 2003 R2. When googling for this CLID I can only find older post, witch would indicate that it have changed in newer version of Windows. Take a look on the this post for anathor solution: MSDN forum

Trackbacks

Check out what others are saying about this post...
  1. review of article builder…

    Working with windows firewall from code : Peter Wibeck’s blog…



Speak Your Mind

Tell us what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!

*