aboutsummaryrefslogtreecommitdiff
path: root/src/ext/Msmq/wixext
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/Msmq/wixext')
-rw-r--r--src/ext/Msmq/wixext/MsmqCompiler.cs528
-rw-r--r--src/ext/Msmq/wixext/MsmqDecompiler.cs305
-rw-r--r--src/ext/Msmq/wixext/MsmqErrors.cs71
-rw-r--r--src/ext/Msmq/wixext/MsmqExtensionData.cs30
-rw-r--r--src/ext/Msmq/wixext/MsmqExtensionFactory.cs18
-rw-r--r--src/ext/Msmq/wixext/MsmqTableDefinitions.cs64
-rw-r--r--src/ext/Msmq/wixext/MsmqWarnings.cs30
-rw-r--r--src/ext/Msmq/wixext/MsmqWindowsInstallerBackendExtension.cs13
-rw-r--r--src/ext/Msmq/wixext/Symbols/MessageQueueGroupPermissionSymbol.cs71
-rw-r--r--src/ext/Msmq/wixext/Symbols/MessageQueueSymbol.cs119
-rw-r--r--src/ext/Msmq/wixext/Symbols/MessageQueueUserPermissionSymbol.cs71
-rw-r--r--src/ext/Msmq/wixext/Symbols/MsmqSymbolDefinitions.cs47
-rw-r--r--src/ext/Msmq/wixext/WixToolset.Msmq.wixext.csproj30
-rw-r--r--src/ext/Msmq/wixext/WixToolset.Msmq.wixext.targets11
14 files changed, 1408 insertions, 0 deletions
diff --git a/src/ext/Msmq/wixext/MsmqCompiler.cs b/src/ext/Msmq/wixext/MsmqCompiler.cs
new file mode 100644
index 00000000..cfc4ef65
--- /dev/null
+++ b/src/ext/Msmq/wixext/MsmqCompiler.cs
@@ -0,0 +1,528 @@
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.Msmq
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.Msmq.Symbols;
11
12 /// <summary>
13 /// The compiler for the WiX Toolset MSMQ Extension.
14 /// </summary>
15 public sealed class MsmqCompiler : BaseCompilerExtension
16 {
17 public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/msmq";
18
19 /// <summary>
20 /// </summary>
21 /// <remarks></remarks>
22 public enum MqiMessageQueueAttributes
23 {
24 Authenticate = (1 << 0),
25 Journal = (1 << 1),
26 Transactional = (1 << 2)
27 }
28
29 /// <summary>
30 /// </summary>
31 /// <remarks></remarks>
32 public enum MqiMessageQueuePrivacyLevel
33 {
34 None = 0,
35 Optional = 1,
36 Body = 2
37 }
38
39 /// <summary>
40 /// </summary>
41 /// <remarks></remarks>
42 public enum MqiMessageQueuePermission
43 {
44 DeleteMessage = (1 << 0),
45 PeekMessage = (1 << 1),
46 WriteMessage = (1 << 2),
47 DeleteJournalMessage = (1 << 3),
48 SetQueueProperties = (1 << 4),
49 GetQueueProperties = (1 << 5),
50 DeleteQueue = (1 << 6),
51 GetQueuePermissions = (1 << 7),
52 ChangeQueuePermissions = (1 << 8),
53 TakeQueueOwnership = (1 << 9),
54 ReceiveMessage = (1 << 10),
55 ReceiveJournalMessage = (1 << 11),
56 QueueGenericRead = (1 << 12),
57 QueueGenericWrite = (1 << 13),
58 QueueGenericExecute = (1 << 14),
59 QueueGenericAll = (1 << 15)
60 }
61
62 /// <summary>
63 /// Processes an element for the Compiler.
64 /// </summary>
65 /// <param name="parentElement">Parent element of element to process.</param>
66 /// <param name="element">Element to process.</param>
67 /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param>
68 public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
69 {
70 switch (parentElement.Name.LocalName)
71 {
72 case "Component":
73 var componentId = context["ComponentId"];
74 var directoryId = context["DirectoryId"];
75
76 switch (element.Name.LocalName)
77 {
78 case "MessageQueue":
79 this.ParseMessageQueueElement(intermediate, section, element, componentId);
80 break;
81 case "MessageQueuePermission":
82 this.ParseMessageQueuePermissionElement(intermediate, section, element, componentId, null);
83 break;
84 default:
85 this.ParseHelper.UnexpectedElement(parentElement, element);
86 break;
87 }
88 break;
89 default:
90 this.ParseHelper.UnexpectedElement(parentElement, element);
91 break;
92 }
93 }
94
95 /// <summary>
96 /// Parses an MSMQ message queue element.
97 /// </summary>
98 /// <param name="node">Element to parse.</param>
99 /// <param name="componentKey">Identifier of parent component.</param>
100 private void ParseMessageQueueElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentId)
101 {
102 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
103
104 Identifier id = null;
105 var basePriority = CompilerConstants.IntegerNotSet;
106 var journalQuota = CompilerConstants.IntegerNotSet;
107 string label = null;
108 string multicastAddress = null;
109 string pathName = null;
110 var privLevel = CompilerConstants.IntegerNotSet;
111 var quota = CompilerConstants.IntegerNotSet;
112 string serviceTypeGuid = null;
113 int attributes = 0;
114
115 foreach (var attrib in node.Attributes())
116 {
117 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
118 {
119 switch (attrib.Name.LocalName)
120 {
121 case "Id":
122 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
123 break;
124 case "Authenticate":
125 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
126 {
127 attributes |= (int)MqiMessageQueueAttributes.Authenticate;
128 }
129 else
130 {
131 attributes &= ~(int)MqiMessageQueueAttributes.Authenticate;
132 }
133 break;
134 case "BasePriority":
135 basePriority = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
136 break;
137 case "Journal":
138 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
139 {
140 attributes |= (int)MqiMessageQueueAttributes.Journal;
141 }
142 else
143 {
144 attributes &= ~(int)MqiMessageQueueAttributes.Journal;
145 }
146 break;
147 case "JournalQuota":
148 journalQuota = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
149 break;
150 case "Label":
151 label = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
152 break;
153 case "MulticastAddress":
154 multicastAddress = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
155 break;
156 case "PathName":
157 pathName = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
158 break;
159 case "PrivLevel":
160 var privLevelAttr = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
161 switch (privLevelAttr)
162 {
163 case "none":
164 privLevel = (int)MqiMessageQueuePrivacyLevel.None;
165 break;
166 case "optional":
167 privLevel = (int)MqiMessageQueuePrivacyLevel.Optional;
168 break;
169 case "body":
170 privLevel = (int)MqiMessageQueuePrivacyLevel.Body;
171 break;
172 default:
173 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "MessageQueue", "PrivLevel", privLevelAttr, "none", "body", "optional"));
174 break;
175 }
176 break;
177 case "Quota":
178 quota = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
179 break;
180 case "Transactional":
181 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
182 {
183 attributes |= (int)MqiMessageQueueAttributes.Transactional;
184 }
185 else
186 {
187 attributes &= ~(int)MqiMessageQueueAttributes.Transactional;
188 }
189 break;
190 case "ServiceTypeGuid":
191 serviceTypeGuid = this.TryFormatGuidValue(this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib));
192 break;
193 default:
194 this.ParseHelper.UnexpectedAttribute(node, attrib);
195 break;
196 }
197 }
198 else
199 {
200 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
201 }
202 }
203
204 foreach (var child in node.Elements())
205 {
206 if (this.Namespace == child.Name.Namespace)
207 {
208 switch (child.Name.LocalName)
209 {
210 case "MessageQueuePermission":
211 this.ParseMessageQueuePermissionElement(intermediate, section, child, componentId, id?.Id);
212 break;
213 default:
214 this.ParseHelper.UnexpectedElement(node, child);
215 break;
216 }
217 }
218 else
219 {
220 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
221 }
222 }
223
224 var symbol = section.AddSymbol(new MessageQueueSymbol(sourceLineNumbers, id)
225 {
226 ComponentRef = componentId,
227 Label = label,
228 MulticastAddress = multicastAddress,
229 PathName = pathName,
230 ServiceTypeGuid = serviceTypeGuid,
231 Attributes = attributes,
232 });
233
234 if (CompilerConstants.IntegerNotSet != basePriority)
235 {
236 symbol.BasePriority = basePriority;
237 }
238 if (CompilerConstants.IntegerNotSet != journalQuota)
239 {
240 symbol.JournalQuota = journalQuota;
241 }
242
243 if (CompilerConstants.IntegerNotSet != privLevel)
244 {
245 symbol.PrivLevel = privLevel;
246 }
247 if (CompilerConstants.IntegerNotSet != quota)
248 {
249 symbol.Quota = quota;
250 }
251
252 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.CustomAction, "MessageQueuingInstall");
253 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.CustomAction, "MessageQueuingUninstall");
254 }
255
256 /// <summary>
257 /// Parses an MSMQ message queue permission element.
258 /// </summary>
259 /// <param name="node">Element to parse.</param>
260 /// <param name="componentKey">Identifier of parent component.</param>
261 /// <param name="applicationKey">Optional identifier of parent message queue.</param>
262 private void ParseMessageQueuePermissionElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentId, string messageQueueId)
263 {
264 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
265
266 Identifier id = null;
267 string user = null;
268 string group = null;
269 int permissions = 0;
270
271 foreach (var attrib in node.Attributes())
272 {
273 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
274 {
275 switch (attrib.Name.LocalName)
276 {
277 case "Id":
278 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
279 break;
280 case "MessageQueue":
281 if (null != messageQueueId)
282 {
283 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
284 }
285 messageQueueId = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
286 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, MsmqSymbolDefinitions.MessageQueue, messageQueueId);
287 break;
288 case "User":
289 if (null != group)
290 {
291 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "User", "Group"));
292 }
293 user = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
294 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", user);
295 break;
296 case "Group":
297 if (null != user)
298 {
299 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Group", "User"));
300 }
301 group = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
302 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "Group", group);
303 break;
304 case "DeleteMessage":
305 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
306 {
307 permissions |= (int)MqiMessageQueuePermission.DeleteMessage;
308 }
309 else
310 {
311 permissions &= ~(int)MqiMessageQueuePermission.DeleteMessage;
312 }
313 break;
314 case "PeekMessage":
315 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
316 {
317 permissions |= (int)MqiMessageQueuePermission.PeekMessage;
318 }
319 else
320 {
321 permissions &= ~(int)MqiMessageQueuePermission.PeekMessage;
322 }
323 break;
324 case "WriteMessage":
325 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
326 {
327 permissions |= (int)MqiMessageQueuePermission.WriteMessage;
328 }
329 else
330 {
331 permissions &= ~(int)MqiMessageQueuePermission.WriteMessage;
332 }
333 break;
334 case "DeleteJournalMessage":
335 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
336 {
337 permissions |= (int)MqiMessageQueuePermission.DeleteJournalMessage;
338 }
339 else
340 {
341 permissions &= ~(int)MqiMessageQueuePermission.DeleteJournalMessage;
342 }
343 break;
344 case "SetQueueProperties":
345 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
346 {
347 permissions |= (int)MqiMessageQueuePermission.SetQueueProperties;
348 }
349 else
350 {
351 permissions &= ~(int)MqiMessageQueuePermission.SetQueueProperties;
352 }
353 break;
354 case "GetQueueProperties":
355 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
356 {
357 permissions |= (int)MqiMessageQueuePermission.GetQueueProperties;
358 }
359 else
360 {
361 permissions &= ~(int)MqiMessageQueuePermission.GetQueueProperties;
362 }
363 break;
364 case "DeleteQueue":
365 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
366 {
367 permissions |= (int)MqiMessageQueuePermission.DeleteQueue;
368 }
369 else
370 {
371 permissions &= ~(int)MqiMessageQueuePermission.DeleteQueue;
372 }
373 break;
374 case "GetQueuePermissions":
375 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
376 {
377 permissions |= (int)MqiMessageQueuePermission.GetQueuePermissions;
378 }
379 else
380 {
381 permissions &= ~(int)MqiMessageQueuePermission.GetQueuePermissions;
382 }
383 break;
384 case "ChangeQueuePermissions":
385 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
386 {
387 permissions |= (int)MqiMessageQueuePermission.ChangeQueuePermissions;
388 }
389 else
390 {
391 permissions &= ~(int)MqiMessageQueuePermission.ChangeQueuePermissions;
392 }
393 break;
394 case "TakeQueueOwnership":
395 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
396 {
397 permissions |= (int)MqiMessageQueuePermission.TakeQueueOwnership;
398 }
399 else
400 {
401 permissions &= ~(int)MqiMessageQueuePermission.TakeQueueOwnership;
402 }
403 break;
404 case "ReceiveMessage":
405 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
406 {
407 permissions |= (int)MqiMessageQueuePermission.ReceiveMessage;
408 }
409 else
410 {
411 permissions &= ~(int)MqiMessageQueuePermission.ReceiveMessage;
412 }
413 break;
414 case "ReceiveJournalMessage":
415 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
416 {
417 permissions |= (int)MqiMessageQueuePermission.ReceiveJournalMessage;
418 }
419 else
420 {
421 permissions &= ~(int)MqiMessageQueuePermission.ReceiveJournalMessage;
422 }
423 break;
424 case "QueueGenericRead":
425 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
426 {
427 permissions |= (int)MqiMessageQueuePermission.QueueGenericRead;
428 }
429 else
430 {
431 permissions &= ~(int)MqiMessageQueuePermission.QueueGenericRead;
432 }
433 break;
434 case "QueueGenericWrite":
435 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
436 {
437 permissions |= (int)MqiMessageQueuePermission.QueueGenericWrite;
438 }
439 else
440 {
441 permissions &= ~(int)MqiMessageQueuePermission.QueueGenericWrite;
442 }
443 break;
444 case "QueueGenericExecute":
445 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
446 {
447 permissions |= (int)MqiMessageQueuePermission.QueueGenericExecute;
448 }
449 else
450 {
451 permissions &= ~(int)MqiMessageQueuePermission.QueueGenericExecute;
452 }
453 break;
454 case "QueueGenericAll":
455 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
456 {
457 permissions |= (int)MqiMessageQueuePermission.QueueGenericAll;
458 }
459 else
460 {
461 permissions &= ~(int)MqiMessageQueuePermission.QueueGenericAll;
462 }
463 break;
464 default:
465 this.ParseHelper.UnexpectedAttribute(node, attrib);
466 break;
467 }
468 }
469 else
470 {
471 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
472 }
473 }
474
475 if (null == id)
476 {
477 id = this.ParseHelper.CreateIdentifier("mqp", componentId, messageQueueId, user, group);
478 }
479
480 if (null == messageQueueId)
481 {
482 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "MessageQueue"));
483 }
484 if (null == user && null == group)
485 {
486 this.Messaging.Write(ErrorMessages.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "User", "Group"));
487 }
488
489 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
490
491 if (null != user)
492 {
493 section.AddSymbol(new MessageQueueUserPermissionSymbol(sourceLineNumbers, id)
494 {
495 ComponentRef = componentId,
496 MessageQueueRef = messageQueueId,
497 UserRef = user,
498 Permissions = permissions,
499 });
500 }
501 if (null != group)
502 {
503 section.AddSymbol(new MessageQueueGroupPermissionSymbol(sourceLineNumbers, id)
504 {
505 ComponentRef = componentId,
506 MessageQueueRef = messageQueueId,
507 GroupRef = group,
508 Permissions = permissions,
509 });
510 }
511 }
512
513 /// <summary>
514 /// Attempts to parse the input value as a GUID, and in case the value is a valid
515 /// GUID returnes it in the format "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}".
516 /// </summary>
517 /// <param name="val"></param>
518 /// <returns></returns>
519 string TryFormatGuidValue(string val)
520 {
521 if (!Guid.TryParse(val, out var guid))
522 {
523 return val;
524 }
525 return guid.ToString("B").ToUpper();
526 }
527 }
528}
diff --git a/src/ext/Msmq/wixext/MsmqDecompiler.cs b/src/ext/Msmq/wixext/MsmqDecompiler.cs
new file mode 100644
index 00000000..aa8c34b6
--- /dev/null
+++ b/src/ext/Msmq/wixext/MsmqDecompiler.cs
@@ -0,0 +1,305 @@
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.Msmq
4{
5#if TODO_CONSIDER_DECOMPILER
6 using System;
7 using System.Collections;
8 using System.Globalization;
9 using WixToolset.Data;
10 using WixToolset.Extensibility;
11 using Msmq = WixToolset.Extensions.Serialize.Msmq;
12 using Wix = WixToolset.Data.Serialize;
13
14 /// <summary>
15 /// The decompiler for the WiX Toolset MSMQ Extension.
16 /// </summary>
17 public sealed class MsmqDecompiler : DecompilerExtension
18 {
19 /// <summary>
20 /// Creates a decompiler for MSMQ Extension.
21 /// </summary>
22 public MsmqDecompiler()
23 {
24 this.TableDefinitions = MsmqExtensionData.GetExtensionTableDefinitions();
25 }
26
27 /// <summary>
28 /// Get the extensions library to be removed.
29 /// </summary>
30 /// <param name="tableDefinitions">Table definitions for library.</param>
31 /// <returns>Library to remove from decompiled output.</returns>
32 public override Library GetLibraryToRemove(TableDefinitionCollection tableDefinitions)
33 {
34 return MsmqExtensionData.GetExtensionLibrary(tableDefinitions);
35 }
36
37 /// <summary>
38 /// Decompiles an extension table.
39 /// </summary>
40 /// <param name="table">The table to decompile.</param>
41 public override void DecompileTable(Table table)
42 {
43 switch (table.Name)
44 {
45 case "MessageQueue":
46 this.DecompileMessageQueueTable(table);
47 break;
48 case "MessageQueueUserPermission":
49 this.DecompileMessageQueueUserPermissionTable(table);
50 break;
51 case "MessageQueueGroupPermission":
52 this.DecompileMessageQueueGroupPermissionTable(table);
53 break;
54 default:
55 base.DecompileTable(table);
56 break;
57 }
58 }
59
60 /// <summary>
61 /// Decompile the MessageQueue table.
62 /// </summary>
63 /// <param name="table">The table to decompile.</param>
64 private void DecompileMessageQueueTable(Table table)
65 {
66 foreach (Row row in table.Rows)
67 {
68 Msmq.MessageQueue queue = new Msmq.MessageQueue();
69
70 queue.Id = (string)row[0];
71
72 if (null != row[2])
73 {
74 queue.BasePriority = (int)row[2];
75 }
76
77 if (null != row[3])
78 {
79 queue.JournalQuota = (int)row[3];
80 }
81
82 queue.Label = (string)row[4];
83
84 if (null != row[5])
85 {
86 queue.MulticastAddress = (string)row[5];
87 }
88
89 queue.PathName = (string)row[6];
90
91 if (null != row[7])
92 {
93 switch ((MsmqCompiler.MqiMessageQueuePrivacyLevel)row[7])
94 {
95 case MsmqCompiler.MqiMessageQueuePrivacyLevel.None:
96 queue.PrivLevel = Msmq.MessageQueue.PrivLevelType.none;
97 break;
98 case MsmqCompiler.MqiMessageQueuePrivacyLevel.Optional:
99 queue.PrivLevel = Msmq.MessageQueue.PrivLevelType.optional;
100 break;
101 case MsmqCompiler.MqiMessageQueuePrivacyLevel.Body:
102 queue.PrivLevel = Msmq.MessageQueue.PrivLevelType.body;
103 break;
104 default:
105 break;
106 }
107 }
108
109 if (null != row[8])
110 {
111 queue.Quota = (int)row[8];
112 }
113
114 if (null != row[9])
115 {
116 queue.ServiceTypeGuid = (string)row[9];
117 }
118
119 int attributes = (int)row[10];
120
121 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueueAttributes.Authenticate))
122 {
123 queue.Authenticate = Msmq.YesNoType.yes;
124 }
125
126 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueueAttributes.Journal))
127 {
128 queue.Journal = Msmq.YesNoType.yes;
129 }
130
131 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueueAttributes.Transactional))
132 {
133 queue.Transactional = Msmq.YesNoType.yes;
134 }
135
136 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]);
137 if (null != component)
138 {
139 component.AddChild(queue);
140 }
141 else
142 {
143 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component"));
144 }
145 }
146 }
147
148 /// <summary>
149 /// Decompile the MessageQueueUserPermission table.
150 /// </summary>
151 /// <param name="table">The table to decompile.</param>
152 private void DecompileMessageQueueUserPermissionTable(Table table)
153 {
154 foreach (Row row in table.Rows)
155 {
156 Msmq.MessageQueuePermission queuePermission = new Msmq.MessageQueuePermission();
157
158 queuePermission.Id = (string)row[0];
159
160 if (null != row[2])
161 {
162 queuePermission.MessageQueue = (string)row[2];
163 }
164
165 queuePermission.User = (string)row[3];
166
167 DecompileMessageQueuePermissionAttributes(row, queuePermission);
168
169 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]);
170 if (null != component)
171 {
172 component.AddChild(queuePermission);
173 }
174 else
175 {
176 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component"));
177 }
178 }
179 }
180
181 /// <summary>
182 /// Decompile the MessageQueueGroupPermission table.
183 /// </summary>
184 /// <param name="table">The table to decompile.</param>
185 private void DecompileMessageQueueGroupPermissionTable(Table table)
186 {
187 foreach (Row row in table.Rows)
188 {
189 Msmq.MessageQueuePermission queuePermission = new Msmq.MessageQueuePermission();
190
191 queuePermission.Id = (string)row[0];
192
193 if (null != row[2])
194 {
195 queuePermission.MessageQueue = (string)row[2];
196 }
197
198 queuePermission.Group = (string)row[3];
199
200 DecompileMessageQueuePermissionAttributes(row, queuePermission);
201
202 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]);
203 if (null != component)
204 {
205 component.AddChild(queuePermission);
206 }
207 else
208 {
209 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component"));
210 }
211 }
212 }
213
214 /// <summary>
215 /// Decompile row attributes for the MessageQueueUserPermission and MessageQueueGroupPermission tables.
216 /// </summary>
217 /// <param name="row">The row to decompile.</param>
218 /// <param name="table">Target element.</param>
219 private void DecompileMessageQueuePermissionAttributes(Row row, Msmq.MessageQueuePermission queuePermission)
220 {
221 int attributes = (int)row[4];
222
223 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.DeleteMessage))
224 {
225 queuePermission.DeleteMessage = Msmq.YesNoType.yes;
226 }
227
228 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.PeekMessage))
229 {
230 queuePermission.PeekMessage = Msmq.YesNoType.yes;
231 }
232
233 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.WriteMessage))
234 {
235 queuePermission.WriteMessage = Msmq.YesNoType.yes;
236 }
237
238 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.DeleteJournalMessage))
239 {
240 queuePermission.DeleteJournalMessage = Msmq.YesNoType.yes;
241 }
242
243 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.SetQueueProperties))
244 {
245 queuePermission.SetQueueProperties = Msmq.YesNoType.yes;
246 }
247
248 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.GetQueueProperties))
249 {
250 queuePermission.GetQueueProperties = Msmq.YesNoType.yes;
251 }
252
253 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.DeleteQueue))
254 {
255 queuePermission.DeleteQueue = Msmq.YesNoType.yes;
256 }
257
258 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.GetQueuePermissions))
259 {
260 queuePermission.GetQueuePermissions = Msmq.YesNoType.yes;
261 }
262
263 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.ChangeQueuePermissions))
264 {
265 queuePermission.ChangeQueuePermissions = Msmq.YesNoType.yes;
266 }
267
268 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.TakeQueueOwnership))
269 {
270 queuePermission.TakeQueueOwnership = Msmq.YesNoType.yes;
271 }
272
273 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.ReceiveMessage))
274 {
275 queuePermission.ReceiveMessage = Msmq.YesNoType.yes;
276 }
277
278 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.ReceiveJournalMessage))
279 {
280 queuePermission.ReceiveJournalMessage = Msmq.YesNoType.yes;
281 }
282
283 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.QueueGenericRead))
284 {
285 queuePermission.QueueGenericRead = Msmq.YesNoType.yes;
286 }
287
288 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.QueueGenericWrite))
289 {
290 queuePermission.QueueGenericWrite = Msmq.YesNoType.yes;
291 }
292
293 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.QueueGenericExecute))
294 {
295 queuePermission.QueueGenericExecute = Msmq.YesNoType.yes;
296 }
297
298 if (0 != (attributes & (int)MsmqCompiler.MqiMessageQueuePermission.QueueGenericAll))
299 {
300 queuePermission.QueueGenericAll = Msmq.YesNoType.yes;
301 }
302 }
303 }
304#endif
305}
diff --git a/src/ext/Msmq/wixext/MsmqErrors.cs b/src/ext/Msmq/wixext/MsmqErrors.cs
new file mode 100644
index 00000000..4342e1cf
--- /dev/null
+++ b/src/ext/Msmq/wixext/MsmqErrors.cs
@@ -0,0 +1,71 @@
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.Data
4{
5 using System;
6 using System.Resources;
7
8 public static class MsmqErrors
9 {
10 public static Message IllegalAttributeWithoutComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName)
11 {
12 return Message(sourceLineNumbers, Ids.IllegalAttributeWithoutComponent, "The {0}/@{1} attribute cannot be specified unless the element has a component as an ancestor. A {0} that does not have a component ancestor is not installed.", elementName, attributeName);
13 }
14
15 public static Message IllegalElementWithoutComponent(SourceLineNumber sourceLineNumbers, string elementName)
16 {
17 return Message(sourceLineNumbers, Ids.IllegalElementWithoutComponent, "The {0} element cannot be specified unless the element has a component as an ancestor. A {0} that does not have a component ancestor is not installed.", elementName);
18 }
19
20 public static Message RequiredAttribute(SourceLineNumber sourceLineNumbers, string elementName, string attributeName1, string attributeName2)
21 {
22 return Message(sourceLineNumbers, Ids.RequiredAttribute, "A {0} element must have either a {1} attribute or a {2} attribute, or both set.", elementName, attributeName1, attributeName2);
23 }
24
25 public static Message RequiredAttributeNotUnderComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName1, string attributeName2)
26 {
27 return Message(sourceLineNumbers, Ids.RequiredAttributeNotUnderComponent, "A {0} element not nested under a component must have either a {1} attribute or a {2} attribute, or both set.", elementName, attributeName1, attributeName2);
28 }
29
30 public static Message RequiredAttributeUnderComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName)
31 {
32 return Message(sourceLineNumbers, Ids.RequiredAttributeUnderComponent, "The {0}/@{1} attribute must be provided when {0} element is nested under a component.", elementName, attributeName);
33 }
34
35 public static Message UnexpectedAttributeWithOtherValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string otherAttributeName, string otherValue)
36 {
37 return Message(sourceLineNumbers, Ids.UnexpectedAttributeWithOtherValue, "The {0}/@{1} attribute cannot coexist with the {2} attribute's value of '{3}'.", elementName, attributeName, otherAttributeName, otherValue);
38 }
39
40 public static Message UnexpectedAttributeWithOtherValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string value, string otherAttributeName, string otherValue)
41 {
42 return Message(sourceLineNumbers, Ids.UnexpectedAttributeWithOtherValue, "The {0}/@{1} attribute's value, '{2}', cannot coexist with the {3} attribute's value of '{4}'.", elementName, attributeName, value, otherAttributeName, otherValue);
43 }
44
45 public static Message UnexpectedAttributeWithoutOtherValue(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string otherAttributeName, string otherValue)
46 {
47 return Message(sourceLineNumbers, Ids.UnexpectedAttributeWithoutOtherValue, "The {0}/@{1} cannot be provided unless the {2} attribute is provided with a value of '{3}'.", elementName, attributeName, otherAttributeName, otherValue);
48 }
49
50 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args)
51 {
52 return new Message(sourceLineNumber, MessageLevel.Error, (int)id, format, args);
53 }
54
55 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, ResourceManager resourceManager, string resourceName, params object[] args)
56 {
57 return new Message(sourceLineNumber, MessageLevel.Error, (int)id, resourceManager, resourceName, args);
58 }
59
60 public enum Ids
61 {
62 IllegalAttributeWithoutComponent = 6000,
63 IllegalElementWithoutComponent = 6001,
64 UnexpectedAttributeWithOtherValue = 6002,
65 UnexpectedAttributeWithoutOtherValue = 6003,
66 RequiredAttributeUnderComponent = 6004,
67 RequiredAttribute = 6005,
68 RequiredAttributeNotUnderComponent = 6006,
69 }
70 }
71}
diff --git a/src/ext/Msmq/wixext/MsmqExtensionData.cs b/src/ext/Msmq/wixext/MsmqExtensionData.cs
new file mode 100644
index 00000000..91485724
--- /dev/null
+++ b/src/ext/Msmq/wixext/MsmqExtensionData.cs
@@ -0,0 +1,30 @@
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.Msmq
4{
5 using WixToolset.Data;
6 using WixToolset.Extensibility;
7
8 /// <summary>
9 /// The WiX Toolset MSMQ Extension.
10 /// </summary>
11 public sealed class MsmqExtensionData : BaseExtensionData
12 {
13 /// <summary>
14 /// Gets the default culture.
15 /// </summary>
16 /// <value>The default culture.</value>
17 public override string DefaultCulture => "en-US";
18
19 public override bool TryGetSymbolDefinitionByName(string name, out IntermediateSymbolDefinition symbolDefinition)
20 {
21 symbolDefinition = MsmqSymbolDefinitions.ByName(name);
22 return symbolDefinition != null;
23 }
24
25 public override Intermediate GetLibrary(ISymbolDefinitionCreator symbolDefinitions)
26 {
27 return Intermediate.Load(typeof(MsmqExtensionData).Assembly, "WixToolset.Msmq.msmq.wixlib", symbolDefinitions);
28 }
29 }
30}
diff --git a/src/ext/Msmq/wixext/MsmqExtensionFactory.cs b/src/ext/Msmq/wixext/MsmqExtensionFactory.cs
new file mode 100644
index 00000000..de9f786d
--- /dev/null
+++ b/src/ext/Msmq/wixext/MsmqExtensionFactory.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.Msmq
4{
5 using System;
6 using System.Collections.Generic;
7 using WixToolset.Extensibility;
8
9 public class MsmqExtensionFactory : BaseExtensionFactory
10 {
11 protected override IReadOnlyCollection<Type> ExtensionTypes => new[]
12 {
13 typeof(MsmqCompiler),
14 typeof(MsmqExtensionData),
15 typeof(MsmqWindowsInstallerBackendBinderExtension),
16 };
17 }
18}
diff --git a/src/ext/Msmq/wixext/MsmqTableDefinitions.cs b/src/ext/Msmq/wixext/MsmqTableDefinitions.cs
new file mode 100644
index 00000000..46e2dd10
--- /dev/null
+++ b/src/ext/Msmq/wixext/MsmqTableDefinitions.cs
@@ -0,0 +1,64 @@
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.Msmq
4{
5 using WixToolset.Data.WindowsInstaller;
6
7 public static class MsmqTableDefinitions
8 {
9 public static readonly TableDefinition MessageQueue = new TableDefinition(
10 "MessageQueue",
11 MsmqSymbolDefinitions.MessageQueue,
12 new[]
13 {
14 new ColumnDefinition("MessageQueue", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
15 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
16 new ColumnDefinition("BasePriority", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown),
17 new ColumnDefinition("JournalQuota", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown),
18 new ColumnDefinition("Label", ColumnType.Localized, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
19 new ColumnDefinition("MulticastAddress", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
20 new ColumnDefinition("PathName", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
21 new ColumnDefinition("PrivLevel", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown),
22 new ColumnDefinition("Quota", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown),
23 new ColumnDefinition("ServiceTypeGuid", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Formatted, modularizeType: ColumnModularizeType.Property),
24 new ColumnDefinition("Attributes", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown),
25 },
26 symbolIdIsPrimaryKey: true
27 );
28
29 public static readonly TableDefinition MessageQueueUserPermission = new TableDefinition(
30 "MessageQueueUserPermission",
31 MsmqSymbolDefinitions.MessageQueueUserPermission,
32 new[]
33 {
34 new ColumnDefinition("MessageQueueUserPermission", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
35 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
36 new ColumnDefinition("MessageQueue_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "MessageQueue", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
37 new ColumnDefinition("User_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
38 new ColumnDefinition("Permissions", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown),
39 },
40 symbolIdIsPrimaryKey: true
41 );
42
43 public static readonly TableDefinition MessageQueueGroupPermission = new TableDefinition(
44 "MessageQueueGroupPermission",
45 MsmqSymbolDefinitions.MessageQueueGroupPermission,
46 new[]
47 {
48 new ColumnDefinition("MessageQueueGroupPermission", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
49 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
50 new ColumnDefinition("MessageQueue_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "MessageQueue", keyColumn: 1, modularizeType: ColumnModularizeType.Column),
51 new ColumnDefinition("Group_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column),
52 new ColumnDefinition("Permissions", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown),
53 },
54 symbolIdIsPrimaryKey: true
55 );
56
57 public static readonly TableDefinition[] All = new[]
58 {
59 MessageQueue,
60 MessageQueueUserPermission,
61 MessageQueueGroupPermission,
62 };
63 }
64}
diff --git a/src/ext/Msmq/wixext/MsmqWarnings.cs b/src/ext/Msmq/wixext/MsmqWarnings.cs
new file mode 100644
index 00000000..41d160e9
--- /dev/null
+++ b/src/ext/Msmq/wixext/MsmqWarnings.cs
@@ -0,0 +1,30 @@
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.Data
4{
5 using System;
6 using System.Resources;
7
8 public static class MsmqWarnings
9 {
10 public static Message MissingComponents(SourceLineNumber sourceLineNumbers)
11 {
12 return Message(sourceLineNumbers, Ids.MissingComponents, "The MsmqAssembly element has a Type attribute with a value of 'native', but the element does not contain any MsmqComponent elements. All components contained in a native assembly must be listed, or they will not be correctly removed during uninstall.");
13 }
14
15 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args)
16 {
17 return new Message(sourceLineNumber, MessageLevel.Warning, (int)id, format, args);
18 }
19
20 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, ResourceManager resourceManager, string resourceName, params object[] args)
21 {
22 return new Message(sourceLineNumber, MessageLevel.Warning, (int)id, resourceManager, resourceName, args);
23 }
24
25 public enum Ids
26 {
27 MissingComponents = 6007,
28 }
29 }
30}
diff --git a/src/ext/Msmq/wixext/MsmqWindowsInstallerBackendExtension.cs b/src/ext/Msmq/wixext/MsmqWindowsInstallerBackendExtension.cs
new file mode 100644
index 00000000..d317fb60
--- /dev/null
+++ b/src/ext/Msmq/wixext/MsmqWindowsInstallerBackendExtension.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.Msmq
4{
5 using System.Collections.Generic;
6 using WixToolset.Data.WindowsInstaller;
7 using WixToolset.Extensibility;
8
9 public class MsmqWindowsInstallerBackendBinderExtension : BaseWindowsInstallerBackendBinderExtension
10 {
11 public override IReadOnlyCollection<TableDefinition> TableDefinitions => MsmqTableDefinitions.All;
12 }
13}
diff --git a/src/ext/Msmq/wixext/Symbols/MessageQueueGroupPermissionSymbol.cs b/src/ext/Msmq/wixext/Symbols/MessageQueueGroupPermissionSymbol.cs
new file mode 100644
index 00000000..404c061c
--- /dev/null
+++ b/src/ext/Msmq/wixext/Symbols/MessageQueueGroupPermissionSymbol.cs
@@ -0,0 +1,71 @@
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.Msmq
4{
5 using WixToolset.Data;
6 using WixToolset.Msmq.Symbols;
7
8 public static partial class MsmqSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition MessageQueueGroupPermission = new IntermediateSymbolDefinition(
11 MsmqSymbolDefinitionType.MessageQueueGroupPermission.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(MessageQueueGroupPermissionSymbolFields.ComponentRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(MessageQueueGroupPermissionSymbolFields.MessageQueueRef), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(MessageQueueGroupPermissionSymbolFields.GroupRef), IntermediateFieldType.String),
17 new IntermediateFieldDefinition(nameof(MessageQueueGroupPermissionSymbolFields.Permissions), IntermediateFieldType.Number),
18 },
19 typeof(MessageQueueGroupPermissionSymbol));
20 }
21}
22
23namespace WixToolset.Msmq.Symbols
24{
25 using WixToolset.Data;
26
27 public enum MessageQueueGroupPermissionSymbolFields
28 {
29 ComponentRef,
30 MessageQueueRef,
31 GroupRef,
32 Permissions,
33 }
34
35 public class MessageQueueGroupPermissionSymbol : IntermediateSymbol
36 {
37 public MessageQueueGroupPermissionSymbol() : base(MsmqSymbolDefinitions.MessageQueueGroupPermission, null, null)
38 {
39 }
40
41 public MessageQueueGroupPermissionSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(MsmqSymbolDefinitions.MessageQueueGroupPermission, sourceLineNumber, id)
42 {
43 }
44
45 public IntermediateField this[MessageQueueGroupPermissionSymbolFields index] => this.Fields[(int)index];
46
47 public string ComponentRef
48 {
49 get => this.Fields[(int)MessageQueueGroupPermissionSymbolFields.ComponentRef].AsString();
50 set => this.Set((int)MessageQueueGroupPermissionSymbolFields.ComponentRef, value);
51 }
52
53 public string MessageQueueRef
54 {
55 get => this.Fields[(int)MessageQueueGroupPermissionSymbolFields.MessageQueueRef].AsString();
56 set => this.Set((int)MessageQueueGroupPermissionSymbolFields.MessageQueueRef, value);
57 }
58
59 public string GroupRef
60 {
61 get => this.Fields[(int)MessageQueueGroupPermissionSymbolFields.GroupRef].AsString();
62 set => this.Set((int)MessageQueueGroupPermissionSymbolFields.GroupRef, value);
63 }
64
65 public int Permissions
66 {
67 get => this.Fields[(int)MessageQueueGroupPermissionSymbolFields.Permissions].AsNumber();
68 set => this.Set((int)MessageQueueGroupPermissionSymbolFields.Permissions, value);
69 }
70 }
71} \ No newline at end of file
diff --git a/src/ext/Msmq/wixext/Symbols/MessageQueueSymbol.cs b/src/ext/Msmq/wixext/Symbols/MessageQueueSymbol.cs
new file mode 100644
index 00000000..b911f0ea
--- /dev/null
+++ b/src/ext/Msmq/wixext/Symbols/MessageQueueSymbol.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.Msmq
4{
5 using WixToolset.Data;
6 using WixToolset.Msmq.Symbols;
7
8 public static partial class MsmqSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition MessageQueue = new IntermediateSymbolDefinition(
11 MsmqSymbolDefinitionType.MessageQueue.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.ComponentRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.BasePriority), IntermediateFieldType.Number),
16 new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.JournalQuota), IntermediateFieldType.Number),
17 new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.Label), IntermediateFieldType.String),
18 new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.MulticastAddress), IntermediateFieldType.String),
19 new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.PathName), IntermediateFieldType.String),
20 new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.PrivLevel), IntermediateFieldType.Number),
21 new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.Quota), IntermediateFieldType.Number),
22 new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.ServiceTypeGuid), IntermediateFieldType.String),
23 new IntermediateFieldDefinition(nameof(MessageQueueSymbolFields.Attributes), IntermediateFieldType.Number),
24 },
25 typeof(MessageQueueSymbol));
26 }
27}
28
29namespace WixToolset.Msmq.Symbols
30{
31 using WixToolset.Data;
32
33 public enum MessageQueueSymbolFields
34 {
35 ComponentRef,
36 BasePriority,
37 JournalQuota,
38 Label,
39 MulticastAddress,
40 PathName,
41 PrivLevel,
42 Quota,
43 ServiceTypeGuid,
44 Attributes,
45 }
46
47 public class MessageQueueSymbol : IntermediateSymbol
48 {
49 public MessageQueueSymbol() : base(MsmqSymbolDefinitions.MessageQueue, null, null)
50 {
51 }
52
53 public MessageQueueSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(MsmqSymbolDefinitions.MessageQueue, sourceLineNumber, id)
54 {
55 }
56
57 public IntermediateField this[MessageQueueSymbolFields index] => this.Fields[(int)index];
58
59 public string ComponentRef
60 {
61 get => this.Fields[(int)MessageQueueSymbolFields.ComponentRef].AsString();
62 set => this.Set((int)MessageQueueSymbolFields.ComponentRef, value);
63 }
64
65 public int? BasePriority
66 {
67 get => this.Fields[(int)MessageQueueSymbolFields.BasePriority].AsNullableNumber();
68 set => this.Set((int)MessageQueueSymbolFields.BasePriority, value);
69 }
70
71 public int? JournalQuota
72 {
73 get => this.Fields[(int)MessageQueueSymbolFields.JournalQuota].AsNullableNumber();
74 set => this.Set((int)MessageQueueSymbolFields.JournalQuota, value);
75 }
76
77 public string Label
78 {
79 get => this.Fields[(int)MessageQueueSymbolFields.Label].AsString();
80 set => this.Set((int)MessageQueueSymbolFields.Label, value);
81 }
82
83 public string MulticastAddress
84 {
85 get => this.Fields[(int)MessageQueueSymbolFields.MulticastAddress].AsString();
86 set => this.Set((int)MessageQueueSymbolFields.MulticastAddress, value);
87 }
88
89 public string PathName
90 {
91 get => this.Fields[(int)MessageQueueSymbolFields.PathName].AsString();
92 set => this.Set((int)MessageQueueSymbolFields.PathName, value);
93 }
94
95 public int? PrivLevel
96 {
97 get => this.Fields[(int)MessageQueueSymbolFields.PrivLevel].AsNullableNumber();
98 set => this.Set((int)MessageQueueSymbolFields.PrivLevel, value);
99 }
100
101 public int? Quota
102 {
103 get => this.Fields[(int)MessageQueueSymbolFields.Quota].AsNullableNumber();
104 set => this.Set((int)MessageQueueSymbolFields.Quota, value);
105 }
106
107 public string ServiceTypeGuid
108 {
109 get => this.Fields[(int)MessageQueueSymbolFields.ServiceTypeGuid].AsString();
110 set => this.Set((int)MessageQueueSymbolFields.ServiceTypeGuid, value);
111 }
112
113 public int Attributes
114 {
115 get => this.Fields[(int)MessageQueueSymbolFields.Attributes].AsNumber();
116 set => this.Set((int)MessageQueueSymbolFields.Attributes, value);
117 }
118 }
119} \ No newline at end of file
diff --git a/src/ext/Msmq/wixext/Symbols/MessageQueueUserPermissionSymbol.cs b/src/ext/Msmq/wixext/Symbols/MessageQueueUserPermissionSymbol.cs
new file mode 100644
index 00000000..cc783845
--- /dev/null
+++ b/src/ext/Msmq/wixext/Symbols/MessageQueueUserPermissionSymbol.cs
@@ -0,0 +1,71 @@
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.Msmq
4{
5 using WixToolset.Data;
6 using WixToolset.Msmq.Symbols;
7
8 public static partial class MsmqSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition MessageQueueUserPermission = new IntermediateSymbolDefinition(
11 MsmqSymbolDefinitionType.MessageQueueUserPermission.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(MessageQueueUserPermissionSymbolFields.ComponentRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(MessageQueueUserPermissionSymbolFields.MessageQueueRef), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(MessageQueueUserPermissionSymbolFields.UserRef), IntermediateFieldType.String),
17 new IntermediateFieldDefinition(nameof(MessageQueueUserPermissionSymbolFields.Permissions), IntermediateFieldType.Number),
18 },
19 typeof(MessageQueueUserPermissionSymbol));
20 }
21}
22
23namespace WixToolset.Msmq.Symbols
24{
25 using WixToolset.Data;
26
27 public enum MessageQueueUserPermissionSymbolFields
28 {
29 ComponentRef,
30 MessageQueueRef,
31 UserRef,
32 Permissions,
33 }
34
35 public class MessageQueueUserPermissionSymbol : IntermediateSymbol
36 {
37 public MessageQueueUserPermissionSymbol() : base(MsmqSymbolDefinitions.MessageQueueUserPermission, null, null)
38 {
39 }
40
41 public MessageQueueUserPermissionSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(MsmqSymbolDefinitions.MessageQueueUserPermission, sourceLineNumber, id)
42 {
43 }
44
45 public IntermediateField this[MessageQueueUserPermissionSymbolFields index] => this.Fields[(int)index];
46
47 public string ComponentRef
48 {
49 get => this.Fields[(int)MessageQueueUserPermissionSymbolFields.ComponentRef].AsString();
50 set => this.Set((int)MessageQueueUserPermissionSymbolFields.ComponentRef, value);
51 }
52
53 public string MessageQueueRef
54 {
55 get => this.Fields[(int)MessageQueueUserPermissionSymbolFields.MessageQueueRef].AsString();
56 set => this.Set((int)MessageQueueUserPermissionSymbolFields.MessageQueueRef, value);
57 }
58
59 public string UserRef
60 {
61 get => this.Fields[(int)MessageQueueUserPermissionSymbolFields.UserRef].AsString();
62 set => this.Set((int)MessageQueueUserPermissionSymbolFields.UserRef, value);
63 }
64
65 public int Permissions
66 {
67 get => this.Fields[(int)MessageQueueUserPermissionSymbolFields.Permissions].AsNumber();
68 set => this.Set((int)MessageQueueUserPermissionSymbolFields.Permissions, value);
69 }
70 }
71} \ No newline at end of file
diff --git a/src/ext/Msmq/wixext/Symbols/MsmqSymbolDefinitions.cs b/src/ext/Msmq/wixext/Symbols/MsmqSymbolDefinitions.cs
new file mode 100644
index 00000000..229417fe
--- /dev/null
+++ b/src/ext/Msmq/wixext/Symbols/MsmqSymbolDefinitions.cs
@@ -0,0 +1,47 @@
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.Msmq
4{
5 using System;
6 using WixToolset.Data;
7
8 public enum MsmqSymbolDefinitionType
9 {
10 MessageQueue,
11 MessageQueueGroupPermission,
12 MessageQueueUserPermission,
13 }
14
15 public static partial class MsmqSymbolDefinitions
16 {
17 public static readonly Version Version = new Version("4.0.0");
18
19 public static IntermediateSymbolDefinition ByName(string name)
20 {
21 if (!Enum.TryParse(name, out MsmqSymbolDefinitionType type))
22 {
23 return null;
24 }
25
26 return ByType(type);
27 }
28
29 public static IntermediateSymbolDefinition ByType(MsmqSymbolDefinitionType type)
30 {
31 switch (type)
32 {
33 case MsmqSymbolDefinitionType.MessageQueue:
34 return MsmqSymbolDefinitions.MessageQueue;
35
36 case MsmqSymbolDefinitionType.MessageQueueGroupPermission:
37 return MsmqSymbolDefinitions.MessageQueueGroupPermission;
38
39 case MsmqSymbolDefinitionType.MessageQueueUserPermission:
40 return MsmqSymbolDefinitions.MessageQueueUserPermission;
41
42 default:
43 throw new ArgumentOutOfRangeException(nameof(type));
44 }
45 }
46 }
47}
diff --git a/src/ext/Msmq/wixext/WixToolset.Msmq.wixext.csproj b/src/ext/Msmq/wixext/WixToolset.Msmq.wixext.csproj
new file mode 100644
index 00000000..4bd6a3f5
--- /dev/null
+++ b/src/ext/Msmq/wixext/WixToolset.Msmq.wixext.csproj
@@ -0,0 +1,30 @@
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.Msmq</RootNamespace>
8 <Description>WiX Toolset MSMQ Extension</Description>
9 <Title>WiX Toolset MSMQ Extension</Title>
10 <IsTool>true</IsTool>
11 <ContentTargetFolders>build</ContentTargetFolders>
12 </PropertyGroup>
13
14 <ItemGroup>
15 <Content Include="$(MSBuildThisFileName).targets" />
16 <EmbeddedResource Include="$(OutputPath)..\msmq.wixlib" />
17 </ItemGroup>
18
19 <ItemGroup>
20 <PackageReference Include="WixToolset.Extensibility" Version="4.0.*" PrivateAssets="all" />
21 </ItemGroup>
22
23 <ItemGroup>
24 <ProjectReference Include="..\wixlib\msmq.wixproj" ReferenceOutputAssembly="false" Condition=" '$(NCrunch)'=='' " />
25 </ItemGroup>
26
27 <ItemGroup>
28 <PackageReference Include="Nerdbank.GitVersioning" Version="3.3.37" PrivateAssets="all" />
29 </ItemGroup>
30</Project>
diff --git a/src/ext/Msmq/wixext/WixToolset.Msmq.wixext.targets b/src/ext/Msmq/wixext/WixToolset.Msmq.wixext.targets
new file mode 100644
index 00000000..5f69fe48
--- /dev/null
+++ b/src/ext/Msmq/wixext/WixToolset.Msmq.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 <WixToolsetMsmqWixextPath Condition=" '$(WixToolsetMsmqWixextPath)' == '' ">$(MSBuildThisFileDirectory)..\tools\WixToolset.Msmq.wixext.dll</WixToolsetMsmqWixextPath>
7 </PropertyGroup>
8 <ItemGroup>
9 <WixExtension Include="$(WixToolsetMsmqWixextPath)" />
10 </ItemGroup>
11</Project>