aboutsummaryrefslogtreecommitdiff
path: root/src/ext/Firewall/wixext
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2021-05-04 22:46:07 -0700
committerRob Mensching <rob@firegiant.com>2021-05-04 22:46:07 -0700
commitba00d844a2e2716a6aa07df89dd9318608bd1909 (patch)
tree0738ebcbcea51a9e4736efbbc19c68d17202ecad /src/ext/Firewall/wixext
parentbfabd9f718af70e59f24ac70046fa3141daf06e8 (diff)
downloadwix-ba00d844a2e2716a6aa07df89dd9318608bd1909.tar.gz
wix-ba00d844a2e2716a6aa07df89dd9318608bd1909.tar.bz2
wix-ba00d844a2e2716a6aa07df89dd9318608bd1909.zip
Move Firewall.wixext into ext
Diffstat (limited to 'src/ext/Firewall/wixext')
-rw-r--r--src/ext/Firewall/wixext/FirewallCompiler.cs354
-rw-r--r--src/ext/Firewall/wixext/FirewallConstants.cs23
-rw-r--r--src/ext/Firewall/wixext/FirewallDecompiler.cs182
-rw-r--r--src/ext/Firewall/wixext/FirewallErrors.cs36
-rw-r--r--src/ext/Firewall/wixext/FirewallExtensionData.cs23
-rw-r--r--src/ext/Firewall/wixext/FirewallExtensionFactory.cs18
-rw-r--r--src/ext/Firewall/wixext/FirewallTableDefinitions.cs34
-rw-r--r--src/ext/Firewall/wixext/FirewallWindowsInstallerBackendExtension.cs13
-rw-r--r--src/ext/Firewall/wixext/Symbols/FirewallSymbolDefinitions.cs39
-rw-r--r--src/ext/Firewall/wixext/Symbols/WixFirewallExceptionSymbol.cs119
-rw-r--r--src/ext/Firewall/wixext/WixToolset.Firewall.wixext.csproj31
-rw-r--r--src/ext/Firewall/wixext/WixToolset.Firewall.wixext.targets11
12 files changed, 883 insertions, 0 deletions
diff --git a/src/ext/Firewall/wixext/FirewallCompiler.cs b/src/ext/Firewall/wixext/FirewallCompiler.cs
new file mode 100644
index 00000000..cbe82d37
--- /dev/null
+++ b/src/ext/Firewall/wixext/FirewallCompiler.cs
@@ -0,0 +1,354 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Firewall
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Xml.Linq;
8 using WixToolset.Data;
9 using WixToolset.Extensibility;
10 using WixToolset.Extensibility.Data;
11 using WixToolset.Firewall.Symbols;
12
13 /// <summary>
14 /// The compiler for the WiX Toolset Firewall Extension.
15 /// </summary>
16 public sealed class FirewallCompiler : BaseCompilerExtension
17 {
18 public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/firewall";
19
20 /// <summary>
21 /// Processes an element for the Compiler.
22 /// </summary>
23 /// <param name="sourceLineNumbers">Source line number for the parent element.</param>
24 /// <param name="parentElement">Parent element of element to process.</param>
25 /// <param name="element">Element to process.</param>
26 /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param>
27 public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
28 {
29 switch (parentElement.Name.LocalName)
30 {
31 case "File":
32 var fileId = context["FileId"];
33 var fileComponentId = context["ComponentId"];
34
35 switch (element.Name.LocalName)
36 {
37 case "FirewallException":
38 this.ParseFirewallExceptionElement(intermediate, section, element, fileComponentId, fileId);
39 break;
40 default:
41 this.ParseHelper.UnexpectedElement(parentElement, element);
42 break;
43 }
44 break;
45 case "Component":
46 var componentId = context["ComponentId"];
47
48 switch (element.Name.LocalName)
49 {
50 case "FirewallException":
51 this.ParseFirewallExceptionElement(intermediate, section, element, componentId, null);
52 break;
53 default:
54 this.ParseHelper.UnexpectedElement(parentElement, element);
55 break;
56 }
57 break;
58 default:
59 this.ParseHelper.UnexpectedElement(parentElement, element);
60 break;
61 }
62 }
63
64 /// <summary>
65 /// Parses a FirewallException element.
66 /// </summary>
67 /// <param name="element">The element to parse.</param>
68 /// <param name="componentId">Identifier of the component that owns this firewall exception.</param>
69 /// <param name="fileId">The file identifier of the parent element (null if nested under Component).</param>
70 private void ParseFirewallExceptionElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId, string fileId)
71 {
72 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
73 Identifier id = null;
74 string name = null;
75 int attributes = 0;
76 string file = null;
77 string program = null;
78 string port = null;
79 int? protocol = null;
80 int? profile = null;
81 string scope = null;
82 string remoteAddresses = null;
83 string description = null;
84 int? direction = null;
85
86 foreach (var attrib in element.Attributes())
87 {
88 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
89 {
90 switch (attrib.Name.LocalName)
91 {
92 case "Id":
93 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
94 break;
95 case "Name":
96 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
97 break;
98 case "File":
99 if (null != fileId)
100 {
101 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, element.Name.LocalName, "File", "File"));
102 }
103 else
104 {
105 file = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
106 }
107 break;
108 case "IgnoreFailure":
109 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
110 {
111 attributes |= 0x1; // feaIgnoreFailures
112 }
113 break;
114 case "Program":
115 if (null != fileId)
116 {
117 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, element.Name.LocalName, "Program", "File"));
118 }
119 else
120 {
121 program = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
122 }
123 break;
124 case "Port":
125 port = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
126 break;
127 case "Protocol":
128 var protocolValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
129 switch (protocolValue)
130 {
131 case "tcp":
132 protocol = FirewallConstants.NET_FW_IP_PROTOCOL_TCP;
133 break;
134 case "udp":
135 protocol = FirewallConstants.NET_FW_IP_PROTOCOL_UDP;
136 break;
137 default:
138 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Protocol", protocolValue, "tcp", "udp"));
139 break;
140 }
141 break;
142 case "Scope":
143 scope = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
144 switch (scope)
145 {
146 case "any":
147 remoteAddresses = "*";
148 break;
149 case "localSubnet":
150 remoteAddresses = "LocalSubnet";
151 break;
152 default:
153 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Scope", scope, "any", "localSubnet"));
154 break;
155 }
156 break;
157 case "Profile":
158 var profileValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
159 switch (profileValue)
160 {
161 case "domain":
162 profile = FirewallConstants.NET_FW_PROFILE2_DOMAIN;
163 break;
164 case "private":
165 profile = FirewallConstants.NET_FW_PROFILE2_PRIVATE;
166 break;
167 case "public":
168 profile = FirewallConstants.NET_FW_PROFILE2_PUBLIC;
169 break;
170 case "all":
171 profile = FirewallConstants.NET_FW_PROFILE2_ALL;
172 break;
173 default:
174 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Profile", profileValue, "domain", "private", "public", "all"));
175 break;
176 }
177 break;
178 case "Description":
179 description = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
180 break;
181 case "Outbound":
182 direction = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) == YesNoType.Yes
183 ? FirewallConstants.NET_FW_RULE_DIR_OUT
184 : FirewallConstants.NET_FW_RULE_DIR_IN;
185 break;
186 default:
187 this.ParseHelper.UnexpectedAttribute(element, attrib);
188 break;
189 }
190 }
191 else
192 {
193 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
194 }
195 }
196
197 // parse RemoteAddress children
198 foreach (var child in element.Elements())
199 {
200 if (this.Namespace == child.Name.Namespace)
201 {
202 switch (child.Name.LocalName)
203 {
204 case "RemoteAddress":
205 if (null != scope)
206 {
207 this.Messaging.Write(FirewallErrors.IllegalRemoteAddressWithScopeAttribute(sourceLineNumbers));
208 }
209 else
210 {
211 this.ParseRemoteAddressElement(intermediate, section, child, ref remoteAddresses);
212 }
213 break;
214 default:
215 this.ParseHelper.UnexpectedElement(element, child);
216 break;
217 }
218 }
219 else
220 {
221 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, element, child);
222 }
223 }
224
225 if (null == id)
226 {
227 id = this.ParseHelper.CreateIdentifier("fex", name, remoteAddresses, componentId);
228 }
229
230 // Name is required
231 if (null == name)
232 {
233 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name"));
234 }
235
236 // Scope or child RemoteAddress(es) are required
237 if (null == remoteAddresses)
238 {
239 this.Messaging.Write(ErrorMessages.ExpectedAttributeOrElement(sourceLineNumbers, element.Name.LocalName, "Scope", "RemoteAddress"));
240 }
241
242 // can't have both Program and File
243 if (null != program && null != file)
244 {
245 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "File", "Program"));
246 }
247
248 // must be nested under File, have File or Program attributes, or have Port attribute
249 if (String.IsNullOrEmpty(fileId) && String.IsNullOrEmpty(file) && String.IsNullOrEmpty(program) && String.IsNullOrEmpty(port))
250 {
251 this.Messaging.Write(FirewallErrors.NoExceptionSpecified(sourceLineNumbers));
252 }
253
254 if (!this.Messaging.EncounteredError)
255 {
256 // at this point, File attribute and File parent element are treated the same
257 if (null != file)
258 {
259 fileId = file;
260 }
261
262 var symbol = section.AddSymbol(new WixFirewallExceptionSymbol(sourceLineNumbers, id)
263 {
264 Name = name,
265 RemoteAddresses = remoteAddresses,
266 Profile = profile ?? FirewallConstants.NET_FW_PROFILE2_ALL,
267 ComponentRef = componentId,
268 Description = description,
269 Direction = direction ?? FirewallConstants.NET_FW_RULE_DIR_IN,
270 });
271
272 if (!String.IsNullOrEmpty(port))
273 {
274 symbol.Port = port;
275
276 if (!protocol.HasValue)
277 {
278 // default protocol is "TCP"
279 protocol = FirewallConstants.NET_FW_IP_PROTOCOL_TCP;
280 }
281 }
282
283 if (protocol.HasValue)
284 {
285 symbol.Protocol = protocol.Value;
286 }
287
288 if (!String.IsNullOrEmpty(fileId))
289 {
290 symbol.Program = $"[#{fileId}]";
291 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.File, fileId);
292 }
293 else if (!String.IsNullOrEmpty(program))
294 {
295 symbol.Program = program;
296 }
297
298 if (CompilerConstants.IntegerNotSet != attributes)
299 {
300 symbol.Attributes = attributes;
301 }
302
303 this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4SchedFirewallExceptionsInstall", this.Context.Platform, CustomActionPlatforms.ARM64 | CustomActionPlatforms.X64 | CustomActionPlatforms.X86);
304 this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4SchedFirewallExceptionsUninstall", this.Context.Platform, CustomActionPlatforms.ARM64 | CustomActionPlatforms.X64 | CustomActionPlatforms.X86);
305 }
306 }
307
308 /// <summary>
309 /// Parses a RemoteAddress element
310 /// </summary>
311 /// <param name="element">The element to parse.</param>
312 private void ParseRemoteAddressElement(Intermediate intermediate, IntermediateSection section, XElement element, ref string remoteAddresses)
313 {
314 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
315 string address = null;
316
317 // no attributes
318 foreach (var attrib in element.Attributes())
319 {
320 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
321 {
322 switch (attrib.Name.LocalName)
323 {
324 case "Value":
325 address = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
326 break;
327 }
328 }
329 else
330 {
331 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
332 }
333 }
334
335 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
336
337 if (String.IsNullOrEmpty(address))
338 {
339 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Value"));
340 }
341 else
342 {
343 if (String.IsNullOrEmpty(remoteAddresses))
344 {
345 remoteAddresses = address;
346 }
347 else
348 {
349 remoteAddresses = String.Concat(remoteAddresses, ",", address);
350 }
351 }
352 }
353 }
354}
diff --git a/src/ext/Firewall/wixext/FirewallConstants.cs b/src/ext/Firewall/wixext/FirewallConstants.cs
new file mode 100644
index 00000000..7bb12ba4
--- /dev/null
+++ b/src/ext/Firewall/wixext/FirewallConstants.cs
@@ -0,0 +1,23 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Firewall
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Text;
8
9 static class FirewallConstants
10 {
11 // from icftypes.h
12 public const int NET_FW_RULE_DIR_IN = 1;
13 public const int NET_FW_RULE_DIR_OUT = 2;
14 public const int NET_FW_IP_PROTOCOL_TCP = 6;
15 public const int NET_FW_IP_PROTOCOL_UDP = 17;
16
17 // from icftypes.h
18 public const int NET_FW_PROFILE2_DOMAIN = 0x0001;
19 public const int NET_FW_PROFILE2_PRIVATE = 0x0002;
20 public const int NET_FW_PROFILE2_PUBLIC = 0x0004;
21 public const int NET_FW_PROFILE2_ALL = 0x7FFFFFFF;
22 }
23}
diff --git a/src/ext/Firewall/wixext/FirewallDecompiler.cs b/src/ext/Firewall/wixext/FirewallDecompiler.cs
new file mode 100644
index 00000000..c9478de1
--- /dev/null
+++ b/src/ext/Firewall/wixext/FirewallDecompiler.cs
@@ -0,0 +1,182 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Firewall
4{
5#if TODO_CONSIDER_DECOMPILER
6 using System;
7 using System.Collections;
8 using System.Diagnostics;
9 using System.Globalization;
10 using WixToolset.Data;
11 using WixToolset.Extensibility;
12 using Firewall = WixToolset.Extensions.Serialize.Firewall;
13 using Wix = WixToolset.Data.Serialize;
14
15 /// <summary>
16 /// The decompiler for the WiX Toolset Firewall Extension.
17 /// </summary>
18 public sealed class FirewallDecompiler : DecompilerExtension
19 {
20 /// <summary>
21 /// Creates a decompiler for Firewall Extension.
22 /// </summary>
23 public FirewallDecompiler()
24 {
25 this.TableDefinitions = FirewallExtensionData.GetExtensionTableDefinitions();
26 }
27
28 /// <summary>
29 /// Get the extensions library to be removed.
30 /// </summary>
31 /// <param name="tableDefinitions">Table definitions for library.</param>
32 /// <returns>Library to remove from decompiled output.</returns>
33 public override Library GetLibraryToRemove(TableDefinitionCollection tableDefinitions)
34 {
35 return FirewallExtensionData.GetExtensionLibrary(tableDefinitions);
36 }
37
38 /// <summary>
39 /// Decompiles an extension table.
40 /// </summary>
41 /// <param name="table">The table to decompile.</param>
42 public override void DecompileTable(Table table)
43 {
44 switch (table.Name)
45 {
46 case "WixFirewallException":
47 this.DecompileWixFirewallExceptionTable(table);
48 break;
49 default:
50 base.DecompileTable(table);
51 break;
52 }
53 }
54
55 /// <summary>
56 /// Decompile the WixFirewallException table.
57 /// </summary>
58 /// <param name="table">The table to decompile.</param>
59 private void DecompileWixFirewallExceptionTable(Table table)
60 {
61 foreach (Row row in table.Rows)
62 {
63 Firewall.FirewallException fire = new Firewall.FirewallException();
64 fire.Id = (string)row[0];
65 fire.Name = (string)row[1];
66
67 string[] addresses = ((string)row[2]).Split(',');
68 if (1 == addresses.Length)
69 {
70 // special-case the Scope attribute values
71 if ("*" == addresses[0])
72 {
73 fire.Scope = Firewall.FirewallException.ScopeType.any;
74 }
75 else if ("LocalSubnet" == addresses[0])
76 {
77 fire.Scope = Firewall.FirewallException.ScopeType.localSubnet;
78 }
79 else
80 {
81 FirewallDecompiler.AddRemoteAddress(fire, addresses[0]);
82 }
83 }
84 else
85 {
86 foreach (string address in addresses)
87 {
88 FirewallDecompiler.AddRemoteAddress(fire, address);
89 }
90 }
91
92 if (!row.IsColumnEmpty(3))
93 {
94 fire.Port = (string)row[3];
95 }
96
97 if (!row.IsColumnEmpty(4))
98 {
99 switch (Convert.ToInt32(row[4]))
100 {
101 case FirewallConstants.NET_FW_IP_PROTOCOL_TCP:
102 fire.Protocol = Firewall.FirewallException.ProtocolType.tcp;
103 break;
104 case FirewallConstants.NET_FW_IP_PROTOCOL_UDP:
105 fire.Protocol = Firewall.FirewallException.ProtocolType.udp;
106 break;
107 }
108 }
109
110 if (!row.IsColumnEmpty(5))
111 {
112 fire.Program = (string)row[5];
113 }
114
115 if (!row.IsColumnEmpty(6))
116 {
117 int attr = Convert.ToInt32(row[6]);
118 if (0x1 == (attr & 0x1)) // feaIgnoreFailures
119 {
120 fire.IgnoreFailure = Firewall.YesNoType.yes;
121 }
122 }
123
124 if (!row.IsColumnEmpty(7))
125 {
126 switch (Convert.ToInt32(row[7]))
127 {
128 case FirewallConstants.NET_FW_PROFILE2_DOMAIN:
129 fire.Profile = Firewall.FirewallException.ProfileType.domain;
130 break;
131 case FirewallConstants.NET_FW_PROFILE2_PRIVATE:
132 fire.Profile = Firewall.FirewallException.ProfileType.@private;
133 break;
134 case FirewallConstants.NET_FW_PROFILE2_PUBLIC:
135 fire.Profile = Firewall.FirewallException.ProfileType.@public;
136 break;
137 case FirewallConstants.NET_FW_PROFILE2_ALL:
138 fire.Profile = Firewall.FirewallException.ProfileType.all;
139 break;
140 }
141 }
142
143 // Description column is new in v3.6
144 if (9 < row.Fields.Length && !row.IsColumnEmpty(9))
145 {
146 fire.Description = (string)row[9];
147 }
148
149 if (!row.IsColumnEmpty(10))
150 {
151 switch (Convert.ToInt32(row[10]))
152 {
153 case FirewallConstants.NET_FW_RULE_DIR_IN:
154 fire.Direction = Firewall.FirewallException.DirectionType.@in;
155 break;
156 case FirewallConstants.NET_FW_RULE_DIR_OUT:
157 fire.Direction = Firewall.FirewallException.DirectionType.@out;
158 break;
159 }
160 }
161
162 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[8]);
163 if (null != component)
164 {
165 component.AddChild(fire);
166 }
167 else
168 {
169 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[6], "Component"));
170 }
171 }
172 }
173
174 private static void AddRemoteAddress(Firewall.FirewallException fire, string address)
175 {
176 Firewall.RemoteAddress remote = new Firewall.RemoteAddress();
177 remote.Content = address;
178 fire.AddChild(remote);
179 }
180 }
181#endif
182}
diff --git a/src/ext/Firewall/wixext/FirewallErrors.cs b/src/ext/Firewall/wixext/FirewallErrors.cs
new file mode 100644
index 00000000..b2dac782
--- /dev/null
+++ b/src/ext/Firewall/wixext/FirewallErrors.cs
@@ -0,0 +1,36 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Firewall
4{
5 using System.Resources;
6 using WixToolset.Data;
7
8 public static class FirewallErrors
9 {
10 public static Message IllegalRemoteAddressWithScopeAttribute(SourceLineNumber sourceLineNumbers)
11 {
12 return Message(sourceLineNumbers, Ids.IllegalRemoteAddressWithScopeAttribute, "The RemoteAddress element cannot be specified because its parent FirewallException already specified the Scope attribute. To use RemoteAddress elements, omit the Scope attribute.");
13 }
14
15 public static Message NoExceptionSpecified(SourceLineNumber sourceLineNumbers)
16 {
17 return Message(sourceLineNumbers, Ids.NoExceptionSpecified, "The FirewallException element doesn't identify the target of the firewall exception. To create an application exception, nest the FirewallException element under a File element or provide a value for the File or Program attributes. To create a port exception, provide a value for the Port attribute.");
18 }
19
20 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args)
21 {
22 return new Message(sourceLineNumber, MessageLevel.Error, (int)id, format, args);
23 }
24
25 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, ResourceManager resourceManager, string resourceName, params object[] args)
26 {
27 return new Message(sourceLineNumber, MessageLevel.Error, (int)id, resourceManager, resourceName, args);
28 }
29
30 public enum Ids
31 {
32 IllegalRemoteAddressWithScopeAttribute = 6401,
33 NoExceptionSpecified = 6403,
34 }
35 }
36}
diff --git a/src/ext/Firewall/wixext/FirewallExtensionData.cs b/src/ext/Firewall/wixext/FirewallExtensionData.cs
new file mode 100644
index 00000000..7481d993
--- /dev/null
+++ b/src/ext/Firewall/wixext/FirewallExtensionData.cs
@@ -0,0 +1,23 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Firewall
4{
5 using WixToolset.Data;
6 using WixToolset.Extensibility;
7
8 public sealed class FirewallExtensionData : BaseExtensionData
9 {
10 public override string DefaultCulture => "en-US";
11
12 public override bool TryGetSymbolDefinitionByName(string name, out IntermediateSymbolDefinition symbolDefinition)
13 {
14 symbolDefinition = FirewallSymbolDefinitions.ByName(name);
15 return symbolDefinition != null;
16 }
17
18 public override Intermediate GetLibrary(ISymbolDefinitionCreator symbolDefinitions)
19 {
20 return Intermediate.Load(typeof(FirewallExtensionData).Assembly, "WixToolset.Firewall.firewall.wixlib", symbolDefinitions);
21 }
22 }
23}
diff --git a/src/ext/Firewall/wixext/FirewallExtensionFactory.cs b/src/ext/Firewall/wixext/FirewallExtensionFactory.cs
new file mode 100644
index 00000000..279b322a
--- /dev/null
+++ b/src/ext/Firewall/wixext/FirewallExtensionFactory.cs
@@ -0,0 +1,18 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Firewall
4{
5 using System;
6 using System.Collections.Generic;
7 using WixToolset.Extensibility;
8
9 public class FirewallExtensionFactory : BaseExtensionFactory
10 {
11 protected override IReadOnlyCollection<Type> ExtensionTypes => new[]
12 {
13 typeof(FirewallCompiler),
14 typeof(FirewallExtensionData),
15 typeof(FirewallWindowsInstallerBackendBinderExtension),
16 };
17 }
18}
diff --git a/src/ext/Firewall/wixext/FirewallTableDefinitions.cs b/src/ext/Firewall/wixext/FirewallTableDefinitions.cs
new file mode 100644
index 00000000..04918f5f
--- /dev/null
+++ b/src/ext/Firewall/wixext/FirewallTableDefinitions.cs
@@ -0,0 +1,34 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Firewall
4{
5 using WixToolset.Data.WindowsInstaller;
6
7 public static class FirewallTableDefinitions
8 {
9 public static readonly TableDefinition WixFirewallException = new TableDefinition(
10 "Wix4FirewallException",
11 FirewallSymbolDefinitions.WixFirewallException,
12 new[]
13 {
14 new ColumnDefinition("Wix4FirewallException", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "The primary key, a non-localized token.", modularizeType: ColumnModularizeType.Column),
15 new ColumnDefinition("Name", ColumnType.Localized, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Localizable display name.", modularizeType: ColumnModularizeType.Property),
16 new ColumnDefinition("RemoteAddresses", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Remote address to accept incoming connections from.", modularizeType: ColumnModularizeType.Property),
17 new ColumnDefinition("Port", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, minValue: 1, description: "Port number.", modularizeType: ColumnModularizeType.Property),
18 new ColumnDefinition("Protocol", ColumnType.Number, 1, primaryKey: false, nullable: true, ColumnCategory.Integer, minValue: 6, maxValue: 17, description: "Protocol (6=TCP; 17=UDP)."),
19 new ColumnDefinition("Program", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Exception for a program (formatted path name).", modularizeType: ColumnModularizeType.Property),
20 new ColumnDefinition("Attributes", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Vital=1"),
21 new ColumnDefinition("Profile", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Integer, minValue: 1, maxValue: 2147483647, description: "Profile (1=domain; 2=private; 4=public; 2147483647=all)."),
22 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key into the Component table referencing component that controls the firewall configuration.", modularizeType: ColumnModularizeType.Column),
23 new ColumnDefinition("Description", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Description displayed in Windows Firewall manager for this firewall rule."),
24 new ColumnDefinition("Direction", ColumnType.Number, 1, primaryKey: false, nullable: true, ColumnCategory.Integer, minValue: 1, maxValue: 2, description: "Direction (1=in; 2=out)"),
25 },
26 symbolIdIsPrimaryKey: true
27 );
28
29 public static readonly TableDefinition[] All = new[]
30 {
31 WixFirewallException,
32 };
33 }
34}
diff --git a/src/ext/Firewall/wixext/FirewallWindowsInstallerBackendExtension.cs b/src/ext/Firewall/wixext/FirewallWindowsInstallerBackendExtension.cs
new file mode 100644
index 00000000..b5b97d85
--- /dev/null
+++ b/src/ext/Firewall/wixext/FirewallWindowsInstallerBackendExtension.cs
@@ -0,0 +1,13 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Firewall
4{
5 using System.Collections.Generic;
6 using WixToolset.Data.WindowsInstaller;
7 using WixToolset.Extensibility;
8
9 public class FirewallWindowsInstallerBackendBinderExtension : BaseWindowsInstallerBackendBinderExtension
10 {
11 public override IReadOnlyCollection<TableDefinition> TableDefinitions => FirewallTableDefinitions.All;
12 }
13}
diff --git a/src/ext/Firewall/wixext/Symbols/FirewallSymbolDefinitions.cs b/src/ext/Firewall/wixext/Symbols/FirewallSymbolDefinitions.cs
new file mode 100644
index 00000000..887893c7
--- /dev/null
+++ b/src/ext/Firewall/wixext/Symbols/FirewallSymbolDefinitions.cs
@@ -0,0 +1,39 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Firewall
4{
5 using System;
6 using WixToolset.Data;
7
8 public enum FirewallSymbolDefinitionType
9 {
10 WixFirewallException,
11 }
12
13 public static partial class FirewallSymbolDefinitions
14 {
15 public static readonly Version Version = new Version("4.0.0");
16
17 public static IntermediateSymbolDefinition ByName(string name)
18 {
19 if (!Enum.TryParse(name, out FirewallSymbolDefinitionType type))
20 {
21 return null;
22 }
23
24 return ByType(type);
25 }
26
27 public static IntermediateSymbolDefinition ByType(FirewallSymbolDefinitionType type)
28 {
29 switch (type)
30 {
31 case FirewallSymbolDefinitionType.WixFirewallException:
32 return FirewallSymbolDefinitions.WixFirewallException;
33
34 default:
35 throw new ArgumentOutOfRangeException(nameof(type));
36 }
37 }
38 }
39}
diff --git a/src/ext/Firewall/wixext/Symbols/WixFirewallExceptionSymbol.cs b/src/ext/Firewall/wixext/Symbols/WixFirewallExceptionSymbol.cs
new file mode 100644
index 00000000..620de969
--- /dev/null
+++ b/src/ext/Firewall/wixext/Symbols/WixFirewallExceptionSymbol.cs
@@ -0,0 +1,119 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Firewall
4{
5 using WixToolset.Data;
6 using WixToolset.Firewall.Symbols;
7
8 public static partial class FirewallSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition WixFirewallException = new IntermediateSymbolDefinition(
11 FirewallSymbolDefinitionType.WixFirewallException.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Name), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.RemoteAddresses), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Port), IntermediateFieldType.String),
17 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Protocol), IntermediateFieldType.Number),
18 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Program), IntermediateFieldType.String),
19 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Attributes), IntermediateFieldType.Number),
20 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Profile), IntermediateFieldType.Number),
21 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.ComponentRef), IntermediateFieldType.String),
22 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Description), IntermediateFieldType.String),
23 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Direction), IntermediateFieldType.Number),
24 },
25 typeof(WixFirewallExceptionSymbol));
26 }
27}
28
29namespace WixToolset.Firewall.Symbols
30{
31 using WixToolset.Data;
32
33 public enum WixFirewallExceptionSymbolFields
34 {
35 Name,
36 RemoteAddresses,
37 Port,
38 Protocol,
39 Program,
40 Attributes,
41 Profile,
42 ComponentRef,
43 Description,
44 Direction,
45 }
46
47 public class WixFirewallExceptionSymbol : IntermediateSymbol
48 {
49 public WixFirewallExceptionSymbol() : base(FirewallSymbolDefinitions.WixFirewallException, null, null)
50 {
51 }
52
53 public WixFirewallExceptionSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(FirewallSymbolDefinitions.WixFirewallException, sourceLineNumber, id)
54 {
55 }
56
57 public IntermediateField this[WixFirewallExceptionSymbolFields index] => this.Fields[(int)index];
58
59 public string Name
60 {
61 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Name].AsString();
62 set => this.Set((int)WixFirewallExceptionSymbolFields.Name, value);
63 }
64
65 public string RemoteAddresses
66 {
67 get => this.Fields[(int)WixFirewallExceptionSymbolFields.RemoteAddresses].AsString();
68 set => this.Set((int)WixFirewallExceptionSymbolFields.RemoteAddresses, value);
69 }
70
71 public string Port
72 {
73 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Port].AsString();
74 set => this.Set((int)WixFirewallExceptionSymbolFields.Port, value);
75 }
76
77 public int? Protocol
78 {
79 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Protocol].AsNullableNumber();
80 set => this.Set((int)WixFirewallExceptionSymbolFields.Protocol, value);
81 }
82
83 public string Program
84 {
85 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Program].AsString();
86 set => this.Set((int)WixFirewallExceptionSymbolFields.Program, value);
87 }
88
89 public int Attributes
90 {
91 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Attributes].AsNumber();
92 set => this.Set((int)WixFirewallExceptionSymbolFields.Attributes, value);
93 }
94
95 public int Profile
96 {
97 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Profile].AsNumber();
98 set => this.Set((int)WixFirewallExceptionSymbolFields.Profile, value);
99 }
100
101 public string ComponentRef
102 {
103 get => this.Fields[(int)WixFirewallExceptionSymbolFields.ComponentRef].AsString();
104 set => this.Set((int)WixFirewallExceptionSymbolFields.ComponentRef, value);
105 }
106
107 public string Description
108 {
109 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Description].AsString();
110 set => this.Set((int)WixFirewallExceptionSymbolFields.Description, value);
111 }
112
113 public int Direction
114 {
115 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Direction].AsNumber();
116 set => this.Set((int)WixFirewallExceptionSymbolFields.Direction, value);
117 }
118 }
119} \ No newline at end of file
diff --git a/src/ext/Firewall/wixext/WixToolset.Firewall.wixext.csproj b/src/ext/Firewall/wixext/WixToolset.Firewall.wixext.csproj
new file mode 100644
index 00000000..6704dad2
--- /dev/null
+++ b/src/ext/Firewall/wixext/WixToolset.Firewall.wixext.csproj
@@ -0,0 +1,31 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project Sdk="Microsoft.NET.Sdk">
5 <PropertyGroup>
6 <TargetFramework>netstandard2.0</TargetFramework>
7 <RootNamespace>WixToolset.Firewall</RootNamespace>
8 <Description>WiX Toolset Firewallity Extension</Description>
9 <Title>WiX Toolset Firewall Extension</Title>
10 <IsTool>true</IsTool>
11 <ContentTargetFolders>build</ContentTargetFolders>
12 </PropertyGroup>
13
14 <ItemGroup>
15 <Content Include="$(MSBuildThisFileName).targets" />
16 <EmbeddedResource Include="$(OutputPath)..\firewall.wixlib" />
17 </ItemGroup>
18
19 <ItemGroup>
20 <PackageReference Include="WixToolset.Data" Version="4.0.*" PrivateAssets="all" />
21 <PackageReference Include="WixToolset.Extensibility" Version="4.0.*" PrivateAssets="all" />
22 </ItemGroup>
23
24 <ItemGroup>
25 <ProjectReference Include="..\wixlib\firewall.wixproj" ReferenceOutputAssembly="false" Condition=" '$(NCrunch)'=='' " />
26 </ItemGroup>
27
28 <ItemGroup>
29 <PackageReference Include="Nerdbank.GitVersioning" Version="3.3.37" PrivateAssets="all" />
30 </ItemGroup>
31</Project>
diff --git a/src/ext/Firewall/wixext/WixToolset.Firewall.wixext.targets b/src/ext/Firewall/wixext/WixToolset.Firewall.wixext.targets
new file mode 100644
index 00000000..c717450f
--- /dev/null
+++ b/src/ext/Firewall/wixext/WixToolset.Firewall.wixext.targets
@@ -0,0 +1,11 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
5 <PropertyGroup>
6 <WixToolsetFirewallWixextPath Condition=" '$(WixToolsetFirewallWixextPath)' == '' ">$(MSBuildThisFileDirectory)..\tools\WixToolset.Firewall.wixext.dll</WixToolsetFirewallWixextPath>
7 </PropertyGroup>
8 <ItemGroup>
9 <WixExtension Include="$(WixToolsetFirewallWixextPath)" />
10 </ItemGroup>
11</Project>