Windows防火墙编程学习

前言

最近在用户电脑上发现应用程序被防火墙拦截,不清楚为什么。研究下Windows防火墙,看看能不能通过编程手段,将应用程序的网络请求放开。

以下文章参考:Windows 防火墙技术

总体介绍

Windows防火墙技术迭代了四次,按照时间的顺序(由最新到最旧排序):

  1. 具有高级安全性的Windows防火墙
  2. Windows防火墙(适用于Service Pack2 Windows XP)
  3. IPv6 Internet 连接防火墙 (适用于Windows XP)
  4. Internet 连接共享和 Internet连接防火墙(适用于 Windows Vista,可能在后续版本不可用)

这么一看,我们只需要学习最新的具有高级安全性的Windows防火墙就可以了。因为名字太长了,以下简称安全防火墙。

安全防火墙总体概述

安全防火墙允许应用程序创建、启用和禁用防火墙,仅适用Windows Vista 及更高版本

封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#ifndef __WIN_FIRE_WALL__
#define __WIN_FIRE_WALL__
#include <windows.h>
#include <stdio.h>
#include <netfw.h>
#include <string>
class WinFireWall
{
public:
WinFireWall();
~WinFireWall();
public:
/* 添加入站出站规则 ,适用于所有规则 */
bool AddAllFireRule(const wchar_t* ruleName, const wchar_t* applicationPath);
bool HasFireRule(const wchar_t* ruleName);
bool DeleteFireRule(const wchar_t* ruleName);

std::wstring GetErrMsg();
protected:
bool Init();
bool Release();
bool CreateRule(const wchar_t* ruleName, const wchar_t* applicationPath, NET_FW_RULE_DIRECTION dir);

private:
bool init;
HRESULT hrComInit;
private:
INetFwPolicy2* pNetFwPolicy2; // 防火墙方案2
INetFwRules* pFwRules;//防火墙规则集合
std::wstring errMsg;
};

#endif // !__WIN_FIRE_WALL__
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include "WinFireWall.h"
#pragma comment( lib, "ole32.lib" )
#pragma comment( lib, "oleaut32.lib" )

WinFireWall::WinFireWall()
{
init = false;
hrComInit = 0;

pNetFwPolicy2 = NULL; // 防火墙方案2
pFwRules = NULL;//防火墙规则集合

//初始化COM环境
hrComInit = CoInitializeEx(
0,
COINIT_MULTITHREADED
);
bool comInit = true;
if (hrComInit != RPC_E_CHANGED_MODE)
{
if (FAILED(hrComInit))
{
comInit = false;
//打印错误信息
printf("CoInitializeEx failed: 0x%08lx\n", hrComInit);
}
}
if (comInit)
{
Init();
}
}

WinFireWall::~WinFireWall()
{
Release();
// Uninitialize COM.
if (SUCCEEDED(hrComInit))
{
CoUninitialize();
}
}

bool WinFireWall::Init()
{
HRESULT hr = S_OK;

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

if (FAILED(hr))
{
printf("CoCreateInstance for INetFwPolicy2 failed: 0x%08lx\n", hr);
return false;
}
//获取规则集合
hr = pNetFwPolicy2->get_Rules(&pFwRules);
if (FAILED(hr))
{
printf("get_Rules failed: 0x%08lx\n", hr);
return false;
}
init = true;
return true;
}

bool WinFireWall::Release()
{
init = false;
if (pFwRules != NULL)
{
pFwRules->Release();
}

if (pNetFwPolicy2 != NULL)
{
pNetFwPolicy2->Release();
}
return true;
}

bool WinFireWall::AddAllFireRule(const wchar_t* ruleName, const wchar_t* applicationPath)
{
if (init)
{
//查询是否有这个规则,有规则则删除
BSTR bstrRuleName = SysAllocString(ruleName);
DeleteFireRule(ruleName);
//添加该规则
bool ret = CreateRule(ruleName, applicationPath, NET_FW_RULE_DIR_IN);
if (ret)
{
ret = CreateRule(ruleName, applicationPath, NET_FW_RULE_DIR_OUT);
}
return ret;
}

return false;
}

bool WinFireWall::HasFireRule(const wchar_t* ruleName)
{
bool ret = false;
if (init)
{
//查询是否有这个规则
INetFwRule* curRule = NULL;
BSTR bstrRuleName = SysAllocString(ruleName);
HRESULT hr = pFwRules->Item(bstrRuleName, &curRule);
if (SUCCEEDED(hr))
{
ret = true;

}
SysFreeString(bstrRuleName);
if (curRule)
{
curRule->Release();
}
}
return ret;
}

bool WinFireWall::DeleteFireRule(const wchar_t* ruleName)
{
bool ret = false;
if (init)
{
//直接删除这个规则
BSTR bstrRuleName = SysAllocString(ruleName);
while (HasFireRule(ruleName))
{
HRESULT hr = pFwRules->Remove(bstrRuleName);
if (SUCCEEDED(hr))
{
ret = true;
}
}
SysFreeString(bstrRuleName);

}
return ret;
}

std::wstring WinFireWall::GetErrMsg()
{
return std::wstring();
}

bool WinFireWall::CreateRule(const wchar_t* ruleName, const wchar_t* applicationPath, NET_FW_RULE_DIRECTION dir)
{
bool ret = true;
BSTR bstrRuleName = SysAllocString(ruleName);
BSTR bstrRuleApplication = SysAllocString(applicationPath);
BSTR bstrRuleDescription = SysAllocString(L"");
BSTR bstrRuleLPorts = SysAllocString(L"*");
BSTR bstrRuleGroup = SysAllocString(L"");

INetFwRule* pFwRule = NULL;//要添加的防火墙规则
HRESULT hr = CoCreateInstance(
__uuidof(NetFwRule),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(INetFwRule),
(void**)&pFwRule);
if (FAILED(hr))
{
printf("in CoCreateInstance for Firewall Rule failed: 0x%08lx\n", hr);
ret = false;
}
else {
// Populate the Firewall Rule object
pFwRule->put_Name(bstrRuleName);
pFwRule->put_Description(bstrRuleDescription);
pFwRule->put_ApplicationName(bstrRuleApplication);
pFwRule->put_Protocol(NET_FW_IP_PROTOCOL_ANY);
pFwRule->put_LocalPorts(bstrRuleLPorts);
pFwRule->put_Direction(dir);
pFwRule->put_Grouping(bstrRuleGroup);
pFwRule->put_Profiles(NET_FW_PROFILE2_ALL);
pFwRule->put_Action(NET_FW_ACTION_ALLOW);
pFwRule->put_Enabled(VARIANT_TRUE);
// Add the Firewall Rule
hr = pFwRules->Add(pFwRule);
if (FAILED(hr))
{
printf("in Firewall Rule Add failed : 0x%08lx\n", hr);
ret = false;
}
}
SysFreeString(bstrRuleName);
SysFreeString(bstrRuleDescription);
SysFreeString(bstrRuleGroup);
SysFreeString(bstrRuleApplication);
SysFreeString(bstrRuleLPorts);
if (pFwRule != NULL)
{
pFwRule->Release();
}
return ret;
}
1
2
3
4
5
6
7
8
9
#include "WinFireWall.h"
int main()
{
WinFireWall wall;
bool ret = wall.AddAllFireRule(L"test测试", L"C:\\Program Files (x86)\\SXCAService\\TomcatService.exe");
ret = wall.HasFireRule(L"test测试");
//wall.DeleteFireRule(L"test测试");
return ret;
}

这个封装类添加了入站和出站规则。

评论