diff options
Diffstat (limited to '')
-rw-r--r-- | src/wixext/IIsCompiler.cs | 2563 |
1 files changed, 2563 insertions, 0 deletions
diff --git a/src/wixext/IIsCompiler.cs b/src/wixext/IIsCompiler.cs new file mode 100644 index 00000000..828d430b --- /dev/null +++ b/src/wixext/IIsCompiler.cs | |||
@@ -0,0 +1,2563 @@ | |||
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.Extensions | ||
4 | { | ||
5 | using System; | ||
6 | using System.Collections.Generic; | ||
7 | using System.Globalization; | ||
8 | using System.Xml.Linq; | ||
9 | using WixToolset.Data; | ||
10 | using WixToolset.Extensibility; | ||
11 | |||
12 | /// <summary> | ||
13 | /// The compiler for the WiX Toolset Internet Information Services Extension. | ||
14 | /// </summary> | ||
15 | public sealed class IIsCompiler : CompilerExtension | ||
16 | { | ||
17 | /// <summary> | ||
18 | /// Instantiate a new IIsCompiler. | ||
19 | /// </summary> | ||
20 | public IIsCompiler() | ||
21 | { | ||
22 | this.Namespace = "http://wixtoolset.org/schemas/v4/wxs/iis"; | ||
23 | } | ||
24 | |||
25 | /// <summary> | ||
26 | /// Types of objects that custom HTTP Headers can be applied to. | ||
27 | /// </summary> | ||
28 | /// <remarks>Note that this must be kept in sync with the eHttpHeaderParentType in scahttpheader.h.</remarks> | ||
29 | private enum HttpHeaderParentType | ||
30 | { | ||
31 | /// <summary>Custom HTTP Header is to be applied to a Web Virtual Directory.</summary> | ||
32 | WebVirtualDir = 1, | ||
33 | /// <summary>Custom HTTP Header is to be applied to a Web Site.</summary> | ||
34 | WebSite = 2, | ||
35 | } | ||
36 | |||
37 | /// <summary> | ||
38 | /// Types of objects that MimeMaps can be applied to. | ||
39 | /// </summary> | ||
40 | /// <remarks>Note that this must be kept in sync with the eMimeMapParentType in scamimemap.h.</remarks> | ||
41 | private enum MimeMapParentType | ||
42 | { | ||
43 | /// <summary>MimeMap is to be applied to a Web Virtual Directory.</summary> | ||
44 | WebVirtualDir = 1, | ||
45 | WebSite = 2, | ||
46 | } | ||
47 | |||
48 | /// <summary> | ||
49 | /// Types of objects that custom WebErrors can be applied to. | ||
50 | /// </summary> | ||
51 | /// <remarks>Note that this must be kept in sync with the eWebErrorParentType in scaweberror.h.</remarks> | ||
52 | private enum WebErrorParentType | ||
53 | { | ||
54 | /// <summary>Custom WebError is to be applied to a Web Virtual Directory.</summary> | ||
55 | WebVirtualDir = 1, | ||
56 | |||
57 | /// <summary>Custom WebError is to be applied to a Web Site.</summary> | ||
58 | WebSite = 2, | ||
59 | } | ||
60 | |||
61 | /// <summary> | ||
62 | /// Processes an element for the Compiler. | ||
63 | /// </summary> | ||
64 | /// <param name="sourceLineNumbers">Source line number for the parent element.</param> | ||
65 | /// <param name="parentElement">Parent element of element to process.</param> | ||
66 | /// <param name="element">Element to process.</param> | ||
67 | /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param> | ||
68 | public override void ParseElement(XElement parentElement, XElement element, IDictionary<string, string> context) | ||
69 | { | ||
70 | switch (parentElement.Name.LocalName) | ||
71 | { | ||
72 | case "Component": | ||
73 | string componentId = context["ComponentId"]; | ||
74 | string directoryId = context["DirectoryId"]; | ||
75 | |||
76 | switch (element.Name.LocalName) | ||
77 | { | ||
78 | case "Certificate": | ||
79 | this.ParseCertificateElement(element, componentId); | ||
80 | break; | ||
81 | case "WebAppPool": | ||
82 | this.ParseWebAppPoolElement(element, componentId); | ||
83 | break; | ||
84 | case "WebDir": | ||
85 | this.ParseWebDirElement(element, componentId, null); | ||
86 | break; | ||
87 | case "WebFilter": | ||
88 | this.ParseWebFilterElement(element, componentId, null); | ||
89 | break; | ||
90 | case "WebProperty": | ||
91 | this.ParseWebPropertyElement(element, componentId); | ||
92 | break; | ||
93 | case "WebServiceExtension": | ||
94 | this.ParseWebServiceExtensionElement(element, componentId); | ||
95 | break; | ||
96 | case "WebSite": | ||
97 | this.ParseWebSiteElement(element, componentId); | ||
98 | break; | ||
99 | case "WebVirtualDir": | ||
100 | this.ParseWebVirtualDirElement(element, componentId, null, null); | ||
101 | break; | ||
102 | default: | ||
103 | this.Core.UnexpectedElement(parentElement, element); | ||
104 | break; | ||
105 | } | ||
106 | break; | ||
107 | case "Fragment": | ||
108 | case "Module": | ||
109 | case "Product": | ||
110 | switch (element.Name.LocalName) | ||
111 | { | ||
112 | case "WebApplication": | ||
113 | this.ParseWebApplicationElement(element); | ||
114 | break; | ||
115 | case "WebAppPool": | ||
116 | this.ParseWebAppPoolElement(element, null); | ||
117 | break; | ||
118 | case "WebDirProperties": | ||
119 | this.ParseWebDirPropertiesElement(element); | ||
120 | break; | ||
121 | case "WebLog": | ||
122 | this.ParseWebLogElement(element); | ||
123 | break; | ||
124 | case "WebSite": | ||
125 | this.ParseWebSiteElement(element, null); | ||
126 | break; | ||
127 | default: | ||
128 | this.Core.UnexpectedElement(parentElement, element); | ||
129 | break; | ||
130 | } | ||
131 | break; | ||
132 | default: | ||
133 | this.Core.UnexpectedElement(parentElement, element); | ||
134 | break; | ||
135 | } | ||
136 | } | ||
137 | |||
138 | /// <summary> | ||
139 | /// Parses a certificate element. | ||
140 | /// </summary> | ||
141 | /// <param name="node">Element to parse.</param> | ||
142 | /// <param name="componentId">Identifier for parent component.</param> | ||
143 | private void ParseCertificateElement(XElement node, string componentId) | ||
144 | { | ||
145 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
146 | string id = null; | ||
147 | int attributes = 0; | ||
148 | string binaryKey = null; | ||
149 | string certificatePath = null; | ||
150 | string name = null; | ||
151 | string pfxPassword = null; | ||
152 | int storeLocation = 0; | ||
153 | string storeName = null; | ||
154 | |||
155 | foreach (XAttribute attrib in node.Attributes()) | ||
156 | { | ||
157 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
158 | { | ||
159 | switch (attrib.Name.LocalName) | ||
160 | { | ||
161 | case "Id": | ||
162 | id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
163 | break; | ||
164 | case "BinaryKey": | ||
165 | attributes |= 2; // SCA_CERT_ATTRIBUTE_BINARYDATA | ||
166 | binaryKey = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
167 | this.Core.CreateSimpleReference(sourceLineNumbers, "Binary", binaryKey); | ||
168 | break; | ||
169 | case "CertificatePath": | ||
170 | certificatePath = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
171 | break; | ||
172 | case "Name": | ||
173 | name = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
174 | break; | ||
175 | case "Overwrite": | ||
176 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
177 | { | ||
178 | attributes |= 4; // SCA_CERT_ATTRIBUTE_OVERWRITE | ||
179 | } | ||
180 | else | ||
181 | { | ||
182 | attributes &= ~4; // SCA_CERT_ATTRIBUTE_OVERWRITE | ||
183 | } | ||
184 | break; | ||
185 | case "PFXPassword": | ||
186 | pfxPassword = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
187 | break; | ||
188 | case "Request": | ||
189 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
190 | { | ||
191 | attributes |= 1; // SCA_CERT_ATTRIBUTE_REQUEST | ||
192 | } | ||
193 | else | ||
194 | { | ||
195 | attributes &= ~1; // SCA_CERT_ATTRIBUTE_REQUEST | ||
196 | } | ||
197 | break; | ||
198 | case "StoreLocation": | ||
199 | string storeLocationValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
200 | if (0 < storeLocationValue.Length) | ||
201 | { | ||
202 | switch (storeLocationValue) | ||
203 | { | ||
204 | case "currentUser": | ||
205 | storeLocation = 1; // SCA_CERTSYSTEMSTORE_CURRENTUSER | ||
206 | break; | ||
207 | case "localMachine": | ||
208 | storeLocation = 2; // SCA_CERTSYSTEMSTORE_LOCALMACHINE | ||
209 | break; | ||
210 | default: | ||
211 | storeLocation = -1; | ||
212 | this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "StoreLocation", storeLocationValue, "currentUser", "localMachine")); | ||
213 | break; | ||
214 | } | ||
215 | } | ||
216 | break; | ||
217 | case "StoreName": | ||
218 | string storeNameValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
219 | if (0 < storeNameValue.Length) | ||
220 | { | ||
221 | switch (storeNameValue) | ||
222 | { | ||
223 | case "ca": | ||
224 | storeName = "CA"; | ||
225 | break; | ||
226 | case "my": | ||
227 | case "personal": | ||
228 | storeName = "MY"; | ||
229 | break; | ||
230 | case "request": | ||
231 | storeName = "REQUEST"; | ||
232 | break; | ||
233 | case "root": | ||
234 | storeName = "Root"; | ||
235 | break; | ||
236 | case "otherPeople": | ||
237 | storeName = "AddressBook"; | ||
238 | break; | ||
239 | case "trustedPeople": | ||
240 | storeName = "TrustedPeople"; | ||
241 | break; | ||
242 | case "trustedPublisher": | ||
243 | storeName = "TrustedPublisher"; | ||
244 | break; | ||
245 | default: | ||
246 | this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "StoreName", storeNameValue, "ca", "my", "request", "root", "otherPeople", "trustedPeople", "trustedPublisher")); | ||
247 | break; | ||
248 | } | ||
249 | } | ||
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 | |||
263 | if (null == id) | ||
264 | { | ||
265 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); | ||
266 | } | ||
267 | |||
268 | if (null == name) | ||
269 | { | ||
270 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); | ||
271 | } | ||
272 | |||
273 | if (0 == storeLocation) | ||
274 | { | ||
275 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "StoreLocation")); | ||
276 | } | ||
277 | |||
278 | if (null == storeName) | ||
279 | { | ||
280 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "StoreName")); | ||
281 | } | ||
282 | |||
283 | if (null != binaryKey && null != certificatePath) | ||
284 | { | ||
285 | this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "BinaryKey", "CertificatePath", certificatePath)); | ||
286 | } | ||
287 | else if (null == binaryKey && null == certificatePath) | ||
288 | { | ||
289 | this.Core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "BinaryKey", "CertificatePath")); | ||
290 | } | ||
291 | |||
292 | this.Core.ParseForExtensionElements(node); | ||
293 | |||
294 | // Reference InstallCertificates and UninstallCertificates since nothing will happen without them | ||
295 | this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "InstallCertificates"); | ||
296 | this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "UninstallCertificates"); | ||
297 | this.Core.EnsureTable(sourceLineNumbers, "CertificateHash"); // Certificate CustomActions require the CertificateHash table | ||
298 | |||
299 | if (!this.Core.EncounteredError) | ||
300 | { | ||
301 | Row row = this.Core.CreateRow(sourceLineNumbers, "Certificate"); | ||
302 | row[0] = id; | ||
303 | row[1] = componentId; | ||
304 | row[2] = name; | ||
305 | row[3] = storeLocation; | ||
306 | row[4] = storeName; | ||
307 | row[5] = attributes; | ||
308 | row[6] = binaryKey; | ||
309 | row[7] = certificatePath; | ||
310 | row[8] = pfxPassword; | ||
311 | } | ||
312 | } | ||
313 | |||
314 | /// <summary> | ||
315 | /// Parses a CertificateRef extension element. | ||
316 | /// </summary> | ||
317 | /// <param name="node">Element to parse.</param> | ||
318 | /// <param name="webId">Identifier for parent web site.</param> | ||
319 | private void ParseCertificateRefElement(XElement node, string webId) | ||
320 | { | ||
321 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
322 | string id = null; | ||
323 | |||
324 | foreach (XAttribute attrib in node.Attributes()) | ||
325 | { | ||
326 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
327 | { | ||
328 | switch (attrib.Name.LocalName) | ||
329 | { | ||
330 | case "Id": | ||
331 | id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
332 | this.Core.CreateSimpleReference(sourceLineNumbers, "Certificate", id); | ||
333 | break; | ||
334 | default: | ||
335 | this.Core.UnexpectedAttribute(node, attrib); | ||
336 | break; | ||
337 | } | ||
338 | } | ||
339 | else | ||
340 | { | ||
341 | this.Core.ParseExtensionAttribute(node, attrib); | ||
342 | } | ||
343 | } | ||
344 | |||
345 | if (null == id) | ||
346 | { | ||
347 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); | ||
348 | } | ||
349 | |||
350 | this.Core.ParseForExtensionElements(node); | ||
351 | |||
352 | if (!this.Core.EncounteredError) | ||
353 | { | ||
354 | this.Core.CreateSimpleReference(sourceLineNumbers, "Certificate", id); | ||
355 | |||
356 | Row row = this.Core.CreateRow(sourceLineNumbers, "IIsWebSiteCertificates"); | ||
357 | row[0] = webId; | ||
358 | row[1] = id; | ||
359 | } | ||
360 | } | ||
361 | |||
362 | /// <summary> | ||
363 | /// Parses a mime map element. | ||
364 | /// </summary> | ||
365 | /// <param name="node">Element to parse.</param> | ||
366 | /// <param name="parentId">Identifier for parent symbol.</param> | ||
367 | /// <param name="parentType">Type that parentId refers to.</param> | ||
368 | private void ParseMimeMapElement(XElement node, string parentId, MimeMapParentType parentType) | ||
369 | { | ||
370 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
371 | string id = null; | ||
372 | string extension = null; | ||
373 | string type = null; | ||
374 | |||
375 | foreach (XAttribute attrib in node.Attributes()) | ||
376 | { | ||
377 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
378 | { | ||
379 | switch (attrib.Name.LocalName) | ||
380 | { | ||
381 | case "Id": | ||
382 | id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
383 | break; | ||
384 | case "Extension": | ||
385 | extension = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
386 | break; | ||
387 | case "Type": | ||
388 | type = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
389 | break; | ||
390 | default: | ||
391 | this.Core.UnexpectedAttribute(node, attrib); | ||
392 | break; | ||
393 | } | ||
394 | } | ||
395 | else | ||
396 | { | ||
397 | this.Core.ParseExtensionAttribute(node, attrib); | ||
398 | } | ||
399 | } | ||
400 | |||
401 | if (null == id) | ||
402 | { | ||
403 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); | ||
404 | } | ||
405 | |||
406 | if (null == extension) | ||
407 | { | ||
408 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Extension")); | ||
409 | } | ||
410 | else if (0 < extension.Length) | ||
411 | { | ||
412 | if (!extension.StartsWith(".", StringComparison.Ordinal)) | ||
413 | { | ||
414 | this.Core.OnMessage(IIsErrors.MimeMapExtensionMissingPeriod(sourceLineNumbers, node.Name.LocalName, "Extension", extension)); | ||
415 | } | ||
416 | } | ||
417 | |||
418 | if (null == type) | ||
419 | { | ||
420 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Type")); | ||
421 | } | ||
422 | |||
423 | this.Core.ParseForExtensionElements(node); | ||
424 | |||
425 | if (!this.Core.EncounteredError) | ||
426 | { | ||
427 | Row row = this.Core.CreateRow(sourceLineNumbers, "IIsMimeMap"); | ||
428 | row[0] = id; | ||
429 | row[1] = (int)parentType; | ||
430 | row[2] = parentId; | ||
431 | row[3] = type; | ||
432 | row[4] = extension; | ||
433 | } | ||
434 | } | ||
435 | |||
436 | /// <summary> | ||
437 | /// Parses a recycle time element. | ||
438 | /// </summary> | ||
439 | /// <param name="node">Element to parse.</param> | ||
440 | /// <returns>Recycle time value.</returns> | ||
441 | private string ParseRecycleTimeElement(XElement node) | ||
442 | { | ||
443 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
444 | string value = null; | ||
445 | |||
446 | foreach (XAttribute attrib in node.Attributes()) | ||
447 | { | ||
448 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
449 | { | ||
450 | switch (attrib.Name.LocalName) | ||
451 | { | ||
452 | case "Value": | ||
453 | value = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
454 | break; | ||
455 | default: | ||
456 | this.Core.UnexpectedAttribute(node, attrib); | ||
457 | break; | ||
458 | } | ||
459 | } | ||
460 | else | ||
461 | { | ||
462 | this.Core.ParseExtensionAttribute(node, attrib); | ||
463 | } | ||
464 | } | ||
465 | |||
466 | if (null == value) | ||
467 | { | ||
468 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value")); | ||
469 | } | ||
470 | |||
471 | this.Core.ParseForExtensionElements(node); | ||
472 | |||
473 | return value; | ||
474 | } | ||
475 | |||
476 | /// <summary> | ||
477 | /// Parses a web address element. | ||
478 | /// </summary> | ||
479 | /// <param name="node">Element to parse.</param> | ||
480 | /// <param name="parentWeb">Identifier of parent web site.</param> | ||
481 | /// <returns>Identifier for web address.</returns> | ||
482 | private string ParseWebAddressElement(XElement node, string parentWeb) | ||
483 | { | ||
484 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
485 | string id = null; | ||
486 | string header = null; | ||
487 | string ip = null; | ||
488 | string port = null; | ||
489 | bool secure = false; | ||
490 | |||
491 | foreach (XAttribute attrib in node.Attributes()) | ||
492 | { | ||
493 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
494 | { | ||
495 | switch (attrib.Name.LocalName) | ||
496 | { | ||
497 | case "Id": | ||
498 | id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
499 | break; | ||
500 | case "Header": | ||
501 | header = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
502 | break; | ||
503 | case "IP": | ||
504 | ip = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
505 | break; | ||
506 | case "Port": | ||
507 | port = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
508 | break; | ||
509 | case "Secure": | ||
510 | secure = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); | ||
511 | break; | ||
512 | default: | ||
513 | this.Core.UnexpectedAttribute(node, attrib); | ||
514 | break; | ||
515 | } | ||
516 | } | ||
517 | else | ||
518 | { | ||
519 | this.Core.ParseExtensionAttribute(node, attrib); | ||
520 | } | ||
521 | } | ||
522 | |||
523 | if (null == id) | ||
524 | { | ||
525 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); | ||
526 | } | ||
527 | |||
528 | if (null == port) | ||
529 | { | ||
530 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Port")); | ||
531 | } | ||
532 | |||
533 | this.Core.ParseForExtensionElements(node); | ||
534 | |||
535 | if (!this.Core.EncounteredError) | ||
536 | { | ||
537 | Row row = this.Core.CreateRow(sourceLineNumbers, "IIsWebAddress"); | ||
538 | row[0] = id; | ||
539 | row[1] = parentWeb; | ||
540 | row[2] = ip; | ||
541 | row[3] = port; | ||
542 | row[4] = header; | ||
543 | row[5] = secure ? 1 : 0; | ||
544 | } | ||
545 | |||
546 | return id; | ||
547 | } | ||
548 | |||
549 | /// <summary> | ||
550 | /// Parses a web application element. | ||
551 | /// </summary> | ||
552 | /// <param name="node">Element to parse.</param> | ||
553 | /// <returns>Identifier for web application.</returns> | ||
554 | private string ParseWebApplicationElement(XElement node) | ||
555 | { | ||
556 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
557 | string id = null; | ||
558 | YesNoDefaultType allowSessions = YesNoDefaultType.Default; | ||
559 | string appPool = null; | ||
560 | YesNoDefaultType buffer = YesNoDefaultType.Default; | ||
561 | YesNoDefaultType clientDebugging = YesNoDefaultType.Default; | ||
562 | string defaultScript = null; | ||
563 | int isolation = 0; | ||
564 | string name = null; | ||
565 | YesNoDefaultType parentPaths = YesNoDefaultType.Default; | ||
566 | int scriptTimeout = CompilerConstants.IntegerNotSet; | ||
567 | int sessionTimeout = CompilerConstants.IntegerNotSet; | ||
568 | YesNoDefaultType serverDebugging = YesNoDefaultType.Default; | ||
569 | |||
570 | foreach (XAttribute attrib in node.Attributes()) | ||
571 | { | ||
572 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
573 | { | ||
574 | switch (attrib.Name.LocalName) | ||
575 | { | ||
576 | case "Id": | ||
577 | id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
578 | break; | ||
579 | case "AllowSessions": | ||
580 | allowSessions = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); | ||
581 | break; | ||
582 | case "Buffer": | ||
583 | buffer = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); | ||
584 | break; | ||
585 | case "ClientDebugging": | ||
586 | clientDebugging = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); | ||
587 | break; | ||
588 | case "DefaultScript": | ||
589 | defaultScript = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
590 | if (0 < defaultScript.Length) | ||
591 | { | ||
592 | switch (defaultScript) | ||
593 | { | ||
594 | case "JScript": | ||
595 | case "VBScript": | ||
596 | // these are valid values | ||
597 | break; | ||
598 | default: | ||
599 | this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, defaultScript, "JScript", "VBScript")); | ||
600 | break; | ||
601 | } | ||
602 | } | ||
603 | break; | ||
604 | case "Isolation": | ||
605 | string isolationValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
606 | if (0 < isolationValue.Length) | ||
607 | { | ||
608 | switch (isolationValue) | ||
609 | { | ||
610 | case "low": | ||
611 | isolation = 0; | ||
612 | break; | ||
613 | case "medium": | ||
614 | isolation = 2; | ||
615 | break; | ||
616 | case "high": | ||
617 | isolation = 1; | ||
618 | break; | ||
619 | default: | ||
620 | this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, isolationValue, "low", "medium", "high")); | ||
621 | break; | ||
622 | } | ||
623 | } | ||
624 | break; | ||
625 | case "Name": | ||
626 | name = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
627 | break; | ||
628 | case "ParentPaths": | ||
629 | parentPaths = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); | ||
630 | break; | ||
631 | case "ScriptTimeout": | ||
632 | scriptTimeout = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); | ||
633 | break; | ||
634 | case "ServerDebugging": | ||
635 | serverDebugging = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); | ||
636 | break; | ||
637 | case "SessionTimeout": | ||
638 | sessionTimeout = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); | ||
639 | break; | ||
640 | case "WebAppPool": | ||
641 | appPool = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
642 | this.Core.CreateSimpleReference(sourceLineNumbers, "IIsAppPool", appPool); | ||
643 | break; | ||
644 | default: | ||
645 | this.Core.UnexpectedAttribute(node, attrib); | ||
646 | break; | ||
647 | } | ||
648 | } | ||
649 | else | ||
650 | { | ||
651 | this.Core.ParseExtensionAttribute(node, attrib); | ||
652 | } | ||
653 | } | ||
654 | |||
655 | if (null == id) | ||
656 | { | ||
657 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); | ||
658 | } | ||
659 | |||
660 | if (null == name) | ||
661 | { | ||
662 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); | ||
663 | } | ||
664 | else if (-1 != name.IndexOf("\\", StringComparison.Ordinal)) | ||
665 | { | ||
666 | this.Core.OnMessage(IIsErrors.IllegalCharacterInAttributeValue(sourceLineNumbers, node.Name.LocalName, "Name", name, '\\')); | ||
667 | } | ||
668 | |||
669 | foreach (XElement child in node.Elements()) | ||
670 | { | ||
671 | if (this.Namespace == child.Name.Namespace) | ||
672 | { | ||
673 | SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); | ||
674 | switch (child.Name.LocalName) | ||
675 | { | ||
676 | case "WebApplicationExtension": | ||
677 | this.ParseWebApplicationExtensionElement(child, id); | ||
678 | break; | ||
679 | default: | ||
680 | this.Core.UnexpectedElement(node, child); | ||
681 | break; | ||
682 | } | ||
683 | } | ||
684 | else | ||
685 | { | ||
686 | this.Core.ParseExtensionElement(node, child); | ||
687 | } | ||
688 | } | ||
689 | |||
690 | if (!this.Core.EncounteredError) | ||
691 | { | ||
692 | Row row = this.Core.CreateRow(sourceLineNumbers, "IIsWebApplication"); | ||
693 | row[0] = id; | ||
694 | row[1] = name; | ||
695 | row[2] = isolation; | ||
696 | if (YesNoDefaultType.Default != allowSessions) | ||
697 | { | ||
698 | row[3] = YesNoDefaultType.Yes == allowSessions ? 1 : 0; | ||
699 | } | ||
700 | |||
701 | if (CompilerConstants.IntegerNotSet != sessionTimeout) | ||
702 | { | ||
703 | row[4] = sessionTimeout; | ||
704 | } | ||
705 | |||
706 | if (YesNoDefaultType.Default != buffer) | ||
707 | { | ||
708 | row[5] = YesNoDefaultType.Yes == buffer ? 1 : 0; | ||
709 | } | ||
710 | |||
711 | if (YesNoDefaultType.Default != parentPaths) | ||
712 | { | ||
713 | row[6] = YesNoDefaultType.Yes == parentPaths ? 1 : 0; | ||
714 | } | ||
715 | row[7] = defaultScript; | ||
716 | if (CompilerConstants.IntegerNotSet != scriptTimeout) | ||
717 | { | ||
718 | row[8] = scriptTimeout; | ||
719 | } | ||
720 | |||
721 | if (YesNoDefaultType.Default != serverDebugging) | ||
722 | { | ||
723 | row[9] = YesNoDefaultType.Yes == serverDebugging ? 1 : 0; | ||
724 | } | ||
725 | |||
726 | if (YesNoDefaultType.Default != clientDebugging) | ||
727 | { | ||
728 | row[10] = YesNoDefaultType.Yes == clientDebugging ? 1 : 0; | ||
729 | } | ||
730 | row[11] = appPool; | ||
731 | } | ||
732 | |||
733 | return id; | ||
734 | } | ||
735 | |||
736 | /// <summary> | ||
737 | /// Parses a web application extension element. | ||
738 | /// </summary> | ||
739 | /// <param name="node">Element to parse.</param> | ||
740 | /// <param name="application">Identifier for parent web application.</param> | ||
741 | private void ParseWebApplicationExtensionElement(XElement node, string application) | ||
742 | { | ||
743 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
744 | int attributes = 0; | ||
745 | string executable = null; | ||
746 | string extension = null; | ||
747 | string verbs = null; | ||
748 | |||
749 | foreach (XAttribute attrib in node.Attributes()) | ||
750 | { | ||
751 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
752 | { | ||
753 | switch (attrib.Name.LocalName) | ||
754 | { | ||
755 | case "CheckPath": | ||
756 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
757 | { | ||
758 | attributes |= 4; | ||
759 | } | ||
760 | else | ||
761 | { | ||
762 | attributes &= ~4; | ||
763 | } | ||
764 | break; | ||
765 | case "Executable": | ||
766 | executable = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
767 | break; | ||
768 | case "Extension": | ||
769 | extension = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
770 | break; | ||
771 | case "Script": | ||
772 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
773 | { | ||
774 | attributes |= 1; | ||
775 | } | ||
776 | else | ||
777 | { | ||
778 | attributes &= ~1; | ||
779 | } | ||
780 | break; | ||
781 | case "Verbs": | ||
782 | verbs = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
783 | break; | ||
784 | default: | ||
785 | this.Core.UnexpectedAttribute(node, attrib); | ||
786 | break; | ||
787 | } | ||
788 | } | ||
789 | else | ||
790 | { | ||
791 | this.Core.ParseExtensionAttribute(node, attrib); | ||
792 | } | ||
793 | } | ||
794 | |||
795 | this.Core.ParseForExtensionElements(node); | ||
796 | |||
797 | if (!this.Core.EncounteredError) | ||
798 | { | ||
799 | Row row = this.Core.CreateRow(sourceLineNumbers, "IIsWebApplicationExtension"); | ||
800 | row[0] = application; | ||
801 | row[1] = extension; | ||
802 | row[2] = verbs; | ||
803 | row[3] = executable; | ||
804 | if (0 < attributes) | ||
805 | { | ||
806 | row[4] = attributes; | ||
807 | } | ||
808 | } | ||
809 | } | ||
810 | |||
811 | /// <summary> | ||
812 | /// Parses web application pool element. | ||
813 | /// </summary> | ||
814 | /// <param name="node">Element to parse.</param> | ||
815 | /// <param name="componentId">Optional identifier of parent component.</param> | ||
816 | private void ParseWebAppPoolElement(XElement node, string componentId) | ||
817 | { | ||
818 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
819 | string id = null; | ||
820 | int attributes = 0; | ||
821 | int cpuAction = CompilerConstants.IntegerNotSet; | ||
822 | string cpuMon = null; | ||
823 | int idleTimeout = CompilerConstants.IntegerNotSet; | ||
824 | int maxCpuUsage = 0; | ||
825 | int maxWorkerProcs = CompilerConstants.IntegerNotSet; | ||
826 | string managedRuntimeVersion = null; | ||
827 | string managedPipelineMode = null; | ||
828 | string name = null; | ||
829 | int privateMemory = CompilerConstants.IntegerNotSet; | ||
830 | int queueLimit = CompilerConstants.IntegerNotSet; | ||
831 | int recycleMinutes = CompilerConstants.IntegerNotSet; | ||
832 | int recycleRequests = CompilerConstants.IntegerNotSet; | ||
833 | string recycleTimes = null; | ||
834 | int refreshCpu = CompilerConstants.IntegerNotSet; | ||
835 | string user = null; | ||
836 | int virtualMemory = CompilerConstants.IntegerNotSet; | ||
837 | |||
838 | foreach (XAttribute attrib in node.Attributes()) | ||
839 | { | ||
840 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
841 | { | ||
842 | switch (attrib.Name.LocalName) | ||
843 | { | ||
844 | case "Id": | ||
845 | id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
846 | break; | ||
847 | case "CpuAction": | ||
848 | if (null == componentId) | ||
849 | { | ||
850 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
851 | } | ||
852 | |||
853 | string cpuActionValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
854 | if (0 < cpuActionValue.Length) | ||
855 | { | ||
856 | switch (cpuActionValue) | ||
857 | { | ||
858 | case "shutdown": | ||
859 | cpuAction = 1; | ||
860 | break; | ||
861 | case "none": | ||
862 | cpuAction = 0; | ||
863 | break; | ||
864 | default: | ||
865 | this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, cpuActionValue, "shutdown", "none")); | ||
866 | break; | ||
867 | } | ||
868 | } | ||
869 | break; | ||
870 | case "Identity": | ||
871 | if (null == componentId) | ||
872 | { | ||
873 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
874 | } | ||
875 | |||
876 | string identityValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
877 | if (0 < identityValue.Length) | ||
878 | { | ||
879 | switch (identityValue) | ||
880 | { | ||
881 | case "networkService": | ||
882 | attributes |= 1; | ||
883 | break; | ||
884 | case "localService": | ||
885 | attributes |= 2; | ||
886 | break; | ||
887 | case "localSystem": | ||
888 | attributes |= 4; | ||
889 | break; | ||
890 | case "other": | ||
891 | attributes |= 8; | ||
892 | break; | ||
893 | case "applicationPoolIdentity": | ||
894 | attributes |= 0x10; | ||
895 | break; | ||
896 | default: | ||
897 | this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, identityValue, "networkService", "localService", "localSystem", "other", "applicationPoolIdentity")); | ||
898 | break; | ||
899 | } | ||
900 | } | ||
901 | break; | ||
902 | case "IdleTimeout": | ||
903 | if (null == componentId) | ||
904 | { | ||
905 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
906 | } | ||
907 | |||
908 | idleTimeout = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); | ||
909 | break; | ||
910 | case "ManagedPipelineMode": | ||
911 | if (null == componentId) | ||
912 | { | ||
913 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
914 | } | ||
915 | |||
916 | managedPipelineMode = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
917 | |||
918 | |||
919 | if (!String.IsNullOrEmpty(managedPipelineMode)) | ||
920 | { | ||
921 | switch (managedPipelineMode) | ||
922 | { | ||
923 | // In 3.5 we allowed lower case values (per camel case enum style), we now use formatted fields, | ||
924 | // so the value needs to match exactly what we pass in to IIS which uses pascal case. | ||
925 | case "classic": | ||
926 | managedPipelineMode = "Classic"; | ||
927 | break; | ||
928 | case "integrated": | ||
929 | managedPipelineMode = "Integrated"; | ||
930 | break; | ||
931 | case "Classic": | ||
932 | break; | ||
933 | case "Integrated": | ||
934 | break; | ||
935 | default: | ||
936 | if (!this.Core.ContainsProperty(managedPipelineMode)) | ||
937 | { | ||
938 | this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, managedPipelineMode, "Classic", "Integrated")); | ||
939 | } | ||
940 | break; | ||
941 | } | ||
942 | } | ||
943 | |||
944 | break; | ||
945 | case "ManagedRuntimeVersion": | ||
946 | if (null == componentId) | ||
947 | { | ||
948 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
949 | } | ||
950 | |||
951 | managedRuntimeVersion = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
952 | break; | ||
953 | case "MaxCpuUsage": | ||
954 | if (null == componentId) | ||
955 | { | ||
956 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
957 | } | ||
958 | |||
959 | maxCpuUsage = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 100); | ||
960 | break; | ||
961 | case "MaxWorkerProcesses": | ||
962 | if (null == componentId) | ||
963 | { | ||
964 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
965 | } | ||
966 | |||
967 | maxWorkerProcs = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); | ||
968 | break; | ||
969 | case "Name": | ||
970 | name = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
971 | break; | ||
972 | case "PrivateMemory": | ||
973 | if (null == componentId) | ||
974 | { | ||
975 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
976 | } | ||
977 | |||
978 | privateMemory = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 4294967); | ||
979 | break; | ||
980 | case "QueueLimit": | ||
981 | if (null == componentId) | ||
982 | { | ||
983 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
984 | } | ||
985 | |||
986 | queueLimit = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); | ||
987 | break; | ||
988 | case "RecycleMinutes": | ||
989 | if (null == componentId) | ||
990 | { | ||
991 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
992 | } | ||
993 | |||
994 | recycleMinutes = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); | ||
995 | break; | ||
996 | case "RecycleRequests": | ||
997 | if (null == componentId) | ||
998 | { | ||
999 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
1000 | } | ||
1001 | |||
1002 | recycleRequests = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); | ||
1003 | break; | ||
1004 | case "RefreshCpu": | ||
1005 | if (null == componentId) | ||
1006 | { | ||
1007 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
1008 | } | ||
1009 | |||
1010 | refreshCpu = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); | ||
1011 | break; | ||
1012 | case "User": | ||
1013 | if (null == componentId) | ||
1014 | { | ||
1015 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
1016 | } | ||
1017 | |||
1018 | user = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
1019 | this.Core.CreateSimpleReference(sourceLineNumbers, "User", user); | ||
1020 | break; | ||
1021 | case "VirtualMemory": | ||
1022 | if (null == componentId) | ||
1023 | { | ||
1024 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
1025 | } | ||
1026 | |||
1027 | virtualMemory = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, 4294967); | ||
1028 | break; | ||
1029 | default: | ||
1030 | this.Core.UnexpectedAttribute(node, attrib); | ||
1031 | break; | ||
1032 | } | ||
1033 | } | ||
1034 | else | ||
1035 | { | ||
1036 | this.Core.ParseExtensionAttribute(node, attrib); | ||
1037 | } | ||
1038 | } | ||
1039 | |||
1040 | if (null == id) | ||
1041 | { | ||
1042 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); | ||
1043 | } | ||
1044 | |||
1045 | if (null == name) | ||
1046 | { | ||
1047 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); | ||
1048 | } | ||
1049 | |||
1050 | if (null == user && 8 == (attributes & 0x1F)) | ||
1051 | { | ||
1052 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "User", "Identity", "other")); | ||
1053 | } | ||
1054 | |||
1055 | if (null != user && 8 != (attributes & 0x1F)) | ||
1056 | { | ||
1057 | this.Core.OnMessage(WixErrors.IllegalAttributeValueWithoutOtherAttribute(sourceLineNumbers, node.Name.LocalName, "User", user, "Identity", "other")); | ||
1058 | } | ||
1059 | |||
1060 | cpuMon = maxCpuUsage.ToString(CultureInfo.InvariantCulture.NumberFormat); | ||
1061 | if (CompilerConstants.IntegerNotSet != refreshCpu) | ||
1062 | { | ||
1063 | cpuMon = String.Concat(cpuMon, ",", refreshCpu.ToString(CultureInfo.InvariantCulture.NumberFormat)); | ||
1064 | if (CompilerConstants.IntegerNotSet != cpuAction) | ||
1065 | { | ||
1066 | cpuMon = String.Concat(cpuMon, ",", cpuAction.ToString(CultureInfo.InvariantCulture.NumberFormat)); | ||
1067 | } | ||
1068 | } | ||
1069 | |||
1070 | foreach (XElement child in node.Elements()) | ||
1071 | { | ||
1072 | if (this.Namespace == child.Name.Namespace) | ||
1073 | { | ||
1074 | switch (child.Name.LocalName) | ||
1075 | { | ||
1076 | case "RecycleTime": | ||
1077 | if (null == componentId) | ||
1078 | { | ||
1079 | SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); | ||
1080 | this.Core.OnMessage(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, node.Name.LocalName)); | ||
1081 | } | ||
1082 | |||
1083 | if (null == recycleTimes) | ||
1084 | { | ||
1085 | recycleTimes = this.ParseRecycleTimeElement(child); | ||
1086 | } | ||
1087 | else | ||
1088 | { | ||
1089 | recycleTimes = String.Concat(recycleTimes, ",", this.ParseRecycleTimeElement(child)); | ||
1090 | } | ||
1091 | break; | ||
1092 | default: | ||
1093 | this.Core.UnexpectedElement(node, child); | ||
1094 | break; | ||
1095 | } | ||
1096 | } | ||
1097 | else | ||
1098 | { | ||
1099 | this.Core.ParseExtensionElement(node, child); | ||
1100 | } | ||
1101 | } | ||
1102 | |||
1103 | if (null != componentId) | ||
1104 | { | ||
1105 | // Reference ConfigureIIs since nothing will happen without it | ||
1106 | this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureIIs"); | ||
1107 | } | ||
1108 | |||
1109 | if (!this.Core.EncounteredError) | ||
1110 | { | ||
1111 | Row row = this.Core.CreateRow(sourceLineNumbers, "IIsAppPool"); | ||
1112 | row[0] = id; | ||
1113 | row[1] = name; | ||
1114 | row[2] = componentId; | ||
1115 | row[3] = attributes; | ||
1116 | row[4] = user; | ||
1117 | if (CompilerConstants.IntegerNotSet != recycleMinutes) | ||
1118 | { | ||
1119 | row[5] = recycleMinutes; | ||
1120 | } | ||
1121 | |||
1122 | if (CompilerConstants.IntegerNotSet != recycleRequests) | ||
1123 | { | ||
1124 | row[6] = recycleRequests; | ||
1125 | } | ||
1126 | row[7] = recycleTimes; | ||
1127 | if (CompilerConstants.IntegerNotSet != idleTimeout) | ||
1128 | { | ||
1129 | row[8] = idleTimeout; | ||
1130 | } | ||
1131 | |||
1132 | if (CompilerConstants.IntegerNotSet != queueLimit) | ||
1133 | { | ||
1134 | row[9] = queueLimit; | ||
1135 | } | ||
1136 | row[10] = cpuMon; | ||
1137 | if (CompilerConstants.IntegerNotSet != maxWorkerProcs) | ||
1138 | { | ||
1139 | row[11] = maxWorkerProcs; | ||
1140 | } | ||
1141 | |||
1142 | if (CompilerConstants.IntegerNotSet != virtualMemory) | ||
1143 | { | ||
1144 | row[12] = virtualMemory; | ||
1145 | } | ||
1146 | |||
1147 | if (CompilerConstants.IntegerNotSet != privateMemory) | ||
1148 | { | ||
1149 | row[13] = privateMemory; | ||
1150 | } | ||
1151 | row[14] = managedRuntimeVersion; | ||
1152 | row[15] = managedPipelineMode; | ||
1153 | } | ||
1154 | } | ||
1155 | |||
1156 | /// <summary> | ||
1157 | /// Parses a web directory element. | ||
1158 | /// </summary> | ||
1159 | /// <param name="node">Element to parse.</param> | ||
1160 | /// <param name="componentId">Identifier for parent component.</param> | ||
1161 | /// <param name="parentWeb">Optional identifier for parent web site.</param> | ||
1162 | private void ParseWebDirElement(XElement node, string componentId, string parentWeb) | ||
1163 | { | ||
1164 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
1165 | string id = null; | ||
1166 | string dirProperties = null; | ||
1167 | string path = null; | ||
1168 | string application = null; | ||
1169 | |||
1170 | foreach (XAttribute attrib in node.Attributes()) | ||
1171 | { | ||
1172 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
1173 | { | ||
1174 | switch (attrib.Name.LocalName) | ||
1175 | { | ||
1176 | case "Id": | ||
1177 | id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
1178 | break; | ||
1179 | case "DirProperties": | ||
1180 | dirProperties = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
1181 | break; | ||
1182 | case "Path": | ||
1183 | path = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
1184 | break; | ||
1185 | case "WebApplication": | ||
1186 | application = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
1187 | break; | ||
1188 | case "WebSite": | ||
1189 | if (null != parentWeb) | ||
1190 | { | ||
1191 | this.Core.OnMessage(IIsErrors.WebSiteAttributeUnderWebSite(sourceLineNumbers, node.Name.LocalName)); | ||
1192 | } | ||
1193 | |||
1194 | parentWeb = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
1195 | this.Core.CreateSimpleReference(sourceLineNumbers, "IIsWebSite", parentWeb); | ||
1196 | break; | ||
1197 | default: | ||
1198 | this.Core.UnexpectedAttribute(node, attrib); | ||
1199 | break; | ||
1200 | } | ||
1201 | } | ||
1202 | else | ||
1203 | { | ||
1204 | this.Core.ParseExtensionAttribute(node, attrib); | ||
1205 | } | ||
1206 | } | ||
1207 | |||
1208 | if (null == id) | ||
1209 | { | ||
1210 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); | ||
1211 | } | ||
1212 | |||
1213 | if (null == path) | ||
1214 | { | ||
1215 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Path")); | ||
1216 | } | ||
1217 | |||
1218 | if (null == parentWeb) | ||
1219 | { | ||
1220 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "WebSite")); | ||
1221 | } | ||
1222 | |||
1223 | foreach (XElement child in node.Elements()) | ||
1224 | { | ||
1225 | if (this.Namespace == child.Name.Namespace) | ||
1226 | { | ||
1227 | SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); | ||
1228 | switch (child.Name.LocalName) | ||
1229 | { | ||
1230 | case "WebApplication": | ||
1231 | if (null != application) | ||
1232 | { | ||
1233 | this.Core.OnMessage(IIsErrors.WebApplicationAlreadySpecified(childSourceLineNumbers, node.Name.LocalName)); | ||
1234 | } | ||
1235 | |||
1236 | application = this.ParseWebApplicationElement(child); | ||
1237 | break; | ||
1238 | case "WebDirProperties": | ||
1239 | if (null == componentId) | ||
1240 | { | ||
1241 | this.Core.OnMessage(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); | ||
1242 | } | ||
1243 | |||
1244 | string childWebDirProperties = this.ParseWebDirPropertiesElement(child); | ||
1245 | if (null == dirProperties) | ||
1246 | { | ||
1247 | dirProperties = childWebDirProperties; | ||
1248 | } | ||
1249 | else | ||
1250 | { | ||
1251 | this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, child.Name.LocalName, "DirProperties", child.Name.LocalName)); | ||
1252 | } | ||
1253 | break; | ||
1254 | default: | ||
1255 | this.Core.UnexpectedElement(node, child); | ||
1256 | break; | ||
1257 | } | ||
1258 | } | ||
1259 | else | ||
1260 | { | ||
1261 | this.Core.ParseExtensionElement(node, child); | ||
1262 | } | ||
1263 | } | ||
1264 | |||
1265 | if (null == dirProperties) | ||
1266 | { | ||
1267 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DirProperties")); | ||
1268 | } | ||
1269 | |||
1270 | if (null != application) | ||
1271 | { | ||
1272 | this.Core.CreateSimpleReference(sourceLineNumbers, "IIsWebApplication", application); | ||
1273 | } | ||
1274 | |||
1275 | this.Core.CreateSimpleReference(sourceLineNumbers, "IIsWebDirProperties", dirProperties); | ||
1276 | |||
1277 | // Reference ConfigureIIs since nothing will happen without it | ||
1278 | this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureIIs"); | ||
1279 | |||
1280 | if (!this.Core.EncounteredError) | ||
1281 | { | ||
1282 | Row row = this.Core.CreateRow(sourceLineNumbers, "IIsWebDir"); | ||
1283 | row[0] = id; | ||
1284 | row[1] = componentId; | ||
1285 | row[2] = parentWeb; | ||
1286 | row[3] = path; | ||
1287 | row[4] = dirProperties; | ||
1288 | row[5] = application; | ||
1289 | } | ||
1290 | } | ||
1291 | |||
1292 | /// <summary> | ||
1293 | /// Parses a web directory properties element. | ||
1294 | /// </summary> | ||
1295 | /// <param name="node">Element to parse.</param> | ||
1296 | /// <returns>The identifier for this WebDirProperties.</returns> | ||
1297 | private string ParseWebDirPropertiesElement(XElement node) | ||
1298 | { | ||
1299 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
1300 | string id = null; | ||
1301 | int access = 0; | ||
1302 | bool accessSet = false; | ||
1303 | int accessSSLFlags = 0; | ||
1304 | bool accessSSLFlagsSet = false; | ||
1305 | string anonymousUser = null; | ||
1306 | YesNoType aspDetailedError = YesNoType.NotSet; | ||
1307 | string authenticationProviders = null; | ||
1308 | int authorization = 0; | ||
1309 | bool authorizationSet = false; | ||
1310 | string cacheControlCustom = null; | ||
1311 | long cacheControlMaxAge = CompilerConstants.LongNotSet; | ||
1312 | string defaultDocuments = null; | ||
1313 | string httpExpires = null; | ||
1314 | bool iisControlledPassword = false; | ||
1315 | YesNoType index = YesNoType.NotSet; | ||
1316 | YesNoType logVisits = YesNoType.NotSet; | ||
1317 | YesNoType notCustomError = YesNoType.NotSet; | ||
1318 | |||
1319 | foreach (XAttribute attrib in node.Attributes()) | ||
1320 | { | ||
1321 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
1322 | { | ||
1323 | switch (attrib.Name.LocalName) | ||
1324 | { | ||
1325 | case "Id": | ||
1326 | id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
1327 | break; | ||
1328 | case "AnonymousUser": | ||
1329 | anonymousUser = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
1330 | this.Core.CreateSimpleReference(sourceLineNumbers, "User", anonymousUser); | ||
1331 | break; | ||
1332 | case "AspDetailedError": | ||
1333 | aspDetailedError = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); | ||
1334 | break; | ||
1335 | case "AuthenticationProviders": | ||
1336 | authenticationProviders = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
1337 | break; | ||
1338 | case "CacheControlCustom": | ||
1339 | cacheControlCustom = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
1340 | break; | ||
1341 | case "CacheControlMaxAge": | ||
1342 | cacheControlMaxAge = this.Core.GetAttributeLongValue(sourceLineNumbers, attrib, 0, uint.MaxValue); // 4294967295 (uint.MaxValue) represents unlimited | ||
1343 | break; | ||
1344 | case "ClearCustomError": | ||
1345 | notCustomError = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); | ||
1346 | break; | ||
1347 | case "DefaultDocuments": | ||
1348 | defaultDocuments = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
1349 | break; | ||
1350 | case "HttpExpires": | ||
1351 | httpExpires = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
1352 | break; | ||
1353 | case "IIsControlledPassword": | ||
1354 | iisControlledPassword = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); | ||
1355 | break; | ||
1356 | case "Index": | ||
1357 | index = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); | ||
1358 | break; | ||
1359 | case "LogVisits": | ||
1360 | logVisits = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); | ||
1361 | break; | ||
1362 | |||
1363 | // Access attributes | ||
1364 | case "Execute": | ||
1365 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
1366 | { | ||
1367 | access |= 4; | ||
1368 | } | ||
1369 | else | ||
1370 | { | ||
1371 | access &= ~4; | ||
1372 | } | ||
1373 | accessSet = true; | ||
1374 | break; | ||
1375 | case "Read": | ||
1376 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
1377 | { | ||
1378 | access |= 1; | ||
1379 | } | ||
1380 | else | ||
1381 | { | ||
1382 | access &= ~1; | ||
1383 | } | ||
1384 | accessSet = true; | ||
1385 | break; | ||
1386 | case "Script": | ||
1387 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
1388 | { | ||
1389 | access |= 512; | ||
1390 | } | ||
1391 | else | ||
1392 | { | ||
1393 | access &= ~512; | ||
1394 | } | ||
1395 | accessSet = true; | ||
1396 | break; | ||
1397 | case "Write": | ||
1398 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
1399 | { | ||
1400 | access |= 2; | ||
1401 | } | ||
1402 | else | ||
1403 | { | ||
1404 | access &= ~2; | ||
1405 | } | ||
1406 | accessSet = true; | ||
1407 | break; | ||
1408 | |||
1409 | // AccessSSL Attributes | ||
1410 | case "AccessSSL": | ||
1411 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
1412 | { | ||
1413 | accessSSLFlags |= 8; | ||
1414 | } | ||
1415 | else | ||
1416 | { | ||
1417 | accessSSLFlags &= ~8; | ||
1418 | } | ||
1419 | accessSSLFlagsSet = true; | ||
1420 | break; | ||
1421 | case "AccessSSL128": | ||
1422 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
1423 | { | ||
1424 | accessSSLFlags |= 256; | ||
1425 | } | ||
1426 | else | ||
1427 | { | ||
1428 | accessSSLFlags &= ~256; | ||
1429 | } | ||
1430 | accessSSLFlagsSet = true; | ||
1431 | break; | ||
1432 | case "AccessSSLMapCert": | ||
1433 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
1434 | { | ||
1435 | accessSSLFlags |= 128; | ||
1436 | } | ||
1437 | else | ||
1438 | { | ||
1439 | accessSSLFlags &= ~128; | ||
1440 | } | ||
1441 | accessSSLFlagsSet = true; | ||
1442 | break; | ||
1443 | case "AccessSSLNegotiateCert": | ||
1444 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
1445 | { | ||
1446 | accessSSLFlags |= 32; | ||
1447 | } | ||
1448 | else | ||
1449 | { | ||
1450 | accessSSLFlags &= ~32; | ||
1451 | } | ||
1452 | accessSSLFlagsSet = true; | ||
1453 | break; | ||
1454 | case "AccessSSLRequireCert": | ||
1455 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
1456 | { | ||
1457 | accessSSLFlags |= 64; | ||
1458 | } | ||
1459 | else | ||
1460 | { | ||
1461 | accessSSLFlags &= ~64; | ||
1462 | } | ||
1463 | accessSSLFlagsSet = true; | ||
1464 | break; | ||
1465 | |||
1466 | // Authorization attributes | ||
1467 | case "AnonymousAccess": | ||
1468 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
1469 | { | ||
1470 | authorization |= 1; | ||
1471 | } | ||
1472 | else | ||
1473 | { | ||
1474 | authorization &= ~1; | ||
1475 | } | ||
1476 | authorizationSet = true; | ||
1477 | break; | ||
1478 | case "BasicAuthentication": | ||
1479 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
1480 | { | ||
1481 | authorization |= 2; | ||
1482 | } | ||
1483 | else | ||
1484 | { | ||
1485 | authorization &= ~2; | ||
1486 | } | ||
1487 | authorizationSet = true; | ||
1488 | break; | ||
1489 | case "DigestAuthentication": | ||
1490 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
1491 | { | ||
1492 | authorization |= 16; | ||
1493 | } | ||
1494 | else | ||
1495 | { | ||
1496 | authorization &= ~16; | ||
1497 | } | ||
1498 | authorizationSet = true; | ||
1499 | break; | ||
1500 | case "PassportAuthentication": | ||
1501 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
1502 | { | ||
1503 | authorization |= 64; | ||
1504 | } | ||
1505 | else | ||
1506 | { | ||
1507 | authorization &= ~64; | ||
1508 | } | ||
1509 | authorizationSet = true; | ||
1510 | break; | ||
1511 | case "WindowsAuthentication": | ||
1512 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
1513 | { | ||
1514 | authorization |= 4; | ||
1515 | } | ||
1516 | else | ||
1517 | { | ||
1518 | authorization &= ~4; | ||
1519 | } | ||
1520 | authorizationSet = true; | ||
1521 | break; | ||
1522 | default: | ||
1523 | this.Core.UnexpectedAttribute(node, attrib); | ||
1524 | break; | ||
1525 | } | ||
1526 | } | ||
1527 | else | ||
1528 | { | ||
1529 | this.Core.ParseExtensionAttribute(node, attrib); | ||
1530 | } | ||
1531 | } | ||
1532 | |||
1533 | if (null == id) | ||
1534 | { | ||
1535 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); | ||
1536 | } | ||
1537 | |||
1538 | this.Core.ParseForExtensionElements(node); | ||
1539 | |||
1540 | if (!this.Core.EncounteredError) | ||
1541 | { | ||
1542 | Row row = this.Core.CreateRow(sourceLineNumbers, "IIsWebDirProperties"); | ||
1543 | row[0] = id; | ||
1544 | if (accessSet) | ||
1545 | { | ||
1546 | row[1] = access; | ||
1547 | } | ||
1548 | |||
1549 | if (authorizationSet) | ||
1550 | { | ||
1551 | row[2] = authorization; | ||
1552 | } | ||
1553 | row[3] = anonymousUser; | ||
1554 | row[4] = iisControlledPassword ? 1 : 0; | ||
1555 | if (YesNoType.NotSet != logVisits) | ||
1556 | { | ||
1557 | row[5] = YesNoType.Yes == logVisits ? 1 : 0; | ||
1558 | } | ||
1559 | |||
1560 | if (YesNoType.NotSet != index) | ||
1561 | { | ||
1562 | row[6] = YesNoType.Yes == index ? 1 : 0; | ||
1563 | } | ||
1564 | row[7] = defaultDocuments; | ||
1565 | if (YesNoType.NotSet != aspDetailedError) | ||
1566 | { | ||
1567 | row[8] = YesNoType.Yes == aspDetailedError ? 1 : 0; | ||
1568 | } | ||
1569 | row[9] = httpExpires; | ||
1570 | if (CompilerConstants.LongNotSet != cacheControlMaxAge) | ||
1571 | { | ||
1572 | row[10] = unchecked((int)cacheControlMaxAge); | ||
1573 | } | ||
1574 | row[11] = cacheControlCustom; | ||
1575 | if (YesNoType.NotSet != notCustomError) | ||
1576 | { | ||
1577 | row[12] = YesNoType.Yes == notCustomError ? 1 : 0; | ||
1578 | } | ||
1579 | |||
1580 | if (accessSSLFlagsSet) | ||
1581 | { | ||
1582 | row[13] = accessSSLFlags; | ||
1583 | } | ||
1584 | |||
1585 | if (null != authenticationProviders) | ||
1586 | { | ||
1587 | row[14] = authenticationProviders; | ||
1588 | } | ||
1589 | } | ||
1590 | |||
1591 | return id; | ||
1592 | } | ||
1593 | |||
1594 | /// <summary> | ||
1595 | /// Parses a web error element. | ||
1596 | /// </summary> | ||
1597 | /// <param name="node">Element to parse.</param> | ||
1598 | /// <param name="parentType">Type of the parent.</param> | ||
1599 | /// <param name="parent">Id of the parent.</param> | ||
1600 | private void ParseWebErrorElement(XElement node, WebErrorParentType parentType, string parent) | ||
1601 | { | ||
1602 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
1603 | int errorCode = CompilerConstants.IntegerNotSet; | ||
1604 | string file = null; | ||
1605 | string url = null; | ||
1606 | int subCode = CompilerConstants.IntegerNotSet; | ||
1607 | |||
1608 | foreach (XAttribute attrib in node.Attributes()) | ||
1609 | { | ||
1610 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
1611 | { | ||
1612 | switch (attrib.Name.LocalName) | ||
1613 | { | ||
1614 | case "ErrorCode": | ||
1615 | errorCode = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 400, 599); | ||
1616 | break; | ||
1617 | case "File": | ||
1618 | file = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
1619 | break; | ||
1620 | case "SubCode": | ||
1621 | subCode = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); | ||
1622 | break; | ||
1623 | case "URL": | ||
1624 | url = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
1625 | break; | ||
1626 | default: | ||
1627 | this.Core.UnexpectedAttribute(node, attrib); | ||
1628 | break; | ||
1629 | } | ||
1630 | } | ||
1631 | else | ||
1632 | { | ||
1633 | this.Core.ParseExtensionAttribute(node, attrib); | ||
1634 | } | ||
1635 | } | ||
1636 | |||
1637 | if (CompilerConstants.IntegerNotSet == errorCode) | ||
1638 | { | ||
1639 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ErrorCode")); | ||
1640 | errorCode = CompilerConstants.IllegalInteger; | ||
1641 | } | ||
1642 | |||
1643 | if (CompilerConstants.IntegerNotSet == subCode) | ||
1644 | { | ||
1645 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SubCode")); | ||
1646 | subCode = CompilerConstants.IllegalInteger; | ||
1647 | } | ||
1648 | |||
1649 | if (String.IsNullOrEmpty(file) && String.IsNullOrEmpty(url)) | ||
1650 | { | ||
1651 | this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "File", "URL")); | ||
1652 | } | ||
1653 | |||
1654 | this.Core.ParseForExtensionElements(node); | ||
1655 | |||
1656 | // Reference ConfigureIIs since nothing will happen without it | ||
1657 | this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureIIs"); | ||
1658 | |||
1659 | if (!this.Core.EncounteredError) | ||
1660 | { | ||
1661 | Row row = this.Core.CreateRow(sourceLineNumbers, "IIsWebError"); | ||
1662 | row[0] = errorCode; | ||
1663 | row[1] = subCode; | ||
1664 | row[2] = (int)parentType; | ||
1665 | row[3] = parent; | ||
1666 | row[4] = file; | ||
1667 | row[5] = url; | ||
1668 | } | ||
1669 | } | ||
1670 | |||
1671 | /// <summary> | ||
1672 | /// Parses a web filter element. | ||
1673 | /// </summary> | ||
1674 | /// <param name="node">Element to parse.</param> | ||
1675 | /// <param name="componentId">Identifier of parent component.</param> | ||
1676 | /// <param name="parentWeb">Optional identifier of parent web site.</param> | ||
1677 | private void ParseWebFilterElement(XElement node, string componentId, string parentWeb) | ||
1678 | { | ||
1679 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
1680 | string id = null; | ||
1681 | string description = null; | ||
1682 | int flags = 0; | ||
1683 | int loadOrder = CompilerConstants.IntegerNotSet; | ||
1684 | string name = null; | ||
1685 | string path = null; | ||
1686 | |||
1687 | foreach (XAttribute attrib in node.Attributes()) | ||
1688 | { | ||
1689 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
1690 | { | ||
1691 | switch (attrib.Name.LocalName) | ||
1692 | { | ||
1693 | case "Id": | ||
1694 | id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
1695 | break; | ||
1696 | case "Description": | ||
1697 | description = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
1698 | break; | ||
1699 | case "Flags": | ||
1700 | flags = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue); | ||
1701 | break; | ||
1702 | case "LoadOrder": | ||
1703 | string loadOrderValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
1704 | if (0 < loadOrderValue.Length) | ||
1705 | { | ||
1706 | switch (loadOrderValue) | ||
1707 | { | ||
1708 | case "first": | ||
1709 | loadOrder = 0; | ||
1710 | break; | ||
1711 | case "last": | ||
1712 | loadOrder = -1; | ||
1713 | break; | ||
1714 | default: | ||
1715 | loadOrder = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); | ||
1716 | break; | ||
1717 | } | ||
1718 | } | ||
1719 | break; | ||
1720 | case "Name": | ||
1721 | name = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
1722 | break; | ||
1723 | case "Path": | ||
1724 | path = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
1725 | break; | ||
1726 | case "WebSite": | ||
1727 | if (null != parentWeb) | ||
1728 | { | ||
1729 | this.Core.OnMessage(IIsErrors.WebSiteAttributeUnderWebSite(sourceLineNumbers, node.Name.LocalName)); | ||
1730 | } | ||
1731 | |||
1732 | parentWeb = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
1733 | this.Core.CreateSimpleReference(sourceLineNumbers, "IIsWebSite", parentWeb); | ||
1734 | break; | ||
1735 | default: | ||
1736 | this.Core.UnexpectedAttribute(node, attrib); | ||
1737 | break; | ||
1738 | } | ||
1739 | } | ||
1740 | else | ||
1741 | { | ||
1742 | this.Core.ParseExtensionAttribute(node, attrib); | ||
1743 | } | ||
1744 | } | ||
1745 | |||
1746 | if (null == id) | ||
1747 | { | ||
1748 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); | ||
1749 | } | ||
1750 | |||
1751 | if (null == name) | ||
1752 | { | ||
1753 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); | ||
1754 | } | ||
1755 | |||
1756 | if (null == path) | ||
1757 | { | ||
1758 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Path")); | ||
1759 | } | ||
1760 | |||
1761 | this.Core.ParseForExtensionElements(node); | ||
1762 | |||
1763 | // Reference ConfigureIIs since nothing will happen without it | ||
1764 | this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureIIs"); | ||
1765 | |||
1766 | if (!this.Core.EncounteredError) | ||
1767 | { | ||
1768 | Row row = this.Core.CreateRow(sourceLineNumbers, "IIsFilter"); | ||
1769 | row[0] = id; | ||
1770 | row[1] = name; | ||
1771 | row[2] = componentId; | ||
1772 | row[3] = path; | ||
1773 | row[4] = parentWeb; | ||
1774 | row[5] = description; | ||
1775 | row[6] = flags; | ||
1776 | if (CompilerConstants.IntegerNotSet != loadOrder) | ||
1777 | { | ||
1778 | row[7] = loadOrder; | ||
1779 | } | ||
1780 | } | ||
1781 | } | ||
1782 | |||
1783 | /// <summary> | ||
1784 | /// Parses web log element. | ||
1785 | /// </summary> | ||
1786 | /// <param name="node">Node to be parsed.</param> | ||
1787 | private void ParseWebLogElement(XElement node) | ||
1788 | { | ||
1789 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
1790 | string id = null; | ||
1791 | string type = null; | ||
1792 | |||
1793 | foreach (XAttribute attrib in node.Attributes()) | ||
1794 | { | ||
1795 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
1796 | { | ||
1797 | switch (attrib.Name.LocalName) | ||
1798 | { | ||
1799 | case "Id": | ||
1800 | id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
1801 | break; | ||
1802 | case "Type": | ||
1803 | string typeValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
1804 | if (0 < typeValue.Length) | ||
1805 | { | ||
1806 | switch (typeValue) | ||
1807 | { | ||
1808 | case "IIS": | ||
1809 | type = "Microsoft IIS Log File Format"; | ||
1810 | break; | ||
1811 | case "NCSA": | ||
1812 | type = "NCSA Common Log File Format"; | ||
1813 | break; | ||
1814 | case "none": | ||
1815 | type = "none"; | ||
1816 | break; | ||
1817 | case "ODBC": | ||
1818 | type = "ODBC Logging"; | ||
1819 | break; | ||
1820 | case "W3C": | ||
1821 | type = "W3C Extended Log File Format"; | ||
1822 | break; | ||
1823 | default: | ||
1824 | this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Type", typeValue, "IIS", "NCSA", "none", "ODBC", "W3C")); | ||
1825 | break; | ||
1826 | } | ||
1827 | } | ||
1828 | break; | ||
1829 | default: | ||
1830 | this.Core.UnexpectedAttribute(node, attrib); | ||
1831 | break; | ||
1832 | } | ||
1833 | } | ||
1834 | else | ||
1835 | { | ||
1836 | this.Core.ParseExtensionAttribute(node, attrib); | ||
1837 | } | ||
1838 | } | ||
1839 | |||
1840 | if (null == id) | ||
1841 | { | ||
1842 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); | ||
1843 | } | ||
1844 | |||
1845 | if (null == type) | ||
1846 | { | ||
1847 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Type")); | ||
1848 | } | ||
1849 | |||
1850 | this.Core.ParseForExtensionElements(node); | ||
1851 | |||
1852 | if (!this.Core.EncounteredError) | ||
1853 | { | ||
1854 | Row row = this.Core.CreateRow(sourceLineNumbers, "IIsWebLog"); | ||
1855 | row[0] = id; | ||
1856 | row[1] = type; | ||
1857 | } | ||
1858 | } | ||
1859 | |||
1860 | /// <summary> | ||
1861 | /// Parses a web property element. | ||
1862 | /// </summary> | ||
1863 | /// <param name="node">Element to parse.</param> | ||
1864 | /// <param name="componentId">Identifier for parent component.</param> | ||
1865 | private void ParseWebPropertyElement(XElement node, string componentId) | ||
1866 | { | ||
1867 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
1868 | string id = null; | ||
1869 | string value = null; | ||
1870 | |||
1871 | foreach (XAttribute attrib in node.Attributes()) | ||
1872 | { | ||
1873 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
1874 | { | ||
1875 | switch (attrib.Name.LocalName) | ||
1876 | { | ||
1877 | case "Id": | ||
1878 | id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
1879 | break; | ||
1880 | case "Value": | ||
1881 | value = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
1882 | break; | ||
1883 | default: | ||
1884 | this.Core.UnexpectedAttribute(node, attrib); | ||
1885 | break; | ||
1886 | } | ||
1887 | } | ||
1888 | else | ||
1889 | { | ||
1890 | this.Core.ParseExtensionAttribute(node, attrib); | ||
1891 | } | ||
1892 | } | ||
1893 | |||
1894 | switch (id) | ||
1895 | { | ||
1896 | case "ETagChangeNumber": | ||
1897 | case "MaxGlobalBandwidth": | ||
1898 | // Must specify a value for these | ||
1899 | if (null == value) | ||
1900 | { | ||
1901 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value", "Id", id)); | ||
1902 | } | ||
1903 | break; | ||
1904 | case "IIs5IsolationMode": | ||
1905 | case "LogInUTF8": | ||
1906 | // Can't specify a value for these | ||
1907 | if (null != value) | ||
1908 | { | ||
1909 | this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Value", "Id", id)); | ||
1910 | } | ||
1911 | break; | ||
1912 | default: | ||
1913 | this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Id", id, "ETagChangeNumber", "IIs5IsolationMode", "LogInUTF8", "MaxGlobalBandwidth")); | ||
1914 | break; | ||
1915 | } | ||
1916 | |||
1917 | this.Core.ParseForExtensionElements(node); | ||
1918 | |||
1919 | // Reference ConfigureIIs since nothing will happen without it | ||
1920 | this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureIIs"); | ||
1921 | |||
1922 | if (!this.Core.EncounteredError) | ||
1923 | { | ||
1924 | Row row = this.Core.CreateRow(sourceLineNumbers, "IIsProperty"); | ||
1925 | row[0] = id; | ||
1926 | row[1] = componentId; | ||
1927 | row[2] = 0; | ||
1928 | row[3] = value; | ||
1929 | } | ||
1930 | } | ||
1931 | |||
1932 | /// <summary> | ||
1933 | /// Parses a web service extension element. | ||
1934 | /// </summary> | ||
1935 | /// <param name="node">Element to parse.</param> | ||
1936 | /// <param name="componentId">Identifier for parent component.</param> | ||
1937 | private void ParseWebServiceExtensionElement(XElement node, string componentId) | ||
1938 | { | ||
1939 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
1940 | string id = null; | ||
1941 | int attributes = 0; | ||
1942 | string description = null; | ||
1943 | string file = null; | ||
1944 | string group = null; | ||
1945 | |||
1946 | foreach (XAttribute attrib in node.Attributes()) | ||
1947 | { | ||
1948 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
1949 | { | ||
1950 | switch (attrib.Name.LocalName) | ||
1951 | { | ||
1952 | case "Id": | ||
1953 | id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
1954 | break; | ||
1955 | case "Allow": | ||
1956 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
1957 | { | ||
1958 | attributes |= 1; | ||
1959 | } | ||
1960 | else | ||
1961 | { | ||
1962 | attributes &= ~1; | ||
1963 | } | ||
1964 | break; | ||
1965 | case "Description": | ||
1966 | description = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
1967 | break; | ||
1968 | case "File": | ||
1969 | file = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
1970 | break; | ||
1971 | case "Group": | ||
1972 | group = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
1973 | break; | ||
1974 | case "UIDeletable": | ||
1975 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
1976 | { | ||
1977 | attributes |= 2; | ||
1978 | } | ||
1979 | else | ||
1980 | { | ||
1981 | attributes &= ~2; | ||
1982 | } | ||
1983 | break; | ||
1984 | default: | ||
1985 | this.Core.UnexpectedAttribute(node, attrib); | ||
1986 | break; | ||
1987 | } | ||
1988 | } | ||
1989 | else | ||
1990 | { | ||
1991 | this.Core.ParseExtensionAttribute(node, attrib); | ||
1992 | } | ||
1993 | } | ||
1994 | |||
1995 | if (null == id) | ||
1996 | { | ||
1997 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); | ||
1998 | } | ||
1999 | |||
2000 | if (null == file) | ||
2001 | { | ||
2002 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "File")); | ||
2003 | } | ||
2004 | |||
2005 | this.Core.ParseForExtensionElements(node); | ||
2006 | |||
2007 | // Reference ConfigureIIs since nothing will happen without it | ||
2008 | this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureIIs"); | ||
2009 | |||
2010 | if (!this.Core.EncounteredError) | ||
2011 | { | ||
2012 | Row row = this.Core.CreateRow(sourceLineNumbers, "IIsWebServiceExtension"); | ||
2013 | row[0] = id; | ||
2014 | row[1] = componentId; | ||
2015 | row[2] = file; | ||
2016 | row[3] = description; | ||
2017 | row[4] = group; | ||
2018 | row[5] = attributes; | ||
2019 | } | ||
2020 | } | ||
2021 | |||
2022 | /// <summary> | ||
2023 | /// Parses a web site element. | ||
2024 | /// </summary> | ||
2025 | /// <param name="node">Element to parse.</param> | ||
2026 | /// <param name="componentId">Optional identifier of parent component.</param> | ||
2027 | private void ParseWebSiteElement(XElement node, string componentId) | ||
2028 | { | ||
2029 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
2030 | string id = null; | ||
2031 | string application = null; | ||
2032 | int attributes = 0; | ||
2033 | int connectionTimeout = CompilerConstants.IntegerNotSet; | ||
2034 | string description = null; | ||
2035 | string directory = null; | ||
2036 | string dirProperties = null; | ||
2037 | string keyAddress = null; | ||
2038 | string log = null; | ||
2039 | string siteId = null; | ||
2040 | int sequence = CompilerConstants.IntegerNotSet; | ||
2041 | int state = CompilerConstants.IntegerNotSet; | ||
2042 | |||
2043 | foreach (XAttribute attrib in node.Attributes()) | ||
2044 | { | ||
2045 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
2046 | { | ||
2047 | switch (attrib.Name.LocalName) | ||
2048 | { | ||
2049 | case "Id": | ||
2050 | id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
2051 | break; | ||
2052 | case "AutoStart": | ||
2053 | if (null == componentId) | ||
2054 | { | ||
2055 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
2056 | } | ||
2057 | |||
2058 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
2059 | { | ||
2060 | state = 2; | ||
2061 | } | ||
2062 | else if (state != 1) | ||
2063 | { | ||
2064 | state = 0; | ||
2065 | } | ||
2066 | break; | ||
2067 | case "ConfigureIfExists": | ||
2068 | if (null == componentId) | ||
2069 | { | ||
2070 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
2071 | } | ||
2072 | |||
2073 | if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
2074 | { | ||
2075 | attributes &= ~2; | ||
2076 | } | ||
2077 | else | ||
2078 | { | ||
2079 | attributes |= 2; | ||
2080 | } | ||
2081 | break; | ||
2082 | case "ConnectionTimeout": | ||
2083 | connectionTimeout = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); | ||
2084 | break; | ||
2085 | case "Description": | ||
2086 | description = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
2087 | break; | ||
2088 | case "Directory": | ||
2089 | directory = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
2090 | this.Core.CreateSimpleReference(sourceLineNumbers, "Directory", directory); | ||
2091 | break; | ||
2092 | case "DirProperties": | ||
2093 | if (null == componentId) | ||
2094 | { | ||
2095 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
2096 | } | ||
2097 | |||
2098 | dirProperties = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
2099 | break; | ||
2100 | case "SiteId": | ||
2101 | siteId = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
2102 | if ("*" == siteId) | ||
2103 | { | ||
2104 | siteId = "-1"; | ||
2105 | } | ||
2106 | break; | ||
2107 | case "Sequence": | ||
2108 | sequence = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); | ||
2109 | break; | ||
2110 | case "StartOnInstall": | ||
2111 | if (null == componentId) | ||
2112 | { | ||
2113 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
2114 | } | ||
2115 | |||
2116 | // when state is set to 2 it implies 1, so don't set it to 1 | ||
2117 | if (2 != state && YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) | ||
2118 | { | ||
2119 | state = 1; | ||
2120 | } | ||
2121 | else if (2 != state) | ||
2122 | { | ||
2123 | state = 0; | ||
2124 | } | ||
2125 | break; | ||
2126 | case "WebApplication": | ||
2127 | if (null == componentId) | ||
2128 | { | ||
2129 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
2130 | } | ||
2131 | |||
2132 | application = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
2133 | break; | ||
2134 | case "WebLog": | ||
2135 | if (null == componentId) | ||
2136 | { | ||
2137 | this.Core.OnMessage(IIsErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); | ||
2138 | } | ||
2139 | |||
2140 | log = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
2141 | this.Core.CreateSimpleReference(sourceLineNumbers, "IIsWebLog", log); | ||
2142 | break; | ||
2143 | default: | ||
2144 | this.Core.UnexpectedAttribute(node, attrib); | ||
2145 | break; | ||
2146 | } | ||
2147 | } | ||
2148 | else | ||
2149 | { | ||
2150 | this.Core.ParseExtensionAttribute(node, attrib); | ||
2151 | } | ||
2152 | } | ||
2153 | |||
2154 | if (null == id) | ||
2155 | { | ||
2156 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); | ||
2157 | } | ||
2158 | |||
2159 | if (null == description) | ||
2160 | { | ||
2161 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Description")); | ||
2162 | } | ||
2163 | |||
2164 | if (null == directory && null != componentId) | ||
2165 | { | ||
2166 | this.Core.OnMessage(IIsErrors.RequiredAttributeUnderComponent(sourceLineNumbers, node.Name.LocalName, "Directory")); | ||
2167 | } | ||
2168 | |||
2169 | foreach (XElement child in node.Elements()) | ||
2170 | { | ||
2171 | if (this.Namespace == child.Name.Namespace) | ||
2172 | { | ||
2173 | SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); | ||
2174 | switch (child.Name.LocalName) | ||
2175 | { | ||
2176 | case "CertificateRef": | ||
2177 | if (null == componentId) | ||
2178 | { | ||
2179 | this.Core.OnMessage(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); | ||
2180 | } | ||
2181 | |||
2182 | this.ParseCertificateRefElement(child, id); | ||
2183 | break; | ||
2184 | case "HttpHeader": | ||
2185 | if (null == componentId) | ||
2186 | { | ||
2187 | this.Core.OnMessage(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); | ||
2188 | } | ||
2189 | |||
2190 | this.ParseHttpHeaderElement(child, HttpHeaderParentType.WebSite, id); | ||
2191 | break; | ||
2192 | case "WebAddress": | ||
2193 | string address = this.ParseWebAddressElement(child, id); | ||
2194 | if (null == keyAddress) | ||
2195 | { | ||
2196 | keyAddress = address; | ||
2197 | } | ||
2198 | break; | ||
2199 | case "WebApplication": | ||
2200 | if (null == componentId) | ||
2201 | { | ||
2202 | this.Core.OnMessage(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); | ||
2203 | } | ||
2204 | |||
2205 | if (null != application) | ||
2206 | { | ||
2207 | this.Core.OnMessage(IIsErrors.WebApplicationAlreadySpecified(childSourceLineNumbers, node.Name.LocalName)); | ||
2208 | } | ||
2209 | |||
2210 | application = this.ParseWebApplicationElement(child); | ||
2211 | break; | ||
2212 | case "WebDir": | ||
2213 | if (null == componentId) | ||
2214 | { | ||
2215 | this.Core.OnMessage(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); | ||
2216 | } | ||
2217 | |||
2218 | this.ParseWebDirElement(child, componentId, id); | ||
2219 | break; | ||
2220 | case "WebDirProperties": | ||
2221 | if (null == componentId) | ||
2222 | { | ||
2223 | this.Core.OnMessage(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); | ||
2224 | } | ||
2225 | |||
2226 | string childWebDirProperties = this.ParseWebDirPropertiesElement(child); | ||
2227 | if (null == dirProperties) | ||
2228 | { | ||
2229 | dirProperties = childWebDirProperties; | ||
2230 | } | ||
2231 | else | ||
2232 | { | ||
2233 | this.Core.OnMessage(WixErrors.IllegalParentAttributeWhenNested(sourceLineNumbers, "WebSite", "DirProperties", child.Name.LocalName)); | ||
2234 | } | ||
2235 | break; | ||
2236 | case "WebError": | ||
2237 | if (null == componentId) | ||
2238 | { | ||
2239 | this.Core.OnMessage(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); | ||
2240 | } | ||
2241 | |||
2242 | this.ParseWebErrorElement(child, WebErrorParentType.WebSite, id); | ||
2243 | break; | ||
2244 | case "WebFilter": | ||
2245 | if (null == componentId) | ||
2246 | { | ||
2247 | this.Core.OnMessage(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); | ||
2248 | } | ||
2249 | |||
2250 | this.ParseWebFilterElement(child, componentId, id); | ||
2251 | break; | ||
2252 | case "WebVirtualDir": | ||
2253 | if (null == componentId) | ||
2254 | { | ||
2255 | this.Core.OnMessage(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); | ||
2256 | } | ||
2257 | |||
2258 | this.ParseWebVirtualDirElement(child, componentId, id, null); | ||
2259 | break; | ||
2260 | case "MimeMap": | ||
2261 | this.ParseMimeMapElement(child, id, MimeMapParentType.WebSite); | ||
2262 | break; | ||
2263 | default: | ||
2264 | this.Core.UnexpectedElement(node, child); | ||
2265 | break; | ||
2266 | } | ||
2267 | } | ||
2268 | else | ||
2269 | { | ||
2270 | this.Core.ParseExtensionElement(node, child); | ||
2271 | } | ||
2272 | } | ||
2273 | |||
2274 | |||
2275 | if (null == keyAddress) | ||
2276 | { | ||
2277 | this.Core.OnMessage(WixErrors.ExpectedElement(sourceLineNumbers, node.Name.LocalName, "WebAddress")); | ||
2278 | } | ||
2279 | |||
2280 | if (null != application) | ||
2281 | { | ||
2282 | this.Core.CreateSimpleReference(sourceLineNumbers, "IIsWebApplication", application); | ||
2283 | } | ||
2284 | |||
2285 | if (null != dirProperties) | ||
2286 | { | ||
2287 | this.Core.CreateSimpleReference(sourceLineNumbers, "IIsWebDirProperties", dirProperties); | ||
2288 | } | ||
2289 | |||
2290 | if (null != componentId) | ||
2291 | { | ||
2292 | // Reference ConfigureIIs since nothing will happen without it | ||
2293 | this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureIIs"); | ||
2294 | } | ||
2295 | |||
2296 | if (!this.Core.EncounteredError) | ||
2297 | { | ||
2298 | Row row = this.Core.CreateRow(sourceLineNumbers, "IIsWebSite"); | ||
2299 | row[0] = id; | ||
2300 | row[1] = componentId; | ||
2301 | row[2] = description; | ||
2302 | if (CompilerConstants.IntegerNotSet != connectionTimeout) | ||
2303 | { | ||
2304 | row[3] = connectionTimeout; | ||
2305 | } | ||
2306 | row[4] = directory; | ||
2307 | if (CompilerConstants.IntegerNotSet != state) | ||
2308 | { | ||
2309 | row[5] = state; | ||
2310 | } | ||
2311 | |||
2312 | if (0 != attributes) | ||
2313 | { | ||
2314 | row[6] = attributes; | ||
2315 | } | ||
2316 | row[7] = keyAddress; | ||
2317 | row[8] = dirProperties; | ||
2318 | row[9] = application; | ||
2319 | if (CompilerConstants.IntegerNotSet != sequence) | ||
2320 | { | ||
2321 | row[10] = sequence; | ||
2322 | } | ||
2323 | row[11] = log; | ||
2324 | row[12] = siteId; | ||
2325 | } | ||
2326 | } | ||
2327 | |||
2328 | /// <summary> | ||
2329 | /// Parses a HTTP Header element. | ||
2330 | /// </summary> | ||
2331 | /// <param name="node">Element to parse.</param> | ||
2332 | /// <param name="parentType">Type of the parent.</param> | ||
2333 | /// <param name="parent">Id of the parent.</param> | ||
2334 | private void ParseHttpHeaderElement(XElement node, HttpHeaderParentType parentType, string parent) | ||
2335 | { | ||
2336 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
2337 | Identifier id = null; | ||
2338 | string headerName = null; | ||
2339 | string headerValue = null; | ||
2340 | |||
2341 | foreach (XAttribute attrib in node.Attributes()) | ||
2342 | { | ||
2343 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
2344 | { | ||
2345 | switch (attrib.Name.LocalName) | ||
2346 | { | ||
2347 | case "Id": | ||
2348 | id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib); | ||
2349 | break; | ||
2350 | case "Name": | ||
2351 | headerName = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
2352 | break; | ||
2353 | case "Value": | ||
2354 | headerValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
2355 | break; | ||
2356 | default: | ||
2357 | this.Core.UnexpectedAttribute(node, attrib); | ||
2358 | break; | ||
2359 | } | ||
2360 | } | ||
2361 | else | ||
2362 | { | ||
2363 | this.Core.ParseExtensionAttribute(node, attrib); | ||
2364 | } | ||
2365 | } | ||
2366 | |||
2367 | if (null == headerName) | ||
2368 | { | ||
2369 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); | ||
2370 | } | ||
2371 | else if (null == id) | ||
2372 | { | ||
2373 | id = this.Core.CreateIdentifierFromFilename(headerName); | ||
2374 | } | ||
2375 | |||
2376 | this.Core.ParseForExtensionElements(node); | ||
2377 | |||
2378 | // Reference ConfigureIIs since nothing will happen without it | ||
2379 | this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureIIs"); | ||
2380 | |||
2381 | Row row = this.Core.CreateRow(sourceLineNumbers, "IIsHttpHeader", id); | ||
2382 | row[1] = (int)parentType; | ||
2383 | row[2] = parent; | ||
2384 | row[3] = headerName; | ||
2385 | row[4] = headerValue; | ||
2386 | row[5] = 0; | ||
2387 | row[6] = null; | ||
2388 | } | ||
2389 | |||
2390 | /// <summary> | ||
2391 | /// Parses a virtual directory element. | ||
2392 | /// </summary> | ||
2393 | /// <param name="node">Element to parse.</param> | ||
2394 | /// <param name="componentId">Identifier of parent component.</param> | ||
2395 | /// <param name="parentWeb">Identifier of parent web site.</param> | ||
2396 | /// <param name="parentAlias">Alias of the parent web site.</param> | ||
2397 | private void ParseWebVirtualDirElement(XElement node, string componentId, string parentWeb, string parentAlias) | ||
2398 | { | ||
2399 | SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
2400 | string id = null; | ||
2401 | string alias = null; | ||
2402 | string application = null; | ||
2403 | string directory = null; | ||
2404 | string dirProperties = null; | ||
2405 | |||
2406 | foreach (XAttribute attrib in node.Attributes()) | ||
2407 | { | ||
2408 | if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) | ||
2409 | { | ||
2410 | switch (attrib.Name.LocalName) | ||
2411 | { | ||
2412 | case "Id": | ||
2413 | id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
2414 | break; | ||
2415 | case "Alias": | ||
2416 | alias = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
2417 | break; | ||
2418 | case "Directory": | ||
2419 | directory = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
2420 | this.Core.CreateSimpleReference(sourceLineNumbers, "Directory", directory); | ||
2421 | break; | ||
2422 | case "DirProperties": | ||
2423 | dirProperties = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
2424 | break; | ||
2425 | case "WebApplication": | ||
2426 | application = this.Core.GetAttributeValue(sourceLineNumbers, attrib); | ||
2427 | break; | ||
2428 | case "WebSite": | ||
2429 | if (null != parentWeb) | ||
2430 | { | ||
2431 | this.Core.OnMessage(IIsErrors.WebSiteAttributeUnderWebSite(sourceLineNumbers, node.Name.LocalName)); | ||
2432 | } | ||
2433 | |||
2434 | parentWeb = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | ||
2435 | this.Core.CreateSimpleReference(sourceLineNumbers, "IIsWebSite", parentWeb); | ||
2436 | break; | ||
2437 | default: | ||
2438 | this.Core.UnexpectedAttribute(node, attrib); | ||
2439 | break; | ||
2440 | } | ||
2441 | } | ||
2442 | else | ||
2443 | { | ||
2444 | this.Core.ParseExtensionAttribute(node, attrib); | ||
2445 | } | ||
2446 | } | ||
2447 | |||
2448 | if (null == id) | ||
2449 | { | ||
2450 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); | ||
2451 | } | ||
2452 | |||
2453 | if (null == alias) | ||
2454 | { | ||
2455 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Alias")); | ||
2456 | } | ||
2457 | else if (-1 != alias.IndexOf("\\", StringComparison.Ordinal)) | ||
2458 | { | ||
2459 | this.Core.OnMessage(IIsErrors.IllegalCharacterInAttributeValue(sourceLineNumbers, node.Name.LocalName, "Alias", alias, '\\')); | ||
2460 | } | ||
2461 | |||
2462 | if (null == directory) | ||
2463 | { | ||
2464 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Directory")); | ||
2465 | } | ||
2466 | |||
2467 | if (null == parentWeb) | ||
2468 | { | ||
2469 | this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "WebSite")); | ||
2470 | } | ||
2471 | |||
2472 | if (null == componentId) | ||
2473 | { | ||
2474 | this.Core.OnMessage(IIsErrors.IllegalElementWithoutComponent(sourceLineNumbers, node.Name.LocalName)); | ||
2475 | } | ||
2476 | |||
2477 | if (null != parentAlias) | ||
2478 | { | ||
2479 | alias = String.Concat(parentAlias, "/", alias); | ||
2480 | } | ||
2481 | |||
2482 | foreach (XElement child in node.Elements()) | ||
2483 | { | ||
2484 | if (this.Namespace == child.Name.Namespace) | ||
2485 | { | ||
2486 | SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); | ||
2487 | switch (child.Name.LocalName) | ||
2488 | { | ||
2489 | case "WebApplication": | ||
2490 | if (null != application) | ||
2491 | { | ||
2492 | this.Core.OnMessage(IIsErrors.WebApplicationAlreadySpecified(childSourceLineNumbers, node.Name.LocalName)); | ||
2493 | } | ||
2494 | |||
2495 | application = this.ParseWebApplicationElement(child); | ||
2496 | break; | ||
2497 | case "WebDirProperties": | ||
2498 | if (null == componentId) | ||
2499 | { | ||
2500 | this.Core.OnMessage(IIsErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); | ||
2501 | } | ||
2502 | |||
2503 | string childWebDirProperties = this.ParseWebDirPropertiesElement(child); | ||
2504 | if (null == dirProperties) | ||
2505 | { | ||
2506 | dirProperties = childWebDirProperties; | ||
2507 | } | ||
2508 | else | ||
2509 | { | ||
2510 | this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, child.Name.LocalName, "DirProperties", child.Name.LocalName)); | ||
2511 | } | ||
2512 | break; | ||
2513 | |||
2514 | case "WebError": | ||
2515 | this.ParseWebErrorElement(child, WebErrorParentType.WebVirtualDir, id); | ||
2516 | break; | ||
2517 | case "WebVirtualDir": | ||
2518 | this.ParseWebVirtualDirElement(child, componentId, parentWeb, alias); | ||
2519 | break; | ||
2520 | case "HttpHeader": | ||
2521 | this.ParseHttpHeaderElement(child, HttpHeaderParentType.WebVirtualDir, id); | ||
2522 | break; | ||
2523 | case "MimeMap": | ||
2524 | this.ParseMimeMapElement(child, id, MimeMapParentType.WebVirtualDir); | ||
2525 | break; | ||
2526 | default: | ||
2527 | this.Core.UnexpectedElement(node, child); | ||
2528 | break; | ||
2529 | } | ||
2530 | } | ||
2531 | else | ||
2532 | { | ||
2533 | this.Core.ParseExtensionElement(node, child); | ||
2534 | } | ||
2535 | } | ||
2536 | |||
2537 | if (null != dirProperties) | ||
2538 | { | ||
2539 | this.Core.CreateSimpleReference(sourceLineNumbers, "IIsWebDirProperties", dirProperties); | ||
2540 | } | ||
2541 | |||
2542 | if (null != application) | ||
2543 | { | ||
2544 | this.Core.CreateSimpleReference(sourceLineNumbers, "IIsWebApplication", application); | ||
2545 | } | ||
2546 | |||
2547 | // Reference ConfigureIIs since nothing will happen without it | ||
2548 | this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "ConfigureIIs"); | ||
2549 | |||
2550 | if (!this.Core.EncounteredError) | ||
2551 | { | ||
2552 | Row row = this.Core.CreateRow(sourceLineNumbers, "IIsWebVirtualDir"); | ||
2553 | row[0] = id; | ||
2554 | row[1] = componentId; | ||
2555 | row[2] = parentWeb; | ||
2556 | row[3] = alias; | ||
2557 | row[4] = directory; | ||
2558 | row[5] = dirProperties; | ||
2559 | row[6] = application; | ||
2560 | } | ||
2561 | } | ||
2562 | } | ||
2563 | } | ||