@joebigelow / wix / commits / d0462be8

Integrate latest changes to tuple definitions

Rob Mensching committed May 22, 2019 at 00:58 UTC d0462be8000f18aa7dc0791d02142f000bb19fbf
41 files changed +4098 -3992
src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs
+17 -18
@@ -16,6 +16,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
16 /// </summary>
17 internal class AssignMediaCommand
18 {
19 + private const int DefaultMaximumUncompressedMediaSize = 200; // Default value is 200 MB
20 +
21 public AssignMediaCommand(IntermediateSection section, IMessaging messaging)
22 {
23 this.CabinetNameTemplate = "Cab{0}.cab";
@@ -82,7 +84,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
84 }
85 else
86 {
85 - this.AutoAssignFiles(mediaTable, this.FileFacades, filesByCabinetMedia, mediaRows, uncompressedFiles);
87 + this.AutoAssignFiles(mediaTable, filesByCabinetMedia, mediaRows, uncompressedFiles);
88 }
89
90 this.FileFacadesByCabinetMedia = new Dictionary<MediaTuple, IEnumerable<FileFacade>>();
@@ -101,7 +103,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
103 /// Assign files to cabinets based on MediaTemplate authoring.
104 /// </summary>
105 /// <param name="fileFacades">FileRowCollection</param>
104 - private void AutoAssignFiles(List<MediaTuple> mediaTable, IEnumerable<FileFacade> fileFacades, Dictionary<MediaTuple, List<FileFacade>> filesByCabinetMedia, Dictionary<int, MediaTuple> mediaRows, List<FileFacade> uncompressedFiles)
106 + private void AutoAssignFiles(List<MediaTuple> mediaTable, Dictionary<MediaTuple, List<FileFacade>> filesByCabinetMedia, Dictionary<int, MediaTuple> mediaRows, List<FileFacade> uncompressedFiles)
107 {
108 const int MaxCabIndex = 999;
109
@@ -140,7 +142,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
142 }
143 else
144 {
143 - maxPreCabSizeInMB = mediaTemplateRow.MaximumUncompressedMediaSize;
145 + maxPreCabSizeInMB = mediaTemplateRow.MaximumUncompressedMediaSize ?? DefaultMaximumUncompressedMediaSize;
146 }
147
148 maxPreCabSizeInBytes = (ulong)maxPreCabSizeInMB * 1024 * 1024;
@@ -212,8 +214,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind
214 // If there are uncompressed files and no MediaRow, create a default one.
215 if (uncompressedFiles.Count > 0 && !this.Section.Tuples.OfType<MediaTuple>().Any())
216 {
215 - var defaultMediaRow = new MediaTuple(null, new Identifier(1, AccessModifier.Private));
216 - defaultMediaRow.DiskId = 1;
217 + var defaultMediaRow = new MediaTuple(null, new Identifier(AccessModifier.Private, 1))
218 + {
219 + DiskId = 1
220 + };
221
222 mediaRows.Add(1, defaultMediaRow);
223 this.Section.Tuples.Add(defaultMediaRow);
@@ -282,7 +286,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
286 }
287 else
288 {
285 - this.Messaging.Write(ErrorMessages.ExpectedMediaCabinet(facade.File.SourceLineNumbers, facade.File.File, facade.WixFile.DiskId));
289 + this.Messaging.Write(ErrorMessages.ExpectedMediaCabinet(facade.File.SourceLineNumbers, facade.File.Id.Id, facade.WixFile.DiskId));
290 }
291 }
292 }
@@ -294,21 +298,16 @@ namespace WixToolset.Core.WindowsInstaller.Bind
298 /// <param name="mediaTable"></param>
299 /// <param name="cabIndex"></param>
300 /// <returns></returns>
297 - private MediaTuple AddMediaRow(WixMediaTemplateTuple mediaTemplateRow, int cabIndex)
301 + private MediaTuple AddMediaRow(WixMediaTemplateTuple mediaTemplateTuple, int cabIndex)
302 {
299 - var currentMediaRow = new MediaTuple(mediaTemplateRow.SourceLineNumbers, new Identifier(cabIndex, AccessModifier.Private));
300 - currentMediaRow.DiskId = cabIndex;
301 - currentMediaRow.Cabinet = String.Format(CultureInfo.InvariantCulture, this.CabinetNameTemplate, cabIndex);
302 -
303 - this.Section.Tuples.Add(currentMediaRow);
304 -
305 - var row = new WixMediaTuple(mediaTemplateRow.SourceLineNumbers, new Identifier(cabIndex, AccessModifier.Private));
306 - row.DiskId_ = cabIndex;
307 - row.CompressionLevel = mediaTemplateRow.CompressionLevel;
303 + var currentMediaTuple = new MediaTuple(mediaTemplateTuple.SourceLineNumbers, new Identifier(AccessModifier.Private, cabIndex));
304 + currentMediaTuple.DiskId = cabIndex;
305 + currentMediaTuple.Cabinet = String.Format(CultureInfo.InvariantCulture, this.CabinetNameTemplate, cabIndex);
306 + currentMediaTuple.CompressionLevel = mediaTemplateTuple.CompressionLevel;
307
309 - this.Section.Tuples.Add(row);
308 + this.Section.Tuples.Add(currentMediaTuple);
309
311 - return currentMediaRow;
310 + return currentMediaTuple;
311 }
312 }
313 }
src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
+3 -4
@@ -128,7 +128,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
128 foreach (var propertyRow in section.Tuples.OfType<PropertyTuple>())
129 {
130 // Set the ProductCode if it is to be generated.
131 - if ("ProductCode".Equals(propertyRow.Property, StringComparison.Ordinal) && "*".Equals(propertyRow.Value, StringComparison.Ordinal))
131 + if ("ProductCode".Equals(propertyRow.Id.Id, StringComparison.Ordinal) && "*".Equals(propertyRow.Value, StringComparison.Ordinal))
132 {
133 propertyRow.Value = Common.GenerateGuid();
134
@@ -159,7 +159,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
159 // Add the property name and value to the variableCache.
160 if (variableCache != null)
161 {
162 - var key = String.Concat("property.", propertyRow.Property);
162 + var key = String.Concat("property.", propertyRow.Id.Id);
163 variableCache[key] = propertyRow.Value;
164 }
165 }
@@ -312,7 +312,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
312
313 // Update file sequence.
314 {
315 - var command = new UpdateMediaSequencesCommand(output, fileFacades, assignedMediaRows);
315 + var command = new UpdateMediaSequencesCommand(output, fileFacades);
316 command.Execute();
317 }
318
@@ -400,7 +400,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
400 command.ResolveMedia = this.ResolveMedia;
401 command.TableDefinitions = this.TableDefinitions;
402 command.TempFilesLocation = this.IntermediateFolder;
403 - command.WixMediaTuples = section.Tuples.OfType<WixMediaTuple>();
403 command.Execute();
404
405 fileTransfers.AddRange(command.FileTransfers);
src/WixToolset.Core.WindowsInstaller/Bind/BindSummaryInfoCommand.cs
+22 -22
@@ -49,13 +49,13 @@ namespace WixToolset.Core.WindowsInstaller.Bind
49 bool foundCreatingApplication = false;
50 string now = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss", CultureInfo.InvariantCulture);
51
52 - foreach (var summaryInformationRow in this.Section.Tuples.OfType<_SummaryInformationTuple>())
52 + foreach (var summaryInformationTuple in this.Section.Tuples.OfType<SummaryInformationTuple>())
53 {
54 - switch (summaryInformationRow.PropertyId)
54 + switch (summaryInformationTuple.PropertyId)
55 {
56 - case 1: // PID_CODEPAGE
57 - // make sure the code page is an int and not a web name or null
58 - var codepage = summaryInformationRow.Value;
56 + case SumaryInformationType.Codepage: // PID_CODEPAGE
57 + // make sure the code page is an int and not a web name or null
58 + var codepage = summaryInformationTuple.Value;
59
60 if (String.IsNullOrEmpty(codepage))
61 {
@@ -63,11 +63,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind
63 }
64 else
65 {
66 - summaryInformationRow.Value = Common.GetValidCodePage(codepage, false, false, summaryInformationRow.SourceLineNumbers).ToString(CultureInfo.InvariantCulture);
66 + summaryInformationTuple.Value = Common.GetValidCodePage(codepage, false, false, summaryInformationTuple.SourceLineNumbers).ToString(CultureInfo.InvariantCulture);
67 }
68 break;
69 - case 9: // PID_REVNUMBER
70 - var packageCode = summaryInformationRow.Value;
69 + case SumaryInformationType.PackageCode: // PID_REVNUMBER
70 + var packageCode = summaryInformationTuple.Value;
71
72 if (SectionType.Module == this.Section.Type)
73 {
@@ -76,19 +76,19 @@ namespace WixToolset.Core.WindowsInstaller.Bind
76 else if ("*" == packageCode)
77 {
78 // set the revision number (package/patch code) if it should be automatically generated
79 - summaryInformationRow.Value = Common.GenerateGuid();
79 + summaryInformationTuple.Value = Common.GenerateGuid();
80 }
81 break;
82 - case 12: // PID_CREATE_DTM
82 + case SumaryInformationType.Created:
83 foundCreateDataTime = true;
84 break;
85 - case 13: // PID_LASTSAVE_DTM
85 + case SumaryInformationType.LastSaved:
86 foundLastSaveDataTime = true;
87 break;
88 - case 14:
89 - this.InstallerVersion = summaryInformationRow[_SummaryInformationTupleFields.Value].AsNumber();
88 + case SumaryInformationType.WindowsInstallerVersion:
89 + this.InstallerVersion = summaryInformationTuple[SummaryInformationTupleFields.Value].AsNumber();
90 break;
91 - case 15: // PID_WORDCOUNT
91 + case SumaryInformationType.WordCount:
92 if (SectionType.Patch == this.Section.Type)
93 {
94 this.LongNames = true;
@@ -96,12 +96,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind
96 }
97 else
98 {
99 - var attributes = summaryInformationRow[_SummaryInformationTupleFields.Value].AsNumber();
99 + var attributes = summaryInformationTuple[SummaryInformationTupleFields.Value].AsNumber();
100 this.LongNames = (0 == (attributes & 1));
101 this.Compressed = (2 == (attributes & 2));
102 }
103 break;
104 - case 18: // PID_APPNAME
104 + case SumaryInformationType.CreatingApplication: // PID_APPNAME
105 foundCreatingApplication = true;
106 break;
107 }
@@ -110,8 +110,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
110 // add a summary information row for the create time/date property if its not already set
111 if (!foundCreateDataTime)
112 {
113 - var createTimeDateRow = new _SummaryInformationTuple(null, new Identifier(12, AccessModifier.Private));
114 - createTimeDateRow.PropertyId = 12;
113 + var createTimeDateRow = new SummaryInformationTuple(null);
114 + createTimeDateRow.PropertyId = SumaryInformationType.Created;
115 createTimeDateRow.Value = now;
116
117 this.Section.Tuples.Add(createTimeDateRow);
@@ -120,8 +120,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
120 // add a summary information row for the last save time/date property if its not already set
121 if (!foundLastSaveDataTime)
122 {
123 - var lastSaveTimeDateRow = new _SummaryInformationTuple(null, new Identifier(13, AccessModifier.Private));
124 - lastSaveTimeDateRow.PropertyId = 13;
123 + var lastSaveTimeDateRow = new SummaryInformationTuple(null);
124 + lastSaveTimeDateRow.PropertyId = SumaryInformationType.LastSaved;
125 lastSaveTimeDateRow.Value = now;
126
127 this.Section.Tuples.Add(lastSaveTimeDateRow);
@@ -130,8 +130,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
130 // add a summary information row for the creating application property if its not already set
131 if (!foundCreatingApplication)
132 {
133 - var creatingApplicationRow = new _SummaryInformationTuple(null, new Identifier(18, AccessModifier.Private));
134 - creatingApplicationRow.PropertyId = 18;
133 + var creatingApplicationRow = new SummaryInformationTuple(null);
134 + creatingApplicationRow.PropertyId = SumaryInformationType.CreatingApplication;
135 creatingApplicationRow.Value = String.Format(CultureInfo.InvariantCulture, AppCommon.GetCreatingApplicationString());
136
137 this.Section.Tuples.Add(creatingApplicationRow);
src/WixToolset.Core.WindowsInstaller/Bind/BindTransformCommand.cs
+1
@@ -8,6 +8,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
8 using System.IO;
9 using WixToolset.Core.WindowsInstaller.Msi;
10 using WixToolset.Data;
11 + using WixToolset.Data.Tuples;
12 using WixToolset.Data.WindowsInstaller;
13 using WixToolset.Extensibility;
14 using WixToolset.Extensibility.Services;
src/WixToolset.Core.WindowsInstaller/Bind/CabinetBuilder.cs
+3 -3
@@ -148,7 +148,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
148 {
149 // Cabinet has Single File, Check if this is Large File than needs Splitting into Multiple cabs
150 // Get the Value for Max Uncompressed Media Size
151 - maxPreCompressedSizeInBytes = (ulong)MaximumUncompressedMediaSize * 1024 * 1024;
151 + maxPreCompressedSizeInBytes = (ulong)this.MaximumUncompressedMediaSize * 1024 * 1024;
152
153 foreach (FileFacade facade in cabinetWorkItem.FileFacades) // No other easy way than looping to get the only row
154 {
@@ -168,8 +168,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
168
169 var files = cabinetWorkItem.FileFacades
170 .Select(facade => facade.Hash == null ?
171 - new CabinetCompressFile(facade.WixFile.Source.Path, facade.File.File) :
172 - new CabinetCompressFile(facade.WixFile.Source.Path, facade.File.File, facade.Hash.HashPart1, facade.Hash.HashPart2, facade.Hash.HashPart3, facade.Hash.HashPart4))
171 + new CabinetCompressFile(facade.WixFile.Source.Path, facade.File.Id.Id) :
172 + new CabinetCompressFile(facade.WixFile.Source.Path, facade.File.Id.Id, facade.Hash.HashPart1, facade.Hash.HashPart2, facade.Hash.HashPart3, facade.Hash.HashPart4))
173 .ToList();
174
175 var cabinetCompressionLevel = (CabinetCompressionLevel)cabinetWorkItem.CompressionLevel;
src/WixToolset.Core.WindowsInstaller/Bind/CabinetResolver.cs
+1 -1
@@ -112,7 +112,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
112 private IBindFileWithPath CreateBindFileWithPath(FileFacade facade)
113 {
114 var result = this.ServiceProvider.GetService<IBindFileWithPath>();
115 - result.Id = facade.File.File;
115 + result.Id = facade.File.Id.Id;
116 result.Path = facade.WixFile.Source.Path;
117
118 return result;
src/WixToolset.Core.WindowsInstaller/Bind/CalculateComponentGuids.cs
+8 -8
@@ -81,25 +81,25 @@ namespace WixToolset.Core.WindowsInstaller.Bind
81 // If the directory Id already exists, we will skip it here since
82 // checking for duplicate primary keys is done later when importing tables
83 // into database
84 - if (targetPathsByDirectoryId.ContainsKey(row.Directory))
84 + if (targetPathsByDirectoryId.ContainsKey(row.Id.Id))
85 {
86 continue;
87 }
88
89 var targetName = Common.GetName(row.DefaultDir, false, true);
90 - targetPathsByDirectoryId.Add(row.Directory, new ResolvedDirectory(row.Directory_Parent, targetName));
90 + targetPathsByDirectoryId.Add(row.Id.Id, new ResolvedDirectory(row.Directory_Parent, targetName));
91 }
92 }
93
94 // If the component id generation seeds have not been indexed
95 - // from the WixDirectory table do that now.
95 + // from the Directory tuples do that now.
96 if (componentIdGenSeeds is null)
97 {
98 - // If there are any WixDirectory rows, build up the Component Guid
98 + // If there are any Directory tuples, build up the Component Guid
99 // generation seeds indexed by Directory/@Id.
100 - componentIdGenSeeds = this.Section.Tuples.OfType<WixDirectoryTuple>()
100 + componentIdGenSeeds = this.Section.Tuples.OfType<DirectoryTuple>()
101 .Where(t => !String.IsNullOrEmpty(t.ComponentGuidGenerationSeed))
102 - .ToDictionary(t => t.Directory_, t => t.ComponentGuidGenerationSeed);
102 + .ToDictionary(t => t.Id.Id, t => t.ComponentGuidGenerationSeed);
103 }
104
105 // if the file rows have not been indexed by File.Component yet
@@ -123,13 +123,13 @@ namespace WixToolset.Core.WindowsInstaller.Bind
123 }
124
125 // validate component meets all the conditions to have a generated guid
126 - var currentComponentFiles = filesByComponentId[componentTuple.Component];
126 + var currentComponentFiles = filesByComponentId[componentTuple.Id.Id];
127 var numFilesInComponent = currentComponentFiles.Count;
128 string path = null;
129
130 foreach (var fileRow in currentComponentFiles)
131 {
132 - if (fileRow.File == componentTuple.KeyPath)
132 + if (fileRow.Id.Id == componentTuple.KeyPath)
133 {
134 // calculate the key file's canonical target path
135 string directoryPath = PathResolver.GetDirectoryPath(targetPathsByDirectoryId, componentIdGenSeeds, componentTuple.Directory_, true);
src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs
+7 -24
@@ -26,11 +26,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind
26 public const int DefaultMaximumUncompressedMediaSize = 200; // Default value is 200 MB
27 public const int MaxValueOfMaxCabSizeForLargeFileSplitting = 2 * 1024; // 2048 MB (i.e. 2 GB)
28
29 - private List<IFileTransfer> fileTransfers;
29 + private readonly List<IFileTransfer> fileTransfers;
30
31 - private List<ITrackedFile> trackedFiles;
31 + private readonly List<ITrackedFile> trackedFiles;
32
33 - private FileSplitCabNamesCallback newCabNamesCallBack;
33 + private readonly FileSplitCabNamesCallback newCabNamesCallBack;
34
35 private Dictionary<string, string> lastCabinetAddedToMediaTable; // Key is First Cabinet Name, Value is Last Cabinet Added in the Split Sequence
36
@@ -82,8 +82,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
82
83 public TableDefinitionCollection TableDefinitions { private get; set; }
84
85 - public IEnumerable<WixMediaTuple> WixMediaTuples { private get; set; }
86 -
85 public IEnumerable<IFileTransfer> FileTransfers => this.fileTransfers;
86
87 public IEnumerable<ITrackedFile> TrackedFiles => this.trackedFiles;
@@ -94,14 +92,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind
92 /// <returns>The uncompressed file rows.</returns>
93 public void Execute()
94 {
97 - var wixMediaTuples = this.WixMediaTuples.ToDictionary(t => t.DiskId_);
98 -
95 this.lastCabinetAddedToMediaTable = new Dictionary<string, string>();
96
97 this.SetCabbingThreadCount();
98
99 // Send Binder object to Facilitate NewCabNamesCallBack Callback
104 - CabinetBuilder cabinetBuilder = new CabinetBuilder(this.Messaging, this.CabbingThreadCount, Marshal.GetFunctionPointerForDelegate(this.newCabNamesCallBack));
100 + var cabinetBuilder = new CabinetBuilder(this.Messaging, this.CabbingThreadCount, Marshal.GetFunctionPointerForDelegate(this.newCabNamesCallBack));
101
102 // Supply Compile MediaTemplate Attributes to Cabinet Builder
103 this.GetMediaTemplateAttributes(out var MaximumCabinetSizeForLargeFileSplitting, out var MaximumUncompressedMediaSize);
@@ -111,22 +107,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind
107 foreach (var entry in this.FileRowsByCabinet)
108 {
109 var mediaTuple = entry.Key;
114 - IEnumerable<FileFacade> files = entry.Value;
115 - CompressionLevel compressionLevel = this.DefaultCompressionLevel ?? CompressionLevel.Medium;
116 -
117 - string mediaLayoutFolder = null;
118 -
119 - if (wixMediaTuples.TryGetValue(mediaTuple.DiskId, out var wixMediaRow))
120 - {
121 - mediaLayoutFolder = wixMediaRow.Layout;
122 -
123 - if (wixMediaRow.CompressionLevel.HasValue)
124 - {
125 - compressionLevel = wixMediaRow.CompressionLevel.Value;
126 - }
127 - }
128 -
129 - string cabinetDir = this.ResolveMedia(mediaTuple, mediaLayoutFolder, this.LayoutDirectory);
110 + var files = entry.Value;
111 + var compressionLevel = mediaTuple.CompressionLevel ?? this.DefaultCompressionLevel ?? CompressionLevel.Medium;
112 + var cabinetDir = this.ResolveMedia(mediaTuple, mediaTuple.Layout, this.LayoutDirectory);
113
114 var cabinetWorkItem = this.CreateCabinetWorkItem(this.Output, cabinetDir, mediaTuple, compressionLevel, files);
115 if (null != cabinetWorkItem)
src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs
+85 -10
@@ -14,6 +14,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind
14
15 internal class CreateOutputFromIRCommand
16 {
17 + private const int DefaultMaximumUncompressedMediaSize = 200; // Default value is 200 MB
18 + private const int MaxValueOfMaxCabSizeForLargeFileSplitting = 2 * 1024; // 2048 MB (i.e. 2 GB)
19 +
20 public CreateOutputFromIRCommand(IntermediateSection section, TableDefinitionCollection tableDefinitions, IEnumerable<IWindowsInstallerBackendBinderExtension> backendExtensions)
21 {
22 this.Section = section;
@@ -46,6 +49,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind
49 {
50 switch (tuple.Definition.Type)
51 {
52 + case TupleDefinitionType.Binary:
53 + this.AddTupleDefaultly(tuple, output, true);
54 + break;
55 +
56 case TupleDefinitionType.BBControl:
57 this.AddBBControlTuple((BBControlTuple)tuple, output);
58 break;
@@ -66,6 +73,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind
73 this.AddDialogTuple((DialogTuple)tuple, output);
74 break;
75
76 + case TupleDefinitionType.Directory:
77 + this.AddDirectoryTuple((DirectoryTuple)tuple, output);
78 + break;
79 +
80 case TupleDefinitionType.Environment:
81 this.AddEnvironmentTuple((EnvironmentTuple)tuple, output);
82 break;
@@ -102,14 +113,26 @@ namespace WixToolset.Core.WindowsInstaller.Bind
113 this.AddMsiServiceConfigFailureActionsTuple((MsiServiceConfigFailureActionsTuple)tuple, output);
114 break;
115
116 + case TupleDefinitionType.MoveFile:
117 + this.AddMoveFileTuple((MoveFileTuple)tuple, output);
118 + break;
119 +
120 case TupleDefinitionType.Property:
121 this.AddPropertyTuple((PropertyTuple)tuple, output);
122 break;
123
124 + case TupleDefinitionType.RemoveFile:
125 + this.AddRemoveFileTuple((RemoveFileTuple)tuple, output);
126 + break;
127 +
128 case TupleDefinitionType.Registry:
129 this.AddRegistryTuple((RegistryTuple)tuple, output);
130 break;
131
132 + case TupleDefinitionType.RegLocator:
133 + this.AddRegLocatorTuple((RegLocatorTuple)tuple, output);
134 + break;
135 +
136 case TupleDefinitionType.RemoveRegistry:
137 this.AddRemoveRegistryTuple((RemoveRegistryTuple)tuple, output);
138 break;
@@ -138,10 +161,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
161 this.AddWixActionTuple((WixActionTuple)tuple, output);
162 break;
163
141 - case TupleDefinitionType.WixMedia:
142 - // Ignored.
143 - break;
144 -
164 case TupleDefinitionType.WixMediaTemplate:
165 this.AddWixMediaTemplateTuple((WixMediaTemplateTuple)tuple, output);
166 break;
@@ -150,6 +169,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind
169 this.AddTupleFromExtension(tuple, output);
170 break;
171
172 + // ignored.
173 + case TupleDefinitionType.WixFile:
174 + case TupleDefinitionType.WixComponentGroup:
175 + case TupleDefinitionType.WixDeltaPatchFile:
176 + break;
177 +
178 default:
179 this.AddTupleDefaultly(tuple, output);
180 break;
@@ -311,6 +336,15 @@ namespace WixToolset.Core.WindowsInstaller.Bind
336 row[9] = tuple.Control_Cancel;
337 }
338
339 + private void AddDirectoryTuple(DirectoryTuple tuple, Output output)
340 + {
341 + var table = output.EnsureTable(this.TableDefinitions["Directory"]);
342 + var row = table.CreateRow(tuple.SourceLineNumbers);
343 + row[0] = tuple.Id.Id;
344 + row[1] = tuple.Directory_Parent;
345 + row[2] = tuple.DefaultDir;
346 + }
347 +
348 private void AddEnvironmentTuple(EnvironmentTuple tuple, Output output)
349 {
350 var action = String.Empty;
@@ -373,7 +407,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
407 {
408 var table = output.EnsureTable(this.TableDefinitions["File"]);
409 var row = (FileRow)table.CreateRow(tuple.SourceLineNumbers);
376 - row.File = tuple.File;
410 + row.File = tuple.Id.Id;
411 row.Component = tuple.Component_;
412 row.FileName = GetMsiFilenameValue(tuple.ShortFileName, tuple.LongFileName);
413 row.FileSize = tuple.FileSize;
@@ -392,7 +426,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
426
427 private void AddIniFileTuple(IniFileTuple tuple, Output output)
428 {
395 - string tableName = (InifFileActionType.AddLine == tuple.Action || InifFileActionType.AddTag == tuple.Action || InifFileActionType.CreateLine == tuple.Action) ? "IniFile" : "RemoveIniFile";
429 + var tableName = (InifFileActionType.AddLine == tuple.Action || InifFileActionType.AddTag == tuple.Action || InifFileActionType.CreateLine == tuple.Action) ? "IniFile" : "RemoveIniFile";
430
431 var table = output.EnsureTable(this.TableDefinitions[tableName]);
432 var row = table.CreateRow(tuple.SourceLineNumbers);
@@ -487,6 +521,19 @@ namespace WixToolset.Core.WindowsInstaller.Bind
521 row[8] = tuple.Component_;
522 }
523
524 + private void AddMoveFileTuple(MoveFileTuple tuple, Output output)
525 + {
526 + var table = output.EnsureTable(this.TableDefinitions["MoveFile"]);
527 + var row = table.CreateRow(tuple.SourceLineNumbers);
528 + row[0] = tuple.Id.Id;
529 + row[1] = tuple.Component_;
530 + row[2] = tuple.SourceName;
531 + row[3] = tuple.DestName;
532 + row[4] = tuple.SourceFolder;
533 + row[5] = tuple.DestFolder;
534 + row[6] = tuple.Delete ? WindowsInstallerConstants.MsidbMoveFileOptionsMove : 0;
535 + }
536 +
537 private void AddPropertyTuple(PropertyTuple tuple, Output output)
538 {
539 if (String.IsNullOrEmpty(tuple.Value))
@@ -496,10 +543,24 @@ namespace WixToolset.Core.WindowsInstaller.Bind
543
544 var table = output.EnsureTable(this.TableDefinitions["Property"]);
545 var row = (PropertyRow)table.CreateRow(tuple.SourceLineNumbers);
499 - row.Property = tuple.Property;
546 + row.Property = tuple.Id.Id;
547 row.Value = tuple.Value;
548 }
549
550 + private void AddRemoveFileTuple(RemoveFileTuple tuple, Output output)
551 + {
552 + var installMode = tuple.OnInstall == true ? WindowsInstallerConstants.MsidbRemoveFileInstallModeOnInstall : 0;
553 + installMode |= tuple.OnUninstall == true ? WindowsInstallerConstants.MsidbRemoveFileInstallModeOnRemove : 0;
554 +
555 + var table = output.EnsureTable(this.TableDefinitions["RemoveFile"]);
556 + var row = table.CreateRow(tuple.SourceLineNumbers);
557 + row[0] = tuple.Id.Id;
558 + row[1] = tuple.Component_;
559 + row[2] = tuple.FileName;
560 + row[3] = tuple.DirProperty;
561 + row[4] = installMode;
562 + }
563 +
564 private void AddRegistryTuple(RegistryTuple tuple, Output output)
565 {
566 var value = tuple.Value;
@@ -552,6 +613,20 @@ namespace WixToolset.Core.WindowsInstaller.Bind
613 row[5] = tuple.Component_;
614 }
615
616 + private void AddRegLocatorTuple(RegLocatorTuple tuple, Output output)
617 + {
618 + var type = (int)tuple.Type;
619 + type |= tuple.Win64 ? WindowsInstallerConstants.MsidbLocatorType64bit : 0;
620 +
621 + var table = output.EnsureTable(this.TableDefinitions["RegLocator"]);
622 + var row = table.CreateRow(tuple.SourceLineNumbers);
623 + row[0] = tuple.Id.Id;
624 + row[1] = tuple.Root;
625 + row[2] = tuple.Key;
626 + row[3] = tuple.Name;
627 + row[4] = type;
628 + }
629 +
630 private void AddRemoveRegistryTuple(RemoveRegistryTuple tuple, Output output)
631 {
632 if (tuple.Action == RemoveRegistryActionType.RemoveOnInstall)
@@ -684,7 +759,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
759 sequenceTableDefinition = this.TableDefinitions["AdminUISequence"];
760 }
761 break;
687 - case SequenceTable.AdvtExecuteSequence:
762 + case SequenceTable.AdvertiseExecuteSequence:
763 if (OutputType.Module == output.Type)
764 {
765 output.EnsureTable(this.TableDefinitions["AdvtExecuteSequence"]);
@@ -754,8 +829,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
829 row.CompressionLevel = tuple.CompressionLevel;
830 row.DiskPrompt = tuple.DiskPrompt;
831 row.VolumeLabel = tuple.VolumeLabel;
757 - row.MaximumUncompressedMediaSize = tuple.MaximumUncompressedMediaSize;
758 - row.MaximumCabinetSizeForLargeFileSplitting = tuple.MaximumCabinetSizeForLargeFileSplitting;
832 + row.MaximumUncompressedMediaSize = tuple.MaximumUncompressedMediaSize ?? DefaultMaximumUncompressedMediaSize;
833 + row.MaximumCabinetSizeForLargeFileSplitting = tuple.MaximumCabinetSizeForLargeFileSplitting ?? MaxValueOfMaxCabSizeForLargeFileSplitting;
834 }
835
836 private void AddTupleFromExtension(IntermediateTuple tuple, Output output)
src/WixToolset.Core.WindowsInstaller/Bind/CreateSpecialPropertiesCommand.cs
+3 -6
@@ -44,8 +44,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
44
45 if (0 < adminProperties.Count)
46 {
47 - var tuple = new PropertyTuple(null, new Identifier("AdminProperties", AccessModifier.Private));
48 - tuple.Property = "AdminProperties";
47 + var tuple = new PropertyTuple(null, new Identifier(AccessModifier.Private, "AdminProperties"));
48 tuple.Value = String.Join(";", adminProperties);
49
50 this.Section.Tuples.Add(tuple);
@@ -53,8 +52,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
52
53 if (0 < secureProperties.Count)
54 {
56 - var tuple = new PropertyTuple(null, new Identifier("SecureCustomProperties", AccessModifier.Private));
57 - tuple.Property = "SecureCustomProperties";
55 + var tuple = new PropertyTuple(null, new Identifier(AccessModifier.Private, "SecureCustomProperties"));
56 tuple.Value = String.Join(";", secureProperties);
57
58 this.Section.Tuples.Add(tuple);
@@ -62,8 +60,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
60
61 if (0 < hiddenProperties.Count)
62 {
65 - var tuple = new PropertyTuple(null, new Identifier("MsiHiddenProperties", AccessModifier.Private));
66 - tuple.Property = "MsiHiddenProperties";
63 + var tuple = new PropertyTuple(null, new Identifier(AccessModifier.Private, "MsiHiddenProperties"));
64 tuple.Value = String.Join(";", hiddenProperties);
65
66 this.Section.Tuples.Add(tuple);
src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs
+8 -17
@@ -57,7 +57,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
57 // Now since Merge Modules are already slow and generally less desirable than .wixlibs we'll let
58 // this case be slightly more expensive because the cost of maintaining an indexed file row collection
59 // is a lot more costly for the common cases.
60 - var indexedFileFacades = this.FileFacades.ToDictionary(f => f.File.File, StringComparer.Ordinal);
60 + var indexedFileFacades = this.FileFacades.ToDictionary(f => f.File.Id.Id, StringComparer.Ordinal);
61
62 foreach (var wixMergeRow in this.WixMergeTuples)
63 {
@@ -101,42 +101,33 @@ namespace WixToolset.Core.WindowsInstaller.Bind
101 // NOTE: this is very tricky - the merge module file rows are not added to the
102 // file table because they should not be created via idt import. Instead, these
103 // rows are created by merging in the actual modules.
104 - var fileRow = new FileTuple(wixMergeRow.SourceLineNumbers, new Identifier(record[1], AccessModifier.Private));
105 - fileRow.File = record[1];
104 + var fileRow = new FileTuple(wixMergeRow.SourceLineNumbers, new Identifier(AccessModifier.Private, record[1]));
105 fileRow.Compressed = wixMergeRow.FileCompression;
107 - //FileRow fileRow = (FileRow)this.FileTable.CreateRow(wixMergeRow.SourceLineNumbers, false);
108 - //fileRow.File = record[1];
109 - //fileRow.Compressed = wixMergeRow.FileCompression;
106
107 var wixFileRow = new WixFileTuple(wixMergeRow.SourceLineNumbers);
108 wixFileRow.Directory_ = record[2];
109 wixFileRow.DiskId = wixMergeRow.DiskId;
110 wixFileRow.PatchGroup = -1;
111 wixFileRow.Source = new IntermediateFieldPathValue { Path = Path.Combine(this.IntermediateFolder, wixMergeRow.Id.Id, record[1]) };
116 - //WixFileRow wixFileRow = (WixFileRow)this.WixFileTable.CreateRow(wixMergeRow.SourceLineNumbers, false);
117 - //wixFileRow.Directory = record[2];
118 - //wixFileRow.DiskId = wixMergeRow.DiskId;
119 - //wixFileRow.PatchGroup = -1;
120 - //wixFileRow.Source = Path.Combine(this.IntermediateFolder, "MergeId.", wixMergeRow.Number.ToString(CultureInfo.InvariantCulture), record[1]);
112
113 var mergeModuleFileFacade = new FileFacade(true, fileRow, wixFileRow);
114
115 // If case-sensitive collision with another merge module or a user-authored file identifier.
125 - if (indexedFileFacades.TryGetValue(mergeModuleFileFacade.File.File, out var collidingFacade))
116 + if (indexedFileFacades.TryGetValue(mergeModuleFileFacade.File.Id.Id, out var collidingFacade))
117 {
127 - this.Messaging.Write(ErrorMessages.DuplicateModuleFileIdentifier(wixMergeRow.SourceLineNumbers, wixMergeRow.Id.Id, collidingFacade.File.File));
118 + this.Messaging.Write(ErrorMessages.DuplicateModuleFileIdentifier(wixMergeRow.SourceLineNumbers, wixMergeRow.Id.Id, collidingFacade.File.Id.Id));
119 }
129 - else if (uniqueModuleFileIdentifiers.TryGetValue(mergeModuleFileFacade.File.File, out collidingFacade)) // case-insensitive collision with another file identifier in the same merge module
120 + else if (uniqueModuleFileIdentifiers.TryGetValue(mergeModuleFileFacade.File.Id.Id, out collidingFacade)) // case-insensitive collision with another file identifier in the same merge module
121 {
131 - this.Messaging.Write(ErrorMessages.DuplicateModuleCaseInsensitiveFileIdentifier(wixMergeRow.SourceLineNumbers, wixMergeRow.Id.Id, mergeModuleFileFacade.File.File, collidingFacade.File.File));
122 + this.Messaging.Write(ErrorMessages.DuplicateModuleCaseInsensitiveFileIdentifier(wixMergeRow.SourceLineNumbers, wixMergeRow.Id.Id, mergeModuleFileFacade.File.Id.Id, collidingFacade.File.Id.Id));
123 }
124 else // no collision
125 {
126 mergeModulesFileFacades.Add(mergeModuleFileFacade);
127
128 // Keep updating the indexes as new rows are added.
138 - indexedFileFacades.Add(mergeModuleFileFacade.File.File, mergeModuleFileFacade);
139 - uniqueModuleFileIdentifiers.Add(mergeModuleFileFacade.File.File, mergeModuleFileFacade);
129 + indexedFileFacades.Add(mergeModuleFileFacade.File.Id.Id, mergeModuleFileFacade);
130 + uniqueModuleFileIdentifiers.Add(mergeModuleFileFacade.File.Id.Id, mergeModuleFileFacade);
131 }
132
133 containsFiles = true;
src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesCommand.cs
+13 -13
@@ -25,14 +25,14 @@ namespace WixToolset.Core.WindowsInstaller.Bind
25 {
26 var facades = new List<FileFacade>();
27
28 - var wixFiles = this.Section.Tuples.OfType<WixFileTuple>().ToDictionary(t => t.File_);
29 - var deltaPatchFiles = this.Section.Tuples.OfType<WixDeltaPatchFileTuple>().ToDictionary(t => t.File_);
28 + var wixFiles = this.Section.Tuples.OfType<WixFileTuple>().ToDictionary(t => t.Id.Id);
29 + var deltaPatchFiles = this.Section.Tuples.OfType<WixDeltaPatchFileTuple>().ToDictionary(t => t.Id.Id);
30
31 foreach (var file in this.Section.Tuples.OfType<FileTuple>())
32 {
33 - var wixFile = wixFiles[file.File];
33 + var wixFile = wixFiles[file.Id.Id];
34
35 - deltaPatchFiles.TryGetValue(file.File, out var deltaPatchFile);
35 + deltaPatchFiles.TryGetValue(file.Id.Id, out var deltaPatchFile);
36
37 facades.Add(new FileFacade(file, wixFile, deltaPatchFile));
38 }
@@ -51,12 +51,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind
51 ILookup<string, FileFacade> filesByDirectory = null;
52 ILookup<string, FileFacade> filesByDiskId = null;
53
54 - foreach (var row in this.Section.Tuples.OfType<WixDeltaPatchSymbolPathsTuple>().OrderBy(r => r.Type))
54 + foreach (var row in this.Section.Tuples.OfType<WixDeltaPatchSymbolPathsTuple>().OrderBy(r => r.SymbolType))
55 {
56 - switch (row.Type)
56 + switch (row.SymbolType)
57 {
58 case SymbolPathType.File:
59 - this.MergeSymbolPaths(row, deltaPatchFiles[row.Id]);
59 + this.MergeSymbolPaths(row, deltaPatchFiles[row.SymbolId]);
60 break;
61
62 case SymbolPathType.Component:
@@ -65,9 +65,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind
65 filesByComponent = facades.ToLookup(f => f.File.Component_);
66 }
67
68 - foreach (var facade in filesByComponent[row.Id])
68 + foreach (var facade in filesByComponent[row.SymbolId])
69 {
70 - this.MergeSymbolPaths(row, deltaPatchFiles[facade.File.File]);
70 + this.MergeSymbolPaths(row, deltaPatchFiles[facade.File.Id.Id]);
71 }
72 break;
73
@@ -77,9 +77,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind
77 filesByDirectory = facades.ToLookup(f => f.WixFile.Directory_);
78 }
79
80 - foreach (var facade in filesByDirectory[row.Id])
80 + foreach (var facade in filesByDirectory[row.SymbolId])
81 {
82 - this.MergeSymbolPaths(row, deltaPatchFiles[facade.File.File]);
82 + this.MergeSymbolPaths(row, deltaPatchFiles[facade.File.Id.Id]);
83 }
84 break;
85
@@ -89,9 +89,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind
89 filesByDiskId = facades.ToLookup(f => f.WixFile.DiskId.ToString(CultureInfo.InvariantCulture));
90 }
91
92 - foreach (var facade in filesByDiskId[row.Id])
92 + foreach (var facade in filesByDiskId[row.SymbolId])
93 {
94 - this.MergeSymbolPaths(row, deltaPatchFiles[facade.File.File]);
94 + this.MergeSymbolPaths(row, deltaPatchFiles[facade.File.Id.Id]);
95 }
96 break;
97
src/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs
+1 -1
@@ -286,7 +286,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
286
287 using (Record record = new Record(1))
288 {
289 - record.SetString(1, file.File.File);
289 + record.SetString(1, file.File.Id.Id);
290 view.Execute(record);
291 }
292
src/WixToolset.Core.WindowsInstaller/Bind/ModularizeCommand.cs
+2 -2
@@ -1,4 +1,4 @@
1 -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
1 +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3 namespace WixToolset.Core.WindowsInstaller.Bind
4 {
@@ -21,7 +21,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
21 this.ModularizationGuid = modularizationGuid;
22
23 // Gather all the unique suppress modularization identifiers.
24 - this.SuppressModularizationIdentifiers = new HashSet<string>(suppressTuples.Select(s => s.WixSuppressModularization));
24 + this.SuppressModularizationIdentifiers = new HashSet<string>(suppressTuples.Select(s => s.Id.Id));
25 }
26
27 private Output Output { get; }
src/WixToolset.Core.WindowsInstaller/Bind/ProcessUncompressedFilesCommand.cs
+3 -10
@@ -54,8 +54,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
54
55 var mediaRows = this.Section.Tuples.OfType<MediaTuple>().ToDictionary(t => t.DiskId);
56
57 - var wixMediaRows = this.Section.Tuples.OfType<WixMediaTuple>().ToDictionary(t => t.DiskId_);
58 -
57 using (Database db = new Database(this.DatabasePath, OpenDatabase.ReadOnly))
58 {
59 using (View directoryView = db.OpenExecuteView("SELECT `Directory`, `Directory_Parent`, `DefaultDir` FROM `Directory`"))
@@ -85,25 +83,20 @@ namespace WixToolset.Core.WindowsInstaller.Bind
83 {
84 var mediaTuple = mediaRows[facade.WixFile.DiskId];
85 string relativeFileLayoutPath = null;
88 - string mediaLayoutFolder = null;
89 -
90 - if (wixMediaRows.TryGetValue(facade.WixFile.DiskId, out var wixMediaRow))
91 - {
92 - mediaLayoutFolder = wixMediaRow.Layout;
93 - }
86 + string mediaLayoutFolder = mediaTuple.Layout;
87
88 var mediaLayoutDirectory = this.ResolveMedia(mediaTuple, mediaLayoutFolder, this.LayoutDirectory);
89
90 // setup up the query record and find the appropriate file in the
91 // previously executed file view
99 - fileQueryRecord[1] = facade.File.File;
92 + fileQueryRecord[1] = facade.File.Id.Id;
93 fileView.Execute(fileQueryRecord);
94
95 using (Record fileRecord = fileView.Fetch())
96 {
97 if (null == fileRecord)
98 {
106 - throw new WixException(ErrorMessages.FileIdentifierNotFound(facade.File.SourceLineNumbers, facade.File.File));
99 + throw new WixException(ErrorMessages.FileIdentifierNotFound(facade.File.SourceLineNumbers, facade.File.Id.Id));
100 }
101
102 relativeFileLayoutPath = PathResolver.GetFileSourcePath(directories, fileRecord[1], fileRecord[2], this.Compressed, this.LongNamesInImage);
src/WixToolset.Core.WindowsInstaller/Bind/SequenceActionsCommand.cs
+32 -28
@@ -6,7 +6,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
6 using System.Collections.Generic;
7 using System.Globalization;
8 using System.Linq;
9 - using WixToolset.Core.Native;
9 using WixToolset.Data;
10 using WixToolset.Data.Tuples;
11 using WixToolset.Data.WindowsInstaller;
@@ -31,20 +30,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind
30
31 public IMessaging Messaging { private get; set; }
32
34 - public void Execute()
35 - {
36 - var actions = this.Section.Tuples.OfType<WixActionTuple>().ToList();
37 - var suppressActions = this.Section.Tuples.OfType<WixSuppressActionTuple>().ToList();
38 -
39 - this.SequenceActions(actions, suppressActions);
40 - }
41 -
33 /// <summary>
34 /// Set sequence numbers for all the actions and create rows in the output object.
35 /// </summary>
45 - /// <param name="actionRows">Collection of actions to schedule.</param>
46 - /// <param name="suppressActionRows">Collection of actions to suppress.</param>
47 - private void SequenceActions(List<WixActionTuple> actionRows, List<WixSuppressActionTuple> suppressActionRows)
36 + public void Execute()
37 {
38 var overridableActionRows = new Dictionary<string, WixActionTuple>();
39 var requiredActionRows = new Dictionary<string, WixActionTuple>();
@@ -118,7 +107,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
107 }
108
109 // Suppress the required actions that are overridable.
121 - foreach (var suppressActionRow in suppressActionRows)
110 + foreach (var suppressActionRow in this.Section.Tuples.OfType<WixSuppressActionTuple>())
111 {
112 var key = suppressActionRow.Id.Id;
113
@@ -233,7 +222,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
222 {
223 if (sequenceScheduledActionRow.Sequence == actionRow.Sequence)
224 {
236 - this.Messaging.Write(WarningMessages.ActionSequenceCollision(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, sequenceScheduledActionRow.Action, actionRow.Sequence));
225 + this.Messaging.Write(WarningMessages.ActionSequenceCollision(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, sequenceScheduledActionRow.Action, actionRow.Sequence ?? 0));
226 if (null != sequenceScheduledActionRow.SourceLineNumbers)
227 {
228 this.Messaging.Write(WarningMessages.ActionSequenceCollision2(sequenceScheduledActionRow.SourceLineNumbers));
@@ -245,7 +234,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
234 }
235 }
236
248 - absoluteActionRows.Sort((x, y) => x.Sequence.CompareTo(y.Sequence));
237 + absoluteActionRows.Sort((x, y) => (x.Sequence ?? 0).CompareTo(y.Sequence ?? 0));
238
239 // Schedule the relatively scheduled actions (by resolving the dependency trees).
240 var previousUsedSequence = 0;
@@ -310,7 +299,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
299 var nextUsedSequence = Int16.MaxValue + 1;
300 if (absoluteActionRows.Count > j + 1)
301 {
313 - nextUsedSequence = absoluteActionRows[j + 1].Sequence;
302 + nextUsedSequence = absoluteActionRows[j + 1].Sequence ?? 0;
303 }
304
305 // Schedule the action rows after this one.
@@ -337,7 +326,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
326 }
327
328 // keep track of this sequence number as the previous used sequence number for the next iteration
340 - previousUsedSequence = absoluteActionRow.Sequence;
329 + previousUsedSequence = absoluteActionRow.Sequence ?? 0;
330 }
331
332 // add the absolutely and relatively scheduled actions to the list of scheduled actions
@@ -412,9 +401,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
401 set.Add("InstallExecuteSequence/AppSearch");
402 set.Add("InstallUISequence/AppSearch");
403 break;
415 - case TupleDefinitionType.BindImage:
416 - set.Add("InstallExecuteSequence/BindImage");
417 - break;
404 case TupleDefinitionType.CCPSearch:
405 set.Add("InstallExecuteSequence/AppSearch");
406 set.Add("InstallExecuteSequence/CCPSearch");
@@ -452,10 +438,32 @@ namespace WixToolset.Core.WindowsInstaller.Bind
438 case TupleDefinitionType.File:
439 set.Add("InstallExecuteSequence/InstallFiles");
440 set.Add("InstallExecuteSequence/RemoveFiles");
455 - break;
456 - case TupleDefinitionType.Font:
457 - set.Add("InstallExecuteSequence/RegisterFonts");
458 - set.Add("InstallExecuteSequence/UnregisterFonts");
441 +
442 + var foundFont = false;
443 + var foundSelfReg = false;
444 + var foundBindPath = false;
445 + foreach (var file in this.Section.Tuples.OfType<FileTuple>())
446 + {
447 + if (!foundFont && !String.IsNullOrEmpty(file.FontTitle))
448 + {
449 + set.Add("InstallExecuteSequence/RegisterFonts");
450 + set.Add("InstallExecuteSequence/UnregisterFonts");
451 + foundFont = true;
452 + }
453 +
454 + if (!foundSelfReg && file.SelfRegCost.HasValue)
455 + {
456 + set.Add("InstallExecuteSequence/SelfRegModules");
457 + set.Add("InstallExecuteSequence/SelfUnregModules");
458 + foundSelfReg = true;
459 + }
460 +
461 + if (!foundBindPath && !String.IsNullOrEmpty(file.BindPath))
462 + {
463 + set.Add("InstallExecuteSequence/BindImage");
464 + foundBindPath = true;
465 + }
466 + }
467 break;
468 case TupleDefinitionType.IniFile:
469 case TupleDefinitionType.RemoveIniFile:
@@ -511,10 +519,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
519 case TupleDefinitionType.RemoveFile:
520 set.Add("InstallExecuteSequence/RemoveFiles");
521 break;
514 - case TupleDefinitionType.SelfReg:
515 - set.Add("InstallExecuteSequence/SelfRegModules");
516 - set.Add("InstallExecuteSequence/SelfUnregModules");
517 - break;
522 case TupleDefinitionType.ServiceControl:
523 set.Add("InstallExecuteSequence/StartServices");
524 set.Add("InstallExecuteSequence/StopServices");
src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs
+13 -13
@@ -79,7 +79,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
79
80 if (!fileInfo.Exists)
81 {
82 - this.Messaging.Write(ErrorMessages.CannotFindFile(file.File.SourceLineNumbers, file.File.File, file.File.LongFileName, file.WixFile.Source.Path));
82 + this.Messaging.Write(ErrorMessages.CannotFindFile(file.File.SourceLineNumbers, file.File.Id.Id, file.File.LongFileName, file.WixFile.Source.Path));
83 return;
84 }
85
@@ -127,16 +127,16 @@ namespace WixToolset.Core.WindowsInstaller.Bind
127 //
128 // Also, if we do not find a matching file identifier then the user provided a default version and is providing a version
129 // for unversioned file. That's allowed but generally a dangerous thing to do so let's point that out to the user.
130 - if (!this.FileFacades.Any(r => file.File.Version.Equals(r.File.File, StringComparison.Ordinal)))
130 + if (!this.FileFacades.Any(r => file.File.Version.Equals(r.File.Id.Id, StringComparison.Ordinal)))
131 {
132 - this.Messaging.Write(WarningMessages.DefaultVersionUsedForUnversionedFile(file.File.SourceLineNumbers, file.File.Version, file.File.File));
132 + this.Messaging.Write(WarningMessages.DefaultVersionUsedForUnversionedFile(file.File.SourceLineNumbers, file.File.Version, file.File.Id.Id));
133 }
134 }
135 else
136 {
137 if (null != file.File.Language)
138 {
139 - this.Messaging.Write(WarningMessages.DefaultLanguageUsedForUnversionedFile(file.File.SourceLineNumbers, file.File.Language, file.File.File));
139 + this.Messaging.Write(WarningMessages.DefaultLanguageUsedForUnversionedFile(file.File.SourceLineNumbers, file.File.Language, file.File.Id.Id));
140 }
141
142 int[] hash;
@@ -162,7 +162,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
162 this.Section.Tuples.Add(file.Hash);
163 }
164
165 - file.Hash.File_ = file.File.File;
165 + file.Hash.File_ = file.File.Id.Id;
166 file.Hash.Options = 0;
167 file.Hash.HashPart1 = hash[0];
168 file.Hash.HashPart2 = hash[1];
@@ -178,7 +178,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
178 {
179 file.File.Version = version;
180 }
181 - else if (!this.FileFacades.Any(r => file.File.Version.Equals(r.File.File, StringComparison.Ordinal))) // this looks expensive, but see explanation below.
181 + else if (!this.FileFacades.Any(r => file.File.Version.Equals(r.File.Id.Id, StringComparison.Ordinal))) // this looks expensive, but see explanation below.
182 {
183 // The user provided a default version for the file row so we looked for a companion file (a file row with Id matching
184 // the version value). We didn't find it so, we will override the default version they provided with the actual
@@ -194,7 +194,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
194
195 if (!String.IsNullOrEmpty(file.File.Language) && String.IsNullOrEmpty(language))
196 {
197 - this.Messaging.Write(WarningMessages.DefaultLanguageUsedForVersionedFile(file.File.SourceLineNumbers, file.File.Language, file.File.File));
197 + this.Messaging.Write(WarningMessages.DefaultLanguageUsedForVersionedFile(file.File.SourceLineNumbers, file.File.Language, file.File.Id.Id));
198 }
199 else // override the default provided by the user (usually nothing) with the actual language from the file itself.
200 {
@@ -206,13 +206,13 @@ namespace WixToolset.Core.WindowsInstaller.Bind
206 {
207 if (!String.IsNullOrEmpty(file.File.Version))
208 {
209 - var key = String.Format(CultureInfo.InvariantCulture, "fileversion.{0}", file.File.File);
209 + var key = String.Format(CultureInfo.InvariantCulture, "fileversion.{0}", file.File.Id.Id);
210 this.VariableCache[key] = file.File.Version;
211 }
212
213 if (!String.IsNullOrEmpty(file.File.Language))
214 {
215 - var key = String.Format(CultureInfo.InvariantCulture, "filelanguage.{0}", file.File.File);
215 + var key = String.Format(CultureInfo.InvariantCulture, "filelanguage.{0}", file.File.Id.Id);
216 this.VariableCache[key] = file.File.Language;
217 }
218 }
@@ -256,7 +256,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
256 // add the assembly name to the information cache
257 if (null != this.VariableCache)
258 {
259 - this.VariableCache[$"assemblyfullname.{file.File.File}"] = assemblyName.GetFullName();
259 + this.VariableCache[$"assemblyfullname.{file.File.Id.Id}"] = assemblyName.GetFullName();
260 }
261 }
262 catch (WixException e)
@@ -269,10 +269,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind
269 // TODO: Consider passing in the this.FileFacades as an indexed collection instead of searching through
270 // all files like this. Even though this is a rare case it looks like we might be able to index the
271 // file earlier.
272 - var fileManifest = this.FileFacades.SingleOrDefault(r => r.File.File.Equals(file.WixFile.File_AssemblyManifest, StringComparison.Ordinal));
272 + var fileManifest = this.FileFacades.FirstOrDefault(r => r.File.Id.Id.Equals(file.WixFile.File_AssemblyManifest, StringComparison.Ordinal));
273 if (null == fileManifest)
274 {
275 - this.Messaging.Write(ErrorMessages.MissingManifestForWin32Assembly(file.File.SourceLineNumbers, file.File.File, file.WixFile.File_AssemblyManifest));
275 + this.Messaging.Write(ErrorMessages.MissingManifestForWin32Assembly(file.File.SourceLineNumbers, file.File.Id.Id, file.WixFile.File_AssemblyManifest));
276 }
277
278 try
@@ -358,7 +358,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
358
359 if (this.VariableCache != null)
360 {
361 - var key = String.Format(CultureInfo.InvariantCulture, "assembly{0}.{1}", name, file.File.File).ToLowerInvariant();
361 + var key = String.Format(CultureInfo.InvariantCulture, "assembly{0}.{1}", name, file.File.Id.Id).ToLowerInvariant();
362 this.VariableCache[key] = value;
363 }
364 }
src/WixToolset.Core.WindowsInstaller/Bind/UpdateMediaSequencesCommand.cs
+5 -6
@@ -1,4 +1,4 @@
1 -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
1 +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3 namespace WixToolset.Core.WindowsInstaller.Bind
4 {
@@ -6,13 +6,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind
6 using System.Linq;
7 using WixToolset.Core.Bind;
8 using WixToolset.Data;
9 - using WixToolset.Data.Tuples;
9 using WixToolset.Data.WindowsInstaller;
10 using WixToolset.Data.WindowsInstaller.Rows;
11
12 internal class UpdateMediaSequencesCommand
13 {
15 - public UpdateMediaSequencesCommand(Output output, List<FileFacade> fileFacades, Dictionary<int, MediaTuple> assignedMediaRows)
14 + public UpdateMediaSequencesCommand(Output output, List<FileFacade> fileFacades)
15 {
16 this.Output = output;
17 this.FileFacades = fileFacades;
@@ -34,7 +33,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
33
34 // Order by Component to group the files by directory.
35 var optimized = this.OptimizedFileFacades();
37 - foreach (var fileId in optimized.Select(f => f.File.File))
36 + foreach (var fileId in optimized.Select(f => f.File.Id.Id))
37 {
38 var fileRow = fileRows.Get(fileId);
39 fileRow.Sequence = ++lastSequence;
@@ -77,7 +76,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
76 }
77 else
78 {
80 - var fileRow = fileRows.Get(facade.File.File);
79 + var fileRow = fileRows.Get(facade.File.Id.Id);
80 fileRow.Sequence = ++lastSequence;
81 }
82 }
@@ -103,7 +102,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
102 mediaRow = mediaRows.Get(facade.WixFile.DiskId);
103 }
104
106 - var fileRow = fileRows.Get(facade.File.File);
105 + var fileRow = fileRows.Get(facade.File.Id.Id);
106 fileRow.Sequence = ++lastSequence;
107 }
108 }
src/WixToolset.Core.WindowsInstaller/Decompile/Decompiler.cs
+1 -1
@@ -375,7 +375,7 @@ namespace WixToolset.Core.WindowsInstaller
375 case SequenceTable.AdminUISequence:
376 sequenceElement = new Wix.AdminUISequence();
377 break;
378 - case SequenceTable.AdvtExecuteSequence:
378 + case SequenceTable.AdvertiseExecuteSequence:
379 sequenceElement = new Wix.AdvertiseExecuteSequence();
380 break;
381 case SequenceTable.InstallExecuteSequence:
src/WixToolset.Core.WindowsInstaller/Differ.cs
+2 -1
@@ -8,6 +8,7 @@ namespace WixToolset.Core.WindowsInstaller
8 using System.Globalization;
9 using WixToolset.Core.WindowsInstaller.Msi;
10 using WixToolset.Data;
11 + using WixToolset.Data.Tuples;
12 using WixToolset.Data.WindowsInstaller;
13 using WixToolset.Data.WindowsInstaller.Rows;
14 using WixToolset.Extensibility;
@@ -18,7 +19,7 @@ namespace WixToolset.Core.WindowsInstaller
19 /// </summary>
20 public sealed class Differ
21 {
21 - private List<IInspectorExtension> inspectorExtensions;
22 + private readonly List<IInspectorExtension> inspectorExtensions;
23 private bool showPedanticMessages;
24 private bool suppressKeepingSpecialRows;
25 private bool preserveUnchangedRows;
src/WixToolset.Core.WindowsInstaller/Rows/WixActionRowCollection.cs
+5 -5
@@ -16,7 +16,7 @@ namespace WixToolset.Core.WindowsInstaller.Rows
16 // TODO: Remove this
17 internal sealed class WixActionRowCollection : ICollection
18 {
19 - private SortedList collection;
19 + private readonly SortedList collection;
20
21 /// <summary>
22 /// Creates a new action table object.
@@ -235,7 +235,7 @@ namespace WixToolset.Core.WindowsInstaller.Rows
235 string id = null;
236 string condition = null;
237 bool empty = reader.IsEmptyElement;
238 - int sequence = int.MinValue;
238 + int sequence = Int32.MinValue;
239 int sequenceCount = 0;
240 SequenceTable[] sequenceTables = new SequenceTable[Enum.GetValues(typeof(SequenceTable)).Length];
241
@@ -263,7 +263,7 @@ namespace WixToolset.Core.WindowsInstaller.Rows
263 case "AdvtExecuteSequence":
264 if (reader.Value.Equals("yes"))
265 {
266 - sequenceTables[sequenceCount] = SequenceTable.AdvtExecuteSequence;
266 + sequenceTables[sequenceCount] = SequenceTable.AdvertiseExecuteSequence;
267 ++sequenceCount;
268 }
269 break;
@@ -295,7 +295,7 @@ namespace WixToolset.Core.WindowsInstaller.Rows
295 throw new XmlException();
296 }
297
298 - if (int.MinValue == sequence)
298 + if (Int32.MinValue == sequence)
299 {
300 throw new XmlException();
301 }
@@ -316,7 +316,7 @@ namespace WixToolset.Core.WindowsInstaller.Rows
316
317 // create the actions
318 WixActionRow[] actionRows = new WixActionRow[sequenceCount];
319 - for (int i = 0; i < sequenceCount; i++)
319 + for (var i = 0; i < sequenceCount; i++)
320 {
321 //WixActionRow actionRow = new WixActionRow(sequenceTables[i], id, condition, sequence);
322 //actionRows[i] = actionRow;
src/WixToolset.Core/Compiler.cs
+598 -2105
@@ -21,8 +21,11 @@ namespace WixToolset.Core
21 /// </summary>
22 internal partial class Compiler : ICompiler
23 {
24 - public const string DefaultComponentIdPlaceholderFormat = "WixComponentIdPlaceholder{0}";
25 - public const string DefaultComponentIdPlaceholderWixVariableFormat = "!(wix.{0})";
24 + private const int MinValueOfMaxCabSizeForLargeFileSplitting = 20; // 20 MB
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})";
29 // If these are true you know you are building a module or product
30 // but if they are false you cannot not be sure they will not end
31 // up a product or module. Use these flags carefully.
@@ -164,6 +167,76 @@ namespace WixToolset.Core
167 return this.Messaging.EncounteredError ? null : target;
168 }
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 +
240 private void ResolveComponentIdPlaceholders(Intermediate target)
241 {
242 if (0 < this.componentIdPlaceholdersResolver.VariableCount)
@@ -214,7 +287,7 @@ namespace WixToolset.Core
287 /// <returns>Null if the string is null, otherwise returns the lowercase.</returns>
288 private static string LowercaseOrNull(string s)
289 {
217 - return (null == s) ? s : s.ToLowerInvariant();
290 + return s?.ToLowerInvariant();
291 }
292
293 /// <summary>
@@ -227,18 +300,11 @@ namespace WixToolset.Core
300 {
301 if (null != shortName && null != longName && !String.Equals(shortName, longName, StringComparison.OrdinalIgnoreCase))
302 {
230 - return String.Format(CultureInfo.InvariantCulture, "{0}|{1}", shortName, longName);
303 + return String.Concat(shortName, "|", longName);
304 }
305 else
306 {
234 - if (this.Core.IsValidShortFilename(longName, false))
235 - {
236 - return longName;
237 - }
238 - else
239 - {
240 - return shortName;
241 - }
307 + return this.Core.IsValidShortFilename(longName, false) ? longName : shortName;
308 }
309 }
310
@@ -246,19 +312,23 @@ namespace WixToolset.Core
312 /// Adds a search property to the active section.
313 /// </summary>
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>
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)
318 {
319 if (!this.Core.EncounteredError)
320 {
255 - if (property.Id != property.Id.ToUpperInvariant())
321 + if (propertyId.Id != propertyId.Id.ToUpperInvariant())
322 {
257 - this.Core.Write(ErrorMessages.SearchPropertyNotUppercase(sourceLineNumbers, "Property", "Id", property.Id));
323 + this.Core.Write(ErrorMessages.SearchPropertyNotUppercase(sourceLineNumbers, "Property", "Id", propertyId.Id));
324 }
325
260 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.AppSearch, property);
261 - row.Set(1, signature);
326 + var tuple = new AppSearchTuple(sourceLineNumbers, propertyId)
327 + {
328 + Signature_ = signature
329 + };
330 +
331 + this.Core.AddTuple(tuple);
332 }
333 }
334
@@ -266,16 +336,16 @@ namespace WixToolset.Core
336 /// Adds a property to the active section.
337 /// </summary>
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>
340 /// <param name="value">Value of property.</param>
341 /// <param name="admin">Flag if property is an admin property.</param>
342 /// <param name="secure">Flag if property is a secure property.</param>
343 /// <param name="hidden">Flag if property is to be hidden.</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)
346 {
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))
349 {
350 return;
351 }
@@ -290,7 +360,7 @@ namespace WixToolset.Core
360 var group = match.Groups["identifier"];
361 if (group.Success)
362 {
293 - this.Core.Write(WarningMessages.PropertyValueContainsPropertyReference(sourceLineNumbers, property.Id, group.Value));
363 + this.Core.Write(WarningMessages.PropertyValueContainsPropertyReference(sourceLineNumbers, propertyId.Id, group.Value));
364 }
365 }
366 }
@@ -302,26 +372,26 @@ namespace WixToolset.Core
372 // Add the row to a separate section if requested.
373 if (fragment)
374 {
305 - var id = String.Concat(this.Core.ActiveSection.Id, ".", property.Id);
375 + var id = String.Concat(this.Core.ActiveSection.Id, ".", propertyId.Id);
376
377 section = this.Core.CreateSection(id, SectionType.Fragment, this.Core.ActiveSection.Codepage, this.Context.CompilationId);
378
379 // Reference the property in the active section.
310 - this.Core.CreateSimpleReference(sourceLineNumbers, "Property", property.Id);
380 + this.Core.CreateSimpleReference(sourceLineNumbers, "Property", propertyId.Id);
381 }
382
313 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Property, section, property);
314 -
383 // Allow row to exist with no value so that PropertyRefs can be made for *Search elements
384 // the linker will remove these rows before the final output is created.
317 - if (null != value)
385 + var tuple = new PropertyTuple(sourceLineNumbers, propertyId)
386 {
319 - row.Set(1, value);
320 - }
387 + Value = value,
388 + };
389 +
390 + section.Tuples.Add(tuple);
391
392 if (admin || hidden || secure)
393 {
324 - this.AddWixPropertyRow(sourceLineNumbers, property, admin, secure, hidden, section);
394 + this.AddWixPropertyRow(sourceLineNumbers, propertyId, admin, secure, hidden, section);
395 }
396 }
397 }
@@ -340,10 +410,15 @@ namespace WixToolset.Core
410 this.Core.EnsureTable(sourceLineNumbers, "Property"); // Property table is always required when using WixProperty table.
411 }
412
343 - var row = (WixPropertyTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixProperty, section, property);
344 - row.Admin = admin;
345 - row.Hidden = hidden;
346 - row.Secure = secure;
413 + var tuple = new WixPropertyTuple(sourceLineNumbers)
414 + {
415 + Property_ = property.Id,
416 + Admin = admin,
417 + Hidden = hidden,
418 + Secure = secure
419 + };
420 +
421 + section.Tuples.Add(tuple);
422 }
423
424 /// <summary>
@@ -375,9 +450,9 @@ namespace WixToolset.Core
450 string localService = null;
451 string serviceParameters = null;
452 string dllSurrogate = null;
378 - var activateAtStorage = YesNoType.NotSet;
453 + bool? activateAtStorage = null;
454 var appIdAdvertise = YesNoType.NotSet;
380 - var runAsInteractiveUser = YesNoType.NotSet;
455 + bool? runAsInteractiveUser = null;
456 string description = null;
457
458 foreach (var attrib in node.Attributes())
@@ -390,7 +465,7 @@ namespace WixToolset.Core
465 appId = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
466 break;
467 case "ActivateAtStorage":
393 - activateAtStorage = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
468 + activateAtStorage = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
469 break;
470 case "Advertise":
471 appIdAdvertise = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
@@ -408,7 +483,7 @@ namespace WixToolset.Core
483 remoteServerName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
484 break;
485 case "RunAsInteractiveUser":
411 - runAsInteractiveUser = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
486 + runAsInteractiveUser = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
487 break;
488 case "ServiceParameters":
489 serviceParameters = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
@@ -473,21 +548,19 @@ namespace WixToolset.Core
548
549 if (!this.Core.EncounteredError)
550 {
476 - var id = new Identifier(appId, AccessModifier.Public);
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 - }
551 + var id = new Identifier(AccessModifier.Public, appId);
552
487 - if (YesNoType.Yes == runAsInteractiveUser)
553 + var tuple = new AppIdTuple(sourceLineNumbers, id)
554 {
489 - row.Set(6, 1);
490 - }
555 + RemoteServerName = remoteServerName,
556 + LocalService = localService,
557 + ServiceParameters = serviceParameters,
558 + DllSurrogate = dllSurrogate,
559 + ActivateAtStorage = activateAtStorage,
560 + RunAsInteractiveUser = runAsInteractiveUser
561 + };
562 +
563 + this.Core.AddTuple(tuple);
564 }
565 }
566 else if (YesNoType.No == advertise)
@@ -521,12 +594,12 @@ namespace WixToolset.Core
594 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "DllSurrogate", dllSurrogate, componentId);
595 }
596
524 - if (YesNoType.Yes == activateAtStorage)
597 + if (true == activateAtStorage)
598 {
599 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "ActivateAtStorage", "Y", componentId);
600 }
601
529 - if (YesNoType.Yes == runAsInteractiveUser)
602 + if (true == runAsInteractiveUser)
603 {
604 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Concat("AppID\\", appId), "RunAs", "Interactive User", componentId);
605 }
@@ -576,10 +649,14 @@ namespace WixToolset.Core
649
650 if (!this.Core.EncounteredError)
651 {
579 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiAssemblyName);
580 - row.Set(0, componentId);
581 - row.Set(1, id);
582 - row.Set(2, value);
652 + var tuple = new MsiAssemblyNameTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, componentId, id))
653 + {
654 + Component_ = componentId,
655 + Name = id,
656 + Value = value
657 + };
658 +
659 + this.Core.AddTuple(tuple);
660 }
661 }
662
@@ -661,12 +738,16 @@ namespace WixToolset.Core
738
739 if (!this.Core.EncounteredError)
740 {
664 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Binary, id);
665 - row.Set(1, sourceFile);
741 + var tuple = new BinaryTuple(sourceLineNumbers, id)
742 + {
743 + Data = sourceFile
744 + };
745 +
746 + this.Core.AddTuple(tuple);
747
748 if (YesNoType.Yes == suppressModularization)
749 {
669 - var wixSuppressModularizationRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixSuppressModularization, id);
750 + this.Core.AddTuple(new WixSuppressModularizationTuple(sourceLineNumbers, id));
751 }
752 }
753
@@ -736,8 +817,10 @@ namespace WixToolset.Core
817
818 if (!this.Core.EncounteredError)
819 {
739 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Icon, id);
740 - row.Set(1, sourceFile);
820 + this.Core.AddTuple(new IconTuple(sourceLineNumbers, id)
821 + {
822 + Data = sourceFile
823 + });
824 }
825
826 return id.Id;
@@ -808,7 +891,7 @@ namespace WixToolset.Core
891 private void ParseInstanceElement(XElement node, string propertyId)
892 {
893 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
811 - string id = null;
894 + Identifier id = null;
895 string productCode = null;
896 string productName = null;
897 string upgradeCode = null;
@@ -820,7 +903,7 @@ namespace WixToolset.Core
903 switch (attrib.Name.LocalName)
904 {
905 case "Id":
823 - id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
906 + id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
907 break;
908 case "ProductCode":
909 productCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, true);
@@ -856,18 +939,15 @@ namespace WixToolset.Core
939
940 if (!this.Core.EncounteredError)
941 {
859 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixInstanceTransforms);
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)
942 + var tuple = new WixInstanceTransformsTuple(sourceLineNumbers, id)
943 {
869 - row.Set(4, upgradeCode);
870 - }
944 + PropertyId = propertyId,
945 + ProductCode = productCode,
946 + ProductName = productName,
947 + UpgradeCode = upgradeCode
948 + };
949 +
950 + this.Core.AddTuple(tuple);
951 }
952 }
953
@@ -928,19 +1008,16 @@ namespace WixToolset.Core
1008
1009 if (!this.Core.EncounteredError)
1010 {
931 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PublishComponent);
932 - row.Set(0, id);
933 - row.Set(1, qualifier);
934 - row.Set(2, componentId);
935 - row.Set(3, appData);
936 - if (null == feature)
1011 + var tuple = new PublishComponentTuple(sourceLineNumbers)
1012 {
938 - row.Set(4, Guid.Empty.ToString("B"));
939 - }
940 - else
941 - {
942 - row.Set(4, feature);
943 - }
1013 + ComponentId = id,
1014 + Qualifier = qualifier,
1015 + Component_ = componentId,
1016 + AppData = appData,
1017 + Feature_ = feature ?? Guid.Empty.ToString("B"),
1018 + };
1019 +
1020 + this.Core.AddTuple(tuple);
1021 }
1022 }
1023
@@ -1662,7 +1739,7 @@ namespace WixToolset.Core
1739 string name = null;
1740 string signature = null;
1741 RegistryRootType? root = null;
1665 - var type = CompilerConstants.IntegerNotSet;
1742 + RegLocatorType? type = null;
1743 var search64bit = false;
1744
1745 foreach (var attrib in node.Attributes())
@@ -1688,13 +1765,13 @@ namespace WixToolset.Core
1765 switch (typeValue)
1766 {
1767 case "directory":
1691 - type = 0;
1768 + type = RegLocatorType.Directory;
1769 break;
1770 case "file":
1694 - type = 1;
1771 + type = RegLocatorType.FileName;
1772 break;
1773 case "raw":
1697 - type = 2;
1774 + type = RegLocatorType.Raw;
1775 break;
1776 case "":
1777 break;
@@ -1738,7 +1815,7 @@ namespace WixToolset.Core
1815 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Root"));
1816 }
1817
1741 - if (CompilerConstants.IntegerNotSet == type)
1818 + if (!type.HasValue)
1819 {
1820 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Type"));
1821 }
@@ -1776,7 +1853,7 @@ namespace WixToolset.Core
1853 }
1854 oneChild = true;
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
1857 break;
1858 case "FileSearchRef":
1859 if (oneChild)
@@ -1785,7 +1862,7 @@ namespace WixToolset.Core
1862 }
1863 oneChild = true;
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);
1866 signature = null;
1867 break;
1868 default:
@@ -1799,14 +1876,18 @@ namespace WixToolset.Core
1876 }
1877 }
1878
1802 -
1879 if (!this.Core.EncounteredError)
1880 {
1805 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.RegLocator, id);
1806 - row.Set(1, (int)root);
1807 - row.Set(2, key);
1808 - row.Set(3, name);
1809 - row.Set(4, search64bit ? (type | 16) : type);
1881 + var tuple = new RegLocatorTuple(sourceLineNumbers, id)
1882 + {
1883 + Root = root.Value,
1884 + Key = key,
1885 + Name = name,
1886 + Type = type.Value,
1887 + Win64 = search64bit
1888 + };
1889 +
1890 + this.Core.AddTuple(tuple);
1891 }
1892
1893 return signature;
@@ -2017,8 +2098,7 @@ namespace WixToolset.Core
2098
2099 if (!this.Core.EncounteredError)
2100 {
2020 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CCPSearch);
2021 - row.Set(0, signature);
2101 + this.Core.AddTuple(new CCPSearchTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, signature)));
2102 }
2103 }
2104
@@ -2044,7 +2124,7 @@ namespace WixToolset.Core
2124 var guid = "*";
2125 var componentIdPlaceholder = String.Format(Compiler.DefaultComponentIdPlaceholderFormat, this.componentIdPlaceholdersResolver.VariableCount); // placeholder id for defaulting Component/@Id to keypath id.
2126 var componentIdPlaceholderWixVariable = String.Format(Compiler.DefaultComponentIdPlaceholderWixVariableFormat, componentIdPlaceholder);
2047 - var id = new Identifier(componentIdPlaceholderWixVariable, AccessModifier.Private);
2127 + var id = new Identifier(AccessModifier.Private, componentIdPlaceholderWixVariable);
2128 var keyFound = false;
2129 string keyPath = null;
2130 var shouldAddCreateFolder = false;
@@ -2402,9 +2482,13 @@ namespace WixToolset.Core
2482
2483 if (shouldAddCreateFolder)
2484 {
2405 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CreateFolder, new Identifier(AccessModifier.Public, directoryId, id.Id));
2406 - row.Set(0, directoryId);
2407 - row.Set(1, id.Id);
2485 + var tuple = new CreateFolderTuple(sourceLineNumbers)
2486 + {
2487 + Directory_ = directoryId,
2488 + Component_ = id.Id
2489 + };
2490 +
2491 + this.Core.AddTuple(tuple);
2492 }
2493
2494 // check for conditions that exclude this component from using generated guids
@@ -2439,7 +2523,7 @@ namespace WixToolset.Core
2523 {
2524 this.componentIdPlaceholdersResolver.AddVariable(sourceLineNumbers, componentIdPlaceholder, keyPath, false);
2525
2442 - id = new Identifier(keyPath, AccessModifier.Private);
2526 + id = new Identifier(AccessModifier.Private, keyPath);
2527 }
2528 else
2529 {
@@ -2458,7 +2542,6 @@ namespace WixToolset.Core
2542 {
2543 var tuple = new ComponentTuple(sourceLineNumbers, id)
2544 {
2461 - Component = id.Id,
2545 ComponentId = guid,
2546 Directory_ = directoryId,
2547 Location = location,
@@ -2472,35 +2555,29 @@ namespace WixToolset.Core
2555 Shared = shared,
2556 Transitive = transitive,
2557 UninstallWhenSuperseded = uninstallWhenSuperseded,
2475 - Win64 = win64,
2558 + Win64 = win64
2559 };
2560
2561 this.Core.AddTuple(tuple);
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 -
2563 if (multiInstance)
2564 {
2489 - //var instanceComponentRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixInstanceComponent, id);
2490 -
2491 - var instanceComponentTuple = new WixInstanceComponentTuple(sourceLineNumbers, id)
2565 + this.Core.AddTuple(new WixInstanceComponentTuple(sourceLineNumbers, id)
2566 {
2567 Component_ = id.Id,
2494 - };
2495 -
2496 - this.Core.AddTuple(instanceComponentTuple);
2568 + });
2569 }
2570
2571 if (0 < symbols.Count)
2572 {
2501 - var symbolRow = (WixDeltaPatchSymbolPathsTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchSymbolPaths, id);
2502 - symbolRow.Type = SymbolPathType.Component;
2503 - symbolRow.SymbolPaths = String.Join(";", symbols);
2573 + var tupleDelaPatch = new WixDeltaPatchSymbolPathsTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, SymbolPathType.Component, id.Id))
2574 + {
2575 + SymbolType = SymbolPathType.Component,
2576 + SymbolId = id.Id,
2577 + SymbolPaths = String.Join(";", symbols)
2578 + };
2579 +
2580 + this.Core.AddTuple(tupleDelaPatch);
2581 }
2582
2583 // Complus
@@ -2607,7 +2684,7 @@ namespace WixToolset.Core
2684
2685 if (!this.Core.EncounteredError)
2686 {
2610 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixComponentGroup, id);
2687 + this.Core.AddTuple(new WixComponentGroupTuple(sourceLineNumbers, id));
2688
2689 // Add this componentGroup and its parent in WixGroup.
2690 this.Core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.ComponentGroup, id.Id);
@@ -2802,7 +2879,7 @@ namespace WixToolset.Core
2879 }
2880 oneChild = true;
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
2883 break;
2884 case "FileSearchRef":
2885 if (oneChild)
@@ -2811,7 +2888,7 @@ namespace WixToolset.Core
2888 }
2889 oneChild = true;
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);
2892 signature = null;
2893 break;
2894 default:
@@ -2903,9 +2980,13 @@ namespace WixToolset.Core
2980
2981 if (!this.Core.EncounteredError)
2982 {
2906 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CreateFolder, new Identifier(AccessModifier.Public, directoryId, componentId));
2907 - row.Set(0, directoryId);
2908 - row.Set(1, componentId);
2983 + var tuple = new CreateFolderTuple(sourceLineNumbers)
2984 + {
2985 + Directory_ = directoryId,
2986 + Component_ = componentId
2987 + };
2988 +
2989 + this.Core.AddTuple(tuple);
2990 }
2991
2992 return directoryId;
@@ -3026,32 +3107,17 @@ namespace WixToolset.Core
3107
3108 if (!this.Core.EncounteredError)
3109 {
3029 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MoveFile, 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)
3110 + var tuple = new MoveFileTuple(sourceLineNumbers, id)
3111 {
3035 - row.Set(4, sourceDirectory);
3036 - }
3037 - else if (null != sourceProperty)
3038 - {
3039 - row.Set(4, sourceProperty);
3040 - }
3041 - else
3042 - {
3043 - row.Set(4, sourceFolder);
3044 - }
3112 + Component_ = componentId,
3113 + SourceName = sourceName,
3114 + DestName= String.IsNullOrEmpty(destinationShortName) && String.IsNullOrEmpty(destinationName) ? null : this.GetMsiFilenameValue(destinationShortName, destinationName),
3115 + SourceFolder = sourceDirectory ?? sourceProperty,
3116 + DestFolder = destinationDirectory ?? destinationProperty,
3117 + Delete = delete
3118 + };
3119
3046 - if (null != destinationDirectory)
3047 - {
3048 - row.Set(5, destinationDirectory);
3049 - }
3050 - else
3051 - {
3052 - row.Set(5, destinationProperty);
3053 - }
3054 - row.Set(6, delete ? 1 : 0);
3120 + this.Core.AddTuple(tuple);
3121 }
3122 }
3123 else // copy the file
@@ -3088,18 +3154,15 @@ namespace WixToolset.Core
3154
3155 if (!this.Core.EncounteredError)
3156 {
3091 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.DuplicateFile, 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)
3157 + var tuple = new DuplicateFileTuple(sourceLineNumbers, id)
3158 {
3097 - row.Set(4, destinationDirectory);
3098 - }
3099 - else
3100 - {
3101 - row.Set(4, destinationProperty);
3102 - }
3159 + Component_ = componentId,
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);
3166 }
3167 }
3168 }
@@ -3499,20 +3562,12 @@ namespace WixToolset.Core
3562 TSAware = tsAware,
3563 Win64 = win64,
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 - //}
3565
3566 this.Core.AddTuple(tuple);
3567
3568 if (YesNoType.Yes == suppressModularization)
3569 {
3515 - this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixSuppressModularization, id);
3570 + this.Core.AddTuple(new WixSuppressModularizationTuple(sourceLineNumbers, id));
3571 }
3572
3573 // For deferred CAs that specify HideTarget we should also hide the CA data property for the action.
@@ -3618,124 +3673,6 @@ namespace WixToolset.Core
3673 }
3674 }
3675
3621 - /// <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 -
3676 /// <summary>
3677 /// Parses an ensure table element.
3678 /// </summary>
@@ -4022,9 +3959,11 @@ namespace WixToolset.Core
3959
3960 if (!this.Core.EncounteredError)
3961 {
4025 - var rowRow = this.Core.CreateRow(childSourceLineNumbers, TupleDefinitionType.WixCustomRow);
4026 - rowRow.Set(0, tableId);
4027 - rowRow.Set(1, dataValue);
3962 + this.Core.AddTuple(new WixCustomRowTuple(childSourceLineNumbers)
3963 + {
3964 + Table = tableId,
3965 + FieldData = dataValue
3966 + });
3967 }
3968 break;
3969 default:
@@ -4047,21 +3986,24 @@ namespace WixToolset.Core
3986
3987 if (!this.Core.EncounteredError)
3988 {
4050 - var id = new Identifier(tableId, AccessModifier.Public);
4051 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixCustomTable, id);
4052 - row.Set(1, columnCount);
4053 - row.Set(2, columnNames);
4054 - row.Set(3, columnTypes);
4055 - row.Set(4, primaryKeys);
4056 - row.Set(5, minValues);
4057 - row.Set(6, maxValues);
4058 - row.Set(7, keyTables);
4059 - row.Set(8, keyColumns);
4060 - row.Set(9, categories);
4061 - row.Set(10, sets);
4062 - row.Set(11, descriptions);
4063 - row.Set(12, modularizations);
4064 - row.Set(13, bootstrapperApplicationData ? 1 : 0);
3989 + var tuple = new WixCustomTableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, tableId))
3990 + {
3991 + ColumnCount = columnCount,
3992 + ColumnNames = columnNames,
3993 + ColumnTypes = columnTypes,
3994 + PrimaryKeys = primaryKeys,
3995 + MinValues = minValues,
3996 + MaxValues = maxValues,
3997 + KeyTables = keyTables,
3998 + KeyColumns = keyColumns,
3999 + Categories = categories,
4000 + Sets = sets,
4001 + Descriptions = descriptions,
4002 + Modularizations = modularizations,
4003 + BootstrapperApplicationData = bootstrapperApplicationData
4004 + };
4005 +
4006 + this.Core.AddTuple(tuple);
4007 }
4008 }
4009 }
@@ -4315,22 +4257,23 @@ namespace WixToolset.Core
4257
4258 if (!this.Core.EncounteredError)
4259 {
4318 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Directory, id);
4319 - row.Set(1, parentId);
4320 - row.Set(2, defaultDir);
4321 -
4322 - if (null != componentGuidGenerationSeed)
4260 + var tuple = new DirectoryTuple(sourceLineNumbers, id)
4261 {
4324 - var wixRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDirectory);
4325 - wixRow.Set(0, id.Id);
4326 - wixRow.Set(1, componentGuidGenerationSeed);
4327 - }
4262 + Directory_Parent = parentId,
4263 + DefaultDir = defaultDir,
4264 + ComponentGuidGenerationSeed = componentGuidGenerationSeed
4265 + };
4266 +
4267 + this.Core.AddTuple(tuple);
4268
4269 if (null != symbols)
4270 {
4331 - var symbolRow = (WixDeltaPatchSymbolPathsTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchSymbolPaths, id);
4332 - symbolRow.Type = SymbolPathType.Directory;
4333 - symbolRow.SymbolPaths = symbols;
4271 + this.Core.AddTuple(new WixDeltaPatchSymbolPathsTuple(sourceLineNumbers, id)
4272 + {
4273 + SymbolType = SymbolPathType.Directory,
4274 + SymbolId = id.Id,
4275 + SymbolPaths = symbols,
4276 + });
4277 }
4278 }
4279 }
@@ -4547,14 +4490,19 @@ namespace WixToolset.Core
4490 signature = id.Id;
4491 }
4492
4550 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.DrLocator, new Identifier(access, rowId, parentSignature, path));
4551 - row.Set(0, rowId);
4552 - row.Set(1, parentSignature);
4553 - row.Set(2, path);
4493 + var tuple = new DrLocatorTuple(sourceLineNumbers)
4494 + {
4495 + Signature_ = rowId,
4496 + Parent = parentSignature,
4497 + Path = path,
4498 + };
4499 +
4500 if (CompilerConstants.IntegerNotSet != depth)
4501 {
4556 - row.Set(3, depth);
4502 + tuple.Depth = depth;
4503 }
4504 +
4505 + this.Core.AddTuple(tuple);
4506 }
4507
4508 return signature;
@@ -5144,7 +5092,7 @@ namespace WixToolset.Core
5092
5093 if (!this.Core.EncounteredError)
5094 {
5147 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixFeatureGroup, id);
5095 + this.Core.AddTuple(new WixFeatureGroupTuple(sourceLineNumbers, id));
5096
5097 //Add this FeatureGroup and its parent in WixGroup.
5098 this.Core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.FeatureGroup, id.Id);
@@ -5403,8 +5351,13 @@ namespace WixToolset.Core
5351
5352 if (!this.Core.EncounteredError)
5353 {
5406 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Error, new Identifier(AccessModifier.Public, id));
5407 - row.Set(1, Common.GetInnerText(node)); // TODO: *
5354 + var tuple = new ErrorTuple(sourceLineNumbers)
5355 + {
5356 + Error = id,
5357 + Message = Common.GetInnerText(node)
5358 + };
5359 +
5360 + this.Core.AddTuple(tuple);
5361 }
5362 }
5363
@@ -5490,12 +5443,16 @@ namespace WixToolset.Core
5443 {
5444 if (!this.Core.EncounteredError)
5445 {
5493 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Extension);
5494 - row.Set(0, extension);
5495 - row.Set(1, componentId);
5496 - row.Set(2, progId);
5497 - row.Set(3, mime);
5498 - row.Set(4, Guid.Empty.ToString("B"));
5446 + var tuple = new ExtensionTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, extension, componentId))
5447 + {
5448 + Extension = extension,
5449 + Component_ = componentId,
5450 + ProgId_ = progId,
5451 + MIME_ = mime,
5452 + Feature_ = Guid.Empty.ToString("B")
5453 + };
5454 +
5455 + this.Core.AddTuple(tuple);
5456
5457 this.Core.EnsureTable(sourceLineNumbers, "Verb");
5458 }
@@ -5560,7 +5517,7 @@ namespace WixToolset.Core
5517 string symbols = null;
5518
5519 string procArch = null;
5563 - var selfRegCost = CompilerConstants.IntegerNotSet;
5520 + int? selfRegCost = null;
5521 string shortName = null;
5522 var source = sourcePath; // assume we'll use the parents as the source for this file
5523 var sourceSet = false;
@@ -5914,30 +5871,29 @@ namespace WixToolset.Core
5871 }
5872 }
5873
5917 - var fileRow = (FileTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.File, 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)
5874 + var tuple = new FileTuple(sourceLineNumbers, id)
5875 {
5929 - fileRow.Version = defaultVersion;
5930 - }
5931 - fileRow.Language = defaultLanguage;
5932 - fileRow.ReadOnly = readOnly;
5933 - fileRow.Checksum = checksum;
5934 - fileRow.Compressed = compressed;
5935 - fileRow.Hidden = hidden;
5936 - fileRow.System = system;
5937 - fileRow.Vital = vital;
5938 - // the Sequence row is set in the binder
5876 + Component_ = componentId,
5877 + ShortFileName = shortName,
5878 + LongFileName = name,
5879 + FileSize = defaultSize,
5880 + Version = companionFile ?? defaultVersion,
5881 + Language = defaultLanguage,
5882 + ReadOnly = readOnly,
5883 + Hidden = hidden,
5884 + System = system,
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);
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);
5897 wixFileRow.AssemblyType = assemblyType;
5898 wixFileRow.File_AssemblyManifest = assemblyManifest;
5899 wixFileRow.File_AssemblyApplication = assemblyApplication;
@@ -5951,50 +5907,34 @@ namespace WixToolset.Core
5907
5908 // Always create a delta patch row for this file since other elements (like Component and Media) may
5909 // want to add symbol paths to it.
5954 - var deltaPatchFileRow = (WixDeltaPatchFileTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchFile, id);
5955 - deltaPatchFileRow.RetainLengths = protectLengths;
5956 - deltaPatchFileRow.IgnoreOffsets = ignoreOffsets;
5957 - deltaPatchFileRow.IgnoreLengths = ignoreLengths;
5958 - deltaPatchFileRow.RetainOffsets = protectOffsets;
5910 + this.Core.AddTuple(new WixDeltaPatchFileTuple(sourceLineNumbers, id)
5911 + {
5912 + RetainLengths = protectLengths,
5913 + IgnoreOffsets = ignoreOffsets,
5914 + IgnoreLengths = ignoreLengths,
5915 + RetainOffsets = protectOffsets
5916 + });
5917
5918 if (null != symbols)
5919 {
5962 - var symbolRow = (WixDeltaPatchSymbolPathsTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchSymbolPaths, id);
5963 - symbolRow.Type = SymbolPathType.File;
5964 - symbolRow.SymbolPaths = symbols;
5920 + this.Core.AddTuple(new WixDeltaPatchSymbolPathsTuple(sourceLineNumbers)
5921 + {
5922 + SymbolType = SymbolPathType.File,
5923 + SymbolId = id.Id,
5924 + SymbolPaths = symbols
5925 + });
5926 }
5927
5928 if (FileAssemblyType.NotAnAssembly != assemblyType)
5929 {
5969 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiAssembly);
5970 - row.Set(0, componentId);
5971 - row.Set(1, Guid.Empty.ToString("B"));
5972 - row.Set(2, assemblyManifest);
5973 - row.Set(3, assemblyApplication);
5974 - row.Set(4, (FileAssemblyType.DotNetAssembly == assemblyType) ? 0 : 1);
5975 - }
5976 -
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);
5930 + this.Core.AddTuple(new MsiAssemblyTuple(sourceLineNumbers)
5931 + {
5932 + Component_ = componentId,
5933 + Feature_ = Guid.Empty.ToString("B"),
5934 + File_Manifest = assemblyManifest,
5935 + File_Application = assemblyApplication,
5936 + Type = assemblyType
5937 + });
5938 }
5939 }
5940
@@ -6110,7 +6050,7 @@ namespace WixToolset.Core
6050 }
6051 else // reuse parent signature in the Signature table
6052 {
6113 - id = new Identifier(parentSignature, AccessModifier.Private);
6053 + id = new Identifier(AccessModifier.Private, parentSignature);
6054 }
6055 }
6056
@@ -6138,28 +6078,35 @@ namespace WixToolset.Core
6078
6079 if (!this.Core.EncounteredError)
6080 {
6141 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Signature, id);
6142 - row.Set(1, name ?? shortName);
6143 - row.Set(2, minVersion);
6144 - row.Set(3, maxVersion);
6081 + var tuple = new SignatureTuple(sourceLineNumbers, id)
6082 + {
6083 + FileName = name ?? shortName,
6084 + MinVersion = minVersion,
6085 + MaxVersion = maxVersion,
6086 + Languages = languages
6087 + };
6088
6089 if (CompilerConstants.IntegerNotSet != minSize)
6090 {
6148 - row.Set(4, minSize);
6091 + tuple.MinSize = minSize;
6092 }
6093 +
6094 if (CompilerConstants.IntegerNotSet != maxSize)
6095 {
6152 - row.Set(5, maxSize);
6096 + tuple.MaxSize = maxSize;
6097 }
6098 +
6099 if (CompilerConstants.IntegerNotSet != minDate)
6100 {
6156 - row.Set(6, minDate);
6101 + tuple.MinDate = minDate;
6102 }
6103 +
6104 if (CompilerConstants.IntegerNotSet != maxDate)
6105 {
6160 - row.Set(7, maxDate);
6106 + tuple.MaxDate = maxDate;
6107 }
6162 - row.Set(8, languages);
6108 +
6109 + this.Core.AddTuple(tuple);
6110
6111 // Create a DrLocator row to associate the file with a directory
6112 // when a different identifier is specified for the FileSearch.
@@ -6169,15 +6116,19 @@ namespace WixToolset.Core
6116 {
6117 // Creates the DrLocator row for the directory search while
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));
6173 - row.Set(0, parentSignature);
6174 - row.Set(1, id.Id);
6119 + this.Core.AddTuple(new DrLocatorTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, parentSignature, id.Id, String.Empty))
6120 + {
6121 + Signature_ = parentSignature,
6122 + Parent = id.Id
6123 + });
6124 }
6125 else
6126 {
6178 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.DrLocator, new Identifier(AccessModifier.Public, id.Id, parentSignature, String.Empty));
6179 - row.Set(0, id.Id);
6180 - row.Set(1, parentSignature);
6127 + this.Core.AddTuple(new DrLocatorTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, id.Id, parentSignature, String.Empty))
6128 + {
6129 + Signature_ = id.Id,
6130 + Parent = parentSignature
6131 + });
6132 }
6133 }
6134 }
@@ -6193,7 +6144,7 @@ namespace WixToolset.Core
6144 private void ParseFragmentElement(XElement node)
6145 {
6146 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
6196 - string id = null;
6147 + Identifier id = null;
6148
6149 this.activeName = null;
6150 this.activeLanguage = null;
@@ -6205,7 +6156,7 @@ namespace WixToolset.Core
6156 switch (attrib.Name.LocalName)
6157 {
6158 case "Id":
6208 - id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
6159 + id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
6160 break;
6161 default:
6162 this.Core.UnexpectedAttribute(node, attrib);
@@ -6220,7 +6171,7 @@ namespace WixToolset.Core
6171
6172 // NOTE: Id is not required for Fragments, this is a departure from the normal run of the mill processing.
6173
6223 - this.Core.CreateActiveSection(id, SectionType.Fragment, 0, this.Context.CompilationId);
6174 + this.Core.CreateActiveSection(id?.Id, SectionType.Fragment, 0, this.Context.CompilationId);
6175
6176 var featureDisplay = 0;
6177 foreach (var child in node.Elements())
@@ -6232,19 +6183,19 @@ namespace WixToolset.Core
6183 case "_locDefinition":
6184 break;
6185 case "AdminExecuteSequence":
6235 - this.ParseSequenceElement(child, child.Name.LocalName);
6186 + this.ParseSequenceElement(child, SequenceTable.AdminExecuteSequence);
6187 break;
6188 case "AdminUISequence":
6238 - this.ParseSequenceElement(child, child.Name.LocalName);
6189 + this.ParseSequenceElement(child, SequenceTable.AdminUISequence);
6190 break;
6191 case "AdvertiseExecuteSequence":
6241 - this.ParseSequenceElement(child, child.Name.LocalName);
6192 + this.ParseSequenceElement(child, SequenceTable.AdvertiseExecuteSequence);
6193 break;
6194 case "InstallExecuteSequence":
6244 - this.ParseSequenceElement(child, child.Name.LocalName);
6195 + this.ParseSequenceElement(child, SequenceTable.InstallExecuteSequence);
6196 break;
6197 case "InstallUISequence":
6247 - this.ParseSequenceElement(child, child.Name.LocalName);
6198 + this.ParseSequenceElement(child, SequenceTable.InstallUISequence);
6199 break;
6200 case "AppId":
6201 this.ParseAppIdElement(child, null, YesNoType.Yes, null, null, null);
@@ -6265,7 +6216,7 @@ namespace WixToolset.Core
6216 this.ParseComponentElement(child, ComplexReferenceParentType.Unknown, null, null, CompilerConstants.IntegerNotSet, null, null);
6217 break;
6218 case "ComponentGroup":
6268 - this.ParseComponentGroupElement(child, ComplexReferenceParentType.Unknown, id);
6219 + this.ParseComponentGroupElement(child, ComplexReferenceParentType.Unknown, id?.Id);
6220 break;
6221 case "Condition":
6222 this.ParseConditionElement(child, node.Name.LocalName, null, null);
@@ -6301,7 +6252,7 @@ namespace WixToolset.Core
6252 this.ParseFeatureElement(child, ComplexReferenceParentType.Unknown, null, ref featureDisplay);
6253 break;
6254 case "FeatureGroup":
6304 - this.ParseFeatureGroupElement(child, ComplexReferenceParentType.Unknown, id);
6255 + this.ParseFeatureGroupElement(child, ComplexReferenceParentType.Unknown, id.Id);
6256 break;
6257 case "FeatureRef":
6258 this.ParseFeatureRefElement(child, ComplexReferenceParentType.Unknown, null);
@@ -6326,13 +6277,13 @@ namespace WixToolset.Core
6277 this.ParseCertificatesElement(child);
6278 break;
6279 case "PatchFamily":
6329 - this.ParsePatchFamilyElement(child, ComplexReferenceParentType.Unknown, id);
6280 + this.ParsePatchFamilyElement(child, ComplexReferenceParentType.Unknown, id.Id);
6281 break;
6282 case "PatchFamilyGroup":
6332 - this.ParsePatchFamilyGroupElement(child, ComplexReferenceParentType.Unknown, id);
6283 + this.ParsePatchFamilyGroupElement(child, ComplexReferenceParentType.Unknown, id.Id);
6284 break;
6285 case "PatchFamilyGroupRef":
6335 - this.ParsePatchFamilyGroupRefElement(child, ComplexReferenceParentType.Unknown, id);
6286 + this.ParsePatchFamilyGroupRefElement(child, ComplexReferenceParentType.Unknown, id.Id);
6287 break;
6288 case "PayloadGroup":
6289 this.ParsePayloadGroupElement(child, ComplexReferenceParentType.Unknown, null);
@@ -6384,8 +6335,7 @@ namespace WixToolset.Core
6335
6336 if (!this.Core.EncounteredError && null != id)
6337 {
6387 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixFragment);
6388 - row.Set(0, id);
6338 + this.Core.AddTuple(new WixFragmentTuple(sourceLineNumbers, id));
6339 }
6340 }
6341
@@ -6498,11 +6448,13 @@ namespace WixToolset.Core
6448
6449 if (!this.Core.EncounteredError)
6450 {
6501 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ControlCondition);
6502 - row.Set(0, dialog);
6503 - row.Set(1, id);
6504 - row.Set(2, action);
6505 - row.Set(3, condition);
6451 + this.Core.AddTuple(new ControlConditionTuple(sourceLineNumbers)
6452 + {
6453 + Dialog_ = dialog,
6454 + Control_ = id,
6455 + Action = action,
6456 + Condition = condition,
6457 + });
6458 }
6459 break;
6460 case "Feature":
@@ -6514,10 +6466,12 @@ namespace WixToolset.Core
6466
6467 if (!this.Core.EncounteredError)
6468 {
6517 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Condition);
6518 - row.Set(0, id);
6519 - row.Set(1, level);
6520 - row.Set(2, condition);
6469 + this.Core.AddTuple(new ConditionTuple(sourceLineNumbers)
6470 + {
6471 + Feature_ = id,
6472 + Level = level,
6473 + Condition = condition
6474 + });
6475 }
6476 break;
6477 case "Fragment":
@@ -6529,9 +6483,11 @@ namespace WixToolset.Core
6483
6484 if (!this.Core.EncounteredError)
6485 {
6532 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.LaunchCondition);
6533 - row.Set(0, condition);
6534 - row.Set(1, message);
6486 + this.Core.AddTuple(new LaunchConditionTuple(sourceLineNumbers)
6487 + {
6488 + Condition = condition,
6489 + Description = message
6490 + });
6491 }
6492 break;
6493 }
@@ -6836,7 +6792,7 @@ namespace WixToolset.Core
6792 }
6793 oneChild = true;
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
6796 break;
6797 case "FileSearchRef":
6798 if (oneChild)
@@ -6845,7 +6801,7 @@ namespace WixToolset.Core
6801 }
6802 oneChild = true;
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);
6805 signature = null;
6806 break;
6807 default:
@@ -6861,15 +6817,20 @@ namespace WixToolset.Core
6817
6818 if (!this.Core.EncounteredError)
6819 {
6864 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.IniLocator, id);
6865 - row.Set(1, this.GetMsiFilenameValue(shortName, name));
6866 - row.Set(2, section);
6867 - row.Set(3, key);
6820 + var tuple = new IniLocatorTuple(sourceLineNumbers, id)
6821 + {
6822 + FileName = this.GetMsiFilenameValue(shortName, name),
6823 + Section = section,
6824 + Key = key,
6825 + Type = type
6826 + };
6827 +
6828 if (CompilerConstants.IntegerNotSet != field)
6829 {
6870 - row.Set(4, field);
6830 + tuple.Field = field;
6831 }
6872 - row.Set(5, type);
6832 +
6833 + this.Core.AddTuple(tuple);
6834 }
6835
6836 return signature;
@@ -6915,9 +6876,11 @@ namespace WixToolset.Core
6876
6877 if (!this.Core.EncounteredError)
6878 {
6918 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.IsolatedComponent);
6919 - row.Set(0, shared);
6920 - row.Set(1, componentId);
6879 + this.Core.AddTuple(new IsolatedComponentTuple(sourceLineNumbers)
6880 + {
6881 + Component_Shared = shared,
6882 + Component_Application = componentId
6883 + });
6884 }
6885 }
6886
@@ -6953,9 +6916,9 @@ namespace WixToolset.Core
6916
6917 if (!this.Core.EncounteredError)
6918 {
6956 - var row = this.Core.CreateRow(sourceLineNumbers, "PatchCertificates" == node.Name.LocalName ? TupleDefinitionType.MsiPatchCertificate : TupleDefinitionType.MsiPackageCertificate);
6957 - row.Set(0, name);
6958 - row.Set(1, name);
6919 + var tuple = this.Core.CreateTuple(sourceLineNumbers, "PatchCertificates" == node.Name.LocalName ? TupleDefinitionType.MsiPatchCertificate : TupleDefinitionType.MsiPackageCertificate);
6920 + tuple.Set(0, name);
6921 + tuple.Set(1, name);
6922 }
6923 break;
6924 default:
@@ -7026,8 +6989,10 @@ namespace WixToolset.Core
6989
6990 if (!this.Core.EncounteredError)
6991 {
7029 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiDigitalCertificate, id);
7030 - row.Set(1, sourceFile);
6992 + this.Core.AddTuple(new MsiDigitalCertificateTuple(sourceLineNumbers, id)
6993 + {
6994 + CertData = sourceFile
6995 + });
6996 }
6997
6998 return id.Id;
@@ -7097,11 +7062,13 @@ namespace WixToolset.Core
7062
7063 if (!this.Core.EncounteredError)
7064 {
7100 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiDigitalSignature);
7101 - row.Set(0, "Media");
7102 - row.Set(1, diskId);
7103 - row.Set(2, certificateId);
7104 - row.Set(3, sourceFile);
7065 + this.Core.AddTuple(new MsiDigitalSignatureTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "Media", diskId))
7066 + {
7067 + Table = "Media",
7068 + SignObject = diskId,
7069 + DigitalCertificate_ = certificateId,
7070 + Hash = sourceFile
7071 + });
7072 }
7073 }
7074
@@ -7242,7 +7209,7 @@ namespace WixToolset.Core
7209 this.Core.AddTuple(tuple);
7210
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);
7213
7214 // Add launch condition that blocks upgrades
7215 if (blockUpgrades)
@@ -7273,7 +7240,7 @@ namespace WixToolset.Core
7240 this.Core.AddTuple(upgradeTuple);
7241
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);
7244
7245 var conditionTuple = new LaunchConditionTuple(sourceLineNumbers)
7246 {
@@ -7479,29 +7446,27 @@ namespace WixToolset.Core
7446 // add the row to the section
7447 if (!this.Core.EncounteredError)
7448 {
7482 - var mediaRow = (MediaTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Media, new Identifier(id, AccessModifier.Public));
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)
7449 + var tuple = new MediaTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, id))
7450 {
7493 - var row = (WixMediaTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixMedia);
7494 - row.DiskId_ = id;
7495 - row.CompressionLevel = compressionLevel;
7496 - row.Layout = layout;
7497 - }
7451 + DiskId = id,
7452 + DiskPrompt = diskPrompt,
7453 + Cabinet = cabinet,
7454 + VolumeLabel = volumeLabel,
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);
7461
7462 if (null != symbols)
7463 {
7501 - var symbolRow = (WixDeltaPatchSymbolPathsTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchSymbolPaths);
7502 - symbolRow.Id = id.ToString(CultureInfo.InvariantCulture);
7503 - symbolRow.Type = SymbolPathType.Media;
7504 - symbolRow.SymbolPaths = symbols;
7464 + this.Core.AddTuple(new WixDeltaPatchSymbolPathsTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, SymbolPathType.Media, id))
7465 + {
7466 + SymbolType = SymbolPathType.Media,
7467 + SymbolId = id.ToString(CultureInfo.InvariantCulture),
7468 + SymbolPaths = symbols
7469 + });
7470 }
7471 }
7472 }
@@ -7518,8 +7483,8 @@ namespace WixToolset.Core
7483 string diskPrompt = null;
7484 var patch = null != patchId;
7485 string volumeLabel = null;
7521 - var maximumUncompressedMediaSize = CompilerConstants.IntegerNotSet;
7522 - var maximumCabinetSizeForLargeFileSplitting = CompilerConstants.IntegerNotSet;
7486 + int? maximumUncompressedMediaSize = null;
7487 + int? maximumCabinetSizeForLargeFileSplitting = null;
7488 CompressionLevel? compressionLevel = null; // this defaults to mszip in Binder
7489
7490 var embedCab = patch ? YesNoType.Yes : YesNoType.NotSet;
@@ -7572,7 +7537,7 @@ namespace WixToolset.Core
7537 maximumUncompressedMediaSize = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, Int32.MaxValue);
7538 break;
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);
7541 break;
7542 default:
7543 this.Core.UnexpectedAttribute(node, attrib);
@@ -7585,46 +7550,39 @@ namespace WixToolset.Core
7550 }
7551 }
7552
7588 - if (YesNoType.IllegalValue != embedCab)
7553 + if (YesNoType.Yes == embedCab)
7554 {
7590 - if (YesNoType.Yes == embedCab)
7591 - {
7592 - cabinetTemplate = String.Concat("#", cabinetTemplate);
7593 - }
7555 + cabinetTemplate = String.Concat("#", cabinetTemplate);
7556 }
7557
7558 if (!this.Core.EncounteredError)
7559 {
7598 - var temporaryMediaRow = (MediaTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Media, new Identifier(1, AccessModifier.Public));
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 - {
7608 - mediaTemplateRow.MaximumUncompressedMediaSize = maximumUncompressedMediaSize;
7609 - }
7610 - else
7560 + this.Core.AddTuple(new MediaTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, 1))
7561 {
7612 - mediaTemplateRow.MaximumUncompressedMediaSize = CompilerCore.DefaultMaximumUncompressedMediaSize;
7613 - }
7562 + DiskId = 1
7563 + });
7564
7615 - if (maximumCabinetSizeForLargeFileSplitting != CompilerConstants.IntegerNotSet)
7616 - {
7617 - mediaTemplateRow.MaximumCabinetSizeForLargeFileSplitting = maximumCabinetSizeForLargeFileSplitting;
7618 - }
7619 - else
7565 + var tuple = new WixMediaTemplateTuple(sourceLineNumbers)
7566 {
7621 - mediaTemplateRow.MaximumCabinetSizeForLargeFileSplitting = 0; // Default value of 0 corresponds to max size of 2048 MB (i.e. 2 GB)
7622 - }
7567 + CabinetTemplate = cabinetTemplate,
7568 + VolumeLabel = volumeLabel,
7569 + DiskPrompt = diskPrompt,
7570 + MaximumUncompressedMediaSize = maximumUncompressedMediaSize,
7571 + MaximumCabinetSizeForLargeFileSplitting = maximumCabinetSizeForLargeFileSplitting,
7572 + CompressionLevel = compressionLevel
7573 + };
7574
7624 - if (compressionLevel.HasValue)
7625 - {
7626 - mediaTemplateRow.CompressionLevel = compressionLevel.Value;
7627 - }
7575 + //else
7576 + //{
7577 + // mediaTemplateRow.MaximumUncompressedMediaSize = CompilerCore.DefaultMaximumUncompressedMediaSize;
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);
7586 }
7587 }
7588
@@ -7639,7 +7597,7 @@ namespace WixToolset.Core
7597 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
7598 Identifier id = null;
7599 var configData = String.Empty;
7642 - var fileCompression = YesNoType.NotSet;
7600 + bool? fileCompression = null;
7601 string language = null;
7602 string sourceFile = null;
7603
@@ -7657,7 +7615,7 @@ namespace WixToolset.Core
7615 this.Core.CreateSimpleReference(sourceLineNumbers, "Media", diskId.ToString(CultureInfo.InvariantCulture.NumberFormat));
7616 break;
7617 case "FileCompression":
7660 - fileCompression = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7618 + fileCompression = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7619 break;
7620 case "Language":
7621 language = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, Int16.MaxValue);
@@ -7726,25 +7684,19 @@ namespace WixToolset.Core
7684
7685 if (!this.Core.EncounteredError)
7686 {
7729 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixMerge, 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 - {
7740 - row.Set(5, false);
7741 - }
7742 - else // YesNoType.NotSet == fileCompression
7687 + var tuple = new WixMergeTuple(sourceLineNumbers, id)
7688 {
7744 - // and we leave the column null
7745 - }
7746 - row.Set(6, configData);
7747 - row.Set(7, Guid.Empty.ToString("B"));
7689 + Directory_ = directoryId,
7690 + SourceFile = sourceFile,
7691 + DiskId = diskId,
7692 + ConfigurationData = configData,
7693 + FileCompression = fileCompression,
7694 + Feature_ = Guid.Empty.ToString("B")
7695 + };
7696 +
7697 + tuple.Set((int)WixMergeTupleFields.Language, language);
7698 +
7699 + this.Core.AddTuple(tuple);
7700 }
7701 }
7702
@@ -7922,10 +7874,14 @@ namespace WixToolset.Core
7874
7875 if (!this.Core.EncounteredError)
7876 {
7925 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MIME);
7926 - row.Set(0, contentType);
7927 - row.Set(1, extension);
7928 - row.Set(2, classId);
7877 + var tuple = new MIMETuple(sourceLineNumbers, new Identifier(AccessModifier.Private, contentType))
7878 + {
7879 + ContentType = contentType,
7880 + Extension_ = extension,
7881 + CLSID = classId
7882 + };
7883 +
7884 + this.Core.AddTuple(tuple);
7885 }
7886 }
7887 else if (YesNoType.No == advertise)
@@ -7946,22 +7902,16 @@ namespace WixToolset.Core
7902 }
7903
7904 /// <summary>
7949 - /// Parses a patch creation element.
7905 + /// Parses a patch property element.
7906 /// </summary>
7907 /// <param name="node">The element to parse.</param>
7952 - private void ParsePatchCreationElement(XElement node)
7908 + /// <param name="patch">True if parsing an patch element.</param>
7909 + private void ParsePatchPropertyElement(XElement node, bool patch)
7910 {
7911 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;
7912 + string name = null;
7913 + string company = null;
7914 + string value = null;
7915
7916 foreach (var attrib in node.Attributes())
7917 {
@@ -7970,31 +7920,14 @@ namespace WixToolset.Core
7920 switch (attrib.Name.LocalName)
7921 {
7922 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);
7923 + case "Name":
7924 + name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7925 break;
7993 - case "SymbolFlags":
7994 - symbolFlags = String.Format(CultureInfo.InvariantCulture, "0x{0:x8}", this.Core.GetAttributeLongValue(sourceLineNumbers, attrib, 0, UInt32.MaxValue));
7926 + case "Company":
7927 + company = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7928 break;
7996 - case "WholeFilesOnly":
7997 - wholeFiles = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7929 + case "Value":
7930 + value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
7931 break;
7932 default:
7933 this.Core.UnexpectedAttribute(node, attrib);
@@ -8007,101 +7940,66 @@ namespace WixToolset.Core
7940 }
7941 }
7942
8010 - if (null == this.activeName)
7943 + if (null == name)
7944 {
8012 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
7945 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
7946 }
7947
8015 - this.Core.CreateActiveSection(this.activeName, SectionType.PatchCreation, codepage, this.Context.CompilationId);
8016 -
8017 - foreach (var child in node.Elements())
7948 + if (null == value)
7949 {
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 - }
7950 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
7951 }
7952
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 - }
7953 + this.Core.ParseForExtensionElements(node);
7954
8071 - if (0 < replaceGuids.Length)
7955 + if (patch)
7956 {
8073 - this.ProcessProperties(sourceLineNumbers, "ListOfPatchGUIDsToReplace", replaceGuids);
7957 + // /Patch/PatchProperty goes directly into MsiPatchMetadata table
7958 + this.Core.AddTuple(new MsiPatchMetadataTuple(sourceLineNumbers)
7959 + {
7960 + Company = company,
7961 + Property = name,
7962 + Value = value
7963 + });
7964 }
8075 -
8076 - if (0 < targetProducts.Length)
7965 + else
7966 {
8078 - this.ProcessProperties(sourceLineNumbers, "ListOfTargetProductCodes", targetProducts);
7967 + if (null != company)
7968 + {
7969 + this.Core.Write(ErrorMessages.UnexpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Company"));
7970 + }
7971 + this.AddPrivateProperty(sourceLineNumbers, name, value);
7972 }
7973 + }
7974
8081 - if (null != outputPath)
7975 + /// <summary>
7976 + /// Adds a row to the properties table.
7977 + /// </summary>
7978 + /// <param name="sourceLineNumbers">Source line numbers.</param>
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)
7982 + {
7983 + if (!this.Core.EncounteredError)
7984 {
8083 - this.ProcessProperties(sourceLineNumbers, "PatchOutputPath", outputPath);
8084 - }
7985 + var tuple = new PropertyTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, name))
7986 + {
7987 + Value = value
7988 + };
7989
8086 - if (null != sourceList)
8087 - {
8088 - this.ProcessProperties(sourceLineNumbers, "PatchSourceList", sourceList);
7990 + this.Core.AddTuple(tuple);
7991 }
7992 }
7993
7994 /// <summary>
8093 - /// Parses a family element.
7995 + /// Parses a TargetProductCode element.
7996 /// </summary>
7997 /// <param name="node">The element to parse.</param>
8096 - private void ParseFamilyElement(XElement node)
7998 + /// <returns>The id from the node.</returns>
7999 + private string ParseTargetProductCodeElement(XElement node)
8000 {
8001 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;
8002 + string id = null;
8003
8004 foreach (var attrib in node.Attributes())
8005 {
@@ -8109,23 +8007,12 @@ namespace WixToolset.Core
8007 {
8008 switch (attrib.Name.LocalName)
8009 {
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);
8010 + case "Id":
8011 + id = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8012 + if (id.Length > 0 && "*" != id)
8013 + {
8014 + id = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
8015 + }
8016 break;
8017 default:
8018 this.Core.UnexpectedAttribute(node, attrib);
@@ -8138,1045 +8025,47 @@ namespace WixToolset.Core
8025 }
8026 }
8027
8141 - if (null == name)
8142 - {
8143 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
8144 - }
8145 - else if (0 < name.Length)
8028 + if (null == id)
8029 {
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 - }
8030 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
8031 }
8032
8163 - foreach (var child in node.Elements())
8033 + this.Core.ParseForExtensionElements(node);
8034 +
8035 + return id;
8036 + }
8037 +
8038 + /// <summary>
8039 + /// Parses a ReplacePatch element.
8040 + /// </summary>
8041 + /// <param name="node">The element to parse.</param>
8042 + /// <returns>The id from the node.</returns>
8043 + private string ParseReplacePatchElement(XElement node)
8044 + {
8045 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
8046 + string id = null;
8047 +
8048 + foreach (var attrib in node.Attributes())
8049 {
8165 - if (CompilerCore.WixNamespace == child.Name.Namespace)
8050 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
8051 {
8167 - switch (child.Name.LocalName)
8052 + switch (attrib.Name.LocalName)
8053 {
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);
8054 + case "Id":
8055 + id = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
8056 break;
8057 default:
8179 - this.Core.UnexpectedElement(node, child);
8058 + this.Core.UnexpectedAttribute(node, attrib);
8059 break;
8060 }
8061 }
8062 else
8063 {
8185 - this.Core.ParseExtensionElement(node, child);
8064 + this.Core.ParseExtensionAttribute(node, attrib);
8065 }
8066 }
8067
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.
8879 - /// </summary>
8880 - /// <param name="node">The element to parse.</param>
8881 - /// <param name="patch">True if parsing an patch element.</param>
8882 - private void ParsePatchPropertyElement(XElement node, bool patch)
8883 - {
8884 - var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
8885 - string name = null;
8886 - string company = null;
8887 - string value = null;
8888 -
8889 - foreach (var attrib in node.Attributes())
8890 - {
8891 - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
8892 - {
8893 - switch (attrib.Name.LocalName)
8894 - {
8895 - case "Id":
8896 - case "Name":
8897 - name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8898 - break;
8899 - case "Company":
8900 - company = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8901 - break;
8902 - case "Value":
8903 - value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
8904 - break;
8905 - default:
8906 - this.Core.UnexpectedAttribute(node, attrib);
8907 - break;
8908 - }
8909 - }
8910 - else
8911 - {
8912 - this.Core.ParseExtensionAttribute(node, attrib);
8913 - }
8914 - }
8915 -
8916 - if (null == name)
8917 - {
8918 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
8919 - }
8920 -
8921 - if (null == value)
8922 - {
8923 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
8924 - }
8925 -
8926 - this.Core.ParseForExtensionElements(node);
8927 -
8928 - if (patch)
8929 - {
8930 - // /Patch/PatchProperty goes directly into MsiPatchMetadata table
8931 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiPatchMetadata);
8932 - row.Set(0, company);
8933 - row.Set(1, name);
8934 - row.Set(2, value);
8935 - }
8936 - else
8937 - {
8938 - if (null != company)
8939 - {
8940 - this.Core.Write(ErrorMessages.UnexpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Company"));
8941 - }
8942 - this.ProcessProperties(sourceLineNumbers, name, value);
8943 - }
8944 - }
8945 -
8946 - /// <summary>
8947 - /// Parses a patch sequence element.
8948 - /// </summary>
8949 - /// <param name="node">The element to parse.</param>
8950 - private void ParsePatchSequenceElement(XElement node)
8951 - {
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)
9018 - {
9019 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchSequence);
9020 - row.Set(0, family);
9021 - row.Set(1, target);
9022 - if (!String.IsNullOrEmpty(sequence))
9023 - {
9024 - row.Set(2, sequence);
9025 - }
9026 - row.Set(3, attributes);
9027 - }
9028 - }
9029 -
9030 - /// <summary>
9031 - /// Parses a TargetProductCode element.
9032 - /// </summary>
9033 - /// <param name="node">The element to parse.</param>
9034 - /// <returns>The id from the node.</returns>
9035 - private string ParseTargetProductCodeElement(XElement node)
9036 - {
9037 - var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
9038 - string id = null;
9039 -
9040 - foreach (var attrib in node.Attributes())
9041 - {
9042 - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
9043 - {
9044 - switch (attrib.Name.LocalName)
9045 - {
9046 - case "Id":
9047 - id = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
9048 - if (id.Length > 0 && "*" != id)
9049 - {
9050 - id = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
9051 - }
9052 - break;
9053 - default:
9054 - this.Core.UnexpectedAttribute(node, attrib);
9055 - break;
9056 - }
9057 - }
9058 - else
9059 - {
9060 - this.Core.ParseExtensionAttribute(node, attrib);
9061 - }
9062 - }
9063 -
9064 - if (null == id)
9065 - {
9066 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
9067 - }
9068 -
9069 - this.Core.ParseForExtensionElements(node);
9070 -
9071 - return id;
9072 - }
9073 -
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>
9150 - /// Parses a ReplacePatch element.
9151 - /// </summary>
9152 - /// <param name="node">The element to parse.</param>
9153 - /// <returns>The id from the node.</returns>
9154 - private string ParseReplacePatchElement(XElement node)
9155 - {
9156 - var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
9157 - string id = null;
9158 -
9159 - foreach (var attrib in node.Attributes())
9160 - {
9161 - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
9162 - {
9163 - switch (attrib.Name.LocalName)
9164 - {
9165 - case "Id":
9166 - id = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
9167 - break;
9168 - default:
9169 - this.Core.UnexpectedAttribute(node, attrib);
9170 - break;
9171 - }
9172 - }
9173 - else
9174 - {
9175 - this.Core.ParseExtensionAttribute(node, attrib);
9176 - }
9177 - }
9178 -
9179 - if (null == id)
8068 + if (null == id)
8069 {
8070 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
8071 }
@@ -9226,402 +8115,6 @@ namespace WixToolset.Core
8115 return path;
8116 }
8117
9229 - /// <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 -
8118 /// <summary>
8119 /// Parses the All element under a PatchFamily.
8120 /// </summary>
@@ -9650,7 +8143,13 @@ namespace WixToolset.Core
8143
8144 if (!this.Core.EncounteredError)
8145 {
9653 - this.Core.CreatePatchFamilyChildReference(sourceLineNumbers, "*", "*");
8146 + var tuple = new WixPatchRefTuple(sourceLineNumbers)
8147 + {
8148 + Table = "*",
8149 + PrimaryKeys = "*"
8150 + };
8151 +
8152 + this.Core.AddTuple(tuple);
8153 }
8154 }
8155
@@ -9693,7 +8192,13 @@ namespace WixToolset.Core
8192
8193 if (!this.Core.EncounteredError)
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);
8202 }
8203 }
8204
@@ -9770,9 +8275,13 @@ namespace WixToolset.Core
8275
8276 if (!this.Core.EncounteredError)
8277 {
9773 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchBaseline, id);
9774 - row.Set(1, diskId);
9775 - row.Set(2, (int)validationFlags);
8278 + var tuple = new WixPatchBaselineTuple(sourceLineNumbers, id)
8279 + {
8280 + DiskId = diskId,
8281 + ValidationFlags = validationFlags
8282 + };
8283 +
8284 + this.Core.AddTuple(tuple);
8285 }
8286 }
8287
@@ -9948,21 +8457,5 @@ namespace WixToolset.Core
8457 }
8458 }
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 - }
8460 }
8461 }
src/WixToolset.Core/CompilerCore.cs
+13 -137
@@ -17,7 +17,6 @@ namespace WixToolset.Core
17 using WixToolset.Extensibility;
18 using WixToolset.Extensibility.Data;
19 using WixToolset.Extensibility.Services;
20 - using Wix = WixToolset.Data.Serialize;
20
21 internal enum ValueListKind
22 {
@@ -50,9 +49,7 @@ namespace WixToolset.Core
49 private const string IllegalLongFilenameCharacters = @"[\\\?|><:/\*""]"; // illegal: \ ? | > < : / * "
50 private static readonly Regex IllegalLongFilename = new Regex(IllegalLongFilenameCharacters, RegexOptions.Compiled);
51
53 - public const int DefaultMaximumUncompressedMediaSize = 200; // Default value is 200 MB
54 - public const int MinValueOfMaxCabSizeForLargeFileSplitting = 20; // 20 MB
55 - public const int MaxValueOfMaxCabSizeForLargeFileSplitting = 2 * 1024; // 2048 MB (i.e. 2 GB)
52 + //public const int DefaultMaximumUncompressedMediaSize = 200; // Default value is 200 MB
53
54
55 // Built-in variables (from burn\engine\variable.cpp, "vrgBuiltInVariables", around line 113)
@@ -354,43 +351,20 @@ namespace WixToolset.Core
351 }
352
353 /// <summary>
357 - /// Creates a row in the active section.
354 + /// Creates a tuple in the active section.
355 /// </summary>
356 /// <param name="sourceLineNumbers">Source and line number of current row.</param>
360 - /// <param name="tupleType">Name of table to create row in.</param>
361 - /// <returns>New row.</returns>
362 - public IntermediateTuple CreateRow(SourceLineNumber sourceLineNumbers, TupleDefinitionType tupleType, Identifier identifier = null)
363 - {
364 - return this.CreateRow(sourceLineNumbers, tupleType, this.ActiveSection, identifier);
365 - }
366 -
367 - /// <summary>
368 - /// Creates a row in the active given <paramref name="section"/>.
369 - /// </summary>
370 - /// <param name="sourceLineNumbers">Source and line number of current row.</param>
371 - /// <param name="tupleType">Name of table to create row in.</param>
372 - /// <param name="section">The section to which the row is added. If null, the row is added to the active section.</param>
373 - /// <returns>New row.</returns>
374 - internal IntermediateTuple CreateRow(SourceLineNumber sourceLineNumbers, TupleDefinitionType tupleType, IntermediateSection section, Identifier identifier = null)
357 + /// <param name="tupleType">Type of tuple to create.</param>
358 + /// <param name="identifier">Optional identifier.</param>
359 + /// <returns>New tuple.</returns>
360 + public IntermediateTuple CreateTuple(SourceLineNumber sourceLineNumbers, TupleDefinitionType tupleType, Identifier identifier = null)
361 {
362 var tupleDefinition = TupleDefinitions.ByType(tupleType);
377 - var row = tupleDefinition.CreateTuple(sourceLineNumbers, identifier);
363 + var tuple = tupleDefinition.CreateTuple(sourceLineNumbers, identifier);
364
379 - if (null != identifier)
380 - {
381 - if (row.Definition.FieldDefinitions[0].Type == IntermediateFieldType.Number)
382 - {
383 - row.Set(0, Convert.ToInt32(identifier.Id));
384 - }
385 - else
386 - {
387 - row.Set(0, identifier.Id);
388 - }
389 - }
390 -
391 - section.Tuples.Add(row);
365 + this.ActiveSection.Tuples.Add(tuple);
366
393 - return row;
367 + return tuple;
368 }
369
370 /// <summary>
@@ -405,20 +379,6 @@ namespace WixToolset.Core
379 return this.parseHelper.CreateDirectoryReferenceFromInlineSyntax(this.ActiveSection, sourceLineNumbers, parentId, attribute, this.activeSectionInlinedDirectoryIds);
380 }
381
408 - /// <summary>
409 - /// Creates a patch resource reference to the list of resoures to be filtered when producing a patch. This method should only be used when processing children of a patch family.
410 - /// </summary>
411 - /// <param name="sourceLineNumbers">Source and line number of current row.</param>
412 - /// <param name="tableName">Name of table to create row in.</param>
413 - /// <param name="primaryKeys">Array of keys that make up the primary key of the table.</param>
414 - /// <returns>New row.</returns>
415 - public void CreatePatchFamilyChildReference(SourceLineNumber sourceLineNumbers, string tableName, params string[] primaryKeys)
416 - {
417 - var patchReferenceRow = this.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchRef);
418 - patchReferenceRow.Set(0, tableName);
419 - patchReferenceRow.Set(1, String.Join("/", primaryKeys));
420 - }
421 -
382 /// <summary>
383 /// Creates a Registry row in the active section.
384 /// </summary>
@@ -430,7 +390,7 @@ namespace WixToolset.Core
390 /// <param name="componentId">The component which will control installation/uninstallation of the registry entry.</param>
391 public Identifier CreateRegistryRow(SourceLineNumber sourceLineNumbers, RegistryRootType root, string key, string name, string value, string componentId)
392 {
433 - return this.parseHelper.CreateRegistryRow(this.ActiveSection, sourceLineNumbers, root, key, name, value, componentId, true);
393 + return this.parseHelper.CreateRegistryTuple(this.ActiveSection, sourceLineNumbers, root, key, name, value, componentId, true);
394 }
395
396 /// <summary>
@@ -466,7 +426,7 @@ namespace WixToolset.Core
426 {
427 if (!this.EncounteredError)
428 {
469 - this.parseHelper.CreateWixGroupRow(this.ActiveSection, sourceLineNumbers, parentType, parentId, childType, childId);
429 + this.parseHelper.CreateWixGroupTuple(this.ActiveSection, sourceLineNumbers, parentType, parentId, childType, childId);
430 }
431 }
432
@@ -752,39 +712,6 @@ namespace WixToolset.Core
712 return this.parseHelper.GetAttributeYesNoDefaultValue(sourceLineNumbers, attribute);
713 }
714
755 - /// <summary>
756 - /// Gets a yes/no/always value and displays an error for an illegal value.
757 - /// </summary>
758 - /// <param name="sourceLineNumbers">Source line information about the owner element.</param>
759 - /// <param name="attribute">The attribute containing the value to get.</param>
760 - /// <returns>The attribute's YesNoAlwaysType value.</returns>
761 - [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")]
762 - public YesNoAlwaysType GetAttributeYesNoAlwaysValue(SourceLineNumber sourceLineNumbers, XAttribute attribute)
763 - {
764 - string value = this.GetAttributeValue(sourceLineNumbers, attribute);
765 -
766 - if (0 < value.Length)
767 - {
768 - switch (Wix.Enums.ParseYesNoAlwaysType(value))
769 - {
770 - case Wix.YesNoAlwaysType.@always:
771 - return YesNoAlwaysType.Always;
772 - case Wix.YesNoAlwaysType.no:
773 - return YesNoAlwaysType.No;
774 - case Wix.YesNoAlwaysType.yes:
775 - return YesNoAlwaysType.Yes;
776 - case Wix.YesNoAlwaysType.NotSet:
777 - // Previous code never returned 'NotSet'!
778 - break;
779 - default:
780 - this.Write(ErrorMessages.IllegalYesNoAlwaysValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value));
781 - break;
782 - }
783 - }
784 -
785 - return YesNoAlwaysType.IllegalValue;
786 - }
787 -
715 /// <summary>
716 /// Gets a short filename value and displays an error for an illegal short filename value.
717 /// </summary>
@@ -854,57 +781,6 @@ namespace WixToolset.Core
781 return this.parseHelper.GetAttributeRegistryRootValue(sourceLineNumbers, attribute, allowHkmu);
782 }
783
857 - /// <summary>
858 - /// Gets an InstallUninstallType value and displays an error for an illegal value.
859 - /// </summary>
860 - /// <param name="sourceLineNumbers">Source line information about the owner element.</param>
861 - /// <param name="attribute">The attribute containing the value to get.</param>
862 - /// <returns>The attribute's InstallUninstallType value.</returns>
863 - [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")]
864 - public Wix.InstallUninstallType GetAttributeInstallUninstallValue(SourceLineNumber sourceLineNumbers, XAttribute attribute)
865 - {
866 - Wix.InstallUninstallType installUninstall = Wix.InstallUninstallType.NotSet;
867 - string value = this.GetAttributeValue(sourceLineNumbers, attribute);
868 -
869 - if (0 < value.Length)
870 - {
871 - installUninstall = Wix.Enums.ParseInstallUninstallType(value);
872 -
873 - if (Wix.InstallUninstallType.IllegalValue == installUninstall)
874 - {
875 - // TODO: Find a way to expose the valid values programatically!
876 - this.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value,
877 - "install", "uninstall", "both"));
878 - }
879 - }
880 -
881 - return installUninstall;
882 - }
883 -
884 - /// <summary>
885 - /// Gets an ExitType value and displays an error for an illegal value.
886 - /// </summary>
887 - /// <param name="sourceLineNumbers">Source line information about the owner element.</param>
888 - /// <param name="attribute">The attribute containing the value to get.</param>
889 - /// <returns>The attribute's ExitType value.</returns>
890 - [SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes")]
891 - public Wix.ExitType GetAttributeExitValue(SourceLineNumber sourceLineNumbers, XAttribute attribute)
892 - {
893 - string value = this.GetAttributeValue(sourceLineNumbers, attribute);
894 -
895 - Wix.ExitType result = Wix.ExitType.NotSet;
896 - if (!Enum.TryParse<Wix.ExitType>(value, out result))
897 - {
898 - result = Wix.ExitType.IllegalValue;
899 -
900 - // TODO: Find a way to expose the valid values programatically!
901 - this.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value,
902 - "success", "cancel", "error", "suspend"));
903 - }
904 -
905 - return result;
906 - }
907 -
784 /// <summary>
785 /// Gets a Bundle variable value and displays an error for an illegal value.
786 /// </summary>
@@ -1062,7 +938,7 @@ namespace WixToolset.Core
938 internal void VerifyRequiredVersion(SourceLineNumber sourceLineNumbers, string requiredVersion)
939 {
940 // an null or empty string means any version will work
1065 - if (!string.IsNullOrEmpty(requiredVersion))
941 + if (!String.IsNullOrEmpty(requiredVersion))
942 {
943 Assembly caller = Assembly.GetCallingAssembly();
944 AssemblyName name = caller.GetName();
@@ -1147,7 +1023,7 @@ namespace WixToolset.Core
1023 /// <returns>Identifier for the newly created row.</returns>
1024 internal Identifier CreateDirectoryRow(SourceLineNumber sourceLineNumbers, Identifier id, string parentId, string name, string shortName = null, string sourceName = null, string shortSourceName = null)
1025 {
1150 - return this.parseHelper.CreateDirectoryRow(this.ActiveSection, sourceLineNumbers, id, parentId, name, this.activeSectionInlinedDirectoryIds, shortName, sourceName, shortSourceName);
1026 + return this.parseHelper.CreateDirectoryTuple(this.ActiveSection, sourceLineNumbers, id, parentId, name, this.activeSectionInlinedDirectoryIds, shortName, sourceName, shortSourceName);
1027 }
1028
1029 /// <summary>
src/WixToolset.Core/Compiler_2.cs
+789 -1130
@@ -20,19 +20,21 @@ namespace WixToolset.Core
20 internal partial class Compiler : ICompiler
21 {
22 /// <summary>
23 - /// Parses an odbc driver or translator element.
23 + /// Parses a product element.
24 /// </summary>
25 /// <param name="node">Element to parse.</param>
26 - /// <param name="componentId">Identifier of parent component.</param>
27 - /// <param name="fileId">Default identifer for driver/translator file.</param>
28 - /// <param name="table">Table we're processing for.</param>
29 - private void ParseODBCDriverOrTranslator(XElement node, string componentId, string fileId, TupleDefinitionType tableName)
26 + private void ParseProductElement(XElement node)
27 {
28 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
32 - Identifier id = null;
33 - var driver = fileId;
34 - string name = null;
35 - var setup = fileId;
29 + var codepage = 65001;
30 + string productCode = "*";
31 + string upgradeCode = null;
32 + string manufacturer = null;
33 + string version = null;
34 + string symbols = null;
35 +
36 + this.activeName = null;
37 + this.activeLanguage = null;
38
39 foreach (var attrib in node.Attributes())
40 {
@@ -41,18 +43,37 @@ namespace WixToolset.Core
43 switch (attrib.Name.LocalName)
44 {
45 case "Id":
44 - id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
46 + productCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, true);
47 break;
46 - case "File":
47 - driver = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
48 - this.Core.CreateSimpleReference(sourceLineNumbers, "File", driver);
48 + case "Codepage":
49 + codepage = this.Core.GetAttributeCodePageValue(sourceLineNumbers, attrib);
50 + break;
51 + case "Language":
52 + this.activeLanguage = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, Int16.MaxValue);
53 + break;
54 + case "Manufacturer":
55 + manufacturer = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.MustHaveNonWhitespaceCharacters);
56 + if ("PUT-COMPANY-NAME-HERE" == manufacturer)
57 + {
58 + this.Core.Write(WarningMessages.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, manufacturer));
59 + }
60 break;
61 case "Name":
51 - name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
62 + this.activeName = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.MustHaveNonWhitespaceCharacters);
63 + if ("PUT-PRODUCT-NAME-HERE" == this.activeName)
64 + {
65 + this.Core.Write(WarningMessages.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, this.activeName));
66 + }
67 break;
53 - case "SetupFile":
54 - setup = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
55 - this.Core.CreateSimpleReference(sourceLineNumbers, "File", setup);
68 + case "UpgradeCode":
69 + upgradeCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
70 + break;
71 + case "Version": // if the attribute is valid version, use the attribute value as is (so "1.0000.01.01" would *not* get translated to "1.0.1.1").
72 + var verifiedVersion = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
73 + if (!String.IsNullOrEmpty(verifiedVersion))
74 + {
75 + version = attrib.Value;
76 + }
77 break;
78 default:
79 this.Core.UnexpectedAttribute(node, attrib);
@@ -65,32 +86,201 @@ namespace WixToolset.Core
86 }
87 }
88
68 - if (null == name)
89 + if (null == productCode)
90 + {
91 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
92 + }
93 +
94 + if (null == this.activeLanguage)
95 + {
96 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Language"));
97 + }
98 +
99 + if (null == manufacturer)
100 + {
101 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Manufacturer"));
102 + }
103 +
104 + if (null == this.activeName)
105 {
106 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
107 }
108
73 - if (null == id)
109 + if (null == upgradeCode)
110 {
75 - id = this.Core.CreateIdentifier("odb", name, fileId, setup);
111 + this.Core.Write(WarningMessages.MissingUpgradeCode(sourceLineNumbers));
112 }
113
78 - // drivers have a few possible children
79 - if (TupleDefinitionType.ODBCDriver == tableName)
114 + if (null == version)
115 {
81 - // process any data sources for the driver
116 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version"));
117 + }
118 + else if (!CompilerCore.IsValidProductVersion(version))
119 + {
120 + this.Core.Write(ErrorMessages.InvalidProductVersion(sourceLineNumbers, version));
121 + }
122 +
123 + if (this.Core.EncounteredError)
124 + {
125 + return;
126 + }
127 +
128 + try
129 + {
130 + this.compilingProduct = true;
131 + this.Core.CreateActiveSection(productCode, SectionType.Product, codepage, this.Context.CompilationId);
132 +
133 + this.AddProperty(sourceLineNumbers, new Identifier(AccessModifier.Public, "Manufacturer"), manufacturer, false, false, false, true);
134 + this.AddProperty(sourceLineNumbers, new Identifier(AccessModifier.Public, "ProductCode"), productCode, false, false, false, true);
135 + this.AddProperty(sourceLineNumbers, new Identifier(AccessModifier.Public, "ProductLanguage"), this.activeLanguage, false, false, false, true);
136 + this.AddProperty(sourceLineNumbers, new Identifier(AccessModifier.Public, "ProductName"), this.activeName, false, false, false, true);
137 + this.AddProperty(sourceLineNumbers, new Identifier(AccessModifier.Public, "ProductVersion"), version, false, false, false, true);
138 + if (null != upgradeCode)
139 + {
140 + this.AddProperty(sourceLineNumbers, new Identifier(AccessModifier.Public, "UpgradeCode"), upgradeCode, false, false, false, true);
141 + }
142 +
143 + var contextValues = new Dictionary<string, string>
144 + {
145 + ["ProductLanguage"] = this.activeLanguage,
146 + ["ProductVersion"] = version,
147 + ["UpgradeCode"] = upgradeCode
148 + };
149 +
150 + var featureDisplay = 0;
151 foreach (var child in node.Elements())
152 {
153 if (CompilerCore.WixNamespace == child.Name.Namespace)
154 {
155 switch (child.Name.LocalName)
156 {
88 - case "ODBCDataSource":
89 - string ignoredKeyPath = null;
90 - this.ParseODBCDataSource(child, componentId, name, out ignoredKeyPath);
157 + case "_locDefinition":
158 + break;
159 + case "AdminExecuteSequence":
160 + this.ParseSequenceElement(child, SequenceTable.AdminExecuteSequence);
161 + break;
162 + case "AdminUISequence":
163 + this.ParseSequenceElement(child, SequenceTable.AdminUISequence);
164 + break;
165 + case "AdvertiseExecuteSequence":
166 + this.ParseSequenceElement(child, SequenceTable.AdvertiseExecuteSequence);
167 + break;
168 + case "InstallExecuteSequence":
169 + this.ParseSequenceElement(child, SequenceTable.InstallExecuteSequence);
170 + break;
171 + case "InstallUISequence":
172 + this.ParseSequenceElement(child, SequenceTable.InstallUISequence);
173 + break;
174 + case "AppId":
175 + this.ParseAppIdElement(child, null, YesNoType.Yes, null, null, null);
176 + break;
177 + case "Binary":
178 + this.ParseBinaryElement(child);
179 + break;
180 + case "ComplianceCheck":
181 + this.ParseComplianceCheckElement(child);
182 + break;
183 + case "Component":
184 + this.ParseComponentElement(child, ComplexReferenceParentType.Unknown, null, null, CompilerConstants.IntegerNotSet, null, null);
185 + break;
186 + case "ComponentGroup":
187 + this.ParseComponentGroupElement(child, ComplexReferenceParentType.Unknown, null);
188 + break;
189 + case "Condition":
190 + this.ParseConditionElement(child, node.Name.LocalName, null, null);
191 + break;
192 + case "CustomAction":
193 + this.ParseCustomActionElement(child);
194 + break;
195 + case "CustomActionRef":
196 + this.ParseSimpleRefElement(child, "CustomAction");
197 + break;
198 + case "CustomTable":
199 + this.ParseCustomTableElement(child);
200 + break;
201 + case "Directory":
202 + this.ParseDirectoryElement(child, null, CompilerConstants.IntegerNotSet, String.Empty);
203 + break;
204 + case "DirectoryRef":
205 + this.ParseDirectoryRefElement(child);
206 + break;
207 + case "EmbeddedChainer":
208 + this.ParseEmbeddedChainerElement(child);
209 + break;
210 + case "EmbeddedChainerRef":
211 + this.ParseSimpleRefElement(child, "MsiEmbeddedChainer");
212 + break;
213 + case "EnsureTable":
214 + this.ParseEnsureTableElement(child);
215 + break;
216 + case "Feature":
217 + this.ParseFeatureElement(child, ComplexReferenceParentType.Product, productCode, ref featureDisplay);
218 + break;
219 + case "FeatureRef":
220 + this.ParseFeatureRefElement(child, ComplexReferenceParentType.Product, productCode);
221 + break;
222 + case "FeatureGroupRef":
223 + this.ParseFeatureGroupRefElement(child, ComplexReferenceParentType.Product, productCode);
224 + break;
225 + case "Icon":
226 + this.ParseIconElement(child);
227 + break;
228 + case "InstanceTransforms":
229 + this.ParseInstanceTransformsElement(child);
230 + break;
231 + case "MajorUpgrade":
232 + this.ParseMajorUpgradeElement(child, contextValues);
233 + break;
234 + case "Media":
235 + this.ParseMediaElement(child, null);
236 + break;
237 + case "MediaTemplate":
238 + this.ParseMediaTemplateElement(child, null);
239 + break;
240 + case "Package":
241 + this.ParsePackageElement(child, manufacturer, null);
242 + break;
243 + case "PackageCertificates":
244 + case "PatchCertificates":
245 + this.ParseCertificatesElement(child);
246 break;
247 case "Property":
93 - this.ParseODBCProperty(child, id.Id, TupleDefinitionType.ODBCAttribute);
248 + this.ParsePropertyElement(child);
249 + break;
250 + case "PropertyRef":
251 + this.ParseSimpleRefElement(child, "Property");
252 + break;
253 + case "SetDirectory":
254 + this.ParseSetDirectoryElement(child);
255 + break;
256 + case "SetProperty":
257 + this.ParseSetPropertyElement(child);
258 + break;
259 + case "SFPCatalog":
260 + string parentName = null;
261 + this.ParseSFPCatalogElement(child, ref parentName);
262 + break;
263 + case "SymbolPath":
264 + if (null != symbols)
265 + {
266 + symbols += ";" + this.ParseSymbolPathElement(child);
267 + }
268 + else
269 + {
270 + symbols = this.ParseSymbolPathElement(child);
271 + }
272 + break;
273 + case "UI":
274 + this.ParseUIElement(child);
275 + break;
276 + case "UIRef":
277 + this.ParseSimpleRefElement(child, "WixUI");
278 + break;
279 + case "Upgrade":
280 + this.ParseUpgradeElement(child);
281 + break;
282 + case "WixVariable":
283 + this.ParseWixVariableElement(child);
284 break;
285 default:
286 this.Core.UnexpectedElement(node, child);
@@ -102,35 +292,140 @@ namespace WixToolset.Core
292 this.Core.ParseExtensionElement(node, child);
293 }
294 }
105 - }
106 - else
107 - {
108 - this.Core.ParseForExtensionElements(node);
109 - }
295
111 - if (!this.Core.EncounteredError)
296 + if (!this.Core.EncounteredError)
297 + {
298 + if (null != symbols)
299 + {
300 + var tuple = new WixDeltaPatchSymbolPathsTuple(sourceLineNumbers)
301 + {
302 + SymbolId = productCode,
303 + SymbolType = SymbolPathType.Product,
304 + SymbolPaths = symbols
305 + };
306 +
307 + this.Core.AddTuple(tuple);
308 + }
309 + }
310 + }
311 + finally
312 {
113 - var row = this.Core.CreateRow(sourceLineNumbers, tableName, id);
114 - row.Set(1, componentId);
115 - row.Set(2, name);
116 - row.Set(3, driver);
117 - row.Set(4, setup);
313 + this.compilingProduct = false;
314 }
315 }
316
317 /// <summary>
122 - /// Parses a Property element underneath an ODBC driver or translator.
318 + /// Parses an odbc driver or translator element.
319 /// </summary>
320 /// <param name="node">Element to parse.</param>
125 - /// <param name="parentId">Identifier of parent driver or translator.</param>
126 - /// <param name="tableName">Name of the table to create property in.</param>
127 - private void ParseODBCProperty(XElement node, string parentId, TupleDefinitionType tableName)
321 + /// <param name="componentId">Identifier of parent component.</param>
322 + /// <param name="fileId">Default identifer for driver/translator file.</param>
323 + /// <param name="tupleDefinitionType">Tuple type we're processing for.</param>
324 + private void ParseODBCDriverOrTranslator(XElement node, string componentId, string fileId, TupleDefinitionType tupleDefinitionType)
325 {
326 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
130 - string id = null;
131 - string propertyValue = null;
132 -
133 - foreach (var attrib in node.Attributes())
327 + Identifier id = null;
328 + var driver = fileId;
329 + string name = null;
330 + var setup = fileId;
331 +
332 + foreach (var attrib in node.Attributes())
333 + {
334 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
335 + {
336 + switch (attrib.Name.LocalName)
337 + {
338 + case "Id":
339 + id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
340 + break;
341 + case "File":
342 + driver = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
343 + this.Core.CreateSimpleReference(sourceLineNumbers, "File", driver);
344 + break;
345 + case "Name":
346 + name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
347 + break;
348 + case "SetupFile":
349 + setup = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
350 + this.Core.CreateSimpleReference(sourceLineNumbers, "File", setup);
351 + break;
352 + default:
353 + this.Core.UnexpectedAttribute(node, attrib);
354 + break;
355 + }
356 + }
357 + else
358 + {
359 + this.Core.ParseExtensionAttribute(node, attrib);
360 + }
361 + }
362 +
363 + if (null == name)
364 + {
365 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
366 + }
367 +
368 + if (null == id)
369 + {
370 + id = this.Core.CreateIdentifier("odb", name, fileId, setup);
371 + }
372 +
373 + // drivers have a few possible children
374 + if (TupleDefinitionType.ODBCDriver == tupleDefinitionType)
375 + {
376 + // process any data sources for the driver
377 + foreach (var child in node.Elements())
378 + {
379 + if (CompilerCore.WixNamespace == child.Name.Namespace)
380 + {
381 + switch (child.Name.LocalName)
382 + {
383 + case "ODBCDataSource":
384 + string ignoredKeyPath = null;
385 + this.ParseODBCDataSource(child, componentId, name, out ignoredKeyPath);
386 + break;
387 + case "Property":
388 + this.ParseODBCProperty(child, id.Id, TupleDefinitionType.ODBCAttribute);
389 + break;
390 + default:
391 + this.Core.UnexpectedElement(node, child);
392 + break;
393 + }
394 + }
395 + else
396 + {
397 + this.Core.ParseExtensionElement(node, child);
398 + }
399 + }
400 + }
401 + else
402 + {
403 + this.Core.ParseForExtensionElements(node);
404 + }
405 +
406 + if (!this.Core.EncounteredError)
407 + {
408 + var tuple = this.Core.CreateTuple(sourceLineNumbers, tupleDefinitionType, id);
409 + tuple.Set(1, componentId);
410 + tuple.Set(2, name);
411 + tuple.Set(3, driver);
412 + tuple.Set(4, setup);
413 + }
414 + }
415 +
416 + /// <summary>
417 + /// Parses a Property element underneath an ODBC driver or translator.
418 + /// </summary>
419 + /// <param name="node">Element to parse.</param>
420 + /// <param name="parentId">Identifier of parent driver or translator.</param>
421 + /// <param name="tupleDefinitionType">Name of the table to create property in.</param>
422 + private void ParseODBCProperty(XElement node, string parentId, TupleDefinitionType tupleDefinitionType)
423 + {
424 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
425 + string id = null;
426 + string propertyValue = null;
427 +
428 + foreach (var attrib in node.Attributes())
429 {
430 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
431 {
@@ -162,10 +457,10 @@ namespace WixToolset.Core
457
458 if (!this.Core.EncounteredError)
459 {
165 - var row = this.Core.CreateRow(sourceLineNumbers, tableName);
166 - row.Set(0, parentId);
167 - row.Set(1, id);
168 - row.Set(2, propertyValue);
460 + var tuple = this.Core.CreateTuple(sourceLineNumbers, tupleDefinitionType, new Identifier(AccessModifier.Private, parentId, id));
461 + tuple.Set(0, parentId);
462 + tuple.Set(1, id);
463 + tuple.Set(2, propertyValue);
464 }
465 }
466
@@ -264,11 +559,13 @@ namespace WixToolset.Core
559
560 if (!this.Core.EncounteredError)
561 {
267 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ODBCDataSource, id);
268 - row.Set(1, componentId);
269 - row.Set(2, name);
270 - row.Set(3, driverName);
271 - row.Set(4, registration);
562 + this.Core.AddTuple(new ODBCDataSourceTuple(sourceLineNumbers, id)
563 + {
564 + Component_ = componentId,
565 + Description = name,
566 + DriverDescription = driverName,
567 + Registration = registration
568 + });
569 }
570
571 possibleKeyPath = id.Id;
@@ -296,7 +593,6 @@ namespace WixToolset.Core
593 string platformValue = null;
594 var security = YesNoDefaultType.Default;
595 var sourceBits = (this.compilingModule ? 2 : 0);
299 - IntermediateTuple row;
596 var installPrivilegeSeen = false;
597 var installScopeSeen = false;
598
@@ -333,7 +629,7 @@ namespace WixToolset.Core
629 case "AdminImage":
630 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
631 {
336 - sourceBits = sourceBits | 4;
632 + sourceBits |= 4;
633 }
634 break;
635 case "Comments":
@@ -348,7 +644,7 @@ namespace WixToolset.Core
644 }
645 else if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
646 {
351 - sourceBits = sourceBits | 2;
647 + sourceBits |= 2;
648 }
649 break;
650 case "Description":
@@ -363,7 +659,7 @@ namespace WixToolset.Core
659 installPrivilegeSeen = true;
660 break;
661 case "limited":
366 - sourceBits = sourceBits | 8;
662 + sourceBits |= 8;
663 installPrivilegeSeen = true;
664 break;
665 case "":
@@ -379,13 +675,15 @@ namespace WixToolset.Core
675 {
676 case "perMachine":
677 {
382 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Property, new Identifier("ALLUSERS", AccessModifier.Public));
383 - row.Set(1, "1");
678 + this.Core.AddTuple(new PropertyTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, "ALLUSERS"))
679 + {
680 + Value = "1"
681 + });
682 installScopeSeen = true;
683 }
684 break;
685 case "perUser":
388 - sourceBits = sourceBits | 8;
686 + sourceBits |= 8;
687 installScopeSeen = true;
688 break;
689 case "":
@@ -461,7 +759,7 @@ namespace WixToolset.Core
759 case "ShortNames":
760 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
761 {
464 - sourceBits = sourceBits | 1;
762 + sourceBits |= 1;
763 this.useShortFileNames = true;
764 }
765 break;
@@ -534,81 +832,88 @@ namespace WixToolset.Core
832
833 if (!this.Core.EncounteredError)
834 {
537 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
538 - row.Set(0, 1);
539 - row.Set(1, codepage);
835 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
836 + {
837 + PropertyId = SumaryInformationType.Codepage,
838 + Value = codepage
839 + });
840
541 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
542 - row.Set(0, 2);
543 - row.Set(1, "Installation Database");
841 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
842 + {
843 + PropertyId = SumaryInformationType.Title,
844 + Value = "Installation Database"
845 + });
846
545 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
546 - row.Set(0, 3);
547 - row.Set(1, packageName);
847 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
848 + {
849 + PropertyId = SumaryInformationType.Subject,
850 + Value = packageName
851 + });
852
549 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
550 - row.Set(0, 4);
551 - row.Set(1, packageAuthor);
853 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
854 + {
855 + PropertyId = SumaryInformationType.Author,
856 + Value = packageAuthor
857 + });
858
553 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
554 - row.Set(0, 5);
555 - row.Set(1, keywords);
859 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
860 + {
861 + PropertyId = SumaryInformationType.Keywords,
862 + Value = keywords
863 + });
864
557 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
558 - row.Set(0, 6);
559 - row.Set(1, comments);
865 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
866 + {
867 + PropertyId = SumaryInformationType.Comments,
868 + Value = comments
869 + });
870
561 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
562 - row.Set(0, 7);
563 - row.Set(1, String.Format(CultureInfo.InvariantCulture, "{0};{1}", platform, packageLanguages));
871 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
872 + {
873 + PropertyId = SumaryInformationType.PlatformAndLanguage,
874 + Value = String.Format(CultureInfo.InvariantCulture, "{0};{1}", platform, packageLanguages)
875 + });
876
565 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
566 - row.Set(0, 9);
567 - row.Set(1, packageCode);
877 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
878 + {
879 + PropertyId = SumaryInformationType.PackageCode,
880 + Value = packageCode
881 + });
882
569 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
570 - row.Set(0, 14);
571 - row.Set(1, msiVersion.ToString(CultureInfo.InvariantCulture));
883 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
884 + {
885 + PropertyId = SumaryInformationType.WindowsInstallerVersion,
886 + Value = msiVersion.ToString(CultureInfo.InvariantCulture)
887 + });
888
573 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
574 - row.Set(0, 15);
575 - row.Set(1, sourceBits.ToString(CultureInfo.InvariantCulture));
889 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
890 + {
891 + PropertyId = SumaryInformationType.WordCount,
892 + Value = sourceBits.ToString(CultureInfo.InvariantCulture)
893 + });
894
577 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
578 - row.Set(0, 19);
579 - switch (security)
895 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
896 {
581 - case YesNoDefaultType.No: // no restriction
582 - row.Set(1, "0");
583 - break;
584 - case YesNoDefaultType.Default: // read-only recommended
585 - row.Set(1, "2");
586 - break;
587 - case YesNoDefaultType.Yes: // read-only enforced
588 - row.Set(1, "4");
589 - break;
590 - }
897 + PropertyId = SumaryInformationType.Security,
898 + Value = YesNoDefaultType.No == security ? "0" : YesNoDefaultType.Yes == security ? "4" : "2"
899 + });
900 }
901 }
902
903 /// <summary>
595 - /// Parses a patch metadata element.
904 + /// Parses a patch information element.
905 /// </summary>
906 /// <param name="node">Element to parse.</param>
598 - private void ParsePatchMetadataElement(XElement node)
907 + private void ParsePatchInformationElement(XElement node)
908 {
909 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
601 - var allowRemoval = YesNoType.NotSet;
602 - string classification = null;
603 - string creationTimeUtc = null;
604 - string description = null;
605 - string displayName = null;
606 - string manufacturerName = null;
607 - string minorUpdateTargetRTM = null;
608 - string moreInfoUrl = null;
609 - var optimizeCA = CompilerConstants.IntegerNotSet;
610 - var optimizedInstallMode = YesNoType.NotSet;
611 - string targetProductName = null;
910 + var codepage = "1252";
911 + string comments = null;
912 + var keywords = "Installer,Patching,PCP,Database";
913 + var msiVersion = 1; // Should always be 1 for patches
914 + string packageAuthor = null;
915 + var packageName = this.activeName;
916 + var security = YesNoDefaultType.Default;
917
918 foreach (var attrib in node.Attributes())
919 {
@@ -616,35 +921,38 @@ namespace WixToolset.Core
921 {
922 switch (attrib.Name.LocalName)
923 {
619 - case "AllowRemoval":
620 - allowRemoval = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
924 + case "AdminImage":
925 + this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
926 break;
622 - case "Classification":
623 - classification = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
927 + case "Comments":
928 + comments = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
929 break;
625 - case "CreationTimeUTC":
626 - creationTimeUtc = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
930 + case "Compressed":
931 + this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
932 break;
933 case "Description":
629 - description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
934 + packageName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
935 break;
631 - case "DisplayName":
632 - displayName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
936 + case "Keywords":
937 + keywords = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
938 + break;
939 + case "Languages":
940 + this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
941 break;
634 - case "ManufacturerName":
635 - manufacturerName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
942 + case "Manufacturer":
943 + packageAuthor = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
944 break;
637 - case "MinorUpdateTargetRTM":
638 - minorUpdateTargetRTM = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
945 + case "Platforms":
946 + this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
947 break;
640 - case "MoreInfoURL":
641 - moreInfoUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
948 + case "ReadOnly":
949 + security = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib);
950 break;
643 - case "OptimizedInstallMode":
644 - optimizedInstallMode = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
951 + case "ShortNames":
952 + this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
953 break;
646 - case "TargetProductName":
647 - targetProductName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
954 + case "SummaryCodepage":
955 + codepage = this.Core.GetAttributeLocalizableCodePageValue(sourceLineNumbers, attrib);
956 break;
957 default:
958 this.Core.UnexpectedAttribute(node, attrib);
@@ -657,425 +965,114 @@ namespace WixToolset.Core
965 }
966 }
967
660 - if (YesNoType.NotSet == allowRemoval)
661 - {
662 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "AllowRemoval"));
663 - }
664 -
665 - if (null == classification)
666 - {
667 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Classification"));
668 - }
669 -
670 - if (null == description)
671 - {
672 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Description"));
673 - }
674 -
675 - if (null == displayName)
676 - {
677 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DisplayName"));
678 - }
679 -
680 - if (null == manufacturerName)
681 - {
682 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ManufacturerName"));
683 - }
684 -
685 - if (null == moreInfoUrl)
686 - {
687 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "MoreInfoURL"));
688 - }
689 -
690 - if (null == targetProductName)
691 - {
692 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "TargetProductName"));
693 - }
694 -
695 - foreach (var child in node.Elements())
696 - {
697 - if (CompilerCore.WixNamespace == child.Name.Namespace)
698 - {
699 - switch (child.Name.LocalName)
700 - {
701 - case "CustomProperty":
702 - this.ParseCustomPropertyElement(child);
703 - break;
704 - case "OptimizeCustomActions":
705 - optimizeCA = this.ParseOptimizeCustomActionsElement(child);
706 - break;
707 - default:
708 - this.Core.UnexpectedElement(node, child);
709 - break;
710 - }
711 - }
712 - else
713 - {
714 - this.Core.ParseExtensionElement(node, child);
715 - }
716 - }
968 + this.Core.ParseForExtensionElements(node);
969
970 if (!this.Core.EncounteredError)
971 {
720 - if (YesNoType.NotSet != allowRemoval)
972 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
973 {
722 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
723 - row.Set(1, "AllowRemoval");
724 - row.Set(2, YesNoType.Yes == allowRemoval ? "1" : "0");
725 - }
726 -
727 - if (null != classification)
728 - {
729 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
730 - row.Set(1, "Classification");
731 - row.Set(2, classification);
732 - }
974 + PropertyId = SumaryInformationType.Codepage,
975 + Value = codepage
976 + });
977
734 - if (null != creationTimeUtc)
978 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
979 {
736 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
737 - row.Set(1, "CreationTimeUTC");
738 - row.Set(2, creationTimeUtc);
739 - }
980 + PropertyId = SumaryInformationType.Title,
981 + Value = "Patch"
982 + });
983
741 - if (null != description)
984 + if (null != packageName)
985 {
743 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
744 - row.Set(1, "Description");
745 - row.Set(2, description);
986 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
987 + {
988 + PropertyId = SumaryInformationType.Subject,
989 + Value = packageName
990 + });
991 }
992
748 - if (null != displayName)
993 + if (null != packageAuthor)
994 {
750 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
751 - row.Set(1, "DisplayName");
752 - row.Set(2, displayName);
995 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
996 + {
997 + PropertyId = SumaryInformationType.Author,
998 + Value = packageAuthor
999 + });
1000 }
1001
755 - if (null != manufacturerName)
1002 + if (null != keywords)
1003 {
757 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
758 - row.Set(1, "ManufacturerName");
759 - row.Set(2, manufacturerName);
1004 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
1005 + {
1006 + PropertyId = SumaryInformationType.Keywords,
1007 + Value = keywords
1008 + });
1009 }
1010
762 - if (null != minorUpdateTargetRTM)
1011 + if (null != comments)
1012 {
764 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
765 - row.Set(1, "MinorUpdateTargetRTM");
766 - row.Set(2, minorUpdateTargetRTM);
1013 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
1014 + {
1015 + PropertyId = SumaryInformationType.Comments,
1016 + Value = comments
1017 + });
1018 }
1019
769 - if (null != moreInfoUrl)
1020 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
1021 {
771 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
772 - row.Set(1, "MoreInfoURL");
773 - row.Set(2, moreInfoUrl);
774 - }
1022 + PropertyId = SumaryInformationType.WindowsInstallerVersion,
1023 + Value = msiVersion.ToString(CultureInfo.InvariantCulture)
1024 + });
1025
776 - if (CompilerConstants.IntegerNotSet != optimizeCA)
1026 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
1027 {
778 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
779 - row.Set(1, "OptimizeCA");
780 - row.Set(2, optimizeCA.ToString(CultureInfo.InvariantCulture));
781 - }
1028 + PropertyId = SumaryInformationType.WordCount,
1029 + Value = "0"
1030 + });
1031
783 - if (YesNoType.NotSet != optimizedInstallMode)
1032 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
1033 {
785 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
786 - row.Set(1, "OptimizedInstallMode");
787 - row.Set(2, YesNoType.Yes == optimizedInstallMode ? "1" : "0");
788 - }
1034 + PropertyId = SumaryInformationType.WindowsInstallerVersion,
1035 + Value = msiVersion.ToString(CultureInfo.InvariantCulture)
1036 + });
1037
790 - if (null != targetProductName)
1038 + this.Core.AddTuple(new SummaryInformationTuple(sourceLineNumbers)
1039 {
792 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
793 - row.Set(1, "TargetProductName");
794 - row.Set(2, targetProductName);
795 - }
1040 + PropertyId = SumaryInformationType.Security,
1041 + Value = YesNoDefaultType.No == security ? "0" : YesNoDefaultType.Yes == security ? "4" : "2"
1042 + });
1043 }
1044 }
1045
1046 /// <summary>
800 - /// Parses a custom property element for the PatchMetadata table.
1047 + /// Parses a permission element.
1048 /// </summary>
1049 /// <param name="node">Element to parse.</param>
803 - private void ParseCustomPropertyElement(XElement node)
1050 + /// <param name="objectId">Identifier of object to be secured.</param>
1051 + /// <param name="tableName">Name of table that contains objectId.</param>
1052 + private void ParsePermissionElement(XElement node, string objectId, string tableName)
1053 {
1054 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
806 - string company = null;
807 - string property = null;
808 - string value = null;
809 -
810 - foreach (var attrib in node.Attributes())
811 - {
812 - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
813 - {
814 - switch (attrib.Name.LocalName)
815 - {
816 - case "Company":
817 - company = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
818 - break;
819 - case "Property":
820 - property = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
821 - break;
822 - case "Value":
823 - value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
824 - break;
825 - default:
826 - this.Core.UnexpectedAttribute(node, attrib);
827 - break;
828 - }
829 - }
830 - else
831 - {
832 - this.Core.ParseExtensionAttribute(node, attrib);
833 - }
834 - }
835 -
836 - if (null == company)
837 - {
838 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Company"));
839 - }
840 -
841 - if (null == property)
842 - {
843 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Property"));
844 - }
845 -
846 - if (null == value)
847 - {
848 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
849 - }
850 -
851 - this.Core.ParseForExtensionElements(node);
852 -
853 - if (!this.Core.EncounteredError)
854 - {
855 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.PatchMetadata);
856 - row.Set(0, company);
857 - row.Set(1, property);
858 - row.Set(2, value);
859 - }
860 - }
861 -
862 - /// <summary>
863 - /// Parses the OptimizeCustomActions element.
864 - /// </summary>
865 - /// <param name="node">Element to parse.</param>
866 - /// <returns>The combined integer value for callers to store as appropriate.</returns>
867 - private int ParseOptimizeCustomActionsElement(XElement node)
868 - {
869 - var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
870 - var optimizeCA = OptimizeCA.None;
871 -
872 - foreach (var attrib in node.Attributes())
873 - {
874 - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
875 - {
876 - switch (attrib.Name.LocalName)
877 - {
878 - case "SkipAssignment":
879 - if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
880 - {
881 - optimizeCA |= OptimizeCA.SkipAssignment;
882 - }
883 - break;
884 - case "SkipImmediate":
885 - if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
886 - {
887 - optimizeCA |= OptimizeCA.SkipImmediate;
888 - }
889 - break;
890 - case "SkipDeferred":
891 - if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
892 - {
893 - optimizeCA |= OptimizeCA.SkipDeferred;
894 - }
895 - break;
896 - default:
897 - this.Core.UnexpectedAttribute(node, attrib);
898 - break;
899 - }
900 - }
901 - else
902 - {
903 - this.Core.ParseExtensionAttribute(node, attrib);
904 - }
905 - }
906 -
907 - return (int)optimizeCA;
908 - }
909 -
910 - /// <summary>
911 - /// Parses a patch information element.
912 - /// </summary>
913 - /// <param name="node">Element to parse.</param>
914 - private void ParsePatchInformationElement(XElement node)
915 - {
916 - var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
917 - var codepage = "1252";
918 - string comments = null;
919 - var keywords = "Installer,Patching,PCP,Database";
920 - var msiVersion = 1; // Should always be 1 for patches
921 - string packageAuthor = null;
922 - var packageName = this.activeName;
923 - var security = YesNoDefaultType.Default;
924 -
925 - foreach (var attrib in node.Attributes())
926 - {
927 - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
928 - {
929 - switch (attrib.Name.LocalName)
930 - {
931 - case "AdminImage":
932 - this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
933 - break;
934 - case "Comments":
935 - comments = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
936 - break;
937 - case "Compressed":
938 - this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
939 - break;
940 - case "Description":
941 - packageName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
942 - break;
943 - case "Keywords":
944 - keywords = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
945 - break;
946 - case "Languages":
947 - this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
948 - break;
949 - case "Manufacturer":
950 - packageAuthor = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
951 - break;
952 - case "Platforms":
953 - this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
954 - break;
955 - case "ReadOnly":
956 - security = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib);
957 - break;
958 - case "ShortNames":
959 - this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
960 - break;
961 - case "SummaryCodepage":
962 - codepage = this.Core.GetAttributeLocalizableCodePageValue(sourceLineNumbers, attrib);
963 - break;
964 - default:
965 - this.Core.UnexpectedAttribute(node, attrib);
966 - break;
967 - }
968 - }
969 - else
970 - {
971 - this.Core.ParseExtensionAttribute(node, attrib);
972 - }
973 - }
974 -
975 - this.Core.ParseForExtensionElements(node);
976 -
977 - if (!this.Core.EncounteredError)
978 - {
979 - // PID_CODEPAGE
980 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
981 - row.Set(0, 1);
982 - row.Set(1, codepage);
983 -
984 - // PID_TITLE
985 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
986 - row.Set(0, 2);
987 - row.Set(1, "Patch");
988 -
989 - // PID_SUBJECT
990 - if (null != packageName)
991 - {
992 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
993 - row.Set(0, 3);
994 - row.Set(1, packageName);
995 - }
996 -
997 - // PID_AUTHOR
998 - if (null != packageAuthor)
999 - {
1000 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
1001 - row.Set(0, 4);
1002 - row.Set(1, packageAuthor);
1003 - }
1004 -
1005 - // PID_KEYWORDS
1006 - if (null != keywords)
1007 - {
1008 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
1009 - row.Set(0, 5);
1010 - row.Set(1, keywords);
1011 - }
1012 -
1013 - // PID_COMMENTS
1014 - if (null != comments)
1015 - {
1016 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
1017 - row.Set(0, 6);
1018 - row.Set(1, comments);
1019 - }
1020 -
1021 - // PID_PAGECOUNT
1022 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
1023 - row.Set(0, 14);
1024 - row.Set(1, msiVersion.ToString(CultureInfo.InvariantCulture));
1025 -
1026 - // PID_WORDCOUNT
1027 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
1028 - row.Set(0, 15);
1029 - row.Set(1, "0");
1030 -
1031 - // PID_SECURITY
1032 - row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType._SummaryInformation);
1033 - row.Set(0, 19);
1034 - switch (security)
1035 - {
1036 - case YesNoDefaultType.No: // no restriction
1037 - row.Set(1, "0");
1038 - break;
1039 - case YesNoDefaultType.Default: // read-only recommended
1040 - row.Set(1, "2");
1041 - break;
1042 - case YesNoDefaultType.Yes: // read-only enforced
1043 - row.Set(1, "4");
1044 - break;
1045 - }
1046 - }
1047 - }
1048 -
1049 - /// <summary>
1050 - /// Parses a permission element.
1051 - /// </summary>
1052 - /// <param name="node">Element to parse.</param>
1053 - /// <param name="objectId">Identifier of object to be secured.</param>
1054 - /// <param name="tableName">Name of table that contains objectId.</param>
1055 - private void ParsePermissionElement(XElement node, string objectId, string tableName)
1056 - {
1057 - var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1058 - var bits = new BitArray(32);
1059 - string domain = null;
1060 - var permission = 0;
1061 - string[] specialPermissions = null;
1062 - string user = null;
1063 -
1064 - switch (tableName)
1065 - {
1066 - case "CreateFolder":
1067 - specialPermissions = Common.FolderPermissions;
1068 - break;
1069 - case "File":
1070 - specialPermissions = Common.FilePermissions;
1071 - break;
1072 - case "Registry":
1073 - specialPermissions = Common.RegistryPermissions;
1074 - break;
1075 - default:
1076 - this.Core.UnexpectedElement(node.Parent, node);
1077 - return; // stop processing this element since no valid permissions are available
1078 - }
1055 + var bits = new BitArray(32);
1056 + string domain = null;
1057 + var permission = 0;
1058 + string[] specialPermissions = null;
1059 + string user = null;
1060 +
1061 + switch (tableName)
1062 + {
1063 + case "CreateFolder":
1064 + specialPermissions = Common.FolderPermissions;
1065 + break;
1066 + case "File":
1067 + specialPermissions = Common.FilePermissions;
1068 + break;
1069 + case "Registry":
1070 + specialPermissions = Common.RegistryPermissions;
1071 + break;
1072 + default:
1073 + this.Core.UnexpectedElement(node.Parent, node);
1074 + return; // stop processing this element since no valid permissions are available
1075 + }
1076
1077 foreach (var attrib in node.Attributes())
1078 {
@@ -1085,440 +1082,160 @@ namespace WixToolset.Core
1082 {
1083 case "Domain":
1084 domain = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1088 - break;
1089 - case "User":
1090 - user = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1091 - break;
1092 - case "FileAllRights":
1093 - // match the WinNT.h mask FILE_ALL_ACCESS for value 0x001F01FF (aka 1 1111 0000 0001 1111 1111 or 2032127)
1094 - bits[0] = bits[1] = bits[2] = bits[3] = bits[4] = bits[5] = bits[6] = bits[7] = bits[8] = bits[16] = bits[17] = bits[18] = bits[19] = bits[20] = true;
1095 - break;
1096 - case "SpecificRightsAll":
1097 - // match the WinNT.h mask SPECIFIC_RIGHTS_ALL for value 0x0000FFFF (aka 1111 1111 1111 1111)
1098 - bits[0] = bits[1] = bits[2] = bits[3] = bits[4] = bits[5] = bits[6] = bits[7] = bits[8] = bits[9] = bits[10] = bits[11] = bits[12] = bits[13] = bits[14] = bits[15] = true;
1099 - break;
1100 - default:
1101 - var attribValue = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
1102 - if (!this.Core.TrySetBitFromName(Common.StandardPermissions, attrib.Name.LocalName, attribValue, bits, 16))
1103 - {
1104 - if (!this.Core.TrySetBitFromName(Common.GenericPermissions, attrib.Name.LocalName, attribValue, bits, 28))
1105 - {
1106 - if (!this.Core.TrySetBitFromName(specialPermissions, attrib.Name.LocalName, attribValue, bits, 0))
1107 - {
1108 - this.Core.UnexpectedAttribute(node, attrib);
1109 - break;
1110 - }
1111 - }
1112 - }
1113 - break;
1114 - }
1115 - }
1116 - else
1117 - {
1118 - this.Core.ParseExtensionAttribute(node, attrib);
1119 - }
1120 - }
1121 -
1122 - permission = this.Core.CreateIntegerFromBitArray(bits);
1123 -
1124 - if (null == user)
1125 - {
1126 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "User"));
1127 - }
1128 -
1129 - if (Int32.MinValue == permission) // just GENERIC_READ, which is MSI_NULL
1130 - {
1131 - this.Core.Write(ErrorMessages.GenericReadNotAllowed(sourceLineNumbers));
1132 - }
1133 -
1134 - this.Core.ParseForExtensionElements(node);
1135 -
1136 - if (!this.Core.EncounteredError)
1137 - {
1138 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.LockPermissions);
1139 - row.Set(0, objectId);
1140 - row.Set(1, tableName);
1141 - row.Set(2, domain);
1142 - row.Set(3, user);
1143 - row.Set(4, permission);
1144 - }
1145 - }
1146 -
1147 - /// <summary>
1148 - /// Parses an extended permission element.
1149 - /// </summary>
1150 - /// <param name="node">Element to parse.</param>
1151 - /// <param name="objectId">Identifier of object to be secured.</param>
1152 - /// <param name="tableName">Name of table that contains objectId.</param>
1153 - private void ParsePermissionExElement(XElement node, string objectId, string tableName)
1154 - {
1155 - var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1156 - string condition = null;
1157 - Identifier id = null;
1158 - string sddl = null;
1159 -
1160 - switch (tableName)
1161 - {
1162 - case "CreateFolder":
1163 - case "File":
1164 - case "Registry":
1165 - case "ServiceInstall":
1166 - break;
1167 - default:
1168 - this.Core.UnexpectedElement(node.Parent, node);
1169 - return; // stop processing this element since nothing will be valid.
1170 - }
1171 -
1172 - foreach (var attrib in node.Attributes())
1173 - {
1174 - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
1175 - {
1176 - switch (attrib.Name.LocalName)
1177 - {
1178 - case "Id":
1179 - id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
1180 - break;
1181 - case "Sddl":
1182 - sddl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1183 - break;
1184 - default:
1185 - this.Core.UnexpectedAttribute(node, attrib);
1186 - break;
1187 - }
1188 - }
1189 - else
1190 - {
1191 - this.Core.ParseExtensionAttribute(node, attrib);
1192 - }
1193 - }
1194 -
1195 - if (null == sddl)
1196 - {
1197 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Sddl"));
1198 - }
1199 -
1200 - if (null == id)
1201 - {
1202 - id = this.Core.CreateIdentifier("pme", objectId, tableName, sddl);
1203 - }
1204 -
1205 - foreach (var child in node.Elements())
1206 - {
1207 - if (CompilerCore.WixNamespace == child.Name.Namespace)
1208 - {
1209 - switch (child.Name.LocalName)
1210 - {
1211 - case "Condition":
1212 - if (null != condition)
1213 - {
1214 - var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1215 - this.Core.Write(ErrorMessages.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, child.Name.LocalName));
1216 - }
1217 -
1218 - condition = this.ParseConditionElement(child, node.Name.LocalName, null, null);
1219 - break;
1220 - default:
1221 - this.Core.UnexpectedElement(node, child);
1222 - break;
1223 - }
1224 - }
1225 - else
1226 - {
1227 - this.Core.ParseExtensionElement(node, child);
1228 - }
1229 - }
1230 -
1231 - if (!this.Core.EncounteredError)
1232 - {
1233 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiLockPermissionsEx, id);
1234 - row.Set(1, objectId);
1235 - row.Set(2, tableName);
1236 - row.Set(3, sddl);
1237 - row.Set(4, condition);
1238 - }
1239 - }
1240 -
1241 - /// <summary>
1242 - /// Parses a product element.
1243 - /// </summary>
1244 - /// <param name="node">Element to parse.</param>
1245 - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
1246 - private void ParseProductElement(XElement node)
1247 - {
1248 - var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1249 - var codepage = 65001;
1250 - string productCode = "*";
1251 - string upgradeCode = null;
1252 - string manufacturer = null;
1253 - string version = null;
1254 - string symbols = null;
1255 -
1256 - this.activeName = null;
1257 - this.activeLanguage = null;
1258 -
1259 - foreach (var attrib in node.Attributes())
1260 - {
1261 - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
1262 - {
1263 - switch (attrib.Name.LocalName)
1264 - {
1265 - case "Id":
1266 - productCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, true);
1267 - break;
1268 - case "Codepage":
1269 - codepage = this.Core.GetAttributeCodePageValue(sourceLineNumbers, attrib);
1270 - break;
1271 - case "Language":
1272 - this.activeLanguage = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, Int16.MaxValue);
1273 - break;
1274 - case "Manufacturer":
1275 - manufacturer = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.MustHaveNonWhitespaceCharacters);
1276 - if ("PUT-COMPANY-NAME-HERE" == manufacturer)
1277 - {
1278 - this.Core.Write(WarningMessages.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, manufacturer));
1279 - }
1280 - break;
1281 - case "Name":
1282 - this.activeName = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.MustHaveNonWhitespaceCharacters);
1283 - if ("PUT-PRODUCT-NAME-HERE" == this.activeName)
1284 - {
1285 - this.Core.Write(WarningMessages.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, this.activeName));
1286 - }
1287 - break;
1288 - case "UpgradeCode":
1289 - upgradeCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
1290 - break;
1291 - case "Version": // if the attribute is valid version, use the attribute value as is (so "1.0000.01.01" would *not* get translated to "1.0.1.1").
1292 - var verifiedVersion = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
1293 - if (!String.IsNullOrEmpty(verifiedVersion))
1294 - {
1295 - version = attrib.Value;
1296 - }
1297 - break;
1298 - default:
1299 - this.Core.UnexpectedAttribute(node, attrib);
1300 - break;
1301 - }
1302 - }
1303 - else
1304 - {
1305 - this.Core.ParseExtensionAttribute(node, attrib);
1306 - }
1307 - }
1308 -
1309 - if (null == productCode)
1310 - {
1311 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
1312 - }
1313 -
1314 - if (null == this.activeLanguage)
1315 - {
1316 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Language"));
1317 - }
1318 -
1319 - if (null == manufacturer)
1320 - {
1321 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Manufacturer"));
1322 - }
1323 -
1324 - if (null == this.activeName)
1325 - {
1326 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
1327 - }
1328 -
1329 - if (null == upgradeCode)
1330 - {
1331 - this.Core.Write(WarningMessages.MissingUpgradeCode(sourceLineNumbers));
1332 - }
1333 -
1334 - if (null == version)
1335 - {
1336 - this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version"));
1337 - }
1338 - else if (!CompilerCore.IsValidProductVersion(version))
1339 - {
1340 - this.Core.Write(ErrorMessages.InvalidProductVersion(sourceLineNumbers, version));
1341 - }
1342 -
1343 - if (this.Core.EncounteredError)
1344 - {
1345 - return;
1346 - }
1347 -
1348 - try
1349 - {
1350 - this.compilingProduct = true;
1351 - this.Core.CreateActiveSection(productCode, SectionType.Product, codepage, this.Context.CompilationId);
1352 -
1353 - this.AddProperty(sourceLineNumbers, new Identifier("Manufacturer", AccessModifier.Public), manufacturer, false, false, false, true);
1354 - this.AddProperty(sourceLineNumbers, new Identifier("ProductCode", AccessModifier.Public), productCode, false, false, false, true);
1355 - this.AddProperty(sourceLineNumbers, new Identifier("ProductLanguage", AccessModifier.Public), this.activeLanguage, false, false, false, true);
1356 - this.AddProperty(sourceLineNumbers, new Identifier("ProductName", AccessModifier.Public), this.activeName, false, false, false, true);
1357 - this.AddProperty(sourceLineNumbers, new Identifier("ProductVersion", AccessModifier.Public), version, false, false, false, true);
1358 - if (null != upgradeCode)
1359 - {
1360 - this.AddProperty(sourceLineNumbers, new Identifier("UpgradeCode", AccessModifier.Public), upgradeCode, false, false, false, true);
1361 - }
1362 -
1363 - var contextValues = new Dictionary<string, string>
1364 - {
1365 - ["ProductLanguage"] = this.activeLanguage,
1366 - ["ProductVersion"] = version,
1367 - ["UpgradeCode"] = upgradeCode
1368 - };
1369 -
1370 - var featureDisplay = 0;
1371 - foreach (var child in node.Elements())
1372 - {
1373 - if (CompilerCore.WixNamespace == child.Name.Namespace)
1374 - {
1375 - switch (child.Name.LocalName)
1376 - {
1377 - case "_locDefinition":
1378 - break;
1379 - case "AdminExecuteSequence":
1380 - case "AdminUISequence":
1381 - case "AdvertiseExecuteSequence":
1382 - case "InstallExecuteSequence":
1383 - case "InstallUISequence":
1384 - this.ParseSequenceElement(child, child.Name.LocalName);
1385 - break;
1386 - case "AppId":
1387 - this.ParseAppIdElement(child, null, YesNoType.Yes, null, null, null);
1388 - break;
1389 - case "Binary":
1390 - this.ParseBinaryElement(child);
1391 - break;
1392 - case "ComplianceCheck":
1393 - this.ParseComplianceCheckElement(child);
1394 - break;
1395 - case "Component":
1396 - this.ParseComponentElement(child, ComplexReferenceParentType.Unknown, null, null, CompilerConstants.IntegerNotSet, null, null);
1397 - break;
1398 - case "ComponentGroup":
1399 - this.ParseComponentGroupElement(child, ComplexReferenceParentType.Unknown, null);
1400 - break;
1401 - case "Condition":
1402 - this.ParseConditionElement(child, node.Name.LocalName, null, null);
1403 - break;
1404 - case "CustomAction":
1405 - this.ParseCustomActionElement(child);
1406 - break;
1407 - case "CustomActionRef":
1408 - this.ParseSimpleRefElement(child, "CustomAction");
1409 - break;
1410 - case "CustomTable":
1411 - this.ParseCustomTableElement(child);
1412 - break;
1413 - case "Directory":
1414 - this.ParseDirectoryElement(child, null, CompilerConstants.IntegerNotSet, String.Empty);
1415 - break;
1416 - case "DirectoryRef":
1417 - this.ParseDirectoryRefElement(child);
1418 - break;
1419 - case "EmbeddedChainer":
1420 - this.ParseEmbeddedChainerElement(child);
1421 - break;
1422 - case "EmbeddedChainerRef":
1423 - this.ParseSimpleRefElement(child, "MsiEmbeddedChainer");
1424 - break;
1425 - case "EnsureTable":
1426 - this.ParseEnsureTableElement(child);
1427 - break;
1428 - case "Feature":
1429 - this.ParseFeatureElement(child, ComplexReferenceParentType.Product, productCode, ref featureDisplay);
1430 - break;
1431 - case "FeatureRef":
1432 - this.ParseFeatureRefElement(child, ComplexReferenceParentType.Product, productCode);
1433 - break;
1434 - case "FeatureGroupRef":
1435 - this.ParseFeatureGroupRefElement(child, ComplexReferenceParentType.Product, productCode);
1436 - break;
1437 - case "Icon":
1438 - this.ParseIconElement(child);
1439 - break;
1440 - case "InstanceTransforms":
1441 - this.ParseInstanceTransformsElement(child);
1442 - break;
1443 - case "MajorUpgrade":
1444 - this.ParseMajorUpgradeElement(child, contextValues);
1445 - break;
1446 - case "Media":
1447 - this.ParseMediaElement(child, null);
1448 - break;
1449 - case "MediaTemplate":
1450 - this.ParseMediaTemplateElement(child, null);
1451 - break;
1452 - case "Package":
1453 - this.ParsePackageElement(child, manufacturer, null);
1454 - break;
1455 - case "PackageCertificates":
1456 - case "PatchCertificates":
1457 - this.ParseCertificatesElement(child);
1458 - break;
1459 - case "Property":
1460 - this.ParsePropertyElement(child);
1461 - break;
1462 - case "PropertyRef":
1463 - this.ParseSimpleRefElement(child, "Property");
1464 - break;
1465 - case "SetDirectory":
1466 - this.ParseSetDirectoryElement(child);
1467 - break;
1468 - case "SetProperty":
1469 - this.ParseSetPropertyElement(child);
1470 - break;
1471 - case "SFPCatalog":
1472 - string parentName = null;
1473 - this.ParseSFPCatalogElement(child, ref parentName);
1474 - break;
1475 - case "SymbolPath":
1476 - if (null != symbols)
1477 - {
1478 - symbols += ";" + this.ParseSymbolPathElement(child);
1479 - }
1480 - else
1085 + break;
1086 + case "User":
1087 + user = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1088 + break;
1089 + case "FileAllRights":
1090 + // match the WinNT.h mask FILE_ALL_ACCESS for value 0x001F01FF (aka 1 1111 0000 0001 1111 1111 or 2032127)
1091 + bits[0] = bits[1] = bits[2] = bits[3] = bits[4] = bits[5] = bits[6] = bits[7] = bits[8] = bits[16] = bits[17] = bits[18] = bits[19] = bits[20] = true;
1092 + break;
1093 + case "SpecificRightsAll":
1094 + // match the WinNT.h mask SPECIFIC_RIGHTS_ALL for value 0x0000FFFF (aka 1111 1111 1111 1111)
1095 + bits[0] = bits[1] = bits[2] = bits[3] = bits[4] = bits[5] = bits[6] = bits[7] = bits[8] = bits[9] = bits[10] = bits[11] = bits[12] = bits[13] = bits[14] = bits[15] = true;
1096 + break;
1097 + default:
1098 + var attribValue = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
1099 + if (!this.Core.TrySetBitFromName(Common.StandardPermissions, attrib.Name.LocalName, attribValue, bits, 16))
1100 + {
1101 + if (!this.Core.TrySetBitFromName(Common.GenericPermissions, attrib.Name.LocalName, attribValue, bits, 28))
1102 {
1482 - symbols = this.ParseSymbolPathElement(child);
1103 + if (!this.Core.TrySetBitFromName(specialPermissions, attrib.Name.LocalName, attribValue, bits, 0))
1104 + {
1105 + this.Core.UnexpectedAttribute(node, attrib);
1106 + break;
1107 + }
1108 }
1484 - break;
1485 - case "UI":
1486 - this.ParseUIElement(child);
1487 - break;
1488 - case "UIRef":
1489 - this.ParseSimpleRefElement(child, "WixUI");
1490 - break;
1491 - case "Upgrade":
1492 - this.ParseUpgradeElement(child);
1493 - break;
1494 - case "WixVariable":
1495 - this.ParseWixVariableElement(child);
1496 - break;
1497 - default:
1498 - this.Core.UnexpectedElement(node, child);
1499 - break;
1109 }
1110 + break;
1111 }
1502 - else
1112 + }
1113 + else
1114 + {
1115 + this.Core.ParseExtensionAttribute(node, attrib);
1116 + }
1117 + }
1118 +
1119 + permission = this.Core.CreateIntegerFromBitArray(bits);
1120 +
1121 + if (null == user)
1122 + {
1123 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "User"));
1124 + }
1125 +
1126 + if (Int32.MinValue == permission) // just GENERIC_READ, which is MSI_NULL
1127 + {
1128 + this.Core.Write(ErrorMessages.GenericReadNotAllowed(sourceLineNumbers));
1129 + }
1130 +
1131 + this.Core.ParseForExtensionElements(node);
1132 +
1133 + if (!this.Core.EncounteredError)
1134 + {
1135 + this.Core.AddTuple(new LockPermissionsTuple(sourceLineNumbers)
1136 + {
1137 + LockObject = objectId,
1138 + Table = tableName,
1139 + Domain = domain,
1140 + User = user,
1141 + Permission = permission
1142 + });
1143 + }
1144 + }
1145 +
1146 + /// <summary>
1147 + /// Parses an extended permission element.
1148 + /// </summary>
1149 + /// <param name="node">Element to parse.</param>
1150 + /// <param name="objectId">Identifier of object to be secured.</param>
1151 + /// <param name="tableName">Name of table that contains objectId.</param>
1152 + private void ParsePermissionExElement(XElement node, string objectId, string tableName)
1153 + {
1154 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1155 + string condition = null;
1156 + Identifier id = null;
1157 + string sddl = null;
1158 +
1159 + switch (tableName)
1160 + {
1161 + case "CreateFolder":
1162 + case "File":
1163 + case "Registry":
1164 + case "ServiceInstall":
1165 + break;
1166 + default:
1167 + this.Core.UnexpectedElement(node.Parent, node);
1168 + return; // stop processing this element since nothing will be valid.
1169 + }
1170 +
1171 + foreach (var attrib in node.Attributes())
1172 + {
1173 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
1174 + {
1175 + switch (attrib.Name.LocalName)
1176 {
1504 - this.Core.ParseExtensionElement(node, child);
1177 + case "Id":
1178 + id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
1179 + break;
1180 + case "Sddl":
1181 + sddl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1182 + break;
1183 + default:
1184 + this.Core.UnexpectedAttribute(node, attrib);
1185 + break;
1186 }
1187 }
1188 + else
1189 + {
1190 + this.Core.ParseExtensionAttribute(node, attrib);
1191 + }
1192 + }
1193
1508 - if (!this.Core.EncounteredError)
1194 + if (null == sddl)
1195 + {
1196 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Sddl"));
1197 + }
1198 +
1199 + if (null == id)
1200 + {
1201 + id = this.Core.CreateIdentifier("pme", objectId, tableName, sddl);
1202 + }
1203 +
1204 + foreach (var child in node.Elements())
1205 + {
1206 + if (CompilerCore.WixNamespace == child.Name.Namespace)
1207 {
1510 - if (null != symbols)
1208 + switch (child.Name.LocalName)
1209 {
1512 - var symbolRow = (WixDeltaPatchSymbolPathsTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixDeltaPatchSymbolPaths);
1513 - symbolRow.Id = productCode;
1514 - symbolRow.Type = SymbolPathType.Product;
1515 - symbolRow.SymbolPaths = symbols;
1210 + case "Condition":
1211 + if (null != condition)
1212 + {
1213 + var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1214 + this.Core.Write(ErrorMessages.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, child.Name.LocalName));
1215 + }
1216 +
1217 + condition = this.ParseConditionElement(child, node.Name.LocalName, null, null);
1218 + break;
1219 + default:
1220 + this.Core.UnexpectedElement(node, child);
1221 + break;
1222 }
1223 }
1224 + else
1225 + {
1226 + this.Core.ParseExtensionElement(node, child);
1227 + }
1228 }
1519 - finally
1229 +
1230 + if (!this.Core.EncounteredError)
1231 {
1521 - this.compilingProduct = false;
1232 + this.Core.AddTuple(new MsiLockPermissionsExTuple(sourceLineNumbers, id)
1233 + {
1234 + LockObject = objectId,
1235 + Table = tableName,
1236 + SDDLText =sddl,
1237 + Condition = condition
1238 + });
1239 }
1240 }
1241
@@ -1644,22 +1361,27 @@ namespace WixToolset.Core
1361 {
1362 if (!this.Core.EncounteredError)
1363 {
1647 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ProgId);
1648 - row.Set(0, progId);
1649 - row.Set(1, parent);
1650 - row.Set(2, classId);
1651 - row.Set(3, description);
1364 + var tuple = new ProgIdTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, progId))
1365 + {
1366 + ProgId = progId,
1367 + ProgId_Parent = parent,
1368 + Class_ = classId,
1369 + Description = description,
1370 + };
1371 +
1372 if (null != icon)
1373 {
1654 - row.Set(4, icon);
1374 + tuple.Icon_ = icon;
1375 this.Core.CreateSimpleReference(sourceLineNumbers, "Icon", icon);
1376 }
1377
1378 if (CompilerConstants.IntegerNotSet != iconIndex)
1379 {
1660 - row.Set(5, iconIndex);
1380 + tuple.IconIndex = iconIndex;
1381 }
1382
1383 + this.Core.AddTuple(tuple);
1384 +
1385 this.Core.EnsureTable(sourceLineNumbers, "Class");
1386 }
1387 }
@@ -1834,7 +1556,7 @@ namespace WixToolset.Core
1556 {
1557 if (complianceCheck && !this.Core.EncounteredError)
1558 {
1837 - this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.CCPSearch, new Identifier(sig, AccessModifier.Private));
1559 + this.Core.AddTuple(new CCPSearchTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, sig)));
1560 }
1561
1562 this.AddAppSearch(sourceLineNumbers, id, sig);
@@ -1863,7 +1585,7 @@ namespace WixToolset.Core
1585 {
1586 this.Core.Write(WarningMessages.PropertyModularizationSuppressed(sourceLineNumbers));
1587
1866 - this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixSuppressModularization, id);
1588 + this.Core.AddTuple(new WixSuppressModularizationTuple(sourceLineNumbers, id));
1589 }
1590 }
1591
@@ -2521,7 +2243,8 @@ namespace WixToolset.Core
2243 Identifier id = null;
2244 string directory = null;
2245 string name = null;
2524 - var on = CompilerConstants.IntegerNotSet;
2246 + bool? onInstall = null;
2247 + bool? onUninstall = null;
2248 string property = null;
2249 string shortName = null;
2250
@@ -2545,16 +2268,14 @@ namespace WixToolset.Core
2268 switch (onValue)
2269 {
2270 case "install":
2548 - on = 1;
2271 + onInstall = true;
2272 break;
2273 case "uninstall":
2551 - on = 2;
2274 + onUninstall = true;
2275 break;
2276 case "both":
2554 - on = 3;
2555 - break;
2556 - default:
2557 - on = CompilerConstants.IllegalInteger;
2277 + onInstall = true;
2278 + onUninstall = true;
2279 break;
2280 }
2281 break;
@@ -2599,10 +2320,9 @@ namespace WixToolset.Core
2320 }
2321 }
2322
2602 - if (CompilerConstants.IntegerNotSet == on)
2323 + if (!onInstall.HasValue && !onUninstall.HasValue)
2324 {
2325 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "On"));
2605 - on = CompilerConstants.IllegalInteger;
2326 }
2327
2328 if (null != directory && null != property)
@@ -2612,6 +2332,7 @@ namespace WixToolset.Core
2332
2333 if (null == id)
2334 {
2335 + var on = (onInstall == true && onUninstall == true) ? 3 : (onUninstall == true) ? 2 : (onInstall == true) ? 1 : 0;
2336 id = this.Core.CreateIdentifier("rmf", directory ?? property ?? parentDirectory, LowercaseOrNull(shortName), LowercaseOrNull(name), on.ToString());
2337 }
2338
@@ -2619,22 +2340,16 @@ namespace WixToolset.Core
2340
2341 if (!this.Core.EncounteredError)
2342 {
2622 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.RemoveFile, id);
2623 - row.Set(1, componentId);
2624 - row.Set(2, this.GetMsiFilenameValue(shortName, name));
2625 - if (null != directory)
2626 - {
2627 - row.Set(3, directory);
2628 - }
2629 - else if (null != property)
2630 - {
2631 - row.Set(3, property);
2632 - }
2633 - else
2343 + var tuple = new RemoveFileTuple(sourceLineNumbers, id)
2344 {
2635 - row.Set(3, parentDirectory);
2636 - }
2637 - row.Set(4, on);
2345 + Component_ = componentId,
2346 + FileName = this.GetMsiFilenameValue(shortName, name),
2347 + DirProperty = directory ?? property ?? parentDirectory,
2348 + OnInstall = onInstall,
2349 + OnUninstall = onUninstall
2350 + };
2351 +
2352 + this.Core.AddTuple(tuple);
2353 }
2354 }
2355
@@ -2649,7 +2364,8 @@ namespace WixToolset.Core
2364 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
2365 Identifier id = null;
2366 string directory = null;
2652 - var on = CompilerConstants.IntegerNotSet;
2367 + bool? onInstall = null;
2368 + bool? onUninstall = null;
2369 string property = null;
2370
2371 foreach (var attrib in node.Attributes())
@@ -2669,16 +2385,14 @@ namespace WixToolset.Core
2385 switch (onValue)
2386 {
2387 case "install":
2672 - on = 1;
2388 + onInstall = true;
2389 break;
2390 case "uninstall":
2675 - on = 2;
2391 + onUninstall = true;
2392 break;
2393 case "both":
2678 - on = 3;
2679 - break;
2680 - default:
2681 - on = CompilerConstants.IllegalInteger;
2394 + onInstall = true;
2395 + onUninstall = true;
2396 break;
2397 }
2398 break;
@@ -2696,10 +2410,9 @@ namespace WixToolset.Core
2410 }
2411 }
2412
2699 - if (CompilerConstants.IntegerNotSet == on)
2413 + if (!onInstall.HasValue && !onUninstall.HasValue)
2414 {
2415 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "On"));
2702 - on = CompilerConstants.IllegalInteger;
2416 }
2417
2418 if (null != directory && null != property)
@@ -2709,6 +2422,7 @@ namespace WixToolset.Core
2422
2423 if (null == id)
2424 {
2425 + var on = (onInstall == true && onUninstall == true) ? 3 : (onUninstall == true) ? 2 : (onInstall == true) ? 1 : 0;
2426 id = this.Core.CreateIdentifier("rmf", directory ?? property ?? parentDirectory, on.ToString());
2427 }
2428
@@ -2716,22 +2430,15 @@ namespace WixToolset.Core
2430
2431 if (!this.Core.EncounteredError)
2432 {
2719 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.RemoveFile, id);
2720 - row.Set(1, componentId);
2721 - //row.Set(2, null);
2722 - if (null != directory)
2723 - {
2724 - row.Set(3, directory);
2725 - }
2726 - else if (null != property)
2727 - {
2728 - row.Set(3, property);
2729 - }
2730 - else
2433 + var tuple = new RemoveFileTuple(sourceLineNumbers, id)
2434 {
2732 - row.Set(3, parentDirectory);
2733 - }
2734 - row.Set(4, on);
2435 + Component_ = componentId,
2436 + DirProperty = directory ?? property ?? parentDirectory,
2437 + OnInstall = onInstall,
2438 + OnUninstall = onUninstall
2439 + };
2440 +
2441 + this.Core.AddTuple(tuple);
2442 }
2443 }
2444
@@ -2796,11 +2503,13 @@ namespace WixToolset.Core
2503
2504 if (!this.Core.EncounteredError)
2505 {
2799 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ReserveCost, id);
2800 - row.Set(1, componentId);
2801 - row.Set(2, directoryId);
2802 - row.Set(3, runLocal);
2803 - row.Set(4, runFromSource);
2506 + this.Core.AddTuple(new ReserveCostTuple(sourceLineNumbers, id)
2507 + {
2508 + Component_ = componentId,
2509 + ReserveFolder = directoryId,
2510 + ReserveLocal = runLocal,
2511 + ReserveSource = runFromSource
2512 + });
2513 }
2514 }
2515
@@ -2809,14 +2518,8 @@ namespace WixToolset.Core
2518 /// </summary>
2519 /// <param name="node">Element to parse.</param>
2520 /// <param name="sequenceTable">Name of sequence table.</param>
2812 - private void ParseSequenceElement(XElement node, string sequenceTable)
2521 + private void ParseSequenceElement(XElement node, SequenceTable sequenceTable)
2522 {
2814 - // use the proper table name internally
2815 - if ("AdvertiseExecuteSequence" == sequenceTable)
2816 - {
2817 - sequenceTable = "AdvtExecuteSequence";
2818 - }
2819 -
2523 // Parse each action in the sequence.
2524 foreach (var child in node.Elements())
2525 {
@@ -2855,7 +2558,7 @@ namespace WixToolset.Core
2558 if (customAction || showDialog || specialAction || specialStandardAction)
2559 {
2560 afterAction = this.Core.GetAttributeIdentifierValue(childSourceLineNumbers, attrib);
2858 - this.Core.CreateSimpleReference(childSourceLineNumbers, "WixAction", sequenceTable, afterAction);
2561 + this.Core.CreateSimpleReference(childSourceLineNumbers, "WixAction", sequenceTable.ToString(), afterAction);
2562 }
2563 else
2564 {
@@ -2866,7 +2569,7 @@ namespace WixToolset.Core
2569 if (customAction || showDialog || specialAction || specialStandardAction)
2570 {
2571 beforeAction = this.Core.GetAttributeIdentifierValue(childSourceLineNumbers, attrib);
2869 - this.Core.CreateSimpleReference(childSourceLineNumbers, "WixAction", sequenceTable, beforeAction);
2572 + this.Core.CreateSimpleReference(childSourceLineNumbers, "WixAction", sequenceTable.ToString(), beforeAction);
2573 }
2574 else
2575 {
@@ -2995,23 +2698,30 @@ namespace WixToolset.Core
2698 {
2699 if (suppress)
2700 {
2998 - var row = this.Core.CreateRow(childSourceLineNumbers, TupleDefinitionType.WixSuppressAction, new Identifier(AccessModifier.Public, sequenceTable, actionName));
2999 - row.Set(0, sequenceTable);
3000 - row.Set(1, actionName);
2701 + this.Core.AddTuple(new WixSuppressActionTuple(childSourceLineNumbers, new Identifier(AccessModifier.Public, sequenceTable, actionName))
2702 + {
2703 + SequenceTable = sequenceTable,
2704 + Action = actionName
2705 + });
2706 }
2707 else
2708 {
3004 - var row = this.Core.CreateRow(childSourceLineNumbers, TupleDefinitionType.WixAction, new Identifier(AccessModifier.Public, sequenceTable, actionName));
3005 - row.Set(0, sequenceTable);
3006 - row.Set(1, actionName);
3007 - row.Set(2, condition);
2709 + var tuple = new WixActionTuple(childSourceLineNumbers, new Identifier(AccessModifier.Public, sequenceTable, actionName))
2710 + {
2711 + SequenceTable = sequenceTable,
2712 + Action = actionName,
2713 + Condition = condition,
2714 + Before = beforeAction,
2715 + After = afterAction,
2716 + Overridable = overridable,
2717 + };
2718 +
2719 if (CompilerConstants.IntegerNotSet != sequence)
2720 {
3010 - row.Set(3, sequence);
2721 + tuple.Sequence = sequence;
2722 }
3012 - row.Set(4, beforeAction);
3013 - row.Set(5, afterAction);
3014 - row.Set(6, overridable ? 1 : 0);
2723 +
2724 + this.Core.AddTuple(tuple);
2725 }
2726 }
2727 }
@@ -3305,7 +3015,7 @@ namespace WixToolset.Core
3015 {
3016 if (!String.IsNullOrEmpty(delayedAutoStart))
3017 {
3308 - var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(String.Concat(id.Id, ".DS"), id.Access))
3018 + var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(id.Access, String.Concat(id.Id, ".DS")))
3019 {
3020 Name = name,
3021 OnInstall = install,
@@ -3327,7 +3037,7 @@ namespace WixToolset.Core
3037
3038 if (!String.IsNullOrEmpty(failureActionsWhen))
3039 {
3330 - var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(String.Concat(id.Id, ".FA"), id.Access))
3040 + var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(id.Access, String.Concat(id.Id, ".FA")))
3041 {
3042 Name = name,
3043 OnInstall = install,
@@ -3349,7 +3059,7 @@ namespace WixToolset.Core
3059
3060 if (!String.IsNullOrEmpty(sid))
3061 {
3352 - var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(String.Concat(id.Id, ".SS"), id.Access))
3062 + var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(id.Access, String.Concat(id.Id, ".SS")))
3063 {
3064 Name = name,
3065 OnInstall = install,
@@ -3371,7 +3081,7 @@ namespace WixToolset.Core
3081
3082 if (!String.IsNullOrEmpty(requiredPrivileges))
3083 {
3374 - var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(String.Concat(id.Id, ".RP"), id.Access))
3084 + var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(id.Access, String.Concat(id.Id, ".RP")))
3085 {
3086 Name = name,
3087 OnInstall = install,
@@ -3393,7 +3103,7 @@ namespace WixToolset.Core
3103
3104 if (!String.IsNullOrEmpty(preShutdownDelay))
3105 {
3396 - var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(String.Concat(id.Id, ".PD"), id.Access))
3106 + var tuple = new MsiServiceConfigTuple(sourceLineNumbers, new Identifier(id.Access, String.Concat(id.Id, ".PD")))
3107 {
3108 Name = name,
3109 OnInstall = install,
@@ -4320,9 +4030,11 @@ namespace WixToolset.Core
4030
4031 if (!this.Core.EncounteredError)
4032 {
4323 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.FileSFPCatalog);
4324 - row.Set(0, id);
4325 - row.Set(1, parentSFPCatalog);
4033 + this.Core.AddTuple(new FileSFPCatalogTuple(sourceLineNumbers)
4034 + {
4035 + File_ = id,
4036 + SFPCatalog_ = parentSFPCatalog
4037 + });
4038 }
4039 }
4040
@@ -4411,10 +4123,12 @@ namespace WixToolset.Core
4123
4124 if (!this.Core.EncounteredError)
4125 {
4414 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.SFPCatalog);
4415 - row.Set(0, name);
4416 - row.Set(1, sourceFile);
4417 - row.Set(2, dependency);
4126 + this.Core.AddTuple(new SFPCatalogTuple(sourceLineNumbers)
4127 + {
4128 + SFPCatalog = name,
4129 + Catalog = sourceFile,
4130 + Dependency = dependency
4131 + });
4132 }
4133 }
4134
@@ -4827,10 +4541,12 @@ namespace WixToolset.Core
4541
4542 if (!this.Core.EncounteredError)
4543 {
4830 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiShortcutProperty, id);
4831 - row.Set(1, shortcutId);
4832 - row.Set(2, key);
4833 - row.Set(3, value);
4544 + this.Core.AddTuple(new MsiShortcutPropertyTuple(sourceLineNumbers, id)
4545 + {
4546 + Shortcut_ = shortcutId,
4547 + PropertyKey = key,
4548 + PropVariantValue = value
4549 + });
4550 }
4551 }
4552
@@ -5022,21 +4738,27 @@ namespace WixToolset.Core
4738
4739 if (!this.Core.EncounteredError)
4740 {
5025 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.TypeLib);
5026 - row.Set(0, id);
5027 - row.Set(1, language);
5028 - row.Set(2, componentId);
4741 + var tuple = new TypeLibTuple(sourceLineNumbers)
4742 + {
4743 + LibId = id,
4744 + Language = language,
4745 + Component_ = componentId,
4746 + Description = description,
4747 + Directory_ = helpDirectory,
4748 + Feature_ = Guid.Empty.ToString("B")
4749 + };
4750 +
4751 if (CompilerConstants.IntegerNotSet != majorVersion || CompilerConstants.IntegerNotSet != minorVersion)
4752 {
5031 - row.Set(3, (CompilerConstants.IntegerNotSet != majorVersion ? majorVersion * 256 : 0) + (CompilerConstants.IntegerNotSet != minorVersion ? minorVersion : 0));
4753 + tuple.Version = (CompilerConstants.IntegerNotSet != majorVersion ? majorVersion * 256 : 0) + (CompilerConstants.IntegerNotSet != minorVersion ? minorVersion : 0);
4754 }
5033 - row.Set(4, description);
5034 - row.Set(5, helpDirectory);
5035 - row.Set(6, Guid.Empty.ToString("B"));
4755 +
4756 if (CompilerConstants.IntegerNotSet != cost)
4757 {
5038 - row.Set(7, cost);
4758 + tuple.Cost = cost;
4759 }
4760 +
4761 + this.Core.AddTuple(tuple);
4762 }
4763 }
4764 else if (YesNoType.No == advertise)
@@ -5250,7 +4972,7 @@ namespace WixToolset.Core
4972 this.Core.AddTuple(tuple);
4973
4974 // Ensure the action property is secure.
5253 - this.AddWixPropertyRow(sourceLineNumbers, new Identifier(actionProperty, AccessModifier.Private), false, true, false);
4975 + this.AddWixPropertyRow(sourceLineNumbers, new Identifier(AccessModifier.Private, actionProperty), false, true, false);
4976
4977 // Ensure that RemoveExistingProducts is authored in InstallExecuteSequence
4978 // if at least one row in Upgrade table lacks the OnlyDetect attribute.
@@ -5361,15 +5083,20 @@ namespace WixToolset.Core
5083
5084 if (!this.Core.EncounteredError)
5085 {
5364 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Verb);
5365 - row.Set(0, extension);
5366 - row.Set(1, id);
5086 + var tuple = new VerbTuple(sourceLineNumbers)
5087 + {
5088 + Extension_ = extension,
5089 + Verb = id,
5090 + Command = command,
5091 + Argument = argument,
5092 + };
5093 +
5094 if (CompilerConstants.IntegerNotSet != sequence)
5095 {
5369 - row.Set(2, sequence);
5096 + tuple.Sequence = sequence;
5097 }
5371 - row.Set(3, command);
5372 - row.Set(4, argument);
5098 +
5099 + this.Core.AddTuple(tuple);
5100 }
5101 }
5102 else if (YesNoType.No == advertise)
@@ -5413,76 +5140,6 @@ namespace WixToolset.Core
5140 }
5141 }
5142
5416 - /// <summary>
5417 - /// Parses a Wix element.
5418 - /// </summary>
5419 - /// <param name="node">Element to parse.</param>
5420 - private void ParseWixElement(XElement node)
5421 - {
5422 - var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
5423 - string requiredVersion = null;
5424 -
5425 - foreach (var attrib in node.Attributes())
5426 - {
5427 - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
5428 - {
5429 - switch (attrib.Name.LocalName)
5430 - {
5431 - case "RequiredVersion":
5432 - requiredVersion = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
5433 - break;
5434 - default:
5435 - this.Core.UnexpectedAttribute(node, attrib);
5436 - break;
5437 - }
5438 - }
5439 - else
5440 - {
5441 - this.Core.ParseExtensionAttribute(node, attrib);
5442 - }
5443 - }
5444 -
5445 - if (null != requiredVersion)
5446 - {
5447 - this.Core.VerifyRequiredVersion(sourceLineNumbers, requiredVersion);
5448 - }
5449 -
5450 - foreach (var child in node.Elements())
5451 - {
5452 - if (CompilerCore.WixNamespace == child.Name.Namespace)
5453 - {
5454 - switch (child.Name.LocalName)
5455 - {
5456 - case "Bundle":
5457 - this.ParseBundleElement(child);
5458 - break;
5459 - case "Fragment":
5460 - this.ParseFragmentElement(child);
5461 - break;
5462 - case "Module":
5463 - this.ParseModuleElement(child);
5464 - break;
5465 - case "PatchCreation":
5466 - this.ParsePatchCreationElement(child);
5467 - break;
5468 - case "Product":
5469 - this.ParseProductElement(child);
5470 - break;
5471 - case "Patch":
5472 - this.ParsePatchElement(child);
5473 - break;
5474 - default:
5475 - this.Core.UnexpectedElement(node, child);
5476 - break;
5477 - }
5478 - }
5479 - else
5480 - {
5481 - this.Core.ParseExtensionElement(node, child);
5482 - }
5483 - }
5484 - }
5485 -
5143 /// <summary>
5144 /// Parses a WixVariable element.
5145 /// </summary>
@@ -5534,9 +5191,11 @@ namespace WixToolset.Core
5191
5192 if (!this.Core.EncounteredError)
5193 {
5537 - var wixVariableRow = (WixVariableTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixVariable, id);
5538 - wixVariableRow.Value = value;
5539 - wixVariableRow.Overridable = overridable;
5194 + this.Core.AddTuple(new WixVariableTuple(sourceLineNumbers, id)
5195 + {
5196 + Value = value,
5197 + Overridable = overridable
5198 + });
5199 }
5200 }
5201
src/WixToolset.Core/Compiler_Bundle.cs
+264 -203
@@ -17,9 +17,10 @@ namespace WixToolset.Core
17 /// </summary>
18 internal partial class Compiler : ICompiler
19 {
20 - public const string BurnUXContainerId = "WixUXContainer";
21 - public const string BurnDefaultAttachedContainerId = "WixAttachedContainer";
22 -
20 + public static readonly Identifier BurnUXContainerId = new Identifier(AccessModifier.Private, "WixUXContainer");
21 + public static readonly Identifier BurnDefaultAttachedContainerId = new Identifier(AccessModifier.Private, "WixAttachedContainer");
22 + public static readonly Identifier BundleLayoutOnlyPayloads = new Identifier(AccessModifier.Private, "BundleLayoutOnlyPayloads");
23 +
24 // The following constants must stay in sync with src\burn\engine\core.h
25 private const string BURN_BUNDLE_NAME = "WixBundleName";
26 private const string BURN_BUNDLE_ORIGINAL_SOURCE = "WixBundleOriginalSource";
@@ -88,10 +89,14 @@ namespace WixToolset.Core
89
90 if (!this.Core.EncounteredError)
91 {
91 - var wixApprovedExeForElevationRow = (WixApprovedExeForElevationTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixApprovedExeForElevation, id);
92 - wixApprovedExeForElevationRow.Key = key;
93 - wixApprovedExeForElevationRow.Value = valueName;
94 - wixApprovedExeForElevationRow.Attributes = (int)attributes;
92 + var tuple = new WixApprovedExeForElevationTuple(sourceLineNumbers, id)
93 + {
94 + Key = key,
95 + Value = valueName,
96 + Attributes = attributes
97 + };
98 +
99 + this.Core.AddTuple(tuple);
100 }
101 }
102
@@ -311,10 +316,10 @@ namespace WixToolset.Core
316 logSeen = true;
317 break;
318 case "PayloadGroup":
314 - this.ParsePayloadGroupElement(child, ComplexReferenceParentType.Layout, "BundleLayoutOnlyPayloads");
319 + this.ParsePayloadGroupElement(child, ComplexReferenceParentType.Layout, Compiler.BundleLayoutOnlyPayloads);
320 break;
321 case "PayloadGroupRef":
317 - this.ParsePayloadGroupRefElement(child, ComplexReferenceParentType.Layout, "BundleLayoutOnlyPayloads", ComplexReferenceChildType.Unknown, null);
322 + this.ParsePayloadGroupRefElement(child, ComplexReferenceParentType.Layout, Compiler.BundleLayoutOnlyPayloads, ComplexReferenceChildType.Unknown, null);
323 break;
324 case "RelatedBundle":
325 this.ParseRelatedBundleElement(child);
@@ -348,72 +353,75 @@ namespace WixToolset.Core
353 {
354 if (null != upgradeCode)
355 {
351 - var tuple = new WixRelatedBundleTuple(sourceLineNumbers)
356 + this.Core.AddTuple(new WixRelatedBundleTuple(sourceLineNumbers)
357 {
358 BundleId = upgradeCode,
359 Action = RelatedBundleActionType.Upgrade,
355 - };
356 -
357 - this.Core.AddTuple(tuple);
360 + });
361 }
362
360 - var containerRow = (WixBundleContainerTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleContainer);
361 - containerRow.WixBundleContainer = Compiler.BurnDefaultAttachedContainerId;
362 - containerRow.Name = "bundle-attached.cab";
363 - containerRow.Type = ContainerType.Attached;
363 + this.Core.AddTuple(new WixBundleContainerTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, Compiler.BurnDefaultAttachedContainerId))
364 + {
365 + Name = "bundle-attached.cab",
366 + Type = ContainerType.Attached
367 + });
368
365 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundle);
366 - row.Set(0, version);
367 - row.Set(1, copyright);
368 - row.Set(2, name);
369 - row.Set(3, aboutUrl);
369 + var bundleTuple = this.Core.CreateTuple(sourceLineNumbers, TupleDefinitionType.WixBundle);
370 + bundleTuple.Set(0, version);
371 + bundleTuple.Set(1, copyright);
372 + bundleTuple.Set(2, name);
373 + bundleTuple.Set(3, aboutUrl);
374 if (-1 != disableModify)
375 {
372 - row.Set(4, disableModify);
376 + bundleTuple.Set(4, disableModify);
377 }
378 if (YesNoType.NotSet != disableRemove)
379 {
376 - row.Set(5, (YesNoType.Yes == disableRemove) ? 1 : 0);
380 + bundleTuple.Set(5, (YesNoType.Yes == disableRemove) ? 1 : 0);
381 }
382 // row.Set(6] - (deprecated) "disable repair"
379 - row.Set(7, helpTelephone);
380 - row.Set(8, helpUrl);
381 - row.Set(9, manufacturer);
382 - row.Set(10, updateUrl);
383 + bundleTuple.Set(7, helpTelephone);
384 + bundleTuple.Set(8, helpUrl);
385 + bundleTuple.Set(9, manufacturer);
386 + bundleTuple.Set(10, updateUrl);
387 if (YesNoDefaultType.Default != compressed)
388 {
385 - row.Set(11, (YesNoDefaultType.Yes == compressed) ? 1 : 0);
389 + bundleTuple.Set(11, (YesNoDefaultType.Yes == compressed) ? 1 : 0);
390 }
391
388 - row.Set(12, logVariablePrefixAndExtension);
389 - row.Set(13, iconSourceFile);
390 - row.Set(14, splashScreenSourceFile);
391 - row.Set(15, condition);
392 - row.Set(16, tag);
393 - row.Set(17, this.CurrentPlatform.ToString());
394 - row.Set(18, parentName);
395 - row.Set(19, upgradeCode);
392 + bundleTuple.Set(12, logVariablePrefixAndExtension);
393 + bundleTuple.Set(13, iconSourceFile);
394 + bundleTuple.Set(14, splashScreenSourceFile);
395 + bundleTuple.Set(15, condition);
396 + bundleTuple.Set(16, tag);
397 + bundleTuple.Set(17, this.CurrentPlatform.ToString());
398 + bundleTuple.Set(18, parentName);
399 + bundleTuple.Set(19, upgradeCode);
400
401 // Ensure that the bundle stores the well-known persisted values.
398 - var bundleNameWellKnownVariable = (WixBundleVariableTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleVariable);
399 - bundleNameWellKnownVariable.WixBundleVariable = Compiler.BURN_BUNDLE_NAME;
400 - bundleNameWellKnownVariable.Hidden = false;
401 - bundleNameWellKnownVariable.Persisted = true;
402 -
403 - var bundleOriginalSourceWellKnownVariable = (WixBundleVariableTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleVariable);
404 - bundleOriginalSourceWellKnownVariable.WixBundleVariable = Compiler.BURN_BUNDLE_ORIGINAL_SOURCE;
405 - bundleOriginalSourceWellKnownVariable.Hidden = false;
406 - bundleOriginalSourceWellKnownVariable.Persisted = true;
407 -
408 - var bundleOriginalSourceFolderWellKnownVariable = (WixBundleVariableTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleVariable);
409 - bundleOriginalSourceFolderWellKnownVariable.WixBundleVariable = Compiler.BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER;
410 - bundleOriginalSourceFolderWellKnownVariable.Hidden = false;
411 - bundleOriginalSourceFolderWellKnownVariable.Persisted = true;
412 -
413 - var bundleLastUsedSourceWellKnownVariable = (WixBundleVariableTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleVariable);
414 - bundleLastUsedSourceWellKnownVariable.WixBundleVariable = Compiler.BURN_BUNDLE_LAST_USED_SOURCE;
415 - bundleLastUsedSourceWellKnownVariable.Hidden = false;
416 - bundleLastUsedSourceWellKnownVariable.Persisted = true;
402 + this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, Compiler.BURN_BUNDLE_NAME))
403 + {
404 + Hidden = false,
405 + Persisted = true
406 + });
407 +
408 + this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, Compiler.BURN_BUNDLE_ORIGINAL_SOURCE))
409 + {
410 + Hidden = false,
411 + Persisted = true
412 + });
413 +
414 + this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, Compiler.BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER))
415 + {
416 + Hidden = false,
417 + Persisted = true
418 + });
419 +
420 + this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, Compiler.BURN_BUNDLE_LAST_USED_SOURCE))
421 + {
422 + Hidden = false,
423 + Persisted = true
424 + });
425 }
426 }
427
@@ -514,8 +522,10 @@ namespace WixToolset.Core
522 {
523 this.CreatePayloadRow(sourceLineNumbers, id, Path.GetFileName(sourceFile), sourceFile, null, ComplexReferenceParentType.Container, Compiler.BurnUXContainerId, ComplexReferenceChildType.Unknown, null, YesNoDefaultType.Yes, YesNoType.Yes, null, null, null);
524
517 - var wixCatalogRow = (WixBundleCatalogTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleCatalog, id);
518 - wixCatalogRow.Payload_ = id.Id;
525 + this.Core.AddTuple(new WixBundleCatalogTuple(sourceLineNumbers, id)
526 + {
527 + Payload_ = id.Id,
528 + });
529 }
530 }
531
@@ -614,10 +624,12 @@ namespace WixToolset.Core
624
625 if (!this.Core.EncounteredError)
626 {
617 - var row = (WixBundleContainerTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleContainer, id);
618 - row.Name = name;
619 - row.Type = type;
620 - row.DownloadUrl = downloadUrl;
627 + this.Core.AddTuple(new WixBundleContainerTuple(sourceLineNumbers, id)
628 + {
629 + Name = name,
630 + Type = type,
631 + DownloadUrl = downloadUrl
632 + });
633 }
634 }
635
@@ -628,12 +640,11 @@ namespace WixToolset.Core
640 private void ParseBootstrapperApplicationElement(XElement node)
641 {
642 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
631 - string id = null;
632 - string previousId = null;
643 + Identifier previousId = null;
644 var previousType = ComplexReferenceChildType.Unknown;
645
646 // The BootstrapperApplication element acts like a Payload element so delegate to the "Payload" attribute parsing code to parse and create a Payload entry.
636 - id = this.ParsePayloadElementContent(node, ComplexReferenceParentType.Container, Compiler.BurnUXContainerId, previousType, previousId, false);
647 + var id = this.ParsePayloadElementContent(node, ComplexReferenceParentType.Container, Compiler.BurnUXContainerId, previousType, previousId, false);
648 if (null != id)
649 {
650 previousId = id;
@@ -676,15 +687,15 @@ namespace WixToolset.Core
687 // Add the application as an attached container and if an Id was provided add that too.
688 if (!this.Core.EncounteredError)
689 {
679 - var containerRow = (WixBundleContainerTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleContainer);
680 - containerRow.WixBundleContainer = Compiler.BurnUXContainerId;
681 - containerRow.Name = "bundle-ux.cab";
682 - containerRow.Type = ContainerType.Attached;
690 + this.Core.AddTuple(new WixBundleContainerTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, Compiler.BurnUXContainerId))
691 + {
692 + Name = "bundle-ux.cab",
693 + Type = ContainerType.Attached
694 + });
695
684 - if (!String.IsNullOrEmpty(id))
696 + if (null != id)
697 {
686 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBootstrapperApplication);
687 - row.Set(0, id);
698 + this.Core.AddTuple(new WixBootstrapperApplicationTuple(sourceLineNumbers, id));
699 }
700 }
701 }
@@ -697,7 +708,7 @@ namespace WixToolset.Core
708 {
709 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
710 string id = null;
700 - string previousId = null;
711 + Identifier previousId = null;
712 var previousType = ComplexReferenceChildType.Unknown;
713
714 foreach (var attrib in node.Attributes())
@@ -847,12 +858,14 @@ namespace WixToolset.Core
858
859 if (!this.Core.EncounteredError)
860 {
850 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixUpdateRegistration);
851 - row.Set(0, manufacturer);
852 - row.Set(1, department);
853 - row.Set(2, productFamily);
854 - row.Set(3, name);
855 - row.Set(4, classification);
861 + this.Core.AddTuple(new WixUpdateRegistrationTuple(sourceLineNumbers)
862 + {
863 + Manufacturer = manufacturer,
864 + Department = department,
865 + ProductFamily = productFamily,
866 + Name = name,
867 + Classification = classification
868 + });
869 }
870 }
871
@@ -862,7 +875,7 @@ namespace WixToolset.Core
875 /// <param name="node">Element to parse</param>
876 /// <param name="parentType">ComplexReferenceParentType of parent element. (BA or PayloadGroup)</param>
877 /// <param name="parentId">Identifier of parent element.</param>
865 - private string ParsePayloadElement(XElement node, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType previousType, string previousId)
878 + private Identifier ParsePayloadElement(XElement node, ComplexReferenceParentType parentType, Identifier parentId, ComplexReferenceChildType previousType, Identifier previousId)
879 {
880 Debug.Assert(ComplexReferenceParentType.PayloadGroup == parentType || ComplexReferenceParentType.Package == parentType || ComplexReferenceParentType.Container == parentType);
881 Debug.Assert(ComplexReferenceChildType.Unknown == previousType || ComplexReferenceChildType.PayloadGroup == previousType || ComplexReferenceChildType.Payload == previousType);
@@ -870,7 +883,7 @@ namespace WixToolset.Core
883 var id = this.ParsePayloadElementContent(node, parentType, parentId, previousType, previousId, true);
884 var context = new Dictionary<string, string>
885 {
873 - ["Id"] = id
886 + ["Id"] = id.Id
887 };
888
889 foreach (var child in node.Elements())
@@ -899,7 +912,7 @@ namespace WixToolset.Core
912 /// <param name="node">Element to parse</param>
913 /// <param name="parentType">ComplexReferenceParentType of parent element.</param>
914 /// <param name="parentId">Identifier of parent element.</param>
902 - private string ParsePayloadElementContent(XElement node, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType previousType, string previousId, bool required)
915 + private Identifier ParsePayloadElementContent(XElement node, ComplexReferenceParentType parentType, Identifier parentId, ComplexReferenceChildType previousType, Identifier previousId, bool required)
916 {
917 Debug.Assert(ComplexReferenceParentType.PayloadGroup == parentType || ComplexReferenceParentType.Package == parentType || ComplexReferenceParentType.Container == parentType);
918
@@ -959,7 +972,7 @@ namespace WixToolset.Core
972
973 if (null == id)
974 {
962 - id = this.Core.CreateIdentifier("pay", (null != sourceFile) ? sourceFile.ToUpperInvariant() : String.Empty);
975 + id = this.Core.CreateIdentifier("pay", sourceFile?.ToUpperInvariant() ?? String.Empty);
976 }
977
978 // Now that the PayloadId is known, we can parse the extension attributes.
@@ -1022,7 +1035,7 @@ namespace WixToolset.Core
1035
1036 this.CreatePayloadRow(sourceLineNumbers, id, name, sourceFile, downloadUrl, parentType, parentId, previousType, previousId, compressed, enableSignatureVerification, null, null, remotePayload);
1037
1025 - return id.Id;
1038 + return id;
1039 }
1040
1041 private RemotePayload ParseRemotePayloadElement(XElement node)
@@ -1103,38 +1116,42 @@ namespace WixToolset.Core
1116 /// <param name="parentType">ComplexReferenceParentType of parent element</param>
1117 /// <param name="parentId">Identifier of parent element.</param>
1118 private WixBundlePayloadTuple CreatePayloadRow(SourceLineNumber sourceLineNumbers, Identifier id, string name, string sourceFile, string downloadUrl, ComplexReferenceParentType parentType,
1106 - string parentId, ComplexReferenceChildType previousType, string previousId, YesNoDefaultType compressed, YesNoType enableSignatureVerification, string displayName, string description,
1119 + Identifier parentId, ComplexReferenceChildType previousType, Identifier previousId, YesNoDefaultType compressed, YesNoType enableSignatureVerification, string displayName, string description,
1120 RemotePayload remotePayload)
1121 {
1109 - WixBundlePayloadTuple row = null;
1122 + WixBundlePayloadTuple tuple = null;
1123
1124 if (!this.Core.EncounteredError)
1125 {
1113 - row = (WixBundlePayloadTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundlePayload, id);
1114 - row.Name = String.IsNullOrEmpty(name) ? Path.GetFileName(sourceFile) : name;
1115 - row.SourceFile = sourceFile;
1116 - row.DownloadUrl = downloadUrl;
1117 - row.Compressed = compressed;
1118 - row.UnresolvedSourceFile = sourceFile; // duplicate of sourceFile but in a string column so it won't get resolved to a full path during binding.
1119 - row.DisplayName = displayName;
1120 - row.Description = description;
1121 - row.EnableSignatureValidation = (YesNoType.Yes == enableSignatureVerification);
1126 + tuple = new WixBundlePayloadTuple(sourceLineNumbers, id)
1127 + {
1128 + Name = String.IsNullOrEmpty(name) ? Path.GetFileName(sourceFile) : name,
1129 + SourceFile = sourceFile,
1130 + DownloadUrl = downloadUrl,
1131 + Compressed = compressed,
1132 + UnresolvedSourceFile = sourceFile, // duplicate of sourceFile but in a string column so it won't get resolved to a full path during binding.
1133 + DisplayName = displayName,
1134 + Description = description,
1135 + EnableSignatureValidation = (YesNoType.Yes == enableSignatureVerification)
1136 + };
1137
1138 if (null != remotePayload)
1139 {
1125 - row.Description = remotePayload.Description;
1126 - row.DisplayName = remotePayload.ProductName;
1127 - row.Hash = remotePayload.Hash;
1128 - row.PublicKey = remotePayload.CertificatePublicKey;
1129 - row.Thumbprint = remotePayload.CertificateThumbprint;
1130 - row.FileSize = remotePayload.Size;
1131 - row.Version = remotePayload.Version;
1140 + tuple.Description = remotePayload.Description;
1141 + tuple.DisplayName = remotePayload.ProductName;
1142 + tuple.Hash = remotePayload.Hash;
1143 + tuple.PublicKey = remotePayload.CertificatePublicKey;
1144 + tuple.Thumbprint = remotePayload.CertificateThumbprint;
1145 + tuple.FileSize = remotePayload.Size;
1146 + tuple.Version = remotePayload.Version;
1147 }
1148
1134 - this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.Payload, id.Id, previousType, previousId);
1149 + this.Core.AddTuple(tuple);
1150 +
1151 + this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId.Id, ComplexReferenceChildType.Payload, id.Id, previousType, previousId.Id);
1152 }
1153
1137 - return row;
1154 + return tuple;
1155 }
1156
1157 /// <summary>
@@ -1143,7 +1160,7 @@ namespace WixToolset.Core
1160 /// <param name="node">Element to parse</param>
1161 /// <param name="parentType">Optional ComplexReferenceParentType of parent element. (typically another PayloadGroup)</param>
1162 /// <param name="parentId">Identifier of parent element.</param>
1146 - private void ParsePayloadGroupElement(XElement node, ComplexReferenceParentType parentType, string parentId)
1163 + private void ParsePayloadGroupElement(XElement node, ComplexReferenceParentType parentType, Identifier parentId)
1164 {
1165 Debug.Assert(ComplexReferenceParentType.Unknown == parentType || ComplexReferenceParentType.Layout == parentType || ComplexReferenceParentType.PayloadGroup == parentType);
1166
@@ -1177,7 +1194,7 @@ namespace WixToolset.Core
1194 }
1195
1196 var previousType = ComplexReferenceChildType.Unknown;
1180 - string previousId = null;
1197 + Identifier previousId = null;
1198 foreach (var child in node.Elements())
1199 {
1200 if (CompilerCore.WixNamespace == child.Name.Namespace)
@@ -1185,11 +1202,11 @@ namespace WixToolset.Core
1202 switch (child.Name.LocalName)
1203 {
1204 case "Payload":
1188 - previousId = this.ParsePayloadElement(child, ComplexReferenceParentType.PayloadGroup, id.Id, previousType, previousId);
1205 + previousId = this.ParsePayloadElement(child, ComplexReferenceParentType.PayloadGroup, id, previousType, previousId);
1206 previousType = ComplexReferenceChildType.Payload;
1207 break;
1208 case "PayloadGroupRef":
1192 - previousId = this.ParsePayloadGroupRefElement(child, ComplexReferenceParentType.PayloadGroup, id.Id, previousType, previousId);
1209 + previousId = this.ParsePayloadGroupRefElement(child, ComplexReferenceParentType.PayloadGroup, id, previousType, previousId);
1210 previousType = ComplexReferenceChildType.PayloadGroup;
1211 break;
1212 default:
@@ -1206,9 +1223,9 @@ namespace WixToolset.Core
1223
1224 if (!this.Core.EncounteredError)
1225 {
1209 - this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundlePayloadGroup, id);
1226 + this.Core.AddTuple(new WixBundlePayloadGroupTuple(sourceLineNumbers, id));
1227
1211 - this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.PayloadGroup, id.Id, ComplexReferenceChildType.Unknown, null);
1228 + this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId?.Id, ComplexReferenceChildType.PayloadGroup, id.Id, ComplexReferenceChildType.Unknown, null);
1229 }
1230 }
1231
@@ -1218,13 +1235,13 @@ namespace WixToolset.Core
1235 /// <param name="node">Element to parse.</param>
1236 /// <param name="parentType">ComplexReferenceParentType of parent element (BA or PayloadGroup).</param>
1237 /// <param name="parentId">Identifier of parent element.</param>
1221 - private string ParsePayloadGroupRefElement(XElement node, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType previousType, string previousId)
1238 + private Identifier ParsePayloadGroupRefElement(XElement node, ComplexReferenceParentType parentType, Identifier parentId, ComplexReferenceChildType previousType, Identifier previousId)
1239 {
1240 Debug.Assert(ComplexReferenceParentType.Layout == parentType || ComplexReferenceParentType.PayloadGroup == parentType || ComplexReferenceParentType.Package == parentType || ComplexReferenceParentType.Container == parentType);
1241 Debug.Assert(ComplexReferenceChildType.Unknown == previousType || ComplexReferenceChildType.PayloadGroup == previousType || ComplexReferenceChildType.Payload == previousType);
1242
1243 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1227 - string id = null;
1244 + Identifier id = null;
1245
1246 foreach (var attrib in node.Attributes())
1247 {
@@ -1233,8 +1250,8 @@ namespace WixToolset.Core
1250 switch (attrib.Name.LocalName)
1251 {
1252 case "Id":
1236 - id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
1237 - this.Core.CreateSimpleReference(sourceLineNumbers, "WixBundlePayloadGroup", id);
1253 + id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
1254 + this.Core.CreateSimpleReference(sourceLineNumbers, "WixBundlePayloadGroup", id.Id);
1255 break;
1256 default:
1257 this.Core.UnexpectedAttribute(node, attrib);
@@ -1254,7 +1271,7 @@ namespace WixToolset.Core
1271
1272 this.Core.ParseForExtensionElements(node);
1273
1257 - this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.PayloadGroup, id, previousType, previousId);
1274 + this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId.Id, ComplexReferenceChildType.PayloadGroup, id.Id, previousType, previousId.Id);
1275
1276 return id;
1277 }
@@ -1274,6 +1291,11 @@ namespace WixToolset.Core
1291 ComplexReferenceChildType type, string id,
1292 ComplexReferenceChildType previousType, string previousId)
1293 {
1294 + if (this.Core.EncounteredError)
1295 + {
1296 + return;
1297 + }
1298 +
1299 if (ComplexReferenceParentType.Unknown != parentType && null != parentId)
1300 {
1301 this.Core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, type, id);
@@ -1281,7 +1303,18 @@ namespace WixToolset.Core
1303
1304 if (ComplexReferenceChildType.Unknown != previousType && null != previousId)
1305 {
1284 - this.CreateWixOrderingRow(sourceLineNumbers, type, id, previousType, previousId);
1306 + // TODO: Should we define our own enum for this, just to ensure there's no "cross-contamination"?
1307 + // TODO: Also, we could potentially include an 'Attributes' field to track things like
1308 + // 'before' vs. 'after', and explicit vs. inferred dependencies.
1309 + var tuple = new WixOrderingTuple(sourceLineNumbers)
1310 + {
1311 + ItemType = type,
1312 + ItemId_ = id,
1313 + DependsOnType = previousType,
1314 + DependsOnId_ = previousId
1315 + };
1316 +
1317 + this.Core.AddTuple(tuple);
1318 }
1319 }
1320
@@ -1307,7 +1340,7 @@ namespace WixToolset.Core
1340 break;
1341 case "Behavior":
1342 var behaviorString = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1310 - if (!Enum.TryParse<ExitCodeBehaviorType>(behaviorString, true, out behavior))
1343 + if (!Enum.TryParse(behaviorString, true, out behavior))
1344 {
1345 this.Core.Write(ErrorMessages.IllegalAttributeValueWithLegalList(sourceLineNumbers, node.Name.LocalName, "Behavior", behaviorString, "success, error, scheduleReboot, forceReboot"));
1346 }
@@ -1332,10 +1365,12 @@ namespace WixToolset.Core
1365
1366 if (!this.Core.EncounteredError)
1367 {
1335 - var row = (WixBundlePackageExitCodeTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundlePackageExitCode);
1336 - row.ChainPackageId = packageId;
1337 - row.Code = value;
1338 - row.Behavior = behavior;
1368 + this.Core.AddTuple(new WixBundlePackageExitCodeTuple(sourceLineNumbers)
1369 + {
1370 + ChainPackageId = packageId,
1371 + Code = value,
1372 + Behavior = behavior
1373 + });
1374 }
1375 }
1376
@@ -1384,7 +1419,7 @@ namespace WixToolset.Core
1419 }
1420
1421 // Ensure there is always a rollback boundary at the beginning of the chain.
1387 - this.CreateRollbackBoundary(sourceLineNumbers, new Identifier("WixDefaultBoundary", AccessModifier.Public), YesNoType.Yes, YesNoType.No, ComplexReferenceParentType.PackageGroup, "WixChain", ComplexReferenceChildType.Unknown, null);
1422 + this.CreateRollbackBoundary(sourceLineNumbers, new Identifier(AccessModifier.Public, "WixDefaultBoundary"), YesNoType.Yes, YesNoType.No, ComplexReferenceParentType.PackageGroup, "WixChain", ComplexReferenceChildType.Unknown, null);
1423
1424 var previousId = "WixDefaultBoundary";
1425 var previousType = ComplexReferenceChildType.Package;
@@ -1438,8 +1473,10 @@ namespace WixToolset.Core
1473
1474 if (!this.Core.EncounteredError)
1475 {
1441 - var row = (WixChainTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixChain);
1442 - row.Attributes = attributes;
1476 + this.Core.AddTuple(new WixChainTuple(sourceLineNumbers)
1477 + {
1478 + Attributes = attributes
1479 + });
1480 }
1481 }
1482
@@ -1680,7 +1717,24 @@ namespace WixToolset.Core
1717 installCondition = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1718 break;
1719 case "Cache":
1683 - cache = this.Core.GetAttributeYesNoAlwaysValue(sourceLineNumbers, attrib);
1720 + var value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1721 + switch (value)
1722 + {
1723 + case "always":
1724 + cache = YesNoAlwaysType.Always;
1725 + break;
1726 + case "yes":
1727 + cache = YesNoAlwaysType.Yes;
1728 + break;
1729 + case "no":
1730 + cache = YesNoAlwaysType.No;
1731 + break;
1732 + case "":
1733 + break;
1734 + default:
1735 + this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, value, "button", "yes", "no"));
1736 + break;
1737 + }
1738 break;
1739 case "CacheId":
1740 cacheId = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
@@ -1933,10 +1987,10 @@ namespace WixToolset.Core
1987 }
1988 break;
1989 case "Payload":
1936 - this.ParsePayloadElement(child, ComplexReferenceParentType.Package, id.Id, ComplexReferenceChildType.Unknown, null);
1990 + this.ParsePayloadElement(child, ComplexReferenceParentType.Package, id, ComplexReferenceChildType.Unknown, null);
1991 break;
1992 case "PayloadGroupRef":
1939 - this.ParsePayloadGroupRefElement(child, ComplexReferenceParentType.Package, id.Id, ComplexReferenceChildType.Unknown, null);
1993 + this.ParsePayloadGroupRefElement(child, ComplexReferenceParentType.Package, id, ComplexReferenceChildType.Unknown, null);
1994 break;
1995 case "ExitCode":
1996 allowed = (packageType == WixBundlePackageType.Exe);
@@ -1975,60 +2029,60 @@ namespace WixToolset.Core
2029 if (!this.Core.EncounteredError)
2030 {
2031 // We create the package contents as a payload with this package as the parent
1978 - this.CreatePayloadRow(sourceLineNumbers, id, name, sourceFile, downloadUrl, ComplexReferenceParentType.Package, id.Id,
2032 + this.CreatePayloadRow(sourceLineNumbers, id, name, sourceFile, downloadUrl, ComplexReferenceParentType.Package, id,
2033 ComplexReferenceChildType.Unknown, null, compressed, enableSignatureVerification, displayName, description, remotePayload);
2034
1981 - var chainItemRow = (WixChainItemTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixChainItem, id);
2035 + this.Core.AddTuple(new WixChainItemTuple(sourceLineNumbers, id));
2036
2037 WixBundlePackageAttributes attributes = 0;
2038 attributes |= (YesNoType.Yes == permanent) ? WixBundlePackageAttributes.Permanent : 0;
2039 attributes |= (YesNoType.Yes == visible) ? WixBundlePackageAttributes.Visible : 0;
2040
1987 - var chainPackageRow = (WixBundlePackageTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundlePackage, id);
1988 - chainPackageRow.Type = packageType;
1989 - chainPackageRow.Payload_ = id.Id;
1990 - chainPackageRow.Attributes = attributes;
1991 -
1992 - chainPackageRow.InstallCondition = installCondition;
2041 + var chainPackageTuple = new WixBundlePackageTuple(sourceLineNumbers, id)
2042 + {
2043 + Type = packageType,
2044 + Payload_ = id.Id,
2045 + Attributes = attributes,
2046 + InstallCondition = installCondition,
2047 + CacheId = cacheId,
2048 + LogPathVariable = logPathVariable,
2049 + RollbackLogPathVariable = rollbackPathVariable,
2050 + };
2051
2052 if (YesNoAlwaysType.NotSet != cache)
2053 {
1996 - chainPackageRow.Cache = cache;
2054 + chainPackageTuple.Cache = cache;
2055 }
2056
1999 - chainPackageRow.CacheId = cacheId;
2000 -
2057 if (YesNoType.NotSet != vital)
2058 {
2003 - chainPackageRow.Vital = (vital == YesNoType.Yes);
2059 + chainPackageTuple.Vital = (vital == YesNoType.Yes);
2060 }
2061
2062 if (YesNoDefaultType.NotSet != perMachine)
2063 {
2008 - chainPackageRow.PerMachine = perMachine;
2064 + chainPackageTuple.PerMachine = perMachine;
2065 }
2066
2011 - chainPackageRow.LogPathVariable = logPathVariable;
2012 - chainPackageRow.RollbackLogPathVariable = rollbackPathVariable;
2013 -
2067 if (CompilerConstants.IntegerNotSet != installSize)
2068 {
2016 - chainPackageRow.InstallSize = installSize;
2069 + chainPackageTuple.InstallSize = installSize;
2070 }
2071
2072 + this.Core.AddTuple(chainPackageTuple);
2073 +
2074 switch (packageType)
2075 {
2076 case WixBundlePackageType.Exe:
2022 - WixBundleExePackageAttributes exeAttributes = 0;
2023 - exeAttributes |= (YesNoType.Yes == repairable) ? WixBundleExePackageAttributes.Repairable : 0;
2024 -
2025 - var exeRow = (WixBundleExePackageTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleExePackage, id);
2026 - exeRow.Attributes = exeAttributes;
2027 - exeRow.DetectCondition = detectCondition;
2028 - exeRow.InstallCommand = installCommand;
2029 - exeRow.RepairCommand = repairCommand;
2030 - exeRow.UninstallCommand = uninstallCommand;
2031 - exeRow.ExeProtocol = protocol;
2077 + this.Core.AddTuple(new WixBundleExePackageTuple(sourceLineNumbers, id)
2078 + {
2079 + Attributes = (YesNoType.Yes == repairable) ? WixBundleExePackageAttributes.Repairable : 0,
2080 + DetectCondition = detectCondition,
2081 + InstallCommand = installCommand,
2082 + RepairCommand = repairCommand,
2083 + UninstallCommand = uninstallCommand,
2084 + ExeProtocol = protocol
2085 + });
2086 break;
2087
2088 case WixBundlePackageType.Msi:
@@ -2038,8 +2092,10 @@ namespace WixToolset.Core
2092 msiAttributes |= (YesNoType.Yes == forcePerMachine) ? WixBundleMsiPackageAttributes.ForcePerMachine : 0;
2093 msiAttributes |= (YesNoType.Yes == suppressLooseFilePayloadGeneration) ? WixBundleMsiPackageAttributes.SuppressLooseFilePayloadGeneration : 0;
2094
2041 - var msiRow = (WixBundleMsiPackageTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleMsiPackage, id);
2042 - msiRow.Attributes = msiAttributes;
2095 + this.Core.AddTuple(new WixBundleMsiPackageTuple(sourceLineNumbers, id)
2096 + {
2097 + Attributes = msiAttributes
2098 + });
2099 break;
2100
2101 case WixBundlePackageType.Msp:
@@ -2047,14 +2103,18 @@ namespace WixToolset.Core
2103 mspAttributes |= (YesNoType.Yes == displayInternalUI) ? WixBundleMspPackageAttributes.DisplayInternalUI : 0;
2104 mspAttributes |= (YesNoType.Yes == slipstream) ? WixBundleMspPackageAttributes.Slipstream : 0;
2105
2050 - var mspRow = (WixBundleMspPackageTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleMspPackage, id);
2051 - mspRow.Attributes = mspAttributes;
2106 + this.Core.AddTuple(new WixBundleMspPackageTuple(sourceLineNumbers, id)
2107 + {
2108 + Attributes = mspAttributes
2109 + });
2110 break;
2111
2112 case WixBundlePackageType.Msu:
2055 - var msuRow = (WixBundleMsuPackageTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleMsuPackage, id);
2056 - msuRow.DetectCondition = detectCondition;
2057 - msuRow.MsuKB = msuKB;
2113 + this.Core.AddTuple(new WixBundleMsuPackageTuple(sourceLineNumbers, id)
2114 + {
2115 + DetectCondition = detectCondition,
2116 + MsuKB = msuKB
2117 + });
2118 break;
2119 }
2120
@@ -2114,12 +2174,14 @@ namespace WixToolset.Core
2174
2175 if (!this.Core.EncounteredError)
2176 {
2117 - var row = (WixBundlePackageCommandLineTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundlePackageCommandLine);
2118 - row.WixBundlePackage_ = packageId;
2119 - row.InstallArgument = installArgument;
2120 - row.UninstallArgument = uninstallArgument;
2121 - row.RepairArgument = repairArgument;
2122 - row.Condition = condition;
2177 + this.Core.AddTuple(new WixBundlePackageCommandLineTuple(sourceLineNumbers)
2178 + {
2179 + WixBundlePackage_ = packageId,
2180 + InstallArgument = installArgument,
2181 + UninstallArgument = uninstallArgument,
2182 + RepairArgument = repairArgument,
2183 + Condition = condition
2184 + });
2185 }
2186 }
2187
@@ -2204,7 +2266,7 @@ namespace WixToolset.Core
2266
2267 if (!this.Core.EncounteredError)
2268 {
2207 - this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundlePackageGroup, id);
2269 + this.Core.AddTuple(new WixBundlePackageGroupTuple(sourceLineNumbers, id));
2270 }
2271 }
2272
@@ -2299,19 +2361,22 @@ namespace WixToolset.Core
2361 /// <param name="previousId">Identifier of previous item, if any.</param>
2362 private void CreateRollbackBoundary(SourceLineNumber sourceLineNumbers, Identifier id, YesNoType vital, YesNoType transaction, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType previousType, string previousId)
2363 {
2302 - var row = (WixChainItemTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixChainItem, id);
2364 + this.Core.AddTuple(new WixChainItemTuple(sourceLineNumbers, id));
2365
2304 - var rollbackBoundary = (WixBundleRollbackBoundaryTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleRollbackBoundary, id);
2366 + var rollbackBoundary = new WixBundleRollbackBoundaryTuple(sourceLineNumbers, id);
2367
2368 if (YesNoType.NotSet != vital)
2369 {
2370 rollbackBoundary.Vital = (vital == YesNoType.Yes);
2371 }
2372 +
2373 if (YesNoType.NotSet != transaction)
2374 {
2375 rollbackBoundary.Transaction = (transaction == YesNoType.Yes);
2376 }
2377
2378 + this.Core.AddTuple(rollbackBoundary);
2379 +
2380 this.CreateChainPackageMetaRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.Package, id.Id, previousType, previousId, null);
2381 }
2382
@@ -2341,23 +2406,6 @@ namespace WixToolset.Core
2406 this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId, type, id, previousType, previousId);
2407 }
2408
2344 - // TODO: Should we define our own enum for this, just to ensure there's no "cross-contamination"?
2345 - // TODO: Also, we could potentially include an 'Attributes' field to track things like
2346 - // 'before' vs. 'after', and explicit vs. inferred dependencies.
2347 - private void CreateWixOrderingRow(SourceLineNumber sourceLineNumbers,
2348 - ComplexReferenceChildType itemType, string itemId,
2349 - ComplexReferenceChildType dependsOnType, string dependsOnId)
2350 - {
2351 - if (!this.Core.EncounteredError)
2352 - {
2353 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixOrdering);
2354 - row.Set(0, itemType.ToString());
2355 - row.Set(1, itemId);
2356 - row.Set(2, dependsOnType.ToString());
2357 - row.Set(3, dependsOnId);
2358 - }
2359 - }
2360 -
2409 /// <summary>
2410 /// Parse MsiProperty element
2411 /// </summary>
@@ -2410,15 +2458,19 @@ namespace WixToolset.Core
2458
2459 if (!this.Core.EncounteredError)
2460 {
2413 - var row = (WixBundleMsiPropertyTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleMsiProperty);
2414 - row.WixBundlePackage_ = packageId;
2415 - row.Name = name;
2416 - row.Value = value;
2461 + var tuple = new WixBundleMsiPropertyTuple(sourceLineNumbers)
2462 + {
2463 + WixBundlePackage_ = packageId,
2464 + Name = name,
2465 + Value = value
2466 + };
2467
2468 if (!String.IsNullOrEmpty(condition))
2469 {
2420 - row.Condition = condition;
2470 + tuple.Condition = condition;
2471 }
2472 +
2473 + this.Core.AddTuple(tuple);
2474 }
2475 }
2476
@@ -2462,9 +2514,11 @@ namespace WixToolset.Core
2514
2515 if (!this.Core.EncounteredError)
2516 {
2465 - var row = (WixBundleSlipstreamMspTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleSlipstreamMsp);
2466 - row.WixBundlePackage_ = packageId;
2467 - row.WixBundlePackage_Msp = id;
2517 + this.Core.AddTuple(new WixBundleSlipstreamMspTuple(sourceLineNumbers)
2518 + {
2519 + WixBundlePackage_ = packageId,
2520 + WixBundlePackage_Msp = id
2521 + });
2522 }
2523 }
2524
@@ -2585,8 +2639,12 @@ namespace WixToolset.Core
2639
2640 if (!this.Core.EncounteredError)
2641 {
2588 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleUpdate);
2589 - row.Set(0, location);
2642 + var tuple = new WixBundleUpdateTuple(sourceLineNumbers)
2643 + {
2644 + Location = location
2645 + };
2646 +
2647 + this.Core.AddTuple(tuple);
2648 }
2649 }
2650
@@ -2698,12 +2756,15 @@ namespace WixToolset.Core
2756
2757 if (!this.Core.EncounteredError)
2758 {
2701 - var row = (WixBundleVariableTuple)this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixBundleVariable);
2702 - row.WixBundleVariable = name;
2703 - row.Value = value;
2704 - row.Type = type;
2705 - row.Hidden = hidden;
2706 - row.Persisted = persisted;
2759 + var tuple = new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, name))
2760 + {
2761 + Value = value,
2762 + Type = type,
2763 + Hidden = hidden,
2764 + Persisted = persisted
2765 + };
2766 +
2767 + this.Core.AddTuple(tuple);
2768 }
2769 }
2770
src/WixToolset.Core/Compiler_EmbeddedUI.cs
+7 -5
@@ -91,11 +91,13 @@ namespace WixToolset.Core
91
92 if (!this.Core.EncounteredError)
93 {
94 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.MsiEmbeddedChainer, id);
95 - row.Set(1, condition);
96 - row.Set(2, commandLine);
97 - row.Set(3, source);
98 - row.Set(4, type);
94 + this.Core.AddTuple(new MsiEmbeddedChainerTuple(sourceLineNumbers, id)
95 + {
96 + Condition = condition,
97 + CommandLine = commandLine,
98 + Source = source,
99 + Type = type
100 + });
101 }
102 }
103
src/WixToolset.Core/Compiler_Module.cs
+52 -27
@@ -100,11 +100,19 @@ namespace WixToolset.Core
100 switch (child.Name.LocalName)
101 {
102 case "AdminExecuteSequence":
103 + this.ParseSequenceElement(child, SequenceTable.AdminExecuteSequence);
104 + break;
105 case "AdminUISequence":
106 + this.ParseSequenceElement(child, SequenceTable.AdminUISequence);
107 + break;
108 case "AdvertiseExecuteSequence":
109 + this.ParseSequenceElement(child, SequenceTable.AdvertiseExecuteSequence);
110 + break;
111 case "InstallExecuteSequence":
112 + this.ParseSequenceElement(child, SequenceTable.InstallExecuteSequence);
113 + break;
114 case "InstallUISequence":
107 - this.ParseSequenceElement(child, child.Name.LocalName);
115 + this.ParseSequenceElement(child, SequenceTable.InstallUISequence);
116 break;
117 case "AppId":
118 this.ParseAppIdElement(child, null, YesNoType.Yes, null, null, null);
@@ -208,10 +216,15 @@ namespace WixToolset.Core
216
217 if (!this.Core.EncounteredError)
218 {
211 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ModuleSignature);
212 - row.Set(0, this.activeName);
213 - row.Set(1, this.activeLanguage);
214 - row.Set(2, version);
219 + var tuple = new ModuleSignatureTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, this.activeName, this.activeLanguage))
220 + {
221 + ModuleID = this.activeName,
222 + Version = version
223 + };
224 +
225 + tuple.Set((int)ModuleSignatureTupleFields.Language, this.activeLanguage);
226 +
227 + this.Core.AddTuple(tuple);
228 }
229 }
230 finally
@@ -273,12 +286,17 @@ namespace WixToolset.Core
286
287 if (!this.Core.EncounteredError)
288 {
276 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ModuleDependency);
277 - row.Set(0, this.activeName);
278 - row.Set(1, this.activeLanguage);
279 - row.Set(2, requiredId);
280 - row.Set(3, requiredLanguage.ToString(CultureInfo.InvariantCulture));
281 - row.Set(4, requiredVersion);
289 + var tuple = new ModuleDependencyTuple(sourceLineNumbers)
290 + {
291 + ModuleID = this.activeName,
292 + RequiredID = requiredId,
293 + RequiredLanguage = requiredLanguage,
294 + RequiredVersion = requiredVersion
295 + };
296 +
297 + tuple.Set((int)ModuleDependencyTupleFields.ModuleLanguage, this.activeLanguage);
298 +
299 + this.Core.AddTuple(tuple);
300 }
301 }
302
@@ -351,13 +369,18 @@ namespace WixToolset.Core
369
370 if (!this.Core.EncounteredError)
371 {
354 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ModuleExclusion);
355 - row.Set(0, this.activeName);
356 - row.Set(1, this.activeLanguage);
357 - row.Set(2, excludedId);
358 - row.Set(3, excludedLanguageField);
359 - row.Set(4, excludedMinVersion);
360 - row.Set(5, excludedMaxVersion);
372 + var tuple = new ModuleExclusionTuple(sourceLineNumbers)
373 + {
374 + ModuleID = this.activeName,
375 + ExcludedID = excludedId,
376 + ExcludedMinVersion = excludedMinVersion,
377 + ExcludedMaxVersion = excludedMaxVersion
378 + };
379 +
380 + tuple.Set((int)ModuleExclusionTupleFields.ModuleLanguage, this.activeLanguage);
381 + tuple.Set((int)ModuleExclusionTupleFields.ExcludedLanguage, excludedLanguageField);
382 +
383 + this.Core.AddTuple(tuple);
384 }
385 }
386
@@ -548,11 +571,15 @@ namespace WixToolset.Core
571
572 if (!this.Core.EncounteredError)
573 {
551 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ModuleSubstitution);
552 - row.Set(0, table);
553 - row.Set(1, rowKeys);
554 - row.Set(2, column);
555 - row.Set(3, value);
574 + var tuple = new ModuleSubstitutionTuple(sourceLineNumbers)
575 + {
576 + Table = table,
577 + Row = rowKeys,
578 + Column = column,
579 + Value = value
580 + };
581 +
582 + this.Core.AddTuple(tuple);
583 }
584 }
585
@@ -599,8 +626,7 @@ namespace WixToolset.Core
626
627 if (!this.Core.EncounteredError)
628 {
602 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixSuppressModularization);
603 - row.Set(0, name);
629 + this.Core.AddTuple(new WixSuppressModularizationTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, name)));
630 }
631 }
632
@@ -642,8 +668,7 @@ namespace WixToolset.Core
668
669 if (!this.Core.EncounteredError)
670 {
645 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ModuleIgnoreTable);
646 - row.Set(0, id);
671 + this.Core.AddTuple(new ModuleIgnoreTableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, id)));
672 }
673 }
674 }
src/WixToolset.Core/Compiler_Patch.cs new
+655
@@ -0,0 +1,655 @@
1 +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2 +
3 +namespace WixToolset.Core
4 +{
5 + using System;
6 + using System.Collections.Generic;
7 + using System.Diagnostics;
8 + using System.Globalization;
9 + using System.Xml.Linq;
10 + using WixToolset.Data;
11 + using WixToolset.Data.Tuples;
12 + using WixToolset.Extensibility;
13 +
14 + /// <summary>
15 + /// Compiler of the WiX toolset.
16 + /// </summary>
17 + internal partial class Compiler : ICompiler
18 + {
19 + /// <summary>
20 + /// Parses an patch element.
21 + /// </summary>
22 + /// <param name="node">The element to parse.</param>
23 + private void ParsePatchElement(XElement node)
24 + {
25 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
26 + string patchId = null;
27 + var codepage = 0;
28 + ////bool versionMismatches = false;
29 + ////bool productMismatches = false;
30 + var allowRemoval = false;
31 + string classification = null;
32 + string clientPatchId = null;
33 + string description = null;
34 + string displayName = null;
35 + string comments = null;
36 + string manufacturer = null;
37 + var minorUpdateTargetRTM = YesNoType.NotSet;
38 + string moreInfoUrl = null;
39 + var optimizeCA = CompilerConstants.IntegerNotSet;
40 + var optimizedInstallMode = YesNoType.NotSet;
41 + string targetProductName = null;
42 + // string replaceGuids = String.Empty;
43 + var apiPatchingSymbolFlags = 0;
44 + var optimizePatchSizeForLargeFiles = false;
45 +
46 + foreach (var attrib in node.Attributes())
47 + {
48 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
49 + {
50 + switch (attrib.Name.LocalName)
51 + {
52 + case "Id":
53 + patchId = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, true);
54 + break;
55 + case "Codepage":
56 + codepage = this.Core.GetAttributeCodePageValue(sourceLineNumbers, attrib);
57 + break;
58 + case "AllowMajorVersionMismatches":
59 + ////versionMismatches = (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib));
60 + break;
61 + case "AllowProductCodeMismatches":
62 + ////productMismatches = (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib));
63 + break;
64 + case "AllowRemoval":
65 + allowRemoval = (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib));
66 + break;
67 + case "Classification":
68 + classification = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
69 + break;
70 + case "ClientPatchId":
71 + clientPatchId = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
72 + break;
73 + case "Description":
74 + description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
75 + break;
76 + case "DisplayName":
77 + displayName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
78 + break;
79 + case "Comments":
80 + comments = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
81 + break;
82 + case "Manufacturer":
83 + manufacturer = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
84 + break;
85 + case "MinorUpdateTargetRTM":
86 + minorUpdateTargetRTM = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
87 + break;
88 + case "MoreInfoURL":
89 + moreInfoUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
90 + break;
91 + case "OptimizedInstallMode":
92 + optimizedInstallMode = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
93 + break;
94 + case "TargetProductName":
95 + targetProductName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
96 + break;
97 + case "ApiPatchingSymbolNoImagehlpFlag":
98 + apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_NO_IMAGEHLP : 0;
99 + break;
100 + case "ApiPatchingSymbolNoFailuresFlag":
101 + apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_NO_FAILURES : 0;
102 + break;
103 + case "ApiPatchingSymbolUndecoratedTooFlag":
104 + apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_UNDECORATED_TOO : 0;
105 + break;
106 + case "OptimizePatchSizeForLargeFiles":
107 + optimizePatchSizeForLargeFiles = (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib));
108 + break;
109 + default:
110 + this.Core.UnexpectedAttribute(node, attrib);
111 + break;
112 + }
113 + }
114 + else
115 + {
116 + this.Core.ParseExtensionAttribute(node, attrib);
117 + }
118 + }
119 +
120 + if (patchId == null || patchId == "*")
121 + {
122 + // auto-generate at compile time, since this value gets dispersed to several locations
123 + patchId = Common.GenerateGuid();
124 + }
125 + this.activeName = patchId;
126 +
127 + if (null == this.activeName)
128 + {
129 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
130 + }
131 + if (null == classification)
132 + {
133 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Classification"));
134 + }
135 + if (null == clientPatchId)
136 + {
137 + clientPatchId = String.Concat("_", new Guid(patchId).ToString("N", CultureInfo.InvariantCulture).ToUpper(CultureInfo.InvariantCulture));
138 + }
139 + if (null == description)
140 + {
141 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Description"));
142 + }
143 + if (null == displayName)
144 + {
145 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DisplayName"));
146 + }
147 + if (null == manufacturer)
148 + {
149 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Manufacturer"));
150 + }
151 +
152 + this.Core.CreateActiveSection(this.activeName, SectionType.Patch, codepage, this.Context.CompilationId);
153 +
154 + foreach (var child in node.Elements())
155 + {
156 + if (CompilerCore.WixNamespace == child.Name.Namespace)
157 + {
158 + switch (child.Name.LocalName)
159 + {
160 + case "PatchInformation":
161 + this.ParsePatchInformationElement(child);
162 + break;
163 + case "Media":
164 + this.ParseMediaElement(child, patchId);
165 + break;
166 + case "OptimizeCustomActions":
167 + optimizeCA = this.ParseOptimizeCustomActionsElement(child);
168 + break;
169 + case "PatchFamily":
170 + this.ParsePatchFamilyElement(child, ComplexReferenceParentType.Patch, patchId);
171 + break;
172 + case "PatchFamilyRef":
173 + this.ParsePatchFamilyRefElement(child, ComplexReferenceParentType.Patch, patchId);
174 + break;
175 + case "PatchFamilyGroup":
176 + this.ParsePatchFamilyGroupElement(child, ComplexReferenceParentType.Patch, patchId);
177 + break;
178 + case "PatchFamilyGroupRef":
179 + this.ParsePatchFamilyGroupRefElement(child, ComplexReferenceParentType.Patch, patchId);
180 + break;
181 + case "PatchProperty":
182 + this.ParsePatchPropertyElement(child, true);
183 + break;
184 + case "TargetProductCodes":
185 + this.ParseTargetProductCodesElement(child);
186 + break;
187 + default:
188 + this.Core.UnexpectedElement(node, child);
189 + break;
190 + }
191 + }
192 + else
193 + {
194 + this.Core.ParseExtensionElement(node, child);
195 + }
196 + }
197 +
198 + if (!this.Core.EncounteredError)
199 + {
200 + var tuple = new WixPatchIdTuple(sourceLineNumbers)
201 + {
202 + ProductCode = patchId,
203 + ClientPatchId = clientPatchId,
204 + OptimizePatchSizeForLargeFiles = optimizePatchSizeForLargeFiles,
205 + ApiPatchingSymbolFlags = apiPatchingSymbolFlags
206 + };
207 +
208 + this.Core.AddTuple(tuple);
209 +
210 + if (allowRemoval)
211 + {
212 + this.AddMsiPatchMetadata(sourceLineNumbers, null, "AllowRemoval", allowRemoval ? "1" : "0");
213 + }
214 +
215 + if (null != classification)
216 + {
217 + this.AddMsiPatchMetadata(sourceLineNumbers, null, "Classification", classification);
218 + }
219 +
220 + // always generate the CreationTimeUTC
221 + {
222 + this.AddMsiPatchMetadata(sourceLineNumbers, null, "CreationTimeUTC", DateTime.UtcNow.ToString("MM-dd-yy HH:mm", CultureInfo.InvariantCulture));
223 + }
224 +
225 + if (null != description)
226 + {
227 + this.AddMsiPatchMetadata(sourceLineNumbers, null, "Description", description);
228 + }
229 +
230 + if (null != displayName)
231 + {
232 + this.AddMsiPatchMetadata(sourceLineNumbers, null, "DisplayName", displayName);
233 + }
234 +
235 + if (null != manufacturer)
236 + {
237 + this.AddMsiPatchMetadata(sourceLineNumbers, null, "ManufacturerName", manufacturer);
238 + }
239 +
240 + if (YesNoType.NotSet != minorUpdateTargetRTM)
241 + {
242 + this.AddMsiPatchMetadata(sourceLineNumbers, null, "MinorUpdateTargetRTM", YesNoType.Yes == minorUpdateTargetRTM ? "1" : "0");
243 + }
244 +
245 + if (null != moreInfoUrl)
246 + {
247 + this.AddMsiPatchMetadata(sourceLineNumbers, null, "MoreInfoURL", moreInfoUrl);
248 + }
249 +
250 + if (CompilerConstants.IntegerNotSet != optimizeCA)
251 + {
252 + this.AddMsiPatchMetadata(sourceLineNumbers, null, "OptimizeCA", optimizeCA.ToString(CultureInfo.InvariantCulture));
253 + }
254 +
255 + if (YesNoType.NotSet != optimizedInstallMode)
256 + {
257 + this.AddMsiPatchMetadata(sourceLineNumbers, null, "OptimizedInstallMode", YesNoType.Yes == optimizedInstallMode ? "1" : "0");
258 + }
259 +
260 + if (null != targetProductName)
261 + {
262 + this.AddMsiPatchMetadata(sourceLineNumbers, null, "TargetProductName", targetProductName);
263 + }
264 +
265 + if (null != comments)
266 + {
267 + this.AddMsiPatchMetadata(sourceLineNumbers, null, "Comments", comments);
268 + }
269 + }
270 + // TODO: do something with versionMismatches and productMismatches
271 + }
272 +
273 + /// <summary>
274 + /// Parses the OptimizeCustomActions element.
275 + /// </summary>
276 + /// <param name="node">Element to parse.</param>
277 + /// <returns>The combined integer value for callers to store as appropriate.</returns>
278 + private int ParseOptimizeCustomActionsElement(XElement node)
279 + {
280 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
281 + var optimizeCA = OptimizeCA.None;
282 +
283 + foreach (var attrib in node.Attributes())
284 + {
285 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
286 + {
287 + switch (attrib.Name.LocalName)
288 + {
289 + case "SkipAssignment":
290 + if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
291 + {
292 + optimizeCA |= OptimizeCA.SkipAssignment;
293 + }
294 + break;
295 + case "SkipImmediate":
296 + if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
297 + {
298 + optimizeCA |= OptimizeCA.SkipImmediate;
299 + }
300 + break;
301 + case "SkipDeferred":
302 + if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
303 + {
304 + optimizeCA |= OptimizeCA.SkipDeferred;
305 + }
306 + break;
307 + default:
308 + this.Core.UnexpectedAttribute(node, attrib);
309 + break;
310 + }
311 + }
312 + else
313 + {
314 + this.Core.ParseExtensionAttribute(node, attrib);
315 + }
316 + }
317 +
318 + return (int)optimizeCA;
319 + }
320 +
321 + /// <summary>
322 + /// Parses a PatchFamily element.
323 + /// </summary>
324 + /// <param name="node">The element to parse.</param>
325 + private void ParsePatchFamilyElement(XElement node, ComplexReferenceParentType parentType, string parentId)
326 + {
327 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
328 + Identifier id = null;
329 + string productCode = null;
330 + string version = null;
331 + var attributes = 0;
332 +
333 + foreach (var attrib in node.Attributes())
334 + {
335 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
336 + {
337 + switch (attrib.Name.LocalName)
338 + {
339 + case "Id":
340 + id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
341 + break;
342 + case "ProductCode":
343 + productCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
344 + break;
345 + case "Version":
346 + version = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
347 + break;
348 + case "Supersede":
349 + if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
350 + {
351 + attributes |= 0x1;
352 + }
353 + break;
354 + default:
355 + this.Core.UnexpectedAttribute(node, attrib);
356 + break;
357 + }
358 + }
359 + else
360 + {
361 + this.Core.ParseExtensionAttribute(node, attrib);
362 + }
363 + }
364 +
365 + if (null == id)
366 + {
367 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
368 + id = Identifier.Invalid;
369 + }
370 +
371 + if (String.IsNullOrEmpty(version))
372 + {
373 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version"));
374 + }
375 + else if (!CompilerCore.IsValidProductVersion(version))
376 + {
377 + this.Core.Write(ErrorMessages.InvalidProductVersion(sourceLineNumbers, version));
378 + }
379 +
380 + // find unexpected child elements
381 + foreach (var child in node.Elements())
382 + {
383 + if (CompilerCore.WixNamespace == child.Name.Namespace)
384 + {
385 + switch (child.Name.LocalName)
386 + {
387 + case "All":
388 + this.ParseAllElement(child);
389 + break;
390 + case "BinaryRef":
391 + this.ParsePatchChildRefElement(child, "Binary");
392 + break;
393 + case "ComponentRef":
394 + this.ParsePatchChildRefElement(child, "Component");
395 + break;
396 + case "CustomActionRef":
397 + this.ParsePatchChildRefElement(child, "CustomAction");
398 + break;
399 + case "DirectoryRef":
400 + this.ParsePatchChildRefElement(child, "Directory");
401 + break;
402 + case "DigitalCertificateRef":
403 + this.ParsePatchChildRefElement(child, "MsiDigitalCertificate");
404 + break;
405 + case "FeatureRef":
406 + this.ParsePatchChildRefElement(child, "Feature");
407 + break;
408 + case "IconRef":
409 + this.ParsePatchChildRefElement(child, "Icon");
410 + break;
411 + case "PropertyRef":
412 + this.ParsePatchChildRefElement(child, "Property");
413 + break;
414 + case "UIRef":
415 + this.ParsePatchChildRefElement(child, "WixUI");
416 + break;
417 + default:
418 + this.Core.UnexpectedElement(node, child);
419 + break;
420 + }
421 + }
422 + else
423 + {
424 + this.Core.ParseExtensionElement(node, child);
425 + }
426 + }
427 +
428 +
429 + if (!this.Core.EncounteredError)
430 + {
431 + var tuple = new MsiPatchSequenceTuple(sourceLineNumbers)
432 + {
433 + PatchFamily = id.Id,
434 + ProductCode = productCode,
435 + Sequence = version,
436 + Attributes = attributes
437 + };
438 +
439 + this.Core.AddTuple(tuple);
440 +
441 + if (ComplexReferenceParentType.Unknown != parentType)
442 + {
443 + this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.PatchFamily, id.Id, ComplexReferenceParentType.Patch == parentType);
444 + }
445 + }
446 + }
447 +
448 + /// <summary>
449 + /// Parses a PatchFamilyGroup element.
450 + /// </summary>
451 + /// <param name="node">Element to parse.</param>
452 + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
453 + private void ParsePatchFamilyGroupElement(XElement node, ComplexReferenceParentType parentType, string parentId)
454 + {
455 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
456 + Identifier id = null;
457 +
458 + foreach (var attrib in node.Attributes())
459 + {
460 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
461 + {
462 + switch (attrib.Name.LocalName)
463 + {
464 + case "Id":
465 + id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
466 + break;
467 + default:
468 + this.Core.UnexpectedAttribute(node, attrib);
469 + break;
470 + }
471 + }
472 + else
473 + {
474 + this.Core.ParseExtensionAttribute(node, attrib);
475 + }
476 + }
477 +
478 + if (null == id)
479 + {
480 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
481 + id = Identifier.Invalid;
482 + }
483 +
484 + foreach (var child in node.Elements())
485 + {
486 + if (CompilerCore.WixNamespace == child.Name.Namespace)
487 + {
488 + switch (child.Name.LocalName)
489 + {
490 + case "PatchFamily":
491 + this.ParsePatchFamilyElement(child, ComplexReferenceParentType.PatchFamilyGroup, id.Id);
492 + break;
493 + case "PatchFamilyRef":
494 + this.ParsePatchFamilyRefElement(child, ComplexReferenceParentType.PatchFamilyGroup, id.Id);
495 + break;
496 + case "PatchFamilyGroupRef":
497 + this.ParsePatchFamilyGroupRefElement(child, ComplexReferenceParentType.PatchFamilyGroup, id.Id);
498 + break;
499 + default:
500 + this.Core.UnexpectedElement(node, child);
501 + break;
502 + }
503 + }
504 + else
505 + {
506 + this.Core.ParseExtensionElement(node, child);
507 + }
508 + }
509 +
510 + if (!this.Core.EncounteredError)
511 + {
512 + this.Core.AddTuple(new WixPatchFamilyGroupTuple(sourceLineNumbers, id));
513 +
514 + //Add this PatchFamilyGroup and its parent in WixGroup.
515 + this.Core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.PatchFamilyGroup, id.Id);
516 + }
517 + }
518 +
519 + /// <summary>
520 + /// Parses a PatchFamilyGroup reference element.
521 + /// </summary>
522 + /// <param name="node">Element to parse.</param>
523 + /// <param name="parentType">The type of parent.</param>
524 + /// <param name="parentId">Identifier of parent element.</param>
525 + private void ParsePatchFamilyGroupRefElement(XElement node, ComplexReferenceParentType parentType, string parentId)
526 + {
527 + Debug.Assert(ComplexReferenceParentType.PatchFamilyGroup == parentType || ComplexReferenceParentType.Patch == parentType);
528 +
529 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
530 + string id = null;
531 +
532 + foreach (var attrib in node.Attributes())
533 + {
534 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
535 + {
536 + switch (attrib.Name.LocalName)
537 + {
538 + case "Id":
539 + id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
540 + this.Core.CreateSimpleReference(sourceLineNumbers, "WixPatchFamilyGroup", id);
541 + break;
542 + default:
543 + this.Core.UnexpectedAttribute(node, attrib);
544 + break;
545 + }
546 + }
547 + else
548 + {
549 + this.Core.ParseExtensionAttribute(node, attrib);
550 + }
551 + }
552 +
553 + if (null == id)
554 + {
555 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
556 + }
557 +
558 + this.Core.ParseForExtensionElements(node);
559 +
560 + if (!this.Core.EncounteredError)
561 + {
562 + this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.PatchFamilyGroup, id, true);
563 + }
564 + }
565 +
566 + /// <summary>
567 + /// Parses a TargetProductCodes element.
568 + /// </summary>
569 + /// <param name="node">The element to parse.</param>
570 + private void ParseTargetProductCodesElement(XElement node)
571 + {
572 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
573 + var replace = false;
574 + var targetProductCodes = new List<string>();
575 +
576 + foreach (var attrib in node.Attributes())
577 + {
578 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
579 + {
580 + switch (attrib.Name.LocalName)
581 + {
582 + case "Replace":
583 + replace = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
584 + break;
585 + default:
586 + this.Core.UnexpectedAttribute(node, attrib);
587 + break;
588 + }
589 + }
590 + else
591 + {
592 + this.Core.ParseExtensionAttribute(node, attrib);
593 + }
594 + }
595 +
596 + foreach (var child in node.Elements())
597 + {
598 + if (CompilerCore.WixNamespace == child.Name.Namespace)
599 + {
600 + switch (child.Name.LocalName)
601 + {
602 + case "TargetProductCode":
603 + var id = this.ParseTargetProductCodeElement(child);
604 + if (0 == String.CompareOrdinal("*", id))
605 + {
606 + this.Core.Write(ErrorMessages.IllegalAttributeValueWhenNested(sourceLineNumbers, child.Name.LocalName, "Id", id, node.Name.LocalName));
607 + }
608 + else
609 + {
610 + targetProductCodes.Add(id);
611 + }
612 + break;
613 + default:
614 + this.Core.UnexpectedElement(node, child);
615 + break;
616 + }
617 + }
618 + else
619 + {
620 + this.Core.ParseExtensionElement(node, child);
621 + }
622 + }
623 +
624 + if (!this.Core.EncounteredError)
625 + {
626 + // By default, target ProductCodes should be added.
627 + if (!replace)
628 + {
629 + this.Core.AddTuple(new WixPatchTargetTuple(sourceLineNumbers)
630 + {
631 + ProductCode = "*"
632 + });
633 + }
634 +
635 + foreach (var targetProductCode in targetProductCodes)
636 + {
637 + this.Core.AddTuple(new WixPatchTargetTuple(sourceLineNumbers)
638 + {
639 + ProductCode = targetProductCode
640 + });
641 + }
642 + }
643 + }
644 +
645 + private void AddMsiPatchMetadata(SourceLineNumber sourceLineNumbers, string company, string property, string value)
646 + {
647 + this.Core.AddTuple(new MsiPatchMetadataTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, company, property))
648 + {
649 + Company = company,
650 + Property = property,
651 + Value = value
652 + });
653 + }
654 + }
655 +}
src/WixToolset.Core/Compiler_PatchCreation.cs new
+1313
@@ -0,0 +1,1313 @@
1 +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2 +
3 +namespace WixToolset.Core
4 +{
5 + using System;
6 + using System.Collections.Generic;
7 + using System.Globalization;
8 + using System.Xml.Linq;
9 + using WixToolset.Data;
10 + using WixToolset.Data.Tuples;
11 + using WixToolset.Extensibility;
12 +
13 + /// <summary>
14 + /// Compiler of the WiX toolset.
15 + /// </summary>
16 + internal partial class Compiler : ICompiler
17 + {
18 + /// <summary>
19 + /// Parses a patch creation element.
20 + /// </summary>
21 + /// <param name="node">The element to parse.</param>
22 + private void ParsePatchCreationElement(XElement node)
23 + {
24 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
25 + var clean = true; // Default is to clean
26 + var codepage = 0;
27 + string outputPath = null;
28 + var productMismatches = false;
29 + var replaceGuids = String.Empty;
30 + string sourceList = null;
31 + string symbolFlags = null;
32 + var targetProducts = String.Empty;
33 + var versionMismatches = false;
34 + var wholeFiles = false;
35 +
36 + foreach (var attrib in node.Attributes())
37 + {
38 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
39 + {
40 + switch (attrib.Name.LocalName)
41 + {
42 + case "Id":
43 + this.activeName = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
44 + break;
45 + case "AllowMajorVersionMismatches":
46 + versionMismatches = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
47 + break;
48 + case "AllowProductCodeMismatches":
49 + productMismatches = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
50 + break;
51 + case "CleanWorkingFolder":
52 + clean = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
53 + break;
54 + case "Codepage":
55 + codepage = this.Core.GetAttributeCodePageValue(sourceLineNumbers, attrib);
56 + break;
57 + case "OutputPath":
58 + outputPath = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
59 + break;
60 + case "SourceList":
61 + sourceList = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
62 + break;
63 + case "SymbolFlags":
64 + symbolFlags = String.Format(CultureInfo.InvariantCulture, "0x{0:x8}", this.Core.GetAttributeLongValue(sourceLineNumbers, attrib, 0, UInt32.MaxValue));
65 + break;
66 + case "WholeFilesOnly":
67 + wholeFiles = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
68 + break;
69 + default:
70 + this.Core.UnexpectedAttribute(node, attrib);
71 + break;
72 + }
73 + }
74 + else
75 + {
76 + this.Core.ParseExtensionAttribute(node, attrib);
77 + }
78 + }
79 +
80 + if (null == this.activeName)
81 + {
82 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
83 + }
84 +
85 + this.Core.CreateActiveSection(this.activeName, SectionType.PatchCreation, codepage, this.Context.CompilationId);
86 +
87 + foreach (var child in node.Elements())
88 + {
89 + if (CompilerCore.WixNamespace == child.Name.Namespace)
90 + {
91 + switch (child.Name.LocalName)
92 + {
93 + case "Family":
94 + this.ParseFamilyElement(child);
95 + break;
96 + case "PatchInformation":
97 + this.ParsePatchInformationElement(child);
98 + break;
99 + case "PatchMetadata":
100 + this.ParsePatchMetadataElement(child);
101 + break;
102 + case "PatchProperty":
103 + this.ParsePatchPropertyElement(child, false);
104 + break;
105 + case "PatchSequence":
106 + this.ParsePatchSequenceElement(child);
107 + break;
108 + case "ReplacePatch":
109 + replaceGuids = String.Concat(replaceGuids, this.ParseReplacePatchElement(child));
110 + break;
111 + case "TargetProductCode":
112 + var targetProduct = this.ParseTargetProductCodeElement(child);
113 + if (0 < targetProducts.Length)
114 + {
115 + targetProducts = String.Concat(targetProducts, ";");
116 + }
117 + targetProducts = String.Concat(targetProducts, targetProduct);
118 + break;
119 + default:
120 + this.Core.UnexpectedElement(node, child);
121 + break;
122 + }
123 + }
124 + else
125 + {
126 + this.Core.ParseExtensionElement(node, child);
127 + }
128 + }
129 +
130 + this.AddPrivateProperty(sourceLineNumbers, "PatchGUID", this.activeName);
131 + this.AddPrivateProperty(sourceLineNumbers, "AllowProductCodeMismatches", productMismatches ? "1" : "0");
132 + this.AddPrivateProperty(sourceLineNumbers, "AllowProductVersionMajorMismatches", versionMismatches ? "1" : "0");
133 + this.AddPrivateProperty(sourceLineNumbers, "DontRemoveTempFolderWhenFinished", clean ? "0" : "1");
134 + this.AddPrivateProperty(sourceLineNumbers, "IncludeWholeFilesOnly", wholeFiles ? "1" : "0");
135 +
136 + if (null != symbolFlags)
137 + {
138 + this.AddPrivateProperty(sourceLineNumbers, "ApiPatchingSymbolFlags", symbolFlags);
139 + }
140 +
141 + if (0 < replaceGuids.Length)
142 + {
143 + this.AddPrivateProperty(sourceLineNumbers, "ListOfPatchGUIDsToReplace", replaceGuids);
144 + }
145 +
146 + if (0 < targetProducts.Length)
147 + {
148 + this.AddPrivateProperty(sourceLineNumbers, "ListOfTargetProductCodes", targetProducts);
149 + }
150 +
151 + if (null != outputPath)
152 + {
153 + this.AddPrivateProperty(sourceLineNumbers, "PatchOutputPath", outputPath);
154 + }
155 +
156 + if (null != sourceList)
157 + {
158 + this.AddPrivateProperty(sourceLineNumbers, "PatchSourceList", sourceList);
159 + }
160 + }
161 +
162 + /// <summary>
163 + /// Parses a family element.
164 + /// </summary>
165 + /// <param name="node">The element to parse.</param>
166 + private void ParseFamilyElement(XElement node)
167 + {
168 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
169 + var diskId = CompilerConstants.IntegerNotSet;
170 + string diskPrompt = null;
171 + string mediaSrcProp = null;
172 + string name = null;
173 + var sequenceStart = CompilerConstants.IntegerNotSet;
174 + string volumeLabel = null;
175 +
176 + foreach (var attrib in node.Attributes())
177 + {
178 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
179 + {
180 + switch (attrib.Name.LocalName)
181 + {
182 + case "DiskId":
183 + diskId = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, Int16.MaxValue);
184 + break;
185 + case "DiskPrompt":
186 + diskPrompt = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
187 + break;
188 + case "MediaSrcProp":
189 + mediaSrcProp = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
190 + break;
191 + case "Name":
192 + name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
193 + break;
194 + case "SequenceStart":
195 + sequenceStart = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, Int32.MaxValue);
196 + break;
197 + case "VolumeLabel":
198 + volumeLabel = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
199 + break;
200 + default:
201 + this.Core.UnexpectedAttribute(node, attrib);
202 + break;
203 + }
204 + }
205 + else
206 + {
207 + this.Core.ParseExtensionAttribute(node, attrib);
208 + }
209 + }
210 +
211 + if (null == name)
212 + {
213 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
214 + }
215 + else if (0 < name.Length)
216 + {
217 + if (8 < name.Length) // check the length
218 + {
219 + this.Core.Write(ErrorMessages.FamilyNameTooLong(sourceLineNumbers, node.Name.LocalName, "Name", name, name.Length));
220 + }
221 + else // check for illegal characters
222 + {
223 + foreach (var character in name)
224 + {
225 + if (!Char.IsLetterOrDigit(character) && '_' != character)
226 + {
227 + this.Core.Write(ErrorMessages.IllegalFamilyName(sourceLineNumbers, node.Name.LocalName, "Name", name));
228 + }
229 + }
230 + }
231 + }
232 +
233 + foreach (var child in node.Elements())
234 + {
235 + if (CompilerCore.WixNamespace == child.Name.Namespace)
236 + {
237 + switch (child.Name.LocalName)
238 + {
239 + case "UpgradeImage":
240 + this.ParseUpgradeImageElement(child, name);
241 + break;
242 + case "ExternalFile":
243 + this.ParseExternalFileElement(child, name);
244 + break;
245 + case "ProtectFile":
246 + this.ParseProtectFileElement(child, name);
247 + break;
248 + default:
249 + this.Core.UnexpectedElement(node, child);
250 + break;
251 + }
252 + }
253 + else
254 + {
255 + this.Core.ParseExtensionElement(node, child);
256 + }
257 + }
258 +
259 + if (!this.Core.EncounteredError)
260 + {
261 + var tuple = new ImageFamiliesTuple(sourceLineNumbers)
262 + {
263 + Family = name,
264 + MediaSrcPropName = mediaSrcProp,
265 + DiskPrompt = diskPrompt,
266 + VolumeLabel = volumeLabel
267 + };
268 +
269 + if (CompilerConstants.IntegerNotSet != diskId)
270 + {
271 + tuple.MediaDiskId = diskId;
272 + }
273 +
274 + if (CompilerConstants.IntegerNotSet != sequenceStart)
275 + {
276 + tuple.FileSequenceStart = sequenceStart;
277 + }
278 +
279 + this.Core.AddTuple(tuple);
280 + }
281 + }
282 +
283 + /// <summary>
284 + /// Parses an upgrade image element.
285 + /// </summary>
286 + /// <param name="node">The element to parse.</param>
287 + /// <param name="family">The family for this element.</param>
288 + private void ParseUpgradeImageElement(XElement node, string family)
289 + {
290 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
291 + string sourceFile = null;
292 + string sourcePatch = null;
293 + var symbols = new List<string>();
294 + string upgrade = null;
295 +
296 + foreach (var attrib in node.Attributes())
297 + {
298 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
299 + {
300 + switch (attrib.Name.LocalName)
301 + {
302 + case "Id":
303 + upgrade = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
304 + if (13 < upgrade.Length)
305 + {
306 + this.Core.Write(ErrorMessages.IdentifierTooLongError(sourceLineNumbers, node.Name.LocalName, "Id", upgrade, 13));
307 + }
308 + break;
309 + case "SourceFile":
310 + case "src":
311 + if (null != sourceFile)
312 + {
313 + this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "src", "SourceFile"));
314 + }
315 +
316 + if ("src" == attrib.Name.LocalName)
317 + {
318 + this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "SourceFile"));
319 + }
320 + sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
321 + break;
322 + case "SourcePatch":
323 + case "srcPatch":
324 + if (null != sourcePatch)
325 + {
326 + this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "srcPatch", "SourcePatch"));
327 + }
328 +
329 + if ("srcPatch" == attrib.Name.LocalName)
330 + {
331 + this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "SourcePatch"));
332 + }
333 + sourcePatch = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
334 + break;
335 + default:
336 + this.Core.UnexpectedAttribute(node, attrib);
337 + break;
338 + }
339 + }
340 + else
341 + {
342 + this.Core.ParseExtensionAttribute(node, attrib);
343 + }
344 + }
345 +
346 + if (null == upgrade)
347 + {
348 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
349 + }
350 +
351 + if (null == sourceFile)
352 + {
353 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile"));
354 + }
355 +
356 + foreach (var child in node.Elements())
357 + {
358 + if (CompilerCore.WixNamespace == child.Name.Namespace)
359 + {
360 + switch (child.Name.LocalName)
361 + {
362 + case "SymbolPath":
363 + symbols.Add(this.ParseSymbolPathElement(child));
364 + break;
365 + case "TargetImage":
366 + this.ParseTargetImageElement(child, upgrade, family);
367 + break;
368 + case "UpgradeFile":
369 + this.ParseUpgradeFileElement(child, upgrade);
370 + break;
371 + default:
372 + this.Core.UnexpectedElement(node, child);
373 + break;
374 + }
375 + }
376 + else
377 + {
378 + this.Core.ParseExtensionElement(node, child);
379 + }
380 + }
381 +
382 + if (!this.Core.EncounteredError)
383 + {
384 + this.Core.AddTuple(new UpgradedImagesTuple(sourceLineNumbers)
385 + {
386 + Upgraded = upgrade,
387 + MsiPath = sourceFile,
388 + PatchMsiPath = sourcePatch,
389 + SymbolPaths = String.Join(";", symbols),
390 + Family = family
391 + });
392 + }
393 + }
394 +
395 + /// <summary>
396 + /// Parses an upgrade file element.
397 + /// </summary>
398 + /// <param name="node">The element to parse.</param>
399 + /// <param name="upgrade">The upgrade key for this element.</param>
400 + private void ParseUpgradeFileElement(XElement node, string upgrade)
401 + {
402 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
403 + var allowIgnoreOnError = false;
404 + string file = null;
405 + var ignore = false;
406 + var symbols = new List<string>();
407 + var wholeFile = false;
408 +
409 + foreach (var attrib in node.Attributes())
410 + {
411 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
412 + {
413 + switch (attrib.Name.LocalName)
414 + {
415 + case "AllowIgnoreOnError":
416 + allowIgnoreOnError = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
417 + break;
418 + case "File":
419 + file = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
420 + break;
421 + case "Ignore":
422 + ignore = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
423 + break;
424 + case "WholeFile":
425 + wholeFile = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
426 + break;
427 + default:
428 + this.Core.UnexpectedAttribute(node, attrib);
429 + break;
430 + }
431 + }
432 + else
433 + {
434 + this.Core.ParseExtensionAttribute(node, attrib);
435 + }
436 + }
437 +
438 + if (null == file)
439 + {
440 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "File"));
441 + }
442 +
443 + foreach (var child in node.Elements())
444 + {
445 + if (CompilerCore.WixNamespace == child.Name.Namespace)
446 + {
447 + switch (child.Name.LocalName)
448 + {
449 + case "SymbolPath":
450 + symbols.Add(this.ParseSymbolPathElement(child));
451 + break;
452 + default:
453 + this.Core.UnexpectedElement(node, child);
454 + break;
455 + }
456 + }
457 + else
458 + {
459 + this.Core.ParseExtensionElement(node, child);
460 + }
461 + }
462 +
463 + if (!this.Core.EncounteredError)
464 + {
465 + if (ignore)
466 + {
467 + this.Core.AddTuple(new UpgradedFilesToIgnoreTuple(sourceLineNumbers)
468 + {
469 + Upgraded = upgrade,
470 + FTK = file
471 + });
472 + }
473 + else
474 + {
475 + this.Core.AddTuple(new UpgradedFiles_OptionalDataTuple(sourceLineNumbers)
476 + {
477 + Upgraded = upgrade,
478 + FTK = file,
479 + SymbolPaths = String.Join(";", symbols),
480 + AllowIgnoreOnPatchError = allowIgnoreOnError,
481 + IncludeWholeFile = wholeFile
482 + });
483 + }
484 + }
485 + }
486 +
487 + /// <summary>
488 + /// Parses a target image element.
489 + /// </summary>
490 + /// <param name="node">The element to parse.</param>
491 + /// <param name="upgrade">The upgrade key for this element.</param>
492 + /// <param name="family">The family key for this element.</param>
493 + private void ParseTargetImageElement(XElement node, string upgrade, string family)
494 + {
495 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
496 + var ignore = false;
497 + var order = CompilerConstants.IntegerNotSet;
498 + string sourceFile = null;
499 + string symbols = null;
500 + string target = null;
501 + string validation = null;
502 +
503 + foreach (var attrib in node.Attributes())
504 + {
505 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
506 + {
507 + switch (attrib.Name.LocalName)
508 + {
509 + case "Id":
510 + target = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
511 + if (target.Length > 13)
512 + {
513 + this.Core.Write(ErrorMessages.IdentifierTooLongError(sourceLineNumbers, node.Name.LocalName, "Id", target, 13));
514 + }
515 + break;
516 + case "IgnoreMissingFiles":
517 + ignore = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
518 + break;
519 + case "Order":
520 + order = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, Int32.MinValue + 2, Int32.MaxValue);
521 + break;
522 + case "SourceFile":
523 + case "src":
524 + if (null != sourceFile)
525 + {
526 + this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "src", "SourceFile"));
527 + }
528 +
529 + if ("src" == attrib.Name.LocalName)
530 + {
531 + this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "SourceFile"));
532 + }
533 + sourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
534 + break;
535 + case "Validation":
536 + validation = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
537 + break;
538 + default:
539 + this.Core.UnexpectedAttribute(node, attrib);
540 + break;
541 + }
542 + }
543 + else
544 + {
545 + this.Core.ParseExtensionAttribute(node, attrib);
546 + }
547 + }
548 +
549 + if (null == target)
550 + {
551 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
552 + }
553 +
554 + if (null == sourceFile)
555 + {
556 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SourceFile"));
557 + }
558 +
559 + if (CompilerConstants.IntegerNotSet == order)
560 + {
561 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Order"));
562 + }
563 +
564 + foreach (var child in node.Elements())
565 + {
566 + if (CompilerCore.WixNamespace == child.Name.Namespace)
567 + {
568 + switch (child.Name.LocalName)
569 + {
570 + case "SymbolPath":
571 + if (null != symbols)
572 + {
573 + symbols = String.Concat(symbols, ";", this.ParseSymbolPathElement(child));
574 + }
575 + else
576 + {
577 + symbols = this.ParseSymbolPathElement(child);
578 + }
579 + break;
580 + case "TargetFile":
581 + this.ParseTargetFileElement(child, target, family);
582 + break;
583 + default:
584 + this.Core.UnexpectedElement(node, child);
585 + break;
586 + }
587 + }
588 + else
589 + {
590 + this.Core.ParseExtensionElement(node, child);
591 + }
592 + }
593 +
594 + if (!this.Core.EncounteredError)
595 + {
596 + this.Core.AddTuple(new TargetImagesTuple(sourceLineNumbers)
597 + {
598 + Target = target,
599 + MsiPath = sourceFile,
600 + SymbolPaths = symbols,
601 + Upgraded = upgrade,
602 + Order = order,
603 + ProductValidateFlags = validation,
604 + IgnoreMissingSrcFiles = ignore
605 + });
606 + }
607 + }
608 +
609 + /// <summary>
610 + /// Parses an upgrade file element.
611 + /// </summary>
612 + /// <param name="node">The element to parse.</param>
613 + /// <param name="target">The upgrade key for this element.</param>
614 + /// <param name="family">The family key for this element.</param>
615 + private void ParseTargetFileElement(XElement node, string target, string family)
616 + {
617 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
618 + string file = null;
619 + string ignoreLengths = null;
620 + string ignoreOffsets = null;
621 + string protectLengths = null;
622 + string protectOffsets = null;
623 + string symbols = null;
624 +
625 + foreach (var attrib in node.Attributes())
626 + {
627 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
628 + {
629 + switch (attrib.Name.LocalName)
630 + {
631 + case "Id":
632 + file = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
633 + break;
634 + default:
635 + this.Core.UnexpectedAttribute(node, attrib);
636 + break;
637 + }
638 + }
639 + else
640 + {
641 + this.Core.ParseExtensionAttribute(node, attrib);
642 + }
643 + }
644 +
645 + if (null == file)
646 + {
647 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
648 + }
649 +
650 + foreach (var child in node.Elements())
651 + {
652 + if (CompilerCore.WixNamespace == child.Name.Namespace)
653 + {
654 + switch (child.Name.LocalName)
655 + {
656 + case "IgnoreRange":
657 + this.ParseRangeElement(child, ref ignoreOffsets, ref ignoreLengths);
658 + break;
659 + case "ProtectRange":
660 + this.ParseRangeElement(child, ref protectOffsets, ref protectLengths);
661 + break;
662 + case "SymbolPath":
663 + symbols = this.ParseSymbolPathElement(child);
664 + break;
665 + default:
666 + this.Core.UnexpectedElement(node, child);
667 + break;
668 + }
669 + }
670 + else
671 + {
672 + this.Core.ParseExtensionElement(node, child);
673 + }
674 + }
675 +
676 + if (!this.Core.EncounteredError)
677 + {
678 + var tuple = new TargetFiles_OptionalDataTuple(sourceLineNumbers)
679 + {
680 + Target = target,
681 + FTK = file,
682 + SymbolPaths = symbols,
683 + IgnoreOffsets = ignoreOffsets,
684 + IgnoreLengths = ignoreLengths
685 + };
686 +
687 + this.Core.AddTuple(tuple);
688 +
689 + if (null != protectOffsets)
690 + {
691 + tuple.RetainOffsets = protectOffsets;
692 +
693 + this.Core.AddTuple(new FamilyFileRangesTuple(sourceLineNumbers)
694 + {
695 + Family = family,
696 + FTK = file,
697 + RetainOffsets = protectOffsets,
698 + RetainLengths = protectLengths
699 + });
700 + }
701 + }
702 + }
703 +
704 + /// <summary>
705 + /// Parses an external file element.
706 + /// </summary>
707 + /// <param name="node">The element to parse.</param>
708 + /// <param name="family">The family for this element.</param>
709 + private void ParseExternalFileElement(XElement node, string family)
710 + {
711 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
712 + string file = null;
713 + string ignoreLengths = null;
714 + string ignoreOffsets = null;
715 + var order = CompilerConstants.IntegerNotSet;
716 + string protectLengths = null;
717 + string protectOffsets = null;
718 + string source = null;
719 + string symbols = null;
720 +
721 + foreach (var attrib in node.Attributes())
722 + {
723 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
724 + {
725 + switch (attrib.Name.LocalName)
726 + {
727 + case "File":
728 + file = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
729 + break;
730 + case "Order":
731 + order = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, Int32.MinValue + 2, Int32.MaxValue);
732 + break;
733 + case "Source":
734 + case "src":
735 + if (null != source)
736 + {
737 + this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "src", "Source"));
738 + }
739 +
740 + if ("src" == attrib.Name.LocalName)
741 + {
742 + this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Source"));
743 + }
744 + source = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
745 + break;
746 + default:
747 + this.Core.UnexpectedAttribute(node, attrib);
748 + break;
749 + }
750 + }
751 + else
752 + {
753 + this.Core.ParseExtensionAttribute(node, attrib);
754 + }
755 + }
756 +
757 + if (null == file)
758 + {
759 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "File"));
760 + }
761 +
762 + if (null == source)
763 + {
764 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Source"));
765 + }
766 +
767 + if (CompilerConstants.IntegerNotSet == order)
768 + {
769 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Order"));
770 + }
771 +
772 + foreach (var child in node.Elements())
773 + {
774 + if (CompilerCore.WixNamespace == child.Name.Namespace)
775 + {
776 + switch (child.Name.LocalName)
777 + {
778 + case "IgnoreRange":
779 + this.ParseRangeElement(child, ref ignoreOffsets, ref ignoreLengths);
780 + break;
781 + case "ProtectRange":
782 + this.ParseRangeElement(child, ref protectOffsets, ref protectLengths);
783 + break;
784 + case "SymbolPath":
785 + symbols = this.ParseSymbolPathElement(child);
786 + break;
787 + default:
788 + this.Core.UnexpectedElement(node, child);
789 + break;
790 + }
791 + }
792 + else
793 + {
794 + this.Core.ParseExtensionElement(node, child);
795 + }
796 + }
797 +
798 + if (!this.Core.EncounteredError)
799 + {
800 + var tuple = new ExternalFilesTuple(sourceLineNumbers)
801 + {
802 + Family = family,
803 + FTK = file,
804 + FilePath = source,
805 + SymbolPaths = symbols,
806 + IgnoreOffsets = ignoreOffsets,
807 + IgnoreLengths = ignoreLengths
808 + };
809 +
810 + if (null != protectOffsets)
811 + {
812 + tuple.RetainOffsets = protectOffsets;
813 + }
814 +
815 + if (CompilerConstants.IntegerNotSet != order)
816 + {
817 + tuple.Order = order;
818 + }
819 +
820 + this.Core.AddTuple(tuple);
821 +
822 + if (null != protectOffsets)
823 + {
824 + this.Core.AddTuple(new FamilyFileRangesTuple(sourceLineNumbers)
825 + {
826 + Family = family,
827 + FTK = file,
828 + RetainOffsets = protectOffsets,
829 + RetainLengths = protectLengths
830 + });
831 + }
832 + }
833 + }
834 +
835 + /// <summary>
836 + /// Parses a protect file element.
837 + /// </summary>
838 + /// <param name="node">The element to parse.</param>
839 + /// <param name="family">The family for this element.</param>
840 + private void ParseProtectFileElement(XElement node, string family)
841 + {
842 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
843 + string file = null;
844 + string protectLengths = null;
845 + string protectOffsets = null;
846 +
847 + foreach (var attrib in node.Attributes())
848 + {
849 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
850 + {
851 + switch (attrib.Name.LocalName)
852 + {
853 + case "File":
854 + file = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
855 + break;
856 + default:
857 + this.Core.UnexpectedAttribute(node, attrib);
858 + break;
859 + }
860 + }
861 + else
862 + {
863 + this.Core.ParseExtensionAttribute(node, attrib);
864 + }
865 + }
866 +
867 + if (null == file)
868 + {
869 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "File"));
870 + }
871 +
872 + foreach (var child in node.Elements())
873 + {
874 + if (CompilerCore.WixNamespace == child.Name.Namespace)
875 + {
876 + switch (child.Name.LocalName)
877 + {
878 + case "ProtectRange":
879 + this.ParseRangeElement(child, ref protectOffsets, ref protectLengths);
880 + break;
881 + default:
882 + this.Core.UnexpectedElement(node, child);
883 + break;
884 + }
885 + }
886 + else
887 + {
888 + this.Core.ParseExtensionElement(node, child);
889 + }
890 + }
891 +
892 + if (null == protectOffsets || null == protectLengths)
893 + {
894 + this.Core.Write(ErrorMessages.ExpectedElement(sourceLineNumbers, node.Name.LocalName, "ProtectRange"));
895 + }
896 +
897 + if (!this.Core.EncounteredError)
898 + {
899 + this.Core.AddTuple(new FamilyFileRangesTuple(sourceLineNumbers)
900 + {
901 + Family = family,
902 + FTK = file,
903 + RetainOffsets = protectOffsets,
904 + RetainLengths = protectLengths
905 + });
906 + }
907 + }
908 +
909 + /// <summary>
910 + /// Parses a range element (ProtectRange, IgnoreRange, etc).
911 + /// </summary>
912 + /// <param name="node">The element to parse.</param>
913 + /// <param name="offsets">Reference to the offsets string.</param>
914 + /// <param name="lengths">Reference to the lengths string.</param>
915 + private void ParseRangeElement(XElement node, ref string offsets, ref string lengths)
916 + {
917 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
918 + string length = null;
919 + string offset = null;
920 +
921 + foreach (var attrib in node.Attributes())
922 + {
923 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
924 + {
925 + switch (attrib.Name.LocalName)
926 + {
927 + case "Length":
928 + length = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
929 + break;
930 + case "Offset":
931 + offset = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
932 + break;
933 + default:
934 + this.Core.UnexpectedAttribute(node, attrib);
935 + break;
936 + }
937 + }
938 + else
939 + {
940 + this.Core.ParseExtensionAttribute(node, attrib);
941 + }
942 + }
943 +
944 + if (null == length)
945 + {
946 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Length"));
947 + }
948 +
949 + if (null == offset)
950 + {
951 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Offset"));
952 + }
953 +
954 + this.Core.ParseForExtensionElements(node);
955 +
956 + if (null != lengths)
957 + {
958 + lengths = String.Concat(lengths, ",", length);
959 + }
960 + else
961 + {
962 + lengths = length;
963 + }
964 +
965 + if (null != offsets)
966 + {
967 + offsets = String.Concat(offsets, ",", offset);
968 + }
969 + else
970 + {
971 + offsets = offset;
972 + }
973 + }
974 +
975 + /// <summary>
976 + /// Parses a patch metadata element.
977 + /// </summary>
978 + /// <param name="node">Element to parse.</param>
979 + private void ParsePatchMetadataElement(XElement node)
980 + {
981 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
982 + var allowRemoval = YesNoType.NotSet;
983 + string classification = null;
984 + string creationTimeUtc = null;
985 + string description = null;
986 + string displayName = null;
987 + string manufacturerName = null;
988 + string minorUpdateTargetRTM = null;
989 + string moreInfoUrl = null;
990 + var optimizeCA = CompilerConstants.IntegerNotSet;
991 + var optimizedInstallMode = YesNoType.NotSet;
992 + string targetProductName = null;
993 +
994 + foreach (var attrib in node.Attributes())
995 + {
996 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
997 + {
998 + switch (attrib.Name.LocalName)
999 + {
1000 + case "AllowRemoval":
1001 + allowRemoval = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
1002 + break;
1003 + case "Classification":
1004 + classification = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1005 + break;
1006 + case "CreationTimeUTC":
1007 + creationTimeUtc = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1008 + break;
1009 + case "Description":
1010 + description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1011 + break;
1012 + case "DisplayName":
1013 + displayName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1014 + break;
1015 + case "ManufacturerName":
1016 + manufacturerName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1017 + break;
1018 + case "MinorUpdateTargetRTM":
1019 + minorUpdateTargetRTM = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1020 + break;
1021 + case "MoreInfoURL":
1022 + moreInfoUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1023 + break;
1024 + case "OptimizedInstallMode":
1025 + optimizedInstallMode = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
1026 + break;
1027 + case "TargetProductName":
1028 + targetProductName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1029 + break;
1030 + default:
1031 + this.Core.UnexpectedAttribute(node, attrib);
1032 + break;
1033 + }
1034 + }
1035 + else
1036 + {
1037 + this.Core.ParseExtensionAttribute(node, attrib);
1038 + }
1039 + }
1040 +
1041 + if (YesNoType.NotSet == allowRemoval)
1042 + {
1043 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "AllowRemoval"));
1044 + }
1045 +
1046 + if (null == classification)
1047 + {
1048 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Classification"));
1049 + }
1050 +
1051 + if (null == description)
1052 + {
1053 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Description"));
1054 + }
1055 +
1056 + if (null == displayName)
1057 + {
1058 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DisplayName"));
1059 + }
1060 +
1061 + if (null == manufacturerName)
1062 + {
1063 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ManufacturerName"));
1064 + }
1065 +
1066 + if (null == moreInfoUrl)
1067 + {
1068 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "MoreInfoURL"));
1069 + }
1070 +
1071 + if (null == targetProductName)
1072 + {
1073 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "TargetProductName"));
1074 + }
1075 +
1076 + foreach (var child in node.Elements())
1077 + {
1078 + if (CompilerCore.WixNamespace == child.Name.Namespace)
1079 + {
1080 + switch (child.Name.LocalName)
1081 + {
1082 + case "CustomProperty":
1083 + this.ParseCustomPropertyElement(child);
1084 + break;
1085 + case "OptimizeCustomActions":
1086 + optimizeCA = this.ParseOptimizeCustomActionsElement(child);
1087 + break;
1088 + default:
1089 + this.Core.UnexpectedElement(node, child);
1090 + break;
1091 + }
1092 + }
1093 + else
1094 + {
1095 + this.Core.ParseExtensionElement(node, child);
1096 + }
1097 + }
1098 +
1099 + if (!this.Core.EncounteredError)
1100 + {
1101 + if (YesNoType.NotSet != allowRemoval)
1102 + {
1103 + this.AddPatchMetadata(sourceLineNumbers, null, "AllowRemoval", YesNoType.Yes == allowRemoval ? "1" : "0");
1104 + }
1105 +
1106 + if (null != classification)
1107 + {
1108 + this.AddPatchMetadata(sourceLineNumbers, null, "Classification", classification);
1109 + }
1110 +
1111 + if (null != creationTimeUtc)
1112 + {
1113 + this.AddPatchMetadata(sourceLineNumbers, null, "CreationTimeUTC", creationTimeUtc);
1114 + }
1115 +
1116 + if (null != description)
1117 + {
1118 + this.AddPatchMetadata(sourceLineNumbers, null, "Description", description);
1119 + }
1120 +
1121 + if (null != displayName)
1122 + {
1123 + this.AddPatchMetadata(sourceLineNumbers, null, "DisplayName", displayName);
1124 + }
1125 +
1126 + if (null != manufacturerName)
1127 + {
1128 + this.AddPatchMetadata(sourceLineNumbers, null, "ManufacturerName", manufacturerName);
1129 + }
1130 +
1131 + if (null != minorUpdateTargetRTM)
1132 + {
1133 + this.AddPatchMetadata(sourceLineNumbers, null, "MinorUpdateTargetRTM", minorUpdateTargetRTM);
1134 + }
1135 +
1136 + if (null != moreInfoUrl)
1137 + {
1138 + this.AddPatchMetadata(sourceLineNumbers, null, "MoreInfoURL", moreInfoUrl);
1139 + }
1140 +
1141 + if (CompilerConstants.IntegerNotSet != optimizeCA)
1142 + {
1143 + this.AddPatchMetadata(sourceLineNumbers, null, "OptimizeCA", optimizeCA.ToString(CultureInfo.InvariantCulture));
1144 + }
1145 +
1146 + if (YesNoType.NotSet != optimizedInstallMode)
1147 + {
1148 + this.AddPatchMetadata(sourceLineNumbers, null, "OptimizedInstallMode", YesNoType.Yes == optimizedInstallMode ? "1" : "0");
1149 + }
1150 +
1151 + if (null != targetProductName)
1152 + {
1153 + this.AddPatchMetadata(sourceLineNumbers, null, "TargetProductName", targetProductName);
1154 + }
1155 + }
1156 + }
1157 +
1158 + /// <summary>
1159 + /// Parses a custom property element for the PatchMetadata table.
1160 + /// </summary>
1161 + /// <param name="node">Element to parse.</param>
1162 + private void ParseCustomPropertyElement(XElement node)
1163 + {
1164 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1165 + string company = null;
1166 + string property = null;
1167 + string value = null;
1168 +
1169 + foreach (var attrib in node.Attributes())
1170 + {
1171 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
1172 + {
1173 + switch (attrib.Name.LocalName)
1174 + {
1175 + case "Company":
1176 + company = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1177 + break;
1178 + case "Property":
1179 + property = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1180 + break;
1181 + case "Value":
1182 + value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1183 + break;
1184 + default:
1185 + this.Core.UnexpectedAttribute(node, attrib);
1186 + break;
1187 + }
1188 + }
1189 + else
1190 + {
1191 + this.Core.ParseExtensionAttribute(node, attrib);
1192 + }
1193 + }
1194 +
1195 + if (null == company)
1196 + {
1197 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Company"));
1198 + }
1199 +
1200 + if (null == property)
1201 + {
1202 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Property"));
1203 + }
1204 +
1205 + if (null == value)
1206 + {
1207 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Value"));
1208 + }
1209 +
1210 + this.Core.ParseForExtensionElements(node);
1211 +
1212 + if (!this.Core.EncounteredError)
1213 + {
1214 + this.AddPatchMetadata(sourceLineNumbers, company, property, value);
1215 + }
1216 + }
1217 +
1218 + /// <summary>
1219 + /// Parses a patch sequence element.
1220 + /// </summary>
1221 + /// <param name="node">The element to parse.</param>
1222 + private void ParsePatchSequenceElement(XElement node)
1223 + {
1224 + var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
1225 + string family = null;
1226 + string target = null;
1227 + string sequence = null;
1228 + var attributes = 0;
1229 +
1230 + foreach (var attrib in node.Attributes())
1231 + {
1232 + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
1233 + {
1234 + switch (attrib.Name.LocalName)
1235 + {
1236 + case "PatchFamily":
1237 + family = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
1238 + break;
1239 + case "ProductCode":
1240 + if (null != target)
1241 + {
1242 + this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Target", "TargetImage"));
1243 + }
1244 + target = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
1245 + break;
1246 + case "Target":
1247 + if (null != target)
1248 + {
1249 + this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "TargetImage", "ProductCode"));
1250 + }
1251 + this.Core.Write(WarningMessages.DeprecatedPatchSequenceTargetAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
1252 + target = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1253 + break;
1254 + case "TargetImage":
1255 + if (null != target)
1256 + {
1257 + this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Target", "ProductCode"));
1258 + }
1259 + target = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
1260 + this.Core.CreateSimpleReference(sourceLineNumbers, "TargetImages", target);
1261 + break;
1262 + case "Sequence":
1263 + sequence = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
1264 + break;
1265 + case "Supersede":
1266 + if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
1267 + {
1268 + attributes |= 0x1;
1269 + }
1270 + break;
1271 + default:
1272 + this.Core.UnexpectedAttribute(node, attrib);
1273 + break;
1274 + }
1275 + }
1276 + else
1277 + {
1278 + this.Core.ParseExtensionAttribute(node, attrib);
1279 + }
1280 + }
1281 +
1282 + if (null == family)
1283 + {
1284 + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "PatchFamily"));
1285 + }
1286 +
1287 + this.Core.ParseForExtensionElements(node);
1288 +
1289 + if (!this.Core.EncounteredError)
1290 + {
1291 + var tuple = new PatchSequenceTuple(sourceLineNumbers)
1292 + {
1293 + PatchFamily = family,
1294 + Target = target,
1295 + Sequence = sequence,
1296 + Supersede = attributes
1297 + };
1298 +
1299 + this.Core.AddTuple(tuple);
1300 + }
1301 + }
1302 +
1303 + private void AddPatchMetadata(SourceLineNumber sourceLineNumbers, string company, string property, string value)
1304 + {
1305 + this.Core.AddTuple(new PatchMetadataTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, company, property))
1306 + {
1307 + Company = company,
1308 + Property = property,
1309 + Value = value
1310 + });
1311 + }
1312 + }
1313 +}
src/WixToolset.Core/Compiler_UI.cs
+71 -46
@@ -120,8 +120,10 @@ namespace WixToolset.Core
120
121 // the following are available indentically under the UI and Product elements for document organization use only
122 case "AdminUISequence":
123 + this.ParseSequenceElement(child, SequenceTable.AdminUISequence);
124 + break;
125 case "InstallUISequence":
124 - this.ParseSequenceElement(child, child.Name.LocalName);
126 + this.ParseSequenceElement(child, SequenceTable.InstallUISequence);
127 break;
128 case "Binary":
129 this.ParseBinaryElement(child);
@@ -149,7 +151,8 @@ namespace WixToolset.Core
151
152 if (null != id && !this.Core.EncounteredError)
153 {
152 - this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixUI, id);
154 + var tuple = new WixUITuple(sourceLineNumbers, id);
155 + this.Core.AddTuple(tuple);
156 }
157 }
158
@@ -160,7 +163,7 @@ namespace WixToolset.Core
163 /// <param name="table">Table to add row to.</param>
164 /// <param name="property">Identifier of property referred to by list item.</param>
165 /// <param name="order">Relative order of list items.</param>
163 - private void ParseListItemElement(XElement node, TupleDefinitionType tableName, string property, ref int order)
166 + private void ParseListItemElement(XElement node, TupleDefinitionType tupleType, string property, ref int order)
167 {
168 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
169 string icon = null;
@@ -174,7 +177,7 @@ namespace WixToolset.Core
177 switch (attrib.Name.LocalName)
178 {
179 case "Icon":
177 - if (TupleDefinitionType.ListView == tableName)
180 + if (TupleDefinitionType.ListView == tupleType)
181 {
182 icon = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
183 this.Core.CreateSimpleReference(sourceLineNumbers, "Binary", icon);
@@ -210,14 +213,14 @@ namespace WixToolset.Core
213
214 if (!this.Core.EncounteredError)
215 {
213 - var row = this.Core.CreateRow(sourceLineNumbers, tableName);
214 - row.Set(0, property);
215 - row.Set(1, ++order);
216 - row.Set(2, value);
217 - row.Set(3, text);
216 + var tuple = this.Core.CreateTuple(sourceLineNumbers, tupleType);
217 + tuple.Set(0, property);
218 + tuple.Set(1, ++order);
219 + tuple.Set(2, value);
220 + tuple.Set(3, text);
221 if (null != icon)
222 {
220 - row.Set(4, icon);
223 + tuple.Set(4, icon);
224 }
225 }
226 }
@@ -335,19 +338,21 @@ namespace WixToolset.Core
338
339 if (!this.Core.EncounteredError)
340 {
338 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.RadioButton);
339 - row.Set(0, property);
340 - row.Set(1, ++order);
341 - row.Set(2, value);
342 - row.Set(3, x);
343 - row.Set(4, y);
344 - row.Set(5, width);
345 - row.Set(6, height);
346 - row.Set(7, text);
347 - if (null != tooltip || null != help)
341 + var tuple = new RadioButtonTuple(sourceLineNumbers)
342 {
349 - row.Set(8, String.Concat(tooltip, "|", help));
350 - }
343 + Property = property,
344 + Order = ++order,
345 + Value = value,
346 + Text = text,
347 + Help = (null != tooltip || null != help) ? String.Concat(tooltip, "|", help) : null
348 + };
349 +
350 + tuple.Set((int)RadioButtonTupleFields.X, x);
351 + tuple.Set((int)RadioButtonTupleFields.Y, y);
352 + tuple.Set((int)RadioButtonTupleFields.Width, width);
353 + tuple.Set((int)RadioButtonTupleFields.Height, height);
354 +
355 + this.Core.AddTuple(tuple);
356 }
357
358 return type;
@@ -481,10 +486,14 @@ namespace WixToolset.Core
486
487 if (!this.Core.EncounteredError)
488 {
484 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Billboard, id);
485 - row.Set(1, feature);
486 - row.Set(2, action);
487 - row.Set(3, order);
489 + var tuple = new BillboardTuple(sourceLineNumbers, id)
490 + {
491 + Feature_ = feature,
492 + Action = action,
493 + Ordering = order
494 + };
495 +
496 + this.Core.AddTuple(tuple);
497 }
498 }
499
@@ -494,7 +503,7 @@ namespace WixToolset.Core
503 /// <param name="node">Element to parse.</param>
504 /// <param name="table">Table referred to by control group.</param>
505 /// <param name="childTag">Expected child elements.</param>
497 - private void ParseControlGroupElement(XElement node, TupleDefinitionType tableName, string childTag)
506 + private void ParseControlGroupElement(XElement node, TupleDefinitionType tupleType, string childTag)
507 {
508 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
509 var order = 0;
@@ -537,7 +546,7 @@ namespace WixToolset.Core
546 switch (child.Name.LocalName)
547 {
548 case "ListItem":
540 - this.ParseListItemElement(child, tableName, property, ref order);
549 + this.ParseListItemElement(child, tupleType, property, ref order);
550 break;
551 case "Property":
552 this.ParsePropertyElement(child);
@@ -668,10 +677,14 @@ namespace WixToolset.Core
677
678 if (!this.Core.EncounteredError)
679 {
671 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ActionText);
672 - row.Set(0, action);
673 - row.Set(1, Common.GetInnerText(node));
674 - row.Set(2, template);
680 + var tuple = new ActionTextTuple(sourceLineNumbers)
681 + {
682 + Action = action,
683 + Description = Common.GetInnerText(node),
684 + Template = template
685 + };
686 +
687 + this.Core.AddTuple(tuple);
688 }
689 }
690
@@ -716,8 +729,12 @@ namespace WixToolset.Core
729
730 if (!this.Core.EncounteredError)
731 {
719 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.UIText, id);
720 - row.Set(1, text);
732 + var tuple = new UITextTuple(sourceLineNumbers, id)
733 + {
734 + Text = text,
735 + };
736 +
737 + this.Core.AddTuple(tuple);
738 }
739 }
740
@@ -1654,13 +1671,17 @@ namespace WixToolset.Core
1671
1672 if (!this.Core.EncounteredError)
1673 {
1657 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.ControlEvent);
1658 - row.Set(0, dialog);
1659 - row.Set(1, control);
1660 - row.Set(2, (null != controlEvent ? controlEvent : property));
1661 - row.Set(3, argument);
1662 - row.Set(4, condition);
1663 - row.Set(5, order);
1674 + var tuple = new ControlEventTuple(sourceLineNumbers)
1675 + {
1676 + Dialog_ = dialog,
1677 + Control_ = control,
1678 + Event = controlEvent ?? property,
1679 + Argument = argument,
1680 + Condition = condition,
1681 + Ordering = order
1682 + };
1683 +
1684 + this.Core.AddTuple(tuple);
1685 }
1686
1687 if ("DoAction" == controlEvent && null != argument)
@@ -1719,11 +1740,15 @@ namespace WixToolset.Core
1740
1741 if (!this.Core.EncounteredError)
1742 {
1722 - var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.EventMapping);
1723 - row.Set(0, dialog);
1724 - row.Set(1, control);
1725 - row.Set(2, eventMapping);
1726 - row.Set(3, controlAttribute);
1743 + var tuple = new EventMappingTuple(sourceLineNumbers)
1744 + {
1745 + Dialog_ = dialog,
1746 + Control_ = control,
1747 + Event = eventMapping,
1748 + Attribute = controlAttribute
1749 + }; ;
1750 +
1751 + this.Core.AddTuple(tuple);
1752 }
1753 }
1754 }
src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
+49 -14
@@ -53,18 +53,29 @@ namespace WixToolset.Core.ExtensibilityServices
53
54 public void CreateComplexReference(IntermediateSection section, SourceLineNumber sourceLineNumbers, ComplexReferenceParentType parentType, string parentId, string parentLanguage, ComplexReferenceChildType childType, string childId, bool isPrimary)
55 {
56 - var wixComplexReferenceRow = (WixComplexReferenceTuple)this.CreateRow(section, sourceLineNumbers, TupleDefinitionType.WixComplexReference);
57 - wixComplexReferenceRow.Parent = parentId;
58 - wixComplexReferenceRow.ParentType = parentType;
59 - wixComplexReferenceRow.ParentLanguage = parentLanguage;
60 - wixComplexReferenceRow.Child = childId;
61 - wixComplexReferenceRow.ChildType = childType;
62 - wixComplexReferenceRow.IsPrimary = isPrimary;
56
64 - this.CreateWixGroupRow(section, sourceLineNumbers, parentType, parentId, childType, childId);
57 + var tuple = new WixComplexReferenceTuple(sourceLineNumbers)
58 + {
59 + Parent = parentId,
60 + ParentType = parentType,
61 + ParentLanguage = parentLanguage,
62 + Child = childId,
63 + ChildType = childType,
64 + IsPrimary = isPrimary
65 + };
66 +
67 + section.Tuples.Add(tuple);
68 +
69 + this.CreateWixGroupTuple(section, sourceLineNumbers, parentType, parentId, childType, childId);
70 }
71
72 + [Obsolete]
73 public Identifier CreateDirectoryRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, Identifier id, string parentId, string name, ISet<string> sectionInlinedDirectoryIds, string shortName = null, string sourceName = null, string shortSourceName = null)
74 + {
75 + return this.CreateDirectoryTuple(section, sourceLineNumbers, id, parentId, name, sectionInlinedDirectoryIds, shortName, sourceName, shortSourceName);
76 + }
77 +
78 + public Identifier CreateDirectoryTuple(IntermediateSection section, SourceLineNumber sourceLineNumbers, Identifier id, string parentId, string name, ISet<string> sectionInlinedDirectoryIds, string shortName = null, string sourceName = null, string shortSourceName = null)
79 {
80 string defaultDir;
81
@@ -158,7 +169,7 @@ namespace WixToolset.Core.ExtensibilityServices
169
170 for (int i = pathStartsAt; i < inlineSyntax.Length; ++i)
171 {
161 - Identifier inlineId = this.CreateDirectoryRow(section, sourceLineNumbers, null, id, inlineSyntax[i], sectionInlinedDirectoryIds);
172 + Identifier inlineId = this.CreateDirectoryTuple(section, sourceLineNumbers, null, id, inlineSyntax[i], sectionInlinedDirectoryIds);
173 id = inlineId.Id;
174 }
175 }
@@ -175,16 +186,22 @@ namespace WixToolset.Core.ExtensibilityServices
186 public Identifier CreateIdentifier(string prefix, params string[] args)
187 {
188 var id = Common.GenerateIdentifier(prefix, args);
178 - return new Identifier(id, AccessModifier.Private);
189 + return new Identifier(AccessModifier.Private, id);
190 }
191
192 public Identifier CreateIdentifierFromFilename(string filename)
193 {
194 var id = Common.GetIdentifierFromName(filename);
184 - return new Identifier(id, AccessModifier.Private);
195 + return new Identifier(AccessModifier.Private, id);
196 }
197
198 + [Obsolete]
199 public Identifier CreateRegistryRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, RegistryRootType root, string key, string name, string value, string componentId, bool escapeLeadingHash)
200 + {
201 + return this.CreateRegistryTuple(section, sourceLineNumbers, root, key, name, value, componentId, escapeLeadingHash);
202 + }
203 +
204 + public Identifier CreateRegistryTuple(IntermediateSection section, SourceLineNumber sourceLineNumbers, RegistryRootType root, string key, string name, string value, string componentId, bool escapeLeadingHash)
205 {
206 if (RegistryRootType.Unknown == root)
207 {
@@ -234,7 +251,13 @@ namespace WixToolset.Core.ExtensibilityServices
251 section.Tuples.Add(tuple);
252 }
253
254 + [Obsolete]
255 public void CreateWixGroupRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType childType, string childId)
256 + {
257 + this.CreateWixGroupTuple(section, sourceLineNumbers, parentType, parentId, childType, childId);
258 + }
259 +
260 + public void CreateWixGroupTuple(IntermediateSection section, SourceLineNumber sourceLineNumbers, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType childType, string childId)
261 {
262 if (null == parentId || ComplexReferenceParentType.Unknown == parentType)
263 {
@@ -257,7 +280,19 @@ namespace WixToolset.Core.ExtensibilityServices
280 section.Tuples.Add(tuple);
281 }
282
283 + [Obsolete]
284 public IntermediateTuple CreateRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, string tableName, Identifier identifier = null)
285 + {
286 + return this.CreateTuple(section, sourceLineNumbers, tableName, identifier);
287 + }
288 +
289 + [Obsolete]
290 + public IntermediateTuple CreateRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, TupleDefinitionType tupleType, Identifier identifier = null)
291 + {
292 + return this.CreateTuple(section, sourceLineNumbers, tupleType, identifier);
293 + }
294 +
295 + public IntermediateTuple CreateTuple(IntermediateSection section, SourceLineNumber sourceLineNumbers, string tableName, Identifier identifier = null)
296 {
297 if (this.Creator == null)
298 {
@@ -272,7 +307,7 @@ namespace WixToolset.Core.ExtensibilityServices
307 return CreateRow(section, sourceLineNumbers, tupleDefinition, identifier);
308 }
309
275 - public IntermediateTuple CreateRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, TupleDefinitionType tupleType, Identifier identifier = null)
310 + public IntermediateTuple CreateTuple(IntermediateSection section, SourceLineNumber sourceLineNumbers, TupleDefinitionType tupleType, Identifier identifier = null)
311 {
312 var tupleDefinition = TupleDefinitions.ByType(tupleType);
313
@@ -331,7 +366,7 @@ namespace WixToolset.Core.ExtensibilityServices
366
367 public void EnsureTable(IntermediateSection section, SourceLineNumber sourceLineNumbers, string tableName)
368 {
334 - var row = this.CreateRow(section, sourceLineNumbers, TupleDefinitionType.WixEnsureTable);
369 + var row = this.CreateTuple(section, sourceLineNumbers, TupleDefinitionType.WixEnsureTable);
370 row.Set(0, tableName);
371
372 if (this.Creator == null)
@@ -428,7 +463,7 @@ namespace WixToolset.Core.ExtensibilityServices
463 this.Messaging.Write(WarningMessages.IdentifierTooLong(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value));
464 }
465
431 - return new Identifier(value, access);
466 + return new Identifier(access, value);
467 }
468
469 public string GetAttributeIdentifierValue(SourceLineNumber sourceLineNumbers, XAttribute attribute)
src/WixToolset.Core/Link/WixGroupingOrdering.cs
+28 -29
@@ -18,11 +18,11 @@ namespace WixToolset.Core.Link
18 /// </summary>
19 internal class WixGroupingOrdering
20 {
21 - private IMessaging messageHandler;
21 + private readonly IMessaging messageHandler;
22 private List<string> groupTypes;
23 private List<string> itemTypes;
24 private ItemCollection items;
25 - private List<int> rowsUsed;
25 + private readonly List<int> rowsUsed;
26 private bool loaded;
27 private bool encounteredError;
28
@@ -50,10 +50,10 @@ namespace WixToolset.Core.Link
50 /// </summary>
51 /// <param name="groupTypes">Group types to include.</param>
52 /// <param name="itemTypes">Item types to include.</param>
53 - public void UseTypes(IEnumerable<string> groupTypes, IEnumerable<string> itemTypes)
53 + public void UseTypes(IEnumerable<ComplexReferenceParentType> groupTypes, IEnumerable<ComplexReferenceChildType> itemTypes)
54 {
55 - this.groupTypes = new List<string>(groupTypes);
56 - this.itemTypes = new List<string>(itemTypes);
55 + this.groupTypes = new List<string>(groupTypes.Select(g => g.ToString()));
56 + this.itemTypes = new List<string>(itemTypes.Select(i => i.ToString()));
57
58 this.items = new ItemCollection();
59 this.loaded = false;
@@ -65,17 +65,18 @@ namespace WixToolset.Core.Link
65 /// <param name="parentType">The group type for the parent group to flatten.</param>
66 /// <param name="parentId">The identifier of the parent group to flatten.</param>
67 /// <param name="removeUsedRows">Whether to remove used group rows before returning.</param>
68 - public void FlattenAndRewriteRows(string parentType, string parentId, bool removeUsedRows)
68 + public void FlattenAndRewriteRows(ComplexReferenceChildType parentType, string parentId, bool removeUsedRows)
69 {
70 - Debug.Assert(this.groupTypes.Contains(parentType));
70 + var parentTypeString = parentType.ToString();
71 + Debug.Assert(this.groupTypes.Contains(parentTypeString));
72
72 - this.CreateOrderedList(parentType, parentId, out var orderedItems);
73 + this.CreateOrderedList(parentTypeString, parentId, out var orderedItems);
74 if (this.encounteredError)
75 {
76 return;
77 }
78
78 - this.CreateNewGroupRows(parentType, parentId, orderedItems);
79 + this.CreateNewGroupRows(parentTypeString, parentId, orderedItems);
80
81 if (removeUsedRows)
82 {
@@ -88,9 +89,10 @@ namespace WixToolset.Core.Link
89 /// </summary>
90 /// <param name="parentType">The type of the parent group to flatten.</param>
91 /// <param name="removeUsedRows">Whether to remove used group rows before returning.</param>
91 - public void FlattenAndRewriteGroups(string parentType, bool removeUsedRows)
92 + public void FlattenAndRewriteGroups(ComplexReferenceParentType parentType, bool removeUsedRows)
93 {
93 - Debug.Assert(this.groupTypes.Contains(parentType));
94 + var parentTypeString = parentType.ToString();
95 + Debug.Assert(this.groupTypes.Contains(parentTypeString));
96
97 this.LoadFlattenOrderGroups();
98 if (this.encounteredError)
@@ -100,10 +102,9 @@ namespace WixToolset.Core.Link
102
103 foreach (Item item in this.items)
104 {
103 - if (parentType == item.Type)
105 + if (parentTypeString == item.Type)
106 {
105 - List<Item> orderedItems;
106 - this.CreateOrderedList(item.Type, item.Id, out orderedItems);
107 + this.CreateOrderedList(item.Type, item.Id, out var orderedItems);
108 this.CreateNewGroupRows(item.Type, item.Id, orderedItems);
109 }
110 }
@@ -131,8 +132,7 @@ namespace WixToolset.Core.Link
132 return;
133 }
134
134 - Item parentItem;
135 - if (!this.items.TryGetValue(parentType, parentId, out parentItem))
135 + if (!this.items.TryGetValue(parentType, parentId, out var parentItem))
136 {
137 this.messageHandler.Write(ErrorMessages.IdentifierNotFound(parentType, parentId));
138 return;
@@ -360,9 +360,9 @@ namespace WixToolset.Core.Link
360
361 foreach (var row in this.EntrySection.Tuples.OfType<WixOrderingTuple>())
362 {
363 - var rowItemType = row.ItemType;
363 + var rowItemType = row.ItemType.ToString();
364 var rowItemName = row.ItemId_;
365 - var rowDependsOnType = row.DependsOnType;
365 + var rowDependsOnType = row.DependsOnType.ToString();
366 var rowDependsOnName = row.DependsOnId_;
367
368 // If this row specifies some other (unknown) type in either
@@ -510,8 +510,8 @@ namespace WixToolset.Core.Link
510 /// ordering dependencies.</remarks>
511 internal class Item
512 {
513 - private ItemCollection afterItems;
514 - private ItemCollection beforeItems; // for checking for circular references
513 + private readonly ItemCollection afterItems;
514 + private readonly ItemCollection beforeItems; // for checking for circular references
515 private bool flattenedAfterItems;
516
517 public Item(IntermediateTuple row, string type, string id)
@@ -522,9 +522,9 @@ namespace WixToolset.Core.Link
522
523 this.Key = ItemCollection.CreateKeyFromTypeId(type, id);
524
525 - afterItems = new ItemCollection();
526 - beforeItems = new ItemCollection();
527 - flattenedAfterItems = false;
525 + this.afterItems = new ItemCollection();
526 + this.beforeItems = new ItemCollection();
527 + this.flattenedAfterItems = false;
528 }
529
530 public IntermediateTuple Row { get; private set; }
@@ -540,8 +540,7 @@ namespace WixToolset.Core.Link
540 }
541 #endif // DEBUG
542
543 - private ItemCollection childItems = new ItemCollection();
544 - public ItemCollection ChildItems { get { return childItems; } }
543 + public ItemCollection ChildItems { get; } = new ItemCollection();
544
545 /// <summary>
546 /// Removes any nested groups under this item and replaces
@@ -614,7 +613,7 @@ namespace WixToolset.Core.Link
613 {
614 if (this.ShouldItemPropagateChildOrdering())
615 {
617 - foreach (Item childItem in this.childItems)
616 + foreach (Item childItem in this.ChildItems)
617 {
618 childItem.AddAfter(this.afterItems, messageHandler);
619 }
@@ -667,9 +666,9 @@ namespace WixToolset.Core.Link
666 // first payload to be the entrypoint.
667 private bool ShouldItemPropagateChildOrdering()
668 {
670 - if (String.Equals("Package", this.Type, StringComparison.Ordinal) ||
671 - (String.Equals("Container", this.Type, StringComparison.Ordinal) &&
672 - !String.Equals(Compiler.BurnUXContainerId, this.Id, StringComparison.Ordinal)))
669 + if (String.Equals(nameof(ComplexReferenceChildType.Package), this.Type, StringComparison.Ordinal) ||
670 + (String.Equals(nameof(ComplexReferenceParentType.Container), this.Type, StringComparison.Ordinal) &&
671 + !String.Equals(Compiler.BurnUXContainerId.Id, this.Id, StringComparison.Ordinal)))
672 {
673 return false;
674 }
src/WixToolset.Core/Linker.cs
+15 -14
@@ -20,8 +20,8 @@ namespace WixToolset.Core
20 /// </summary>
21 internal class Linker : ILinker
22 {
23 - private static readonly char[] colonCharacter = ":".ToCharArray();
24 - private static readonly string emptyGuid = Guid.Empty.ToString("B");
23 + private static readonly char[] ColonCharacter = new[] { ':' };
24 + private static readonly string EmptyGuid = Guid.Empty.ToString("B");
25
26 private readonly bool sectionIdOnRows;
27
@@ -428,21 +428,22 @@ namespace WixToolset.Core
428 // check for colliding values and collect the wix variable rows
429 {
430 var row = (WixVariableTuple)tuple;
431 + var id = row.Id.Id;
432
432 - if (wixVariables.TryGetValue(row.WixVariable, out var collidingRow))
433 + if (wixVariables.TryGetValue(id, out var collidingRow))
434 {
435 if (collidingRow.Overridable && !row.Overridable)
436 {
436 - wixVariables[row.WixVariable] = row;
437 + wixVariables[id] = row;
438 }
439 else if (!row.Overridable || (collidingRow.Overridable && row.Overridable))
440 {
440 - this.OnMessage(ErrorMessages.WixVariableCollision(row.SourceLineNumbers, row.WixVariable));
441 + this.OnMessage(ErrorMessages.WixVariableCollision(row.SourceLineNumbers, id));
442 }
443 }
444 else
445 {
445 - wixVariables.Add(row.WixVariable, row);
446 + wixVariables.Add(id, row);
447 }
448 }
449
@@ -1609,14 +1610,14 @@ namespace WixToolset.Core
1610 var groups = new WixGroupingOrdering(entrySection, this.Messaging);
1611
1612 // Create UX payloads and Package payloads
1612 - groups.UseTypes(new string[] { "Container", "Layout", "PackageGroup", "PayloadGroup", "Package" }, new string[] { "PackageGroup", "Package", "PayloadGroup", "Payload" });
1613 - groups.FlattenAndRewriteGroups("Package", false);
1614 - groups.FlattenAndRewriteGroups("Container", false);
1615 - groups.FlattenAndRewriteGroups("Layout", false);
1616 -
1613 + groups.UseTypes(new[] { ComplexReferenceParentType.Container, ComplexReferenceParentType.Layout, ComplexReferenceParentType.PackageGroup, ComplexReferenceParentType.PayloadGroup, ComplexReferenceParentType.Package }, new[] { ComplexReferenceChildType.PackageGroup, ComplexReferenceChildType.Package, ComplexReferenceChildType.PayloadGroup, ComplexReferenceChildType.Payload });
1614 + groups.FlattenAndRewriteGroups(ComplexReferenceParentType.Package, false);
1615 + groups.FlattenAndRewriteGroups(ComplexReferenceParentType.Container, false);
1616 + groups.FlattenAndRewriteGroups(ComplexReferenceParentType.Layout, false);
1617 +
1618 // Create Chain packages...
1618 - groups.UseTypes(new string[] { "PackageGroup" }, new string[] { "Package", "PackageGroup" });
1619 - groups.FlattenAndRewriteRows("PackageGroup", "WixChain", false);
1619 + groups.UseTypes(new[] { ComplexReferenceParentType.PackageGroup }, new[] { ComplexReferenceChildType.Package, ComplexReferenceChildType.PackageGroup });
1620 + groups.FlattenAndRewriteRows(ComplexReferenceChildType.PackageGroup, "WixChain", false);
1621
1622 groups.RemoveUsedGroupRows();
1623 }
@@ -1702,7 +1703,7 @@ namespace WixToolset.Core
1703 var connectionId = row.AsString(connectionColumn);
1704 var featureId = row.AsString(featureColumn);
1705
1705 - if (emptyGuid == featureId)
1706 + if (EmptyGuid == featureId)
1707 {
1708 var connection = connectToFeatures[connectionId];
1709
src/WixToolset.Core/Preprocessor.cs
+2 -1
@@ -66,7 +66,8 @@ namespace WixToolset.Core
66 /// <summary>
67 /// Event for resolved variables.
68 /// </summary>
69 - public event ResolvedVariableEventHandler ResolvedVariable;
69 + /// TOOD: Remove?
70 + //public event ResolvedVariableEventHandler ResolvedVariable;
71
72 /// <summary>
73 /// Get the source line information for the current element. The precompiler will insert
src/WixToolset.Core/Resolver.cs
+1 -1
@@ -213,7 +213,7 @@ namespace WixToolset.Core
213 var wixVariableTuples = context.IntermediateRepresentation.Sections.SelectMany(s => s.Tuples).OfType<WixVariableTuple>();
214 foreach (var tuple in wixVariableTuples)
215 {
216 - context.VariableResolver.AddVariable(tuple.SourceLineNumbers, tuple.WixVariable, tuple.Value, tuple.Overridable);
216 + context.VariableResolver.AddVariable(tuple.SourceLineNumbers, tuple.Id.Id, tuple.Value, tuple.Overridable);
217 }
218 }
219
src/WixToolset.Core/TransformsFlags.cs deleted
-81
@@ -1,81 +0,0 @@
1 -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2 -
3 -namespace WixToolset.Core
4 -{
5 - using System;
6 - using System.Diagnostics.CodeAnalysis;
7 -
8 - /// <summary>
9 - /// Summary information values for the CharCount property in transforms.
10 - /// </summary>
11 - [Flags]
12 - [SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")]
13 - public enum TransformFlags
14 - {
15 - /// <summary>Ignore error when adding a row that exists.</summary>
16 - ErrorAddExistingRow = 0x1,
17 -
18 - /// <summary>Ignore error when deleting a row that does not exist.</summary>
19 - ErrorDeleteMissingRow = 0x2,
20 -
21 - /// <summary>Ignore error when adding a table that exists. </summary>
22 - ErrorAddExistingTable = 0x4,
23 -
24 - /// <summary>Ignore error when deleting a table that does not exist. </summary>
25 - ErrorDeleteMissingTable = 0x8,
26 -
27 - /// <summary>Ignore error when updating a row that does not exist. </summary>
28 - ErrorUpdateMissingRow = 0x10,
29 -
30 - /// <summary>Ignore error when transform and database code pages do not match, and their code pages are neutral.</summary>
31 - ErrorChangeCodePage = 0x20,
32 -
33 - /// <summary>Default language must match base database. </summary>
34 - ValidateLanguage = 0x10000,
35 -
36 - /// <summary>Product must match base database.</summary>
37 - ValidateProduct = 0x20000,
38 -
39 - /// <summary>Check major version only. </summary>
40 - ValidateMajorVersion = 0x80000,
41 -
42 - /// <summary>Check major and minor versions only. </summary>
43 - ValidateMinorVersion = 0x100000,
44 -
45 - /// <summary>Check major, minor, and update versions.</summary>
46 - ValidateUpdateVersion = 0x200000,
47 -
48 - /// <summary>Installed version lt base version. </summary>
49 - ValidateNewLessBaseVersion = 0x400000,
50 -
51 - /// <summary>Installed version lte base version. </summary>
52 - ValidateNewLessEqualBaseVersion = 0x800000,
53 -
54 - /// <summary>Installed version eq base version. </summary>
55 - ValidateNewEqualBaseVersion = 0x1000000,
56 -
57 - /// <summary>Installed version gte base version.</summary>
58 - ValidateNewGreaterEqualBaseVersion = 0x2000000,
59 -
60 - /// <summary>Installed version gt base version.</summary>
61 - ValidateNewGreaterBaseVersion = 0x4000000,
62 -
63 - /// <summary>UpgradeCode must match base database.</summary>
64 - ValidateUpgradeCode = 0x8000000,
65 -
66 - /// <summary>Masks all version checks on ProductVersion.</summary>
67 - ProductVersionMask = ValidateMajorVersion | ValidateMinorVersion | ValidateUpdateVersion,
68 -
69 - /// <summary>Masks all operations on ProductVersion.</summary>
70 - ProductVersionOperatorMask = ValidateNewLessBaseVersion | ValidateNewLessEqualBaseVersion | ValidateNewEqualBaseVersion | ValidateNewGreaterEqualBaseVersion | ValidateNewGreaterBaseVersion,
71 -
72 - /// <summary>Default value for instance transforms.</summary>
73 - InstanceTransformDefault = ErrorAddExistingRow | ErrorDeleteMissingRow | ErrorAddExistingTable | ErrorDeleteMissingTable | ErrorUpdateMissingRow | ErrorChangeCodePage | ValidateProduct | ValidateUpdateVersion | ValidateNewGreaterEqualBaseVersion,
74 -
75 - /// <summary>Default value for language transforms.</summary>
76 - LanguageTransformDefault = ErrorAddExistingRow | ErrorDeleteMissingRow | ErrorAddExistingTable | ErrorDeleteMissingTable | ErrorUpdateMissingRow | ErrorChangeCodePage | ValidateProduct,
77 -
78 - /// <summary>Default value for patch transforms.</summary>
79 - PatchTransformDefault = ErrorAddExistingRow | ErrorDeleteMissingRow | ErrorAddExistingTable | ErrorDeleteMissingTable | ErrorUpdateMissingRow | ValidateProduct | ValidateUpdateVersion | ValidateNewEqualBaseVersion | ValidateUpgradeCode,
80 - }
81 -}
src/test/Example.Extension/Data/example.wir
Binary files a/src/test/Example.Extension/Data/example.wir and b/src/test/Example.Extension/Data/example.wir differ
src/test/Example.Extension/ExampleCompilerExtension.cs
+2 -2
@@ -1,4 +1,4 @@
1 -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
1 +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3 namespace Example.Extension
4 {
@@ -73,7 +73,7 @@ namespace Example.Extension
73
74 if (!this.Messaging.EncounteredError)
75 {
76 - var tuple = this.ParseHelper.CreateRow(section, sourceLineNumbers, "Example", id);
76 + var tuple = this.ParseHelper.CreateTuple(section, sourceLineNumbers, "Example", id);
77 tuple.Set(1, value);
78 }
79 }
src/test/WixToolsetTest.CoreIntegration/ExtensionFixture.cs
+1 -1
@@ -98,7 +98,7 @@ namespace WixToolsetTest.CoreIntegration
98 var section = intermediate.Sections.Single();
99
100 var property = section.Tuples.OfType<PropertyTuple>().Where(p => p.Id.Id == "ExampleProperty").Single();
101 - Assert.Equal("ExampleProperty", property.Property);
101 + Assert.Equal("ExampleProperty", property.Id.Id);
102 Assert.Equal("test", property.Value);
103 }
104 }
src/test/WixToolsetTest.CoreIntegration/MsiFixture.cs
+1 -1
@@ -534,7 +534,7 @@ namespace WixToolsetTest.CoreIntegration
534 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir"));
535 var section = intermediate.Sections.Single();
536
537 - var platformSummary = section.Tuples.OfType<_SummaryInformationTuple>().Single(s => s.PropertyId == 7);
537 + var platformSummary = section.Tuples.OfType<SummaryInformationTuple>().Single(s => s.PropertyId == SumaryInformationType.PlatformAndLanguage);
538 Assert.Equal("x64;1033", platformSummary.Value);
539 }
540 }
src/test/WixToolsetTest.CoreIntegration/WixiplFixture.cs
+2 -2
@@ -130,7 +130,7 @@ namespace WixToolsetTest.CoreIntegration
130 var path = binary[BinaryTupleFields.Data].AsPath().Path;
131 Assert.Contains("Example.Extension", path);
132 Assert.EndsWith(@"\0", path);
133 - Assert.Equal(@"BinFromWir", binary[BinaryTupleFields.Name].AsString());
133 + Assert.Equal(@"BinFromWir", binary.Id.Id);
134 }
135 }
136 }
@@ -185,7 +185,7 @@ namespace WixToolsetTest.CoreIntegration
185 var path = binary[BinaryTupleFields.Data].AsPath().Path;
186 Assert.Contains("Example.Extension", path);
187 Assert.EndsWith(@"\0", path);
188 - Assert.Equal(@"BinFromWir", binary[BinaryTupleFields.Name].AsString());
188 + Assert.Equal(@"BinFromWir", binary.Id.Id);
189 }
190 }
191 }