aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core/Compiler_2.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core/Compiler_2.cs')
-rw-r--r--src/WixToolset.Core/Compiler_2.cs1465
1 files changed, 562 insertions, 903 deletions
diff --git a/src/WixToolset.Core/Compiler_2.cs b/src/WixToolset.Core/Compiler_2.cs
index 32768aca..c1c189ca 100644
--- a/src/WixToolset.Core/Compiler_2.cs
+++ b/src/WixToolset.Core/Compiler_2.cs
@@ -20,13 +20,308 @@ namespace WixToolset.Core
20 internal partial class Compiler : ICompiler 20 internal partial class Compiler : ICompiler
21 { 21 {
22 /// <summary> 22 /// <summary>
23 /// Parses a product element.
24 /// </summary>
25 /// <param name="node">Element to parse.</param>
26 private void ParseProductElement(XElement node)
27 {
28 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
29 var codepage = 65001;
30 string productCode = "*";
31 string upgradeCode = null;
32 string manufacturer = null;
33 string version = null;
34 string symbols = null;
35
36 this.activeName = null;
37 this.activeLanguage = null;
38
39 foreach (var attrib in node.Attributes())
40 {
41 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
42 {
43 switch (attrib.Name.LocalName)
44 {
45 case "Id":
46 productCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, true);
47 break;
48 case "Codepage":
49 codepage = this.Core.GetAttributeCodePageValue(sourceLineNumbers, attrib);
50 break;
51 case "Language":
52 this.activeLanguage = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, Int16.MaxValue);
53 break;
54 case "Manufacturer":
55 manufacturer = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.MustHaveNonWhitespaceCharacters);
56 if ("PUT-COMPANY-NAME-HERE" == manufacturer)
57 {
58 this.Core.Write(WarningMessages.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, manufacturer));
59 }
60 break;
61 case "Name":
62 this.activeName = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.MustHaveNonWhitespaceCharacters);
63 if ("PUT-PRODUCT-NAME-HERE" == this.activeName)
64 {
65 this.Core.Write(WarningMessages.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, this.activeName));
66 }
67 break;
68 case "UpgradeCode":
69 upgradeCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
70 break;
71 case "Version": // if the attribute is valid version, use the attribute value as is (so "1.0000.01.01" would *not* get translated to "1.0.1.1").
72 var verifiedVersion = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
73 if (!String.IsNullOrEmpty(verifiedVersion))
74 {
75 version = attrib.Value;
76 }
77 break;
78 default:
79 this.Core.UnexpectedAttribute(node, attrib);
80 break;
81 }
82 }
83 else
84 {
85 this.Core.ParseExtensionAttribute(node, attrib);
86 }
87 }
88
89 if (null == productCode)
90 {
91 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
92 }
93
94 if (null == this.activeLanguage)
95 {
96 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Language"));
97 }
98
99 if (null == manufacturer)
100 {
101 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Manufacturer"));
102 }
103
104 if (null == this.activeName)
105 {
106 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
107 }
108
109 if (null == upgradeCode)
110 {
111 this.Core.Write(WarningMessages.MissingUpgradeCode(sourceLineNumbers));
112 }
113
114 if (null == version)
115 {
116 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version"));
117 }
118 else if (!CompilerCore.IsValidProductVersion(version))
119 {
120 this.Core.Write(ErrorMessages.InvalidProductVersion(sourceLineNumbers, version));
121 }
122
123 if (this.Core.EncounteredError)
124 {
125 return;
126 }
127
128 try
129 {
130 this.compilingProduct = true;
131 this.Core.CreateActiveSection(productCode, SectionType.Product, codepage, this.Context.CompilationId);
132
133 this.AddProperty(sourceLineNumbers, new Identifier(AccessModifier.Public, "Manufacturer"), manufacturer, false, false, false, true);
134 this.AddProperty(sourceLineNumbers, new Identifier(AccessModifier.Public, "ProductCode"), productCode, false, false, false, true);
135 this.AddProperty(sourceLineNumbers, new Identifier(AccessModifier.Public, "ProductLanguage"), this.activeLanguage, false, false, false, true);
136 this.AddProperty(sourceLineNumbers, new Identifier(AccessModifier.Public, "ProductName"), this.activeName, false, false, false, true);
137 this.AddProperty(sourceLineNumbers, new Identifier(AccessModifier.Public, "ProductVersion"), version, false, false, false, true);
138 if (null != upgradeCode)
139 {
140 this.AddProperty(sourceLineNumbers, new Identifier(AccessModifier.Public, "UpgradeCode"), upgradeCode, false, false, false, true);
141 }
142
143 var contextValues = new Dictionary<string, string>
144 {
145 ["ProductLanguage"] = this.activeLanguage,
146 ["ProductVersion"] = version,
147 ["UpgradeCode"] = upgradeCode
148 };
149
150 var featureDisplay = 0;
151 foreach (var child in node.Elements())
152 {
153 if (CompilerCore.WixNamespace == child.Name.Namespace)
154 {
155 switch (child.Name.LocalName)
156 {
157 case "_locDefinition":
158 break;
159 case "AdminExecuteSequence":
160 this.ParseSequenceElement(child, SequenceTable.AdminExecuteSequence);
161 break;
162 case "AdminUISequence":
163 this.ParseSequenceElement(child, SequenceTable.AdminUISequence);
164 break;
165 case "AdvertiseExecuteSequence":
166 this.ParseSequenceElement(child, SequenceTable.AdvertiseExecuteSequence);
167 break;
168 case "InstallExecuteSequence":
169 this.ParseSequenceElement(child, SequenceTable.InstallExecuteSequence);
170 break;
171 case "InstallUISequence":
172 this.ParseSequenceElement(child, SequenceTable.InstallUISequence);
173 break;
174 case "AppId":
175 this.ParseAppIdElement(child, null, YesNoType.Yes, null, null, null);
176 break;
177 case "Binary":
178 this.ParseBinaryElement(child);
179 break;
180 case "ComplianceCheck":
181 this.ParseComplianceCheckElement(child);
182 break;
183 case "Component":
184 this.ParseComponentElement(child, ComplexReferenceParentType.Unknown, null, null, CompilerConstants.IntegerNotSet, null, null);
185 break;
186 case "ComponentGroup":
187 this.ParseComponentGroupElement(child, ComplexReferenceParentType.Unknown, null);
188 break;
189 case "Condition":
190 this.ParseConditionElement(child, node.Name.LocalName, null, null);
191 break;
192 case "CustomAction":
193 this.ParseCustomActionElement(child);
194 break;
195 case "CustomActionRef":
196 this.ParseSimpleRefElement(child, "CustomAction");
197 break;
198 case "CustomTable":
199 this.ParseCustomTableElement(child);
200 break;
201 case "Directory":
202 this.ParseDirectoryElement(child, null, CompilerConstants.IntegerNotSet, String.Empty);
203 break;
204 case "DirectoryRef":
205 this.ParseDirectoryRefElement(child);
206 break;
207 case "EmbeddedChainer":
208 this.ParseEmbeddedChainerElement(child);
209 break;
210 case "EmbeddedChainerRef":
211 this.ParseSimpleRefElement(child, "MsiEmbeddedChainer");
212 break;
213 case "EnsureTable":
214 this.ParseEnsureTableElement(child);
215 break;
216 case "Feature":
217 this.ParseFeatureElement(child, ComplexReferenceParentType.Product, productCode, ref featureDisplay);
218 break;
219 case "FeatureRef":
220 this.ParseFeatureRefElement(child, ComplexReferenceParentType.Product, productCode);
221 break;
222 case "FeatureGroupRef":
223 this.ParseFeatureGroupRefElement(child, ComplexReferenceParentType.Product, productCode);
224 break;
225 case "Icon":
226 this.ParseIconElement(child);
227 break;
228 case "InstanceTransforms":
229 this.ParseInstanceTransformsElement(child);
230 break;
231 case "MajorUpgrade":
232 this.ParseMajorUpgradeElement(child, contextValues);
233 break;
234 case "Media":
235 this.ParseMediaElement(child, null);
236 break;
237 case "MediaTemplate":
238 this.ParseMediaTemplateElement(child, null);
239 break;
240 case "Package":
241 this.ParsePackageElement(child, manufacturer, null);
242 break;
243 case "PackageCertificates":
244 case "PatchCertificates":
245 this.ParseCertificatesElement(child);
246 break;
247 case "Property":
248 this.ParsePropertyElement(child);
249 break;
250 case "PropertyRef":
251 this.ParseSimpleRefElement(child, "Property");
252 break;
253 case "SetDirectory":
254 this.ParseSetDirectoryElement(child);
255 break;
256 case "SetProperty":
257 this.ParseSetPropertyElement(child);
258 break;
259 case "SFPCatalog":
260 string parentName = null;
261 this.ParseSFPCatalogElement(child, ref parentName);
262 break;
263 case "SymbolPath":
264 if (null != symbols)
265 {
266 symbols += ";" + this.ParseSymbolPathElement(child);
267 }
268 else
269 {
270 symbols = this.ParseSymbolPathElement(child);
271 }
272 break;
273 case "UI":
274 this.ParseUIElement(child);
275 break;
276 case "UIRef":
277 this.ParseSimpleRefElement(child, "WixUI");
278 break;
279 case "Upgrade":
280 this.ParseUpgradeElement(child);
281 break;
282 case "WixVariable":
283 this.ParseWixVariableElement(child);
284 break;
285 default:
286 this.Core.UnexpectedElement(node, child);
287 break;
288 }
289 }
290 else
291 {
292 this.Core.ParseExtensionElement(node, child);
293 }
294 }
295
296 if (!this.Core.EncounteredError)
297 {
298 if (null != symbols)
299 {
300 var tuple = new WixDeltaPatchSymbolPathsTuple(sourceLineNumbers)
301 {
302 SymbolId = productCode,
303 SymbolType = SymbolPathType.Product,
304 SymbolPaths = symbols
305 };
306
307 this.Core.AddTuple(tuple);
308 }
309 }
310 }
311 finally
312 {
313 this.compilingProduct = false;
314 }
315 }
316
317 /// <summary>
23 /// Parses an odbc driver or translator element. 318 /// Parses an odbc driver or translator element.
24 /// </summary> 319 /// </summary>
25 /// <param name="node">Element to parse.</param> 320 /// <param name="node">Element to parse.</param>
26 /// <param name="componentId">Identifier of parent component.</param> 321 /// <param name="componentId">Identifier of parent component.</param>
27 /// <param name="fileId">Default identifer for driver/translator file.</param> 322 /// <param name="fileId">Default identifer for driver/translator file.</param>
28 /// <param name="table">Table we're processing for.</param> 323 /// <param name="tupleDefinitionType">Tuple type we're processing for.</param>
29 private void ParseODBCDriverOrTranslator(XElement node, string componentId, string fileId, TupleDefinitionType tableName) 324 private void ParseODBCDriverOrTranslator(XElement node, string componentId, string fileId, TupleDefinitionType tupleDefinitionType)
30 { 325 {
31 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 326 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
32 Identifier id = null; 327 Identifier id = null;
@@ -76,7 +371,7 @@ namespace WixToolset.Core
76 } 371 }
77 372
78 // drivers have a few possible children 373 // drivers have a few possible children
79 if (TupleDefinitionType.ODBCDriver == tableName) 374 if (TupleDefinitionType.ODBCDriver == tupleDefinitionType)
80 { 375 {
81 // process any data sources for the driver 376 // process any data sources for the driver
82 foreach (var child in node.Elements()) 377 foreach (var child in node.Elements())
@@ -110,11 +405,11 @@ namespace WixToolset.Core
110 405
111 if (!this.Core.EncounteredError) 406 if (!this.Core.EncounteredError)
112 { 407 {
113 var row = this.Core.CreateRow(sourceLineNumbers, tableName, id); 408 var tuple = this.Core.CreateTuple(sourceLineNumbers, tupleDefinitionType, id);
114 row.Set(1, componentId); 409 tuple.Set(1, componentId);
115 row.Set(2, name); 410 tuple.Set(2, name);
116 row.Set(3, driver); 411 tuple.Set(3, driver);
117 row.Set(4, setup); 412 tuple.Set(4, setup);
118 } 413 }
119 } 414 }
120 415
@@ -123,8 +418,8 @@ namespace WixToolset.Core
123 /// </summary> 418 /// </summary>
124 /// <param name="node">Element to parse.</param> 419 /// <param name="node">Element to parse.</param>
125 /// <param name="parentId">Identifier of parent driver or translator.</param> 420 /// <param name="parentId">Identifier of parent driver or translator.</param>
126 /// <param name="tableName">Name of the table to create property in.</param> 421 /// <param name="tupleDefinitionType">Name of the table to create property in.</param>
127 private void ParseODBCProperty(XElement node, string parentId, TupleDefinitionType tableName) 422 private void ParseODBCProperty(XElement node, string parentId, TupleDefinitionType tupleDefinitionType)
128 { 423 {
129 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 424 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
130 string id = null; 425 string id = null;
@@ -162,10 +457,10 @@ namespace WixToolset.Core
162 457
163 if (!this.Core.EncounteredError) 458 if (!this.Core.EncounteredError)
164 { 459 {
165 var row = this.Core.CreateRow(sourceLineNumbers, tableName); 460 var tuple = this.Core.CreateTuple(sourceLineNumbers, tupleDefinitionType, new Identifier(AccessModifier.Private, parentId, id));
166 row.Set(0, parentId); 461 tuple.Set(0, parentId);
167 row.Set(1, id); 462 tuple.Set(1, id);
168 row.Set(2, propertyValue); 463 tuple.Set(2, propertyValue);
169 } 464 }
170 } 465 }
171 466
@@ -264,11 +559,13 @@ namespace WixToolset.Core
264 559
265 if (!this.Core.EncounteredError) 560 if (!this.Core.EncounteredError)
266 { 561 {
267 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ODBCDataSource, id); 562 this.Core.AddTuple(new ODBCDataSourceTuple(sourceLineNumbers, id)
268 row.Set(1, componentId); 563 {
269 row.Set(2, name); 564 Component_ = componentId,
270 row.Set(3, driverName); 565 Description = name,
271 row.Set(4, registration); 566 DriverDescription = driverName,
567 Registration = registration
568 });
272 } 569 }
273 570
274 possibleKeyPath = id.Id; 571 possibleKeyPath = id.Id;
@@ -296,7 +593,6 @@ namespace WixToolset.Core
296 string platformValue = null; 593 string platformValue = null;
297 var security = YesNoDefaultType.Default; 594 var security = YesNoDefaultType.Default;
298 var sourceBits = (this.compilingModule ? 2 : 0); 595 var sourceBits = (this.compilingModule ? 2 : 0);
299 IntermediateTuple row;
300 var installPrivilegeSeen = false; 596 var installPrivilegeSeen = false;
301 var installScopeSeen = false; 597 var installScopeSeen = false;
302 598
@@ -333,7 +629,7 @@ namespace WixToolset.Core
333 case "AdminImage": 629 case "AdminImage":
334 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 630 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
335 { 631 {
336 sourceBits = sourceBits | 4; 632 sourceBits |= 4;
337 } 633 }
338 break; 634 break;
339 case "Comments": 635 case "Comments":
@@ -348,7 +644,7 @@ namespace WixToolset.Core
348 } 644 }
349 else if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 645 else if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
350 { 646 {
351 sourceBits = sourceBits | 2; 647 sourceBits |= 2;
352 } 648 }
353 break; 649 break;
354 case "Description": 650 case "Description":
@@ -363,7 +659,7 @@ namespace WixToolset.Core
363 installPrivilegeSeen = true; 659 installPrivilegeSeen = true;
364 break; 660 break;
365 case "limited": 661 case "limited":
366 sourceBits = sourceBits | 8; 662 sourceBits |= 8;
367 installPrivilegeSeen = true; 663 installPrivilegeSeen = true;
368 break; 664 break;
369 case "": 665 case "":
@@ -379,13 +675,15 @@ namespace WixToolset.Core
379 { 675 {
380 case "perMachine": 676 case "perMachine":
381 { 677 {
382 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Property, new Identifier("ALLUSERS", AccessModifier.Public)); 678 this.Core.AddTuple(new PropertyTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "ALLUSERS"))
383 row.Set(1, "1"); 679 {
680 Value = "1"
681 });
384 installScopeSeen = true; 682 installScopeSeen = true;
385 } 683 }
386 break; 684 break;
387 case "perUser": 685 case "perUser":
388 sourceBits = sourceBits | 8; 686 sourceBits |= 8;
389 installScopeSeen = true; 687 installScopeSeen = true;
390 break; 688 break;
391 case "": 689 case "":
@@ -461,7 +759,7 @@ namespace WixToolset.Core
461 case "ShortNames": 759 case "ShortNames":
462 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 760 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
463 { 761 {
464 sourceBits = sourceBits | 1; 762 sourceBits |= 1;
465 this.useShortFileNames = true; 763 this.useShortFileNames = true;
466 } 764 }
467 break; 765 break;
@@ -534,380 +832,75 @@ namespace WixToolset.Core
534 832
535 if (!this.Core.EncounteredError) 833 if (!this.Core.EncounteredError)
536 { 834 {
537 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation); 835 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
538 row.Set(0, 1);
539 row.Set(1, codepage);
540
541 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
542 row.Set(0, 2);
543 row.Set(1, "Installation Database");
544
545 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
546 row.Set(0, 3);
547 row.Set(1, packageName);
548
549 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
550 row.Set(0, 4);
551 row.Set(1, packageAuthor);
552
553 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
554 row.Set(0, 5);
555 row.Set(1, keywords);
556
557 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
558 row.Set(0, 6);
559 row.Set(1, comments);
560
561 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
562 row.Set(0, 7);
563 row.Set(1, String.Format(CultureInfo.InvariantCulture, "{0};{1}", platform, packageLanguages));
564
565 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
566 row.Set(0, 9);
567 row.Set(1, packageCode);
568
569 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
570 row.Set(0, 14);
571 row.Set(1, msiVersion.ToString(CultureInfo.InvariantCulture));
572
573 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
574 row.Set(0, 15);
575 row.Set(1, sourceBits.ToString(CultureInfo.InvariantCulture));
576
577 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
578 row.Set(0, 19);
579 switch (security)
580 {
581 case YesNoDefaultType.No: // no restriction
582 row.Set(1, "0");
583 break;
584 case YesNoDefaultType.Default: // read-only recommended
585 row.Set(1, "2");
586 break;
587 case YesNoDefaultType.Yes: // read-only enforced
588 row.Set(1, "4");
589 break;
590 }
591 }
592 }
593
594 /// <summary>
595 /// Parses a patch metadata element.
596 /// </summary>
597 /// <param name="node">Element to parse.</param>
598 private void ParsePatchMetadataElement(XElement node)
599 {
600 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
601 var allowRemoval = YesNoType.NotSet;
602 string classification = null;
603 string creationTimeUtc = null;
604 string description = null;
605 string displayName = null;
606 string manufacturerName = null;
607 string minorUpdateTargetRTM = null;
608 string moreInfoUrl = null;
609 var optimizeCA = CompilerConstants.IntegerNotSet;
610 var optimizedInstallMode = YesNoType.NotSet;
611 string targetProductName = null;
612
613 foreach (var attrib in node.Attributes())
614 {
615 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
616 {
617 switch (attrib.Name.LocalName)
618 {
619 case "AllowRemoval":
620 allowRemoval = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
621 break;
622 case "Classification":
623 classification = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
624 break;
625 case "CreationTimeUTC":
626 creationTimeUtc = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
627 break;
628 case "Description":
629 description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
630 break;
631 case "DisplayName":
632 displayName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
633 break;
634 case "ManufacturerName":
635 manufacturerName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
636 break;
637 case "MinorUpdateTargetRTM":
638 minorUpdateTargetRTM = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
639 break;
640 case "MoreInfoURL":
641 moreInfoUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
642 break;
643 case "OptimizedInstallMode":
644 optimizedInstallMode = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
645 break;
646 case "TargetProductName":
647 targetProductName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
648 break;
649 default:
650 this.Core.UnexpectedAttribute(node, attrib);
651 break;
652 }
653 }
654 else
655 {
656 this.Core.ParseExtensionAttribute(node, attrib);
657 }
658 }
659
660 if (YesNoType.NotSet == allowRemoval)
661 {
662 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "AllowRemoval"));
663 }
664
665 if (null == classification)
666 {
667 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Classification"));
668 }
669
670 if (null == description)
671 {
672 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Description"));
673 }
674
675 if (null == displayName)
676 {
677 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DisplayName"));
678 }
679
680 if (null == manufacturerName)
681 {
682 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ManufacturerName"));
683 }
684
685 if (null == moreInfoUrl)
686 {
687 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "MoreInfoURL"));
688 }
689
690 if (null == targetProductName)
691 {
692 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "TargetProductName"));
693 }
694
695 foreach (var child in node.Elements())
696 {
697 if (CompilerCore.WixNamespace == child.Name.Namespace)
698 {
699 switch (child.Name.LocalName)
700 {
701 case "CustomProperty":
702 this.ParseCustomPropertyElement(child);
703 break;
704 case "OptimizeCustomActions":
705 optimizeCA = this.ParseOptimizeCustomActionsElement(child);
706 break;
707 default:
708 this.Core.UnexpectedElement(node, child);
709 break;
710 }
711 }
712 else
713 {
714 this.Core.ParseExtensionElement(node, child);
715 }
716 }
717
718 if (!this.Core.EncounteredError)
719 {
720 if (YesNoType.NotSet != allowRemoval)
721 { 836 {
722 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata); 837 PropertyId = SumaryInformationType.Codepage,
723 row.Set(1, "AllowRemoval"); 838 Value = codepage
724 row.Set(2, YesNoType.Yes == allowRemoval ? "1" : "0"); 839 });
725 }
726 840
727 if (null != classification) 841 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
728 { 842 {
729 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata); 843 PropertyId = SumaryInformationType.Title,
730 row.Set(1, "Classification"); 844 Value = "Installation Database"
731 row.Set(2, classification); 845 });
732 }
733 846
734 if (null != creationTimeUtc) 847 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
735 { 848 {
736 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata); 849 PropertyId = SumaryInformationType.Subject,
737 row.Set(1, "CreationTimeUTC"); 850 Value = packageName
738 row.Set(2, creationTimeUtc); 851 });
739 }
740 852
741 if (null != description) 853 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
742 { 854 {
743 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata); 855 PropertyId = SumaryInformationType.Author,
744 row.Set(1, "Description"); 856 Value = packageAuthor
745 row.Set(2, description); 857 });
746 }
747 858
748 if (null != displayName) 859 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
749 { 860 {
750 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata); 861 PropertyId = SumaryInformationType.Keywords,
751 row.Set(1, "DisplayName"); 862 Value = keywords
752 row.Set(2, displayName); 863 });
753 }
754 864
755 if (null != manufacturerName) 865 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
756 { 866 {
757 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata); 867 PropertyId = SumaryInformationType.Comments,
758 row.Set(1, "ManufacturerName"); 868 Value = comments
759 row.Set(2, manufacturerName); 869 });
760 }
761 870
762 if (null != minorUpdateTargetRTM) 871 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
763 { 872 {
764 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata); 873 PropertyId = SumaryInformationType.PlatformAndLanguage,
765 row.Set(1, "MinorUpdateTargetRTM"); 874 Value = String.Format(CultureInfo.InvariantCulture, "{0};{1}", platform, packageLanguages)
766 row.Set(2, minorUpdateTargetRTM); 875 });
767 }
768 876
769 if (null != moreInfoUrl) 877 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
770 { 878 {
771 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata); 879 PropertyId = SumaryInformationType.PackageCode,
772 row.Set(1, "MoreInfoURL"); 880 Value = packageCode
773 row.Set(2, moreInfoUrl); 881 });
774 }
775 882
776 if (CompilerConstants.IntegerNotSet != optimizeCA) 883 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
777 { 884 {
778 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata); 885 PropertyId = SumaryInformationType.WindowsInstallerVersion,
779 row.Set(1, "OptimizeCA"); 886 Value = msiVersion.ToString(CultureInfo.InvariantCulture)
780 row.Set(2, optimizeCA.ToString(CultureInfo.InvariantCulture)); 887 });
781 }
782 888
783 if (YesNoType.NotSet != optimizedInstallMode) 889 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
784 { 890 {
785 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata); 891 PropertyId = SumaryInformationType.WordCount,
786 row.Set(1, "OptimizedInstallMode"); 892 Value = sourceBits.ToString(CultureInfo.InvariantCulture)
787 row.Set(2, YesNoType.Yes == optimizedInstallMode ? "1" : "0"); 893 });
788 }
789 894
790 if (null != targetProductName) 895 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
791 { 896 {
792 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata); 897 PropertyId = SumaryInformationType.Security,
793 row.Set(1, "TargetProductName"); 898 Value = YesNoDefaultType.No == security ? "0" : YesNoDefaultType.Yes == security ? "4" : "2"
794 row.Set(2, targetProductName); 899 });
795 }
796 } 900 }
797 } 901 }
798 902
799 /// <summary> 903 /// <summary>
800 /// Parses a custom property element for the PatchMetadata table.
801 /// </summary>
802 /// <param name="node">Element to parse.</param>
803 private void ParseCustomPropertyElement(XElement node)
804 {
805 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
806 string company = null;
807 string property = null;
808 string value = null;
809
810 foreach (var attrib in node.Attributes())
811 {
812 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
813 {
814 switch (attrib.Name.LocalName)
815 {
816 case "Company":
817 company = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
818 break;
819 case "Property":
820 property = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
821 break;
822 case "Value":
823 value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
824 break;
825 default:
826 this.Core.UnexpectedAttribute(node, attrib);
827 break;
828 }
829 }
830 else
831 {
832 this.Core.ParseExtensionAttribute(node, attrib);
833 }
834 }
835
836 if (null == company)
837 {
838 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Company"));
839 }
840
841 if (null == property)
842 {
843 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Property"));
844 }
845
846 if (null == value)
847 {
848 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
849 }
850
851 this.Core.ParseForExtensionElements(node);
852
853 if (!this.Core.EncounteredError)
854 {
855 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
856 row.Set(0, company);
857 row.Set(1, property);
858 row.Set(2, value);
859 }
860 }
861
862 /// <summary>
863 /// Parses the OptimizeCustomActions element.
864 /// </summary>
865 /// <param name="node">Element to parse.</param>
866 /// <returns>The combined integer value for callers to store as appropriate.</returns>
867 private int ParseOptimizeCustomActionsElement(XElement node)
868 {
869 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
870 var optimizeCA = OptimizeCA.None;
871
872 foreach (var attrib in node.Attributes())
873 {
874 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
875 {
876 switch (attrib.Name.LocalName)
877 {
878 case "SkipAssignment":
879 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
880 {
881 optimizeCA |= OptimizeCA.SkipAssignment;
882 }
883 break;
884 case "SkipImmediate":
885 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
886 {
887 optimizeCA |= OptimizeCA.SkipImmediate;
888 }
889 break;
890 case "SkipDeferred":
891 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
892 {
893 optimizeCA |= OptimizeCA.SkipDeferred;
894 }
895 break;
896 default:
897 this.Core.UnexpectedAttribute(node, attrib);
898 break;
899 }
900 }
901 else
902 {
903 this.Core.ParseExtensionAttribute(node, attrib);
904 }
905 }
906
907 return (int)optimizeCA;
908 }
909
910 /// <summary>
911 /// Parses a patch information element. 904 /// Parses a patch information element.
912 /// </summary> 905 /// </summary>
913 /// <param name="node">Element to parse.</param> 906 /// <param name="node">Element to parse.</param>
@@ -976,73 +969,77 @@ namespace WixToolset.Core
976 969
977 if (!this.Core.EncounteredError) 970 if (!this.Core.EncounteredError)
978 { 971 {
979 // PID_CODEPAGE 972 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
980 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation); 973 {
981 row.Set(0, 1); 974 PropertyId = SumaryInformationType.Codepage,
982 row.Set(1, codepage); 975 Value = codepage
976 });
983 977
984 // PID_TITLE 978 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
985 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation); 979 {
986 row.Set(0, 2); 980 PropertyId = SumaryInformationType.Title,
987 row.Set(1, "Patch"); 981 Value = "Patch"
982 });
988 983
989 // PID_SUBJECT
990 if (null != packageName) 984 if (null != packageName)
991 { 985 {
992 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation); 986 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
993 row.Set(0, 3); 987 {
994 row.Set(1, packageName); 988 PropertyId = SumaryInformationType.Subject,
989 Value = packageName
990 });
995 } 991 }
996 992
997 // PID_AUTHOR
998 if (null != packageAuthor) 993 if (null != packageAuthor)
999 { 994 {
1000 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation); 995 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
1001 row.Set(0, 4); 996 {
1002 row.Set(1, packageAuthor); 997 PropertyId = SumaryInformationType.Author,
998 Value = packageAuthor
999 });
1003 } 1000 }
1004 1001
1005 // PID_KEYWORDS
1006 if (null != keywords) 1002 if (null != keywords)
1007 { 1003 {
1008 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation); 1004 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
1009 row.Set(0, 5); 1005 {
1010 row.Set(1, keywords); 1006 PropertyId = SumaryInformationType.Keywords,
1007 Value = keywords
1008 });
1011 } 1009 }
1012 1010
1013 // PID_COMMENTS
1014 if (null != comments) 1011 if (null != comments)
1015 { 1012 {
1016 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation); 1013 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
1017 row.Set(0, 6); 1014 {
1018 row.Set(1, comments); 1015 PropertyId = SumaryInformationType.Comments,
1016 Value = comments
1017 });
1019 } 1018 }
1020 1019
1021 // PID_PAGECOUNT 1020 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
1022 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation); 1021 {
1023 row.Set(0, 14); 1022 PropertyId = SumaryInformationType.WindowsInstallerVersion,
1024 row.Set(1, msiVersion.ToString(CultureInfo.InvariantCulture)); 1023 Value = msiVersion.ToString(CultureInfo.InvariantCulture)
1024 });
1025
1026 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
1027 {
1028 PropertyId = SumaryInformationType.WordCount,
1029 Value = "0"
1030 });
1025 1031
1026 // PID_WORDCOUNT 1032 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
1027 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation); 1033 {
1028 row.Set(0, 15); 1034 PropertyId = SumaryInformationType.WindowsInstallerVersion,
1029 row.Set(1, "0"); 1035 Value = msiVersion.ToString(CultureInfo.InvariantCulture)
1036 });
1030 1037
1031 // PID_SECURITY 1038 this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
1032 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
1033 row.Set(0, 19);
1034 switch (security)
1035 { 1039 {
1036 case YesNoDefaultType.No: // no restriction 1040 PropertyId = SumaryInformationType.Security,
1037 row.Set(1, "0"); 1041 Value = YesNoDefaultType.No == security ? "0" : YesNoDefaultType.Yes == security ? "4" : "2"
1038 break; 1042 });
1039 case YesNoDefaultType.Default: // read-only recommended
1040 row.Set(1, "2");
1041 break;
1042 case YesNoDefaultType.Yes: // read-only enforced
1043 row.Set(1, "4");
1044 break;
1045 }
1046 } 1043 }
1047 } 1044 }
1048 1045
@@ -1135,12 +1132,14 @@ namespace WixToolset.Core
1135 1132
1136 if (!this.Core.EncounteredError) 1133 if (!this.Core.EncounteredError)
1137 { 1134 {
1138 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.LockPermissions); 1135 this.Core.AddTuple(new LockPermissionsTuple(sourceLineNumbers)
1139 row.Set(0, objectId); 1136 {
1140 row.Set(1, tableName); 1137 LockObject = objectId,
1141 row.Set(2, domain); 1138 Table = tableName,
1142 row.Set(3, user); 1139 Domain = domain,
1143 row.Set(4, permission); 1140 User = user,
1141 Permission = permission
1142 });
1144 } 1143 }
1145 } 1144 }
1146 1145
@@ -1230,295 +1229,13 @@ namespace WixToolset.Core
1230 1229
1231 if (!this.Core.EncounteredError) 1230 if (!this.Core.EncounteredError)
1232 { 1231 {
1233 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiLockPermissionsEx, id); 1232 this.Core.AddTuple(new MsiLockPermissionsExTuple(sourceLineNumbers, id)
1234 row.Set(1, objectId);
1235 row.Set(2, tableName);
1236 row.Set(3, sddl);
1237 row.Set(4, condition);
1238 }
1239 }
1240
1241 /// <summary>
1242 /// Parses a product element.
1243 /// </summary>
1244 /// <param name="node">Element to parse.</param>
1245 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
1246 private void ParseProductElement(XElement node)
1247 {
1248 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1249 var codepage = 65001;
1250 string productCode = "*";
1251 string upgradeCode = null;
1252 string manufacturer = null;
1253 string version = null;
1254 string symbols = null;
1255
1256 this.activeName = null;
1257 this.activeLanguage = null;
1258
1259 foreach (var attrib in node.Attributes())
1260 {
1261 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
1262 {
1263 switch (attrib.Name.LocalName)
1264 {
1265 case "Id":
1266 productCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, true);
1267 break;
1268 case "Codepage":
1269 codepage = this.Core.GetAttributeCodePageValue(sourceLineNumbers, attrib);
1270 break;
1271 case "Language":
1272 this.activeLanguage = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, Int16.MaxValue);
1273 break;
1274 case "Manufacturer":
1275 manufacturer = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.MustHaveNonWhitespaceCharacters);
1276 if ("PUT-COMPANY-NAME-HERE" == manufacturer)
1277 {
1278 this.Core.Write(WarningMessages.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, manufacturer));
1279 }
1280 break;
1281 case "Name":
1282 this.activeName = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.MustHaveNonWhitespaceCharacters);
1283 if ("PUT-PRODUCT-NAME-HERE" == this.activeName)
1284 {
1285 this.Core.Write(WarningMessages.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, this.activeName));
1286 }
1287 break;
1288 case "UpgradeCode":
1289 upgradeCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
1290 break;
1291 case "Version": // if the attribute is valid version, use the attribute value as is (so "1.0000.01.01" would *not* get translated to "1.0.1.1").
1292 var verifiedVersion = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
1293 if (!String.IsNullOrEmpty(verifiedVersion))
1294 {
1295 version = attrib.Value;
1296 }
1297 break;
1298 default:
1299 this.Core.UnexpectedAttribute(node, attrib);
1300 break;
1301 }
1302 }
1303 else
1304 {
1305 this.Core.ParseExtensionAttribute(node, attrib);
1306 }
1307 }
1308
1309 if (null == productCode)
1310 {
1311 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
1312 }
1313
1314 if (null == this.activeLanguage)
1315 {
1316 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Language"));
1317 }
1318
1319 if (null == manufacturer)
1320 {
1321 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Manufacturer"));
1322 }
1323
1324 if (null == this.activeName)
1325 {
1326 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
1327 }
1328
1329 if (null == upgradeCode)
1330 {
1331 this.Core.Write(WarningMessages.MissingUpgradeCode(sourceLineNumbers));
1332 }
1333
1334 if (null == version)
1335 {
1336 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version"));
1337 }
1338 else if (!CompilerCore.IsValidProductVersion(version))
1339 {
1340 this.Core.Write(ErrorMessages.InvalidProductVersion(sourceLineNumbers, version));
1341 }
1342
1343 if (this.Core.EncounteredError)
1344 {
1345 return;
1346 }
1347
1348 try
1349 {
1350 this.compilingProduct = true;
1351 this.Core.CreateActiveSection(productCode, SectionType.Product, codepage, this.Context.CompilationId);
1352
1353 this.AddProperty(sourceLineNumbers, new Identifier("Manufacturer", AccessModifier.Public), manufacturer, false, false, false, true);
1354 this.AddProperty(sourceLineNumbers, new Identifier("ProductCode", AccessModifier.Public), productCode, false, false, false, true);
1355 this.AddProperty(sourceLineNumbers, new Identifier("ProductLanguage", AccessModifier.Public), this.activeLanguage, false, false, false, true);
1356 this.AddProperty(sourceLineNumbers, new Identifier("ProductName", AccessModifier.Public), this.activeName, false, false, false, true);
1357 this.AddProperty(sourceLineNumbers, new Identifier("ProductVersion", AccessModifier.Public), version, false, false, false, true);
1358 if (null != upgradeCode)
1359 {
1360 this.AddProperty(sourceLineNumbers, new Identifier("UpgradeCode", AccessModifier.Public), upgradeCode, false, false, false, true);
1361 }
1362
1363 var contextValues = new Dictionary<string, string>
1364 {
1365 ["ProductLanguage"] = this.activeLanguage,
1366 ["ProductVersion"] = version,
1367 ["UpgradeCode"] = upgradeCode
1368 };
1369
1370 var featureDisplay = 0;
1371 foreach (var child in node.Elements())
1372 {
1373 if (CompilerCore.WixNamespace == child.Name.Namespace)
1374 {
1375 switch (child.Name.LocalName)
1376 {
1377 case "_locDefinition":
1378 break;
1379 case "AdminExecuteSequence":
1380 case "AdminUISequence":
1381 case "AdvertiseExecuteSequence":
1382 case "InstallExecuteSequence":
1383 case "InstallUISequence":
1384 this.ParseSequenceElement(child, child.Name.LocalName);
1385 break;
1386 case "AppId":
1387 this.ParseAppIdElement(child, null, YesNoType.Yes, null, null, null);
1388 break;
1389 case "Binary":
1390 this.ParseBinaryElement(child);
1391 break;
1392 case "ComplianceCheck":
1393 this.ParseComplianceCheckElement(child);
1394 break;
1395 case "Component":
1396 this.ParseComponentElement(child, ComplexReferenceParentType.Unknown, null, null, CompilerConstants.IntegerNotSet, null, null);
1397 break;
1398 case "ComponentGroup":
1399 this.ParseComponentGroupElement(child, ComplexReferenceParentType.Unknown, null);
1400 break;
1401 case "Condition":
1402 this.ParseConditionElement(child, node.Name.LocalName, null, null);
1403 break;
1404 case "CustomAction":
1405 this.ParseCustomActionElement(child);
1406 break;
1407 case "CustomActionRef":
1408 this.ParseSimpleRefElement(child, "CustomAction");
1409 break;
1410 case "CustomTable":
1411 this.ParseCustomTableElement(child);
1412 break;
1413 case "Directory":
1414 this.ParseDirectoryElement(child, null, CompilerConstants.IntegerNotSet, String.Empty);
1415 break;
1416 case "DirectoryRef":
1417 this.ParseDirectoryRefElement(child);
1418 break;
1419 case "EmbeddedChainer":
1420 this.ParseEmbeddedChainerElement(child);
1421 break;
1422 case "EmbeddedChainerRef":
1423 this.ParseSimpleRefElement(child, "MsiEmbeddedChainer");
1424 break;
1425 case "EnsureTable":
1426 this.ParseEnsureTableElement(child);
1427 break;
1428 case "Feature":
1429 this.ParseFeatureElement(child, ComplexReferenceParentType.Product, productCode, ref featureDisplay);
1430 break;
1431 case "FeatureRef":
1432 this.ParseFeatureRefElement(child, ComplexReferenceParentType.Product, productCode);
1433 break;
1434 case "FeatureGroupRef":
1435 this.ParseFeatureGroupRefElement(child, ComplexReferenceParentType.Product, productCode);
1436 break;
1437 case "Icon":
1438 this.ParseIconElement(child);
1439 break;
1440 case "InstanceTransforms":
1441 this.ParseInstanceTransformsElement(child);
1442 break;
1443 case "MajorUpgrade":
1444 this.ParseMajorUpgradeElement(child, contextValues);
1445 break;
1446 case "Media":
1447 this.ParseMediaElement(child, null);
1448 break;
1449 case "MediaTemplate":
1450 this.ParseMediaTemplateElement(child, null);
1451 break;
1452 case "Package":
1453 this.ParsePackageElement(child, manufacturer, null);
1454 break;
1455 case "PackageCertificates":
1456 case "PatchCertificates":
1457 this.ParseCertificatesElement(child);
1458 break;
1459 case "Property":
1460 this.ParsePropertyElement(child);
1461 break;
1462 case "PropertyRef":
1463 this.ParseSimpleRefElement(child, "Property");
1464 break;
1465 case "SetDirectory":
1466 this.ParseSetDirectoryElement(child);
1467 break;
1468 case "SetProperty":
1469 this.ParseSetPropertyElement(child);
1470 break;
1471 case "SFPCatalog":
1472 string parentName = null;
1473 this.ParseSFPCatalogElement(child, ref parentName);
1474 break;
1475 case "SymbolPath":
1476 if (null != symbols)
1477 {
1478 symbols += ";" + this.ParseSymbolPathElement(child);
1479 }
1480 else
1481 {
1482 symbols = this.ParseSymbolPathElement(child);
1483 }
1484 break;
1485 case "UI":
1486 this.ParseUIElement(child);
1487 break;
1488 case "UIRef":
1489 this.ParseSimpleRefElement(child, "WixUI");
1490 break;
1491 case "Upgrade":
1492 this.ParseUpgradeElement(child);
1493 break;
1494 case "WixVariable":
1495 this.ParseWixVariableElement(child);
1496 break;
1497 default:
1498 this.Core.UnexpectedElement(node, child);
1499 break;
1500 }
1501 }
1502 else
1503 {
1504 this.Core.ParseExtensionElement(node, child);
1505 }
1506 }
1507
1508 if (!this.Core.EncounteredError)
1509 { 1233 {
1510 if (null != symbols) 1234 LockObject = objectId,
1511 { 1235 Table = tableName,
1512 var symbolRow = (WixDeltaPatchSymbolPathsTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchSymbolPaths); 1236 SDDLText =sddl,
1513 symbolRow.Id = productCode; 1237 Condition = condition
1514 symbolRow.Type = SymbolPathType.Product; 1238 });
1515 symbolRow.SymbolPaths = symbols;
1516 }
1517 }
1518 }
1519 finally
1520 {
1521 this.compilingProduct = false;
1522 } 1239 }
1523 } 1240 }
1524 1241
@@ -1644,22 +1361,27 @@ namespace WixToolset.Core
1644 { 1361 {
1645 if (!this.Core.EncounteredError) 1362 if (!this.Core.EncounteredError)
1646 { 1363 {
1647 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ProgId); 1364 var tuple = new ProgIdTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, progId))
1648 row.Set(0, progId); 1365 {
1649 row.Set(1, parent); 1366 ProgId = progId,
1650 row.Set(2, classId); 1367 ProgId_Parent = parent,
1651 row.Set(3, description); 1368 Class_ = classId,
1369 Description = description,
1370 };
1371
1652 if (null != icon) 1372 if (null != icon)
1653 { 1373 {
1654 row.Set(4, icon); 1374 tuple.Icon_ = icon;
1655 this.Core.CreateSimpleReference(sourceLineNumbers, "Icon", icon); 1375 this.Core.CreateSimpleReference(sourceLineNumbers, "Icon", icon);
1656 } 1376 }
1657 1377
1658 if (CompilerConstants.IntegerNotSet != iconIndex) 1378 if (CompilerConstants.IntegerNotSet != iconIndex)
1659 { 1379 {
1660 row.Set(5, iconIndex); 1380 tuple.IconIndex = iconIndex;
1661 } 1381 }
1662 1382
1383 this.Core.AddTuple(tuple);
1384
1663 this.Core.EnsureTable(sourceLineNumbers, "Class"); 1385 this.Core.EnsureTable(sourceLineNumbers, "Class");
1664 } 1386 }
1665 } 1387 }
@@ -1834,7 +1556,7 @@ namespace WixToolset.Core
1834 { 1556 {
1835 if (complianceCheck && !this.Core.EncounteredError) 1557 if (complianceCheck && !this.Core.EncounteredError)
1836 { 1558 {
1837 this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CCPSearch, new Identifier(sig, AccessModifier.Private)); 1559 this.Core.AddTuple(new CCPSearchTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, sig)));
1838 } 1560 }
1839 1561
1840 this.AddAppSearch(sourceLineNumbers, id, sig); 1562 this.AddAppSearch(sourceLineNumbers, id, sig);
@@ -1863,7 +1585,7 @@ namespace WixToolset.Core
1863 { 1585 {
1864 this.Core.Write(WarningMessages.PropertyModularizationSuppressed(sourceLineNumbers)); 1586 this.Core.Write(WarningMessages.PropertyModularizationSuppressed(sourceLineNumbers));
1865 1587
1866 this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixSuppressModularization, id); 1588 this.Core.AddTuple(new WixSuppressModularizationTuple(sourceLineNumbers, id));
1867 } 1589 }
1868 } 1590 }
1869 1591
@@ -2521,7 +2243,8 @@ namespace WixToolset.Core
2521 Identifier id = null; 2243 Identifier id = null;
2522 string directory = null; 2244 string directory = null;
2523 string name = null; 2245 string name = null;
2524 var on = CompilerConstants.IntegerNotSet; 2246 bool? onInstall = null;
2247 bool? onUninstall = null;
2525 string property = null; 2248 string property = null;
2526 string shortName = null; 2249 string shortName = null;
2527 2250
@@ -2545,16 +2268,14 @@ namespace WixToolset.Core
2545 switch (onValue) 2268 switch (onValue)
2546 { 2269 {
2547 case "install": 2270 case "install":
2548 on = 1; 2271 onInstall = true;
2549 break; 2272 break;
2550 case "uninstall": 2273 case "uninstall":
2551 on = 2; 2274 onUninstall = true;
2552 break; 2275 break;
2553 case "both": 2276 case "both":
2554 on = 3; 2277 onInstall = true;
2555 break; 2278 onUninstall = true;
2556 default:
2557 on = CompilerConstants.IllegalInteger;
2558 break; 2279 break;
2559 } 2280 }
2560 break; 2281 break;
@@ -2599,10 +2320,9 @@ namespace WixToolset.Core
2599 } 2320 }
2600 } 2321 }
2601 2322
2602 if (CompilerConstants.IntegerNotSet == on) 2323 if (!onInstall.HasValue && !onUninstall.HasValue)
2603 { 2324 {
2604 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "On")); 2325 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "On"));
2605 on = CompilerConstants.IllegalInteger;
2606 } 2326 }
2607 2327
2608 if (null != directory && null != property) 2328 if (null != directory && null != property)
@@ -2612,6 +2332,7 @@ namespace WixToolset.Core
2612 2332
2613 if (null == id) 2333 if (null == id)
2614 { 2334 {
2335 var on = (onInstall == true && onUninstall == true) ? 3 : (onUninstall == true) ? 2 : (onInstall == true) ? 1 : 0;
2615 id = this.Core.CreateIdentifier("rmf", directory ?? property ?? parentDirectory, LowercaseOrNull(shortName), LowercaseOrNull(name), on.ToString()); 2336 id = this.Core.CreateIdentifier("rmf", directory ?? property ?? parentDirectory, LowercaseOrNull(shortName), LowercaseOrNull(name), on.ToString());
2616 } 2337 }
2617 2338
@@ -2619,22 +2340,16 @@ namespace WixToolset.Core
2619 2340
2620 if (!this.Core.EncounteredError) 2341 if (!this.Core.EncounteredError)
2621 { 2342 {
2622 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.RemoveFile, id); 2343 var tuple = new RemoveFileTuple(sourceLineNumbers, id)
2623 row.Set(1, componentId);
2624 row.Set(2, this.GetMsiFilenameValue(shortName, name));
2625 if (null != directory)
2626 {
2627 row.Set(3, directory);
2628 }
2629 else if (null != property)
2630 {
2631 row.Set(3, property);
2632 }
2633 else
2634 { 2344 {
2635 row.Set(3, parentDirectory); 2345 Component_ = componentId,
2636 } 2346 FileName = this.GetMsiFilenameValue(shortName, name),
2637 row.Set(4, on); 2347 DirProperty = directory ?? property ?? parentDirectory,
2348 OnInstall = onInstall,
2349 OnUninstall = onUninstall
2350 };
2351
2352 this.Core.AddTuple(tuple);
2638 } 2353 }
2639 } 2354 }
2640 2355
@@ -2649,7 +2364,8 @@ namespace WixToolset.Core
2649 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 2364 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
2650 Identifier id = null; 2365 Identifier id = null;
2651 string directory = null; 2366 string directory = null;
2652 var on = CompilerConstants.IntegerNotSet; 2367 bool? onInstall = null;
2368 bool? onUninstall = null;
2653 string property = null; 2369 string property = null;
2654 2370
2655 foreach (var attrib in node.Attributes()) 2371 foreach (var attrib in node.Attributes())
@@ -2669,16 +2385,14 @@ namespace WixToolset.Core
2669 switch (onValue) 2385 switch (onValue)
2670 { 2386 {
2671 case "install": 2387 case "install":
2672 on = 1; 2388 onInstall = true;
2673 break; 2389 break;
2674 case "uninstall": 2390 case "uninstall":
2675 on = 2; 2391 onUninstall = true;
2676 break; 2392 break;
2677 case "both": 2393 case "both":
2678 on = 3; 2394 onInstall = true;
2679 break; 2395 onUninstall = true;
2680 default:
2681 on = CompilerConstants.IllegalInteger;
2682 break; 2396 break;
2683 } 2397 }
2684 break; 2398 break;
@@ -2696,10 +2410,9 @@ namespace WixToolset.Core
2696 } 2410 }
2697 } 2411 }
2698 2412
2699 if (CompilerConstants.IntegerNotSet == on) 2413 if (!onInstall.HasValue && !onUninstall.HasValue)
2700 { 2414 {
2701 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "On")); 2415 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "On"));
2702 on = CompilerConstants.IllegalInteger;
2703 } 2416 }
2704 2417
2705 if (null != directory && null != property) 2418 if (null != directory && null != property)
@@ -2709,6 +2422,7 @@ namespace WixToolset.Core
2709 2422
2710 if (null == id) 2423 if (null == id)
2711 { 2424 {
2425 var on = (onInstall == true && onUninstall == true) ? 3 : (onUninstall == true) ? 2 : (onInstall == true) ? 1 : 0;
2712 id = this.Core.CreateIdentifier("rmf", directory ?? property ?? parentDirectory, on.ToString()); 2426 id = this.Core.CreateIdentifier("rmf", directory ?? property ?? parentDirectory, on.ToString());
2713 } 2427 }
2714 2428
@@ -2716,22 +2430,15 @@ namespace WixToolset.Core
2716 2430
2717 if (!this.Core.EncounteredError) 2431 if (!this.Core.EncounteredError)
2718 { 2432 {
2719 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.RemoveFile, id); 2433 var tuple = new RemoveFileTuple(sourceLineNumbers, id)
2720 row.Set(1, componentId);
2721 //row.Set(2, null);
2722 if (null != directory)
2723 { 2434 {
2724 row.Set(3, directory); 2435 Component_ = componentId,
2725 } 2436 DirProperty = directory ?? property ?? parentDirectory,
2726 else if (null != property) 2437 OnInstall = onInstall,
2727 { 2438 OnUninstall = onUninstall
2728 row.Set(3, property); 2439 };
2729 } 2440
2730 else 2441 this.Core.AddTuple(tuple);
2731 {
2732 row.Set(3, parentDirectory);
2733 }
2734 row.Set(4, on);
2735 } 2442 }
2736 } 2443 }
2737 2444
@@ -2796,11 +2503,13 @@ namespace WixToolset.Core
2796 2503
2797 if (!this.Core.EncounteredError) 2504 if (!this.Core.EncounteredError)
2798 { 2505 {
2799 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ReserveCost, id); 2506 this.Core.AddTuple(new ReserveCostTuple(sourceLineNumbers, id)
2800 row.Set(1, componentId); 2507 {
2801 row.Set(2, directoryId); 2508 Component_ = componentId,
2802 row.Set(3, runLocal); 2509 ReserveFolder = directoryId,
2803 row.Set(4, runFromSource); 2510 ReserveLocal = runLocal,
2511 ReserveSource = runFromSource
2512 });
2804 } 2513 }
2805 } 2514 }
2806 2515
@@ -2809,14 +2518,8 @@ namespace WixToolset.Core
2809 /// </summary> 2518 /// </summary>
2810 /// <param name="node">Element to parse.</param> 2519 /// <param name="node">Element to parse.</param>
2811 /// <param name="sequenceTable">Name of sequence table.</param> 2520 /// <param name="sequenceTable">Name of sequence table.</param>
2812 private void ParseSequenceElement(XElement node, string sequenceTable) 2521 private void ParseSequenceElement(XElement node, SequenceTable sequenceTable)
2813 { 2522 {
2814 // use the proper table name internally
2815 if ("AdvertiseExecuteSequence" == sequenceTable)
2816 {
2817 sequenceTable = "AdvtExecuteSequence";
2818 }
2819
2820 // Parse each action in the sequence. 2523 // Parse each action in the sequence.
2821 foreach (var child in node.Elements()) 2524 foreach (var child in node.Elements())
2822 { 2525 {
@@ -2855,7 +2558,7 @@ namespace WixToolset.Core
2855 if (customAction || showDialog || specialAction || specialStandardAction) 2558 if (customAction || showDialog || specialAction || specialStandardAction)
2856 { 2559 {
2857 afterAction = this.Core.GetAttributeIdentifierValue(childSourceLineNumbers, attrib); 2560 afterAction = this.Core.GetAttributeIdentifierValue(childSourceLineNumbers, attrib);
2858 this.Core.CreateSimpleReference(childSourceLineNumbers, "WixAction", sequenceTable, afterAction); 2561 this.Core.CreateSimpleReference(childSourceLineNumbers, "WixAction", sequenceTable.ToString(), afterAction);
2859 } 2562 }
2860 else 2563 else
2861 { 2564 {
@@ -2866,7 +2569,7 @@ namespace WixToolset.Core
2866 if (customAction || showDialog || specialAction || specialStandardAction) 2569 if (customAction || showDialog || specialAction || specialStandardAction)
2867 { 2570 {
2868 beforeAction = this.Core.GetAttributeIdentifierValue(childSourceLineNumbers, attrib); 2571 beforeAction = this.Core.GetAttributeIdentifierValue(childSourceLineNumbers, attrib);
2869 this.Core.CreateSimpleReference(childSourceLineNumbers, "WixAction", sequenceTable, beforeAction); 2572 this.Core.CreateSimpleReference(childSourceLineNumbers, "WixAction", sequenceTable.ToString(), beforeAction);
2870 } 2573 }
2871 else 2574 else
2872 { 2575 {
@@ -2995,23 +2698,30 @@ namespace WixToolset.Core
2995 { 2698 {
2996 if (suppress) 2699 if (suppress)
2997 { 2700 {
2998 var row = this.Core.CreateRow(childSourceLineNumbers, TupleDefinitionType.WixSuppressAction, new Identifier(AccessModifier.Public, sequenceTable, actionName)); 2701 this.Core.AddTuple(new WixSuppressActionTuple(childSourceLineNumbers, new Identifier(AccessModifier.Public, sequenceTable, actionName))
2999 row.Set(0, sequenceTable); 2702 {
3000 row.Set(1, actionName); 2703 SequenceTable = sequenceTable,
2704 Action = actionName
2705 });
3001 } 2706 }
3002 else 2707 else
3003 { 2708 {
3004 var row = this.Core.CreateRow(childSourceLineNumbers, TupleDefinitionType.WixAction, new Identifier(AccessModifier.Public, sequenceTable, actionName)); 2709 var tuple = new WixActionTuple(childSourceLineNumbers, new Identifier(AccessModifier.Public, sequenceTable, actionName))
3005 row.Set(0, sequenceTable); 2710 {
3006 row.Set(1, actionName); 2711 SequenceTable = sequenceTable,
3007 row.Set(2, condition); 2712 Action = actionName,
2713 Condition = condition,
2714 Before = beforeAction,
2715 After = afterAction,
2716 Overridable = overridable,
2717 };
2718
3008 if (CompilerConstants.IntegerNotSet != sequence) 2719 if (CompilerConstants.IntegerNotSet != sequence)
3009 { 2720 {
3010 row.Set(3, sequence); 2721 tuple.Sequence = sequence;
3011 } 2722 }
3012 row.Set(4, beforeAction); 2723
3013 row.Set(5, afterAction); 2724 this.Core.AddTuple(tuple);
3014 row.Set(6, overridable ? 1 : 0);
3015 } 2725 }
3016 } 2726 }
3017 } 2727 }
@@ -3305,7 +3015,7 @@ namespace WixToolset.Core
3305 { 3015 {
3306 if (!String.IsNullOrEmpty(delayedAutoStart)) 3016 if (!String.IsNullOrEmpty(delayedAutoStart))
3307 { 3017 {
3308 var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(String.Concat(id.Id, ".DS"), id.Access)) 3018 var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(id.Access, String.Concat(id.Id, ".DS")))
3309 { 3019 {
3310 Name = name, 3020 Name = name,
3311 OnInstall = install, 3021 OnInstall = install,
@@ -3327,7 +3037,7 @@ namespace WixToolset.Core
3327 3037
3328 if (!String.IsNullOrEmpty(failureActionsWhen)) 3038 if (!String.IsNullOrEmpty(failureActionsWhen))
3329 { 3039 {
3330 var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(String.Concat(id.Id, ".FA"), id.Access)) 3040 var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(id.Access, String.Concat(id.Id, ".FA")))
3331 { 3041 {
3332 Name = name, 3042 Name = name,
3333 OnInstall = install, 3043 OnInstall = install,
@@ -3349,7 +3059,7 @@ namespace WixToolset.Core
3349 3059
3350 if (!String.IsNullOrEmpty(sid)) 3060 if (!String.IsNullOrEmpty(sid))
3351 { 3061 {
3352 var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(String.Concat(id.Id, ".SS"), id.Access)) 3062 var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(id.Access, String.Concat(id.Id, ".SS")))
3353 { 3063 {
3354 Name = name, 3064 Name = name,
3355 OnInstall = install, 3065 OnInstall = install,
@@ -3371,7 +3081,7 @@ namespace WixToolset.Core
3371 3081
3372 if (!String.IsNullOrEmpty(requiredPrivileges)) 3082 if (!String.IsNullOrEmpty(requiredPrivileges))
3373 { 3083 {
3374 var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(String.Concat(id.Id, ".RP"), id.Access)) 3084 var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(id.Access, String.Concat(id.Id, ".RP")))
3375 { 3085 {
3376 Name = name, 3086 Name = name,
3377 OnInstall = install, 3087 OnInstall = install,
@@ -3393,7 +3103,7 @@ namespace WixToolset.Core
3393 3103
3394 if (!String.IsNullOrEmpty(preShutdownDelay)) 3104 if (!String.IsNullOrEmpty(preShutdownDelay))
3395 { 3105 {
3396 var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(String.Concat(id.Id, ".PD"), id.Access)) 3106 var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(id.Access, String.Concat(id.Id, ".PD")))
3397 { 3107 {
3398 Name = name, 3108 Name = name,
3399 OnInstall = install, 3109 OnInstall = install,
@@ -4320,9 +4030,11 @@ namespace WixToolset.Core
4320 4030
4321 if (!this.Core.EncounteredError) 4031 if (!this.Core.EncounteredError)
4322 { 4032 {
4323 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.FileSFPCatalog); 4033 this.Core.AddTuple(new FileSFPCatalogTuple(sourceLineNumbers)
4324 row.Set(0, id); 4034 {
4325 row.Set(1, parentSFPCatalog); 4035 File_ = id,
4036 SFPCatalog_ = parentSFPCatalog
4037 });
4326 } 4038 }
4327 } 4039 }
4328 4040
@@ -4411,10 +4123,12 @@ namespace WixToolset.Core
4411 4123
4412 if (!this.Core.EncounteredError) 4124 if (!this.Core.EncounteredError)
4413 { 4125 {
4414 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.SFPCatalog); 4126 this.Core.AddTuple(new SFPCatalogTuple(sourceLineNumbers)
4415 row.Set(0, name); 4127 {
4416 row.Set(1, sourceFile); 4128 SFPCatalog = name,
4417 row.Set(2, dependency); 4129 Catalog = sourceFile,
4130 Dependency = dependency
4131 });
4418 } 4132 }
4419 } 4133 }
4420 4134
@@ -4827,10 +4541,12 @@ namespace WixToolset.Core
4827 4541
4828 if (!this.Core.EncounteredError) 4542 if (!this.Core.EncounteredError)
4829 { 4543 {
4830 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiShortcutProperty, id); 4544 this.Core.AddTuple(new MsiShortcutPropertyTuple(sourceLineNumbers, id)
4831 row.Set(1, shortcutId); 4545 {
4832 row.Set(2, key); 4546 Shortcut_ = shortcutId,
4833 row.Set(3, value); 4547 PropertyKey = key,
4548 PropVariantValue = value
4549 });
4834 } 4550 }
4835 } 4551 }
4836 4552
@@ -5022,21 +4738,27 @@ namespace WixToolset.Core
5022 4738
5023 if (!this.Core.EncounteredError) 4739 if (!this.Core.EncounteredError)
5024 { 4740 {
5025 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.TypeLib); 4741 var tuple = new TypeLibTuple(sourceLineNumbers)
5026 row.Set(0, id); 4742 {
5027 row.Set(1, language); 4743 LibId = id,
5028 row.Set(2, componentId); 4744 Language = language,
4745 Component_ = componentId,
4746 Description = description,
4747 Directory_ = helpDirectory,
4748 Feature_ = Guid.Empty.ToString("B")
4749 };
4750
5029 if (CompilerConstants.IntegerNotSet != majorVersion || CompilerConstants.IntegerNotSet != minorVersion) 4751 if (CompilerConstants.IntegerNotSet != majorVersion || CompilerConstants.IntegerNotSet != minorVersion)
5030 { 4752 {
5031 row.Set(3, (CompilerConstants.IntegerNotSet != majorVersion ? majorVersion * 256 : 0) + (CompilerConstants.IntegerNotSet != minorVersion ? minorVersion : 0)); 4753 tuple.Version = (CompilerConstants.IntegerNotSet != majorVersion ? majorVersion * 256 : 0) + (CompilerConstants.IntegerNotSet != minorVersion ? minorVersion : 0);
5032 } 4754 }
5033 row.Set(4, description); 4755
5034 row.Set(5, helpDirectory);
5035 row.Set(6, Guid.Empty.ToString("B"));
5036 if (CompilerConstants.IntegerNotSet != cost) 4756 if (CompilerConstants.IntegerNotSet != cost)
5037 { 4757 {
5038 row.Set(7, cost); 4758 tuple.Cost = cost;
5039 } 4759 }
4760
4761 this.Core.AddTuple(tuple);
5040 } 4762 }
5041 } 4763 }
5042 else if (YesNoType.No == advertise) 4764 else if (YesNoType.No == advertise)
@@ -5250,7 +4972,7 @@ namespace WixToolset.Core
5250 this.Core.AddTuple(tuple); 4972 this.Core.AddTuple(tuple);
5251 4973
5252 // Ensure the action property is secure. 4974 // Ensure the action property is secure.
5253 this.AddWixPropertyRow(sourceLineNumbers, new Identifier(actionProperty, AccessModifier.Private), false, true, false); 4975 this.AddWixPropertyRow(sourceLineNumbers, new Identifier(AccessModifier.Private, actionProperty), false, true, false);
5254 4976
5255 // Ensure that RemoveExistingProducts is authored in InstallExecuteSequence 4977 // Ensure that RemoveExistingProducts is authored in InstallExecuteSequence
5256 // if at least one row in Upgrade table lacks the OnlyDetect attribute. 4978 // if at least one row in Upgrade table lacks the OnlyDetect attribute.
@@ -5361,15 +5083,20 @@ namespace WixToolset.Core
5361 5083
5362 if (!this.Core.EncounteredError) 5084 if (!this.Core.EncounteredError)
5363 { 5085 {
5364 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Verb); 5086 var tuple = new VerbTuple(sourceLineNumbers)
5365 row.Set(0, extension); 5087 {
5366 row.Set(1, id); 5088 Extension_ = extension,
5089 Verb = id,
5090 Command = command,
5091 Argument = argument,
5092 };
5093
5367 if (CompilerConstants.IntegerNotSet != sequence) 5094 if (CompilerConstants.IntegerNotSet != sequence)
5368 { 5095 {
5369 row.Set(2, sequence); 5096 tuple.Sequence = sequence;
5370 } 5097 }
5371 row.Set(3, command); 5098
5372 row.Set(4, argument); 5099 this.Core.AddTuple(tuple);
5373 } 5100 }
5374 } 5101 }
5375 else if (YesNoType.No == advertise) 5102 else if (YesNoType.No == advertise)
@@ -5414,76 +5141,6 @@ namespace WixToolset.Core
5414 } 5141 }
5415 5142
5416 /// <summary> 5143 /// <summary>
5417 /// Parses a Wix element.
5418 /// </summary>
5419 /// <param name="node">Element to parse.</param>
5420 private void ParseWixElement(XElement node)
5421 {
5422 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
5423 string requiredVersion = null;
5424
5425 foreach (var attrib in node.Attributes())
5426 {
5427 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
5428 {
5429 switch (attrib.Name.LocalName)
5430 {
5431 case "RequiredVersion":
5432 requiredVersion = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
5433 break;
5434 default:
5435 this.Core.UnexpectedAttribute(node, attrib);
5436 break;
5437 }
5438 }
5439 else
5440 {
5441 this.Core.ParseExtensionAttribute(node, attrib);
5442 }
5443 }
5444
5445 if (null != requiredVersion)
5446 {
5447 this.Core.VerifyRequiredVersion(sourceLineNumbers, requiredVersion);
5448 }
5449
5450 foreach (var child in node.Elements())
5451 {
5452 if (CompilerCore.WixNamespace == child.Name.Namespace)
5453 {
5454 switch (child.Name.LocalName)
5455 {
5456 case "Bundle":
5457 this.ParseBundleElement(child);
5458 break;
5459 case "Fragment":
5460 this.ParseFragmentElement(child);
5461 break;
5462 case "Module":
5463 this.ParseModuleElement(child);
5464 break;
5465 case "PatchCreation":
5466 this.ParsePatchCreationElement(child);
5467 break;
5468 case "Product":
5469 this.ParseProductElement(child);
5470 break;
5471 case "Patch":
5472 this.ParsePatchElement(child);
5473 break;
5474 default:
5475 this.Core.UnexpectedElement(node, child);
5476 break;
5477 }
5478 }
5479 else
5480 {
5481 this.Core.ParseExtensionElement(node, child);
5482 }
5483 }
5484 }
5485
5486 /// <summary>
5487 /// Parses a WixVariable element. 5144 /// Parses a WixVariable element.
5488 /// </summary> 5145 /// </summary>
5489 /// <param name="node">Element to parse.</param> 5146 /// <param name="node">Element to parse.</param>
@@ -5534,9 +5191,11 @@ namespace WixToolset.Core
5534 5191
5535 if (!this.Core.EncounteredError) 5192 if (!this.Core.EncounteredError)
5536 { 5193 {
5537 var wixVariableRow = (WixVariableTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixVariable, id); 5194 this.Core.AddTuple(new WixVariableTuple(sourceLineNumbers, id)
5538 wixVariableRow.Value = value; 5195 {
5539 wixVariableRow.Overridable = overridable; 5196 Value = value,
5197 Overridable = overridable
5198 });
5540 } 5199 }
5541 } 5200 }
5542 5201