← Back to overview
May 20, 2010 · Dynamic Windows Firewall

The 'dynamic' keyword for higher productivity: Windows Firewall API example


The .NET 4.0 framework introduces a new keyword, dynamic. On MSDN the dynamic keyword is described as follows:

The type is a static type, but an object of type dynamic bypasses static type checking. In most cases, it functions like it has type object. At compile time, an element that is typed as dynamic is assumed to support any operation. Therefore, you do not have to be concerned about whether the object gets its value from a COM API, from a dynamic language such as IronPython, from the HTML Document Object Model (DOM), from reflection, or from somewhere else in the program. However, if the code is not valid, errors are caught at run time.

Scott has a great post on the dynamic keyword with a few good examples: http://www.hanselman.com/blog/C4AndTheDynamicKeywordWhirlwindTourAroundNET4AndVisualStudio2010Beta1.aspx

In short you can write anything you want for dynamic objects and your application will always compile. What you wrote will be evaluated at run time.

How it was

For one of my projects I was required to add exceptions in the Windows Firewall. MSDN did provide me with some examples of how to do this: http://msdn.microsoft.com/en-us/library/aa366415(v=VS.85).aspx The downside: These examples only cover C/C++/VBscript.


Ah yes, VBscript. Look at this script to handle the Windows Firewall API:

' Create the firewall manager object.  
Dim fwMgr  
Set fwMgr = CreateObject("HNetCfg.FwMgr")

' Get the current profile for the local firewall policy.  
Dim profile  
Set profile = fwMgr.LocalPolicy.CurrentProfile  

That’s it, easy. No references, no mapping with COM objects…
You just look at the MSDN reference and you write the code. That’s being productive.

But I don’t say that this is perfect. The downside of this is that you are missing the strength of the compiler.
If you would make an error and write LocalLopicy instead of LocalPolicy well you’d only find out when running that line of code.


    HRESULT hr = S_OK;
    INetFwMgr* fwMgr = NULL;
    INetFwPolicy* fwPolicy = NULL;

    _ASSERT(fwProfile != NULL);

    *fwProfile = NULL;

    // Create an instance of the firewall settings manager.
    hr = CoCreateInstance(
    if (FAILED(hr))
        printf("CoCreateInstance failed: 0x%08lx\n", hr);
        goto error;

    // Retrieve the local firewall policy.
    hr = fwMgr->get_LocalPolicy(&fwPolicy);
    if (FAILED(hr))
        printf("get_LocalPolicy failed: 0x%08lx\n", hr);
        goto error;

    // Retrieve the firewall profile currently in effect.
    hr = fwPolicy->get_CurrentProfile(fwProfile);
    if (FAILED(hr))
        printf("get_CurrentProfile failed: 0x%08lx\n", hr);
        goto error;

Having to write that much code is not productive… enough said.

C# with ComImport

Jon Cole wrote a nice article on using ComImport in C# to talk to the Windows Firewall API:

 [ComImport, ComVisible(false), Guid("F7898AF5-CAC4-4632-A2EC-DA06E5111AF2"), System.Runtime.InteropServices.InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
 public interface INetFwMgr
    INetFwPolicy LocalPolicy { get; }
    FirewallProfileType CurrentProfileType { get; }

    void RestoreDefaults();
    void IsPortAllowed(string imageFileName, IPVersion ipVersion, long portNumber, string localAddress, IPProtocol ipProtocol, [Out] out bool allowed, [Out] out bool restricted);
    void IsIcmpTypeAllowed(IPVersion ipVersion, string localAddress, byte type, [Out] out bool allowed, [Out] out bool restricted);

For me this is a semi-clean solution. But it involves a lot of trial and error but also research…
And it’s a lot of code too…

How it is since .NET 4.0

This dynamic keyword can be put to good use when doing COM. And in turn you could be more productive when you need to complete tasks regarding the Windows API (that expose COM functionality).
Now I can access COM objects as if I was working in VBscript:

 Type fwMgrType = Type.GetTypeFromProgID("HNetCfg.FwMgr");
 dynamic fwMgr = Activator.CreateInstance(fwMgrType);

 bool isFwEnabled = fwMgr.LocalPolicy.CurrentProfile.FirewallEnabled;

How it works:

This gives you the possibility to just take existing VBScript code, modify it a bit and you’ll have compilable .NET code.
All those things that were easy to do in VBScript are now easy to do in .NET

And with the modern unit testing tools of today I think the missing compiler support isn’t such a big issue after all.

Windows Firewall API using ‘dynamic’

And now for our example. I’ve written some classes that implement a few interesting parts of the Windows Firewall API.
To be honest I only tested this on my local machine (Windows Server 2008 R2) so please let me know if you encounter any issues while using the code.

I’ve done 3 things:

Mapping the enums

 /// <summary>
 /// Msdn reference: http://msdn.microsoft.com/en-us/library/aa366282(v=VS.85).aspx
 /// </summary>
 public enum NetFwAction
    Block = 0,
    Allow = 1,
    Max = 2

Nothing fancy about this. This is just a mapping with the information found on MSDN.
Current enums:

Mapping the objects

I also needed the following objects: NetFwAuthorizedApplication and NetFwRule.

First I tried it like this:

 /// <summary>
 /// Msdn reference: http://msdn.microsoft.com/en-us/library/aa365100(v=VS.85).aspx
 /// </summary>
 public class NetFwAuthorizedApplication

    /// <summary>
    /// Initialize the application object.
    /// </summary>
    /// <param name="comObj"></param>
    internal NetFwAuthorizedApplication(dynamic comObj)
        this.Name = comObj.Name;
        this.RemoteAddress = comObj.RemoteAddress;
        this.Enabled = comObj.Enabled;

Again this shows the power of the dynamic keyword. Just by looking at the reference (http://msdn.microsoft.com/en-us/library/aa365100(v=VS.85).aspx) I can access the properties without any extra code.
If I want the RemoteAddress of the object I just write comObj.RemoteAddress.

For me this is a clean solution but maybe too much work. If we have to do the mapping for each new object we want this is not so productive.
That’s why I also wrote a base class that handles the mapping automatically. It uses reflection so you might get a (small) performance hit doing it this way.

public class DynamicComMapper  
    /// <summary>
    /// Map all the properties of the object to the properties of the COM object.
    /// </summary>
    /// <param name="comObj"></param>
    protected void Map(dynamic comObj)
        foreach (PropertyInfo property in this.GetType().GetProperties())
                // Retrieve the value of a property of the COM object.
                object comPropertyValue = typeof(Object).InvokeMember(property.Name, BindingFlags.GetProperty, null, comObj, null);

                // Set value in our managed object.
                property.SetValue(this, comPropertyValue, null);
            catch (COMException)
                // You could skip errors for unknown properties.
                // if (ex.ErrorCode != -2147352570)
                //    throw ex;

This base class for "object mappings" tries to get the value from the COM object’s property matching our current object’s property.
Meaning, all properties of my NetFwAuthorizedApplication object will be populated automatically.

Creating the worker classes

Since we’re working with COM we also have to think about cleaning up resources. That’s why we’ll use the DynamicComBase as base class for our worker classes.
This class implements IDisposable for cleaning up things automatically (since the dynamic object comObj is included in this base class).

It also provides functionality to clean up temporary COM objects that will be used in our "mapped objects".

 /// <summary>
 /// Release a COM object so that it can be cleaned up.
 /// </summary>
 /// <param name="comObj"></param>
 protected void ReleaseCom(dynamic comObj)

 /// <summary>
 /// Clean up all released COM objects.
 /// </summary>
 protected void CleanAllReleased()

Now that we have a base class, we can create the NetFwMgr:

public class NetFwMgr : DynamicComBase  
    /// <summary>
    /// Default constructor.
    /// </summary>
    public NetFwMgr()
        // Initialize the COM object.
        Type fwMgrType = Type.GetTypeFromProgID("HNetCfg.FwMgr");
        base.comObj = Activator.CreateInstance(fwMgrType);

    /// <summary>
    /// Set the port in the firewall.
    /// </summary>
    /// <param name="profile"></param>
    /// <param name="name"></param>
    /// <param name="protocol"></param>
    /// <param name="port"></param>
    /// <param name="scope"></param>
    /// <param name="enabled"></param>
    public void SetPort(NetFwProfile profile, string name, NetFwIpProtocol protocol, int port, NetFwScope scope, bool enabled)
        if (profile == NetFwProfile.All)
            throw new ArgumentException("The profile 'All' is not allowed here.");

        // Create a port object.
        Type fwPortType = Type.GetTypeFromProgID("HNetCfg.FwOpenPort");
        dynamic fwPort = Activator.CreateInstance(fwPortType);

        // Configure the port.
        fwPort.Name = name;
        fwPort.Protocol = (int)protocol;
        fwPort.Port = port;
        fwPort.Scope = (int)scope;
        fwPort.Enabled = enabled;

        // Add to profile.

    /// <summary>
    /// Verify if the firewall is enabled.
    /// Note, this will fail if the service is stopped.
    /// </summary>
    public bool IsEnabled
            return comObj.LocalPolicy.CurrentProfile.FirewallEnabled;

    /// <summary>
    /// Get a list of authorized applications.
    /// </summary>
    public List<NetFwAuthorizedApplication> GetAuthorizedApplications()
        // Create a new list.
        List<NetFwAuthorizedApplication> applications = new List<NetFwAuthorizedApplication>();

        // Get all applications and create typed objects.
        foreach (dynamic application in comObj.LocalPolicy.CurrentProfile.AuthorizedApplications)
            applications.Add(new NetFwAuthorizedApplication(application));

            // Clean current COM object.

        // Clean up all released COM objects.

        // Done.
        return applications;

How does this class work?

The project also includes a test application that uses the classes and this is the result:

What’s next?

Currently the classes I’ve written allow you to:

But actually I’ve done nothing more than just modify the existing VBScript examples available on MSDN: http://msdn.microsoft.com/en-us/library/aa366415(v=VS.85).aspx
Using the base classes you can easly add your own code to handle other common tasks, and you can start by looking at VBScript code.

On the other hand you can also use these base classes to ‘port’ other VBScripts to .NET.
Just take a look here http://gallery.technet.microsoft.com/ScriptCenter/en-usand you’ll be able to access things like Backups, Windows Update, … in no time.

The only thing not to forget is writing unit tests! Sincewe don’t havehelp from the compiler for tracing errors in dynamic objects our unit tests are the only line of defence…

I hope this article showed you a few of the strengths of the new dynamic keyword and you’ll start using it too..

Download: Sandrino.WindowsFirewallApi.zip (31.51 kb)


  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket
Comments powered by Disqus