aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core/Compiler_EmbeddedUI.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core/Compiler_EmbeddedUI.cs')
-rw-r--r--src/WixToolset.Core/Compiler_EmbeddedUI.cs417
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
3namespace 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}