aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core/Compiler.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core/Compiler.cs')
-rw-r--r--src/WixToolset.Core/Compiler.cs2577
1 files changed, 535 insertions, 2042 deletions
diff --git a/src/WixToolset.Core/Compiler.cs b/src/WixToolset.Core/Compiler.cs
index 25cc095b..6be4c9ba 100644
--- a/src/WixToolset.Core/Compiler.cs
+++ b/src/WixToolset.Core/Compiler.cs
@@ -21,8 +21,11 @@ namespace WixToolset.Core
21 /// </summary> 21 /// </summary>
22 internal partial class Compiler : ICompiler 22 internal partial class Compiler : ICompiler
23 { 23 {
24 public const string DefaultComponentIdPlaceholderFormat = "WixComponentIdPlaceholder{0}"; 24 private const int MinValueOfMaxCabSizeForLargeFileSplitting = 20; // 20 MB
25 public const string DefaultComponentIdPlaceholderWixVariableFormat = "!(wix.{0})"; 25 private const int MaxValueOfMaxCabSizeForLargeFileSplitting = 2 * 1024; // 2048 MB (i.e. 2 GB)
26
27 private const string DefaultComponentIdPlaceholderFormat = "WixComponentIdPlaceholder{0}";
28 private const string DefaultComponentIdPlaceholderWixVariableFormat = "!(wix.{0})";
26 // If these are true you know you are building a module or product 29 // If these are true you know you are building a module or product
27 // but if they are false you cannot not be sure they will not end 30 // but if they are false you cannot not be sure they will not end
28 // up a product or module. Use these flags carefully. 31 // up a product or module. Use these flags carefully.
@@ -164,6 +167,76 @@ namespace WixToolset.Core
164 return this.Messaging.EncounteredError ? null : target; 167 return this.Messaging.EncounteredError ? null : target;
165 } 168 }
166 169
170 /// <summary>
171 /// Parses a Wix element.
172 /// </summary>
173 /// <param name="node">Element to parse.</param>
174 private void ParseWixElement(XElement node)
175 {
176 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
177 string requiredVersion = null;
178
179 foreach (var attrib in node.Attributes())
180 {
181 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
182 {
183 switch (attrib.Name.LocalName)
184 {
185 case "RequiredVersion":
186 requiredVersion = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
187 break;
188 default:
189 this.Core.UnexpectedAttribute(node, attrib);
190 break;
191 }
192 }
193 else
194 {
195 this.Core.ParseExtensionAttribute(node, attrib);
196 }
197 }
198
199 if (null != requiredVersion)
200 {
201 this.Core.VerifyRequiredVersion(sourceLineNumbers, requiredVersion);
202 }
203
204 foreach (var child in node.Elements())
205 {
206 if (CompilerCore.WixNamespace == child.Name.Namespace)
207 {
208 switch (child.Name.LocalName)
209 {
210 case "Bundle":
211 this.ParseBundleElement(child);
212 break;
213 case "Fragment":
214 this.ParseFragmentElement(child);
215 break;
216 case "Module":
217 this.ParseModuleElement(child);
218 break;
219 case "PatchCreation":
220 this.ParsePatchCreationElement(child);
221 break;
222 case "Product":
223 this.ParseProductElement(child);
224 break;
225 case "Patch":
226 this.ParsePatchElement(child);
227 break;
228 default:
229 this.Core.UnexpectedElement(node, child);
230 break;
231 }
232 }
233 else
234 {
235 this.Core.ParseExtensionElement(node, child);
236 }
237 }
238 }
239
167 private void ResolveComponentIdPlaceholders(Intermediate target) 240 private void ResolveComponentIdPlaceholders(Intermediate target)
168 { 241 {
169 if (0 < this.componentIdPlaceholdersResolver.VariableCount) 242 if (0 < this.componentIdPlaceholdersResolver.VariableCount)
@@ -214,7 +287,7 @@ namespace WixToolset.Core
214 /// <returns>Null if the string is null, otherwise returns the lowercase.</returns> 287 /// <returns>Null if the string is null, otherwise returns the lowercase.</returns>
215 private static string LowercaseOrNull(string s) 288 private static string LowercaseOrNull(string s)
216 { 289 {
217 return (null == s) ? s : s.ToLowerInvariant(); 290 return s?.ToLowerInvariant();
218 } 291 }
219 292
220 /// <summary> 293 /// <summary>
@@ -227,18 +300,11 @@ namespace WixToolset.Core
227 { 300 {
228 if (null != shortName && null != longName && !String.Equals(shortName, longName, StringComparison.OrdinalIgnoreCase)) 301 if (null != shortName && null != longName && !String.Equals(shortName, longName, StringComparison.OrdinalIgnoreCase))
229 { 302 {
230 return String.Format(CultureInfo.InvariantCulture, "{0}|{1}", shortName, longName); 303 return String.Concat(shortName, "|", longName);
231 } 304 }
232 else 305 else
233 { 306 {
234 if (this.Core.IsValidShortFilename(longName, false)) 307 return this.Core.IsValidShortFilename(longName, false) ? longName : shortName;
235 {
236 return longName;
237 }
238 else
239 {
240 return shortName;
241 }
242 } 308 }
243 } 309 }
244 310
@@ -246,19 +312,23 @@ namespace WixToolset.Core
246 /// Adds a search property to the active section. 312 /// Adds a search property to the active section.
247 /// </summary> 313 /// </summary>
248 /// <param name="sourceLineNumbers">Current source/line number of processing.</param> 314 /// <param name="sourceLineNumbers">Current source/line number of processing.</param>
249 /// <param name="property">Property to add to search.</param> 315 /// <param name="propertyId">Property to add to search.</param>
250 /// <param name="signature">Signature for search.</param> 316 /// <param name="signature">Signature for search.</param>
251 private void AddAppSearch(SourceLineNumber sourceLineNumbers, Identifier property, string signature) 317 private void AddAppSearch(SourceLineNumber sourceLineNumbers, Identifier propertyId, string signature)
252 { 318 {
253 if (!this.Core.EncounteredError) 319 if (!this.Core.EncounteredError)
254 { 320 {
255 if (property.Id != property.Id.ToUpperInvariant()) 321 if (propertyId.Id != propertyId.Id.ToUpperInvariant())
256 { 322 {
257 this.Core.Write(ErrorMessages.SearchPropertyNotUppercase(sourceLineNumbers, "Property", "Id", property.Id)); 323 this.Core.Write(ErrorMessages.SearchPropertyNotUppercase(sourceLineNumbers, "Property", "Id", propertyId.Id));
258 } 324 }
259 325
260 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.AppSearch, property); 326 var tuple = new AppSearchTuple(sourceLineNumbers, propertyId)
261 row.Set(1, signature); 327 {
328 Signature_ = signature
329 };
330
331 this.Core.AddTuple(tuple);
262 } 332 }
263 } 333 }
264 334
@@ -266,16 +336,16 @@ namespace WixToolset.Core
266 /// Adds a property to the active section. 336 /// Adds a property to the active section.
267 /// </summary> 337 /// </summary>
268 /// <param name="sourceLineNumbers">Current source/line number of processing.</param> 338 /// <param name="sourceLineNumbers">Current source/line number of processing.</param>
269 /// <param name="property">Name of property to add.</param> 339 /// <param name="propertyId">Identifier of property to add.</param>
270 /// <param name="value">Value of property.</param> 340 /// <param name="value">Value of property.</param>
271 /// <param name="admin">Flag if property is an admin property.</param> 341 /// <param name="admin">Flag if property is an admin property.</param>
272 /// <param name="secure">Flag if property is a secure property.</param> 342 /// <param name="secure">Flag if property is a secure property.</param>
273 /// <param name="hidden">Flag if property is to be hidden.</param> 343 /// <param name="hidden">Flag if property is to be hidden.</param>
274 /// <param name="fragment">Adds the property to a new section.</param> 344 /// <param name="fragment">Adds the property to a new section.</param>
275 private void AddProperty(SourceLineNumber sourceLineNumbers, Identifier property, string value, bool admin, bool secure, bool hidden, bool fragment) 345 private void AddProperty(SourceLineNumber sourceLineNumbers, Identifier propertyId, string value, bool admin, bool secure, bool hidden, bool fragment)
276 { 346 {
277 // properties without a valid identifier should not be processed any further 347 // properties without a valid identifier should not be processed any further
278 if (null == property || String.IsNullOrEmpty(property.Id)) 348 if (null == propertyId || String.IsNullOrEmpty(propertyId.Id))
279 { 349 {
280 return; 350 return;
281 } 351 }
@@ -290,7 +360,7 @@ namespace WixToolset.Core
290 var group = match.Groups["identifier"]; 360 var group = match.Groups["identifier"];
291 if (group.Success) 361 if (group.Success)
292 { 362 {
293 this.Core.Write(WarningMessages.PropertyValueContainsPropertyReference(sourceLineNumbers, property.Id, group.Value)); 363 this.Core.Write(WarningMessages.PropertyValueContainsPropertyReference(sourceLineNumbers, propertyId.Id, group.Value));
294 } 364 }
295 } 365 }
296 } 366 }
@@ -302,26 +372,26 @@ namespace WixToolset.Core
302 // Add the row to a separate section if requested. 372 // Add the row to a separate section if requested.
303 if (fragment) 373 if (fragment)
304 { 374 {
305 var id = String.Concat(this.Core.ActiveSection.Id, ".", property.Id); 375 var id = String.Concat(this.Core.ActiveSection.Id, ".", propertyId.Id);
306 376
307 section = this.Core.CreateSection(id, SectionType.Fragment, this.Core.ActiveSection.Codepage, this.Context.CompilationId); 377 section = this.Core.CreateSection(id, SectionType.Fragment, this.Core.ActiveSection.Codepage, this.Context.CompilationId);
308 378
309 // Reference the property in the active section. 379 // Reference the property in the active section.
310 this.Core.CreateSimpleReference(sourceLineNumbers, "Property", property.Id); 380 this.Core.CreateSimpleReference(sourceLineNumbers, "Property", propertyId.Id);
311 } 381 }
312 382
313 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Property, section, property);
314
315 // Allow row to exist with no value so that PropertyRefs can be made for *Search elements 383 // Allow row to exist with no value so that PropertyRefs can be made for *Search elements
316 // the linker will remove these rows before the final output is created. 384 // the linker will remove these rows before the final output is created.
317 if (null != value) 385 var tuple = new PropertyTuple(sourceLineNumbers, propertyId)
318 { 386 {
319 row.Set(1, value); 387 Value = value,
320 } 388 };
389
390 section.Tuples.Add(tuple);
321 391
322 if (admin || hidden || secure) 392 if (admin || hidden || secure)
323 { 393 {
324 this.AddWixPropertyRow(sourceLineNumbers, property, admin, secure, hidden, section); 394 this.AddWixPropertyRow(sourceLineNumbers, propertyId, admin, secure, hidden, section);
325 } 395 }
326 } 396 }
327 } 397 }
@@ -340,10 +410,15 @@ namespace WixToolset.Core
340 this.Core.EnsureTable(sourceLineNumbers, "Property"); // Property table is always required when using WixProperty table. 410 this.Core.EnsureTable(sourceLineNumbers, "Property"); // Property table is always required when using WixProperty table.
341 } 411 }
342 412
343 var row = (WixPropertyTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixProperty, section, property); 413 var tuple = new WixPropertyTuple(sourceLineNumbers)
344 row.Admin = admin; 414 {
345 row.Hidden = hidden; 415 Property_ = property.Id,
346 row.Secure = secure; 416 Admin = admin,
417 Hidden = hidden,
418 Secure = secure
419 };
420
421 section.Tuples.Add(tuple);
347 } 422 }
348 423
349 /// <summary> 424 /// <summary>
@@ -375,9 +450,9 @@ namespace WixToolset.Core
375 string localService = null; 450 string localService = null;
376 string serviceParameters = null; 451 string serviceParameters = null;
377 string dllSurrogate = null; 452 string dllSurrogate = null;
378 var activateAtStorage = YesNoType.NotSet; 453 bool? activateAtStorage = null;
379 var appIdAdvertise = YesNoType.NotSet; 454 var appIdAdvertise = YesNoType.NotSet;
380 var runAsInteractiveUser = YesNoType.NotSet; 455 bool? runAsInteractiveUser = null;
381 string description = null; 456 string description = null;
382 457
383 foreach (var attrib in node.Attributes()) 458 foreach (var attrib in node.Attributes())
@@ -390,7 +465,7 @@ namespace WixToolset.Core
390 appId = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); 465 appId = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
391 break; 466 break;
392 case "ActivateAtStorage": 467 case "ActivateAtStorage":
393 activateAtStorage = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 468 activateAtStorage = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
394 break; 469 break;
395 case "Advertise": 470 case "Advertise":
396 appIdAdvertise = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 471 appIdAdvertise = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
@@ -408,7 +483,7 @@ namespace WixToolset.Core
408 remoteServerName = this.Core.GetAttributeValue(sourceLineNumbers, attrib); 483 remoteServerName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
409 break; 484 break;
410 case "RunAsInteractiveUser": 485 case "RunAsInteractiveUser":
411 runAsInteractiveUser = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 486 runAsInteractiveUser = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
412 break; 487 break;
413 case "ServiceParameters": 488 case "ServiceParameters":
414 serviceParameters = this.Core.GetAttributeValue(sourceLineNumbers, attrib); 489 serviceParameters = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
@@ -473,21 +548,19 @@ namespace WixToolset.Core
473 548
474 if (!this.Core.EncounteredError) 549 if (!this.Core.EncounteredError)
475 { 550 {
476 var id = new Identifier(appId, AccessModifier.Public); 551 var id = new Identifier(AccessModifier.Public, appId);
477 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.AppId, id);
478 row.Set(1, remoteServerName);
479 row.Set(2, localService);
480 row.Set(3, serviceParameters);
481 row.Set(4, dllSurrogate);
482 if (YesNoType.Yes == activateAtStorage)
483 {
484 row.Set(5, 1);
485 }
486 552
487 if (YesNoType.Yes == runAsInteractiveUser) 553 var tuple = new AppIdTuple(sourceLineNumbers, id)
488 { 554 {
489 row.Set(6, 1); 555 RemoteServerName = remoteServerName,
490 } 556 LocalService = localService,
557 ServiceParameters = serviceParameters,
558 DllSurrogate = dllSurrogate,
559 ActivateAtStorage = activateAtStorage,
560 RunAsInteractiveUser = runAsInteractiveUser
561 };
562
563 this.Core.AddTuple(tuple);
491 } 564 }
492 } 565 }
493 else if (YesNoType.No == advertise) 566 else if (YesNoType.No == advertise)
@@ -521,12 +594,12 @@ namespace WixToolset.Core
521 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "DllSurrogate", dllSurrogate, componentId); 594 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "DllSurrogate", dllSurrogate, componentId);
522 } 595 }
523 596
524 if (YesNoType.Yes == activateAtStorage) 597 if (true == activateAtStorage)
525 { 598 {
526 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "ActivateAtStorage", "Y", componentId); 599 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "ActivateAtStorage", "Y", componentId);
527 } 600 }
528 601
529 if (YesNoType.Yes == runAsInteractiveUser) 602 if (true == runAsInteractiveUser)
530 { 603 {
531 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "RunAs", "Interactive User", componentId); 604 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "RunAs", "Interactive User", componentId);
532 } 605 }
@@ -576,10 +649,14 @@ namespace WixToolset.Core
576 649
577 if (!this.Core.EncounteredError) 650 if (!this.Core.EncounteredError)
578 { 651 {
579 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiAssemblyName); 652 var tuple = new MsiAssemblyNameTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, componentId, id))
580 row.Set(0, componentId); 653 {
581 row.Set(1, id); 654 Component_ = componentId,
582 row.Set(2, value); 655 Name = id,
656 Value = value
657 };
658
659 this.Core.AddTuple(tuple);
583 } 660 }
584 } 661 }
585 662
@@ -661,12 +738,16 @@ namespace WixToolset.Core
661 738
662 if (!this.Core.EncounteredError) 739 if (!this.Core.EncounteredError)
663 { 740 {
664 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Binary, id); 741 var tuple = new BinaryTuple(sourceLineNumbers, id)
665 row.Set(1, sourceFile); 742 {
743 Data = sourceFile
744 };
745
746 this.Core.AddTuple(tuple);
666 747
667 if (YesNoType.Yes == suppressModularization) 748 if (YesNoType.Yes == suppressModularization)
668 { 749 {
669 var wixSuppressModularizationRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixSuppressModularization, id); 750 this.Core.AddTuple(new WixSuppressModularizationTuple(sourceLineNumbers, id));
670 } 751 }
671 } 752 }
672 753
@@ -736,8 +817,10 @@ namespace WixToolset.Core
736 817
737 if (!this.Core.EncounteredError) 818 if (!this.Core.EncounteredError)
738 { 819 {
739 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Icon, id); 820 this.Core.AddTuple(new IconTuple(sourceLineNumbers, id)
740 row.Set(1, sourceFile); 821 {
822 Data = sourceFile
823 });
741 } 824 }
742 825
743 return id.Id; 826 return id.Id;
@@ -808,7 +891,7 @@ namespace WixToolset.Core
808 private void ParseInstanceElement(XElement node, string propertyId) 891 private void ParseInstanceElement(XElement node, string propertyId)
809 { 892 {
810 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 893 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
811 string id = null; 894 Identifier id = null;
812 string productCode = null; 895 string productCode = null;
813 string productName = null; 896 string productName = null;
814 string upgradeCode = null; 897 string upgradeCode = null;
@@ -820,7 +903,7 @@ namespace WixToolset.Core
820 switch (attrib.Name.LocalName) 903 switch (attrib.Name.LocalName)
821 { 904 {
822 case "Id": 905 case "Id":
823 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 906 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
824 break; 907 break;
825 case "ProductCode": 908 case "ProductCode":
826 productCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, true); 909 productCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, true);
@@ -856,18 +939,15 @@ namespace WixToolset.Core
856 939
857 if (!this.Core.EncounteredError) 940 if (!this.Core.EncounteredError)
858 { 941 {
859 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixInstanceTransforms); 942 var tuple = new WixInstanceTransformsTuple(sourceLineNumbers, id)
860 row.Set(0, id);
861 row.Set(1, propertyId);
862 row.Set(2, productCode);
863 if (null != productName)
864 {
865 row.Set(3, productName);
866 }
867 if (null != upgradeCode)
868 { 943 {
869 row.Set(4, upgradeCode); 944 PropertyId = propertyId,
870 } 945 ProductCode = productCode,
946 ProductName = productName,
947 UpgradeCode = upgradeCode
948 };
949
950 this.Core.AddTuple(tuple);
871 } 951 }
872 } 952 }
873 953
@@ -928,19 +1008,16 @@ namespace WixToolset.Core
928 1008
929 if (!this.Core.EncounteredError) 1009 if (!this.Core.EncounteredError)
930 { 1010 {
931 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PublishComponent); 1011 var tuple = new PublishComponentTuple(sourceLineNumbers)
932 row.Set(0, id);
933 row.Set(1, qualifier);
934 row.Set(2, componentId);
935 row.Set(3, appData);
936 if (null == feature)
937 { 1012 {
938 row.Set(4, Guid.Empty.ToString("B")); 1013 ComponentId = id,
939 } 1014 Qualifier = qualifier,
940 else 1015 Component_ = componentId,
941 { 1016 AppData = appData,
942 row.Set(4, feature); 1017 Feature_ = feature ?? Guid.Empty.ToString("B"),
943 } 1018 };
1019
1020 this.Core.AddTuple(tuple);
944 } 1021 }
945 } 1022 }
946 1023
@@ -1662,7 +1739,7 @@ namespace WixToolset.Core
1662 string name = null; 1739 string name = null;
1663 string signature = null; 1740 string signature = null;
1664 RegistryRootType? root = null; 1741 RegistryRootType? root = null;
1665 var type = CompilerConstants.IntegerNotSet; 1742 RegLocatorType? type = null;
1666 var search64bit = false; 1743 var search64bit = false;
1667 1744
1668 foreach (var attrib in node.Attributes()) 1745 foreach (var attrib in node.Attributes())
@@ -1688,13 +1765,13 @@ namespace WixToolset.Core
1688 switch (typeValue) 1765 switch (typeValue)
1689 { 1766 {
1690 case "directory": 1767 case "directory":
1691 type = 0; 1768 type = RegLocatorType.Directory;
1692 break; 1769 break;
1693 case "file": 1770 case "file":
1694 type = 1; 1771 type = RegLocatorType.FileName;
1695 break; 1772 break;
1696 case "raw": 1773 case "raw":
1697 type = 2; 1774 type = RegLocatorType.Raw;
1698 break; 1775 break;
1699 case "": 1776 case "":
1700 break; 1777 break;
@@ -1738,7 +1815,7 @@ namespace WixToolset.Core
1738 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Root")); 1815 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Root"));
1739 } 1816 }
1740 1817
1741 if (CompilerConstants.IntegerNotSet == type) 1818 if (!type.HasValue)
1742 { 1819 {
1743 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Type")); 1820 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Type"));
1744 } 1821 }
@@ -1776,7 +1853,7 @@ namespace WixToolset.Core
1776 } 1853 }
1777 oneChild = true; 1854 oneChild = true;
1778 signature = this.ParseFileSearchElement(child, id.Id, false, CompilerConstants.IntegerNotSet); 1855 signature = this.ParseFileSearchElement(child, id.Id, false, CompilerConstants.IntegerNotSet);
1779 id = new Identifier(signature, AccessModifier.Private); // FileSearch signatures override parent signatures 1856 id = new Identifier(AccessModifier.Private, signature); // FileSearch signatures override parent signatures
1780 break; 1857 break;
1781 case "FileSearchRef": 1858 case "FileSearchRef":
1782 if (oneChild) 1859 if (oneChild)
@@ -1785,7 +1862,7 @@ namespace WixToolset.Core
1785 } 1862 }
1786 oneChild = true; 1863 oneChild = true;
1787 var newId = this.ParseSimpleRefElement(child, "Signature"); // FileSearch signatures override parent signatures 1864 var newId = this.ParseSimpleRefElement(child, "Signature"); // FileSearch signatures override parent signatures
1788 id = new Identifier(newId, AccessModifier.Private); 1865 id = new Identifier(AccessModifier.Private, newId);
1789 signature = null; 1866 signature = null;
1790 break; 1867 break;
1791 default: 1868 default:
@@ -1799,14 +1876,18 @@ namespace WixToolset.Core
1799 } 1876 }
1800 } 1877 }
1801 1878
1802
1803 if (!this.Core.EncounteredError) 1879 if (!this.Core.EncounteredError)
1804 { 1880 {
1805 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.RegLocator, id); 1881 var tuple = new RegLocatorTuple(sourceLineNumbers, id)
1806 row.Set(1, (int)root); 1882 {
1807 row.Set(2, key); 1883 Root = root.Value,
1808 row.Set(3, name); 1884 Key = key,
1809 row.Set(4, search64bit ? (type | 16) : type); 1885 Name = name,
1886 Type = type.Value,
1887 Win64 = search64bit
1888 };
1889
1890 this.Core.AddTuple(tuple);
1810 } 1891 }
1811 1892
1812 return signature; 1893 return signature;
@@ -2017,8 +2098,7 @@ namespace WixToolset.Core
2017 2098
2018 if (!this.Core.EncounteredError) 2099 if (!this.Core.EncounteredError)
2019 { 2100 {
2020 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CCPSearch); 2101 this.Core.AddTuple(new CCPSearchTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, signature)));
2021 row.Set(0, signature);
2022 } 2102 }
2023 } 2103 }
2024 2104
@@ -2044,7 +2124,7 @@ namespace WixToolset.Core
2044 var guid = "*"; 2124 var guid = "*";
2045 var componentIdPlaceholder = String.Format(Compiler.DefaultComponentIdPlaceholderFormat, this.componentIdPlaceholdersResolver.VariableCount); // placeholder id for defaulting Component/@Id to keypath id. 2125 var componentIdPlaceholder = String.Format(Compiler.DefaultComponentIdPlaceholderFormat, this.componentIdPlaceholdersResolver.VariableCount); // placeholder id for defaulting Component/@Id to keypath id.
2046 var componentIdPlaceholderWixVariable = String.Format(Compiler.DefaultComponentIdPlaceholderWixVariableFormat, componentIdPlaceholder); 2126 var componentIdPlaceholderWixVariable = String.Format(Compiler.DefaultComponentIdPlaceholderWixVariableFormat, componentIdPlaceholder);
2047 var id = new Identifier(componentIdPlaceholderWixVariable, AccessModifier.Private); 2127 var id = new Identifier(AccessModifier.Private, componentIdPlaceholderWixVariable);
2048 var keyFound = false; 2128 var keyFound = false;
2049 string keyPath = null; 2129 string keyPath = null;
2050 var shouldAddCreateFolder = false; 2130 var shouldAddCreateFolder = false;
@@ -2402,9 +2482,13 @@ namespace WixToolset.Core
2402 2482
2403 if (shouldAddCreateFolder) 2483 if (shouldAddCreateFolder)
2404 { 2484 {
2405 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CreateFolder, new Identifier(AccessModifier.Public, directoryId, id.Id)); 2485 var tuple = new CreateFolderTuple(sourceLineNumbers)
2406 row.Set(0, directoryId); 2486 {
2407 row.Set(1, id.Id); 2487 Directory_ = directoryId,
2488 Component_ = id.Id
2489 };
2490
2491 this.Core.AddTuple(tuple);
2408 } 2492 }
2409 2493
2410 // check for conditions that exclude this component from using generated guids 2494 // check for conditions that exclude this component from using generated guids
@@ -2439,7 +2523,7 @@ namespace WixToolset.Core
2439 { 2523 {
2440 this.componentIdPlaceholdersResolver.AddVariable(sourceLineNumbers, componentIdPlaceholder, keyPath, false); 2524 this.componentIdPlaceholdersResolver.AddVariable(sourceLineNumbers, componentIdPlaceholder, keyPath, false);
2441 2525
2442 id = new Identifier(keyPath, AccessModifier.Private); 2526 id = new Identifier(AccessModifier.Private, keyPath);
2443 } 2527 }
2444 else 2528 else
2445 { 2529 {
@@ -2458,7 +2542,6 @@ namespace WixToolset.Core
2458 { 2542 {
2459 var tuple = new ComponentTuple(sourceLineNumbers, id) 2543 var tuple = new ComponentTuple(sourceLineNumbers, id)
2460 { 2544 {
2461 Component = id.Id,
2462 ComponentId = guid, 2545 ComponentId = guid,
2463 Directory_ = directoryId, 2546 Directory_ = directoryId,
2464 Location = location, 2547 Location = location,
@@ -2472,35 +2555,29 @@ namespace WixToolset.Core
2472 Shared = shared, 2555 Shared = shared,
2473 Transitive = transitive, 2556 Transitive = transitive,
2474 UninstallWhenSuperseded = uninstallWhenSuperseded, 2557 UninstallWhenSuperseded = uninstallWhenSuperseded,
2475 Win64 = win64, 2558 Win64 = win64
2476 }; 2559 };
2477 2560
2478 this.Core.AddTuple(tuple); 2561 this.Core.AddTuple(tuple);
2479 2562
2480 //var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Component, id);
2481 //row.Set(1, guid);
2482 //row.Set(2, directoryId);
2483 //row.Set(3, bits | keyBits);
2484 //row.Set(4, condition);
2485 //row.Set(5, keyPath);
2486
2487 if (multiInstance) 2563 if (multiInstance)
2488 { 2564 {
2489 //var instanceComponentRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixInstanceComponent, id); 2565 this.Core.AddTuple(new WixInstanceComponentTuple(sourceLineNumbers, id)
2490
2491 var instanceComponentTuple = new WixInstanceComponentTuple(sourceLineNumbers, id)
2492 { 2566 {
2493 Component_ = id.Id, 2567 Component_ = id.Id,
2494 }; 2568 });
2495
2496 this.Core.AddTuple(instanceComponentTuple);
2497 } 2569 }
2498 2570
2499 if (0 < symbols.Count) 2571 if (0 < symbols.Count)
2500 { 2572 {
2501 var symbolRow = (WixDeltaPatchSymbolPathsTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchSymbolPaths, id); 2573 var tupleDelaPatch = new WixDeltaPatchSymbolPathsTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, SymbolPathType.Component, id.Id))
2502 symbolRow.Type = SymbolPathType.Component; 2574 {
2503 symbolRow.SymbolPaths = String.Join(";", symbols); 2575 SymbolType = SymbolPathType.Component,
2576 SymbolId = id.Id,
2577 SymbolPaths = String.Join(";", symbols)
2578 };
2579
2580 this.Core.AddTuple(tupleDelaPatch);
2504 } 2581 }
2505 2582
2506 // Complus 2583 // Complus
@@ -2607,7 +2684,7 @@ namespace WixToolset.Core
2607 2684
2608 if (!this.Core.EncounteredError) 2685 if (!this.Core.EncounteredError)
2609 { 2686 {
2610 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixComponentGroup, id); 2687 this.Core.AddTuple(new WixComponentGroupTuple(sourceLineNumbers, id));
2611 2688
2612 // Add this componentGroup and its parent in WixGroup. 2689 // Add this componentGroup and its parent in WixGroup.
2613 this.Core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.ComponentGroup, id.Id); 2690 this.Core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.ComponentGroup, id.Id);
@@ -2802,7 +2879,7 @@ namespace WixToolset.Core
2802 } 2879 }
2803 oneChild = true; 2880 oneChild = true;
2804 signature = this.ParseFileSearchElement(child, id.Id, false, CompilerConstants.IntegerNotSet); 2881 signature = this.ParseFileSearchElement(child, id.Id, false, CompilerConstants.IntegerNotSet);
2805 id = new Identifier(signature, AccessModifier.Private); // FileSearch signatures override parent signatures 2882 id = new Identifier(AccessModifier.Private, signature); // FileSearch signatures override parent signatures
2806 break; 2883 break;
2807 case "FileSearchRef": 2884 case "FileSearchRef":
2808 if (oneChild) 2885 if (oneChild)
@@ -2811,7 +2888,7 @@ namespace WixToolset.Core
2811 } 2888 }
2812 oneChild = true; 2889 oneChild = true;
2813 var newId = this.ParseSimpleRefElement(child, "Signature"); // FileSearch signatures override parent signatures 2890 var newId = this.ParseSimpleRefElement(child, "Signature"); // FileSearch signatures override parent signatures
2814 id = new Identifier(newId, AccessModifier.Private); 2891 id = new Identifier(AccessModifier.Private, newId);
2815 signature = null; 2892 signature = null;
2816 break; 2893 break;
2817 default: 2894 default:
@@ -2903,9 +2980,13 @@ namespace WixToolset.Core
2903 2980
2904 if (!this.Core.EncounteredError) 2981 if (!this.Core.EncounteredError)
2905 { 2982 {
2906 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CreateFolder, new Identifier(AccessModifier.Public, directoryId, componentId)); 2983 var tuple = new CreateFolderTuple(sourceLineNumbers)
2907 row.Set(0, directoryId); 2984 {
2908 row.Set(1, componentId); 2985 Directory_ = directoryId,
2986 Component_ = componentId
2987 };
2988
2989 this.Core.AddTuple(tuple);
2909 } 2990 }
2910 2991
2911 return directoryId; 2992 return directoryId;
@@ -3026,32 +3107,17 @@ namespace WixToolset.Core
3026 3107
3027 if (!this.Core.EncounteredError) 3108 if (!this.Core.EncounteredError)
3028 { 3109 {
3029 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MoveFile, id); 3110 var tuple = new MoveFileTuple(sourceLineNumbers, id)
3030 row.Set(1, componentId);
3031 row.Set(2, sourceName);
3032 row.Set(3, String.IsNullOrEmpty(destinationShortName) && String.IsNullOrEmpty(destinationName) ? null : this.GetMsiFilenameValue(destinationShortName, destinationName));
3033 if (null != sourceDirectory)
3034 {
3035 row.Set(4, sourceDirectory);
3036 }
3037 else if (null != sourceProperty)
3038 { 3111 {
3039 row.Set(4, sourceProperty); 3112 Component_ = componentId,
3040 } 3113 SourceName = sourceName,
3041 else 3114 DestName= String.IsNullOrEmpty(destinationShortName) && String.IsNullOrEmpty(destinationName) ? null : this.GetMsiFilenameValue(destinationShortName, destinationName),
3042 { 3115 SourceFolder = sourceDirectory ?? sourceProperty,
3043 row.Set(4, sourceFolder); 3116 DestFolder = destinationDirectory ?? destinationProperty,
3044 } 3117 Delete = delete
3118 };
3045 3119
3046 if (null != destinationDirectory) 3120 this.Core.AddTuple(tuple);
3047 {
3048 row.Set(5, destinationDirectory);
3049 }
3050 else
3051 {
3052 row.Set(5, destinationProperty);
3053 }
3054 row.Set(6, delete ? 1 : 0);
3055 } 3121 }
3056 } 3122 }
3057 else // copy the file 3123 else // copy the file
@@ -3088,18 +3154,15 @@ namespace WixToolset.Core
3088 3154
3089 if (!this.Core.EncounteredError) 3155 if (!this.Core.EncounteredError)
3090 { 3156 {
3091 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.DuplicateFile, id); 3157 var tuple = new DuplicateFileTuple(sourceLineNumbers, id)
3092 row.Set(1, componentId);
3093 row.Set(2, fileId);
3094 row.Set(3, String.IsNullOrEmpty(destinationShortName) && String.IsNullOrEmpty(destinationName) ? null : this.GetMsiFilenameValue(destinationShortName, destinationName));
3095 if (null != destinationDirectory)
3096 {
3097 row.Set(4, destinationDirectory);
3098 }
3099 else
3100 { 3158 {
3101 row.Set(4, destinationProperty); 3159 Component_ = componentId,
3102 } 3160 File_ = fileId,
3161 DestName = String.IsNullOrEmpty(destinationShortName) && String.IsNullOrEmpty(destinationName) ? null : this.GetMsiFilenameValue(destinationShortName, destinationName),
3162 DestFolder = destinationDirectory ?? destinationProperty
3163 };
3164
3165 this.Core.AddTuple(tuple);
3103 } 3166 }
3104 } 3167 }
3105 } 3168 }
@@ -3499,20 +3562,12 @@ namespace WixToolset.Core
3499 TSAware = tsAware, 3562 TSAware = tsAware,
3500 Win64 = win64, 3563 Win64 = win64,
3501 }; 3564 };
3502 //var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CustomAction, id);
3503 //row.Set(1, bits | sourceBits | targetBits);
3504 //row.Set(2, source);
3505 //row.Set(3, target);
3506 //if (0 != extendedBits)
3507 //{
3508 // row.Set(4, extendedBits);
3509 //}
3510 3565
3511 this.Core.AddTuple(tuple); 3566 this.Core.AddTuple(tuple);
3512 3567
3513 if (YesNoType.Yes == suppressModularization) 3568 if (YesNoType.Yes == suppressModularization)
3514 { 3569 {
3515 this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixSuppressModularization, id); 3570 this.Core.AddTuple(new WixSuppressModularizationTuple(sourceLineNumbers, id));
3516 } 3571 }
3517 3572
3518 // For deferred CAs that specify HideTarget we should also hide the CA data property for the action. 3573 // For deferred CAs that specify HideTarget we should also hide the CA data property for the action.
@@ -3619,124 +3674,6 @@ namespace WixToolset.Core
3619 } 3674 }
3620 3675
3621 /// <summary> 3676 /// <summary>
3622 /// Parses a PatchFamilyGroup element.
3623 /// </summary>
3624 /// <param name="node">Element to parse.</param>
3625 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
3626 private void ParsePatchFamilyGroupElement(XElement node, ComplexReferenceParentType parentType, string parentId)
3627 {
3628 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
3629 Identifier id = null;
3630
3631 foreach (var attrib in node.Attributes())
3632 {
3633 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
3634 {
3635 switch (attrib.Name.LocalName)
3636 {
3637 case "Id":
3638 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
3639 break;
3640 default:
3641 this.Core.UnexpectedAttribute(node, attrib);
3642 break;
3643 }
3644 }
3645 else
3646 {
3647 this.Core.ParseExtensionAttribute(node, attrib);
3648 }
3649 }
3650
3651 if (null == id)
3652 {
3653 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
3654 id = Identifier.Invalid;
3655 }
3656
3657 foreach (var child in node.Elements())
3658 {
3659 if (CompilerCore.WixNamespace == child.Name.Namespace)
3660 {
3661 switch (child.Name.LocalName)
3662 {
3663 case "PatchFamily":
3664 this.ParsePatchFamilyElement(child, ComplexReferenceParentType.PatchFamilyGroup, id.Id);
3665 break;
3666 case "PatchFamilyRef":
3667 this.ParsePatchFamilyRefElement(child, ComplexReferenceParentType.PatchFamilyGroup, id.Id);
3668 break;
3669 case "PatchFamilyGroupRef":
3670 this.ParsePatchFamilyGroupRefElement(child, ComplexReferenceParentType.PatchFamilyGroup, id.Id);
3671 break;
3672 default:
3673 this.Core.UnexpectedElement(node, child);
3674 break;
3675 }
3676 }
3677 else
3678 {
3679 this.Core.ParseExtensionElement(node, child);
3680 }
3681 }
3682
3683 if (!this.Core.EncounteredError)
3684 {
3685 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchFamilyGroup, id);
3686
3687 //Add this PatchFamilyGroup and its parent in WixGroup.
3688 this.Core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.PatchFamilyGroup, id.Id);
3689 }
3690 }
3691
3692 /// <summary>
3693 /// Parses a PatchFamilyGroup reference element.
3694 /// </summary>
3695 /// <param name="node">Element to parse.</param>
3696 /// <param name="parentType">The type of parent.</param>
3697 /// <param name="parentId">Identifier of parent element.</param>
3698 private void ParsePatchFamilyGroupRefElement(XElement node, ComplexReferenceParentType parentType, string parentId)
3699 {
3700 Debug.Assert(ComplexReferenceParentType.PatchFamilyGroup == parentType || ComplexReferenceParentType.Patch == parentType);
3701
3702 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
3703 string id = null;
3704
3705 foreach (var attrib in node.Attributes())
3706 {
3707 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
3708 {
3709 switch (attrib.Name.LocalName)
3710 {
3711 case "Id":
3712 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3713 this.Core.CreateSimpleReference(sourceLineNumbers, "WixPatchFamilyGroup", id);
3714 break;
3715 default:
3716 this.Core.UnexpectedAttribute(node, attrib);
3717 break;
3718 }
3719 }
3720 else
3721 {
3722 this.Core.ParseExtensionAttribute(node, attrib);
3723 }
3724 }
3725
3726 if (null == id)
3727 {
3728 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
3729 }
3730
3731 this.Core.ParseForExtensionElements(node);
3732
3733 if (!this.Core.EncounteredError)
3734 {
3735 this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.PatchFamilyGroup, id, true);
3736 }
3737 }
3738
3739 /// <summary>
3740 /// Parses an ensure table element. 3677 /// Parses an ensure table element.
3741 /// </summary> 3678 /// </summary>
3742 /// <param name="node">Element to parse.</param> 3679 /// <param name="node">Element to parse.</param>
@@ -4022,9 +3959,11 @@ namespace WixToolset.Core
4022 3959
4023 if (!this.Core.EncounteredError) 3960 if (!this.Core.EncounteredError)
4024 { 3961 {
4025 var rowRow = this.Core.CreateRow(childSourceLineNumbers, TupleDefinitionType.WixCustomRow); 3962 this.Core.AddTuple(new WixCustomRowTuple(childSourceLineNumbers)
4026 rowRow.Set(0, tableId); 3963 {
4027 rowRow.Set(1, dataValue); 3964 Table = tableId,
3965 FieldData = dataValue
3966 });
4028 } 3967 }
4029 break; 3968 break;
4030 default: 3969 default:
@@ -4047,21 +3986,24 @@ namespace WixToolset.Core
4047 3986
4048 if (!this.Core.EncounteredError) 3987 if (!this.Core.EncounteredError)
4049 { 3988 {
4050 var id = new Identifier(tableId, AccessModifier.Public); 3989 var tuple = new WixCustomTableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, tableId))
4051 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixCustomTable, id); 3990 {
4052 row.Set(1, columnCount); 3991 ColumnCount = columnCount,
4053 row.Set(2, columnNames); 3992 ColumnNames = columnNames,
4054 row.Set(3, columnTypes); 3993 ColumnTypes = columnTypes,
4055 row.Set(4, primaryKeys); 3994 PrimaryKeys = primaryKeys,
4056 row.Set(5, minValues); 3995 MinValues = minValues,
4057 row.Set(6, maxValues); 3996 MaxValues = maxValues,
4058 row.Set(7, keyTables); 3997 KeyTables = keyTables,
4059 row.Set(8, keyColumns); 3998 KeyColumns = keyColumns,
4060 row.Set(9, categories); 3999 Categories = categories,
4061 row.Set(10, sets); 4000 Sets = sets,
4062 row.Set(11, descriptions); 4001 Descriptions = descriptions,
4063 row.Set(12, modularizations); 4002 Modularizations = modularizations,
4064 row.Set(13, bootstrapperApplicationData ? 1 : 0); 4003 BootstrapperApplicationData = bootstrapperApplicationData
4004 };
4005
4006 this.Core.AddTuple(tuple);
4065 } 4007 }
4066 } 4008 }
4067 } 4009 }
@@ -4315,22 +4257,23 @@ namespace WixToolset.Core
4315 4257
4316 if (!this.Core.EncounteredError) 4258 if (!this.Core.EncounteredError)
4317 { 4259 {
4318 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Directory, id); 4260 var tuple = new DirectoryTuple(sourceLineNumbers, id)
4319 row.Set(1, parentId);
4320 row.Set(2, defaultDir);
4321
4322 if (null != componentGuidGenerationSeed)
4323 { 4261 {
4324 var wixRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDirectory); 4262 Directory_Parent = parentId,
4325 wixRow.Set(0, id.Id); 4263 DefaultDir = defaultDir,
4326 wixRow.Set(1, componentGuidGenerationSeed); 4264 ComponentGuidGenerationSeed = componentGuidGenerationSeed
4327 } 4265 };
4266
4267 this.Core.AddTuple(tuple);
4328 4268
4329 if (null != symbols) 4269 if (null != symbols)
4330 { 4270 {
4331 var symbolRow = (WixDeltaPatchSymbolPathsTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchSymbolPaths, id); 4271 this.Core.AddTuple(new WixDeltaPatchSymbolPathsTuple(sourceLineNumbers, id)
4332 symbolRow.Type = SymbolPathType.Directory; 4272 {
4333 symbolRow.SymbolPaths = symbols; 4273 SymbolType = SymbolPathType.Directory,
4274 SymbolId = id.Id,
4275 SymbolPaths = symbols,
4276 });
4334 } 4277 }
4335 } 4278 }
4336 } 4279 }
@@ -4547,14 +4490,19 @@ namespace WixToolset.Core
4547 signature = id.Id; 4490 signature = id.Id;
4548 } 4491 }
4549 4492
4550 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.DrLocator, new Identifier(access, rowId, parentSignature, path)); 4493 var tuple = new DrLocatorTuple(sourceLineNumbers)
4551 row.Set(0, rowId); 4494 {
4552 row.Set(1, parentSignature); 4495 Signature_ = rowId,
4553 row.Set(2, path); 4496 Parent = parentSignature,
4497 Path = path,
4498 };
4499
4554 if (CompilerConstants.IntegerNotSet != depth) 4500 if (CompilerConstants.IntegerNotSet != depth)
4555 { 4501 {
4556 row.Set(3, depth); 4502 tuple.Depth = depth;
4557 } 4503 }
4504
4505 this.Core.AddTuple(tuple);
4558 } 4506 }
4559 4507
4560 return signature; 4508 return signature;
@@ -5144,7 +5092,7 @@ namespace WixToolset.Core
5144 5092
5145 if (!this.Core.EncounteredError) 5093 if (!this.Core.EncounteredError)
5146 { 5094 {
5147 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixFeatureGroup, id); 5095 this.Core.AddTuple(new WixFeatureGroupTuple(sourceLineNumbers, id));
5148 5096
5149 //Add this FeatureGroup and its parent in WixGroup. 5097 //Add this FeatureGroup and its parent in WixGroup.
5150 this.Core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.FeatureGroup, id.Id); 5098 this.Core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.FeatureGroup, id.Id);
@@ -5403,8 +5351,13 @@ namespace WixToolset.Core
5403 5351
5404 if (!this.Core.EncounteredError) 5352 if (!this.Core.EncounteredError)
5405 { 5353 {
5406 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Error, new Identifier(AccessModifier.Public, id)); 5354 var tuple = new ErrorTuple(sourceLineNumbers)
5407 row.Set(1, Common.GetInnerText(node)); // TODO: * 5355 {
5356 Error = id,
5357 Message = Common.GetInnerText(node)
5358 };
5359
5360 this.Core.AddTuple(tuple);
5408 } 5361 }
5409 } 5362 }
5410 5363
@@ -5490,12 +5443,16 @@ namespace WixToolset.Core
5490 { 5443 {
5491 if (!this.Core.EncounteredError) 5444 if (!this.Core.EncounteredError)
5492 { 5445 {
5493 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Extension); 5446 var tuple = new ExtensionTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, extension, componentId))
5494 row.Set(0, extension); 5447 {
5495 row.Set(1, componentId); 5448 Extension = extension,
5496 row.Set(2, progId); 5449 Component_ = componentId,
5497 row.Set(3, mime); 5450 ProgId_ = progId,
5498 row.Set(4, Guid.Empty.ToString("B")); 5451 MIME_ = mime,
5452 Feature_ = Guid.Empty.ToString("B")
5453 };
5454
5455 this.Core.AddTuple(tuple);
5499 5456
5500 this.Core.EnsureTable(sourceLineNumbers, "Verb"); 5457 this.Core.EnsureTable(sourceLineNumbers, "Verb");
5501 } 5458 }
@@ -5560,7 +5517,7 @@ namespace WixToolset.Core
5560 string symbols = null; 5517 string symbols = null;
5561 5518
5562 string procArch = null; 5519 string procArch = null;
5563 var selfRegCost = CompilerConstants.IntegerNotSet; 5520 int? selfRegCost = null;
5564 string shortName = null; 5521 string shortName = null;
5565 var source = sourcePath; // assume we'll use the parents as the source for this file 5522 var source = sourcePath; // assume we'll use the parents as the source for this file
5566 var sourceSet = false; 5523 var sourceSet = false;
@@ -5914,30 +5871,29 @@ namespace WixToolset.Core
5914 } 5871 }
5915 } 5872 }
5916 5873
5917 var fileRow = (FileTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.File, id); 5874 var tuple = new FileTuple(sourceLineNumbers, id)
5918 fileRow.Component_ = componentId;
5919 //fileRow.FileName = GetMsiFilenameValue(shortName, name);
5920 fileRow.ShortFileName = shortName;
5921 fileRow.LongFileName = name;
5922 fileRow.FileSize = defaultSize;
5923 if (null != companionFile)
5924 {
5925 fileRow.Version = companionFile;
5926 }
5927 else if (null != defaultVersion)
5928 { 5875 {
5929 fileRow.Version = defaultVersion; 5876 Component_ = componentId,
5930 } 5877 ShortFileName = shortName,
5931 fileRow.Language = defaultLanguage; 5878 LongFileName = name,
5932 fileRow.ReadOnly = readOnly; 5879 FileSize = defaultSize,
5933 fileRow.Checksum = checksum; 5880 Version = companionFile ?? defaultVersion,
5934 fileRow.Compressed = compressed; 5881 Language = defaultLanguage,
5935 fileRow.Hidden = hidden; 5882 ReadOnly = readOnly,
5936 fileRow.System = system; 5883 Hidden = hidden,
5937 fileRow.Vital = vital; 5884 System = system,
5938 // the Sequence row is set in the binder 5885 Vital = vital,
5886 Checksum = checksum,
5887 Compressed = compressed,
5888 FontTitle = fontTitle,
5889 SelfRegCost = selfRegCost,
5890 BindPath = bindPath,
5891 };
5892
5893 this.Core.AddTuple(tuple);
5939 5894
5940 var wixFileRow = (WixFileTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixFile, id); 5895 // TODO: Remove all this.
5896 var wixFileRow = (WixFileTuple)this.Core.CreateTuple(sourceLineNumbers, TupleDefinitionType.WixFile, id);
5941 wixFileRow.AssemblyType = assemblyType; 5897 wixFileRow.AssemblyType = assemblyType;
5942 wixFileRow.File_AssemblyManifest = assemblyManifest; 5898 wixFileRow.File_AssemblyManifest = assemblyManifest;
5943 wixFileRow.File_AssemblyApplication = assemblyApplication; 5899 wixFileRow.File_AssemblyApplication = assemblyApplication;
@@ -5951,50 +5907,34 @@ namespace WixToolset.Core
5951 5907
5952 // Always create a delta patch row for this file since other elements (like Component and Media) may 5908 // Always create a delta patch row for this file since other elements (like Component and Media) may
5953 // want to add symbol paths to it. 5909 // want to add symbol paths to it.
5954 var deltaPatchFileRow = (WixDeltaPatchFileTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchFile, id); 5910 this.Core.AddTuple(new WixDeltaPatchFileTuple(sourceLineNumbers, id)
5955 deltaPatchFileRow.RetainLengths = protectLengths; 5911 {
5956 deltaPatchFileRow.IgnoreOffsets = ignoreOffsets; 5912 RetainLengths = protectLengths,
5957 deltaPatchFileRow.IgnoreLengths = ignoreLengths; 5913 IgnoreOffsets = ignoreOffsets,
5958 deltaPatchFileRow.RetainOffsets = protectOffsets; 5914 IgnoreLengths = ignoreLengths,
5915 RetainOffsets = protectOffsets
5916 });
5959 5917
5960 if (null != symbols) 5918 if (null != symbols)
5961 { 5919 {
5962 var symbolRow = (WixDeltaPatchSymbolPathsTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchSymbolPaths, id); 5920 this.Core.AddTuple(new WixDeltaPatchSymbolPathsTuple(sourceLineNumbers)
5963 symbolRow.Type = SymbolPathType.File; 5921 {
5964 symbolRow.SymbolPaths = symbols; 5922 SymbolType = SymbolPathType.File,
5923 SymbolId = id.Id,
5924 SymbolPaths = symbols
5925 });
5965 } 5926 }
5966 5927
5967 if (FileAssemblyType.NotAnAssembly != assemblyType) 5928 if (FileAssemblyType.NotAnAssembly != assemblyType)
5968 { 5929 {
5969 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiAssembly); 5930 this.Core.AddTuple(new MsiAssemblyTuple(sourceLineNumbers)
5970 row.Set(0, componentId); 5931 {
5971 row.Set(1, Guid.Empty.ToString("B")); 5932 Component_ = componentId,
5972 row.Set(2, assemblyManifest); 5933 Feature_ = Guid.Empty.ToString("B"),
5973 row.Set(3, assemblyApplication); 5934 File_Manifest = assemblyManifest,
5974 row.Set(4, (FileAssemblyType.DotNetAssembly == assemblyType) ? 0 : 1); 5935 File_Application = assemblyApplication,
5975 } 5936 Type = assemblyType
5976 5937 });
5977 if (null != bindPath)
5978 {
5979 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.BindImage);
5980 row.Set(0, id.Id);
5981 row.Set(1, bindPath);
5982
5983 // TODO: technically speaking each of the properties in the "bindPath" should be added as references, but how much do we really care about BindImage?
5984 }
5985
5986 if (CompilerConstants.IntegerNotSet != selfRegCost)
5987 {
5988 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.SelfReg);
5989 row.Set(0, id.Id);
5990 row.Set(1, selfRegCost);
5991 }
5992
5993 if (null != fontTitle)
5994 {
5995 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Font);
5996 row.Set(0, id.Id);
5997 row.Set(1, fontTitle);
5998 } 5938 }
5999 } 5939 }
6000 5940
@@ -6110,7 +6050,7 @@ namespace WixToolset.Core
6110 } 6050 }
6111 else // reuse parent signature in the Signature table 6051 else // reuse parent signature in the Signature table
6112 { 6052 {
6113 id = new Identifier(parentSignature, AccessModifier.Private); 6053 id = new Identifier(AccessModifier.Private, parentSignature);
6114 } 6054 }
6115 } 6055 }
6116 6056
@@ -6138,28 +6078,35 @@ namespace WixToolset.Core
6138 6078
6139 if (!this.Core.EncounteredError) 6079 if (!this.Core.EncounteredError)
6140 { 6080 {
6141 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Signature, id); 6081 var tuple = new SignatureTuple(sourceLineNumbers, id)
6142 row.Set(1, name ?? shortName); 6082 {
6143 row.Set(2, minVersion); 6083 FileName = name ?? shortName,
6144 row.Set(3, maxVersion); 6084 MinVersion = minVersion,
6085 MaxVersion = maxVersion,
6086 Languages = languages
6087 };
6145 6088
6146 if (CompilerConstants.IntegerNotSet != minSize) 6089 if (CompilerConstants.IntegerNotSet != minSize)
6147 { 6090 {
6148 row.Set(4, minSize); 6091 tuple.MinSize = minSize;
6149 } 6092 }
6093
6150 if (CompilerConstants.IntegerNotSet != maxSize) 6094 if (CompilerConstants.IntegerNotSet != maxSize)
6151 { 6095 {
6152 row.Set(5, maxSize); 6096 tuple.MaxSize = maxSize;
6153 } 6097 }
6098
6154 if (CompilerConstants.IntegerNotSet != minDate) 6099 if (CompilerConstants.IntegerNotSet != minDate)
6155 { 6100 {
6156 row.Set(6, minDate); 6101 tuple.MinDate = minDate;
6157 } 6102 }
6103
6158 if (CompilerConstants.IntegerNotSet != maxDate) 6104 if (CompilerConstants.IntegerNotSet != maxDate)
6159 { 6105 {
6160 row.Set(7, maxDate); 6106 tuple.MaxDate = maxDate;
6161 } 6107 }
6162 row.Set(8, languages); 6108
6109 this.Core.AddTuple(tuple);
6163 6110
6164 // Create a DrLocator row to associate the file with a directory 6111 // Create a DrLocator row to associate the file with a directory
6165 // when a different identifier is specified for the FileSearch. 6112 // when a different identifier is specified for the FileSearch.
@@ -6169,15 +6116,19 @@ namespace WixToolset.Core
6169 { 6116 {
6170 // Creates the DrLocator row for the directory search while 6117 // Creates the DrLocator row for the directory search while
6171 // the parent DirectorySearch creates the file locator row. 6118 // the parent DirectorySearch creates the file locator row.
6172 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.DrLocator, new Identifier(AccessModifier.Public, parentSignature, id.Id, String.Empty)); 6119 this.Core.AddTuple(new DrLocatorTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, parentSignature, id.Id, String.Empty))
6173 row.Set(0, parentSignature); 6120 {
6174 row.Set(1, id.Id); 6121 Signature_ = parentSignature,
6122 Parent = id.Id
6123 });
6175 } 6124 }
6176 else 6125 else
6177 { 6126 {
6178 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.DrLocator, new Identifier(AccessModifier.Public, id.Id, parentSignature, String.Empty)); 6127 this.Core.AddTuple(new DrLocatorTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, id.Id, parentSignature, String.Empty))
6179 row.Set(0, id.Id); 6128 {
6180 row.Set(1, parentSignature); 6129 Signature_ = id.Id,
6130 Parent = parentSignature
6131 });
6181 } 6132 }
6182 } 6133 }
6183 } 6134 }
@@ -6193,7 +6144,7 @@ namespace WixToolset.Core
6193 private void ParseFragmentElement(XElement node) 6144 private void ParseFragmentElement(XElement node)
6194 { 6145 {
6195 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 6146 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
6196 string id = null; 6147 Identifier id = null;
6197 6148
6198 this.activeName = null; 6149 this.activeName = null;
6199 this.activeLanguage = null; 6150 this.activeLanguage = null;
@@ -6205,7 +6156,7 @@ namespace WixToolset.Core
6205 switch (attrib.Name.LocalName) 6156 switch (attrib.Name.LocalName)
6206 { 6157 {
6207 case "Id": 6158 case "Id":
6208 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); 6159 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
6209 break; 6160 break;
6210 default: 6161 default:
6211 this.Core.UnexpectedAttribute(node, attrib); 6162 this.Core.UnexpectedAttribute(node, attrib);
@@ -6220,7 +6171,7 @@ namespace WixToolset.Core
6220 6171
6221 // NOTE: Id is not required for Fragments, this is a departure from the normal run of the mill processing. 6172 // NOTE: Id is not required for Fragments, this is a departure from the normal run of the mill processing.
6222 6173
6223 this.Core.CreateActiveSection(id, SectionType.Fragment, 0, this.Context.CompilationId); 6174 this.Core.CreateActiveSection(id?.Id, SectionType.Fragment, 0, this.Context.CompilationId);
6224 6175
6225 var featureDisplay = 0; 6176 var featureDisplay = 0;
6226 foreach (var child in node.Elements()) 6177 foreach (var child in node.Elements())
@@ -6232,19 +6183,19 @@ namespace WixToolset.Core
6232 case "_locDefinition": 6183 case "_locDefinition":
6233 break; 6184 break;
6234 case "AdminExecuteSequence": 6185 case "AdminExecuteSequence":
6235 this.ParseSequenceElement(child, child.Name.LocalName); 6186 this.ParseSequenceElement(child, SequenceTable.AdminExecuteSequence);
6236 break; 6187 break;
6237 case "AdminUISequence": 6188 case "AdminUISequence":
6238 this.ParseSequenceElement(child, child.Name.LocalName); 6189 this.ParseSequenceElement(child, SequenceTable.AdminUISequence);
6239 break; 6190 break;
6240 case "AdvertiseExecuteSequence": 6191 case "AdvertiseExecuteSequence":
6241 this.ParseSequenceElement(child, child.Name.LocalName); 6192 this.ParseSequenceElement(child, SequenceTable.AdvertiseExecuteSequence);
6242 break; 6193 break;
6243 case "InstallExecuteSequence": 6194 case "InstallExecuteSequence":
6244 this.ParseSequenceElement(child, child.Name.LocalName); 6195 this.ParseSequenceElement(child, SequenceTable.InstallExecuteSequence);
6245 break; 6196 break;
6246 case "InstallUISequence": 6197 case "InstallUISequence":
6247 this.ParseSequenceElement(child, child.Name.LocalName); 6198 this.ParseSequenceElement(child, SequenceTable.InstallUISequence);
6248 break; 6199 break;
6249 case "AppId": 6200 case "AppId":
6250 this.ParseAppIdElement(child, null, YesNoType.Yes, null, null, null); 6201 this.ParseAppIdElement(child, null, YesNoType.Yes, null, null, null);
@@ -6265,7 +6216,7 @@ namespace WixToolset.Core
6265 this.ParseComponentElement(child, ComplexReferenceParentType.Unknown, null, null, CompilerConstants.IntegerNotSet, null, null); 6216 this.ParseComponentElement(child, ComplexReferenceParentType.Unknown, null, null, CompilerConstants.IntegerNotSet, null, null);
6266 break; 6217 break;
6267 case "ComponentGroup": 6218 case "ComponentGroup":
6268 this.ParseComponentGroupElement(child, ComplexReferenceParentType.Unknown, id); 6219 this.ParseComponentGroupElement(child, ComplexReferenceParentType.Unknown, id?.Id);
6269 break; 6220 break;
6270 case "Condition": 6221 case "Condition":
6271 this.ParseConditionElement(child, node.Name.LocalName, null, null); 6222 this.ParseConditionElement(child, node.Name.LocalName, null, null);
@@ -6301,7 +6252,7 @@ namespace WixToolset.Core
6301 this.ParseFeatureElement(child, ComplexReferenceParentType.Unknown, null, ref featureDisplay); 6252 this.ParseFeatureElement(child, ComplexReferenceParentType.Unknown, null, ref featureDisplay);
6302 break; 6253 break;
6303 case "FeatureGroup": 6254 case "FeatureGroup":
6304 this.ParseFeatureGroupElement(child, ComplexReferenceParentType.Unknown, id); 6255 this.ParseFeatureGroupElement(child, ComplexReferenceParentType.Unknown, id.Id);
6305 break; 6256 break;
6306 case "FeatureRef": 6257 case "FeatureRef":
6307 this.ParseFeatureRefElement(child, ComplexReferenceParentType.Unknown, null); 6258 this.ParseFeatureRefElement(child, ComplexReferenceParentType.Unknown, null);
@@ -6326,13 +6277,13 @@ namespace WixToolset.Core
6326 this.ParseCertificatesElement(child); 6277 this.ParseCertificatesElement(child);
6327 break; 6278 break;
6328 case "PatchFamily": 6279 case "PatchFamily":
6329 this.ParsePatchFamilyElement(child, ComplexReferenceParentType.Unknown, id); 6280 this.ParsePatchFamilyElement(child, ComplexReferenceParentType.Unknown, id.Id);
6330 break; 6281 break;
6331 case "PatchFamilyGroup": 6282 case "PatchFamilyGroup":
6332 this.ParsePatchFamilyGroupElement(child, ComplexReferenceParentType.Unknown, id); 6283 this.ParsePatchFamilyGroupElement(child, ComplexReferenceParentType.Unknown, id.Id);
6333 break; 6284 break;
6334 case "PatchFamilyGroupRef": 6285 case "PatchFamilyGroupRef":
6335 this.ParsePatchFamilyGroupRefElement(child, ComplexReferenceParentType.Unknown, id); 6286 this.ParsePatchFamilyGroupRefElement(child, ComplexReferenceParentType.Unknown, id.Id);
6336 break; 6287 break;
6337 case "PayloadGroup": 6288 case "PayloadGroup":
6338 this.ParsePayloadGroupElement(child, ComplexReferenceParentType.Unknown, null); 6289 this.ParsePayloadGroupElement(child, ComplexReferenceParentType.Unknown, null);
@@ -6384,8 +6335,7 @@ namespace WixToolset.Core
6384 6335
6385 if (!this.Core.EncounteredError && null != id) 6336 if (!this.Core.EncounteredError && null != id)
6386 { 6337 {
6387 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixFragment); 6338 this.Core.AddTuple(new WixFragmentTuple(sourceLineNumbers, id));
6388 row.Set(0, id);
6389 } 6339 }
6390 } 6340 }
6391 6341
@@ -6498,11 +6448,13 @@ namespace WixToolset.Core
6498 6448
6499 if (!this.Core.EncounteredError) 6449 if (!this.Core.EncounteredError)
6500 { 6450 {
6501 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ControlCondition); 6451 this.Core.AddTuple(new ControlConditionTuple(sourceLineNumbers)
6502 row.Set(0, dialog); 6452 {
6503 row.Set(1, id); 6453 Dialog_ = dialog,
6504 row.Set(2, action); 6454 Control_ = id,
6505 row.Set(3, condition); 6455 Action = action,
6456 Condition = condition,
6457 });
6506 } 6458 }
6507 break; 6459 break;
6508 case "Feature": 6460 case "Feature":
@@ -6514,10 +6466,12 @@ namespace WixToolset.Core
6514 6466
6515 if (!this.Core.EncounteredError) 6467 if (!this.Core.EncounteredError)
6516 { 6468 {
6517 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Condition); 6469 this.Core.AddTuple(new ConditionTuple(sourceLineNumbers)
6518 row.Set(0, id); 6470 {
6519 row.Set(1, level); 6471 Feature_ = id,
6520 row.Set(2, condition); 6472 Level = level,
6473 Condition = condition
6474 });
6521 } 6475 }
6522 break; 6476 break;
6523 case "Fragment": 6477 case "Fragment":
@@ -6529,9 +6483,11 @@ namespace WixToolset.Core
6529 6483
6530 if (!this.Core.EncounteredError) 6484 if (!this.Core.EncounteredError)
6531 { 6485 {
6532 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.LaunchCondition); 6486 this.Core.AddTuple(new LaunchConditionTuple(sourceLineNumbers)
6533 row.Set(0, condition); 6487 {
6534 row.Set(1, message); 6488 Condition = condition,
6489 Description = message
6490 });
6535 } 6491 }
6536 break; 6492 break;
6537 } 6493 }
@@ -6836,7 +6792,7 @@ namespace WixToolset.Core
6836 } 6792 }
6837 oneChild = true; 6793 oneChild = true;
6838 signature = this.ParseFileSearchElement(child, id.Id, false, CompilerConstants.IntegerNotSet); 6794 signature = this.ParseFileSearchElement(child, id.Id, false, CompilerConstants.IntegerNotSet);
6839 id = new Identifier(signature, AccessModifier.Private); // FileSearch signatures override parent signatures 6795 id = new Identifier(AccessModifier.Private, signature); // FileSearch signatures override parent signatures
6840 break; 6796 break;
6841 case "FileSearchRef": 6797 case "FileSearchRef":
6842 if (oneChild) 6798 if (oneChild)
@@ -6845,7 +6801,7 @@ namespace WixToolset.Core
6845 } 6801 }
6846 oneChild = true; 6802 oneChild = true;
6847 var newId = this.ParseSimpleRefElement(child, "Signature"); // FileSearch signatures override parent signatures 6803 var newId = this.ParseSimpleRefElement(child, "Signature"); // FileSearch signatures override parent signatures
6848 id = new Identifier(newId, AccessModifier.Private); 6804 id = new Identifier(AccessModifier.Private, newId);
6849 signature = null; 6805 signature = null;
6850 break; 6806 break;
6851 default: 6807 default:
@@ -6861,15 +6817,20 @@ namespace WixToolset.Core
6861 6817
6862 if (!this.Core.EncounteredError) 6818 if (!this.Core.EncounteredError)
6863 { 6819 {
6864 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.IniLocator, id); 6820 var tuple = new IniLocatorTuple(sourceLineNumbers, id)
6865 row.Set(1, this.GetMsiFilenameValue(shortName, name)); 6821 {
6866 row.Set(2, section); 6822 FileName = this.GetMsiFilenameValue(shortName, name),
6867 row.Set(3, key); 6823 Section = section,
6824 Key = key,
6825 Type = type
6826 };
6827
6868 if (CompilerConstants.IntegerNotSet != field) 6828 if (CompilerConstants.IntegerNotSet != field)
6869 { 6829 {
6870 row.Set(4, field); 6830 tuple.Field = field;
6871 } 6831 }
6872 row.Set(5, type); 6832
6833 this.Core.AddTuple(tuple);
6873 } 6834 }
6874 6835
6875 return signature; 6836 return signature;
@@ -6915,9 +6876,11 @@ namespace WixToolset.Core
6915 6876
6916 if (!this.Core.EncounteredError) 6877 if (!this.Core.EncounteredError)
6917 { 6878 {
6918 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.IsolatedComponent); 6879 this.Core.AddTuple(new IsolatedComponentTuple(sourceLineNumbers)
6919 row.Set(0, shared); 6880 {
6920 row.Set(1, componentId); 6881 Component_Shared = shared,
6882 Component_Application = componentId
6883 });
6921 } 6884 }
6922 } 6885 }
6923 6886
@@ -6953,9 +6916,9 @@ namespace WixToolset.Core
6953 6916
6954 if (!this.Core.EncounteredError) 6917 if (!this.Core.EncounteredError)
6955 { 6918 {
6956 var row = this.Core.CreateRow(sourceLineNumbers, "PatchCertificates" == node.Name.LocalName ? TupleDefinitionType.MsiPatchCertificate : TupleDefinitionType.MsiPackageCertificate); 6919 var tuple = this.Core.CreateTuple(sourceLineNumbers, "PatchCertificates" == node.Name.LocalName ? TupleDefinitionType.MsiPatchCertificate : TupleDefinitionType.MsiPackageCertificate);
6957 row.Set(0, name); 6920 tuple.Set(0, name);
6958 row.Set(1, name); 6921 tuple.Set(1, name);
6959 } 6922 }
6960 break; 6923 break;
6961 default: 6924 default:
@@ -7026,8 +6989,10 @@ namespace WixToolset.Core
7026 6989
7027 if (!this.Core.EncounteredError) 6990 if (!this.Core.EncounteredError)
7028 { 6991 {
7029 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiDigitalCertificate, id); 6992 this.Core.AddTuple(new MsiDigitalCertificateTuple(sourceLineNumbers, id)
7030 row.Set(1, sourceFile); 6993 {
6994 CertData = sourceFile
6995 });
7031 } 6996 }
7032 6997
7033 return id.Id; 6998 return id.Id;
@@ -7097,11 +7062,13 @@ namespace WixToolset.Core
7097 7062
7098 if (!this.Core.EncounteredError) 7063 if (!this.Core.EncounteredError)
7099 { 7064 {
7100 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiDigitalSignature); 7065 this.Core.AddTuple(new MsiDigitalSignatureTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "Media", diskId))
7101 row.Set(0, "Media"); 7066 {
7102 row.Set(1, diskId); 7067 Table = "Media",
7103 row.Set(2, certificateId); 7068 SignObject = diskId,
7104 row.Set(3, sourceFile); 7069 DigitalCertificate_ = certificateId,
7070 Hash = sourceFile
7071 });
7105 } 7072 }
7106 } 7073 }
7107 7074
@@ -7242,7 +7209,7 @@ namespace WixToolset.Core
7242 this.Core.AddTuple(tuple); 7209 this.Core.AddTuple(tuple);
7243 7210
7244 // Ensure the action property is secure. 7211 // Ensure the action property is secure.
7245 this.AddWixPropertyRow(sourceLineNumbers, new Identifier(Common.UpgradeDetectedProperty, AccessModifier.Public), false, true, false); 7212 this.AddWixPropertyRow(sourceLineNumbers, new Identifier(AccessModifier.Public, Common.UpgradeDetectedProperty), false, true, false);
7246 7213
7247 // Add launch condition that blocks upgrades 7214 // Add launch condition that blocks upgrades
7248 if (blockUpgrades) 7215 if (blockUpgrades)
@@ -7273,7 +7240,7 @@ namespace WixToolset.Core
7273 this.Core.AddTuple(upgradeTuple); 7240 this.Core.AddTuple(upgradeTuple);
7274 7241
7275 // Ensure the action property is secure. 7242 // Ensure the action property is secure.
7276 this.AddWixPropertyRow(sourceLineNumbers, new Identifier(Common.DowngradeDetectedProperty, AccessModifier.Public), false, true, false); 7243 this.AddWixPropertyRow(sourceLineNumbers, new Identifier(AccessModifier.Public, Common.DowngradeDetectedProperty), false, true, false);
7277 7244
7278 var conditionTuple = new LaunchConditionTuple(sourceLineNumbers) 7245 var conditionTuple = new LaunchConditionTuple(sourceLineNumbers)
7279 { 7246 {
@@ -7479,29 +7446,27 @@ namespace WixToolset.Core
7479 // add the row to the section 7446 // add the row to the section
7480 if (!this.Core.EncounteredError) 7447 if (!this.Core.EncounteredError)
7481 { 7448 {
7482 var mediaRow = (MediaTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Media, new Identifier(id, AccessModifier.Public)); 7449 var tuple = new MediaTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, id))
7483 mediaRow.LastSequence = 0; // this is set in the binder
7484 mediaRow.DiskPrompt = diskPrompt;
7485 mediaRow.Cabinet = cabinet;
7486 mediaRow.VolumeLabel = volumeLabel;
7487 mediaRow.Source = source;
7488
7489 // the Source column is only set when creating a patch
7490
7491 if (null != compressionLevel || null != layout)
7492 { 7450 {
7493 var row = (WixMediaTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixMedia); 7451 DiskId = id,
7494 row.DiskId_ = id; 7452 DiskPrompt = diskPrompt,
7495 row.CompressionLevel = compressionLevel; 7453 Cabinet = cabinet,
7496 row.Layout = layout; 7454 VolumeLabel = volumeLabel,
7497 } 7455 Source = source, // the Source column is only set when creating a patch
7456 CompressionLevel = compressionLevel,
7457 Layout = layout
7458 };
7459
7460 this.Core.AddTuple(tuple);
7498 7461
7499 if (null != symbols) 7462 if (null != symbols)
7500 { 7463 {
7501 var symbolRow = (WixDeltaPatchSymbolPathsTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchSymbolPaths); 7464 this.Core.AddTuple(new WixDeltaPatchSymbolPathsTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, SymbolPathType.Media, id))
7502 symbolRow.Id = id.ToString(CultureInfo.InvariantCulture); 7465 {
7503 symbolRow.Type = SymbolPathType.Media; 7466 SymbolType = SymbolPathType.Media,
7504 symbolRow.SymbolPaths = symbols; 7467 SymbolId = id.ToString(CultureInfo.InvariantCulture),
7468 SymbolPaths = symbols
7469 });
7505 } 7470 }
7506 } 7471 }
7507 } 7472 }
@@ -7518,8 +7483,8 @@ namespace WixToolset.Core
7518 string diskPrompt = null; 7483 string diskPrompt = null;
7519 var patch = null != patchId; 7484 var patch = null != patchId;
7520 string volumeLabel = null; 7485 string volumeLabel = null;
7521 var maximumUncompressedMediaSize = CompilerConstants.IntegerNotSet; 7486 int? maximumUncompressedMediaSize = null;
7522 var maximumCabinetSizeForLargeFileSplitting = CompilerConstants.IntegerNotSet; 7487 int? maximumCabinetSizeForLargeFileSplitting = null;
7523 CompressionLevel? compressionLevel = null; // this defaults to mszip in Binder 7488 CompressionLevel? compressionLevel = null; // this defaults to mszip in Binder
7524 7489
7525 var embedCab = patch ? YesNoType.Yes : YesNoType.NotSet; 7490 var embedCab = patch ? YesNoType.Yes : YesNoType.NotSet;
@@ -7572,7 +7537,7 @@ namespace WixToolset.Core
7572 maximumUncompressedMediaSize = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, Int32.MaxValue); 7537 maximumUncompressedMediaSize = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, Int32.MaxValue);
7573 break; 7538 break;
7574 case "MaximumCabinetSizeForLargeFileSplitting": 7539 case "MaximumCabinetSizeForLargeFileSplitting":
7575 maximumCabinetSizeForLargeFileSplitting = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, CompilerCore.MinValueOfMaxCabSizeForLargeFileSplitting, CompilerCore.MaxValueOfMaxCabSizeForLargeFileSplitting); 7540 maximumCabinetSizeForLargeFileSplitting = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, Compiler.MinValueOfMaxCabSizeForLargeFileSplitting, Compiler.MaxValueOfMaxCabSizeForLargeFileSplitting);
7576 break; 7541 break;
7577 default: 7542 default:
7578 this.Core.UnexpectedAttribute(node, attrib); 7543 this.Core.UnexpectedAttribute(node, attrib);
@@ -7585,46 +7550,39 @@ namespace WixToolset.Core
7585 } 7550 }
7586 } 7551 }
7587 7552
7588 if (YesNoType.IllegalValue != embedCab) 7553 if (YesNoType.Yes == embedCab)
7589 { 7554 {
7590 if (YesNoType.Yes == embedCab) 7555 cabinetTemplate = String.Concat("#", cabinetTemplate);
7591 {
7592 cabinetTemplate = String.Concat("#", cabinetTemplate);
7593 }
7594 } 7556 }
7595 7557
7596 if (!this.Core.EncounteredError) 7558 if (!this.Core.EncounteredError)
7597 { 7559 {
7598 var temporaryMediaRow = (MediaTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Media, new Identifier(1, AccessModifier.Public)); 7560 this.Core.AddTuple(new MediaTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, 1))
7599
7600 var mediaTemplateRow = (WixMediaTemplateTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixMediaTemplate);
7601 mediaTemplateRow.CabinetTemplate = cabinetTemplate;
7602 mediaTemplateRow.VolumeLabel = volumeLabel;
7603 mediaTemplateRow.DiskPrompt = diskPrompt;
7604 mediaTemplateRow.VolumeLabel = volumeLabel;
7605
7606 if (maximumUncompressedMediaSize != CompilerConstants.IntegerNotSet)
7607 { 7561 {
7608 mediaTemplateRow.MaximumUncompressedMediaSize = maximumUncompressedMediaSize; 7562 DiskId = 1
7609 } 7563 });
7610 else
7611 {
7612 mediaTemplateRow.MaximumUncompressedMediaSize = CompilerCore.DefaultMaximumUncompressedMediaSize;
7613 }
7614 7564
7615 if (maximumCabinetSizeForLargeFileSplitting != CompilerConstants.IntegerNotSet) 7565 var tuple = new WixMediaTemplateTuple(sourceLineNumbers)
7616 {
7617 mediaTemplateRow.MaximumCabinetSizeForLargeFileSplitting = maximumCabinetSizeForLargeFileSplitting;
7618 }
7619 else
7620 { 7566 {
7621 mediaTemplateRow.MaximumCabinetSizeForLargeFileSplitting = 0; // Default value of 0 corresponds to max size of 2048 MB (i.e. 2 GB) 7567 CabinetTemplate = cabinetTemplate,
7622 } 7568 VolumeLabel = volumeLabel,
7569 DiskPrompt = diskPrompt,
7570 MaximumUncompressedMediaSize = maximumUncompressedMediaSize,
7571 MaximumCabinetSizeForLargeFileSplitting = maximumCabinetSizeForLargeFileSplitting,
7572 CompressionLevel = compressionLevel
7573 };
7623 7574
7624 if (compressionLevel.HasValue) 7575 //else
7625 { 7576 //{
7626 mediaTemplateRow.CompressionLevel = compressionLevel.Value; 7577 // mediaTemplateRow.MaximumUncompressedMediaSize = CompilerCore.DefaultMaximumUncompressedMediaSize;
7627 } 7578 //}
7579
7580 //else
7581 //{
7582 // mediaTemplateRow.MaximumCabinetSizeForLargeFileSplitting = 0; // Default value of 0 corresponds to max size of 2048 MB (i.e. 2 GB)
7583 //}
7584
7585 this.Core.AddTuple(tuple);
7628 } 7586 }
7629 } 7587 }
7630 7588
@@ -7639,7 +7597,7 @@ namespace WixToolset.Core
7639 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 7597 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
7640 Identifier id = null; 7598 Identifier id = null;
7641 var configData = String.Empty; 7599 var configData = String.Empty;
7642 var fileCompression = YesNoType.NotSet; 7600 bool? fileCompression = null;
7643 string language = null; 7601 string language = null;
7644 string sourceFile = null; 7602 string sourceFile = null;
7645 7603
@@ -7657,7 +7615,7 @@ namespace WixToolset.Core
7657 this.Core.CreateSimpleReference(sourceLineNumbers, "Media", diskId.ToString(CultureInfo.InvariantCulture.NumberFormat)); 7615 this.Core.CreateSimpleReference(sourceLineNumbers, "Media", diskId.ToString(CultureInfo.InvariantCulture.NumberFormat));
7658 break; 7616 break;
7659 case "FileCompression": 7617 case "FileCompression":
7660 fileCompression = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 7618 fileCompression = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7661 break; 7619 break;
7662 case "Language": 7620 case "Language":
7663 language = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, Int16.MaxValue); 7621 language = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, Int16.MaxValue);
@@ -7726,25 +7684,19 @@ namespace WixToolset.Core
7726 7684
7727 if (!this.Core.EncounteredError) 7685 if (!this.Core.EncounteredError)
7728 { 7686 {
7729 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixMerge, id); 7687 var tuple = new WixMergeTuple(sourceLineNumbers, id)
7730 row.Set(1, language);
7731 row.Set(2, directoryId);
7732 row.Set(3, sourceFile);
7733 row.Set(4, diskId);
7734 if (YesNoType.Yes == fileCompression)
7735 {
7736 row.Set(5, true);
7737 }
7738 else if (YesNoType.No == fileCompression)
7739 { 7688 {
7740 row.Set(5, false); 7689 Directory_ = directoryId,
7741 } 7690 SourceFile = sourceFile,
7742 else // YesNoType.NotSet == fileCompression 7691 DiskId = diskId,
7743 { 7692 ConfigurationData = configData,
7744 // and we leave the column null 7693 FileCompression = fileCompression,
7745 } 7694 Feature_ = Guid.Empty.ToString("B")
7746 row.Set(6, configData); 7695 };
7747 row.Set(7, Guid.Empty.ToString("B")); 7696
7697 tuple.Set((int)WixMergeTupleFields.Language, language);
7698
7699 this.Core.AddTuple(tuple);
7748 } 7700 }
7749 } 7701 }
7750 7702
@@ -7922,10 +7874,14 @@ namespace WixToolset.Core
7922 7874
7923 if (!this.Core.EncounteredError) 7875 if (!this.Core.EncounteredError)
7924 { 7876 {
7925 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MIME); 7877 var tuple = new MIMETuple(sourceLineNumbers, new Identifier(AccessModifier.Private, contentType))
7926 row.Set(0, contentType); 7878 {
7927 row.Set(1, extension); 7879 ContentType = contentType,
7928 row.Set(2, classId); 7880 Extension_ = extension,
7881 CLSID = classId
7882 };
7883
7884 this.Core.AddTuple(tuple);
7929 } 7885 }
7930 } 7886 }
7931 else if (YesNoType.No == advertise) 7887 else if (YesNoType.No == advertise)
@@ -7946,935 +7902,6 @@ namespace WixToolset.Core
7946 } 7902 }
7947 7903
7948 /// <summary> 7904 /// <summary>
7949 /// Parses a patch creation element.
7950 /// </summary>
7951 /// <param name="node">The element to parse.</param>
7952 private void ParsePatchCreationElement(XElement node)
7953 {
7954 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
7955 var clean = true; // Default is to clean
7956 var codepage = 0;
7957 string outputPath = null;
7958 var productMismatches = false;
7959 var replaceGuids = String.Empty;
7960 string sourceList = null;
7961 string symbolFlags = null;
7962 var targetProducts = String.Empty;
7963 var versionMismatches = false;
7964 var wholeFiles = false;
7965
7966 foreach (var attrib in node.Attributes())
7967 {
7968 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
7969 {
7970 switch (attrib.Name.LocalName)
7971 {
7972 case "Id":
7973 this.activeName = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
7974 break;
7975 case "AllowMajorVersionMismatches":
7976 versionMismatches = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7977 break;
7978 case "AllowProductCodeMismatches":
7979 productMismatches = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7980 break;
7981 case "CleanWorkingFolder":
7982 clean = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7983 break;
7984 case "Codepage":
7985 codepage = this.Core.GetAttributeCodePageValue(sourceLineNumbers, attrib);
7986 break;
7987 case "OutputPath":
7988 outputPath = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7989 break;
7990 case "SourceList":
7991 sourceList = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7992 break;
7993 case "SymbolFlags":
7994 symbolFlags = String.Format(CultureInfo.InvariantCulture, "0x{0:x8}", this.Core.GetAttributeLongValue(sourceLineNumbers, attrib, 0, UInt32.MaxValue));
7995 break;
7996 case "WholeFilesOnly":
7997 wholeFiles = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7998 break;
7999 default:
8000 this.Core.UnexpectedAttribute(node, attrib);
8001 break;
8002 }
8003 }
8004 else
8005 {
8006 this.Core.ParseExtensionAttribute(node, attrib);
8007 }
8008 }
8009
8010 if (null == this.activeName)
8011 {
8012 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
8013 }
8014
8015 this.Core.CreateActiveSection(this.activeName, SectionType.PatchCreation, codepage, this.Context.CompilationId);
8016
8017 foreach (var child in node.Elements())
8018 {
8019 if (CompilerCore.WixNamespace == child.Name.Namespace)
8020 {
8021 switch (child.Name.LocalName)
8022 {
8023 case "Family":
8024 this.ParseFamilyElement(child);
8025 break;
8026 case "PatchInformation":
8027 this.ParsePatchInformationElement(child);
8028 break;
8029 case "PatchMetadata":
8030 this.ParsePatchMetadataElement(child);
8031 break;
8032 case "PatchProperty":
8033 this.ParsePatchPropertyElement(child, false);
8034 break;
8035 case "PatchSequence":
8036 this.ParsePatchSequenceElement(child);
8037 break;
8038 case "ReplacePatch":
8039 replaceGuids = String.Concat(replaceGuids, this.ParseReplacePatchElement(child));
8040 break;
8041 case "TargetProductCode":
8042 var targetProduct = this.ParseTargetProductCodeElement(child);
8043 if (0 < targetProducts.Length)
8044 {
8045 targetProducts = String.Concat(targetProducts, ";");
8046 }
8047 targetProducts = String.Concat(targetProducts, targetProduct);
8048 break;
8049 default:
8050 this.Core.UnexpectedElement(node, child);
8051 break;
8052 }
8053 }
8054 else
8055 {
8056 this.Core.ParseExtensionElement(node, child);
8057 }
8058 }
8059
8060 this.ProcessProperties(sourceLineNumbers, "PatchGUID", this.activeName);
8061 this.ProcessProperties(sourceLineNumbers, "AllowProductCodeMismatches", productMismatches ? "1" : "0");
8062 this.ProcessProperties(sourceLineNumbers, "AllowProductVersionMajorMismatches", versionMismatches ? "1" : "0");
8063 this.ProcessProperties(sourceLineNumbers, "DontRemoveTempFolderWhenFinished", clean ? "0" : "1");
8064 this.ProcessProperties(sourceLineNumbers, "IncludeWholeFilesOnly", wholeFiles ? "1" : "0");
8065
8066 if (null != symbolFlags)
8067 {
8068 this.ProcessProperties(sourceLineNumbers, "ApiPatchingSymbolFlags", symbolFlags);
8069 }
8070
8071 if (0 < replaceGuids.Length)
8072 {
8073 this.ProcessProperties(sourceLineNumbers, "ListOfPatchGUIDsToReplace", replaceGuids);
8074 }
8075
8076 if (0 < targetProducts.Length)
8077 {
8078 this.ProcessProperties(sourceLineNumbers, "ListOfTargetProductCodes", targetProducts);
8079 }
8080
8081 if (null != outputPath)
8082 {
8083 this.ProcessProperties(sourceLineNumbers, "PatchOutputPath", outputPath);
8084 }
8085
8086 if (null != sourceList)
8087 {
8088 this.ProcessProperties(sourceLineNumbers, "PatchSourceList", sourceList);
8089 }
8090 }
8091
8092 /// <summary>
8093 /// Parses a family element.
8094 /// </summary>
8095 /// <param name="node">The element to parse.</param>
8096 private void ParseFamilyElement(XElement node)
8097 {
8098 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
8099 var diskId = CompilerConstants.IntegerNotSet;
8100 string diskPrompt = null;
8101 string mediaSrcProp = null;
8102 string name = null;
8103 var sequenceStart = CompilerConstants.IntegerNotSet;
8104 string volumeLabel = null;
8105
8106 foreach (var attrib in node.Attributes())
8107 {
8108 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
8109 {
8110 switch (attrib.Name.LocalName)
8111 {
8112 case "DiskId":
8113 diskId = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, Int16.MaxValue);
8114 break;
8115 case "DiskPrompt":
8116 diskPrompt = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8117 break;
8118 case "MediaSrcProp":
8119 mediaSrcProp = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8120 break;
8121 case "Name":
8122 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8123 break;
8124 case "SequenceStart":
8125 sequenceStart = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, Int32.MaxValue);
8126 break;
8127 case "VolumeLabel":
8128 volumeLabel = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8129 break;
8130 default:
8131 this.Core.UnexpectedAttribute(node, attrib);
8132 break;
8133 }
8134 }
8135 else
8136 {
8137 this.Core.ParseExtensionAttribute(node, attrib);
8138 }
8139 }
8140
8141 if (null == name)
8142 {
8143 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
8144 }
8145 else if (0 < name.Length)
8146 {
8147 if (8 < name.Length) // check the length
8148 {
8149 this.Core.Write(ErrorMessages.FamilyNameTooLong(sourceLineNumbers, node.Name.LocalName, "Name", name, name.Length));
8150 }
8151 else // check for illegal characters
8152 {
8153 foreach (var character in name)
8154 {
8155 if (!Char.IsLetterOrDigit(character) && '_' != character)
8156 {
8157 this.Core.Write(ErrorMessages.IllegalFamilyName(sourceLineNumbers, node.Name.LocalName, "Name", name));
8158 }
8159 }
8160 }
8161 }
8162
8163 foreach (var child in node.Elements())
8164 {
8165 if (CompilerCore.WixNamespace == child.Name.Namespace)
8166 {
8167 switch (child.Name.LocalName)
8168 {
8169 case "UpgradeImage":
8170 this.ParseUpgradeImageElement(child, name);
8171 break;
8172 case "ExternalFile":
8173 this.ParseExternalFileElement(child, name);
8174 break;
8175 case "ProtectFile":
8176 this.ParseProtectFileElement(child, name);
8177 break;
8178 default:
8179 this.Core.UnexpectedElement(node, child);
8180 break;
8181 }
8182 }
8183 else
8184 {
8185 this.Core.ParseExtensionElement(node, child);
8186 }
8187 }
8188
8189 if (!this.Core.EncounteredError)
8190 {
8191 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ImageFamilies);
8192 row.Set(0, name);
8193 row.Set(1, mediaSrcProp);
8194 if (CompilerConstants.IntegerNotSet != diskId)
8195 {
8196 row.Set(2, diskId);
8197 }
8198
8199 if (CompilerConstants.IntegerNotSet != sequenceStart)
8200 {
8201 row.Set(3, sequenceStart);
8202 }
8203 row.Set(4, diskPrompt);
8204 row.Set(5, volumeLabel);
8205 }
8206 }
8207
8208 /// <summary>
8209 /// Parses an upgrade image element.
8210 /// </summary>
8211 /// <param name="node">The element to parse.</param>
8212 /// <param name="family">The family for this element.</param>
8213 private void ParseUpgradeImageElement(XElement node, string family)
8214 {
8215 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
8216 string sourceFile = null;
8217 string sourcePatch = null;
8218 var symbols = new List<string>();
8219 string upgrade = null;
8220
8221 foreach (var attrib in node.Attributes())
8222 {
8223 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
8224 {
8225 switch (attrib.Name.LocalName)
8226 {
8227 case "Id":
8228 upgrade = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8229 if (13 < upgrade.Length)
8230 {
8231 this.Core.Write(ErrorMessages.IdentifierTooLongError(sourceLineNumbers, node.Name.LocalName, "Id", upgrade, 13));
8232 }
8233 break;
8234 case "SourceFile":
8235 case "src":
8236 if (null != sourceFile)
8237 {
8238 this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "src", "SourceFile"));
8239 }
8240
8241 if ("src" == attrib.Name.LocalName)
8242 {
8243 this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "SourceFile"));
8244 }
8245 sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8246 break;
8247 case "SourcePatch":
8248 case "srcPatch":
8249 if (null != sourcePatch)
8250 {
8251 this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "srcPatch", "SourcePatch"));
8252 }
8253
8254 if ("srcPatch" == attrib.Name.LocalName)
8255 {
8256 this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "SourcePatch"));
8257 }
8258 sourcePatch = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8259 break;
8260 default:
8261 this.Core.UnexpectedAttribute(node, attrib);
8262 break;
8263 }
8264 }
8265 else
8266 {
8267 this.Core.ParseExtensionAttribute(node, attrib);
8268 }
8269 }
8270
8271 if (null == upgrade)
8272 {
8273 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
8274 }
8275
8276 if (null == sourceFile)
8277 {
8278 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile"));
8279 }
8280
8281 foreach (var child in node.Elements())
8282 {
8283 if (CompilerCore.WixNamespace == child.Name.Namespace)
8284 {
8285 switch (child.Name.LocalName)
8286 {
8287 case "SymbolPath":
8288 symbols.Add(this.ParseSymbolPathElement(child));
8289 break;
8290 case "TargetImage":
8291 this.ParseTargetImageElement(child, upgrade, family);
8292 break;
8293 case "UpgradeFile":
8294 this.ParseUpgradeFileElement(child, upgrade);
8295 break;
8296 default:
8297 this.Core.UnexpectedElement(node, child);
8298 break;
8299 }
8300 }
8301 else
8302 {
8303 this.Core.ParseExtensionElement(node, child);
8304 }
8305 }
8306
8307 if (!this.Core.EncounteredError)
8308 {
8309 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.UpgradedImages);
8310 row.Set(0, upgrade);
8311 row.Set(1, sourceFile);
8312 row.Set(2, sourcePatch);
8313 row.Set(3, String.Join(";", symbols));
8314 row.Set(4, family);
8315 }
8316 }
8317
8318 /// <summary>
8319 /// Parses an upgrade file element.
8320 /// </summary>
8321 /// <param name="node">The element to parse.</param>
8322 /// <param name="upgrade">The upgrade key for this element.</param>
8323 private void ParseUpgradeFileElement(XElement node, string upgrade)
8324 {
8325 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
8326 var allowIgnoreOnError = false;
8327 string file = null;
8328 var ignore = false;
8329 var symbols = new List<string>();
8330 var wholeFile = false;
8331
8332 foreach (var attrib in node.Attributes())
8333 {
8334 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
8335 {
8336 switch (attrib.Name.LocalName)
8337 {
8338 case "AllowIgnoreOnError":
8339 allowIgnoreOnError = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
8340 break;
8341 case "File":
8342 file = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8343 break;
8344 case "Ignore":
8345 ignore = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
8346 break;
8347 case "WholeFile":
8348 wholeFile = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
8349 break;
8350 default:
8351 this.Core.UnexpectedAttribute(node, attrib);
8352 break;
8353 }
8354 }
8355 else
8356 {
8357 this.Core.ParseExtensionAttribute(node, attrib);
8358 }
8359 }
8360
8361 if (null == file)
8362 {
8363 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "File"));
8364 }
8365
8366 foreach (var child in node.Elements())
8367 {
8368 if (CompilerCore.WixNamespace == child.Name.Namespace)
8369 {
8370 switch (child.Name.LocalName)
8371 {
8372 case "SymbolPath":
8373 symbols.Add(this.ParseSymbolPathElement(child));
8374 break;
8375 default:
8376 this.Core.UnexpectedElement(node, child);
8377 break;
8378 }
8379 }
8380 else
8381 {
8382 this.Core.ParseExtensionElement(node, child);
8383 }
8384 }
8385
8386 if (!this.Core.EncounteredError)
8387 {
8388 if (ignore)
8389 {
8390 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.UpgradedFilesToIgnore);
8391 row.Set(0, upgrade);
8392 row.Set(1, file);
8393 }
8394 else
8395 {
8396 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.UpgradedFiles_OptionalData);
8397 row.Set(0, upgrade);
8398 row.Set(1, file);
8399 row.Set(2, String.Join(";", symbols));
8400 row.Set(3, allowIgnoreOnError ? 1 : 0);
8401 row.Set(4, wholeFile ? 1 : 0);
8402 }
8403 }
8404 }
8405
8406 /// <summary>
8407 /// Parses a target image element.
8408 /// </summary>
8409 /// <param name="node">The element to parse.</param>
8410 /// <param name="upgrade">The upgrade key for this element.</param>
8411 /// <param name="family">The family key for this element.</param>
8412 private void ParseTargetImageElement(XElement node, string upgrade, string family)
8413 {
8414 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
8415 var ignore = false;
8416 var order = CompilerConstants.IntegerNotSet;
8417 string sourceFile = null;
8418 string symbols = null;
8419 string target = null;
8420 string validation = null;
8421
8422 foreach (var attrib in node.Attributes())
8423 {
8424 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
8425 {
8426 switch (attrib.Name.LocalName)
8427 {
8428 case "Id":
8429 target = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8430 if (target.Length > 13)
8431 {
8432 this.Core.Write(ErrorMessages.IdentifierTooLongError(sourceLineNumbers, node.Name.LocalName, "Id", target, 13));
8433 }
8434 break;
8435 case "IgnoreMissingFiles":
8436 ignore = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
8437 break;
8438 case "Order":
8439 order = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, Int32.MinValue + 2, Int32.MaxValue);
8440 break;
8441 case "SourceFile":
8442 case "src":
8443 if (null != sourceFile)
8444 {
8445 this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "src", "SourceFile"));
8446 }
8447
8448 if ("src" == attrib.Name.LocalName)
8449 {
8450 this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "SourceFile"));
8451 }
8452 sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8453 break;
8454 case "Validation":
8455 validation = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8456 break;
8457 default:
8458 this.Core.UnexpectedAttribute(node, attrib);
8459 break;
8460 }
8461 }
8462 else
8463 {
8464 this.Core.ParseExtensionAttribute(node, attrib);
8465 }
8466 }
8467
8468 if (null == target)
8469 {
8470 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
8471 }
8472
8473 if (null == sourceFile)
8474 {
8475 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile"));
8476 }
8477
8478 if (CompilerConstants.IntegerNotSet == order)
8479 {
8480 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Order"));
8481 }
8482
8483 foreach (var child in node.Elements())
8484 {
8485 if (CompilerCore.WixNamespace == child.Name.Namespace)
8486 {
8487 switch (child.Name.LocalName)
8488 {
8489 case "SymbolPath":
8490 if (null != symbols)
8491 {
8492 symbols = String.Concat(symbols, ";", this.ParseSymbolPathElement(child));
8493 }
8494 else
8495 {
8496 symbols = this.ParseSymbolPathElement(child);
8497 }
8498 break;
8499 case "TargetFile":
8500 this.ParseTargetFileElement(child, target, family);
8501 break;
8502 default:
8503 this.Core.UnexpectedElement(node, child);
8504 break;
8505 }
8506 }
8507 else
8508 {
8509 this.Core.ParseExtensionElement(node, child);
8510 }
8511 }
8512
8513 if (!this.Core.EncounteredError)
8514 {
8515 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.TargetImages);
8516 row.Set(0, target);
8517 row.Set(1, sourceFile);
8518 row.Set(2, symbols);
8519 row.Set(3, upgrade);
8520 row.Set(4, order);
8521 row.Set(5, validation);
8522 row.Set(6, ignore ? 1 : 0);
8523 }
8524 }
8525
8526 /// <summary>
8527 /// Parses an upgrade file element.
8528 /// </summary>
8529 /// <param name="node">The element to parse.</param>
8530 /// <param name="target">The upgrade key for this element.</param>
8531 /// <param name="family">The family key for this element.</param>
8532 private void ParseTargetFileElement(XElement node, string target, string family)
8533 {
8534 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
8535 string file = null;
8536 string ignoreLengths = null;
8537 string ignoreOffsets = null;
8538 string protectLengths = null;
8539 string protectOffsets = null;
8540 string symbols = null;
8541
8542 foreach (var attrib in node.Attributes())
8543 {
8544 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
8545 {
8546 switch (attrib.Name.LocalName)
8547 {
8548 case "Id":
8549 file = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8550 break;
8551 default:
8552 this.Core.UnexpectedAttribute(node, attrib);
8553 break;
8554 }
8555 }
8556 else
8557 {
8558 this.Core.ParseExtensionAttribute(node, attrib);
8559 }
8560 }
8561
8562 if (null == file)
8563 {
8564 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
8565 }
8566
8567 foreach (var child in node.Elements())
8568 {
8569 if (CompilerCore.WixNamespace == child.Name.Namespace)
8570 {
8571 switch (child.Name.LocalName)
8572 {
8573 case "IgnoreRange":
8574 this.ParseRangeElement(child, ref ignoreOffsets, ref ignoreLengths);
8575 break;
8576 case "ProtectRange":
8577 this.ParseRangeElement(child, ref protectOffsets, ref protectLengths);
8578 break;
8579 case "SymbolPath":
8580 symbols = this.ParseSymbolPathElement(child);
8581 break;
8582 default:
8583 this.Core.UnexpectedElement(node, child);
8584 break;
8585 }
8586 }
8587 else
8588 {
8589 this.Core.ParseExtensionElement(node, child);
8590 }
8591 }
8592
8593 if (!this.Core.EncounteredError)
8594 {
8595 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.TargetFiles_OptionalData);
8596 row.Set(0, target);
8597 row.Set(1, file);
8598 row.Set(2, symbols);
8599 row.Set(3, ignoreOffsets);
8600 row.Set(4, ignoreLengths);
8601
8602 if (null != protectOffsets)
8603 {
8604 row.Set(5, protectOffsets);
8605
8606 var row2 = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.FamilyFileRanges);
8607 row2.Set(0, family);
8608 row2.Set(1, file);
8609 row2.Set(2, protectOffsets);
8610 row2.Set(3, protectLengths);
8611 }
8612 }
8613 }
8614
8615 /// <summary>
8616 /// Parses an external file element.
8617 /// </summary>
8618 /// <param name="node">The element to parse.</param>
8619 /// <param name="family">The family for this element.</param>
8620 private void ParseExternalFileElement(XElement node, string family)
8621 {
8622 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
8623 string file = null;
8624 string ignoreLengths = null;
8625 string ignoreOffsets = null;
8626 var order = CompilerConstants.IntegerNotSet;
8627 string protectLengths = null;
8628 string protectOffsets = null;
8629 string source = null;
8630 string symbols = null;
8631
8632 foreach (var attrib in node.Attributes())
8633 {
8634 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
8635 {
8636 switch (attrib.Name.LocalName)
8637 {
8638 case "File":
8639 file = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8640 break;
8641 case "Order":
8642 order = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, Int32.MinValue + 2, Int32.MaxValue);
8643 break;
8644 case "Source":
8645 case "src":
8646 if (null != source)
8647 {
8648 this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "src", "Source"));
8649 }
8650
8651 if ("src" == attrib.Name.LocalName)
8652 {
8653 this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Source"));
8654 }
8655 source = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8656 break;
8657 default:
8658 this.Core.UnexpectedAttribute(node, attrib);
8659 break;
8660 }
8661 }
8662 else
8663 {
8664 this.Core.ParseExtensionAttribute(node, attrib);
8665 }
8666 }
8667
8668 if (null == file)
8669 {
8670 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "File"));
8671 }
8672
8673 if (null == source)
8674 {
8675 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Source"));
8676 }
8677
8678 if (CompilerConstants.IntegerNotSet == order)
8679 {
8680 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Order"));
8681 }
8682
8683 foreach (var child in node.Elements())
8684 {
8685 if (CompilerCore.WixNamespace == child.Name.Namespace)
8686 {
8687 switch (child.Name.LocalName)
8688 {
8689 case "IgnoreRange":
8690 this.ParseRangeElement(child, ref ignoreOffsets, ref ignoreLengths);
8691 break;
8692 case "ProtectRange":
8693 this.ParseRangeElement(child, ref protectOffsets, ref protectLengths);
8694 break;
8695 case "SymbolPath":
8696 symbols = this.ParseSymbolPathElement(child);
8697 break;
8698 default:
8699 this.Core.UnexpectedElement(node, child);
8700 break;
8701 }
8702 }
8703 else
8704 {
8705 this.Core.ParseExtensionElement(node, child);
8706 }
8707 }
8708
8709 if (!this.Core.EncounteredError)
8710 {
8711 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ExternalFiles);
8712 row.Set(0, family);
8713 row.Set(1, file);
8714 row.Set(2, source);
8715 row.Set(3, symbols);
8716 row.Set(4, ignoreOffsets);
8717 row.Set(5, ignoreLengths);
8718 if (null != protectOffsets)
8719 {
8720 row.Set(6, protectOffsets);
8721 }
8722
8723 if (CompilerConstants.IntegerNotSet != order)
8724 {
8725 row.Set(7, order);
8726 }
8727
8728 if (null != protectOffsets)
8729 {
8730 var row2 = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.FamilyFileRanges);
8731 row2.Set(0, family);
8732 row2.Set(1, file);
8733 row2.Set(2, protectOffsets);
8734 row2.Set(3, protectLengths);
8735 }
8736 }
8737 }
8738
8739 /// <summary>
8740 /// Parses a protect file element.
8741 /// </summary>
8742 /// <param name="node">The element to parse.</param>
8743 /// <param name="family">The family for this element.</param>
8744 private void ParseProtectFileElement(XElement node, string family)
8745 {
8746 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
8747 string file = null;
8748 string protectLengths = null;
8749 string protectOffsets = null;
8750
8751 foreach (var attrib in node.Attributes())
8752 {
8753 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
8754 {
8755 switch (attrib.Name.LocalName)
8756 {
8757 case "File":
8758 file = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8759 break;
8760 default:
8761 this.Core.UnexpectedAttribute(node, attrib);
8762 break;
8763 }
8764 }
8765 else
8766 {
8767 this.Core.ParseExtensionAttribute(node, attrib);
8768 }
8769 }
8770
8771 if (null == file)
8772 {
8773 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "File"));
8774 }
8775
8776 foreach (var child in node.Elements())
8777 {
8778 if (CompilerCore.WixNamespace == child.Name.Namespace)
8779 {
8780 switch (child.Name.LocalName)
8781 {
8782 case "ProtectRange":
8783 this.ParseRangeElement(child, ref protectOffsets, ref protectLengths);
8784 break;
8785 default:
8786 this.Core.UnexpectedElement(node, child);
8787 break;
8788 }
8789 }
8790 else
8791 {
8792 this.Core.ParseExtensionElement(node, child);
8793 }
8794 }
8795
8796 if (null == protectOffsets || null == protectLengths)
8797 {
8798 this.Core.Write(ErrorMessages.ExpectedElement(sourceLineNumbers, node.Name.LocalName, "ProtectRange"));
8799 }
8800
8801 if (!this.Core.EncounteredError)
8802 {
8803 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.FamilyFileRanges);
8804 row.Set(0, family);
8805 row.Set(1, file);
8806 row.Set(2, protectOffsets);
8807 row.Set(3, protectLengths);
8808 }
8809 }
8810
8811 /// <summary>
8812 /// Parses a range element (ProtectRange, IgnoreRange, etc).
8813 /// </summary>
8814 /// <param name="node">The element to parse.</param>
8815 /// <param name="offsets">Reference to the offsets string.</param>
8816 /// <param name="lengths">Reference to the lengths string.</param>
8817 private void ParseRangeElement(XElement node, ref string offsets, ref string lengths)
8818 {
8819 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
8820 string length = null;
8821 string offset = null;
8822
8823 foreach (var attrib in node.Attributes())
8824 {
8825 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
8826 {
8827 switch (attrib.Name.LocalName)
8828 {
8829 case "Length":
8830 length = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8831 break;
8832 case "Offset":
8833 offset = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8834 break;
8835 default:
8836 this.Core.UnexpectedAttribute(node, attrib);
8837 break;
8838 }
8839 }
8840 else
8841 {
8842 this.Core.ParseExtensionAttribute(node, attrib);
8843 }
8844 }
8845
8846 if (null == length)
8847 {
8848 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Length"));
8849 }
8850
8851 if (null == offset)
8852 {
8853 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Offset"));
8854 }
8855
8856 this.Core.ParseForExtensionElements(node);
8857
8858 if (null != lengths)
8859 {
8860 lengths = String.Concat(lengths, ",", length);
8861 }
8862 else
8863 {
8864 lengths = length;
8865 }
8866
8867 if (null != offsets)
8868 {
8869 offsets = String.Concat(offsets, ",", offset);
8870 }
8871 else
8872 {
8873 offsets = offset;
8874 }
8875 }
8876
8877 /// <summary>
8878 /// Parses a patch property element. 7905 /// Parses a patch property element.
8879 /// </summary> 7906 /// </summary>
8880 /// <param name="node">The element to parse.</param> 7907 /// <param name="node">The element to parse.</param>
@@ -8928,10 +7955,12 @@ namespace WixToolset.Core
8928 if (patch) 7955 if (patch)
8929 { 7956 {
8930 // /Patch/PatchProperty goes directly into MsiPatchMetadata table 7957 // /Patch/PatchProperty goes directly into MsiPatchMetadata table
8931 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata); 7958 this.Core.AddTuple(new MsiPatchMetadataTuple(sourceLineNumbers)
8932 row.Set(0, company); 7959 {
8933 row.Set(1, name); 7960 Company = company,
8934 row.Set(2, value); 7961 Property = name,
7962 Value = value
7963 });
8935 } 7964 }
8936 else 7965 else
8937 { 7966 {
@@ -8939,91 +7968,26 @@ namespace WixToolset.Core
8939 { 7968 {
8940 this.Core.Write(ErrorMessages.UnexpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Company")); 7969 this.Core.Write(ErrorMessages.UnexpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Company"));
8941 } 7970 }
8942 this.ProcessProperties(sourceLineNumbers, name, value); 7971 this.AddPrivateProperty(sourceLineNumbers, name, value);
8943 } 7972 }
8944 } 7973 }
8945 7974
8946 /// <summary> 7975 /// <summary>
8947 /// Parses a patch sequence element. 7976 /// Adds a row to the properties table.
8948 /// </summary> 7977 /// </summary>
8949 /// <param name="node">The element to parse.</param> 7978 /// <param name="sourceLineNumbers">Source line numbers.</param>
8950 private void ParsePatchSequenceElement(XElement node) 7979 /// <param name="name">Name of the property.</param>
7980 /// <param name="value">Value of the property.</param>
7981 private void AddPrivateProperty(SourceLineNumber sourceLineNumbers, string name, string value)
8951 { 7982 {
8952 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
8953 string family = null;
8954 string target = null;
8955 string sequence = null;
8956 var attributes = 0;
8957
8958 foreach (var attrib in node.Attributes())
8959 {
8960 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
8961 {
8962 switch (attrib.Name.LocalName)
8963 {
8964 case "PatchFamily":
8965 family = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
8966 break;
8967 case "ProductCode":
8968 if (null != target)
8969 {
8970 this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Target", "TargetImage"));
8971 }
8972 target = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
8973 break;
8974 case "Target":
8975 if (null != target)
8976 {
8977 this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "TargetImage", "ProductCode"));
8978 }
8979 this.Core.Write(WarningMessages.DeprecatedPatchSequenceTargetAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
8980 target = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8981 break;
8982 case "TargetImage":
8983 if (null != target)
8984 {
8985 this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Target", "ProductCode"));
8986 }
8987 target = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8988 this.Core.CreateSimpleReference(sourceLineNumbers, "TargetImages", target);
8989 break;
8990 case "Sequence":
8991 sequence = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
8992 break;
8993 case "Supersede":
8994 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
8995 {
8996 attributes |= 0x1;
8997 }
8998 break;
8999 default:
9000 this.Core.UnexpectedAttribute(node, attrib);
9001 break;
9002 }
9003 }
9004 else
9005 {
9006 this.Core.ParseExtensionAttribute(node, attrib);
9007 }
9008 }
9009
9010 if (null == family)
9011 {
9012 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "PatchFamily"));
9013 }
9014
9015 this.Core.ParseForExtensionElements(node);
9016
9017 if (!this.Core.EncounteredError) 7983 if (!this.Core.EncounteredError)
9018 { 7984 {
9019 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchSequence); 7985 var tuple = new PropertyTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, name))
9020 row.Set(0, family);
9021 row.Set(1, target);
9022 if (!String.IsNullOrEmpty(sequence))
9023 { 7986 {
9024 row.Set(2, sequence); 7987 Value = value
9025 } 7988 };
9026 row.Set(3, attributes); 7989
7990 this.Core.AddTuple(tuple);
9027 } 7991 }
9028 } 7992 }
9029 7993
@@ -9070,82 +8034,7 @@ namespace WixToolset.Core
9070 8034
9071 return id; 8035 return id;
9072 } 8036 }
9073 8037
9074 /// <summary>
9075 /// Parses a TargetProductCodes element.
9076 /// </summary>
9077 /// <param name="node">The element to parse.</param>
9078 private void ParseTargetProductCodesElement(XElement node)
9079 {
9080 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
9081 var replace = false;
9082 var targetProductCodes = new List<string>();
9083
9084 foreach (var attrib in node.Attributes())
9085 {
9086 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
9087 {
9088 switch (attrib.Name.LocalName)
9089 {
9090 case "Replace":
9091 replace = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
9092 break;
9093 default:
9094 this.Core.UnexpectedAttribute(node, attrib);
9095 break;
9096 }
9097 }
9098 else
9099 {
9100 this.Core.ParseExtensionAttribute(node, attrib);
9101 }
9102 }
9103
9104 foreach (var child in node.Elements())
9105 {
9106 if (CompilerCore.WixNamespace == child.Name.Namespace)
9107 {
9108 switch (child.Name.LocalName)
9109 {
9110 case "TargetProductCode":
9111 var id = this.ParseTargetProductCodeElement(child);
9112 if (0 == String.CompareOrdinal("*", id))
9113 {
9114 this.Core.Write(ErrorMessages.IllegalAttributeValueWhenNested(sourceLineNumbers, child.Name.LocalName, "Id", id, node.Name.LocalName));
9115 }
9116 else
9117 {
9118 targetProductCodes.Add(id);
9119 }
9120 break;
9121 default:
9122 this.Core.UnexpectedElement(node, child);
9123 break;
9124 }
9125 }
9126 else
9127 {
9128 this.Core.ParseExtensionElement(node, child);
9129 }
9130 }
9131
9132 if (!this.Core.EncounteredError)
9133 {
9134 // By default, target ProductCodes should be added.
9135 if (!replace)
9136 {
9137 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchTarget);
9138 row.Set(0, "*");
9139 }
9140
9141 foreach (var targetProductCode in targetProductCodes)
9142 {
9143 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchTarget);
9144 row.Set(0, targetProductCode);
9145 }
9146 }
9147 }
9148
9149 /// <summary> 8038 /// <summary>
9150 /// Parses a ReplacePatch element. 8039 /// Parses a ReplacePatch element.
9151 /// </summary> 8040 /// </summary>
@@ -9227,402 +8116,6 @@ namespace WixToolset.Core
9227 } 8116 }
9228 8117
9229 /// <summary> 8118 /// <summary>
9230 /// Parses an patch element.
9231 /// </summary>
9232 /// <param name="node">The element to parse.</param>
9233 private void ParsePatchElement(XElement node)
9234 {
9235 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
9236 string patchId = null;
9237 var codepage = 0;
9238 ////bool versionMismatches = false;
9239 ////bool productMismatches = false;
9240 var allowRemoval = false;
9241 string classification = null;
9242 string clientPatchId = null;
9243 string description = null;
9244 string displayName = null;
9245 string comments = null;
9246 string manufacturer = null;
9247 var minorUpdateTargetRTM = YesNoType.NotSet;
9248 string moreInfoUrl = null;
9249 var optimizeCA = CompilerConstants.IntegerNotSet;
9250 var optimizedInstallMode = YesNoType.NotSet;
9251 string targetProductName = null;
9252 // string replaceGuids = String.Empty;
9253 var apiPatchingSymbolFlags = 0;
9254 var optimizePatchSizeForLargeFiles = false;
9255
9256 foreach (var attrib in node.Attributes())
9257 {
9258 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
9259 {
9260 switch (attrib.Name.LocalName)
9261 {
9262 case "Id":
9263 patchId = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, true);
9264 break;
9265 case "Codepage":
9266 codepage = this.Core.GetAttributeCodePageValue(sourceLineNumbers, attrib);
9267 break;
9268 case "AllowMajorVersionMismatches":
9269 ////versionMismatches = (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib));
9270 break;
9271 case "AllowProductCodeMismatches":
9272 ////productMismatches = (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib));
9273 break;
9274 case "AllowRemoval":
9275 allowRemoval = (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib));
9276 break;
9277 case "Classification":
9278 classification = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9279 break;
9280 case "ClientPatchId":
9281 clientPatchId = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9282 break;
9283 case "Description":
9284 description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9285 break;
9286 case "DisplayName":
9287 displayName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9288 break;
9289 case "Comments":
9290 comments = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9291 break;
9292 case "Manufacturer":
9293 manufacturer = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9294 break;
9295 case "MinorUpdateTargetRTM":
9296 minorUpdateTargetRTM = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
9297 break;
9298 case "MoreInfoURL":
9299 moreInfoUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9300 break;
9301 case "OptimizedInstallMode":
9302 optimizedInstallMode = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
9303 break;
9304 case "TargetProductName":
9305 targetProductName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9306 break;
9307 case "ApiPatchingSymbolNoImagehlpFlag":
9308 apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_NO_IMAGEHLP : 0;
9309 break;
9310 case "ApiPatchingSymbolNoFailuresFlag":
9311 apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_NO_FAILURES : 0;
9312 break;
9313 case "ApiPatchingSymbolUndecoratedTooFlag":
9314 apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_UNDECORATED_TOO : 0;
9315 break;
9316 case "OptimizePatchSizeForLargeFiles":
9317 optimizePatchSizeForLargeFiles = (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib));
9318 break;
9319 default:
9320 this.Core.UnexpectedAttribute(node, attrib);
9321 break;
9322 }
9323 }
9324 else
9325 {
9326 this.Core.ParseExtensionAttribute(node, attrib);
9327 }
9328 }
9329
9330 if (patchId == null || patchId == "*")
9331 {
9332 // auto-generate at compile time, since this value gets dispersed to several locations
9333 patchId = Common.GenerateGuid();
9334 }
9335 this.activeName = patchId;
9336
9337 if (null == this.activeName)
9338 {
9339 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
9340 }
9341 if (null == classification)
9342 {
9343 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Classification"));
9344 }
9345 if (null == clientPatchId)
9346 {
9347 clientPatchId = String.Concat("_", new Guid(patchId).ToString("N", CultureInfo.InvariantCulture).ToUpper(CultureInfo.InvariantCulture));
9348 }
9349 if (null == description)
9350 {
9351 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Description"));
9352 }
9353 if (null == displayName)
9354 {
9355 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DisplayName"));
9356 }
9357 if (null == manufacturer)
9358 {
9359 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Manufacturer"));
9360 }
9361
9362 this.Core.CreateActiveSection(this.activeName, SectionType.Patch, codepage, this.Context.CompilationId);
9363
9364 foreach (var child in node.Elements())
9365 {
9366 if (CompilerCore.WixNamespace == child.Name.Namespace)
9367 {
9368 switch (child.Name.LocalName)
9369 {
9370 case "PatchInformation":
9371 this.ParsePatchInformationElement(child);
9372 break;
9373 case "Media":
9374 this.ParseMediaElement(child, patchId);
9375 break;
9376 case "OptimizeCustomActions":
9377 optimizeCA = this.ParseOptimizeCustomActionsElement(child);
9378 break;
9379 case "PatchFamily":
9380 this.ParsePatchFamilyElement(child, ComplexReferenceParentType.Patch, patchId);
9381 break;
9382 case "PatchFamilyRef":
9383 this.ParsePatchFamilyRefElement(child, ComplexReferenceParentType.Patch, patchId);
9384 break;
9385 case "PatchFamilyGroup":
9386 this.ParsePatchFamilyGroupElement(child, ComplexReferenceParentType.Patch, patchId);
9387 break;
9388 case "PatchFamilyGroupRef":
9389 this.ParsePatchFamilyGroupRefElement(child, ComplexReferenceParentType.Patch, patchId);
9390 break;
9391 case "PatchProperty":
9392 this.ParsePatchPropertyElement(child, true);
9393 break;
9394 case "TargetProductCodes":
9395 this.ParseTargetProductCodesElement(child);
9396 break;
9397 default:
9398 this.Core.UnexpectedElement(node, child);
9399 break;
9400 }
9401 }
9402 else
9403 {
9404 this.Core.ParseExtensionElement(node, child);
9405 }
9406 }
9407
9408 if (!this.Core.EncounteredError)
9409 {
9410 var patchIdRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchId);
9411 patchIdRow.Set(0, patchId);
9412 patchIdRow.Set(1, clientPatchId);
9413 patchIdRow.Set(2, optimizePatchSizeForLargeFiles);
9414 patchIdRow.Set(3, apiPatchingSymbolFlags);
9415
9416 if (allowRemoval)
9417 {
9418 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9419 row.Set(1, "AllowRemoval");
9420 row.Set(2, allowRemoval ? "1" : "0");
9421 }
9422
9423 if (null != classification)
9424 {
9425 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9426 row.Set(1, "Classification");
9427 row.Set(2, classification);
9428 }
9429
9430 // always generate the CreationTimeUTC
9431 {
9432 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9433 row.Set(1, "CreationTimeUTC");
9434 row.Set(2, DateTime.UtcNow.ToString("MM-dd-yy HH:mm", CultureInfo.InvariantCulture));
9435 }
9436
9437 if (null != description)
9438 {
9439 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9440 row.Set(1, "Description");
9441 row.Set(2, description);
9442 }
9443
9444 if (null != displayName)
9445 {
9446 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9447 row.Set(1, "DisplayName");
9448 row.Set(2, displayName);
9449 }
9450
9451 if (null != manufacturer)
9452 {
9453 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9454 row.Set(1, "ManufacturerName");
9455 row.Set(2, manufacturer);
9456 }
9457
9458 if (YesNoType.NotSet != minorUpdateTargetRTM)
9459 {
9460 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9461 row.Set(1, "MinorUpdateTargetRTM");
9462 row.Set(2, YesNoType.Yes == minorUpdateTargetRTM ? "1" : "0");
9463 }
9464
9465 if (null != moreInfoUrl)
9466 {
9467 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9468 row.Set(1, "MoreInfoURL");
9469 row.Set(2, moreInfoUrl);
9470 }
9471
9472 if (CompilerConstants.IntegerNotSet != optimizeCA)
9473 {
9474 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9475 row.Set(1, "OptimizeCA");
9476 row.Set(2, optimizeCA.ToString(CultureInfo.InvariantCulture));
9477 }
9478
9479 if (YesNoType.NotSet != optimizedInstallMode)
9480 {
9481 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9482 row.Set(1, "OptimizedInstallMode");
9483 row.Set(2, YesNoType.Yes == optimizedInstallMode ? "1" : "0");
9484 }
9485
9486 if (null != targetProductName)
9487 {
9488 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
9489 row.Set(1, "TargetProductName");
9490 row.Set(2, targetProductName);
9491 }
9492
9493 if (null != comments)
9494 {
9495 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchMetadata);
9496 row.Set(0, "Comments");
9497 row.Set(1, comments);
9498 }
9499 }
9500 // TODO: do something with versionMismatches and productMismatches
9501 }
9502
9503 /// <summary>
9504 /// Parses a PatchFamily element.
9505 /// </summary>
9506 /// <param name="node">The element to parse.</param>
9507 private void ParsePatchFamilyElement(XElement node, ComplexReferenceParentType parentType, string parentId)
9508 {
9509 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
9510 Identifier id = null;
9511 string productCode = null;
9512 string version = null;
9513 var attributes = 0;
9514
9515 foreach (var attrib in node.Attributes())
9516 {
9517 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
9518 {
9519 switch (attrib.Name.LocalName)
9520 {
9521 case "Id":
9522 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
9523 break;
9524 case "ProductCode":
9525 productCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
9526 break;
9527 case "Version":
9528 version = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
9529 break;
9530 case "Supersede":
9531 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
9532 {
9533 attributes |= 0x1;
9534 }
9535 break;
9536 default:
9537 this.Core.UnexpectedAttribute(node, attrib);
9538 break;
9539 }
9540 }
9541 else
9542 {
9543 this.Core.ParseExtensionAttribute(node, attrib);
9544 }
9545 }
9546
9547 if (null == id)
9548 {
9549 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
9550 id = Identifier.Invalid;
9551 }
9552
9553 if (String.IsNullOrEmpty(version))
9554 {
9555 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version"));
9556 }
9557 else if (!CompilerCore.IsValidProductVersion(version))
9558 {
9559 this.Core.Write(ErrorMessages.InvalidProductVersion(sourceLineNumbers, version));
9560 }
9561
9562 // find unexpected child elements
9563 foreach (var child in node.Elements())
9564 {
9565 if (CompilerCore.WixNamespace == child.Name.Namespace)
9566 {
9567 switch (child.Name.LocalName)
9568 {
9569 case "All":
9570 this.ParseAllElement(child);
9571 break;
9572 case "BinaryRef":
9573 this.ParsePatchChildRefElement(child, "Binary");
9574 break;
9575 case "ComponentRef":
9576 this.ParsePatchChildRefElement(child, "Component");
9577 break;
9578 case "CustomActionRef":
9579 this.ParsePatchChildRefElement(child, "CustomAction");
9580 break;
9581 case "DirectoryRef":
9582 this.ParsePatchChildRefElement(child, "Directory");
9583 break;
9584 case "DigitalCertificateRef":
9585 this.ParsePatchChildRefElement(child, "MsiDigitalCertificate");
9586 break;
9587 case "FeatureRef":
9588 this.ParsePatchChildRefElement(child, "Feature");
9589 break;
9590 case "IconRef":
9591 this.ParsePatchChildRefElement(child, "Icon");
9592 break;
9593 case "PropertyRef":
9594 this.ParsePatchChildRefElement(child, "Property");
9595 break;
9596 case "UIRef":
9597 this.ParsePatchChildRefElement(child, "WixUI");
9598 break;
9599 default:
9600 this.Core.UnexpectedElement(node, child);
9601 break;
9602 }
9603 }
9604 else
9605 {
9606 this.Core.ParseExtensionElement(node, child);
9607 }
9608 }
9609
9610
9611 if (!this.Core.EncounteredError)
9612 {
9613 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchSequence, id);
9614 row.Set(1, productCode);
9615 row.Set(2, version);
9616 row.Set(3, attributes);
9617
9618 if (ComplexReferenceParentType.Unknown != parentType)
9619 {
9620 this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.PatchFamily, id.Id, ComplexReferenceParentType.Patch == parentType);
9621 }
9622 }
9623 }
9624
9625 /// <summary>
9626 /// Parses the All element under a PatchFamily. 8119 /// Parses the All element under a PatchFamily.
9627 /// </summary> 8120 /// </summary>
9628 /// <param name="node">The element to parse.</param> 8121 /// <param name="node">The element to parse.</param>
@@ -9650,7 +8143,13 @@ namespace WixToolset.Core
9650 8143
9651 if (!this.Core.EncounteredError) 8144 if (!this.Core.EncounteredError)
9652 { 8145 {
9653 this.Core.CreatePatchFamilyChildReference(sourceLineNumbers, "*", "*"); 8146 var tuple = new WixPatchRefTuple(sourceLineNumbers)
8147 {
8148 Table = "*",
8149 PrimaryKeys = "*"
8150 };
8151
8152 this.Core.AddTuple(tuple);
9654 } 8153 }
9655 } 8154 }
9656 8155
@@ -9693,7 +8192,13 @@ namespace WixToolset.Core
9693 8192
9694 if (!this.Core.EncounteredError) 8193 if (!this.Core.EncounteredError)
9695 { 8194 {
9696 this.Core.CreatePatchFamilyChildReference(sourceLineNumbers, tableName, id); 8195 var tuple = new WixPatchRefTuple(sourceLineNumbers)
8196 {
8197 Table = tableName,
8198 PrimaryKeys = id
8199 };
8200
8201 this.Core.AddTuple(tuple);
9697 } 8202 }
9698 } 8203 }
9699 8204
@@ -9770,9 +8275,13 @@ namespace WixToolset.Core
9770 8275
9771 if (!this.Core.EncounteredError) 8276 if (!this.Core.EncounteredError)
9772 { 8277 {
9773 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchBaseline, id); 8278 var tuple = new WixPatchBaselineTuple(sourceLineNumbers, id)
9774 row.Set(1, diskId); 8279 {
9775 row.Set(2, (int)validationFlags); 8280 DiskId = diskId,
8281 ValidationFlags = validationFlags
8282 };
8283
8284 this.Core.AddTuple(tuple);
9776 } 8285 }
9777 } 8286 }
9778 8287
@@ -9948,21 +8457,5 @@ namespace WixToolset.Core
9948 } 8457 }
9949 } 8458 }
9950 } 8459 }
9951
9952 /// <summary>
9953 /// Adds a row to the properties table.
9954 /// </summary>
9955 /// <param name="sourceLineNumbers">Source line numbers.</param>
9956 /// <param name="name">Name of the property.</param>
9957 /// <param name="value">Value of the property.</param>
9958 private void ProcessProperties(SourceLineNumber sourceLineNumbers, string name, string value)
9959 {
9960 if (!this.Core.EncounteredError)
9961 {
9962 var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Properties);
9963 row.Set(0, name);
9964 row.Set(1, value);
9965 }
9966 }
9967 } 8460 }
9968} 8461}