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