aboutsummaryrefslogtreecommitdiff
path: root/src/ext/DifxApp/wixext/DifxAppCompiler.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/DifxApp/wixext/DifxAppCompiler.cs')
-rw-r--r--src/ext/DifxApp/wixext/DifxAppCompiler.cs161
1 files changed, 161 insertions, 0 deletions
diff --git a/src/ext/DifxApp/wixext/DifxAppCompiler.cs b/src/ext/DifxApp/wixext/DifxAppCompiler.cs
new file mode 100644
index 00000000..e056988f
--- /dev/null
+++ b/src/ext/DifxApp/wixext/DifxAppCompiler.cs
@@ -0,0 +1,161 @@
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.DifxApp
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Xml.Linq;
8 using WixToolset.Data;
9 using WixToolset.DifxApp.Symbols;
10 using WixToolset.Extensibility;
11
12 /// <summary>
13 /// The compiler for the WiX Toolset Driver Install Frameworks for Applications Extension.
14 /// </summary>
15 public sealed class DifxAppCompiler : BaseCompilerExtension
16 {
17 private HashSet<string> components;
18
19 public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/difxapp";
20 /// <summary>
21 /// Instantiate a new DifxAppCompiler.
22 /// </summary>
23 public DifxAppCompiler()
24 {
25 this.components = new HashSet<string>();
26 }
27
28 /// <summary>
29 /// Processes an element for the Compiler.
30 /// </summary>
31 /// <param name="sourceLineNumbers">Source line number for the parent element.</param>
32 /// <param name="parentElement">Parent element of element to process.</param>
33 /// <param name="element">Element to process.</param>
34 /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param>
35 public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
36 {
37 switch (parentElement.Name.LocalName)
38 {
39 case "Component":
40 var componentId = context["ComponentId"];
41 var directoryId = context["DirectoryId"];
42 var componentWin64 = Boolean.Parse(context["Win64"]);
43
44 switch (element.Name.LocalName)
45 {
46 case "Driver":
47 this.ParseDriverElement(intermediate, section, element, componentId, componentWin64);
48 break;
49 default:
50 this.ParseHelper.UnexpectedElement(parentElement, element);
51 break;
52 }
53 break;
54 default:
55 this.ParseHelper.UnexpectedElement(parentElement, element);
56 break;
57 }
58 }
59
60 /// <summary>
61 /// Parses a Driver element.
62 /// </summary>
63 /// <param name="node">Element to parse.</param>
64 /// <param name="componentId">Identifier for parent component.</param>
65 private void ParseDriverElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentId, bool win64)
66 {
67 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
68 int attributes = 0;
69 var sequence = CompilerConstants.IntegerNotSet;
70
71 // check the number of times a Driver element has been nested under this Component element
72 if (null != componentId)
73 {
74 if (this.components.Contains(componentId))
75 {
76 this.Messaging.Write(ErrorMessages.TooManyElements(sourceLineNumbers, "Component", node.Name.LocalName, 1));
77 }
78 else
79 {
80 this.components.Add(componentId);
81 }
82 }
83
84 foreach (var attrib in node.Attributes())
85 {
86 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
87 {
88 switch (attrib.Name.LocalName)
89 {
90 case "AddRemovePrograms":
91 if (YesNoType.No == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
92 {
93 attributes |= 0x4;
94 }
95 break;
96 case "DeleteFiles":
97 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
98 {
99 attributes |= 0x10;
100 }
101 break;
102 case "ForceInstall":
103 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
104 {
105 attributes |= 0x1;
106 }
107 break;
108 case "Legacy":
109 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
110 {
111 attributes |= 0x8;
112 }
113 break;
114 case "PlugAndPlayPrompt":
115 if (YesNoType.No == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
116 {
117 attributes |= 0x2;
118 }
119 break;
120 case "Sequence":
121 sequence = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
122 break;
123 default:
124 this.ParseHelper.UnexpectedAttribute(node, attrib);
125 break;
126 }
127 }
128 else
129 {
130 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, node, attrib);
131 }
132 }
133
134 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
135
136 if (!this.Messaging.EncounteredError)
137 {
138 switch (this.Context.Platform)
139 {
140 case Platform.X86:
141 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.CustomAction, "MsiProcessDrivers");
142 break;
143 case Platform.X64:
144 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.CustomAction, "MsiProcessDrivers_x64");
145 break;
146 }
147
148 var symbol = section.AddSymbol(new MsiDriverPackagesSymbol(sourceLineNumbers)
149 {
150 ComponentRef = componentId,
151 Flags = attributes,
152 });
153
154 if (CompilerConstants.IntegerNotSet != sequence)
155 {
156 symbol.Sequence = sequence;
157 }
158 }
159 }
160 }
161}