aboutsummaryrefslogtreecommitdiff
path: root/src/ext/ComPlus/wixext/ComPlusCompiler.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/ComPlus/wixext/ComPlusCompiler.cs')
-rw-r--r--src/ext/ComPlus/wixext/ComPlusCompiler.cs2164
1 files changed, 2164 insertions, 0 deletions
diff --git a/src/ext/ComPlus/wixext/ComPlusCompiler.cs b/src/ext/ComPlus/wixext/ComPlusCompiler.cs
new file mode 100644
index 00000000..4404801e
--- /dev/null
+++ b/src/ext/ComPlus/wixext/ComPlusCompiler.cs
@@ -0,0 +1,2164 @@
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.ComPlus
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Xml.Linq;
8 using WixToolset.ComPlus.Symbols;
9 using WixToolset.Data;
10 using WixToolset.Extensibility;
11
12 /// <summary>
13 /// The compiler for the WiX Toolset COM+ Extension.
14 /// </summary>
15 public sealed class ComPlusCompiler : BaseCompilerExtension
16 {
17 /// <summary>
18 /// </summary>
19 /// <remarks></remarks>
20 public enum CpiAssemblyAttributes
21 {
22 EventClass = (1 << 0),
23 DotNetAssembly = (1 << 1),
24 DllPathFromGAC = (1 << 2),
25 RegisterInCommit = (1 << 3)
26 }
27
28 public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/complus";
29
30 /// <summary>
31 /// Processes an element for the Compiler.
32 /// </summary>
33 /// <param name="sourceLineNumbers">Source line number for the parent element.</param>
34 /// <param name="parentElement">Parent element of element to process.</param>
35 /// <param name="element">Element to process.</param>
36 /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param>
37 public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
38 {
39 switch (parentElement.Name.LocalName)
40 {
41 case "Component":
42 var componentId = context["ComponentId"];
43 var directoryId = context["DirectoryId"];
44 var win64 = Boolean.Parse(context["Win64"]);
45
46 switch (element.Name.LocalName)
47 {
48 case "ComPlusPartition":
49 this.ParseComPlusPartitionElement(intermediate, section, element, componentId, win64);
50 break;
51 case "ComPlusPartitionRole":
52 this.ParseComPlusPartitionRoleElement(intermediate, section, element, componentId, null);
53 break;
54 case "ComPlusUserInPartitionRole":
55 this.ParseComPlusUserInPartitionRoleElement(intermediate, section, element, componentId, null);
56 break;
57 case "ComPlusGroupInPartitionRole":
58 this.ParseComPlusGroupInPartitionRoleElement(intermediate, section, element, componentId, null);
59 break;
60 case "ComPlusPartitionUser":
61 this.ParseComPlusPartitionUserElement(intermediate, section, element, componentId, null);
62 break;
63 case "ComPlusApplication":
64 this.ParseComPlusApplicationElement(intermediate, section, element, componentId, win64, null);
65 break;
66 case "ComPlusApplicationRole":
67 this.ParseComPlusApplicationRoleElement(intermediate, section, element, componentId, null);
68 break;
69 case "ComPlusUserInApplicationRole":
70 this.ParseComPlusUserInApplicationRoleElement(intermediate, section, element, componentId, null);
71 break;
72 case "ComPlusGroupInApplicationRole":
73 this.ParseComPlusGroupInApplicationRoleElement(intermediate, section, element, componentId, null);
74 break;
75 case "ComPlusAssembly":
76 this.ParseComPlusAssemblyElement(intermediate, section, element, componentId, win64, null);
77 break;
78 case "ComPlusRoleForComponent":
79 this.ParseComPlusRoleForComponentElement(intermediate, section, element, componentId, null);
80 break;
81 case "ComPlusRoleForInterface":
82 this.ParseComPlusRoleForInterfaceElement(intermediate, section, element, componentId, null);
83 break;
84 case "ComPlusRoleForMethod":
85 this.ParseComPlusRoleForMethodElement(intermediate, section, element, componentId, null);
86 break;
87 case "ComPlusSubscription":
88 this.ParseComPlusSubscriptionElement(intermediate, section, element, componentId, null);
89 break;
90 default:
91 this.ParseHelper.UnexpectedElement(parentElement, element);
92 break;
93 }
94 break;
95 case "Fragment":
96 case "Module":
97 case "Package":
98 switch (element.Name.LocalName)
99 {
100 case "ComPlusPartition":
101 this.ParseComPlusPartitionElement(intermediate, section, element, null, false);
102 break;
103 case "ComPlusPartitionRole":
104 this.ParseComPlusPartitionRoleElement(intermediate, section, element, null, null);
105 break;
106 case "ComPlusApplication":
107 this.ParseComPlusApplicationElement(intermediate, section, element, null, false, null);
108 break;
109 case "ComPlusApplicationRole":
110 this.ParseComPlusApplicationRoleElement(intermediate, section, element, null, null);
111 break;
112 default:
113 this.ParseHelper.UnexpectedElement(parentElement, element);
114 break;
115 }
116 break;
117 default:
118 this.ParseHelper.UnexpectedElement(parentElement, element);
119 break;
120 }
121 }
122
123 /// <summary>
124 /// Parses a COM+ partition element.
125 /// </summary>
126 /// <param name="node">Element to parse.</param>
127 /// <param name="componentKey">Identifier of parent component.</param>
128 private void ParseComPlusPartitionElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, bool win64)
129 {
130 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
131
132 Identifier key = null;
133 string id = null;
134 string name = null;
135
136 var properties = new Dictionary<string, string>();
137
138 foreach (var attrib in node.Attributes())
139 {
140 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
141 {
142 switch (attrib.Name.LocalName)
143 {
144 case "Id":
145 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
146 break;
147 case "PartitionId":
148 id = this.TryFormatGuidValue(this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib));
149 break;
150 case "Name":
151 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
152 break;
153 case "Changeable":
154 this.Messaging.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
155 break;
156 case "Deleteable":
157 if (null == componentKey)
158 {
159 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
160 }
161 properties["Deleteable"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
162 break;
163 case "Description":
164 if (null == componentKey)
165 {
166 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
167 }
168 properties["Description"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
169 break;
170 default:
171 this.ParseHelper.UnexpectedAttribute(node, attrib);
172 break;
173 }
174 }
175 else
176 {
177 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
178 }
179 }
180
181 if (null != componentKey && null == name)
182 {
183 this.Messaging.Write(ComPlusErrors.RequiredAttributeUnderComponent(sourceLineNumbers, node.Name.LocalName, "Name"));
184 }
185 if (null == componentKey && null == id && null == name)
186 {
187 this.Messaging.Write(ComPlusErrors.RequiredAttributeNotUnderComponent(sourceLineNumbers, node.Name.LocalName, "Id", "Name"));
188 }
189
190 foreach (var child in node.Elements())
191 {
192 if (this.Namespace == child.Name.Namespace)
193 {
194 switch (child.Name.LocalName)
195 {
196 case "ComPlusPartitionRole":
197 this.ParseComPlusPartitionRoleElement(intermediate, section, child, componentKey, key?.Id);
198 break;
199 case "ComPlusPartitionUser":
200 this.ParseComPlusPartitionUserElement(intermediate, section, child, componentKey, key?.Id);
201 break;
202 case "ComPlusApplication":
203 this.ParseComPlusApplicationElement(intermediate, section, child, componentKey, win64, key?.Id);
204 break;
205 default:
206 this.ParseHelper.UnexpectedElement(node, child);
207 break;
208 }
209 }
210 else
211 {
212 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
213 }
214 }
215
216 section.AddSymbol(new ComPlusPartitionSymbol(sourceLineNumbers, key)
217 {
218 ComponentRef = componentKey,
219 PartitionId = id,
220 Name = name,
221 });
222
223 foreach (var kvp in properties)
224 {
225 section.AddSymbol(new ComPlusPartitionPropertySymbol(sourceLineNumbers)
226 {
227 PartitionRef = key?.Id,
228 Name = kvp.Key,
229 Value = kvp.Value,
230 });
231 }
232
233 if (componentKey != null)
234 {
235 this.AddReferenceToConfigureComPlus(section, sourceLineNumbers, node.Name.LocalName, win64);
236 }
237 }
238
239 /// <summary>
240 /// Parses a COM+ partition role element.
241 /// </summary>
242 /// <param name="node">Element to parse.</param>
243 /// <param name="componentKey">Identifier of parent component.</param>
244 /// <param name="applicationKey">Optional identifier of parent application.</param>
245 private void ParseComPlusPartitionRoleElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string partitionKey)
246 {
247 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
248
249 Identifier key = null;
250 string name = null;
251
252 foreach (var attrib in node.Attributes())
253 {
254 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
255 {
256 switch (attrib.Name.LocalName)
257 {
258 case "Id":
259 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
260 break;
261 case "Partition":
262 if (null != partitionKey)
263 {
264 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
265 }
266 partitionKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
267 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusPartition, partitionKey);
268 break;
269 case "Name":
270 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
271 break;
272 default:
273 this.ParseHelper.UnexpectedAttribute(node, attrib);
274 break;
275 }
276 }
277 else
278 {
279 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
280 }
281 }
282
283 if (null == partitionKey)
284 {
285 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Partition"));
286 }
287
288 foreach (var child in node.Elements())
289 {
290 if (this.Namespace == child.Name.Namespace)
291 {
292 switch (child.Name.LocalName)
293 {
294 case "ComPlusUserInPartitionRole":
295 this.ParseComPlusUserInPartitionRoleElement(intermediate, section, child, componentKey, key?.Id);
296 break;
297 case "ComPlusGroupInPartitionRole":
298 this.ParseComPlusGroupInPartitionRoleElement(intermediate, section, child, componentKey, key?.Id);
299 break;
300 default:
301 this.ParseHelper.UnexpectedElement(node, child);
302 break;
303 }
304 }
305 else
306 {
307 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
308 }
309 }
310
311 section.AddSymbol(new ComPlusPartitionRoleSymbol(sourceLineNumbers, key)
312 {
313 PartitionRef = partitionKey,
314 Name = name,
315 });
316 }
317
318 /// <summary>
319 /// Parses a COM+ partition role user element.
320 /// </summary>
321 /// <param name="node">Element to parse.</param>
322 /// <param name="componentKey">Identifier of parent component.</param>
323 /// <param name="applicationKey">Optional identifier of parent application role.</param>
324 private void ParseComPlusUserInPartitionRoleElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string partitionRoleKey)
325 {
326 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
327
328 Identifier key = null;
329 string user = null;
330
331 foreach (var attrib in node.Attributes())
332 {
333 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
334 {
335 switch (attrib.Name.LocalName)
336 {
337 case "Id":
338 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
339 break;
340 case "PartitionRole":
341 if (null != partitionRoleKey)
342 {
343 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
344 }
345 partitionRoleKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
346 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusPartitionRole, partitionRoleKey);
347 break;
348 case "User":
349 user = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
350 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", user);
351 break;
352 default:
353 this.ParseHelper.UnexpectedAttribute(node, attrib);
354 break;
355 }
356 }
357 else
358 {
359 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
360 }
361 }
362
363 if (null == partitionRoleKey)
364 {
365 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "PartitionRole"));
366 }
367
368 section.AddSymbol(new ComPlusUserInPartitionRoleSymbol(sourceLineNumbers, key)
369 {
370 PartitionRoleRef = partitionRoleKey,
371 ComponentRef = componentKey,
372 UserRef = user,
373 });
374 }
375
376 /// <summary>
377 /// Parses a COM+ partition role user element.
378 /// </summary>
379 /// <param name="node">Element to parse.</param>
380 /// <param name="componentKey">Identifier of parent component.</param>
381 /// <param name="applicationKey">Optional identifier of parent application role.</param>
382 private void ParseComPlusGroupInPartitionRoleElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string partitionRoleKey)
383 {
384 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
385
386 Identifier key = null;
387 string group = null;
388
389 foreach (var attrib in node.Attributes())
390 {
391 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
392 {
393 switch (attrib.Name.LocalName)
394 {
395 case "Id":
396 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
397 break;
398 case "PartitionRole":
399 if (null != partitionRoleKey)
400 {
401 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
402 }
403 partitionRoleKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
404 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusPartitionRole, partitionRoleKey);
405 break;
406 case "Group":
407 group = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
408 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "Group", group);
409 break;
410 default:
411 this.ParseHelper.UnexpectedAttribute(node, attrib);
412 break;
413 }
414 }
415 else
416 {
417 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
418 }
419 }
420
421 if (null == partitionRoleKey)
422 {
423 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "PartitionRole"));
424 }
425
426 section.AddSymbol(new ComPlusGroupInPartitionRoleSymbol(sourceLineNumbers, key)
427 {
428 PartitionRoleRef = partitionRoleKey,
429 ComponentRef = componentKey,
430 GroupRef = group,
431 });
432 }
433
434 /// <summary>
435 /// Parses a COM+ partition element.
436 /// </summary>
437 /// <param name="node">Element to parse.</param>
438 /// <param name="componentKey">Identifier of parent component.</param>
439 private void ParseComPlusPartitionUserElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string partitionKey)
440 {
441 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
442
443 Identifier key = null;
444 string user = null;
445
446 foreach (var attrib in node.Attributes())
447 {
448 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
449 {
450 switch (attrib.Name.LocalName)
451 {
452 case "Id":
453 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
454 break;
455 case "Partition":
456 if (null != partitionKey)
457 {
458 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
459 }
460 partitionKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
461 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusPartition, partitionKey);
462 break;
463 case "User":
464 user = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
465 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", user);
466 break;
467 default:
468 this.ParseHelper.UnexpectedAttribute(node, attrib);
469 break;
470 }
471 }
472 else
473 {
474 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
475 }
476 }
477
478 if (null == partitionKey)
479 {
480 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Partition"));
481 }
482
483 section.AddSymbol(new ComPlusPartitionUserSymbol(sourceLineNumbers, key)
484 {
485 PartitionRef = partitionKey,
486 ComponentRef = componentKey,
487 UserRef = user,
488 });
489 }
490
491 /// <summary>
492 /// Parses a COM+ application element.
493 /// </summary>
494 /// <param name="node">Element to parse.</param>
495 /// <param name="componentKey">Identifier of parent component.</param>
496 /// <param name="partitionKey">Optional identifier of parent partition.</param>
497 private void ParseComPlusApplicationElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, bool win64, string partitionKey)
498 {
499 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
500
501 Identifier key = null;
502 string id = null;
503 string name = null;
504
505 var properties = new Dictionary<string, string>();
506
507 foreach (XAttribute attrib in node.Attributes())
508 {
509 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
510 {
511 switch (attrib.Name.LocalName)
512 {
513 case "Id":
514 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
515 break;
516 case "Partition":
517 if (null != partitionKey)
518 {
519 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
520 }
521 partitionKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
522 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusPartition, partitionKey);
523 break;
524 case "ApplicationId":
525 id = this.TryFormatGuidValue(this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib));
526 break;
527 case "Name":
528 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
529 break;
530 case "ThreeGigSupportEnabled":
531 if (null == componentKey)
532 {
533 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
534 }
535 properties["3GigSupportEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
536 break;
537 case "AccessChecksLevel":
538 if (null == componentKey)
539 {
540 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
541 }
542 var accessChecksLevelValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
543 switch (accessChecksLevelValue)
544 {
545 case "applicationLevel":
546 properties["AccessChecksLevel"] = "0";
547 break;
548 case "applicationComponentLevel":
549 properties["AccessChecksLevel"] = "1";
550 break;
551 default:
552 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "AccessChecksLevel", accessChecksLevelValue, "applicationLevel", "applicationComponentLevel"));
553 break;
554 }
555 break;
556 case "Activation":
557 if (null == componentKey)
558 {
559 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
560 }
561 var activationValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
562 switch (activationValue)
563 {
564 case "inproc":
565 properties["Activation"] = "Inproc";
566 break;
567 case "local":
568 properties["Activation"] = "Local";
569 break;
570 default:
571 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "Activation", activationValue, "inproc", "local"));
572 break;
573 }
574 break;
575 case "ApplicationAccessChecksEnabled":
576 if (null == componentKey)
577 {
578 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
579 }
580 properties["ApplicationAccessChecksEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
581 break;
582 case "ApplicationDirectory":
583 if (null == componentKey)
584 {
585 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
586 }
587 properties["ApplicationDirectory"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
588 break;
589 case "Authentication":
590 if (null == componentKey)
591 {
592 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
593 }
594 string authenticationValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
595 switch (authenticationValue)
596 {
597 case "default":
598 properties["Authentication"] = "0";
599 break;
600 case "none":
601 properties["Authentication"] = "1";
602 break;
603 case "connect":
604 properties["Authentication"] = "2";
605 break;
606 case "call":
607 properties["Authentication"] = "3";
608 break;
609 case "packet":
610 properties["Authentication"] = "4";
611 break;
612 case "integrity":
613 properties["Authentication"] = "5";
614 break;
615 case "privacy":
616 properties["Authentication"] = "6";
617 break;
618 default:
619 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "Authentication", authenticationValue, "default", "none", "connect", "call", "packet", "integrity", "privacy"));
620 break;
621 }
622 break;
623 case "AuthenticationCapability":
624 if (null == componentKey)
625 {
626 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
627 }
628 var authenticationCapabilityValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
629 switch (authenticationCapabilityValue)
630 {
631 case "none":
632 properties["AuthenticationCapability"] = "0";
633 break;
634 case "secureReference":
635 properties["AuthenticationCapability"] = "2";
636 break;
637 case "staticCloaking":
638 properties["AuthenticationCapability"] = "32";
639 break;
640 case "dynamicCloaking":
641 properties["AuthenticationCapability"] = "64";
642 break;
643 default:
644 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "AuthenticationCapability", authenticationCapabilityValue, "none", "secureReference", "staticCloaking", "dynamicCloaking"));
645 break;
646 }
647 break;
648 case "Changeable":
649 this.Messaging.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
650 break;
651 case "CommandLine":
652 if (null == componentKey)
653 {
654 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
655 }
656 properties["CommandLine"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
657 break;
658 case "ConcurrentApps":
659 if (null == componentKey)
660 {
661 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
662 }
663 properties["ConcurrentApps"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
664 break;
665 case "CreatedBy":
666 if (null == componentKey)
667 {
668 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
669 }
670 properties["CreatedBy"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
671 break;
672 case "CRMEnabled":
673 if (null == componentKey)
674 {
675 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
676 }
677 properties["CRMEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
678 break;
679 case "CRMLogFile":
680 if (null == componentKey)
681 {
682 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
683 }
684 properties["CRMLogFile"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
685 break;
686 case "Deleteable":
687 if (null == componentKey)
688 {
689 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
690 }
691 properties["Deleteable"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
692 break;
693 case "Description":
694 if (null == componentKey)
695 {
696 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
697 }
698 properties["Description"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
699 break;
700 case "DumpEnabled":
701 if (null == componentKey)
702 {
703 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
704 }
705 properties["DumpEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
706 break;
707 case "DumpOnException":
708 if (null == componentKey)
709 {
710 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
711 }
712 properties["DumpOnException"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
713 break;
714 case "DumpOnFailfast":
715 if (null == componentKey)
716 {
717 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
718 }
719 properties["DumpOnFailfast"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
720 break;
721 case "DumpPath":
722 if (null == componentKey)
723 {
724 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
725 }
726 properties["DumpPath"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
727 break;
728 case "EventsEnabled":
729 if (null == componentKey)
730 {
731 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
732 }
733 properties["EventsEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
734 break;
735 case "Identity":
736 if (null == componentKey)
737 {
738 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
739 }
740 properties["Identity"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
741 break;
742 case "ImpersonationLevel":
743 if (null == componentKey)
744 {
745 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
746 }
747 string impersonationLevelValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
748 switch (impersonationLevelValue)
749 {
750 case "anonymous":
751 properties["ImpersonationLevel"] = "1";
752 break;
753 case "identify":
754 properties["ImpersonationLevel"] = "2";
755 break;
756 case "impersonate":
757 properties["ImpersonationLevel"] = "3";
758 break;
759 case "delegate":
760 properties["ImpersonationLevel"] = "4";
761 break;
762 default:
763 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "ImpersonationLevel", impersonationLevelValue, "anonymous", "identify", "impersonate", "delegate"));
764 break;
765 }
766 break;
767 case "IsEnabled":
768 if (null == componentKey)
769 {
770 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
771 }
772 properties["IsEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
773 break;
774 case "MaxDumpCount":
775 if (null == componentKey)
776 {
777 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
778 }
779 properties["MaxDumpCount"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
780 break;
781 case "Password":
782 if (null == componentKey)
783 {
784 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
785 }
786 properties["Password"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
787 break;
788 case "QCAuthenticateMsgs":
789 if (null == componentKey)
790 {
791 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
792 }
793 string qcAuthenticateMsgsValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
794 switch (qcAuthenticateMsgsValue)
795 {
796 case "secureApps":
797 properties["QCAuthenticateMsgs"] = "0";
798 break;
799 case "off":
800 properties["QCAuthenticateMsgs"] = "1";
801 break;
802 case "on":
803 properties["QCAuthenticateMsgs"] = "2";
804 break;
805 default:
806 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "QCAuthenticateMsgs", qcAuthenticateMsgsValue, "secureApps", "off", "on"));
807 break;
808 }
809 break;
810 case "QCListenerMaxThreads":
811 if (null == componentKey)
812 {
813 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
814 }
815 properties["QCListenerMaxThreads"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
816 break;
817 case "QueueListenerEnabled":
818 if (null == componentKey)
819 {
820 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
821 }
822 properties["QueueListenerEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
823 break;
824 case "QueuingEnabled":
825 if (null == componentKey)
826 {
827 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
828 }
829 properties["QueuingEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
830 break;
831 case "RecycleActivationLimit":
832 if (null == componentKey)
833 {
834 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
835 }
836 properties["RecycleActivationLimit"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
837 break;
838 case "RecycleCallLimit":
839 if (null == componentKey)
840 {
841 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
842 }
843 properties["RecycleCallLimit"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
844 break;
845 case "RecycleExpirationTimeout":
846 if (null == componentKey)
847 {
848 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
849 }
850 properties["RecycleExpirationTimeout"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
851 break;
852 case "RecycleLifetimeLimit":
853 if (null == componentKey)
854 {
855 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
856 }
857 properties["RecycleLifetimeLimit"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
858 break;
859 case "RecycleMemoryLimit":
860 if (null == componentKey)
861 {
862 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
863 }
864 properties["RecycleMemoryLimit"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
865 break;
866 case "Replicable":
867 if (null == componentKey)
868 {
869 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
870 }
871 properties["Replicable"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
872 break;
873 case "RunForever":
874 if (null == componentKey)
875 {
876 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
877 }
878 properties["RunForever"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
879 break;
880 case "ShutdownAfter":
881 if (null == componentKey)
882 {
883 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
884 }
885 properties["ShutdownAfter"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
886 break;
887 case "SoapActivated":
888 if (null == componentKey)
889 {
890 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
891 }
892 properties["SoapActivated"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
893 break;
894 case "SoapBaseUrl":
895 if (null == componentKey)
896 {
897 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
898 }
899 properties["SoapBaseUrl"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
900 break;
901 case "SoapMailTo":
902 if (null == componentKey)
903 {
904 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
905 }
906 properties["SoapMailTo"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
907 break;
908 case "SoapVRoot":
909 if (null == componentKey)
910 {
911 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
912 }
913 properties["SoapVRoot"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
914 break;
915 case "SRPEnabled":
916 if (null == componentKey)
917 {
918 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
919 }
920 properties["SRPEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
921 break;
922 case "SRPTrustLevel":
923 if (null == componentKey)
924 {
925 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
926 }
927 var srpTrustLevelValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
928 switch (srpTrustLevelValue)
929 {
930 case "disallowed":
931 properties["SRPTrustLevel"] = "0";
932 break;
933 case "fullyTrusted":
934 properties["SRPTrustLevel"] = "262144";
935 break;
936 default:
937 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusApplication", "SRPTrustLevel", srpTrustLevelValue, "disallowed", "fullyTrusted"));
938 break;
939 }
940 break;
941 default:
942 this.ParseHelper.UnexpectedAttribute(node, attrib);
943 break;
944 }
945 }
946 else
947 {
948 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
949 }
950 }
951
952 if (null != componentKey && null == name)
953 {
954 this.Messaging.Write(ComPlusErrors.RequiredAttributeUnderComponent(sourceLineNumbers, node.Name.LocalName, "Name"));
955 }
956 if (null == componentKey && null == id && null == name)
957 {
958 this.Messaging.Write(ComPlusErrors.RequiredAttributeNotUnderComponent(sourceLineNumbers, node.Name.LocalName, "Id", "Name"));
959 }
960
961 foreach (var child in node.Elements())
962 {
963 if (this.Namespace == child.Name.Namespace)
964 {
965 switch (child.Name.LocalName)
966 {
967 case "ComPlusApplicationRole":
968 this.ParseComPlusApplicationRoleElement(intermediate, section, child, componentKey, key?.Id);
969 break;
970 case "ComPlusAssembly":
971 this.ParseComPlusAssemblyElement(intermediate, section, child, componentKey, win64, key?.Id);
972 break;
973 default:
974 this.ParseHelper.UnexpectedElement(node, child);
975 break;
976 }
977 }
978 else
979 {
980 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
981 }
982 }
983
984 section.AddSymbol(new ComPlusApplicationSymbol(sourceLineNumbers, key)
985 {
986 PartitionRef = partitionKey,
987 ComponentRef = componentKey,
988 ApplicationId = id,
989 Name = name,
990 });
991
992 foreach (var kvp in properties)
993 {
994 section.AddSymbol(new ComPlusApplicationPropertySymbol(sourceLineNumbers)
995 {
996 ApplicationRef = key?.Id,
997 Name = kvp.Key,
998 Value = kvp.Value,
999 });
1000 }
1001
1002 if (componentKey != null)
1003 {
1004 this.AddReferenceToConfigureComPlus(section, sourceLineNumbers, node.Name.LocalName, win64);
1005 }
1006 }
1007
1008 /// <summary>
1009 /// Parses a COM+ application role element.
1010 /// </summary>
1011 /// <param name="node">Element to parse.</param>
1012 /// <param name="componentKey">Identifier of parent component.</param>
1013 /// <param name="applicationKey">Optional identifier of parent application.</param>
1014 private void ParseComPlusApplicationRoleElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string applicationKey)
1015 {
1016 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1017
1018 Identifier key = null;
1019 string name = null;
1020
1021 var properties = new Dictionary<string, string>();
1022
1023 foreach (var attrib in node.Attributes())
1024 {
1025 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1026 {
1027 switch (attrib.Name.LocalName)
1028 {
1029 case "Id":
1030 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1031 break;
1032 case "Application":
1033 if (null != applicationKey)
1034 {
1035 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1036 }
1037 applicationKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1038 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusApplication, applicationKey);
1039 break;
1040 case "Name":
1041 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1042 break;
1043 case "Description":
1044 if (null == componentKey)
1045 {
1046 this.Messaging.Write(ComPlusErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
1047 }
1048 properties["Description"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1049 break;
1050 default:
1051 this.ParseHelper.UnexpectedAttribute(node, attrib);
1052 break;
1053 }
1054 }
1055 else
1056 {
1057 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1058 }
1059 }
1060
1061 if (null == applicationKey)
1062 {
1063 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Application"));
1064 }
1065
1066 foreach (var child in node.Elements())
1067 {
1068 if (this.Namespace == child.Name.Namespace)
1069 {
1070 switch (child.Name.LocalName)
1071 {
1072 case "ComPlusUserInApplicationRole":
1073 this.ParseComPlusUserInApplicationRoleElement(intermediate, section, child, componentKey, key?.Id);
1074 break;
1075 case "ComPlusGroupInApplicationRole":
1076 this.ParseComPlusGroupInApplicationRoleElement(intermediate, section, child, componentKey, key?.Id);
1077 break;
1078 default:
1079 this.ParseHelper.UnexpectedElement(node, child);
1080 break;
1081 }
1082 }
1083 else
1084 {
1085 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
1086 }
1087 }
1088
1089 section.AddSymbol(new ComPlusApplicationRoleSymbol(sourceLineNumbers, key)
1090 {
1091 ApplicationRef = applicationKey,
1092 ComponentRef = componentKey,
1093 Name = name,
1094 });
1095
1096 foreach (var kvp in properties)
1097 {
1098 section.AddSymbol(new ComPlusApplicationRolePropertySymbol(sourceLineNumbers)
1099 {
1100 ApplicationRoleRef = key?.Id,
1101 Name = kvp.Key,
1102 Value = kvp.Value,
1103 });
1104 }
1105 }
1106
1107 /// <summary>
1108 /// Parses a COM+ application role user element.
1109 /// </summary>
1110 /// <param name="node">Element to parse.</param>
1111 /// <param name="componentKey">Identifier of parent component.</param>
1112 /// <param name="applicationKey">Optional identifier of parent application role.</param>
1113 private void ParseComPlusUserInApplicationRoleElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string applicationRoleKey)
1114 {
1115 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1116
1117 Identifier key = null;
1118 string user = null;
1119
1120 foreach (var attrib in node.Attributes())
1121 {
1122 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1123 {
1124 switch (attrib.Name.LocalName)
1125 {
1126 case "Id":
1127 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1128 break;
1129 case "ApplicationRole":
1130 if (null != applicationRoleKey)
1131 {
1132 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1133 }
1134 applicationRoleKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1135 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusApplicationRole, applicationRoleKey);
1136 break;
1137 case "User":
1138 user = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1139 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", user);
1140 break;
1141 default:
1142 this.ParseHelper.UnexpectedAttribute(node, attrib);
1143 break;
1144 }
1145 }
1146 else
1147 {
1148 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1149 }
1150 }
1151
1152 if (null == applicationRoleKey)
1153 {
1154 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ApplicationRole"));
1155 }
1156
1157 section.AddSymbol(new ComPlusUserInApplicationRoleSymbol(sourceLineNumbers, key)
1158 {
1159 ApplicationRoleRef = applicationRoleKey,
1160 ComponentRef = componentKey,
1161 UserRef = user,
1162 });
1163 }
1164
1165 /// <summary>
1166 /// Parses a COM+ application role group element.
1167 /// </summary>
1168 /// <param name="node">Element to parse.</param>
1169 /// <param name="componentKey">Identifier of parent component.</param>
1170 /// <param name="applicationKey">Optional identifier of parent application role.</param>
1171 private void ParseComPlusGroupInApplicationRoleElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string applicationRoleKey)
1172 {
1173 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1174
1175 Identifier key = null;
1176 string group = null;
1177
1178 foreach (var attrib in node.Attributes())
1179 {
1180 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1181 {
1182 switch (attrib.Name.LocalName)
1183 {
1184 case "Id":
1185 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1186 break;
1187 case "ApplicationRole":
1188 if (null != applicationRoleKey)
1189 {
1190 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1191 }
1192 applicationRoleKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1193 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusApplicationRole, applicationRoleKey);
1194 break;
1195 case "Group":
1196 group = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1197 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "Group", group);
1198 break;
1199 default:
1200 this.ParseHelper.UnexpectedAttribute(node, attrib);
1201 break;
1202 }
1203 }
1204 else
1205 {
1206 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1207 }
1208 }
1209
1210 if (null == applicationRoleKey)
1211 {
1212 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ApplicationRole"));
1213 }
1214
1215 section.AddSymbol(new ComPlusGroupInApplicationRoleSymbol(sourceLineNumbers, key)
1216 {
1217 ApplicationRoleRef = applicationRoleKey,
1218 ComponentRef = componentKey,
1219 GroupRef = group,
1220 });
1221 }
1222
1223 /// <summary>
1224 /// Parses a COM+ assembly element.
1225 /// </summary>
1226 /// <param name="node">Element to parse.</param>
1227 /// <param name="componentKey">Identifier of parent component.</param>
1228 /// <param name="applicationKey">Optional identifier of parent application.</param>
1229 private void ParseComPlusAssemblyElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, bool win64, string applicationKey)
1230 {
1231 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1232
1233 Identifier key = null;
1234 string assemblyName = null;
1235 string dllPath = null;
1236 string tlbPath = null;
1237 string psDllPath = null;
1238 int attributes = 0;
1239
1240 var hasComponents = false;
1241
1242 foreach (var attrib in node.Attributes())
1243 {
1244 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1245 {
1246 switch (attrib.Name.LocalName)
1247 {
1248 case "Id":
1249 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1250 break;
1251 case "Application":
1252 if (null != applicationKey)
1253 {
1254 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1255 }
1256 applicationKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1257 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusApplication, applicationKey);
1258 break;
1259 case "AssemblyName":
1260 assemblyName = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1261 break;
1262 case "DllPath":
1263 dllPath = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1264 break;
1265 case "TlbPath":
1266 tlbPath = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1267 break;
1268 case "PSDllPath":
1269 psDllPath = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1270 break;
1271 case "Type":
1272 string typeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1273 switch (typeValue)
1274 {
1275 case ".net":
1276 attributes |= (int)CpiAssemblyAttributes.DotNetAssembly;
1277 break;
1278 case "native":
1279 attributes &= ~(int)CpiAssemblyAttributes.DotNetAssembly;
1280 break;
1281 default:
1282 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusAssembly", "Type", typeValue, ".net", "native"));
1283 break;
1284 }
1285 break;
1286 case "EventClass":
1287 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
1288 {
1289 attributes |= (int)CpiAssemblyAttributes.EventClass;
1290 }
1291 else
1292 {
1293 attributes &= ~(int)CpiAssemblyAttributes.EventClass;
1294 }
1295 break;
1296 case "DllPathFromGAC":
1297 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
1298 {
1299 attributes |= (int)CpiAssemblyAttributes.DllPathFromGAC;
1300 }
1301 else
1302 {
1303 attributes &= ~(int)CpiAssemblyAttributes.DllPathFromGAC;
1304 }
1305 break;
1306 case "RegisterInCommit":
1307 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
1308 {
1309 attributes |= (int)CpiAssemblyAttributes.RegisterInCommit;
1310 }
1311 else
1312 {
1313 attributes &= ~(int)CpiAssemblyAttributes.RegisterInCommit;
1314 }
1315 break;
1316 default:
1317 this.ParseHelper.UnexpectedAttribute(node, attrib);
1318 break;
1319 }
1320 }
1321 else
1322 {
1323 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1324 }
1325 }
1326
1327 if (null == applicationKey && 0 == (attributes & (int)CpiAssemblyAttributes.DotNetAssembly))
1328 {
1329 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Application", "Type", "native"));
1330 }
1331 if (null != assemblyName && 0 == (attributes & (int)CpiAssemblyAttributes.DllPathFromGAC))
1332 {
1333 this.Messaging.Write(ComPlusErrors.UnexpectedAttributeWithoutOtherValue(sourceLineNumbers, node.Name.LocalName, "AssemblyName", "DllPathFromGAC", "no"));
1334 }
1335 if (null == tlbPath && 0 != (attributes & (int)CpiAssemblyAttributes.DotNetAssembly))
1336 {
1337 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "TlbPath", "Type", ".net"));
1338 }
1339 if (null != psDllPath && 0 != (attributes & (int)CpiAssemblyAttributes.DotNetAssembly))
1340 {
1341 this.Messaging.Write(ComPlusErrors.UnexpectedAttributeWithOtherValue(sourceLineNumbers, node.Name.LocalName, "PSDllPath", "Type", ".net"));
1342 }
1343 if (0 != (attributes & (int)CpiAssemblyAttributes.EventClass) && 0 != (attributes & (int)CpiAssemblyAttributes.DotNetAssembly))
1344 {
1345 this.Messaging.Write(ComPlusErrors.UnexpectedAttributeWithOtherValue(sourceLineNumbers, node.Name.LocalName, "EventClass", "yes", "Type", ".net"));
1346 }
1347
1348 foreach (var child in node.Elements())
1349 {
1350 if (this.Namespace == child.Name.Namespace)
1351 {
1352 switch (child.Name.LocalName)
1353 {
1354 case "ComPlusAssemblyDependency":
1355 this.ParseComPlusAssemblyDependencyElement(intermediate, section, child, key?.Id);
1356 break;
1357 case "ComPlusComponent":
1358 this.ParseComPlusComponentElement(intermediate, section, child, componentKey, key?.Id);
1359 hasComponents = true;
1360 break;
1361 default:
1362 this.ParseHelper.UnexpectedElement(node, child);
1363 break;
1364 }
1365 }
1366 else
1367 {
1368 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
1369 }
1370 }
1371
1372 if (0 == (attributes & (int)CpiAssemblyAttributes.DotNetAssembly) && !hasComponents)
1373 {
1374 this.Messaging.Write(ComPlusWarnings.MissingComponents(sourceLineNumbers));
1375 }
1376
1377 section.AddSymbol(new ComPlusAssemblySymbol(sourceLineNumbers, key)
1378 {
1379 ApplicationRef = applicationKey,
1380 ComponentRef = componentKey,
1381 AssemblyName = assemblyName,
1382 DllPath = dllPath,
1383 TlbPath = tlbPath,
1384 PSDllPath = psDllPath,
1385 Attributes = attributes,
1386 });
1387
1388 this.AddReferenceToConfigureComPlus(section, sourceLineNumbers, node.Name.LocalName, win64);
1389 }
1390
1391 /// <summary>
1392 /// Parses a COM+ assembly dependency element.
1393 /// </summary>
1394 /// <param name="node">Element to parse.</param>
1395 /// <param name="assemblyKey">Identifier of parent assembly.</param>
1396 private void ParseComPlusAssemblyDependencyElement(Intermediate intermediate, IntermediateSection section, XElement node, string assemblyKey)
1397 {
1398 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1399
1400 string requiredAssemblyKey = null;
1401
1402 foreach (var attrib in node.Attributes())
1403 {
1404 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1405 {
1406 switch (attrib.Name.LocalName)
1407 {
1408 case "RequiredAssembly":
1409 requiredAssemblyKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1410 break;
1411 default:
1412 this.ParseHelper.UnexpectedAttribute(node, attrib);
1413 break;
1414 }
1415 }
1416 else
1417 {
1418 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1419 }
1420 }
1421
1422 section.AddSymbol(new ComPlusAssemblyDependencySymbol(sourceLineNumbers)
1423 {
1424 AssemblyRef = assemblyKey,
1425 RequiredAssemblyRef = requiredAssemblyKey,
1426 });
1427 }
1428
1429 /// <summary>
1430 /// Parses a COM+ component element.
1431 /// </summary>
1432 /// <param name="node">Element to parse.</param>
1433 /// <param name="componentKey">Identifier of parent component.</param>
1434 /// <param name="assemblyKey">Identifier of parent assembly.</param>
1435 private void ParseComPlusComponentElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string assemblyKey)
1436 {
1437 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1438
1439 Identifier key = null;
1440 string clsid = null;
1441
1442 var properties = new Dictionary<string, string>();
1443
1444 foreach (var attrib in node.Attributes())
1445 {
1446 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1447 {
1448 switch (attrib.Name.LocalName)
1449 {
1450 case "Id":
1451 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1452 break;
1453 case "CLSID":
1454 clsid = "{" + this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib) + "}";
1455 break;
1456 case "AllowInprocSubscribers":
1457 properties["AllowInprocSubscribers"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1458 break;
1459 case "ComponentAccessChecksEnabled":
1460 properties["ComponentAccessChecksEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1461 break;
1462 case "ComponentTransactionTimeout":
1463 properties["ComponentTransactionTimeout"] = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 3600).ToString();
1464 break;
1465 case "ComponentTransactionTimeoutEnabled":
1466 properties["ComponentTransactionTimeoutEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1467 break;
1468 case "COMTIIntrinsics":
1469 properties["COMTIIntrinsics"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1470 break;
1471 case "ConstructionEnabled":
1472 properties["ConstructionEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1473 break;
1474 case "ConstructorString":
1475 properties["ConstructorString"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1476 break;
1477 case "CreationTimeout":
1478 properties["CreationTimeout"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1479 break;
1480 case "Description":
1481 properties["Description"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1482 break;
1483 case "EventTrackingEnabled":
1484 properties["EventTrackingEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1485 break;
1486 case "ExceptionClass":
1487 properties["ExceptionClass"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1488 break;
1489 case "FireInParallel":
1490 properties["FireInParallel"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1491 break;
1492 case "IISIntrinsics":
1493 properties["IISIntrinsics"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1494 break;
1495 case "InitializesServerApplication":
1496 properties["InitializesServerApplication"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1497 break;
1498 case "IsEnabled":
1499 properties["IsEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1500 break;
1501 case "IsPrivateComponent":
1502 properties["IsPrivateComponent"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1503 break;
1504 case "JustInTimeActivation":
1505 properties["JustInTimeActivation"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1506 break;
1507 case "LoadBalancingSupported":
1508 properties["LoadBalancingSupported"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1509 break;
1510 case "MaxPoolSize":
1511 properties["MaxPoolSize"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1512 break;
1513 case "MinPoolSize":
1514 properties["MinPoolSize"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1515 break;
1516 case "MultiInterfacePublisherFilterCLSID":
1517 properties["MultiInterfacePublisherFilterCLSID"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1518 break;
1519 case "MustRunInClientContext":
1520 properties["MustRunInClientContext"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1521 break;
1522 case "MustRunInDefaultContext":
1523 properties["MustRunInDefaultContext"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1524 break;
1525 case "ObjectPoolingEnabled":
1526 properties["ObjectPoolingEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1527 break;
1528 case "PublisherID":
1529 properties["PublisherID"] = this.TryFormatGuidValue(this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib));
1530 break;
1531 case "SoapAssemblyName":
1532 properties["SoapAssemblyName"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1533 break;
1534 case "SoapTypeName":
1535 properties["SoapTypeName"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1536 break;
1537 case "Synchronization":
1538 var synchronizationValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1539 switch (synchronizationValue)
1540 {
1541 case "ignored":
1542 properties["Synchronization"] = "0";
1543 break;
1544 case "none":
1545 properties["Synchronization"] = "1";
1546 break;
1547 case "supported":
1548 properties["Synchronization"] = "2";
1549 break;
1550 case "required":
1551 properties["Synchronization"] = "3";
1552 break;
1553 case "requiresNew":
1554 properties["Synchronization"] = "4";
1555 break;
1556 default:
1557 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusComponent", "Synchronization", synchronizationValue, "ignored", "none", "supported", "required", "requiresNew"));
1558 break;
1559 }
1560 break;
1561 case "Transaction":
1562 var transactionValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1563 switch (transactionValue)
1564 {
1565 case "ignored":
1566 properties["Transaction"] = "0";
1567 break;
1568 case "none":
1569 properties["Transaction"] = "1";
1570 break;
1571 case "supported":
1572 properties["Transaction"] = "2";
1573 break;
1574 case "required":
1575 properties["Transaction"] = "3";
1576 break;
1577 case "requiresNew":
1578 properties["Transaction"] = "4";
1579 break;
1580 default:
1581 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusComponent", "Transaction", transactionValue, "ignored", "none", "supported", "required", "requiresNew"));
1582 break;
1583 }
1584 break;
1585 case "TxIsolationLevel":
1586 var txIsolationLevelValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1587 switch (txIsolationLevelValue)
1588 {
1589 case "any":
1590 properties["TxIsolationLevel"] = "0";
1591 break;
1592 case "readUnCommitted":
1593 properties["TxIsolationLevel"] = "1";
1594 break;
1595 case "readCommitted":
1596 properties["TxIsolationLevel"] = "2";
1597 break;
1598 case "repeatableRead":
1599 properties["TxIsolationLevel"] = "3";
1600 break;
1601 case "serializable":
1602 properties["TxIsolationLevel"] = "4";
1603 break;
1604 default:
1605 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "ComPlusComponent", "TxIsolationLevel", txIsolationLevelValue, "any", "readUnCommitted", "readCommitted", "repeatableRead", "serializable"));
1606 break;
1607 }
1608 break;
1609 default:
1610 this.ParseHelper.UnexpectedAttribute(node, attrib);
1611 break;
1612 }
1613 }
1614 else
1615 {
1616 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1617 }
1618 }
1619
1620 foreach (var child in node.Elements())
1621 {
1622 if (this.Namespace == child.Name.Namespace)
1623 {
1624 switch (child.Name.LocalName)
1625 {
1626 case "ComPlusRoleForComponent":
1627 this.ParseComPlusRoleForComponentElement(intermediate, section, child, componentKey, key?.Id);
1628 break;
1629 case "ComPlusInterface":
1630 this.ParseComPlusInterfaceElement(intermediate, section, child, componentKey, key?.Id);
1631 break;
1632 case "ComPlusSubscription":
1633 this.ParseComPlusSubscriptionElement(intermediate, section, child, componentKey, key?.Id);
1634 break;
1635 default:
1636 this.ParseHelper.UnexpectedElement(node, child);
1637 break;
1638 }
1639 }
1640 else
1641 {
1642 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
1643 }
1644 }
1645
1646 section.AddSymbol(new ComPlusComponentSymbol(sourceLineNumbers, key)
1647 {
1648 AssemblyRef = assemblyKey,
1649 CLSID = clsid,
1650 });
1651
1652 foreach (var kvp in properties)
1653 {
1654 section.AddSymbol(new ComPlusComponentPropertySymbol(sourceLineNumbers)
1655 {
1656 ComPlusComponentRef = key?.Id,
1657 Name = kvp.Key,
1658 Value = kvp.Value,
1659 });
1660 }
1661 }
1662
1663 /// <summary>
1664 /// Parses a COM+ application role for component element.
1665 /// </summary>
1666 /// <param name="node">Element to parse.</param>
1667 /// <param name="componentKey">Identifier of parent component.</param>
1668 /// <param name="cpcomponentKey">Identifier of parent COM+ component.</param>
1669 private void ParseComPlusRoleForComponentElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string cpcomponentKey)
1670 {
1671 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1672
1673 Identifier key = null;
1674 string applicationRoleKey = null;
1675
1676 foreach (var attrib in node.Attributes())
1677 {
1678 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1679 {
1680 switch (attrib.Name.LocalName)
1681 {
1682 case "Id":
1683 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1684 break;
1685 case "Component":
1686 if (null != cpcomponentKey)
1687 {
1688 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1689 }
1690 cpcomponentKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1691 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusComponent, cpcomponentKey);
1692 break;
1693 case "ApplicationRole":
1694 applicationRoleKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1695 break;
1696 default:
1697 this.ParseHelper.UnexpectedAttribute(node, attrib);
1698 break;
1699 }
1700 }
1701 else
1702 {
1703 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1704 }
1705 }
1706
1707 if (null == cpcomponentKey)
1708 {
1709 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Component"));
1710 }
1711
1712 section.AddSymbol(new ComPlusRoleForComponentSymbol(sourceLineNumbers, key)
1713 {
1714 ComPlusComponentRef = cpcomponentKey,
1715 ApplicationRoleRef = applicationRoleKey,
1716 ComponentRef = componentKey,
1717 });
1718 }
1719
1720 /// <summary>
1721 /// Parses a COM+ interface element.
1722 /// </summary>
1723 /// <param name="node">Element to parse.</param>
1724 /// <param name="componentKey">Identifier of parent component.</param>
1725 /// <param name="cpcomponentKey">Identifier of parent COM+ component.</param>
1726 private void ParseComPlusInterfaceElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string cpcomponentKey)
1727 {
1728 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1729
1730 // parse attributes
1731 Identifier key = null;
1732 string iid = null;
1733
1734 var properties = new Dictionary<string, string>();
1735
1736 foreach (var attrib in node.Attributes())
1737 {
1738 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1739 {
1740 switch (attrib.Name.LocalName)
1741 {
1742 case "Id":
1743 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1744 break;
1745 case "IID":
1746 iid = "{" + this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib) + "}";
1747 break;
1748 case "Description":
1749 properties["Description"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1750 break;
1751 case "QueuingEnabled":
1752 properties["QueuingEnabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1753 break;
1754 default:
1755 this.ParseHelper.UnexpectedAttribute(node, attrib);
1756 break;
1757 }
1758 }
1759 else
1760 {
1761 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1762 }
1763 }
1764
1765 foreach (var child in node.Elements())
1766 {
1767 if (this.Namespace == child.Name.Namespace)
1768 {
1769 switch (child.Name.LocalName)
1770 {
1771 case "ComPlusRoleForInterface":
1772 this.ParseComPlusRoleForInterfaceElement(intermediate, section, child, componentKey, key?.Id);
1773 break;
1774 case "ComPlusMethod":
1775 this.ParseComPlusMethodElement(intermediate, section, child, componentKey, key?.Id);
1776 break;
1777 default:
1778 this.ParseHelper.UnexpectedElement(node, child);
1779 break;
1780 }
1781 }
1782 else
1783 {
1784 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
1785 }
1786 }
1787
1788 section.AddSymbol(new ComPlusInterfaceSymbol(sourceLineNumbers, key)
1789 {
1790 ComPlusComponentRef = cpcomponentKey,
1791 IID = iid,
1792 });
1793
1794 foreach (var kvp in properties)
1795 {
1796 section.AddSymbol(new ComPlusInterfacePropertySymbol(sourceLineNumbers)
1797 {
1798 InterfaceRef = key?.Id,
1799 Name = kvp.Key,
1800 Value = kvp.Value,
1801 });
1802 }
1803 }
1804
1805 /// <summary>
1806 /// Parses a COM+ application role for interface element.
1807 /// </summary>
1808 /// <param name="node">Element to parse.</param>
1809 /// <param name="componentKey">Identifier of parent component.</param>
1810 /// <param name="interfaceKey">Identifier of parent interface.</param>
1811 private void ParseComPlusRoleForInterfaceElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string interfaceKey)
1812 {
1813 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1814
1815 Identifier key = null;
1816 string applicationRoleKey = null;
1817
1818 foreach (var attrib in node.Attributes())
1819 {
1820 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1821 {
1822 switch (attrib.Name.LocalName)
1823 {
1824 case "Id":
1825 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1826 break;
1827 case "Interface":
1828 if (null != interfaceKey)
1829 {
1830 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1831 }
1832 interfaceKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1833 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusInterface, interfaceKey);
1834 break;
1835 case "ApplicationRole":
1836 applicationRoleKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1837 break;
1838 default:
1839 this.ParseHelper.UnexpectedAttribute(node, attrib);
1840 break;
1841 }
1842 }
1843 else
1844 {
1845 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1846 }
1847 }
1848
1849 if (null == interfaceKey)
1850 {
1851 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Interface"));
1852 }
1853
1854 section.AddSymbol(new ComPlusRoleForInterfaceSymbol(sourceLineNumbers, key)
1855 {
1856 InterfaceRef = interfaceKey,
1857 ApplicationRoleRef = applicationRoleKey,
1858 ComponentRef = componentKey,
1859 });
1860 }
1861
1862 /// <summary>
1863 /// Parses a COM+ method element.
1864 /// </summary>
1865 /// <param name="node">Element to parse.</param>
1866 /// <param name="componentKey">Identifier of parent component.</param>
1867 /// <param name="interfaceKey">Identifier of parent interface.</param>
1868 private void ParseComPlusMethodElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string interfaceKey)
1869 {
1870 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1871
1872 Identifier key = null;
1873 var index = CompilerConstants.IntegerNotSet;
1874 string name = null;
1875
1876 var properties = new Dictionary<string, string>();
1877
1878 foreach (var attrib in node.Attributes())
1879 {
1880 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1881 {
1882 switch (attrib.Name.LocalName)
1883 {
1884 case "Id":
1885 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1886 break;
1887 case "Index":
1888 index = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
1889 break;
1890 case "Name":
1891 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1892 break;
1893 case "AutoComplete":
1894 properties["AutoComplete"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
1895 break;
1896 case "Description":
1897 properties["Description"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1898 break;
1899 default:
1900 this.ParseHelper.UnexpectedAttribute(node, attrib);
1901 break;
1902 }
1903 }
1904 else
1905 {
1906 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1907 }
1908 }
1909
1910 foreach (var child in node.Elements())
1911 {
1912 if (this.Namespace == child.Name.Namespace)
1913 {
1914 switch (child.Name.LocalName)
1915 {
1916 case "ComPlusRoleForMethod":
1917 this.ParseComPlusRoleForMethodElement(intermediate, section, child, componentKey, key?.Id);
1918 break;
1919 default:
1920 this.ParseHelper.UnexpectedElement(node, child);
1921 break;
1922 }
1923 }
1924 else
1925 {
1926 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, node, child);
1927 }
1928 }
1929
1930 if (CompilerConstants.IntegerNotSet == index && null == name)
1931 {
1932 this.Messaging.Write(ComPlusErrors.RequiredAttribute(sourceLineNumbers, node.Name.LocalName, "Index", "Name"));
1933 }
1934
1935 var symbol = section.AddSymbol(new ComPlusMethodSymbol(sourceLineNumbers, key)
1936 {
1937 InterfaceRef = interfaceKey,
1938 Name = name,
1939 });
1940
1941 if (CompilerConstants.IntegerNotSet != index)
1942 {
1943 symbol.Index = index;
1944 }
1945
1946 foreach (var kvp in properties)
1947 {
1948 section.AddSymbol(new ComPlusMethodPropertySymbol(sourceLineNumbers)
1949 {
1950 MethodRef = key?.Id,
1951 Name = kvp.Key,
1952 Value = kvp.Value,
1953 });
1954 }
1955 }
1956
1957 /// <summary>
1958 /// Parses a COM+ application role for method element.
1959 /// </summary>
1960 /// <param name="node">Element to parse.</param>
1961 /// <param name="componentKey">Identifier of parent component.</param>
1962 /// <param name="methodKey">Identifier of parent method.</param>
1963 private void ParseComPlusRoleForMethodElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string methodKey)
1964 {
1965 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
1966
1967 Identifier key = null;
1968 string applicationRoleKey = null;
1969
1970 foreach (var attrib in node.Attributes())
1971 {
1972 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
1973 {
1974 switch (attrib.Name.LocalName)
1975 {
1976 case "Id":
1977 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
1978 break;
1979 case "Method":
1980 if (null != methodKey)
1981 {
1982 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
1983 }
1984 methodKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1985 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusMethod, methodKey);
1986 break;
1987 case "ApplicationRole":
1988 applicationRoleKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
1989 break;
1990 default:
1991 this.ParseHelper.UnexpectedAttribute(node, attrib);
1992 break;
1993 }
1994 }
1995 else
1996 {
1997 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
1998 }
1999 }
2000
2001 if (null == methodKey)
2002 {
2003 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Method"));
2004 }
2005
2006 section.AddSymbol(new ComPlusRoleForMethodSymbol(sourceLineNumbers, key)
2007 {
2008 MethodRef = methodKey,
2009 ApplicationRoleRef = applicationRoleKey,
2010 ComponentRef = componentKey,
2011 });
2012 }
2013
2014 /// <summary>
2015 /// Parses a COM+ event subscription element.
2016 /// </summary>
2017 /// <param name="node">Element to parse.</param>
2018 /// <param name="componentKey">Identifier of parent component.</param>
2019 /// <param name="cpcomponentKey">Identifier of parent COM+ component.</param>
2020 private void ParseComPlusSubscriptionElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentKey, string cpcomponentKey)
2021 {
2022 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
2023
2024 Identifier key = null;
2025 string id = null;
2026 string name = null;
2027 string eventCLSID = null;
2028 string publisherID = null;
2029
2030 var properties = new Dictionary<string, string>();
2031
2032 foreach (var attrib in node.Attributes())
2033 {
2034 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
2035 {
2036 switch (attrib.Name.LocalName)
2037 {
2038 case "Id":
2039 key = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
2040 break;
2041 case "Component":
2042 if (null != cpcomponentKey)
2043 {
2044 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
2045 }
2046 cpcomponentKey = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2047 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, ComPlusSymbolDefinitions.ComPlusComponent, cpcomponentKey);
2048 break;
2049 case "SubscriptionId":
2050 id = this.TryFormatGuidValue(this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib));
2051 break;
2052 case "Name":
2053 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2054 break;
2055 case "EventCLSID":
2056 eventCLSID = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2057 break;
2058 case "PublisherID":
2059 publisherID = this.TryFormatGuidValue(this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib));
2060 break;
2061 case "Description":
2062 properties["Description"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2063 break;
2064 case "Enabled":
2065 properties["Enabled"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
2066 break;
2067 case "EventClassPartitionID":
2068 properties["EventClassPartitionID"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2069 break;
2070 case "FilterCriteria":
2071 properties["FilterCriteria"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2072 break;
2073 case "InterfaceID":
2074 properties["InterfaceID"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2075 break;
2076 case "MachineName":
2077 properties["MachineName"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2078 break;
2079 case "MethodName":
2080 properties["MethodName"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2081 break;
2082 case "PerUser":
2083 properties["PerUser"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
2084 break;
2085 case "Queued":
2086 properties["Queued"] = YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) ? "1" : "0";
2087 break;
2088 case "SubscriberMoniker":
2089 properties["SubscriberMoniker"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2090 break;
2091 case "UserName":
2092 properties["UserName"] = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2093 break;
2094 default:
2095 this.ParseHelper.UnexpectedAttribute(node, attrib);
2096 break;
2097 }
2098 }
2099 else
2100 {
2101 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
2102 }
2103 }
2104
2105 if (null == cpcomponentKey)
2106 {
2107 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Component"));
2108 }
2109
2110 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
2111
2112 section.AddSymbol(new ComPlusSubscriptionSymbol(sourceLineNumbers, key)
2113 {
2114 Subscription = key?.Id,
2115 ComPlusComponentRef = cpcomponentKey,
2116 ComponentRef = componentKey,
2117 SubscriptionId = id,
2118 Name = name,
2119 EventCLSID = eventCLSID,
2120 PublisherID = publisherID,
2121 });
2122
2123 foreach (var kvp in properties)
2124 {
2125 section.AddSymbol(new ComPlusSubscriptionPropertySymbol(sourceLineNumbers)
2126 {
2127 SubscriptionRef = key?.Id,
2128 Name = kvp.Key,
2129 Value = kvp.Value,
2130 });
2131 }
2132 }
2133
2134 /// <summary>
2135 /// Attempts to parse the input value as a GUID, and in case the value is a valid
2136 /// GUID returnes it in the format "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}".
2137 /// </summary>
2138 /// <param name="val"></param>
2139 /// <returns></returns>
2140 private string TryFormatGuidValue(string val)
2141 {
2142 if (!Guid.TryParse(val, out var guid))
2143 {
2144 return val;
2145 }
2146 return guid.ToString("B").ToUpper();
2147 }
2148
2149 private void AddReferenceToConfigureComPlus(IntermediateSection section, SourceLineNumber sourceLineNumbers, string elementName, bool win64)
2150 {
2151 if (win64)
2152 {
2153 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "ConfigureComPlusInstall_x64");
2154 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "ConfigureComPlusUninstall_x64");
2155 }
2156 else
2157 {
2158 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "ConfigureComPlusInstall");
2159 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "ConfigureComPlusUninstall");
2160 }
2161
2162 }
2163 }
2164}