如何使用Windows防火墙API为Store应用程序设置规则?

时间:2015-10-23 10:32:59

标签: c# .net com windows-firewall windows-firewall-api

所以我已经非常了解如何使用INetFwPolicy2INetFwRule COM接口以编程方式设置防火墙规则。但是,如何使用COM interop为特定的“Modern App”/“Metro App”/“Store App”设置规则?

如果我使用防火墙MMC,我可以去:

  

规则 - >属性 - >计划和服务 - >应用程序包

并允许/阻止指定的包。但我不知道如何在代码中执行此操作。我找到了提供INetFwRule3属性的LocalAppPackageId接口,这就是我认为所有的魔力。但是LocalAppPackageId包含包的SID,而不是像microsoft.windows.photos_8wekyb3d8bbwe这样的名称。那么,当我所知道的是它的名字时,我怎么能阻止我想要的包裹呢?我想我必须得到SID,所以我该如何找到它? SID的范围是本地的(每台机器是唯一的),或者我可以在找到SID后对其进行硬编码,而不是动态查找SID吗?

1 个答案:

答案 0 :(得分:1)

可以使用NetworkIsolationEnumAppContainersConvertSidToStringSid API找到应用容器的SID。这是他们Fiddler does中的AppContainer Loopback Exemption Utility(这就是我找到API的方式)。

如果您只关心SID而不关心其他任何事情,那么使用DeriveAppContainerSidFromAppContainerName / ConvertSidToStringSid组合会更容易。您甚至不必使用ConvertSidToStringSid,.NET框架已经提供了转换:

private static string SidToString(IntPtr sid)
{
    return new SecurityIdentifier(sid).Value;
}

奇怪的是,DeriveAppContainerSidFromAppContainerName没有检查系统上是否存在应用程序容器,它似乎只是接受你抛出的任何输入并仅从该信息生成SID(如散列函数)。

完整的代码:

public static string AppContainerNameToSid(string appContainerName)
{
    var sid = IntPtr.Zero;
    try
    {
        if (DeriveAppContainerSidFromAppContainerName(appContainerName, out sid) == 0)
            return new SecurityIdentifier(sid).Value;
        else
            return null;
    }
    finally
    {
        if (sid != IntPtr.Zero)
            FreeSid(sid);
    }
}

[DllImport("userenv.dll", SetLastError = false, CharSet = CharSet.Unicode)]
private static extern int DeriveAppContainerSidFromAppContainerName(string appContainerName, out IntPtr sid);

[DllImport("advapi32.dll", SetLastError = false)]
private static extern IntPtr FreeSid(IntPtr sid);