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