Click here to Skip to main content
Licence CPOL
First Posted 23 Jul 2006
Views 49,206
Bookmarked 28 times

Open Windows Firewall During Installation

By | 23 Jul 2006 | Article
This test code will serve as an MSI custom action to open the Windows firewall after installation.

Introduction

During the installation of my application, I needed to add it to the Windows firewall as an allowed application and open two ports for another application. This code will function as a custom action during the install to open the firewall on install and close it on uninstall. In trying to keep things as simple as possible, the following C# class library will be called from the setup - openFirewall() and closeFirewall().

First, I generated the FWSetupAction project as a C# class library. After that, I use the properties page to switch the output type to a console application to step through it with the debugger. When it's operational, switch back to the class library for integration with the MSI setup logic and incorporate it as a custom action.

After the initial project creation, rename Class1.cs to Firewall.cs in the Solution Navigator. If you're writing code anew, add the NetFwTypeLib reference first to allow intellisense to help you recognize the terms you'll be coding. This reference will be required for correct compilation, so whether you put it in before coding or after doesn't matter, but it will be needed. To add the reference, right click on References and select Browse. Browse to %windir%\system32\hnetcfg.dll and select it - the NetFwTypeLib will be created.

Edit the Firewall.cs class to have the following code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using NetFwTypeLib;
using Microsoft.Win32;
namespace FWSetupAction
{
public class Firewall
{
    protected int[] discoPorts = { 0xD100, 0xD101 };
    protected INetFwProfile fwProfile;

    public void openFirewall()
    {
        ///////////// Firewall Authorize Application ////////////
        String imageFilename = getImageFilename();
        setProfile();
        NetFwAuthorizedApplications apps = fwProfile.AuthorizedApplications;
        INetFwAuthorizedApplication app = 
          ( INetFwAuthorizedApplication ) getInstance( "INetAuthApp" );
        app.Name = "Application Name";
        app.ProcessImageFileName = imageFilename;
        apps.Add( app );
        apps = null;

        //////////////// Open Needed Ports /////////////////
        INetFwOpenPorts openports = fwProfile.GloballyOpenPorts;
        foreach( int port in discoPorts )
        {
            INetFwOpenPort openport = 
              ( INetFwOpenPort ) getInstance( "INetOpenPort" );
            openport.Port = port;
            openport.Protocol = NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_UDP;
            openport.Name = "New Open Port";
            openports.Add( openport );
        }
        openports = null;
    } // openFirewall

    public void closeFirewall()
    {
        String imageFilename = getImageFilename();
        setProfile();
        INetFwAuthorizedApplications apps = fwProfile.AuthorizedApplications;
        apps.Remove( imageFilename );
        apps = null;
        INetFwOpenPorts ports = fwProfile.GloballyOpenPorts;
        ports.Remove( discoPorts[ 0 ], NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_UDP );
        ports.Remove( discoPorts[ 1 ], NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_UDP );
        ports = null;
    }

    protected string getImageFilename()
    {
        // Get install directory from the registry
        RegistryKey pRegKey = Registry.LocalMachine;
        pRegKey = pRegKey.OpenSubKey( "SOFTWARE\\Company Directory\\AppDir" );
        Object insDir = pRegKey.GetValue( "InstallDir" );
        return insDir + "RVP.exe";
    }

    protected void setProfile()
    {
        // Access INetFwMgr
        INetFwMgr fwMgr = ( INetFwMgr ) getInstance( "INetFwMgr" );
        INetFwPolicy fwPolicy = fwMgr.LocalPolicy;
        fwProfile = fwPolicy.CurrentProfile;
        fwMgr = null;
        fwPolicy = null;
    }

    protected Object getInstance( String typeName )
    {
        if( typeName == "INetFwMgr" )
        {
            Type type = Type.GetTypeFromCLSID(
            new Guid( "{304CE942-6E39-40D8-943A-B913C40C9CD4}" ) );
            return Activator.CreateInstance( type );
        }
        else if( typeName == "INetAuthApp" )
        {
            Type type = Type.GetTypeFromCLSID(
            new Guid( "{EC9846B3-2762-4A6B-A214-6ACB603462D2}" ) );
            return Activator.CreateInstance( type );
        }
        else if( typeName == "INetOpenPort" )
        {
            Type type = Type.GetTypeFromCLSID(
            new Guid( "{0CA545C6-37AD-4A6C-BF92-9F7610067EF5}" ) );
            return Activator.CreateInstance( type );
        }
        else return null;
    }

    static void Main( string[] args )
    {
        Firewall fw = new Firewall();
        fw.openFirewall();
        fw.closeFirewall();
    }
}
}

Once compiled, you're ready to test. Set a breakpoint on each of the firewall entry methods - openFirewall() and closeFirewall(), and step through the program. Use a DOS box to verify the operations. The netsh firewall command will verify the operation of the code:

  • netsh fire show allowed - shows the programs that are allowed
  • netsh fire show port - shows the ports that are open

Acknowledgements

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Don Hamson

Web Developer

United States United States

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralNetFwAuthorizedApplications type Pinmembertriplebit6:10 25 Sep '09  
GeneralRe: NetFwAuthorizedApplications type PinmemberDonsw10:36 27 Oct '09  
Generalgood for xp PinmemberDonsw7:00 18 Sep '09  
QuestionDoes it work on vista? PinmemberDavid Engler10:10 29 May '08  
AnswerRe: Does it work on vista? PinmemberJmgxu3:57 21 Dec '08  
GeneralHelp anybody - very peculiar bug PinmemberDave Midgley8:13 28 Nov '07  
GeneralRe: Help anybody - very peculiar bug [modified] PinmemberDon Hamson23:31 28 Nov '07  
GeneralSetting things back to null PinmemberDave Midgley7:16 28 Nov '07  
GeneralRe: Setting things back to null PinmemberDon Hamson22:33 28 Nov '07  
GeneralError checking PinmemberDave Midgley5:40 26 Nov '07  
AnswerRe: Error checking PinmemberDon Hamson16:51 26 Nov '07  
GeneralRe: Error checking PinmemberDave Midgley7:14 28 Nov '07  
GeneralRe: Error checking PinmemberDon Hamson22:19 28 Nov '07  
Questionnecessary privs PinmemberAleRanza5:11 25 May '07  
AnswerRe: necessary privs PinmemberDon Hamson13:48 25 May '07  
GeneralA different way of doing things PinmemberYiogi5:04 11 Jan '07  
I have converted your code to a class, so that someone can actually use it in an application from any point in the code the programmer considers suitable. I have separated the open and close ports and made the class take as parameters the application location to open as well as what ports need to be opened. As I believe some users might find it useful, I'm posting the code below. Great article by the way.
 

 
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using NetFwTypeLib;
using Microsoft.Win32;
 
namespace FWSetupAction {
public class Firewall {
protected INetFwProfile fwProfile;
 
#region openFirewall
///
/// Opens the given ports on windows firewall. Also opens entirely the given application on the firewall.
/// Please remember that you need administrative rights to use this function.
///

/// The path of the application. Please include the ending \
/// The name of the executable to open
/// The ports that you wish to open individually
public void openFirewall(string filePath, string applicationName, int[] portsToOpen) {
///////////// Firewall Authorize Application ////////////
String imageFilename = filePath + applicationName;
setProfile();
INetFwAuthorizedApplications apps = fwProfile.AuthorizedApplications;
INetFwAuthorizedApplication app = (INetFwAuthorizedApplication)getInstance("INetAuthApp");
app.Name = applicationName;
app.ProcessImageFileName = imageFilename;
apps.Add(app);
apps = null;
 
//////////////// Open Needed Ports /////////////////
INetFwOpenPorts openports = fwProfile.GloballyOpenPorts;
foreach (int port in portsToOpen) {
INetFwOpenPort openport = (INetFwOpenPort)getInstance("INetOpenPort");
openport.Port = port;
openport.Protocol = NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP;
openport.Name = applicationName + " Operation Port (" + port.ToString() + ")";
openports.Add(openport);
}
openports = null;
}
#endregion // openFirewall
 
#region closeFirewall
///
/// Deletes the firewall ports specified from the windows firewall exclusions list. Also deletes
/// the given application from the excluded apps.
///

/// The path of the application. Please include the ending \
/// The name of the executable to close
/// The ports that you wish to close individually
public void closeFirewall(string filePath, string applicationName, int[] portsToClose) {
String imageFilename = filePath + applicationName;
setProfile();
INetFwAuthorizedApplications apps = fwProfile.AuthorizedApplications;
apps.Remove(imageFilename);
apps = null;
INetFwOpenPorts ports = fwProfile.GloballyOpenPorts;
foreach (int port in portsToClose) {
ports.Remove(port, NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP);
}
ports = null;
}
#endregion
 
#region setProfile
protected void setProfile() {
// Access INetFwMgr
INetFwMgr fwMgr = (INetFwMgr)getInstance("INetFwMgr");
INetFwPolicy fwPolicy = fwMgr.LocalPolicy;
fwProfile = fwPolicy.CurrentProfile;
fwMgr = null;
fwPolicy = null;
}
#endregion
 
#region getInstance
protected Object getInstance(String typeName) {
if (typeName == "INetFwMgr") {
Type type = Type.GetTypeFromCLSID(
new Guid("{304CE942-6E39-40D8-943A-B913C40C9CD4}"));
return Activator.CreateInstance(type);
}
else if (typeName == "INetAuthApp") {
Type type = Type.GetTypeFromCLSID(
new Guid("{EC9846B3-2762-4A6B-A214-6ACB603462D2}"));
return Activator.CreateInstance(type);
}
else if (typeName == "INetOpenPort") {
Type type = Type.GetTypeFromCLSID(
new Guid("{0CA545C6-37AD-4A6C-BF92-9F7610067EF5}"));
return Activator.CreateInstance(type);
}
else return null;
}
#endregion
 
#region OpenFirewallPorts
///
/// Opens the given ports on windows firewall. Also opens entirely the given application on the firewall.
/// Please remember that you need administrative rights to use this function.
///

/// The path of the application. Please include the ending \
/// The name of the executable to open
/// The ports that you wish to open individually
public static void OpenFirewallPorts(string executableFilePath, string applicationName, int[] portsToOpen) {
Firewall fw = new Firewall();
fw.openFirewall(executableFilePath, applicationName, portsToOpen);
}
#endregion
 
#region CloseFirewallPorts
///
/// Deletes the firewall ports specified from the windows firewall exclusions list. Also deletes
/// the given application from the excluded apps.
///

/// The path of the application. Please include the ending \
/// The name of the executable to close
/// The ports that you wish to close individually
public static void CloseFirewallPorts(string executableFilePath, string applicationName, int[] portsToClose) {
Firewall fw = new Firewall();
fw.closeFirewall(executableFilePath, applicationName, portsToClose);
}
#endregion
}
}

GeneralRe: A different way of doing things Pinmembershysan2:29 24 Apr '07  
Generalsecurity caveat Pinmemberkckn4fun2:03 26 Jul '06  
GeneralRe: security caveat PinmemberDon Hamson8:34 26 Jul '06  
GeneralRe: security caveat Pinmembertverweij21:17 26 Jul '06  
GeneralRe: security caveat [modified] PinmemberDon Hamson3:36 27 Jul '06  
GeneralRe: security caveat PinmemberJason Barry13:20 26 Jun '08  
GeneralThis is not a feature, but a security leak [modified] Pinmembertverweij7:04 25 Jul '06  
GeneralRe: This is not a feature, but a security leak PinmemberDon Hamson1:36 26 Jul '06  
GeneralRe: This is not a feature, but a security leak Pinmembertverweij21:20 26 Jul '06  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120529.1 | Last Updated 23 Jul 2006
Article Copyright 2006 by Don Hamson
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid