summaryrefslogtreecommitdiff
path: root/src/ext/Firewall/ca
diff options
context:
space:
mode:
authorchris_bednarski <Chris.Bednarski@minfos.com.au>2023-09-21 16:03:28 +1000
committerBob Arnson <github@bobs.org>2023-11-19 12:17:13 -0500
commitdfb7512b85536b7726080648f2228cf8d0153724 (patch)
treed053018ee47afe7e349dda6739a6580c771a1a3d /src/ext/Firewall/ca
parent80e604761b4f43b9b79a4878fcae360b071a7c35 (diff)
downloadwix-dfb7512b85536b7726080648f2228cf8d0153724.tar.gz
wix-dfb7512b85536b7726080648f2228cf8d0153724.tar.bz2
wix-dfb7512b85536b7726080648f2228cf8d0153724.zip
add firewall extension decompiler, make msi modifications work, add all attributes
Diffstat (limited to 'src/ext/Firewall/ca')
-rw-r--r--src/ext/Firewall/ca/firewall.cpp980
1 files changed, 783 insertions, 197 deletions
diff --git a/src/ext/Firewall/ca/firewall.cpp b/src/ext/Firewall/ca/firewall.cpp
index eed6f9df..f50ae409 100644
--- a/src/ext/Firewall/ca/firewall.cpp
+++ b/src/ext/Firewall/ca/firewall.cpp
@@ -3,34 +3,54 @@
3#include "precomp.h" 3#include "precomp.h"
4 4
5LPCWSTR vcsFirewallExceptionQuery = 5LPCWSTR vcsFirewallExceptionQuery =
6 L"SELECT `Name`, `RemoteAddresses`, `Port`, `Protocol`, `Program`, `Attributes`, `Profile`, `Component_`, `Description`, `Direction` FROM `Wix5FirewallException`"; 6L"SELECT `Name`, `RemoteAddresses`, `Port`, `Protocol`, `Program`, `Attributes`, `Profile`, `Component_`, `Description`, `Direction`, `Action`, `EdgeTraversal`, `Enabled`, `Grouping`, `IcmpTypesAndCodes`, `Interfaces`, `InterfaceTypes`, `LocalAddresses`, `RemotePort`, `ServiceName`, `LocalAppPackageId`, `LocalUserAuthorizedList`, `LocalUserOwner`, `RemoteMachineAuthorizedList`, `RemoteUserAuthorizedList`, `SecureFlags` FROM `Wix5FirewallException`";
7enum eFirewallExceptionQuery { feqName = 1, feqRemoteAddresses, feqPort, feqProtocol, feqProgram, feqAttributes, feqProfile, feqComponent, feqDescription, feqDirection }; 7enum eFirewallExceptionQuery { feqName = 1, feqRemoteAddresses, feqPort, feqProtocol, feqProgram, feqAttributes, feqProfile, feqComponent, feqDescription, feqDirection, feqAction, feqEdgeTraversal, feqEnabled, feqGrouping, feqIcmpTypesAndCodes, feqInterfaces, feqInterfaceTypes, feqLocalAddresses, feqRemotePort, feqServiceName, feqLocalAppPackageId, feqLocalUserAuthorizedList, feqLocalUserOwner, feqRemoteMachineAuthorizedList, feqRemoteUserAuthorizedList, feqSecureFlags };
8enum eFirewallExceptionTarget { fetPort = 1, fetApplication, fetUnknown }; 8enum eFirewallExceptionAttributes { feaIgnoreFailures = 1, feaIgnoreUpdates = 2, feaEnableOnUpdate = 4, feaAddINetFwRule2 = 8, feaAddINetFwRule3 = 16 };
9enum eFirewallExceptionAttributes { feaIgnoreFailures = 1 };
10 9
11struct FIREWALL_EXCEPTION_ATTRIBUTES 10struct FIREWALL_EXCEPTION_ATTRIBUTES
12{ 11{
13 LPWSTR pwzName; 12 LPWSTR pwzName;
14
15 LPWSTR pwzRemoteAddresses;
16 LPWSTR pwzPort;
17 int iProtocol;
18 LPWSTR pwzProgram;
19 int iAttributes; 13 int iAttributes;
20 int iProfile; 14
15 // INetFwRule
16 int iAction;
17 LPWSTR pwzApplicationName;
21 LPWSTR pwzDescription; 18 LPWSTR pwzDescription;
22 int iDirection; 19 int iDirection;
20 int iEnabled;
21 LPWSTR pwzGrouping;
22 LPWSTR pwzIcmpTypesAndCodes;
23 LPWSTR pwzInterfaces;
24 LPWSTR pwzInterfaceTypes;
25 LPWSTR pwzLocalAddresses;
26 LPWSTR pwzLocalPorts;
27 int iProfile;
28 int iProtocol;
29 LPWSTR pwzRemoteAddresses;
30 LPWSTR pwzRemotePorts;
31 LPWSTR pwzServiceName;
32
33 // INetFwRule2
34 int iEdgeTraversal;
35
36 // INetFwRule3
37 LPWSTR pwzLocalAppPackageId;
38 LPWSTR pwzLocalUserAuthorizedList;
39 LPWSTR pwzLocalUserOwner;
40 LPWSTR pwzRemoteMachineAuthorizedList;
41 LPWSTR pwzRemoteUserAuthorizedList;
42 int iSecureFlags;
23}; 43};
24 44
25/****************************************************************** 45/******************************************************************
26 SchedFirewallExceptions - immediate custom action worker to 46 SchedFirewallExceptions - immediate custom action worker to
27 register and remove firewall exceptions. 47 register and remove firewall exceptions.
28 48
29********************************************************************/ 49********************************************************************/
30static UINT SchedFirewallExceptions( 50static UINT SchedFirewallExceptions(
31 __in MSIHANDLE hInstall, 51 __in MSIHANDLE hInstall,
32 WCA_TODO todoSched 52 __in WCA_TODO todoSched
33 ) 53)
34{ 54{
35 HRESULT hr = S_OK; 55 HRESULT hr = S_OK;
36 UINT er = ERROR_SUCCESS; 56 UINT er = ERROR_SUCCESS;
@@ -67,19 +87,19 @@ static UINT SchedFirewallExceptions(
67 hr = WcaGetRecordFormattedString(hRec, feqRemoteAddresses, &attrs.pwzRemoteAddresses); 87 hr = WcaGetRecordFormattedString(hRec, feqRemoteAddresses, &attrs.pwzRemoteAddresses);
68 ExitOnFailure(hr, "Failed to get firewall exception remote addresses."); 88 ExitOnFailure(hr, "Failed to get firewall exception remote addresses.");
69 89
70 hr = WcaGetRecordFormattedString(hRec, feqPort, &attrs.pwzPort); 90 hr = WcaGetRecordFormattedString(hRec, feqPort, &attrs.pwzLocalPorts);
71 ExitOnFailure(hr, "Failed to get firewall exception port."); 91 ExitOnFailure(hr, "Failed to get firewall exception port.");
72 92
73 hr = WcaGetRecordInteger(hRec, feqProtocol, &attrs.iProtocol); 93 hr = WcaGetRecordFormattedInteger(hRec, feqProtocol, &attrs.iProtocol);
74 ExitOnFailure(hr, "Failed to get firewall exception protocol."); 94 ExitOnFailure(hr, "Failed to get firewall exception protocol.");
75 95
76 hr = WcaGetRecordFormattedString(hRec, feqProgram, &attrs.pwzProgram); 96 hr = WcaGetRecordFormattedString(hRec, feqProgram, &attrs.pwzApplicationName);
77 ExitOnFailure(hr, "Failed to get firewall exception program."); 97 ExitOnFailure(hr, "Failed to get firewall exception program.");
78 98
79 hr = WcaGetRecordInteger(hRec, feqAttributes, &attrs.iAttributes); 99 hr = WcaGetRecordInteger(hRec, feqAttributes, &attrs.iAttributes);
80 ExitOnFailure(hr, "Failed to get firewall exception attributes."); 100 ExitOnFailure(hr, "Failed to get firewall exception attributes.");
81 101
82 hr = WcaGetRecordInteger(hRec, feqProfile, &attrs.iProfile); 102 hr = WcaGetRecordFormattedInteger(hRec, feqProfile, &attrs.iProfile);
83 ExitOnFailure(hr, "Failed to get firewall exception profile."); 103 ExitOnFailure(hr, "Failed to get firewall exception profile.");
84 104
85 hr = WcaGetRecordString(hRec, feqComponent, &pwzComponent); 105 hr = WcaGetRecordString(hRec, feqComponent, &pwzComponent);
@@ -91,6 +111,54 @@ static UINT SchedFirewallExceptions(
91 hr = WcaGetRecordInteger(hRec, feqDirection, &attrs.iDirection); 111 hr = WcaGetRecordInteger(hRec, feqDirection, &attrs.iDirection);
92 ExitOnFailure(hr, "Failed to get firewall exception direction."); 112 ExitOnFailure(hr, "Failed to get firewall exception direction.");
93 113
114 hr = WcaGetRecordFormattedInteger(hRec, feqAction, &attrs.iAction);
115 ExitOnFailure(hr, "Failed to get firewall exception action.");
116
117 hr = WcaGetRecordFormattedInteger(hRec, feqEdgeTraversal, &attrs.iEdgeTraversal);
118 ExitOnFailure(hr, "Failed to get firewall exception edge traversal.");
119
120 hr = WcaGetRecordFormattedInteger(hRec, feqEnabled, &attrs.iEnabled);
121 ExitOnFailure(hr, "Failed to get firewall exception enabled flag.");
122
123 hr = WcaGetRecordFormattedString(hRec, feqGrouping, &attrs.pwzGrouping);
124 ExitOnFailure(hr, "Failed to get firewall exception grouping.");
125
126 hr = WcaGetRecordFormattedString(hRec, feqIcmpTypesAndCodes, &attrs.pwzIcmpTypesAndCodes);
127 ExitOnFailure(hr, "Failed to get firewall exception ICMP types and codes.");
128
129 hr = WcaGetRecordFormattedString(hRec, feqInterfaces, &attrs.pwzInterfaces);
130 ExitOnFailure(hr, "Failed to get firewall exception interfaces.");
131
132 hr = WcaGetRecordFormattedString(hRec, feqInterfaceTypes, &attrs.pwzInterfaceTypes);
133 ExitOnFailure(hr, "Failed to get firewall exception interface types.");
134
135 hr = WcaGetRecordFormattedString(hRec, feqLocalAddresses, &attrs.pwzLocalAddresses);
136 ExitOnFailure(hr, "Failed to get firewall exception local addresses.");
137
138 hr = WcaGetRecordFormattedString(hRec, feqRemotePort, &attrs.pwzRemotePorts);
139 ExitOnFailure(hr, "Failed to get firewall exception remote port.");
140
141 hr = WcaGetRecordFormattedString(hRec, feqServiceName, &attrs.pwzServiceName);
142 ExitOnFailure(hr, "Failed to get firewall exception service name.");
143
144 hr = WcaGetRecordFormattedString(hRec, feqLocalAppPackageId, &attrs.pwzLocalAppPackageId);
145 ExitOnFailure(hr, "Failed to get firewall exception local app package id.");
146
147 hr = WcaGetRecordFormattedString(hRec, feqLocalUserAuthorizedList, &attrs.pwzLocalUserAuthorizedList);
148 ExitOnFailure(hr, "Failed to get firewall exception local user authorized list.");
149
150 hr = WcaGetRecordFormattedString(hRec, feqLocalUserOwner, &attrs.pwzLocalUserOwner);
151 ExitOnFailure(hr, "Failed to get firewall exception local user owner.");
152
153 hr = WcaGetRecordFormattedString(hRec, feqRemoteMachineAuthorizedList, &attrs.pwzRemoteMachineAuthorizedList);
154 ExitOnFailure(hr, "Failed to get firewall exception remote machine authorized list.");
155
156 hr = WcaGetRecordFormattedString(hRec, feqRemoteUserAuthorizedList, &attrs.pwzRemoteUserAuthorizedList);
157 ExitOnFailure(hr, "Failed to get firewall exception remote user authorized list.");
158
159 hr = WcaGetRecordFormattedInteger(hRec, feqSecureFlags, &attrs.iSecureFlags);
160 ExitOnFailure(hr, "Failed to get firewall exception secure flag.");
161
94 // figure out what we're doing for this exception, treating reinstall the same as install 162 // figure out what we're doing for this exception, treating reinstall the same as install
95 WCA_TODO todoComponent = WcaGetComponentToDo(pwzComponent); 163 WCA_TODO todoComponent = WcaGetComponentToDo(pwzComponent);
96 if ((WCA_TODO_REINSTALL == todoComponent ? WCA_TODO_INSTALL : todoComponent) != todoSched) 164 if ((WCA_TODO_REINSTALL == todoComponent ? WCA_TODO_INSTALL : todoComponent) != todoSched)
@@ -99,7 +167,6 @@ static UINT SchedFirewallExceptions(
99 continue; 167 continue;
100 } 168 }
101 169
102 // action :: name :: profile :: remoteaddresses :: attributes :: target :: {port::protocol | path}
103 ++cFirewallExceptions; 170 ++cFirewallExceptions;
104 hr = WcaWriteIntegerToCaData(todoComponent, &pwzCustomActionData); 171 hr = WcaWriteIntegerToCaData(todoComponent, &pwzCustomActionData);
105 ExitOnFailure(hr, "failed to write exception action to custom action data"); 172 ExitOnFailure(hr, "failed to write exception action to custom action data");
@@ -116,40 +183,75 @@ static UINT SchedFirewallExceptions(
116 hr = WcaWriteIntegerToCaData(attrs.iAttributes, &pwzCustomActionData); 183 hr = WcaWriteIntegerToCaData(attrs.iAttributes, &pwzCustomActionData);
117 ExitOnFailure(hr, "failed to write exception attributes to custom action data"); 184 ExitOnFailure(hr, "failed to write exception attributes to custom action data");
118 185
119 if (*attrs.pwzProgram) 186 hr = WcaWriteStringToCaData(attrs.pwzApplicationName, &pwzCustomActionData);
120 {
121 // If program is defined, we have an application exception.
122 hr = WcaWriteIntegerToCaData(fetApplication, &pwzCustomActionData);
123 ExitOnFailure(hr, "failed to write exception target (application) to custom action data");
124
125 hr = WcaWriteStringToCaData(attrs.pwzProgram, &pwzCustomActionData);
126 ExitOnFailure(hr, "failed to write application path to custom action data");
127 }
128 else
129 {
130 // we have a port-only exception
131 hr = WcaWriteIntegerToCaData(fetPort, &pwzCustomActionData);
132 ExitOnFailure(hr, "failed to write exception target (port) to custom action data");
133 }
134
135 hr = WcaWriteStringToCaData(attrs.pwzPort, &pwzCustomActionData);
136 ExitOnFailure(hr, "failed to write application path to custom action data"); 187 ExitOnFailure(hr, "failed to write application path to custom action data");
137 188
189 hr = WcaWriteStringToCaData(attrs.pwzLocalPorts, &pwzCustomActionData);
190 ExitOnFailure(hr, "failed to write local ports to custom action data");
191
138 hr = WcaWriteIntegerToCaData(attrs.iProtocol, &pwzCustomActionData); 192 hr = WcaWriteIntegerToCaData(attrs.iProtocol, &pwzCustomActionData);
139 ExitOnFailure(hr, "failed to write exception protocol to custom action data"); 193 ExitOnFailure(hr, "failed to write exception protocol to custom action data");
140 194
141 hr = WcaWriteStringToCaData(attrs.pwzDescription, &pwzCustomActionData); 195 hr = WcaWriteStringToCaData(attrs.pwzDescription, &pwzCustomActionData);
142 ExitOnFailure(hr, "failed to write firewall rule description to custom action data"); 196 ExitOnFailure(hr, "failed to write firewall exception description to custom action data");
143 197
144 hr = WcaWriteIntegerToCaData(attrs.iDirection, &pwzCustomActionData); 198 hr = WcaWriteIntegerToCaData(attrs.iDirection, &pwzCustomActionData);
145 ExitOnFailure(hr, "failed to write firewall rule direction to custom action data"); 199 ExitOnFailure(hr, "failed to write firewall exception direction to custom action data");
200
201 hr = WcaWriteIntegerToCaData(attrs.iAction, &pwzCustomActionData);
202 ExitOnFailure(hr, "failed to write exception action to custom action data");
203
204 hr = WcaWriteIntegerToCaData(attrs.iEdgeTraversal, &pwzCustomActionData);
205 ExitOnFailure(hr, "failed to write exception edge traversal to custom action data");
206
207 hr = WcaWriteIntegerToCaData(attrs.iEnabled, &pwzCustomActionData);
208 ExitOnFailure(hr, "failed to write exception enabled flag to custom action data");
209
210 hr = WcaWriteStringToCaData(attrs.pwzGrouping, &pwzCustomActionData);
211 ExitOnFailure(hr, "failed to write grouping to custom action data");
212
213 hr = WcaWriteStringToCaData(attrs.pwzIcmpTypesAndCodes, &pwzCustomActionData);
214 ExitOnFailure(hr, "failed to write icmp types and codes to custom action data");
215
216 hr = WcaWriteStringToCaData(attrs.pwzInterfaces, &pwzCustomActionData);
217 ExitOnFailure(hr, "failed to write interfaces to custom action data");
218
219 hr = WcaWriteStringToCaData(attrs.pwzInterfaceTypes, &pwzCustomActionData);
220 ExitOnFailure(hr, "failed to write interface types to custom action data");
221
222 hr = WcaWriteStringToCaData(attrs.pwzLocalAddresses, &pwzCustomActionData);
223 ExitOnFailure(hr, "failed to write local addresses to custom action data");
224
225 hr = WcaWriteStringToCaData(attrs.pwzRemotePorts, &pwzCustomActionData);
226 ExitOnFailure(hr, "failed to write remote ports to custom action data");
227
228 hr = WcaWriteStringToCaData(attrs.pwzServiceName, &pwzCustomActionData);
229 ExitOnFailure(hr, "failed to write service name to custom action data");
230
231 hr = WcaWriteStringToCaData(attrs.pwzLocalAppPackageId, &pwzCustomActionData);
232 ExitOnFailure(hr, "failed to write local app package id to custom action data");
233
234 hr = WcaWriteStringToCaData(attrs.pwzLocalUserAuthorizedList, &pwzCustomActionData);
235 ExitOnFailure(hr, "failed to write local user authorized list to custom action data");
236
237 hr = WcaWriteStringToCaData(attrs.pwzLocalUserOwner, &pwzCustomActionData);
238 ExitOnFailure(hr, "failed to write local user owner to custom action data");
239
240 hr = WcaWriteStringToCaData(attrs.pwzRemoteMachineAuthorizedList, &pwzCustomActionData);
241 ExitOnFailure(hr, "failed to write remote machine authorized list to custom action data");
242
243 hr = WcaWriteStringToCaData(attrs.pwzRemoteUserAuthorizedList, &pwzCustomActionData);
244 ExitOnFailure(hr, "failed to write remote user authorized list to custom action data");
245
246 hr = WcaWriteIntegerToCaData(attrs.iSecureFlags, &pwzCustomActionData);
247 ExitOnFailure(hr, "failed to write exception secure flags to custom action data");
146 } 248 }
147 249
148 // reaching the end of the list is actually a good thing, not an error 250 // reaching the end of the list is actually a good thing, not an error
149 if (E_NOMOREITEMS == hr) 251 if (E_NOMOREITEMS == hr)
150 { 252 {
151 hr = S_OK; 253 hr = S_OK;
152 } 254 }
153 ExitOnFailure(hr, "failure occured while processing Wix5FirewallException table"); 255 ExitOnFailure(hr, "failure occured while processing Wix5FirewallException table");
154 256
155 // schedule ExecFirewallExceptions if there's anything to do 257 // schedule ExecFirewallExceptions if there's anything to do
@@ -160,14 +262,14 @@ static UINT SchedFirewallExceptions(
160 if (WCA_TODO_INSTALL == todoSched) 262 if (WCA_TODO_INSTALL == todoSched)
161 { 263 {
162 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"RollbackFirewallExceptionsInstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION); 264 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"RollbackFirewallExceptionsInstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION);
163 ExitOnFailure(hr, "failed to schedule firewall install exceptions rollback"); 265 ExitOnFailure(hr, "failed to schedule firewall install exceptions rollback");
164 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"ExecFirewallExceptionsInstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION); 266 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"ExecFirewallExceptionsInstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION);
165 ExitOnFailure(hr, "failed to schedule firewall install exceptions execution"); 267 ExitOnFailure(hr, "failed to schedule firewall install exceptions execution");
166 } 268 }
167 else 269 else
168 { 270 {
169 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"RollbackFirewallExceptionsUninstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION); 271 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"RollbackFirewallExceptionsUninstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION);
170 ExitOnFailure(hr, "failed to schedule firewall uninstall exceptions rollback"); 272 ExitOnFailure(hr, "failed to schedule firewall uninstall exceptions rollback");
171 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"ExecFirewallExceptionsUninstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION); 273 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"ExecFirewallExceptionsUninstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION);
172 ExitOnFailure(hr, "failed to schedule firewall uninstall exceptions execution"); 274 ExitOnFailure(hr, "failed to schedule firewall uninstall exceptions execution");
173 } 275 }
@@ -180,53 +282,68 @@ static UINT SchedFirewallExceptions(
180LExit: 282LExit:
181 ReleaseStr(attrs.pwzName); 283 ReleaseStr(attrs.pwzName);
182 ReleaseStr(attrs.pwzRemoteAddresses); 284 ReleaseStr(attrs.pwzRemoteAddresses);
183 ReleaseStr(attrs.pwzPort); 285 ReleaseStr(attrs.pwzLocalPorts);
184 ReleaseStr(attrs.pwzProgram); 286 ReleaseStr(attrs.pwzApplicationName);
185 ReleaseStr(attrs.pwzDescription); 287 ReleaseStr(attrs.pwzDescription);
288 ReleaseStr(attrs.pwzGrouping);
289 ReleaseStr(attrs.pwzIcmpTypesAndCodes);
290 ReleaseStr(attrs.pwzInterfaces);
291 ReleaseStr(attrs.pwzInterfaceTypes);
292 ReleaseStr(attrs.pwzLocalAddresses);
293 ReleaseStr(attrs.pwzRemotePorts);
294 ReleaseStr(attrs.pwzServiceName);
295 ReleaseStr(attrs.pwzLocalAppPackageId);
296 ReleaseStr(attrs.pwzLocalUserAuthorizedList);
297 ReleaseStr(attrs.pwzLocalUserOwner);
298 ReleaseStr(attrs.pwzRemoteMachineAuthorizedList);
299 ReleaseStr(attrs.pwzRemoteUserAuthorizedList);
186 ReleaseStr(pwzComponent); 300 ReleaseStr(pwzComponent);
187 ReleaseStr(pwzCustomActionData); 301 ReleaseStr(pwzCustomActionData);
188 302
189 return WcaFinalize(er = FAILED(hr) ? ERROR_INSTALL_FAILURE : er); 303 return WcaFinalize(er = FAILED(hr) ? ERROR_INSTALL_FAILURE : er);
190} 304}
191 305
192/****************************************************************** 306
307/*******************************************************************
193 SchedFirewallExceptionsInstall - immediate custom action entry 308 SchedFirewallExceptionsInstall - immediate custom action entry
194 point to register firewall exceptions. 309 point to register firewall exceptions.
195 310
196********************************************************************/ 311********************************************************************/
197extern "C" UINT __stdcall SchedFirewallExceptionsInstall( 312extern "C" UINT __stdcall SchedFirewallExceptionsInstall(
198 __in MSIHANDLE hInstall 313 __in MSIHANDLE hInstall
199 ) 314)
200{ 315{
201 return SchedFirewallExceptions(hInstall, WCA_TODO_INSTALL); 316 return SchedFirewallExceptions(hInstall, WCA_TODO_INSTALL);
202} 317}
203 318
204/****************************************************************** 319
320/*******************************************************************
205 SchedFirewallExceptionsUninstall - immediate custom action entry 321 SchedFirewallExceptionsUninstall - immediate custom action entry
206 point to remove firewall exceptions. 322 point to remove firewall exceptions.
207 323
208********************************************************************/ 324********************************************************************/
209extern "C" UINT __stdcall SchedFirewallExceptionsUninstall( 325extern "C" UINT __stdcall SchedFirewallExceptionsUninstall(
210 __in MSIHANDLE hInstall 326 __in MSIHANDLE hInstall
211 ) 327)
212{ 328{
213 return SchedFirewallExceptions(hInstall, WCA_TODO_UNINSTALL); 329 return SchedFirewallExceptions(hInstall, WCA_TODO_UNINSTALL);
214} 330}
215 331
216/****************************************************************** 332
333/*******************************************************************
217 GetFirewallRules - Get the collection of firewall rules. 334 GetFirewallRules - Get the collection of firewall rules.
218 335
219********************************************************************/ 336********************************************************************/
220static HRESULT GetFirewallRules( 337static HRESULT GetFirewallRules(
221 __in BOOL fIgnoreFailures, 338 __in BOOL fIgnoreFailures,
222 __out INetFwRules** ppNetFwRules 339 __out INetFwRules** ppNetFwRules
223 ) 340)
224{ 341{
225 HRESULT hr = S_OK; 342 HRESULT hr = S_OK;
226 INetFwPolicy2* pNetFwPolicy2 = NULL; 343 INetFwPolicy2* pNetFwPolicy2 = NULL;
227 INetFwRules* pNetFwRules = NULL; 344 INetFwRules* pNetFwRules = NULL;
228 *ppNetFwRules = NULL; 345 *ppNetFwRules = NULL;
229 346
230 do 347 do
231 { 348 {
232 ReleaseNullObject(pNetFwPolicy2); 349 ReleaseNullObject(pNetFwPolicy2);
@@ -262,7 +379,7 @@ static HRESULT GetFirewallRules(
262 379
263 *ppNetFwRules = pNetFwRules; 380 *ppNetFwRules = pNetFwRules;
264 pNetFwRules = NULL; 381 pNetFwRules = NULL;
265 382
266LExit: 383LExit:
267 ReleaseObject(pNetFwPolicy2); 384 ReleaseObject(pNetFwPolicy2);
268 ReleaseObject(pNetFwRules); 385 ReleaseObject(pNetFwRules);
@@ -270,51 +387,380 @@ LExit:
270 return hr; 387 return hr;
271} 388}
272 389
273/****************************************************************** 390
274 CreateFwRuleObject - CoCreate a firewall rule, and set the common set of properties which are shared 391/*******************************************************************
275 between port and application firewall rules 392 CreateFwRuleObject - CoCreate a firewall rule, and set the name
276 393
277********************************************************************/ 394********************************************************************/
278static HRESULT CreateFwRuleObject( 395static HRESULT CreateFwRuleObject(
279 __in BSTR bstrName, 396 __in BSTR bstrName,
280 __in FIREWALL_EXCEPTION_ATTRIBUTES const& attrs,
281 __out INetFwRule** ppNetFwRule 397 __out INetFwRule** ppNetFwRule
282 ) 398)
399{
400 HRESULT hr = S_OK;
401 INetFwRule* pNetFwRule = NULL;
402 *ppNetFwRule = NULL;
403
404 hr = ::CoCreateInstance(__uuidof(NetFwRule), NULL, CLSCTX_ALL, __uuidof(INetFwRule), (LPVOID*)&pNetFwRule);
405 ExitOnFailure(hr, "failed to create NetFwRule object");
406
407 hr = pNetFwRule->put_Name(bstrName);
408 ExitOnFailure(hr, "failed to set firewall exception name");
409
410 *ppNetFwRule = pNetFwRule;
411
412LExit:
413 return hr;
414}
415
416
417/*********************************************************************
418 GetFwRuleInterfaces - pack firewall rule interfaces into a VARIANT.
419 The populated VARIANT needs to be cleaned up by the calling function.
420
421**********************************************************************/
422static HRESULT GetFwRuleInterfaces(
423 __in FIREWALL_EXCEPTION_ATTRIBUTES const& attrs,
424 __out VARIANT& vInterfaces
425)
426{
427 HRESULT hr = S_OK;
428 BSTR bstrInterfaces = NULL;
429 const WCHAR FORBIDDEN_FIREWALL_CHAR = L'|';
430 LONG iInterfacesCount = 0;
431 UINT iLength = 0;
432 LONG iIndex = 0;
433
434 ::VariantInit(&vInterfaces);
435 ExitOnNull(attrs.pwzInterfaces, hr, S_OK, "No interfaces to pack");
436
437 bstrInterfaces = ::SysAllocString(attrs.pwzInterfaces);
438 ExitOnNull(bstrInterfaces, hr, E_OUTOFMEMORY, "failed SysAllocString for interfaces");
439
440 iLength = ::SysStringLen(bstrInterfaces);
441
442 LPWSTR pwzT = bstrInterfaces;
443 while (*pwzT)
444 {
445 if (FORBIDDEN_FIREWALL_CHAR == *pwzT)
446 {
447 *pwzT = L'\0';
448 pwzT++;
449
450 // skip empty values inside the interfaces eg. |||
451 if (*pwzT && FORBIDDEN_FIREWALL_CHAR != *pwzT)
452 {
453 iInterfacesCount++;
454 }
455 }
456 else
457 {
458 if (pwzT == bstrInterfaces)
459 {
460 iInterfacesCount++;
461 }
462
463 pwzT++;
464 }
465 }
466
467 ExitOnNull(iInterfacesCount, hr, S_OK, "All interfaces are empty values");
468
469 vInterfaces.vt = VT_ARRAY | VT_VARIANT;
470 // this will be cleaned up by ReleaseVariant call of the calling function
471 vInterfaces.parray = SafeArrayCreateVector(VT_VARIANT, 0, iInterfacesCount);
472
473 for (LPCWSTR pwzElement = bstrInterfaces; pwzElement < (bstrInterfaces + iLength); ++pwzElement)
474 {
475 if (*pwzElement)
476 {
477 VARIANT vElement;
478 ::VariantInit(&vElement);
479
480 vElement.vt = VT_BSTR;
481 // this will be cleaned up by ReleaseVariant call of the calling function
482 vElement.bstrVal = ::SysAllocString(pwzElement);
483 ExitOnNull(vElement.bstrVal, hr, E_OUTOFMEMORY, "failed SysAllocString for interface element");
484
485 hr = SafeArrayPutElement(vInterfaces.parray, &iIndex, &vElement);
486 ExitOnFailure(hr, "failed to put interface '%ls' into safe array", pwzElement);
487
488 pwzElement += ::SysStringLen(vElement.bstrVal);
489 iIndex++;
490 }
491 }
492
493LExit:
494 ReleaseBSTR(bstrInterfaces);
495
496 return hr;
497}
498
499/******************************************************************************
500 UpdateFwRule2Object - update properties for a firewall INetFwRule2 interface.
501 Requires Windows 7 / 2008 R2
502
503 ******************************************************************************/
504static HRESULT UpdateFwRule2Object(
505 __in INetFwRule* pNetFwRule,
506 __in BOOL fUpdateRule,
507 __in FIREWALL_EXCEPTION_ATTRIBUTES const& attrs
508)
283{ 509{
284 HRESULT hr = S_OK; 510 HRESULT hr = S_OK;
511 INetFwRule2* pNetFwRule2 = NULL;
512
513 hr = pNetFwRule->QueryInterface(__uuidof(INetFwRule2), (LPVOID*)&pNetFwRule2);
514 ExitOnFailure(hr, "failed to query INetFwRule2 interface");
515
516 if (MSI_NULL_INTEGER != attrs.iEdgeTraversal)
517 {
518 hr = pNetFwRule2->put_EdgeTraversalOptions(attrs.iEdgeTraversal);
519 ExitOnFailure(hr, "failed to set exception edge traversal option");
520 }
521 else if (fUpdateRule)
522 {
523 hr = pNetFwRule2->put_EdgeTraversalOptions(NET_FW_EDGE_TRAVERSAL_TYPE_DENY);
524 ExitOnFailure(hr, "failed to remove exception edge traversal option");
525 }
526
527LExit:
528 ReleaseObject(pNetFwRule2);
529
530 return hr;
531}
532
533
534/******************************************************************************
535 UpdateFwRule3Object - update properties for a firewall INetFwRule3 interface.
536 Requires Windows 8 / 2012
537
538 ******************************************************************************/
539static HRESULT UpdateFwRule3Object(
540 __in INetFwRule* pNetFwRule,
541 __in BOOL fUpdateRule,
542 __in FIREWALL_EXCEPTION_ATTRIBUTES const& attrs
543)
544{
545 HRESULT hr = S_OK;
546
547 BSTR bstrLocalAppPackageId = NULL;
548 BSTR bstrLocalUserAuthorizedList = NULL;
549 BSTR bstrLocalUserOwner = NULL;
550 BSTR bstrRemoteMachineAuthorizedList = NULL;
551 BSTR bstrRemoteUserAuthorizedList = NULL;
552 INetFwRule3* pNetFwRule3 = NULL;
553
554 bstrLocalAppPackageId = ::SysAllocString(attrs.pwzLocalAppPackageId);
555 ExitOnNull(bstrLocalAppPackageId, hr, E_OUTOFMEMORY, "failed SysAllocString for local app package id");
556 bstrLocalUserAuthorizedList = ::SysAllocString(attrs.pwzLocalUserAuthorizedList);
557 ExitOnNull(bstrLocalUserAuthorizedList, hr, E_OUTOFMEMORY, "failed SysAllocString for local user authorized list");
558 bstrLocalUserOwner = ::SysAllocString(attrs.pwzLocalUserOwner);
559 ExitOnNull(bstrLocalUserOwner, hr, E_OUTOFMEMORY, "failed SysAllocString for local user owner");
560 bstrRemoteMachineAuthorizedList = ::SysAllocString(attrs.pwzRemoteMachineAuthorizedList);
561 ExitOnNull(bstrRemoteMachineAuthorizedList, hr, E_OUTOFMEMORY, "failed SysAllocString for remote machine authorized list");
562 bstrRemoteUserAuthorizedList = ::SysAllocString(attrs.pwzRemoteUserAuthorizedList);
563 ExitOnNull(bstrRemoteUserAuthorizedList, hr, E_OUTOFMEMORY, "failed SysAllocString for remote user authorized list");
564
565 hr = pNetFwRule->QueryInterface(__uuidof(INetFwRule3), (LPVOID*)&pNetFwRule3);
566 ExitOnFailure(hr, "failed to query INetFwRule3 interface");
567
568 if (bstrLocalAppPackageId && *bstrLocalAppPackageId)
569 {
570 hr = pNetFwRule3->put_LocalAppPackageId(bstrLocalAppPackageId);
571 ExitOnFailure(hr, "failed to set exception local app package id");
572 }
573 else if (fUpdateRule)
574 {
575 hr = pNetFwRule3->put_LocalAppPackageId(NULL);
576 ExitOnFailure(hr, "failed to remove exception local app package id");
577 }
578
579 if (bstrLocalUserAuthorizedList && *bstrLocalUserAuthorizedList)
580 {
581 hr = pNetFwRule3->put_LocalUserAuthorizedList(bstrLocalUserAuthorizedList);
582 ExitOnFailure(hr, "failed to set exception local user authorized list");
583 }
584 else if (fUpdateRule)
585 {
586 hr = pNetFwRule3->put_LocalUserAuthorizedList(NULL);
587 ExitOnFailure(hr, "failed to remove exception local user authorized list");
588 }
589
590 if (bstrLocalUserOwner && *bstrLocalUserOwner)
591 {
592 hr = pNetFwRule3->put_LocalUserOwner(bstrLocalUserOwner);
593 ExitOnFailure(hr, "failed to set exception local user owner");
594 }
595 else if (fUpdateRule)
596 {
597 hr = pNetFwRule3->put_LocalUserOwner(NULL);
598 ExitOnFailure(hr, "failed to remove exception local user owner");
599 }
600
601 if (bstrRemoteMachineAuthorizedList && *bstrRemoteMachineAuthorizedList)
602 {
603 hr = pNetFwRule3->put_RemoteMachineAuthorizedList(bstrRemoteMachineAuthorizedList);
604 ExitOnFailure(hr, "failed to set exception remote machine authorized list");
605 }
606 else if (fUpdateRule)
607 {
608 hr = pNetFwRule3->put_RemoteMachineAuthorizedList(NULL);
609 ExitOnFailure(hr, "failed to remove exception remote machine authorized list");
610 }
611
612 if (bstrRemoteUserAuthorizedList && *bstrRemoteUserAuthorizedList)
613 {
614 hr = pNetFwRule3->put_RemoteUserAuthorizedList(bstrRemoteUserAuthorizedList);
615 ExitOnFailure(hr, "failed to set exception remote user authorized list");
616 }
617 else if (fUpdateRule)
618 {
619 hr = pNetFwRule3->put_RemoteUserAuthorizedList(NULL);
620 ExitOnFailure(hr, "failed to remove exception remote user authorized list");
621 }
622
623 if (MSI_NULL_INTEGER != attrs.iSecureFlags)
624 {
625 hr = pNetFwRule3->put_SecureFlags(attrs.iSecureFlags);
626 ExitOnFailure(hr, "failed to set exception IPsec secure flags");
627 }
628 else if (fUpdateRule)
629 {
630 hr = pNetFwRule3->put_SecureFlags(NET_FW_AUTHENTICATE_NONE);
631 ExitOnFailure(hr, "failed to reset exception IPsec secure flags");
632 }
633
634LExit:
635 ReleaseBSTR(bstrLocalAppPackageId);
636 ReleaseBSTR(bstrLocalUserAuthorizedList);
637 ReleaseBSTR(bstrLocalUserOwner);
638 ReleaseBSTR(bstrRemoteMachineAuthorizedList);
639 ReleaseBSTR(bstrRemoteUserAuthorizedList);
640 ReleaseObject(pNetFwRule3);
641
642 return hr;
643}
644
645
646/**********************************************************************
647 UpdateFwRuleObject - update all properties for a basic firewall rule.
648 Requires Windows Vista / 2008
649
650 **********************************************************************/
651static HRESULT UpdateFwRuleObject(
652 __in INetFwRule* pNetFwRule,
653 __in BOOL fUpdateRule,
654 __in FIREWALL_EXCEPTION_ATTRIBUTES const& attrs
655)
656{
657 HRESULT hr = S_OK;
658 BSTR bstrEmpty = NULL;
285 BSTR bstrRemoteAddresses = NULL; 659 BSTR bstrRemoteAddresses = NULL;
660 BSTR bstrFile = NULL;
286 BSTR bstrPort = NULL; 661 BSTR bstrPort = NULL;
287 BSTR bstrDescription = NULL; 662 BSTR bstrDescription = NULL;
288 INetFwRule* pNetFwRule = NULL; 663 BSTR bstrGrouping = NULL;
289 *ppNetFwRule = NULL; 664 BSTR bstrIcmpTypesAndCodes = NULL;
665 BSTR bstrInterfaceTypes = NULL;
666 BSTR bstrLocalAddresses = NULL;
667 BSTR bstrRemotePort = NULL;
668 BSTR bstrServiceName = NULL;
669 VARIANT vInterfaces;
670 ::VariantInit(&vInterfaces);
671 LONG iProtocol = 0;
672
673 INetFwRule2* pNetFwRule2 = NULL;
290 674
291 // convert to BSTRs to make COM happy 675 // convert to BSTRs to make COM happy
676 bstrEmpty = ::SysAllocString(L"");
677 ExitOnNull(bstrEmpty, hr, E_OUTOFMEMORY, "failed SysAllocString for empty placeholder");
678
292 bstrRemoteAddresses = ::SysAllocString(attrs.pwzRemoteAddresses); 679 bstrRemoteAddresses = ::SysAllocString(attrs.pwzRemoteAddresses);
293 ExitOnNull(bstrRemoteAddresses, hr, E_OUTOFMEMORY, "failed SysAllocString for remote addresses"); 680 ExitOnNull(bstrRemoteAddresses, hr, E_OUTOFMEMORY, "failed SysAllocString for remote addresses");
294 bstrPort = ::SysAllocString(attrs.pwzPort); 681 bstrFile = ::SysAllocString(attrs.pwzApplicationName);
682 ExitOnNull(bstrFile, hr, E_OUTOFMEMORY, "failed SysAllocString for application name");
683 bstrPort = ::SysAllocString(attrs.pwzLocalPorts);
295 ExitOnNull(bstrPort, hr, E_OUTOFMEMORY, "failed SysAllocString for port"); 684 ExitOnNull(bstrPort, hr, E_OUTOFMEMORY, "failed SysAllocString for port");
296 bstrDescription = ::SysAllocString(attrs.pwzDescription); 685 bstrDescription = ::SysAllocString(attrs.pwzDescription);
297 ExitOnNull(bstrDescription, hr, E_OUTOFMEMORY, "failed SysAllocString for description"); 686 ExitOnNull(bstrDescription, hr, E_OUTOFMEMORY, "failed SysAllocString for description");
687 bstrGrouping = ::SysAllocString(attrs.pwzGrouping);
688 ExitOnNull(bstrGrouping, hr, E_OUTOFMEMORY, "failed SysAllocString for grouping");
689 bstrIcmpTypesAndCodes = ::SysAllocString(attrs.pwzIcmpTypesAndCodes);
690 ExitOnNull(bstrIcmpTypesAndCodes, hr, E_OUTOFMEMORY, "failed SysAllocString for icmp types and codes");
691 bstrInterfaceTypes = ::SysAllocString(attrs.pwzInterfaceTypes);
692 ExitOnNull(bstrInterfaceTypes, hr, E_OUTOFMEMORY, "failed SysAllocString for interface types");
693 bstrLocalAddresses = ::SysAllocString(attrs.pwzLocalAddresses);
694 ExitOnNull(bstrLocalAddresses, hr, E_OUTOFMEMORY, "failed SysAllocString for local addresses");
695 bstrRemotePort = ::SysAllocString(attrs.pwzRemotePorts);
696 ExitOnNull(bstrRemotePort, hr, E_OUTOFMEMORY, "failed SysAllocString for remote port");
697 bstrServiceName = ::SysAllocString(attrs.pwzServiceName);
698 ExitOnNull(bstrServiceName, hr, E_OUTOFMEMORY, "failed SysAllocString for service name");
699
700 if (fUpdateRule)
701 {
702 hr = pNetFwRule->get_Protocol(&iProtocol);
703 ExitOnFailure(hr, "failed to get exception protocol");
298 704
299 hr = ::CoCreateInstance(__uuidof(NetFwRule), NULL, CLSCTX_ALL, __uuidof(INetFwRule), (void**)&pNetFwRule); 705 // If you are editing a TCP port rule and converting it into an ICMP rule,
300 ExitOnFailure(hr, "failed to create NetFwRule object"); 706 // first delete the ports, change protocol from TCP to ICMP, and then add the ports.
301 707
302 hr = pNetFwRule->put_Name(bstrName); 708 switch (iProtocol)
303 ExitOnFailure(hr, "failed to set exception name"); 709 {
710 case NET_FW_IP_PROTOCOL_ANY:
711 break;
304 712
305 hr = pNetFwRule->put_Profiles(static_cast<NET_FW_PROFILE_TYPE2>(attrs.iProfile)); 713 case 1: // ICMP
306 ExitOnFailure(hr, "failed to set exception profile"); 714 hr = pNetFwRule->put_IcmpTypesAndCodes(NULL);
715 ExitOnFailure(hr, "failed to remove exception icmp types and codes");
716 // fall through and reset ports too
307 717
718 default:
719 hr = pNetFwRule->put_LocalPorts(NULL);
720 ExitOnFailure(hr, "failed to update exception local ports to NULL");
721
722 hr = pNetFwRule->put_RemotePorts(NULL);
723 ExitOnFailure(hr, "failed to update exception remote ports to NULL");
724 break;
725 }
726 }
727
728 if (MSI_NULL_INTEGER != attrs.iProfile)
729 {
730 hr = pNetFwRule->put_Profiles(static_cast<NET_FW_PROFILE_TYPE2> (attrs.iProfile));
731 ExitOnFailure(hr, "failed to set exception profile");
732 }
733 else if (fUpdateRule)
734 {
735 hr = pNetFwRule->put_Profiles(NET_FW_PROFILE2_ALL);
736 ExitOnFailure(hr, "failed to reset exception profile to all");
737 }
738
739 // The Protocol property must be set before the LocalPorts/RemotePorts properties or an error will be returned.
308 if (MSI_NULL_INTEGER != attrs.iProtocol) 740 if (MSI_NULL_INTEGER != attrs.iProtocol)
309 { 741 {
310 hr = pNetFwRule->put_Protocol(static_cast<NET_FW_IP_PROTOCOL>(attrs.iProtocol)); 742 hr = pNetFwRule->put_Protocol(static_cast<NET_FW_IP_PROTOCOL> (attrs.iProtocol));
311 ExitOnFailure(hr, "failed to set exception protocol"); 743 ExitOnFailure(hr, "failed to set exception protocol");
312 } 744 }
745 else if (fUpdateRule)
746 {
747 if ((bstrPort && *bstrPort) || (bstrRemotePort && *bstrRemotePort))
748 {
749 // default protocol is "TCP" in the WiX firewall compiler if a port is specified
750 hr = pNetFwRule->put_Protocol(NET_FW_IP_PROTOCOL_TCP);
751 ExitOnFailure(hr, "failed to reset exception protocol to TCP");
752 }
753 else
754 {
755 hr = pNetFwRule->put_Protocol(NET_FW_IP_PROTOCOL_ANY);
756 ExitOnFailure(hr, "failed to reset exception protocol to ANY");
757 }
758 }
313 759
314 if (bstrPort && *bstrPort) 760 if (bstrPort && *bstrPort)
315 { 761 {
316 hr = pNetFwRule->put_LocalPorts(bstrPort); 762 hr = pNetFwRule->put_LocalPorts(bstrPort);
317 ExitOnFailure(hr, "failed to set exception port"); 763 ExitOnFailure(hr, "failed to set exception local ports '%ls'", bstrPort);
318 } 764 }
319 765
320 if (bstrRemoteAddresses && *bstrRemoteAddresses) 766 if (bstrRemoteAddresses && *bstrRemoteAddresses)
@@ -322,122 +768,195 @@ static HRESULT CreateFwRuleObject(
322 hr = pNetFwRule->put_RemoteAddresses(bstrRemoteAddresses); 768 hr = pNetFwRule->put_RemoteAddresses(bstrRemoteAddresses);
323 ExitOnFailure(hr, "failed to set exception remote addresses '%ls'", bstrRemoteAddresses); 769 ExitOnFailure(hr, "failed to set exception remote addresses '%ls'", bstrRemoteAddresses);
324 } 770 }
771 else if (fUpdateRule)
772 {
773 hr = pNetFwRule->put_RemoteAddresses(bstrEmpty);
774 ExitOnFailure(hr, "failed to remove exception remote addresses");
775 }
325 776
326 if (bstrDescription && *bstrDescription) 777 if (bstrDescription && *bstrDescription)
327 { 778 {
328 hr = pNetFwRule->put_Description(bstrDescription); 779 hr = pNetFwRule->put_Description(bstrDescription);
329 ExitOnFailure(hr, "failed to set exception description '%ls'", bstrDescription); 780 ExitOnFailure(hr, "failed to set exception description '%ls'", bstrDescription);
330 } 781 }
782 else if (fUpdateRule)
783 {
784 hr = pNetFwRule->put_Description(bstrEmpty);
785 ExitOnFailure(hr, "failed to remove exception description");
786 }
331 787
332 if (MSI_NULL_INTEGER != attrs.iDirection) 788 if (MSI_NULL_INTEGER != attrs.iDirection)
333 { 789 {
334 hr = pNetFwRule->put_Direction(static_cast<NET_FW_RULE_DIRECTION> (attrs.iDirection)); 790 hr = pNetFwRule->put_Direction(static_cast<NET_FW_RULE_DIRECTION> (attrs.iDirection));
335 ExitOnFailure(hr, "failed to set exception direction"); 791 ExitOnFailure(hr, "failed to set exception direction");
336 } 792 }
793 else if (fUpdateRule)
794 {
795 hr = pNetFwRule->put_Direction(NET_FW_RULE_DIR_IN);
796 ExitOnFailure(hr, "failed to reset exception direction to in");
797 }
337 798
338 *ppNetFwRule = pNetFwRule; 799 if (MSI_NULL_INTEGER != attrs.iAction)
339 pNetFwRule = NULL; 800 {
801 hr = pNetFwRule->put_Action(static_cast<NET_FW_ACTION> (attrs.iAction));
802 ExitOnFailure(hr, "failed to set exception action");
803 }
804 else if (fUpdateRule)
805 {
806 hr = pNetFwRule->put_Action(NET_FW_ACTION_ALLOW);
807 ExitOnFailure(hr, "failed to reset exception action to allow");
808 }
340 809
341LExit: 810 if (bstrFile && *bstrFile)
342 ReleaseBSTR(bstrRemoteAddresses); 811 {
343 ReleaseBSTR(bstrPort); 812 hr = pNetFwRule->put_ApplicationName(bstrFile);
344 ReleaseBSTR(bstrDescription); 813 ExitOnFailure(hr, "failed to set exception application name");
345 ReleaseObject(pNetFwRule); 814 }
815 else if (fUpdateRule)
816 {
817 hr = pNetFwRule->put_ApplicationName(NULL);
818 ExitOnFailure(hr, "failed to remove exception application name");
819 }
346 820
347 return hr; 821 if (MSI_NULL_INTEGER != attrs.iEdgeTraversal)
348} 822 {
823 switch (attrs.iEdgeTraversal)
824 {
825 default:
826 hr = pNetFwRule->put_EdgeTraversal(NET_FW_EDGE_TRAVERSAL_TYPE_DENY != attrs.iEdgeTraversal ? VARIANT_TRUE : VARIANT_FALSE);
827 ExitOnFailure(hr, "failed to set exception edge traversal");
828 break;
349 829
350/****************************************************************** 830 // handled by put_EdgeTraversalOptions
351 AddApplicationException 831 case NET_FW_EDGE_TRAVERSAL_TYPE_DEFER_TO_APP:
832 case NET_FW_EDGE_TRAVERSAL_TYPE_DEFER_TO_USER:
833 break;
834 }
835 }
836 else if (fUpdateRule)
837 {
838 hr = pNetFwRule->put_EdgeTraversal(VARIANT_FALSE);
839 ExitOnFailure(hr, "failed to remove exception edge traversal");
840 }
352 841
353********************************************************************/ 842 // enable even when iEnabled == MSI_NULL_INTEGER
354static HRESULT AddApplicationException( 843 hr = pNetFwRule->put_Enabled(attrs.iEnabled ? VARIANT_TRUE : VARIANT_FALSE);
355 __in FIREWALL_EXCEPTION_ATTRIBUTES const& attrs, 844 ExitOnFailure(hr, "failed to set exception enabled flag");
356 __in BOOL fIgnoreFailures
357 )
358{
359 HRESULT hr = S_OK;
360 BSTR bstrFile = NULL;
361 BSTR bstrName = NULL;
362 INetFwRules* pNetFwRules = NULL;
363 INetFwRule* pNetFwRule = NULL;
364 845
365 // convert to BSTRs to make COM happy 846 if (bstrGrouping && *bstrGrouping)
366 bstrFile = ::SysAllocString(attrs.pwzProgram); 847 {
367 ExitOnNull(bstrFile, hr, E_OUTOFMEMORY, "failed SysAllocString for path"); 848 hr = pNetFwRule->put_Grouping(bstrGrouping);
368 bstrName = ::SysAllocString(attrs.pwzName); 849 ExitOnFailure(hr, "failed to set exception grouping '%ls'", bstrGrouping);
369 ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "failed SysAllocString for name"); 850 }
851 else if (fUpdateRule)
852 {
853 hr = pNetFwRule->put_Grouping(bstrEmpty);
854 ExitOnFailure(hr, "failed to remove exception grouping");
855 }
370 856
371 // get the collection of firewall rules 857 if (bstrIcmpTypesAndCodes && *bstrIcmpTypesAndCodes)
372 hr = GetFirewallRules(fIgnoreFailures, &pNetFwRules);
373 ExitOnFailure(hr, "failed to get firewall rules object");
374 if (S_FALSE == hr) // user or package author chose to ignore missing firewall
375 { 858 {
376 ExitFunction(); 859 hr = pNetFwRule->put_IcmpTypesAndCodes(bstrIcmpTypesAndCodes);
860 ExitOnFailure(hr, "failed to set exception icmp types and codes '%ls'", bstrIcmpTypesAndCodes);
377 } 861 }
378 862
379 // try to find it (i.e., support reinstall) 863 hr = GetFwRuleInterfaces(attrs, vInterfaces);
380 hr = pNetFwRules->Item(bstrName, &pNetFwRule); 864 ExitOnFailure(hr, "failed to prepare exception interfaces '%ls'", attrs.pwzInterfaces);
381 if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) 865
866 if (attrs.pwzInterfaces && *attrs.pwzInterfaces)
382 { 867 {
383 hr = CreateFwRuleObject(bstrName, attrs, &pNetFwRule); 868 hr = pNetFwRule->put_Interfaces(vInterfaces);
384 ExitOnFailure(hr, "failed to create FwRule object"); 869 ExitOnFailure(hr, "failed to set exception interfaces '%ls'", attrs.pwzInterfaces);
870 }
871 else if (fUpdateRule)
872 {
873 hr = pNetFwRule->put_Interfaces(vInterfaces);
874 ExitOnFailure(hr, "failed to remove exception interfaces");
875 }
385 876
386 // set edge traversal to true 877 if (bstrInterfaceTypes && *bstrInterfaceTypes)
387 hr = pNetFwRule->put_EdgeTraversal(VARIANT_TRUE); 878 {
388 ExitOnFailure(hr, "failed to set application exception edgetraversal property"); 879 hr = pNetFwRule->put_InterfaceTypes(bstrInterfaceTypes);
389 880 ExitOnFailure(hr, "failed to set exception interface types '%ls'", bstrInterfaceTypes);
390 // set path
391 hr = pNetFwRule->put_ApplicationName(bstrFile);
392 ExitOnFailure(hr, "failed to set application name");
393
394 // enable it
395 hr = pNetFwRule->put_Enabled(VARIANT_TRUE);
396 ExitOnFailure(hr, "failed to to enable application exception");
397
398 // add it to the list of authorized apps
399 hr = pNetFwRules->Add(pNetFwRule);
400 ExitOnFailure(hr, "failed to add app to the authorized apps list");
401 } 881 }
402 else 882 else if (fUpdateRule)
403 { 883 {
404 // we found an existing app exception (if we succeeded, that is) 884 hr = pNetFwRule->put_InterfaceTypes(bstrEmpty);
405 ExitOnFailure(hr, "failed trying to find existing app"); 885 ExitOnFailure(hr, "failed to remove exception interface types");
406 886 }
407 // enable it (just in case it was disabled) 887
408 pNetFwRule->put_Enabled(VARIANT_TRUE); 888 if (bstrLocalAddresses && *bstrLocalAddresses)
889 {
890 hr = pNetFwRule->put_LocalAddresses(bstrLocalAddresses);
891 ExitOnFailure(hr, "failed to set exception local addresses '%ls'", bstrLocalAddresses);
892 }
893 else if (fUpdateRule)
894 {
895 hr = pNetFwRule->put_LocalAddresses(bstrEmpty);
896 ExitOnFailure(hr, "failed to remove exception local addresses");
897 }
898
899 if (bstrRemotePort && *bstrRemotePort)
900 {
901 hr = pNetFwRule->put_RemotePorts(bstrRemotePort);
902 ExitOnFailure(hr, "failed to set exception remote ports '%ls'", bstrRemotePort);
903 }
904
905 if (bstrServiceName && *bstrServiceName)
906 {
907 hr = pNetFwRule->put_ServiceName(bstrServiceName);
908 ExitOnFailure(hr, "failed to set exception service name '%ls'", bstrServiceName);
909 }
910 else if (fUpdateRule)
911 {
912 hr = pNetFwRule->put_ServiceName(NULL);
913 ExitOnFailure(hr, "failed to remove exception service name");
409 } 914 }
410 915
411LExit: 916LExit:
412 ReleaseBSTR(bstrName); 917 ReleaseBSTR(bstrRemoteAddresses);
413 ReleaseBSTR(bstrFile); 918 ReleaseBSTR(bstrFile);
414 ReleaseObject(pNetFwRules); 919 ReleaseBSTR(bstrPort);
415 ReleaseObject(pNetFwRule); 920 ReleaseBSTR(bstrDescription);
921 ReleaseBSTR(bstrGrouping);
922 ReleaseBSTR(bstrIcmpTypesAndCodes);
923 ReleaseBSTR(bstrInterfaceTypes);
924 ReleaseBSTR(bstrLocalAddresses);
925 ReleaseBSTR(bstrRemotePort);
926 ReleaseBSTR(bstrServiceName);
927 ReleaseVariant(vInterfaces);
928 ReleaseObject(pNetFwRule2);
416 929
417 return fIgnoreFailures ? S_OK : hr; 930 return hr;
418} 931}
419 932
420/****************************************************************** 933
421 AddPortException 934/*******************************************************************
935 AddFirewallException
422 936
423********************************************************************/ 937********************************************************************/
424static HRESULT AddPortException( 938static HRESULT AddFirewallException(
425 __in FIREWALL_EXCEPTION_ATTRIBUTES const& attrs, 939 __in FIREWALL_EXCEPTION_ATTRIBUTES const& attrs,
426 __in BOOL fIgnoreFailures 940 __in BOOL fIgnoreFailures
427 ) 941)
428{ 942{
429 HRESULT hr = S_OK; 943 HRESULT hr = S_OK;
430 BSTR bstrName = NULL; 944 BSTR bstrName = NULL;
431 INetFwRules* pNetFwRules = NULL; 945 INetFwRules* pNetFwRules = NULL;
432 INetFwRule* pNetFwRule = NULL; 946 INetFwRule* pNetFwRule = NULL;
433 947
948 BOOL fIgnoreUpdates = feaIgnoreUpdates == (attrs.iAttributes & feaIgnoreUpdates);
949 BOOL fEnableOnUpdate = feaEnableOnUpdate == (attrs.iAttributes & feaEnableOnUpdate);
950 BOOL fAddINetFwRule2 = feaAddINetFwRule2 == (attrs.iAttributes & feaAddINetFwRule2);
951 BOOL fAddINetFwRule3 = feaAddINetFwRule3 == (attrs.iAttributes & feaAddINetFwRule3);
952
434 // convert to BSTRs to make COM happy 953 // convert to BSTRs to make COM happy
435 bstrName = ::SysAllocString(attrs.pwzName); 954 bstrName = ::SysAllocString(attrs.pwzName);
436 ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "failed SysAllocString for name"); 955 ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "failed SysAllocString for name");
437 956
438 // get the collection of firewall rules 957 // get the collection of firewall rules
439 hr = GetFirewallRules(fIgnoreFailures, &pNetFwRules); 958 hr = GetFirewallRules(fIgnoreFailures, &pNetFwRules);
440 ExitOnFailure(hr, "failed to get firewall rules object"); 959 ExitOnFailure(hr, "failed to get firewall exception object");
441 if (S_FALSE == hr) // user or package author chose to ignore missing firewall 960 if (S_FALSE == hr) // user or package author chose to ignore missing firewall
442 { 961 {
443 ExitFunction(); 962 ExitFunction();
@@ -447,24 +966,56 @@ static HRESULT AddPortException(
447 hr = pNetFwRules->Item(bstrName, &pNetFwRule); 966 hr = pNetFwRules->Item(bstrName, &pNetFwRule);
448 if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) 967 if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
449 { 968 {
450 hr = CreateFwRuleObject(bstrName, attrs, &pNetFwRule); 969 hr = CreateFwRuleObject(bstrName, &pNetFwRule);
451 ExitOnFailure(hr, "failed to create FwRule object"); 970 ExitOnFailure(hr, "failed to create FwRule object '%ls'", attrs.pwzName);
452 971
453 // enable it 972 // set attributes of the new firewall rule
454 hr = pNetFwRule->put_Enabled(VARIANT_TRUE); 973 hr = UpdateFwRuleObject(pNetFwRule, FALSE, attrs);
455 ExitOnFailure(hr, "failed to to enable port exception"); 974 ExitOnFailure(hr, "failed to create INetFwRule firewall exception '%ls'", attrs.pwzName);
975
976 if (fAddINetFwRule2)
977 {
978 hr = UpdateFwRule2Object(pNetFwRule, FALSE, attrs);
979 ExitOnFailure(hr, "failed to create INetFwRule2 firewall exception '%ls'", attrs.pwzName);
980 }
981
982 if (fAddINetFwRule3)
983 {
984 hr = UpdateFwRule3Object(pNetFwRule, FALSE, attrs);
985 ExitOnFailure(hr, "failed to create INetFwRule3 firewall exception '%ls'", attrs.pwzName);
986 }
456 987
457 // add it to the list of authorized ports
458 hr = pNetFwRules->Add(pNetFwRule); 988 hr = pNetFwRules->Add(pNetFwRule);
459 ExitOnFailure(hr, "failed to add app to the authorized ports list"); 989 ExitOnFailure(hr, "failed to add firewall exception '%ls' to the list", attrs.pwzName);
460 } 990 }
461 else 991 else
462 { 992 {
463 // we found an existing port exception (if we succeeded, that is) 993 // we found an existing firewall rule (if we succeeded, that is)
464 ExitOnFailure(hr, "failed trying to find existing port rule"); 994 ExitOnFailure(hr, "failed trying to find existing firewall exception '%ls'", attrs.pwzName);
995
996 if (fEnableOnUpdate)
997 {
998 hr = pNetFwRule->put_Enabled(VARIANT_TRUE);
999 ExitOnFailure(hr, "failed to enable existing firewall exception '%ls'", attrs.pwzName);
1000 }
1001 else if (!fIgnoreUpdates)
1002 {
1003 // overwrite attributes of the existing firewall rule
1004 hr = UpdateFwRuleObject(pNetFwRule, TRUE, attrs);
1005 ExitOnFailure(hr, "failed to update INetFwRule firewall exception '%ls'", attrs.pwzName);
465 1006
466 // enable it (just in case it was disabled) 1007 if (fAddINetFwRule2)
467 pNetFwRule->put_Enabled(VARIANT_TRUE); 1008 {
1009 hr = UpdateFwRule2Object(pNetFwRule, TRUE, attrs);
1010 ExitOnFailure(hr, "failed to update INetFwRule2 firewall exception '%ls'", attrs.pwzName);
1011 }
1012
1013 if (fAddINetFwRule3)
1014 {
1015 hr = UpdateFwRule3Object(pNetFwRule, TRUE, attrs);
1016 ExitOnFailure(hr, "failed to update INetFwRule3 firewall exception '%ls'", attrs.pwzName);
1017 }
1018 }
468 } 1019 }
469 1020
470LExit: 1021LExit:
@@ -475,14 +1026,15 @@ LExit:
475 return fIgnoreFailures ? S_OK : hr; 1026 return fIgnoreFailures ? S_OK : hr;
476} 1027}
477 1028
478/****************************************************************** 1029
1030/*******************************************************************
479 RemoveException - Removes all exception rules with the given name. 1031 RemoveException - Removes all exception rules with the given name.
480 1032
481********************************************************************/ 1033********************************************************************/
482static HRESULT RemoveException( 1034static HRESULT RemoveException(
483 __in LPCWSTR wzName, 1035 __in LPCWSTR wzName,
484 __in BOOL fIgnoreFailures 1036 __in BOOL fIgnoreFailures
485 ) 1037)
486{ 1038{
487 HRESULT hr = S_OK;; 1039 HRESULT hr = S_OK;;
488 INetFwRules* pNetFwRules = NULL; 1040 INetFwRules* pNetFwRules = NULL;
@@ -500,7 +1052,7 @@ static HRESULT RemoveException(
500 } 1052 }
501 1053
502 hr = pNetFwRules->Remove(bstrName); 1054 hr = pNetFwRules->Remove(bstrName);
503 ExitOnFailure(hr, "failed to remove firewall rule"); 1055 ExitOnFailure(hr, "failed to remove firewall exception for name %ls", wzName);
504 1056
505LExit: 1057LExit:
506 ReleaseBSTR(bstrName); 1058 ReleaseBSTR(bstrName);
@@ -509,20 +1061,20 @@ LExit:
509 return fIgnoreFailures ? S_OK : hr; 1061 return fIgnoreFailures ? S_OK : hr;
510} 1062}
511 1063
512/****************************************************************** 1064
513 ExecFirewallExceptions - deferred custom action entry point to 1065/*******************************************************************
1066 ExecFirewallExceptions - deferred custom action entry point to
514 register and remove firewall exceptions. 1067 register and remove firewall exceptions.
515 1068
516********************************************************************/ 1069********************************************************************/
517extern "C" UINT __stdcall ExecFirewallExceptions( 1070extern "C" UINT __stdcall ExecFirewallExceptions(
518 __in MSIHANDLE hInstall 1071 __in MSIHANDLE hInstall
519 ) 1072)
520{ 1073{
521 HRESULT hr = S_OK; 1074 HRESULT hr = S_OK;
522 LPWSTR pwz = NULL; 1075 LPWSTR pwz = NULL;
523 LPWSTR pwzCustomActionData = NULL; 1076 LPWSTR pwzCustomActionData = NULL;
524 int iTodo = WCA_TODO_UNKNOWN; 1077 int iTodo = WCA_TODO_UNKNOWN;
525 int iTarget = fetUnknown;
526 1078
527 FIREWALL_EXCEPTION_ATTRIBUTES attrs = { 0 }; 1079 FIREWALL_EXCEPTION_ATTRIBUTES attrs = { 0 };
528 1080
@@ -530,7 +1082,7 @@ extern "C" UINT __stdcall ExecFirewallExceptions(
530 hr = WcaInitialize(hInstall, "ExecFirewallExceptions"); 1082 hr = WcaInitialize(hInstall, "ExecFirewallExceptions");
531 ExitOnFailure(hr, "failed to initialize"); 1083 ExitOnFailure(hr, "failed to initialize");
532 1084
533 hr = WcaGetProperty( L"CustomActionData", &pwzCustomActionData); 1085 hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData);
534 ExitOnFailure(hr, "failed to get CustomActionData"); 1086 ExitOnFailure(hr, "failed to get CustomActionData");
535 WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzCustomActionData); 1087 WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzCustomActionData);
536 1088
@@ -569,60 +1121,82 @@ extern "C" UINT __stdcall ExecFirewallExceptions(
569 ExitOnFailure(hr, "failed to read attributes from custom action data"); 1121 ExitOnFailure(hr, "failed to read attributes from custom action data");
570 BOOL fIgnoreFailures = feaIgnoreFailures == (attrs.iAttributes & feaIgnoreFailures); 1122 BOOL fIgnoreFailures = feaIgnoreFailures == (attrs.iAttributes & feaIgnoreFailures);
571 1123
572 hr = WcaReadIntegerFromCaData(&pwz, &iTarget); 1124 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzApplicationName);
573 ExitOnFailure(hr, "failed to read target from custom action data"); 1125 ExitOnFailure(hr, "failed to read file path from custom action data");
574 1126
575 if (iTarget == fetApplication) 1127 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzLocalPorts);
576 {
577 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzProgram);
578 ExitOnFailure(hr, "failed to read file path from custom action data");
579 }
580
581 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzPort);
582 ExitOnFailure(hr, "failed to read port from custom action data"); 1128 ExitOnFailure(hr, "failed to read port from custom action data");
1129
583 hr = WcaReadIntegerFromCaData(&pwz, &attrs.iProtocol); 1130 hr = WcaReadIntegerFromCaData(&pwz, &attrs.iProtocol);
584 ExitOnFailure(hr, "failed to read protocol from custom action data"); 1131 ExitOnFailure(hr, "failed to read protocol from custom action data");
1132
585 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzDescription); 1133 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzDescription);
586 ExitOnFailure(hr, "failed to read protocol from custom action data"); 1134 ExitOnFailure(hr, "failed to read protocol from custom action data");
1135
587 hr = WcaReadIntegerFromCaData(&pwz, &attrs.iDirection); 1136 hr = WcaReadIntegerFromCaData(&pwz, &attrs.iDirection);
588 ExitOnFailure(hr, "failed to read direction from custom action data"); 1137 ExitOnFailure(hr, "failed to read direction from custom action data");
589 1138
590 switch (iTarget) 1139 hr = WcaReadIntegerFromCaData(&pwz, &attrs.iAction);
591 { 1140 ExitOnFailure(hr, "failed to read action from custom action data");
592 case fetPort:
593 switch (iTodo)
594 {
595 case WCA_TODO_INSTALL:
596 case WCA_TODO_REINSTALL:
597 WcaLog(LOGMSG_STANDARD, "Installing firewall exception %ls on port %ls, protocol %d", attrs.pwzName, attrs.pwzPort, attrs.iProtocol);
598 hr = AddPortException(attrs, fIgnoreFailures);
599 ExitOnFailure(hr, "failed to add/update port exception for name '%ls' on port %ls, protocol %d", attrs.pwzName, attrs.pwzPort, attrs.iProtocol);
600 break;
601 1141
602 case WCA_TODO_UNINSTALL: 1142 hr = WcaReadIntegerFromCaData(&pwz, &attrs.iEdgeTraversal);
603 WcaLog(LOGMSG_STANDARD, "Uninstalling firewall exception %ls on port %ls, protocol %d", attrs.pwzName, attrs.pwzPort, attrs.iProtocol); 1143 ExitOnFailure(hr, "failed to read edge traversal from custom action data");
604 hr = RemoveException(attrs.pwzName, fIgnoreFailures);
605 ExitOnFailure(hr, "failed to remove port exception for name '%ls' on port %ls, protocol %d", attrs.pwzName, attrs.pwzPort, attrs.iProtocol);
606 break;
607 }
608 break;
609 1144
610 case fetApplication: 1145 hr = WcaReadIntegerFromCaData(&pwz, &attrs.iEnabled);
611 switch (iTodo) 1146 ExitOnFailure(hr, "failed to read enabled flag from custom action data");
612 {
613 case WCA_TODO_INSTALL:
614 case WCA_TODO_REINSTALL:
615 WcaLog(LOGMSG_STANDARD, "Installing firewall exception %ls (%ls)", attrs.pwzName, attrs.pwzProgram);
616 hr = AddApplicationException(attrs, fIgnoreFailures);
617 ExitOnFailure(hr, "failed to add/update application exception for name '%ls', file '%ls'", attrs.pwzName, attrs.pwzProgram);
618 break;
619 1147
620 case WCA_TODO_UNINSTALL: 1148 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzGrouping);
621 WcaLog(LOGMSG_STANDARD, "Uninstalling firewall exception %ls (%ls)", attrs.pwzName, attrs.pwzProgram); 1149 ExitOnFailure(hr, "failed to read grouping from custom action data");
622 hr = RemoveException(attrs.pwzName, fIgnoreFailures); 1150
623 ExitOnFailure(hr, "failed to remove application exception for name '%ls', file '%ls'", attrs.pwzName, attrs.pwzProgram); 1151 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzIcmpTypesAndCodes);
624 break; 1152 ExitOnFailure(hr, "failed to read icmp types and codes from custom action data");
625 } 1153
1154 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzInterfaces);
1155 ExitOnFailure(hr, "failed to read interfaces from custom action data");
1156
1157 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzInterfaceTypes);
1158 ExitOnFailure(hr, "failed to read interface types from custom action data");
1159
1160 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzLocalAddresses);
1161 ExitOnFailure(hr, "failed to read local addresses from custom action data");
1162
1163 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzRemotePorts);
1164 ExitOnFailure(hr, "failed to read remote port from custom action data");
1165
1166 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzServiceName);
1167 ExitOnFailure(hr, "failed to read service name from custom action data");
1168
1169 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzLocalAppPackageId);
1170 ExitOnFailure(hr, "failed to read local app package id from custom action data");
1171
1172 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzLocalUserAuthorizedList);
1173 ExitOnFailure(hr, "failed to read local user authorized list from custom action data");
1174
1175 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzLocalUserOwner);
1176 ExitOnFailure(hr, "failed to read local user owner from custom action data");
1177
1178 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzRemoteMachineAuthorizedList);
1179 ExitOnFailure(hr, "failed to read remote machine authorized list from custom action data");
1180
1181 hr = WcaReadStringFromCaData(&pwz, &attrs.pwzRemoteUserAuthorizedList);
1182 ExitOnFailure(hr, "failed to read remote user authorized list from custom action data");
1183
1184 hr = WcaReadIntegerFromCaData(&pwz, &attrs.iSecureFlags);
1185 ExitOnFailure(hr, "failed to read exception secure flags from custom action data");
1186
1187 switch (iTodo)
1188 {
1189 case WCA_TODO_INSTALL:
1190 case WCA_TODO_REINSTALL:
1191 WcaLog(LOGMSG_STANDARD, "Installing firewall exception %ls", attrs.pwzName);
1192 hr = AddFirewallException(attrs, fIgnoreFailures);
1193 ExitOnFailure(hr, "failed to add/update firewall exception for name '%ls'", attrs.pwzName);
1194 break;
1195
1196 case WCA_TODO_UNINSTALL:
1197 WcaLog(LOGMSG_STANDARD, "Uninstalling firewall exception %ls", attrs.pwzName);
1198 hr = RemoveException(attrs.pwzName, fIgnoreFailures);
1199 ExitOnFailure(hr, "failed to remove firewall exception");
626 break; 1200 break;
627 } 1201 }
628 } 1202 }
@@ -631,9 +1205,21 @@ LExit:
631 ReleaseStr(pwzCustomActionData); 1205 ReleaseStr(pwzCustomActionData);
632 ReleaseStr(attrs.pwzName); 1206 ReleaseStr(attrs.pwzName);
633 ReleaseStr(attrs.pwzRemoteAddresses); 1207 ReleaseStr(attrs.pwzRemoteAddresses);
634 ReleaseStr(attrs.pwzProgram); 1208 ReleaseStr(attrs.pwzApplicationName);
635 ReleaseStr(attrs.pwzPort); 1209 ReleaseStr(attrs.pwzLocalPorts);
636 ReleaseStr(attrs.pwzDescription); 1210 ReleaseStr(attrs.pwzDescription);
1211 ReleaseStr(attrs.pwzGrouping);
1212 ReleaseStr(attrs.pwzIcmpTypesAndCodes);
1213 ReleaseStr(attrs.pwzInterfaces);
1214 ReleaseStr(attrs.pwzInterfaceTypes);
1215 ReleaseStr(attrs.pwzLocalAddresses);
1216 ReleaseStr(attrs.pwzRemotePorts);
1217 ReleaseStr(attrs.pwzServiceName);
1218 ReleaseStr(attrs.pwzLocalAppPackageId);
1219 ReleaseStr(attrs.pwzLocalUserAuthorizedList);
1220 ReleaseStr(attrs.pwzLocalUserOwner);
1221 ReleaseStr(attrs.pwzRemoteMachineAuthorizedList);
1222 ReleaseStr(attrs.pwzRemoteUserAuthorizedList);
637 ::CoUninitialize(); 1223 ::CoUninitialize();
638 1224
639 return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS); 1225 return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS);