Click here to Skip to main content
15,439,973 members
Articles / Web Development / ASP.NET
Article
Posted 23 Jul 2006

Stats

110.6K views
38 bookmarked

Open Windows Firewall During Installation

Rate me:
Please Sign up or sign in to vote.
4.13/5 (8 votes)
23 Jul 2006CPOL2 min read
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:

C#
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)


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralNetFwAuthorizedApplications type Pin
triplebit25-Sep-09 6:10
Membertriplebit25-Sep-09 6:10 
GeneralRe: NetFwAuthorizedApplications type Pin
Donsw27-Oct-09 10:36
MemberDonsw27-Oct-09 10:36 
Generalgood for xp Pin
Donsw18-Sep-09 7:00
MemberDonsw18-Sep-09 7:00 
QuestionDoes it work on vista? Pin
David Engler29-May-08 10:10
MemberDavid Engler29-May-08 10:10 
AnswerRe: Does it work on vista? Pin
Jmgxu21-Dec-08 3:57
MemberJmgxu21-Dec-08 3:57 
GeneralHelp anybody - very peculiar bug Pin
Dave Midgley28-Nov-07 8:13
MemberDave Midgley28-Nov-07 8:13 
GeneralRe: Help anybody - very peculiar bug [modified] Pin
Don Hamson28-Nov-07 23:31
MemberDon Hamson28-Nov-07 23:31 
Issues with an "Installer class" vs. a normal application introduces many considerations that are very different from the core code in the example. When your Installer class executes, it's within the context of Microsoft's installer - msiexec which is a database and functionality combined to perform MS sanctified installations. They consider the authority to perform these operations, the ability to rollback operations; acceptability based on the concept of advertised functionality, etc.

To be honest, I did get the example to work as an installer class when I first developed it using msiexec installing for Administrators as an Administrator; however for needing to install my application for unpriviledged users there were many msiexec context issues that I didn't have time to work through and ended up not using msiexec.

For downloading some Google software, I noticed that they used the NSIS installer http://nsis.sourceforge.net/Main_Page. It's Windows specific, easy to learn and use, allows rebranding, looks very professional; and your executables behave like normal applications; ie you probably won't get the class cast exception running under NSIS.

It could be too that Microsoft views this functionality as a security hole as mentioned in a previous thread and so the cast exception is intentional; or the underlying functionality may have changed and the example now has a bug. For me, I wasn't interested in becoming an install expert and soon reached diminishing returns with msiexec issues. I just needed my app installed as a priviledged app with those needed ports open.

-- modified at 5:36 Thursday 29th November, 2007

Don

GeneralSetting things back to null Pin
Dave Midgley28-Nov-07 7:16
MemberDave Midgley28-Nov-07 7:16 
GeneralRe: Setting things back to null Pin
Don Hamson28-Nov-07 22:33
MemberDon Hamson28-Nov-07 22:33 
GeneralError checking Pin
Dave Midgley26-Nov-07 5:40
MemberDave Midgley26-Nov-07 5:40 
AnswerRe: Error checking Pin
Don Hamson26-Nov-07 16:51
MemberDon Hamson26-Nov-07 16:51 
GeneralRe: Error checking Pin
Dave Midgley28-Nov-07 7:14
MemberDave Midgley28-Nov-07 7:14 
GeneralRe: Error checking Pin
Don Hamson28-Nov-07 22:19
MemberDon Hamson28-Nov-07 22:19 
Questionnecessary privs Pin
AleRanza25-May-07 5:11
MemberAleRanza25-May-07 5:11 
AnswerRe: necessary privs Pin
Don Hamson25-May-07 13:48
MemberDon Hamson25-May-07 13:48 
GeneralA different way of doing things Pin
Yiogi11-Jan-07 5:04
MemberYiogi11-Jan-07 5:04 
GeneralRe: A different way of doing things Pin
shysan24-Apr-07 2:29
Membershysan24-Apr-07 2:29 
Generalsecurity caveat Pin
kckn4fun26-Jul-06 2:03
Memberkckn4fun26-Jul-06 2:03 
GeneralRe: security caveat Pin
Don Hamson26-Jul-06 8:34
MemberDon Hamson26-Jul-06 8:34 
GeneralRe: security caveat Pin
tverweij26-Jul-06 21:17
Membertverweij26-Jul-06 21:17 
GeneralRe: security caveat [modified] Pin
Don Hamson27-Jul-06 3:36
MemberDon Hamson27-Jul-06 3:36 
GeneralRe: security caveat Pin
Jason Barry26-Jun-08 13:20
professionalJason Barry26-Jun-08 13:20 
GeneralThis is not a feature, but a security leak [modified] Pin
tverweij25-Jul-06 7:04
Membertverweij25-Jul-06 7:04 
GeneralRe: This is not a feature, but a security leak Pin
Don Hamson26-Jul-06 1:36
MemberDon Hamson26-Jul-06 1:36 
GeneralRe: This is not a feature, but a security leak Pin
tverweij26-Jul-06 21:20
Membertverweij26-Jul-06 21:20 

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

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