小鱼塘--自说自话的地方

  • 小玩意
  • 小想法
记录自己技术和想法地方
  1. 首页
  2. win32
  3. 正文

vc++ 增加防火墙规则

27 3 月, 2023 1265点热度 0人点赞 0条评论
内容目录

背景

最近给自己一个手机协作软件增加防火墙规则(一直准备发布出来,但感觉写不够完善就一直拖着),于是找了一些网上资料,我感觉资料真的比较少,后面找到微软demo代码,直接copy稍微改了给自己用。

资料

Exercising the Firewall using C++ (Windows) | Microsoft Learn
微软官方代码页,我感觉这个没有下面demo好

Windows-classic-samples/FirewallConfig.cpp at main · microsoft/Windows-classic-samples (github.com)
这个直接demo代码,直接复制firewallConfig.cpp、firewallConfig.h 2个文件就可以了

代码

//这个是关键函数,这个fOpenPortForPNRP 代表是否开启PNRP 端口,这个函数我们改掉,
//我懒的复制我自己工程的代码,直接说明
HRESULT OpenFirewallForDrtSdkSample(BOOL fOpenPortForPNRP)
{
    HRESULT hr = S_OK;
    HRESULT hrComInitialized = S_OK;
    INetFwProfile *fwProfile = NULL;
    WCHAR lpFilename[1024];
    BOOL fFirewallOn = FALSE;

    // Initialize COM.
    hr = CoInitializeEx(
                0,
                COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE
                );

    // Ignore RPC_E_CHANGED_MODE. Since we don't care what the mode is,
    // we'll just use the existing mode.
    hrComInitialized = hr;
    if (hr != RPC_E_CHANGED_MODE)
    {
        if (FAILED(hr))
        {
            printf("CoInitializeEx failed: 0x%08lx\n", hr);
            goto error;
        }
    }

    WindowsFirewallInitialize(&fwProfile);
    if (FAILED(hr))
    {
        printf("WindowsFirewallInitialize failed: 0x%08lx\n", hr);
        goto error;
    }

    hr = WindowsFirewallIsOn(fwProfile, &fFirewallOn);
    if (FAILED(hr))
    {
        printf("WindowsFirewallIsOn failed: 0x%08lx\n", hr);
        goto error;
    }

    if(fFirewallOn)
    {
        hr = GetModuleFileName(
                NULL,
                lpFilename,
                1024);
        if (FAILED(hr))
        {
            printf("GetModuleFileName failed: 0x%08lx\n", hr);
            goto error;
        }

        // Add DrtSdkSample to the authorized application collection.
        hr = WindowsFirewallAddApp(
                fwProfile,
                lpFilename,
                L"DrtSdkSample"//这个是规则名字,这个代表全规则
                );
        if (FAILED(hr))
        {
            printf("WindowsFirewallAddApp failed: 0x%08lx\n", hr);
            goto error;
        }

        if(fOpenPortForPNRP)
        {
            // Add PNRP Port to list of globally open ports.
            //这个增加指定端口,这里是3540 udp协议
            hr = WindowsFirewallPortAdd(fwProfile, 3540, NET_FW_IP_PROTOCOL_UDP, L"PNRP");
            if (FAILED(hr))
            {
                printf("WindowsFirewallPortAdd failed: 0x%08lx\n", hr);
                goto error;
            }
        }   

    }

error:

    // Release the firewall profile.
    WindowsFirewallCleanup(fwProfile);

    // Uninitialize COM.
    if (SUCCEEDED(hrComInitialized))
    {
        CoUninitialize();
    }

    return hr;
}
  1. CoInitializeEx 初始化com ,因为他用com接口的API
  2. 判断防火墙是否打开
  3. 如果打开增加 应用程序规则(匹配指定软件指定路径,不管什么协议全部放开) WindowsFirewallAddApp
  4. 增加指定端口开发,跟程序没有直接关系 WindowsFirewallPortAdd
        // Add DrtSdkSample to the authorized application collection.
        hr = WindowsFirewallAddApp(
                fwProfile,
                lpFilename,
                L"DrtSdkSample"//这个是规则名字,这个代表全规则
                );

规则的名字,指定程序已经存在,那么规则不会生效,我开始测试以后没有生效,后面发现是我以前手动填写指定程序规则。

这个对应控制面板防火墙界面
file

指定端口类似下面规则
hr = WindowsFirewallPortAdd(fwProfile, 3540, NET_FW_IP_PROTOCOL_UDP, L"PNRP");
file

图片和代码不一样,因为我手动删除了,我随便找一条规则。

补充

如果不用代码,可以考虑创建进程然后执行防火墙命令进行增加,我只是觉得这样子卡顿一样不好。

如果不添加规则,如果软件监听端口,可能无法访问。

好久没有写博客了,最近太多事情了,主要写在自己笔记里面,我只能说obsidian 加 wps同步yyds..

标签: 暂无
最后更新:27 3 月, 2023

小鱼儿

爱研究技术,爱玩LOL

点赞
< 上一篇
下一篇 >

COPYRIGHT © 2022 小鱼塘. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

湘ICP备18005349号