Working with Multiple Profiles

This example shows how to perform several tasks using the Windows Firewall with Advanced Security APIs.

 /*
    Copyright (C) Microsoft. All rights reserved.

    SYNOPSIS

        Sample code for 'Windows Firewall with Advanced Security' COM interfaces.

        Illustrates correct usage of following methods/properties of INetFwPolicy2 COM interface
        in the presence of multiple firewall profiles:
          - CurrentProfileTypes
          - IsRuleGroupCurrentlyEnabled
          - IsRuleGroupEnabled
          - LocalPolicyModifyState
*/


#include <windows.h>
#include <stdio.h>
#include <netfw.h>

#pragma comment( lib, "ole32.lib" )
#pragma comment( lib, "oleaut32.lib" )

// Forward declarations
HRESULT    WFCOMInitialize(INetFwPolicy2** ppNetFwPolicy2);
void       WFCOMCleanup(INetFwPolicy2* pNetFwPolicy2);
HRESULT    GetCurrentFirewallState(__in INetFwPolicy2 *pNetFwPolicy2);
HRESULT    IsRuleGroupEnabled(__in INetFwPolicy2 *pNetFwPolicy2);
HRESULT    IsRuleGroupCurrentlyEnabled(__in INetFwPolicy2 *pNetFwPolicy2);
HRESULT    GetLocalPolicyModifyState(__in INetFwPolicy2 *pNetFwPolicy2);


int __cdecl wmain()
{
    HRESULT hrComInit = S_OK;
    HRESULT hr = S_OK;
    INetFwPolicy2 *pNetFwPolicy2 = NULL;

    // Initialize COM.
    hrComInit = CoInitializeEx(
                    0,
                    COINIT_APARTMENTTHREADED
                    );

    // Ignore RPC_E_CHANGED_MODE; this just means that COM has already been
    // initialized with a different mode. Since we don't care what the mode is,
    // we'll just use the existing mode.
    if (hrComInit != RPC_E_CHANGED_MODE)
    {
        if (FAILED(hrComInit))
        {
            wprintf(L"CoInitializeEx failed: 0x%08lx\n", hrComInit);
            goto Cleanup;
        }
    }

    // Retrieve INetFwPolicy2
    hr = WFCOMInitialize(&amp;pNetFwPolicy2);
    if (FAILED(hr))
    {
        goto Cleanup;
    }

    // Show Firewall ON/OFF state on current profiles
    GetCurrentFirewallState(pNetFwPolicy2);

    // Show status of 'File and Printer Sharing' rule group on current profiles
    IsRuleGroupCurrentlyEnabled(pNetFwPolicy2);

    // Show status of 'File and Printer Sharing' rule group on specified profiles
    IsRuleGroupEnabled(pNetFwPolicy2);

    // For the current firewall profiles display whether the changes to firewall rules 
    //  will take effect or not
    GetLocalPolicyModifyState(pNetFwPolicy2);

Cleanup:

    // Release INetFwPolicy2
    WFCOMCleanup(pNetFwPolicy2);

    // Uninitialize COM.
    if (SUCCEEDED(hrComInit))
    {
        CoUninitialize();
    }
   
    return 0;
}


// Instantiate INetFwPolicy2
HRESULT WFCOMInitialize(INetFwPolicy2** ppNetFwPolicy2)
{
    HRESULT hr = S_OK;

    hr = CoCreateInstance(
        __uuidof(NetFwPolicy2), 
        NULL, 
        CLSCTX_INPROC_SERVER, 
        __uuidof(INetFwPolicy2), 
        (void**)ppNetFwPolicy2);

    if (FAILED(hr))
    {
        wprintf(L"CoCreateInstance for INetFwPolicy2 failed: 0x%08lx\n", hr);
        goto Cleanup;        
    }

Cleanup:
    return hr;
}


// Release INetFwPolicy2
void WFCOMCleanup(INetFwPolicy2* pNetFwPolicy2)
{
    // Release the INetFwPolicy2 object (Vista+)
    if (pNetFwPolicy2 != NULL)
    {
        pNetFwPolicy2->Release();
    }
}


// For the currently active firewall profiles display whether firewall is ON or OFF
HRESULT GetCurrentFirewallState(__in INetFwPolicy2 *pNetFwPolicy2)
{
    HRESULT hr = S_FALSE;
    long    CurrentProfilesBitMask = 0;
    VARIANT_BOOL bActualFirewallEnabled = VARIANT_FALSE;
    struct ProfileMapElement 
    {
        NET_FW_PROFILE_TYPE2 Id;
        LPCWSTR Name;
    };
    ProfileMapElement ProfileMap[3];
    ProfileMap[0].Id = NET_FW_PROFILE2_DOMAIN;
    ProfileMap[0].Name = L"Domain";
    ProfileMap[1].Id = NET_FW_PROFILE2_PRIVATE;
    ProfileMap[1].Name = L"Private";
    ProfileMap[2].Id = NET_FW_PROFILE2_PUBLIC;
    ProfileMap[2].Name = L"Public";

    wprintf(L"\n\nCurrent Firewall State:\n");
    wprintf(L"-----------------------\n");

    hr = pNetFwPolicy2->get_CurrentProfileTypes(&amp;CurrentProfilesBitMask);
    if (FAILED(hr))
    {
        wprintf(L"Failed to get CurrentProfileTypes. Error: %x.\n", hr);
        goto CLEANUP;
    }

    // The returned 'CurrentProfiles' bitmask can have more than 1 bit set if multiple profiles 
    //   are active or current at the same time

    for (int i=0; i<3; i++)
    {
        if ( CurrentProfilesBitMask & ProfileMap[i].Id  )
        {
            /*Is Firewall Enabled?*/
            hr = pNetFwPolicy2->get_FirewallEnabled(ProfileMap[i].Id, &amp;bActualFirewallEnabled);
            if (FAILED(hr))
            {
                wprintf(L"Failed to get FirewallEnabled settings for %s profile. Error: %x.\n", ProfileMap[i].Name, hr);
                goto CLEANUP;
            }
            wprintf(L"On %s profile (Current) : Firewall state is %s\n", ProfileMap[i].Name, (bActualFirewallEnabled ? L"ON" : L"OFF"));
        }
    }


CLEANUP:
    return hr;
}


// For the currently active firewall profiles display whether the rule group is enabled or not
HRESULT IsRuleGroupCurrentlyEnabled(__in INetFwPolicy2 *pNetFwPolicy2)
{
    HRESULT hr = S_OK;
    VARIANT_BOOL bActualEnabled = VARIANT_FALSE;

    BSTR GroupName = SysAllocString(L"File and Printer Sharing");

    wprintf(L"\n\nIs 'File and Printer Sharing' rule group currently enabled ?\n");
    wprintf(L"------------------------------------------------------------\n");


    hr = pNetFwPolicy2->get_IsRuleGroupCurrentlyEnabled(GroupName, &amp;bActualEnabled);

    if ( SUCCEEDED(hr) )
    {
        if (VARIANT_TRUE == bActualEnabled &amp;&amp; S_OK == hr)
        {
            wprintf(L"Rule Group currently enabled on all the current profiles\n");
        }
        else if (VARIANT_TRUE == bActualEnabled &amp;&amp; S_FALSE == hr)
        {
            wprintf(L"Rule Group currently enabled on some of the current profiles but not on all the current profiles\n");
        }
        else if (VARIANT_FALSE == bActualEnabled)
        {
            wprintf(L"Rule Group Currently not enabled on any of the current profiles\n");
        }
    }
    else
    {  
        wprintf(L"Failed calling API IsRuleGroupCurrentlyEnabled. Error: 0x %x.\n", hr);
        goto Cleanup;
    }
    

Cleanup:
    SysFreeString(GroupName);
    return hr;
}


// For the specified firewall profiles display whether the rule group is enabled or not
HRESULT IsRuleGroupEnabled(__in INetFwPolicy2 *pNetFwPolicy2)
{
    HRESULT hr = S_OK;
    VARIANT_BOOL bActualEnabled = VARIANT_FALSE;

    BSTR GroupName = SysAllocString(L"File and Printer Sharing");

    wprintf(L"\n\nIs 'File and Printer Sharing' rule group enabled in public and private profiles ?\n");
    wprintf(L"---------------------------------------------------------------------------------\n");

    hr = pNetFwPolicy2->IsRuleGroupEnabled(NET_FW_PROFILE2_PRIVATE | NET_FW_PROFILE2_PUBLIC, GroupName, &amp;bActualEnabled);

    if ( SUCCEEDED(hr) )
    {
        if (VARIANT_TRUE == bActualEnabled &amp;&amp; S_OK == hr)
        {
            wprintf(L"Rule Group currently enabled on both public and private profiles\n");
        }
        else if (VARIANT_TRUE == bActualEnabled &amp;&amp; S_FALSE == hr)
        {
            wprintf(L"Rule Group currently enabled on either public or private profile but not both\n");
        }
        else if (VARIANT_FALSE == bActualEnabled)
        {
            wprintf(L"Rule Group currently disabled on both public and private profiles\n");
        }
    }
    else
    {  
        wprintf(L"Failed calling API IsRuleGroupCurrentlyEnabled. Error: 0x %x.\n", hr);
        goto Cleanup;
    }
    

Cleanup:
    SysFreeString(GroupName);
    return hr;
}


// For the currently active firewall profiles display whether the changes to firewall rules will take effect or not
HRESULT GetLocalPolicyModifyState(__in INetFwPolicy2 *pNetFwPolicy2)
{
    HRESULT hr;
    NET_FW_MODIFY_STATE modifystate;

    wprintf(L"\n\nWill changes to firewall rules take effect ?\n");
    wprintf(L"--------------------------------------------\n");

    hr = pNetFwPolicy2->get_LocalPolicyModifyState(&amp;modifystate);
    if (FAILED(hr))
    {
        wprintf(L"Failed calling API get_LocalPolicyModifyState. Error: %x.\n", hr);
        return hr;
    }

    if(modifystate == NET_FW_MODIFY_STATE_OK)
    {
        if (hr == S_OK)
        {
            wprintf(L"Changing or adding firewall rule (or group) to the current profiles will take effect on all current profiles.\n");
        }
        else if (hr == S_FALSE)
        {
            wprintf(L"Changing or adding firewall rule (or group) to the current profiles will take effect on only some current profiles but not all.\n");
        }
    }
    else if(modifystate == NET_FW_MODIFY_STATE_GP_OVERRIDE)
    {
        if (hr == S_OK)
        {
            wprintf(L"Changing or adding a firewall rule (or group) to the current profiles will not take effect because group policy overrides it on all current profiles.\n");
        }
        else if (hr == S_FALSE)
        {
            wprintf(L"Changing or adding a firewall rule (or group) to the current profiles will not take effect because group policy overrides it on some of the current profiles.\n");
        }
    }
    else if(modifystate == NET_FW_MODIFY_STATE_INBOUND_BLOCKED)
    {
        if (hr == S_OK)
        {
            wprintf(L"Changing or adding firewall rule (or group) to the current profiles will not take effect because unsolicited inbound traffic is not allowed on all the current profiles.\n");
        }
        else if (hr == S_FALSE)
        {
            wprintf(L"Changing or adding firewall rule (or group) to the current profiles will not take effect because unsolicited inbound traffic is not allowed on some of the current profiles.\n");
        }
    }
    
    return hr;
}