diff options
Diffstat (limited to '')
-rw-r--r-- | src/WixToolset.Core/Compiler_EmbeddedUI.cs | 417 |
1 files changed, 417 insertions, 0 deletions
diff --git a/src/WixToolset.Core/Compiler_EmbeddedUI.cs b/src/WixToolset.Core/Compiler_EmbeddedUI.cs new file mode 100644 index 00000000..3245941e --- /dev/null +++ b/src/WixToolset.Core/Compiler_EmbeddedUI.cs | |||
@@ -0,0 +1,417 @@ | |||
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 | |||
3 | namespace WixToolset.Core | ||
4 | { | ||
5 | using System; | ||
6 | using System.IO; | ||
7 | using System.Xml.Linq; | ||
8 | using WixToolset.Data; | ||
9 | using WixToolset.Data.Tuples; | ||
10 | using WixToolset.Data.WindowsInstaller; | ||
11 | |||
12 | /// <summary> | ||
13 | /// Compiler of the WiX toolset. | ||
14 | /// </summary> | ||
15 | internal partial class Compiler : ICompiler | ||
16 | { | ||
17 | /// <summary> | ||
18 | /// Parses an EmbeddedChaniner element. | ||
19 | /// </summary> | ||
20 | /// <param name="node">Element to parse.</param> | ||
21 | private void ParseEmbeddedChainerElement(XElement node) | ||
22 | { | ||
23 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
24 | Identifier id = null; | ||
25 | string commandLine = null; | ||
26 | string source = null; | ||
27 | var type = 0; | ||
28 | |||
29 | foreach (var attrib in node.Attributes()) | ||
30 | { | ||
31 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace) | ||
32 | { | ||
33 | switch (attrib.Name.LocalName) | ||
34 | { | ||
35 | case "Id": | ||
36 | id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib); | ||
37 | break; | ||
38 | case "BinarySource": | ||
39 | if (null != source) | ||
40 | { | ||
41 | this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "FileSource", "PropertySource")); | ||
42 | } | ||
43 | source = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
44 | type = 0x2; | ||
45 | this.Core.CreateSimpleReference(sourceLineNumbers, "Binary", source); // add a reference to the appropriate Binary | ||
46 | break; | ||
47 | case "CommandLine": | ||
48 | commandLine = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
49 | break; | ||
50 | case "FileSource": | ||
51 | if (null != source) | ||
52 | { | ||
53 | this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinarySource", "PropertySource")); | ||
54 | } | ||
55 | source = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
56 | type = 0x12; | ||
57 | this.Core.CreateSimpleReference(sourceLineNumbers, "File", source); // add a reference to the appropriate File | ||
58 | break; | ||
59 | case "PropertySource": | ||
60 | if (null != source) | ||
61 | { | ||
62 | this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinarySource", "FileSource")); | ||
63 | } | ||
64 | source = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
65 | type = 0x32; | ||
66 | // cannot add a reference to a Property because it may be created at runtime. | ||
67 | break; | ||
68 | default: | ||
69 | this.Core.UnexpectedAttribute(node, attrib); | ||
70 | break; | ||
71 | } | ||
72 | } | ||
73 | else | ||
74 | { | ||
75 | this.Core.ParseExtensionAttribute(node, attrib); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | // Get the condition from the inner text of the element. | ||
80 | var condition = this.Core.GetConditionInnerText(node); | ||
81 | |||
82 | if (null == id) | ||
83 | { | ||
84 | id = this.Core.CreateIdentifier("mec", source, type.ToString()); | ||
85 | } | ||
86 | |||
87 | if (null == source) | ||
88 | { | ||
89 | this.Core.Write(ErrorMessages.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "BinarySource", "FileSource", "PropertySource")); | ||
90 | } | ||
91 | |||
92 | if (!this.Core.EncounteredError) | ||
93 | { | ||
94 | var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiEmbeddedChainer, id); | ||
95 | row.Set(1, condition); | ||
96 | row.Set(2, commandLine); | ||
97 | row.Set(3, source); | ||
98 | row.Set(4, type); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | /// <summary> | ||
103 | /// Parses an EmbeddedUI element. | ||
104 | /// </summary> | ||
105 | /// <param name="node">Element to parse.</param> | ||
106 | private void ParseEmbeddedUIElement(XElement node) | ||
107 | { | ||
108 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
109 | Identifier id = null; | ||
110 | string name = null; | ||
111 | var supportsBasicUI = false; | ||
112 | var messageFilter = WindowsInstallerConstants.INSTALLLOGMODE_FATALEXIT | WindowsInstallerConstants.INSTALLLOGMODE_ERROR | WindowsInstallerConstants.INSTALLLOGMODE_WARNING | WindowsInstallerConstants.INSTALLLOGMODE_USER | ||
113 | | WindowsInstallerConstants.INSTALLLOGMODE_INFO | WindowsInstallerConstants.INSTALLLOGMODE_FILESINUSE | WindowsInstallerConstants.INSTALLLOGMODE_RESOLVESOURCE | ||
114 | | WindowsInstallerConstants.INSTALLLOGMODE_OUTOFDISKSPACE | WindowsInstallerConstants.INSTALLLOGMODE_ACTIONSTART | WindowsInstallerConstants.INSTALLLOGMODE_ACTIONDATA | ||
115 | | WindowsInstallerConstants.INSTALLLOGMODE_PROGRESS | WindowsInstallerConstants.INSTALLLOGMODE_COMMONDATA | WindowsInstallerConstants.INSTALLLOGMODE_INITIALIZE | ||
116 | | WindowsInstallerConstants.INSTALLLOGMODE_TERMINATE | WindowsInstallerConstants.INSTALLLOGMODE_SHOWDIALOG | WindowsInstallerConstants.INSTALLLOGMODE_RMFILESINUSE | ||
117 | | WindowsInstallerConstants.INSTALLLOGMODE_INSTALLSTART | WindowsInstallerConstants.INSTALLLOGMODE_INSTALLEND; | ||
118 | string sourceFile = null; | ||
119 | |||
120 | foreach (var attrib in node.Attributes()) | ||
121 | { | ||
122 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace) | ||
123 | { | ||
124 | switch (attrib.Name.LocalName) | ||
125 | { | ||
126 | case "Id": | ||
127 | id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib); | ||
128 | break; | ||
129 | case "Name": | ||
130 | name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false); | ||
131 | break; | ||
132 | case "IgnoreFatalExit": | ||
133 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
134 | { | ||
135 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_FATALEXIT; | ||
136 | } | ||
137 | break; | ||
138 | case "IgnoreError": | ||
139 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
140 | { | ||
141 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_ERROR; | ||
142 | } | ||
143 | break; | ||
144 | case "IgnoreWarning": | ||
145 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
146 | { | ||
147 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_WARNING; | ||
148 | } | ||
149 | break; | ||
150 | case "IgnoreUser": | ||
151 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
152 | { | ||
153 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_USER; | ||
154 | } | ||
155 | break; | ||
156 | case "IgnoreInfo": | ||
157 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
158 | { | ||
159 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_INFO; | ||
160 | } | ||
161 | break; | ||
162 | case "IgnoreFilesInUse": | ||
163 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
164 | { | ||
165 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_FILESINUSE; | ||
166 | } | ||
167 | break; | ||
168 | case "IgnoreResolveSource": | ||
169 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
170 | { | ||
171 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_RESOLVESOURCE; | ||
172 | } | ||
173 | break; | ||
174 | case "IgnoreOutOfDiskSpace": | ||
175 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
176 | { | ||
177 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_OUTOFDISKSPACE; | ||
178 | } | ||
179 | break; | ||
180 | case "IgnoreActionStart": | ||
181 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
182 | { | ||
183 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_ACTIONSTART; | ||
184 | } | ||
185 | break; | ||
186 | case "IgnoreActionData": | ||
187 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
188 | { | ||
189 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_ACTIONDATA; | ||
190 | } | ||
191 | break; | ||
192 | case "IgnoreProgress": | ||
193 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
194 | { | ||
195 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_PROGRESS; | ||
196 | } | ||
197 | break; | ||
198 | case "IgnoreCommonData": | ||
199 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
200 | { | ||
201 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_COMMONDATA; | ||
202 | } | ||
203 | break; | ||
204 | case "IgnoreInitialize": | ||
205 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
206 | { | ||
207 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_INITIALIZE; | ||
208 | } | ||
209 | break; | ||
210 | case "IgnoreTerminate": | ||
211 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
212 | { | ||
213 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_TERMINATE; | ||
214 | } | ||
215 | break; | ||
216 | case "IgnoreShowDialog": | ||
217 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
218 | { | ||
219 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_SHOWDIALOG; | ||
220 | } | ||
221 | break; | ||
222 | case "IgnoreRMFilesInUse": | ||
223 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
224 | { | ||
225 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_RMFILESINUSE; | ||
226 | } | ||
227 | break; | ||
228 | case "IgnoreInstallStart": | ||
229 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
230 | { | ||
231 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_INSTALLSTART; | ||
232 | } | ||
233 | break; | ||
234 | case "IgnoreInstallEnd": | ||
235 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
236 | { | ||
237 | messageFilter ^= WindowsInstallerConstants.INSTALLLOGMODE_INSTALLEND; | ||
238 | } | ||
239 | break; | ||
240 | case "SourceFile": | ||
241 | sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
242 | break; | ||
243 | case "SupportBasicUI": | ||
244 | supportsBasicUI = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); | ||
245 | break; | ||
246 | default: | ||
247 | this.Core.UnexpectedAttribute(node, attrib); | ||
248 | break; | ||
249 | } | ||
250 | } | ||
251 | else | ||
252 | { | ||
253 | this.Core.ParseExtensionAttribute(node, attrib); | ||
254 | } | ||
255 | } | ||
256 | |||
257 | if (String.IsNullOrEmpty(sourceFile)) | ||
258 | { | ||
259 | this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile")); | ||
260 | } | ||
261 | else if (String.IsNullOrEmpty(name)) | ||
262 | { | ||
263 | name = Path.GetFileName(sourceFile); | ||
264 | if (!this.Core.IsValidLongFilename(name, false)) | ||
265 | { | ||
266 | this.Core.Write(ErrorMessages.IllegalLongFilename(sourceLineNumbers, node.Name.LocalName, "Source", name)); | ||
267 | } | ||
268 | } | ||
269 | |||
270 | if (null == id) | ||
271 | { | ||
272 | if (!String.IsNullOrEmpty(name)) | ||
273 | { | ||
274 | id = this.Core.CreateIdentifierFromFilename(name); | ||
275 | } | ||
276 | |||
277 | if (null == id) | ||
278 | { | ||
279 | this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); | ||
280 | } | ||
281 | else if (!Common.IsIdentifier(id.Id)) | ||
282 | { | ||
283 | this.Core.Write(ErrorMessages.IllegalIdentifier(sourceLineNumbers, node.Name.LocalName, "Id", id.Id)); | ||
284 | } | ||
285 | } | ||
286 | else if (String.IsNullOrEmpty(name)) | ||
287 | { | ||
288 | name = id.Id; | ||
289 | } | ||
290 | |||
291 | if (!name.Contains(".")) | ||
292 | { | ||
293 | this.Core.Write(ErrorMessages.InvalidEmbeddedUIFileName(sourceLineNumbers, name)); | ||
294 | } | ||
295 | |||
296 | foreach (var child in node.Elements()) | ||
297 | { | ||
298 | if (CompilerCore.WixNamespace == child.Name.Namespace) | ||
299 | { | ||
300 | switch (child.Name.LocalName) | ||
301 | { | ||
302 | case "EmbeddedUIResource": | ||
303 | this.ParseEmbeddedUIResourceElement(child); | ||
304 | break; | ||
305 | default: | ||
306 | this.Core.UnexpectedElement(node, child); | ||
307 | break; | ||
308 | } | ||
309 | } | ||
310 | else | ||
311 | { | ||
312 | this.Core.ParseExtensionElement(node, child); | ||
313 | } | ||
314 | } | ||
315 | |||
316 | if (!this.Core.EncounteredError) | ||
317 | { | ||
318 | var tuple = new MsiEmbeddedUITuple(sourceLineNumbers, id) | ||
319 | { | ||
320 | FileName = name, | ||
321 | EntryPoint = true, | ||
322 | SupportsBasicUI = supportsBasicUI, | ||
323 | MessageFilter = messageFilter, | ||
324 | Source = sourceFile | ||
325 | }; | ||
326 | |||
327 | this.Core.AddTuple(tuple); | ||
328 | } | ||
329 | } | ||
330 | |||
331 | /// <summary> | ||
332 | /// Parses a embedded UI resource element. | ||
333 | /// </summary> | ||
334 | /// <param name="node">Element to parse.</param> | ||
335 | /// <param name="parentId">Identifier of parent EmbeddedUI element.</param> | ||
336 | private void ParseEmbeddedUIResourceElement(XElement node) | ||
337 | { | ||
338 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
339 | Identifier id = null; | ||
340 | string name = null; | ||
341 | string sourceFile = null; | ||
342 | |||
343 | foreach (var attrib in node.Attributes()) | ||
344 | { | ||
345 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace) | ||
346 | { | ||
347 | switch (attrib.Name.LocalName) | ||
348 | { | ||
349 | case "Id": | ||
350 | id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib); | ||
351 | break; | ||
352 | case "Name": | ||
353 | name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false); | ||
354 | break; | ||
355 | case "SourceFile": | ||
356 | sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
357 | break; | ||
358 | default: | ||
359 | this.Core.UnexpectedAttribute(node, attrib); | ||
360 | break; | ||
361 | } | ||
362 | } | ||
363 | else | ||
364 | { | ||
365 | this.Core.ParseExtensionAttribute(node, attrib); | ||
366 | } | ||
367 | } | ||
368 | |||
369 | if (String.IsNullOrEmpty(sourceFile)) | ||
370 | { | ||
371 | this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile")); | ||
372 | } | ||
373 | else if (String.IsNullOrEmpty(name)) | ||
374 | { | ||
375 | name = Path.GetFileName(sourceFile); | ||
376 | if (!this.Core.IsValidLongFilename(name, false)) | ||
377 | { | ||
378 | this.Core.Write(ErrorMessages.IllegalLongFilename(sourceLineNumbers, node.Name.LocalName, "Source", name)); | ||
379 | } | ||
380 | } | ||
381 | |||
382 | if (null == id) | ||
383 | { | ||
384 | if (!String.IsNullOrEmpty(name)) | ||
385 | { | ||
386 | id = this.Core.CreateIdentifierFromFilename(name); | ||
387 | } | ||
388 | |||
389 | if (null == id) | ||
390 | { | ||
391 | this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); | ||
392 | } | ||
393 | else if (!Common.IsIdentifier(id.Id)) | ||
394 | { | ||
395 | this.Core.Write(ErrorMessages.IllegalIdentifier(sourceLineNumbers, node.Name.LocalName, "Id", id.Id)); | ||
396 | } | ||
397 | } | ||
398 | else if (String.IsNullOrEmpty(name)) | ||
399 | { | ||
400 | name = id.Id; | ||
401 | } | ||
402 | |||
403 | this.Core.ParseForExtensionElements(node); | ||
404 | |||
405 | if (!this.Core.EncounteredError) | ||
406 | { | ||
407 | var tuple = new MsiEmbeddedUITuple(sourceLineNumbers, id) | ||
408 | { | ||
409 | FileName = name, | ||
410 | Source = sourceFile | ||
411 | }; | ||
412 | |||
413 | this.Core.AddTuple(tuple); | ||
414 | } | ||
415 | } | ||
416 | } | ||
417 | } | ||