aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2019-05-23 15:37:56 -0700
committerRob Mensching <rob@firegiant.com>2019-05-23 16:02:37 -0700
commit354f6d5b79404544cb7c0e11a0d9212b4780ce09 (patch)
tree1082ce6dd66604f7da315d6a15c85ac3f56b745a
parent3051bf2fc300df125115c9538a0bfc8256bfde6a (diff)
downloadwix-354f6d5b79404544cb7c0e11a0d9212b4780ce09.tar.gz
wix-354f6d5b79404544cb7c0e11a0d9212b4780ce09.tar.bz2
wix-354f6d5b79404544cb7c0e11a0d9212b4780ce09.zip
Integrate latest Data changes for FileTuple and AssemblyTuple
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs32
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs2
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/CabinetBuilder.cs4
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/CabinetResolver.cs2
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs3
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs14
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs15
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesCommand.cs23
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs19
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/ProcessUncompressedFilesCommand.cs4
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/SequenceActionsCommand.cs2
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs118
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/UpdateMediaSequencesCommand.cs18
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs3
-rw-r--r--src/WixToolset.Core/Bind/FileFacade.cs14
-rw-r--r--src/WixToolset.Core/Compiler.cs128
-rw-r--r--src/WixToolset.Core/Compiler_2.cs1
-rw-r--r--src/WixToolset.Core/Linker.cs2
-rw-r--r--src/test/WixToolsetTest.CoreIntegration/ExtensionFixture.cs6
-rw-r--r--src/test/WixToolsetTest.CoreIntegration/MsiFixture.cs36
-rw-r--r--src/test/WixToolsetTest.CoreIntegration/WixiplFixture.cs18
-rw-r--r--src/test/WixToolsetTest.CoreIntegration/WixlibFixture.cs22
22 files changed, 233 insertions, 253 deletions
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs
index 8c6a3e67..2199bbde 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs
@@ -156,13 +156,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind
156 throw new WixException(ErrorMessages.MaximumUncompressedMediaSizeTooLarge(null, maxPreCabSizeInMB)); 156 throw new WixException(ErrorMessages.MaximumUncompressedMediaSizeTooLarge(null, maxPreCabSizeInMB));
157 } 157 }
158 158
159 foreach (FileFacade facade in this.FileFacades) 159 foreach (var facade in this.FileFacades)
160 { 160 {
161 // When building a product, if the current file is not to be compressed or if 161 // When building a product, if the current file is not to be compressed or if
162 // the package set not to be compressed, don't cab it. 162 // the package set not to be compressed, don't cab it.
163 if (SectionType.Product == this.Section.Type && 163 if (SectionType.Product == this.Section.Type && (facade.Uncompressed || !this.FilesCompressed))
164 ((facade.File.Compressed.HasValue && !facade.File.Compressed.Value) ||
165 (!facade.File.Compressed.HasValue && !this.FilesCompressed)))
166 { 164 {
167 uncompressedFiles.Add(facade); 165 uncompressedFiles.Add(facade);
168 continue; 166 continue;
@@ -171,8 +169,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
171 if (currentCabIndex == MaxCabIndex) 169 if (currentCabIndex == MaxCabIndex)
172 { 170 {
173 // Associate current file with last cab (irrespective of the size) and cab index is not incremented anymore. 171 // Associate current file with last cab (irrespective of the size) and cab index is not incremented anymore.
174 List<FileFacade> cabinetFiles = filesByCabinetMedia[currentMediaRow]; 172 var cabinetFiles = filesByCabinetMedia[currentMediaRow];
175 facade.WixFile.DiskId = currentCabIndex; 173 facade.File.DiskId = currentCabIndex;
176 cabinetFiles.Add(facade); 174 cabinetFiles.Add(facade);
177 continue; 175 continue;
178 } 176 }
@@ -187,8 +185,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
187 mediaRows.Add(currentMediaRow.DiskId, currentMediaRow); 185 mediaRows.Add(currentMediaRow.DiskId, currentMediaRow);
188 filesByCabinetMedia.Add(currentMediaRow, new List<FileFacade>()); 186 filesByCabinetMedia.Add(currentMediaRow, new List<FileFacade>());
189 187
190 List<FileFacade> cabinetFileRows = filesByCabinetMedia[currentMediaRow]; 188 var cabinetFileRows = filesByCabinetMedia[currentMediaRow];
191 facade.WixFile.DiskId = currentCabIndex; 189 facade.File.DiskId = currentCabIndex;
192 cabinetFileRows.Add(facade); 190 cabinetFileRows.Add(facade);
193 // Now files larger than MaxUncompressedMediaSize will be the only file in its cabinet so as to respect MaxUncompressedMediaSize 191 // Now files larger than MaxUncompressedMediaSize will be the only file in its cabinet so as to respect MaxUncompressedMediaSize
194 currentPreCabSize = (ulong)facade.File.FileSize; 192 currentPreCabSize = (ulong)facade.File.FileSize;
@@ -205,8 +203,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
205 } 203 }
206 204
207 // Associate current file with current cab. 205 // Associate current file with current cab.
208 List<FileFacade> cabinetFiles = filesByCabinetMedia[currentMediaRow]; 206 var cabinetFiles = filesByCabinetMedia[currentMediaRow];
209 facade.WixFile.DiskId = currentCabIndex; 207 facade.File.DiskId = currentCabIndex;
210 cabinetFiles.Add(facade); 208 cabinetFiles.Add(facade);
211 } 209 }
212 } 210 }
@@ -264,17 +262,17 @@ namespace WixToolset.Core.WindowsInstaller.Bind
264 262
265 foreach (FileFacade facade in fileFacades) 263 foreach (FileFacade facade in fileFacades)
266 { 264 {
267 if (!mediaRows.TryGetValue(facade.WixFile.DiskId, out var mediaRow)) 265 if (!mediaRows.TryGetValue(facade.DiskId, out var mediaRow))
268 { 266 {
269 this.Messaging.Write(ErrorMessages.MissingMedia(facade.File.SourceLineNumbers, facade.WixFile.DiskId)); 267 this.Messaging.Write(ErrorMessages.MissingMedia(facade.File.SourceLineNumbers, facade.DiskId));
270 continue; 268 continue;
271 } 269 }
272 270
273 // When building a product, if the current file is not to be compressed or if 271 // When building a product, if the current file is to be uncompressed or if
274 // the package set not to be compressed, don't cab it. 272 // the package set not to be compressed, don't cab it.
275 if (SectionType.Product == this.Section.Type && 273 var compressed = (facade.File.Attributes & FileTupleAttributes.Compressed) == FileTupleAttributes.Compressed;
276 ((!facade.File.Compressed.HasValue && !this.FilesCompressed) || 274 var uncompressed = (facade.File.Attributes & FileTupleAttributes.Uncompressed) == FileTupleAttributes.Uncompressed;
277 (facade.File.Compressed.HasValue && !facade.File.Compressed.Value))) 275 if (SectionType.Product == this.Section.Type && (uncompressed || (!compressed && !this.FilesCompressed)))
278 { 276 {
279 uncompressedFiles.Add(facade); 277 uncompressedFiles.Add(facade);
280 } 278 }
@@ -286,7 +284,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
286 } 284 }
287 else 285 else
288 { 286 {
289 this.Messaging.Write(ErrorMessages.ExpectedMediaCabinet(facade.File.SourceLineNumbers, facade.File.Id.Id, facade.WixFile.DiskId)); 287 this.Messaging.Write(ErrorMessages.ExpectedMediaCabinet(facade.File.SourceLineNumbers, facade.File.Id.Id, facade.DiskId));
290 } 288 }
291 } 289 }
292 } 290 }
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
index cf7fe423..830880ee 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
@@ -526,7 +526,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
526 526
527 this.FileTransfers = fileTransfers; 527 this.FileTransfers = fileTransfers;
528 // TODO: this is not sufficient to collect all Input files (for example, it misses Binary and Icon tables). 528 // TODO: this is not sufficient to collect all Input files (for example, it misses Binary and Icon tables).
529 trackedFiles.AddRange(fileFacades.Select(f => this.BackendHelper.TrackFile(f.WixFile.Source.Path, TrackedFileType.Input, f.File.SourceLineNumbers))); 529 trackedFiles.AddRange(fileFacades.Select(f => this.BackendHelper.TrackFile(f.File.Source.Path, TrackedFileType.Input, f.File.SourceLineNumbers)));
530 this.TrackedFiles = trackedFiles; 530 this.TrackedFiles = trackedFiles;
531 531
532 // TODO: Eventually this gets removed 532 // TODO: Eventually this gets removed
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CabinetBuilder.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CabinetBuilder.cs
index 24011214..abf1ef53 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/CabinetBuilder.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/CabinetBuilder.cs
@@ -166,8 +166,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
166 166
167 var files = cabinetWorkItem.FileFacades 167 var files = cabinetWorkItem.FileFacades
168 .Select(facade => facade.Hash == null ? 168 .Select(facade => facade.Hash == null ?
169 new CabinetCompressFile(facade.WixFile.Source.Path, facade.File.Id.Id) : 169 new CabinetCompressFile(facade.File.Source.Path, facade.File.Id.Id) :
170 new CabinetCompressFile(facade.WixFile.Source.Path, facade.File.Id.Id, facade.Hash.HashPart1, facade.Hash.HashPart2, facade.Hash.HashPart3, facade.Hash.HashPart4)) 170 new CabinetCompressFile(facade.File.Source.Path, facade.File.Id.Id, facade.Hash.HashPart1, facade.Hash.HashPart2, facade.Hash.HashPart3, facade.Hash.HashPart4))
171 .ToList(); 171 .ToList();
172 172
173 var cabinetCompressionLevel = (CabinetCompressionLevel)cabinetWorkItem.CompressionLevel; 173 var cabinetCompressionLevel = (CabinetCompressionLevel)cabinetWorkItem.CompressionLevel;
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CabinetResolver.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CabinetResolver.cs
index 987266f4..3fa3f3a0 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/CabinetResolver.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/CabinetResolver.cs
@@ -113,7 +113,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
113 { 113 {
114 var result = this.ServiceProvider.GetService<IBindFileWithPath>(); 114 var result = this.ServiceProvider.GetService<IBindFileWithPath>();
115 result.Id = facade.File.Id.Id; 115 result.Id = facade.File.Id.Id;
116 result.Path = facade.WixFile.Source.Path; 116 result.Path = facade.File.Source.Path;
117 117
118 return result; 118 return result;
119 } 119 }
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs
index be3c720f..95438f96 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs
@@ -296,6 +296,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
296 /// <param name="fileToken">The file token of the first file present in the splitting cabinet</param> 296 /// <param name="fileToken">The file token of the first file present in the splitting cabinet</param>
297 internal void NewCabNamesCallBack([MarshalAs(UnmanagedType.LPWStr)]string firstCabName, [MarshalAs(UnmanagedType.LPWStr)]string newCabinetName, [MarshalAs(UnmanagedType.LPWStr)]string fileToken) 297 internal void NewCabNamesCallBack([MarshalAs(UnmanagedType.LPWStr)]string firstCabName, [MarshalAs(UnmanagedType.LPWStr)]string newCabinetName, [MarshalAs(UnmanagedType.LPWStr)]string fileToken)
298 { 298 {
299 throw new NotImplementedException();
300#if TODO_CAB_SPANNING
299 // Locking Mutex here as this callback can come from Multiple Cabinet Builder Threads 301 // Locking Mutex here as this callback can come from Multiple Cabinet Builder Threads
300 var mutex = new Mutex(false, "WixCabinetSplitBinderCallback"); 302 var mutex = new Mutex(false, "WixCabinetSplitBinderCallback");
301 try 303 try
@@ -417,6 +419,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
417 // Releasing the Mutex here 419 // Releasing the Mutex here
418 mutex.ReleaseMutex(); 420 mutex.ReleaseMutex();
419 } 421 }
422#endif
420 } 423 }
421 424
422 425
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs
index 57861502..9001b704 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs
@@ -424,13 +424,13 @@ namespace WixToolset.Core.WindowsInstaller.Bind
424 row.Version = tuple.Version; 424 row.Version = tuple.Version;
425 row.Language = tuple.Language; 425 row.Language = tuple.Language;
426 426
427 var attributes = tuple.Checksum ? WindowsInstallerConstants.MsidbFileAttributesChecksum : 0; 427 var attributes = (tuple.Attributes & FileTupleAttributes.Checksum) == FileTupleAttributes.Checksum ? WindowsInstallerConstants.MsidbFileAttributesChecksum : 0;
428 attributes |= (tuple.Compressed.HasValue && tuple.Compressed.Value) ? WindowsInstallerConstants.MsidbFileAttributesCompressed : 0; 428 attributes |= (tuple.Attributes & FileTupleAttributes.Compressed) == FileTupleAttributes.Compressed ? WindowsInstallerConstants.MsidbFileAttributesCompressed : 0;
429 attributes |= (tuple.Compressed.HasValue && !tuple.Compressed.Value) ? WindowsInstallerConstants.MsidbFileAttributesNoncompressed : 0; 429 attributes |= (tuple.Attributes & FileTupleAttributes.Uncompressed) == FileTupleAttributes.Uncompressed ? WindowsInstallerConstants.MsidbFileAttributesNoncompressed : 0;
430 attributes |= tuple.Hidden ? WindowsInstallerConstants.MsidbFileAttributesHidden : 0; 430 attributes |= (tuple.Attributes & FileTupleAttributes.Hidden) == FileTupleAttributes.Hidden ? WindowsInstallerConstants.MsidbFileAttributesHidden : 0;
431 attributes |= tuple.ReadOnly ? WindowsInstallerConstants.MsidbFileAttributesReadOnly : 0; 431 attributes |= (tuple.Attributes & FileTupleAttributes.ReadOnly) == FileTupleAttributes.ReadOnly ? WindowsInstallerConstants.MsidbFileAttributesReadOnly : 0;
432 attributes |= tuple.System ? WindowsInstallerConstants.MsidbFileAttributesSystem : 0; 432 attributes |= (tuple.Attributes & FileTupleAttributes.System) == FileTupleAttributes.System ? WindowsInstallerConstants.MsidbFileAttributesSystem : 0;
433 attributes |= tuple.Vital ? WindowsInstallerConstants.MsidbFileAttributesVital : 0; 433 attributes |= (tuple.Attributes & FileTupleAttributes.Vital) == FileTupleAttributes.Vital ? WindowsInstallerConstants.MsidbFileAttributesVital : 0;
434 row.Attributes = attributes; 434 row.Attributes = attributes;
435 } 435 }
436 436
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs
index f1a6653c..4105cb8f 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs
@@ -101,16 +101,13 @@ namespace WixToolset.Core.WindowsInstaller.Bind
101 // NOTE: this is very tricky - the merge module file rows are not added to the 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 102 // file table because they should not be created via idt import. Instead, these
103 // rows are created by merging in the actual modules. 103 // rows are created by merging in the actual modules.
104 var fileRow = new FileTuple(wixMergeRow.SourceLineNumbers, new Identifier(AccessModifier.Private, record[1])); 104 var fileTuple = new FileTuple(wixMergeRow.SourceLineNumbers, new Identifier(AccessModifier.Private, record[1]));
105 fileRow.Compressed = wixMergeRow.FileCompression; 105 fileTuple.Attributes = wixMergeRow.FileAttributes;
106 fileTuple.DirectoryRef = record[2];
107 fileTuple.DiskId = wixMergeRow.DiskId;
108 fileTuple.Source = new IntermediateFieldPathValue { Path = Path.Combine(this.IntermediateFolder, wixMergeRow.Id.Id, record[1]) };
106 109
107 var wixFileRow = new WixFileTuple(wixMergeRow.SourceLineNumbers); 110 var mergeModuleFileFacade = new FileFacade(true, fileTuple);
108 wixFileRow.DirectoryRef = 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]) };
112
113 var mergeModuleFileFacade = new FileFacade(true, fileRow, wixFileRow);
114 111
115 // If case-sensitive collision with another merge module or a user-authored file identifier. 112 // If case-sensitive collision with another merge module or a user-authored file identifier.
116 if (indexedFileFacades.TryGetValue(mergeModuleFileFacade.File.Id.Id, out var collidingFacade)) 113 if (indexedFileFacades.TryGetValue(mergeModuleFileFacade.File.Id.Id, out var collidingFacade))
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesCommand.cs
index db85a6fa..0da6a6b0 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesCommand.cs
@@ -25,23 +25,29 @@ namespace WixToolset.Core.WindowsInstaller.Bind
25 { 25 {
26 var facades = new List<FileFacade>(); 26 var facades = new List<FileFacade>();
27 27
28 var wixFiles = this.Section.Tuples.OfType<WixFileTuple>().ToDictionary(t => t.Id.Id); 28 var assemblyFile = this.Section.Tuples.OfType<AssemblyTuple>().ToDictionary(t => t.Id.Id);
29 var deltaPatchFiles = this.Section.Tuples.OfType<WixDeltaPatchFileTuple>().ToDictionary(t => t.Id.Id); 29 //var wixFiles = this.Section.Tuples.OfType<WixFileTuple>().ToDictionary(t => t.Id.Id);
30 //var deltaPatchFiles = this.Section.Tuples.OfType<WixDeltaPatchFileTuple>().ToDictionary(t => t.Id.Id);
30 31
31 foreach (var file in this.Section.Tuples.OfType<FileTuple>()) 32 foreach (var file in this.Section.Tuples.OfType<FileTuple>())
32 { 33 {
33 var wixFile = wixFiles[file.Id.Id]; 34 //var wixFile = wixFiles[file.Id.Id];
34 35
35 deltaPatchFiles.TryGetValue(file.Id.Id, out var deltaPatchFile); 36 //deltaPatchFiles.TryGetValue(file.Id.Id, out var deltaPatchFile);
36 37
37 facades.Add(new FileFacade(file, wixFile, deltaPatchFile)); 38 //facades.Add(new FileFacade(file, wixFile, deltaPatchFile));
39
40 assemblyFile.TryGetValue(file.Id.Id, out var assembly);
41
42 facades.Add(new FileFacade(file, assembly));
38 } 43 }
39 44
40 this.ResolveDeltaPatchSymbolPaths(deltaPatchFiles, facades); 45 //this.ResolveDeltaPatchSymbolPaths(deltaPatchFiles, facades);
41 46
42 this.FileFacades = facades; 47 this.FileFacades = facades;
43 } 48 }
44 49
50#if FIX_THIS
45 /// <summary> 51 /// <summary>
46 /// Merge data from the WixPatchSymbolPaths rows into the WixDeltaPatchFile rows. 52 /// Merge data from the WixPatchSymbolPaths rows into the WixDeltaPatchFile rows.
47 /// </summary> 53 /// </summary>
@@ -74,7 +80,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
74 case SymbolPathType.Directory: 80 case SymbolPathType.Directory:
75 if (null == filesByDirectory) 81 if (null == filesByDirectory)
76 { 82 {
77 filesByDirectory = facades.ToLookup(f => f.WixFile.DirectoryRef); 83 filesByDirectory = facades.ToLookup(f => f.File.DirectoryRef);
78 } 84 }
79 85
80 foreach (var facade in filesByDirectory[row.SymbolId]) 86 foreach (var facade in filesByDirectory[row.SymbolId])
@@ -86,7 +92,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
86 case SymbolPathType.Media: 92 case SymbolPathType.Media:
87 if (null == filesByDiskId) 93 if (null == filesByDiskId)
88 { 94 {
89 filesByDiskId = facades.ToLookup(f => f.WixFile.DiskId.ToString(CultureInfo.InvariantCulture)); 95 filesByDiskId = facades.ToLookup(f => f.File.DiskId.ToString(CultureInfo.InvariantCulture));
90 } 96 }
91 97
92 foreach (var facade in filesByDiskId[row.SymbolId]) 98 foreach (var facade in filesByDiskId[row.SymbolId])
@@ -141,5 +147,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
141 } 147 }
142#endif 148#endif
143 } 149 }
150#endif
144 } 151 }
145} 152}
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs
index db887f09..3c8b4999 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs
@@ -11,6 +11,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
11 using WixToolset.Core.Bind; 11 using WixToolset.Core.Bind;
12 using WixToolset.Core.WindowsInstaller.Msi; 12 using WixToolset.Core.WindowsInstaller.Msi;
13 using WixToolset.Data; 13 using WixToolset.Data;
14 using WixToolset.Data.Tuples;
14 using WixToolset.Data.WindowsInstaller; 15 using WixToolset.Data.WindowsInstaller;
15 using WixToolset.Data.WindowsInstaller.Rows; 16 using WixToolset.Data.WindowsInstaller.Rows;
16 using WixToolset.Extensibility.Services; 17 using WixToolset.Extensibility.Services;
@@ -297,8 +298,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
297 throw new InvalidOperationException("Failed to fetch a File row from the database that was merged in from a module."); 298 throw new InvalidOperationException("Failed to fetch a File row from the database that was merged in from a module.");
298 } 299 }
299 300
300 //recordUpdate.SetInteger(1, file.File.Sequence); 301 recordUpdate.SetInteger(1, file.File.Sequence);
301 throw new NotImplementedException();
302 302
303 // Update the file attributes to match the compression specified 303 // Update the file attributes to match the compression specified
304 // on the Merge element or on the Package element. 304 // on the Merge element or on the Package element.
@@ -310,22 +310,21 @@ namespace WixToolset.Core.WindowsInstaller.Bind
310 attributes = recordUpdate.GetInteger(2); 310 attributes = recordUpdate.GetInteger(2);
311 } 311 }
312 312
313 if (!file.File.Compressed.HasValue) 313 if ((file.File.Attributes & FileTupleAttributes.Compressed) == FileTupleAttributes.Compressed)
314 {
315 // Clear all compression bits.
316 attributes &= ~WindowsInstallerConstants.MsidbFileAttributesCompressed;
317 attributes &= ~WindowsInstallerConstants.MsidbFileAttributesNoncompressed;
318 }
319 else if (file.File.Compressed.Value)
320 { 314 {
321 attributes |= WindowsInstallerConstants.MsidbFileAttributesCompressed; 315 attributes |= WindowsInstallerConstants.MsidbFileAttributesCompressed;
322 attributes &= ~WindowsInstallerConstants.MsidbFileAttributesNoncompressed; 316 attributes &= ~WindowsInstallerConstants.MsidbFileAttributesNoncompressed;
323 } 317 }
324 else if (!file.File.Compressed.Value) 318 else if ((file.File.Attributes & FileTupleAttributes.Uncompressed) == FileTupleAttributes.Uncompressed)
325 { 319 {
326 attributes |= WindowsInstallerConstants.MsidbFileAttributesNoncompressed; 320 attributes |= WindowsInstallerConstants.MsidbFileAttributesNoncompressed;
327 attributes &= ~WindowsInstallerConstants.MsidbFileAttributesCompressed; 321 attributes &= ~WindowsInstallerConstants.MsidbFileAttributesCompressed;
328 } 322 }
323 else // clear all compression bits.
324 {
325 attributes &= ~WindowsInstallerConstants.MsidbFileAttributesCompressed;
326 attributes &= ~WindowsInstallerConstants.MsidbFileAttributesNoncompressed;
327 }
329 328
330 recordUpdate.SetInteger(2, attributes); 329 recordUpdate.SetInteger(2, attributes);
331 330
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/ProcessUncompressedFilesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/ProcessUncompressedFilesCommand.cs
index 369c241c..61e82f68 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/ProcessUncompressedFilesCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/ProcessUncompressedFilesCommand.cs
@@ -81,7 +81,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
81 // for each file in the array of uncompressed files 81 // for each file in the array of uncompressed files
82 foreach (FileFacade facade in this.FileFacades) 82 foreach (FileFacade facade in this.FileFacades)
83 { 83 {
84 var mediaTuple = mediaRows[facade.WixFile.DiskId]; 84 var mediaTuple = mediaRows[facade.DiskId];
85 string relativeFileLayoutPath = null; 85 string relativeFileLayoutPath = null;
86 string mediaLayoutFolder = mediaTuple.Layout; 86 string mediaLayoutFolder = mediaTuple.Layout;
87 87
@@ -105,7 +105,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
105 // finally put together the base media layout path and the relative file layout path 105 // finally put together the base media layout path and the relative file layout path
106 var fileLayoutPath = Path.Combine(mediaLayoutDirectory, relativeFileLayoutPath); 106 var fileLayoutPath = Path.Combine(mediaLayoutDirectory, relativeFileLayoutPath);
107 107
108 var transfer = this.BackendHelper.CreateFileTransfer(facade.WixFile.Source.Path, fileLayoutPath, false, facade.File.SourceLineNumbers); 108 var transfer = this.BackendHelper.CreateFileTransfer(facade.File.Source.Path, fileLayoutPath, false, facade.File.SourceLineNumbers);
109 fileTransfers.Add(transfer); 109 fileTransfers.Add(transfer);
110 110
111 // Track the location where the cabinet will be placed. If the transfer is 111 // Track the location where the cabinet will be placed. If the transfer is
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/SequenceActionsCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/SequenceActionsCommand.cs
index 3cba0f51..97602afa 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/SequenceActionsCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/SequenceActionsCommand.cs
@@ -485,7 +485,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
485 case TupleDefinitionType.MoveFile: 485 case TupleDefinitionType.MoveFile:
486 set.Add("InstallExecuteSequence/MoveFiles"); 486 set.Add("InstallExecuteSequence/MoveFiles");
487 break; 487 break;
488 case TupleDefinitionType.MsiAssembly: 488 case TupleDefinitionType.Assembly:
489 set.Add("AdvtExecuteSequence/MsiPublishAssemblies"); 489 set.Add("AdvtExecuteSequence/MsiPublishAssemblies");
490 set.Add("InstallExecuteSequence/MsiPublishAssemblies"); 490 set.Add("InstallExecuteSequence/MsiPublishAssemblies");
491 set.Add("InstallExecuteSequence/MsiUnpublishAssemblies"); 491 set.Add("InstallExecuteSequence/MsiUnpublishAssemblies");
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs
index 0d15bf2e..397092c4 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs
@@ -48,7 +48,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
48 } 48 }
49 } 49 }
50 50
51 private void UpdateFileFacade(FileFacade file) 51 private void UpdateFileFacade(FileFacade facade)
52 { 52 {
53 var assemblyNameTuples = new Dictionary<string, MsiAssemblyNameTuple>(); 53 var assemblyNameTuples = new Dictionary<string, MsiAssemblyNameTuple>();
54 foreach (var assemblyTuple in this.Section.Tuples.OfType<MsiAssemblyNameTuple>()) 54 foreach (var assemblyTuple in this.Section.Tuples.OfType<MsiAssemblyNameTuple>())
@@ -59,27 +59,27 @@ namespace WixToolset.Core.WindowsInstaller.Bind
59 FileInfo fileInfo = null; 59 FileInfo fileInfo = null;
60 try 60 try
61 { 61 {
62 fileInfo = new FileInfo(file.WixFile.Source.Path); 62 fileInfo = new FileInfo(facade.File.Source.Path);
63 } 63 }
64 catch (ArgumentException) 64 catch (ArgumentException)
65 { 65 {
66 this.Messaging.Write(ErrorMessages.InvalidFileName(file.File.SourceLineNumbers, file.WixFile.Source.Path)); 66 this.Messaging.Write(ErrorMessages.InvalidFileName(facade.File.SourceLineNumbers, facade.File.Source.Path));
67 return; 67 return;
68 } 68 }
69 catch (PathTooLongException) 69 catch (PathTooLongException)
70 { 70 {
71 this.Messaging.Write(ErrorMessages.InvalidFileName(file.File.SourceLineNumbers, file.WixFile.Source.Path)); 71 this.Messaging.Write(ErrorMessages.InvalidFileName(facade.File.SourceLineNumbers, facade.File.Source.Path));
72 return; 72 return;
73 } 73 }
74 catch (NotSupportedException) 74 catch (NotSupportedException)
75 { 75 {
76 this.Messaging.Write(ErrorMessages.InvalidFileName(file.File.SourceLineNumbers, file.WixFile.Source.Path)); 76 this.Messaging.Write(ErrorMessages.InvalidFileName(facade.File.SourceLineNumbers, facade.File.Source.Path));
77 return; 77 return;
78 } 78 }
79 79
80 if (!fileInfo.Exists) 80 if (!fileInfo.Exists)
81 { 81 {
82 this.Messaging.Write(ErrorMessages.CannotFindFile(file.File.SourceLineNumbers, file.File.Id.Id, file.File.Name, file.WixFile.Source.Path)); 82 this.Messaging.Write(ErrorMessages.CannotFindFile(facade.File.SourceLineNumbers, facade.File.Id.Id, facade.File.Name, facade.File.Source.Path));
83 return; 83 return;
84 } 84 }
85 85
@@ -87,10 +87,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind
87 { 87 {
88 if (Int32.MaxValue < fileStream.Length) 88 if (Int32.MaxValue < fileStream.Length)
89 { 89 {
90 throw new WixException(ErrorMessages.FileTooLarge(file.File.SourceLineNumbers, file.WixFile.Source.Path)); 90 throw new WixException(ErrorMessages.FileTooLarge(facade.File.SourceLineNumbers, facade.File.Source.Path));
91 } 91 }
92 92
93 file.File.FileSize = Convert.ToInt32(fileStream.Length, CultureInfo.InvariantCulture); 93 facade.File.FileSize = Convert.ToInt32(fileStream.Length, CultureInfo.InvariantCulture);
94 } 94 }
95 95
96 string version = null; 96 string version = null;
@@ -103,7 +103,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
103 { 103 {
104 if (0x2 == e.NativeErrorCode) // ERROR_FILE_NOT_FOUND 104 if (0x2 == e.NativeErrorCode) // ERROR_FILE_NOT_FOUND
105 { 105 {
106 throw new WixException(ErrorMessages.FileNotFound(file.File.SourceLineNumbers, fileInfo.FullName)); 106 throw new WixException(ErrorMessages.FileNotFound(facade.File.SourceLineNumbers, fileInfo.FullName));
107 } 107 }
108 else 108 else
109 { 109 {
@@ -118,7 +118,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
118 { 118 {
119 // not overwriting hash, so don't do the rest of these options. 119 // not overwriting hash, so don't do the rest of these options.
120 } 120 }
121 else if (null != file.File.Version) 121 else if (null != facade.File.Version)
122 { 122 {
123 // Search all of the file rows available to see if the specified version is actually a companion file. Yes, this looks 123 // Search all of the file rows available to see if the specified version is actually a companion file. Yes, this looks
124 // very expensive and you're probably thinking it would be better to create an index of some sort to do an O(1) look up. 124 // very expensive and you're probably thinking it would be better to create an index of some sort to do an O(1) look up.
@@ -127,16 +127,16 @@ namespace WixToolset.Core.WindowsInstaller.Bind
127 // 127 //
128 // Also, if we do not find a matching file identifier then the user provided a default version and is providing a version 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. 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.Id.Id, StringComparison.Ordinal))) 130 if (!this.FileFacades.Any(r => facade.File.Version.Equals(r.File.Id.Id, StringComparison.Ordinal)))
131 { 131 {
132 this.Messaging.Write(WarningMessages.DefaultVersionUsedForUnversionedFile(file.File.SourceLineNumbers, file.File.Version, file.File.Id.Id)); 132 this.Messaging.Write(WarningMessages.DefaultVersionUsedForUnversionedFile(facade.File.SourceLineNumbers, facade.File.Version, facade.File.Id.Id));
133 } 133 }
134 } 134 }
135 else 135 else
136 { 136 {
137 if (null != file.File.Language) 137 if (null != facade.File.Language)
138 { 138 {
139 this.Messaging.Write(WarningMessages.DefaultLanguageUsedForUnversionedFile(file.File.SourceLineNumbers, file.File.Language, file.File.Id.Id)); 139 this.Messaging.Write(WarningMessages.DefaultLanguageUsedForUnversionedFile(facade.File.SourceLineNumbers, facade.File.Language, facade.File.Id.Id));
140 } 140 }
141 141
142 int[] hash; 142 int[] hash;
@@ -148,7 +148,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
148 { 148 {
149 if (0x2 == e.NativeErrorCode) // ERROR_FILE_NOT_FOUND 149 if (0x2 == e.NativeErrorCode) // ERROR_FILE_NOT_FOUND
150 { 150 {
151 throw new WixException(ErrorMessages.FileNotFound(file.File.SourceLineNumbers, fileInfo.FullName)); 151 throw new WixException(ErrorMessages.FileNotFound(facade.File.SourceLineNumbers, fileInfo.FullName));
152 } 152 }
153 else 153 else
154 { 154 {
@@ -156,29 +156,29 @@ namespace WixToolset.Core.WindowsInstaller.Bind
156 } 156 }
157 } 157 }
158 158
159 if (null == file.Hash) 159 if (null == facade.Hash)
160 { 160 {
161 file.Hash = new MsiFileHashTuple(file.File.SourceLineNumbers, file.File.Id); 161 facade.Hash = new MsiFileHashTuple(facade.File.SourceLineNumbers, facade.File.Id);
162 this.Section.Tuples.Add(file.Hash); 162 this.Section.Tuples.Add(facade.Hash);
163 } 163 }
164 164
165 file.Hash.FileRef = file.File.Id.Id; 165 facade.Hash.FileRef = facade.File.Id.Id;
166 file.Hash.Options = 0; 166 facade.Hash.Options = 0;
167 file.Hash.HashPart1 = hash[0]; 167 facade.Hash.HashPart1 = hash[0];
168 file.Hash.HashPart2 = hash[1]; 168 facade.Hash.HashPart2 = hash[1];
169 file.Hash.HashPart3 = hash[2]; 169 facade.Hash.HashPart3 = hash[2];
170 file.Hash.HashPart4 = hash[3]; 170 facade.Hash.HashPart4 = hash[3];
171 } 171 }
172 } 172 }
173 else // update the file row with the version and language information. 173 else // update the file row with the version and language information.
174 { 174 {
175 // If no version was provided by the user, use the version from the file itself. 175 // If no version was provided by the user, use the version from the file itself.
176 // This is the most common case. 176 // This is the most common case.
177 if (String.IsNullOrEmpty(file.File.Version)) 177 if (String.IsNullOrEmpty(facade.File.Version))
178 { 178 {
179 file.File.Version = version; 179 facade.File.Version = version;
180 } 180 }
181 else if (!this.FileFacades.Any(r => file.File.Version.Equals(r.File.Id.Id, StringComparison.Ordinal))) // this looks expensive, but see explanation below. 181 else if (!this.FileFacades.Any(r => facade.File.Version.Equals(r.File.Id.Id, StringComparison.Ordinal))) // this looks expensive, but see explanation below.
182 { 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 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 184 // the version value). We didn't find it so, we will override the default version they provided with the actual
@@ -189,49 +189,49 @@ namespace WixToolset.Core.WindowsInstaller.Bind
189 // 189 //
190 // Also note this case can occur when the file is being updated using the WixBindUpdatedFiles extension mechanism. 190 // Also note this case can occur when the file is being updated using the WixBindUpdatedFiles extension mechanism.
191 // That's typically even more rare than companion files so again, no index, just search. 191 // That's typically even more rare than companion files so again, no index, just search.
192 file.File.Version = version; 192 facade.File.Version = version;
193 } 193 }
194 194
195 if (!String.IsNullOrEmpty(file.File.Language) && String.IsNullOrEmpty(language)) 195 if (!String.IsNullOrEmpty(facade.File.Language) && String.IsNullOrEmpty(language))
196 { 196 {
197 this.Messaging.Write(WarningMessages.DefaultLanguageUsedForVersionedFile(file.File.SourceLineNumbers, file.File.Language, file.File.Id.Id)); 197 this.Messaging.Write(WarningMessages.DefaultLanguageUsedForVersionedFile(facade.File.SourceLineNumbers, facade.File.Language, facade.File.Id.Id));
198 } 198 }
199 else // override the default provided by the user (usually nothing) with the actual language from the file itself. 199 else // override the default provided by the user (usually nothing) with the actual language from the file itself.
200 { 200 {
201 file.File.Language = language; 201 facade.File.Language = language;
202 } 202 }
203 203
204 // Populate the binder variables for this file information if requested. 204 // Populate the binder variables for this file information if requested.
205 if (null != this.VariableCache) 205 if (null != this.VariableCache)
206 { 206 {
207 if (!String.IsNullOrEmpty(file.File.Version)) 207 if (!String.IsNullOrEmpty(facade.File.Version))
208 { 208 {
209 var key = String.Format(CultureInfo.InvariantCulture, "fileversion.{0}", file.File.Id.Id); 209 var key = String.Format(CultureInfo.InvariantCulture, "fileversion.{0}", facade.File.Id.Id);
210 this.VariableCache[key] = file.File.Version; 210 this.VariableCache[key] = facade.File.Version;
211 } 211 }
212 212
213 if (!String.IsNullOrEmpty(file.File.Language)) 213 if (!String.IsNullOrEmpty(facade.File.Language))
214 { 214 {
215 var key = String.Format(CultureInfo.InvariantCulture, "filelanguage.{0}", file.File.Id.Id); 215 var key = String.Format(CultureInfo.InvariantCulture, "filelanguage.{0}", facade.File.Id.Id);
216 this.VariableCache[key] = file.File.Language; 216 this.VariableCache[key] = facade.File.Language;
217 } 217 }
218 } 218 }
219 } 219 }
220 220
221 // If this is a CLR assembly, load the assembly and get the assembly name information 221 // If this is a CLR assembly, load the assembly and get the assembly name information
222 if (FileAssemblyType.DotNetAssembly == file.WixFile.AssemblyType) 222 if (AssemblyType.DotNetAssembly == facade.Assembly?.Type)
223 { 223 {
224 try 224 try
225 { 225 {
226 var assemblyName = AssemblyNameReader.ReadAssembly(file.File.SourceLineNumbers, fileInfo.FullName, version); 226 var assemblyName = AssemblyNameReader.ReadAssembly(facade.File.SourceLineNumbers, fileInfo.FullName, version);
227 227
228 this.SetMsiAssemblyName(assemblyNameTuples, file, "name", assemblyName.Name); 228 this.SetMsiAssemblyName(assemblyNameTuples, facade, "name", assemblyName.Name);
229 this.SetMsiAssemblyName(assemblyNameTuples, file, "culture", assemblyName.Culture); 229 this.SetMsiAssemblyName(assemblyNameTuples, facade, "culture", assemblyName.Culture);
230 this.SetMsiAssemblyName(assemblyNameTuples, file, "version", assemblyName.Version); 230 this.SetMsiAssemblyName(assemblyNameTuples, facade, "version", assemblyName.Version);
231 231
232 if (!String.IsNullOrEmpty(assemblyName.Architecture)) 232 if (!String.IsNullOrEmpty(assemblyName.Architecture))
233 { 233 {
234 this.SetMsiAssemblyName(assemblyNameTuples, file, "processorArchitecture", assemblyName.Architecture); 234 this.SetMsiAssemblyName(assemblyNameTuples, facade, "processorArchitecture", assemblyName.Architecture);
235 } 235 }
236 // TODO: WiX v3 seemed to do this but not clear it should actually be done. 236 // TODO: WiX v3 seemed to do this but not clear it should actually be done.
237 //else if (!String.IsNullOrEmpty(file.WixFile.ProcessorArchitecture)) 237 //else if (!String.IsNullOrEmpty(file.WixFile.ProcessorArchitecture))
@@ -241,22 +241,22 @@ namespace WixToolset.Core.WindowsInstaller.Bind
241 241
242 if (assemblyName.StrongNamedSigned) 242 if (assemblyName.StrongNamedSigned)
243 { 243 {
244 this.SetMsiAssemblyName(assemblyNameTuples, file, "publicKeyToken", assemblyName.PublicKeyToken); 244 this.SetMsiAssemblyName(assemblyNameTuples, facade, "publicKeyToken", assemblyName.PublicKeyToken);
245 } 245 }
246 else if (file.WixFile.AssemblyApplicationFileRef == null) 246 else if (facade.Assembly.ApplicationFileRef == null)
247 { 247 {
248 throw new WixException(ErrorMessages.GacAssemblyNoStrongName(file.File.SourceLineNumbers, fileInfo.FullName, file.File.ComponentRef)); 248 throw new WixException(ErrorMessages.GacAssemblyNoStrongName(facade.File.SourceLineNumbers, fileInfo.FullName, facade.File.ComponentRef));
249 } 249 }
250 250
251 if (!String.IsNullOrEmpty(assemblyName.FileVersion)) 251 if (!String.IsNullOrEmpty(assemblyName.FileVersion))
252 { 252 {
253 this.SetMsiAssemblyName(assemblyNameTuples, file, "fileVersion", assemblyName.FileVersion); 253 this.SetMsiAssemblyName(assemblyNameTuples, facade, "fileVersion", assemblyName.FileVersion);
254 } 254 }
255 255
256 // add the assembly name to the information cache 256 // add the assembly name to the information cache
257 if (null != this.VariableCache) 257 if (null != this.VariableCache)
258 { 258 {
259 this.VariableCache[$"assemblyfullname.{file.File.Id.Id}"] = assemblyName.GetFullName(); 259 this.VariableCache[$"assemblyfullname.{facade.File.Id.Id}"] = assemblyName.GetFullName();
260 } 260 }
261 } 261 }
262 catch (WixException e) 262 catch (WixException e)
@@ -264,44 +264,44 @@ namespace WixToolset.Core.WindowsInstaller.Bind
264 this.Messaging.Write(e.Error); 264 this.Messaging.Write(e.Error);
265 } 265 }
266 } 266 }
267 else if (FileAssemblyType.Win32Assembly == file.WixFile.AssemblyType) 267 else if (AssemblyType.Win32Assembly == facade.Assembly?.Type)
268 { 268 {
269 // TODO: Consider passing in the this.FileFacades as an indexed collection instead of searching through 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 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. 271 // file earlier.
272 var fileManifest = this.FileFacades.FirstOrDefault(r => r.File.Id.Id.Equals(file.WixFile.AssemblyManifestFileRef, StringComparison.Ordinal)); 272 var fileManifest = this.FileFacades.FirstOrDefault(r => r.File.Id.Id.Equals(facade.Assembly.ManifestFileRef, StringComparison.Ordinal));
273 if (null == fileManifest) 273 if (null == fileManifest)
274 { 274 {
275 this.Messaging.Write(ErrorMessages.MissingManifestForWin32Assembly(file.File.SourceLineNumbers, file.File.Id.Id, file.WixFile.AssemblyManifestFileRef)); 275 this.Messaging.Write(ErrorMessages.MissingManifestForWin32Assembly(facade.File.SourceLineNumbers, facade.File.Id.Id, facade.Assembly.ManifestFileRef));
276 } 276 }
277 277
278 try 278 try
279 { 279 {
280 var assemblyName = AssemblyNameReader.ReadAssemblyManifest(file.File.SourceLineNumbers, fileManifest.WixFile.Source.Path); 280 var assemblyName = AssemblyNameReader.ReadAssemblyManifest(facade.File.SourceLineNumbers, fileManifest.File.Source.Path);
281 281
282 if (!String.IsNullOrEmpty(assemblyName.Name)) 282 if (!String.IsNullOrEmpty(assemblyName.Name))
283 { 283 {
284 this.SetMsiAssemblyName(assemblyNameTuples, file, "name", assemblyName.Name); 284 this.SetMsiAssemblyName(assemblyNameTuples, facade, "name", assemblyName.Name);
285 } 285 }
286 286
287 if (!String.IsNullOrEmpty(assemblyName.Version)) 287 if (!String.IsNullOrEmpty(assemblyName.Version))
288 { 288 {
289 this.SetMsiAssemblyName(assemblyNameTuples, file, "version", assemblyName.Version); 289 this.SetMsiAssemblyName(assemblyNameTuples, facade, "version", assemblyName.Version);
290 } 290 }
291 291
292 if (!String.IsNullOrEmpty(assemblyName.Type)) 292 if (!String.IsNullOrEmpty(assemblyName.Type))
293 { 293 {
294 this.SetMsiAssemblyName(assemblyNameTuples, file, "type", assemblyName.Type); 294 this.SetMsiAssemblyName(assemblyNameTuples, facade, "type", assemblyName.Type);
295 } 295 }
296 296
297 if (!String.IsNullOrEmpty(assemblyName.Architecture)) 297 if (!String.IsNullOrEmpty(assemblyName.Architecture))
298 { 298 {
299 this.SetMsiAssemblyName(assemblyNameTuples, file, "processorArchitecture", assemblyName.Architecture); 299 this.SetMsiAssemblyName(assemblyNameTuples, facade, "processorArchitecture", assemblyName.Architecture);
300 } 300 }
301 301
302 if (!String.IsNullOrEmpty(assemblyName.PublicKeyToken)) 302 if (!String.IsNullOrEmpty(assemblyName.PublicKeyToken))
303 { 303 {
304 this.SetMsiAssemblyName(assemblyNameTuples, file, "publicKeyToken", assemblyName.PublicKeyToken); 304 this.SetMsiAssemblyName(assemblyNameTuples, facade, "publicKeyToken", assemblyName.PublicKeyToken);
305 } 305 }
306 } 306 }
307 catch (WixException e) 307 catch (WixException e)
@@ -329,8 +329,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
329 else 329 else
330 { 330 {
331 // if the assembly will be GAC'd and the name in the file table doesn't match the name in the MsiAssemblyName table, error because the install will fail. 331 // if the assembly will be GAC'd and the name in the file table doesn't match the name in the MsiAssemblyName table, error because the install will fail.
332 if ("name" == name && FileAssemblyType.DotNetAssembly == file.WixFile.AssemblyType && 332 if ("name" == name && AssemblyType.DotNetAssembly == file.Assembly.Type &&
333 String.IsNullOrEmpty(file.WixFile.AssemblyApplicationFileRef) && 333 String.IsNullOrEmpty(file.Assembly.ApplicationFileRef) &&
334 !String.Equals(Path.GetFileNameWithoutExtension(file.File.Name), value, StringComparison.OrdinalIgnoreCase)) 334 !String.Equals(Path.GetFileNameWithoutExtension(file.File.Name), value, StringComparison.OrdinalIgnoreCase))
335 { 335 {
336 this.Messaging.Write(ErrorMessages.GACAssemblyIdentityWarning(file.File.SourceLineNumbers, Path.GetFileNameWithoutExtension(file.File.Name), value)); 336 this.Messaging.Write(ErrorMessages.GACAssemblyIdentityWarning(file.File.SourceLineNumbers, Path.GetFileNameWithoutExtension(file.File.Name), value));
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/UpdateMediaSequencesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/UpdateMediaSequencesCommand.cs
index f9df9636..889d5df2 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/UpdateMediaSequencesCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/UpdateMediaSequencesCommand.cs
@@ -51,25 +51,25 @@ namespace WixToolset.Core.WindowsInstaller.Bind
51 { 51 {
52 if (null == mediaRow) 52 if (null == mediaRow)
53 { 53 {
54 mediaRow = mediaRows.Get(facade.WixFile.DiskId); 54 mediaRow = mediaRows.Get(facade.DiskId);
55 if (OutputType.Patch == this.Output.Type) 55 if (OutputType.Patch == this.Output.Type)
56 { 56 {
57 // patch Media cannot start at zero 57 // patch Media cannot start at zero
58 lastSequence = mediaRow.LastSequence; 58 lastSequence = mediaRow.LastSequence;
59 } 59 }
60 } 60 }
61 else if (mediaRow.DiskId != facade.WixFile.DiskId) 61 else if (mediaRow.DiskId != facade.DiskId)
62 { 62 {
63 mediaRow.LastSequence = lastSequence; 63 mediaRow.LastSequence = lastSequence;
64 mediaRow = mediaRows.Get(facade.WixFile.DiskId); 64 mediaRow = mediaRows.Get(facade.DiskId);
65 } 65 }
66 66
67 if (0 < facade.WixFile.PatchGroup) 67 if (facade.File.PatchGroup.HasValue)
68 { 68 {
69 if (patchGroups.TryGetValue(facade.WixFile.PatchGroup, out var patchGroup)) 69 if (patchGroups.TryGetValue(facade.File.PatchGroup.Value, out var patchGroup))
70 { 70 {
71 patchGroup = new List<FileFacade>(); 71 patchGroup = new List<FileFacade>();
72 patchGroups.Add(facade.WixFile.PatchGroup, patchGroup); 72 patchGroups.Add(facade.File.PatchGroup.Value, patchGroup);
73 } 73 }
74 74
75 patchGroup.Add(facade); 75 patchGroup.Add(facade);
@@ -94,12 +94,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind
94 { 94 {
95 if (null == mediaRow) 95 if (null == mediaRow)
96 { 96 {
97 mediaRow = mediaRows.Get(facade.WixFile.DiskId); 97 mediaRow = mediaRows.Get(facade.DiskId);
98 } 98 }
99 else if (mediaRow.DiskId != facade.WixFile.DiskId) 99 else if (mediaRow.DiskId != facade.DiskId)
100 { 100 {
101 mediaRow.LastSequence = lastSequence; 101 mediaRow.LastSequence = lastSequence;
102 mediaRow = mediaRows.Get(facade.WixFile.DiskId); 102 mediaRow = mediaRows.Get(facade.DiskId);
103 } 103 }
104 104
105 var fileRow = fileRows.Get(facade.File.Id.Id); 105 var fileRow = fileRows.Get(facade.File.Id.Id);
diff --git a/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs b/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs
index 4c24ff7e..e671f6a1 100644
--- a/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs
@@ -444,6 +444,8 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
444 /// <param name="output">The Output that represents the msi database.</param> 444 /// <param name="output">The Output that represents the msi database.</param>
445 private void GenerateWixFileTable(string databaseFile, Output output) 445 private void GenerateWixFileTable(string databaseFile, Output output)
446 { 446 {
447 throw new NotImplementedException();
448#if TODO_FIX_UNBINDING_FILES
447 var adminRootPath = Path.GetDirectoryName(databaseFile); 449 var adminRootPath = Path.GetDirectoryName(databaseFile);
448 450
449 var componentDirectoryIndex = new Hashtable(); 451 var componentDirectoryIndex = new Hashtable();
@@ -495,6 +497,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
495 497
496 wixFileTable.Rows.Add(wixFileRow); 498 wixFileTable.Rows.Add(wixFileRow);
497 } 499 }
500#endif
498 } 501 }
499 502
500 /// <summary> 503 /// <summary>
diff --git a/src/WixToolset.Core/Bind/FileFacade.cs b/src/WixToolset.Core/Bind/FileFacade.cs
index 825c2c7a..d631a3b5 100644
--- a/src/WixToolset.Core/Bind/FileFacade.cs
+++ b/src/WixToolset.Core/Bind/FileFacade.cs
@@ -7,27 +7,27 @@ namespace WixToolset.Core.Bind
7 7
8 public class FileFacade 8 public class FileFacade
9 { 9 {
10 public FileFacade(FileTuple file, WixFileTuple wixFile, WixDeltaPatchFileTuple deltaPatchFile) 10 public FileFacade(FileTuple file, AssemblyTuple assembly)
11 { 11 {
12 this.File = file; 12 this.File = file;
13 this.WixFile = wixFile; 13 this.Assembly = assembly;
14 this.DeltaPatchFile = deltaPatchFile;
15 } 14 }
16 15
17 public FileFacade(bool fromModule, FileTuple file, WixFileTuple wixFile) 16 public FileFacade(bool fromModule, FileTuple file)
18 { 17 {
19 this.FromModule = fromModule; 18 this.FromModule = fromModule;
20 this.File = file; 19 this.File = file;
21 this.WixFile = wixFile;
22 } 20 }
23 21
24 public bool FromModule { get; } 22 public bool FromModule { get; }
25 23
26 public FileTuple File { get; } 24 public FileTuple File { get; }
27 25
28 public WixFileTuple WixFile { get; } 26 public AssemblyTuple Assembly { get; }
29 27
30 public WixDeltaPatchFileTuple DeltaPatchFile { get; } 28 public int DiskId => this.File.DiskId ?? 0;
29
30 public bool Uncompressed => (this.File.Attributes & FileTupleAttributes.Uncompressed) == FileTupleAttributes.Uncompressed;
31 31
32 /// <summary> 32 /// <summary>
33 /// Gets the set of MsiAssemblyName rows created for this file. 33 /// Gets the set of MsiAssemblyName rows created for this file.
diff --git a/src/WixToolset.Core/Compiler.cs b/src/WixToolset.Core/Compiler.cs
index d543c6b8..0dade46d 100644
--- a/src/WixToolset.Core/Compiler.cs
+++ b/src/WixToolset.Core/Compiler.cs
@@ -32,7 +32,6 @@ namespace WixToolset.Core
32 private bool compilingModule; 32 private bool compilingModule;
33 private bool compilingProduct; 33 private bool compilingProduct;
34 34
35 private bool useShortFileNames;
36 private string activeName; 35 private string activeName;
37 private string activeLanguage; 36 private string activeLanguage;
38 37
@@ -4184,16 +4183,7 @@ namespace WixToolset.Core
4184 } 4183 }
4185 else // add the appropriate part of this directory element to the file source. 4184 else // add the appropriate part of this directory element to the file source.
4186 { 4185 {
4187 string append = null; 4186 string append = String.IsNullOrEmpty(sourceName) ? name : sourceName;
4188 if (this.useShortFileNames)
4189 {
4190 append = !String.IsNullOrEmpty(shortSourceName) ? shortSourceName : shortName;
4191 }
4192
4193 if (String.IsNullOrEmpty(append))
4194 {
4195 append = !String.IsNullOrEmpty(sourceName) ? sourceName : name;
4196 }
4197 4187
4198 if (!String.IsNullOrEmpty(append)) 4188 if (!String.IsNullOrEmpty(append))
4199 { 4189 {
@@ -5486,7 +5476,7 @@ namespace WixToolset.Core
5486 { 5476 {
5487 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 5477 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
5488 Identifier id = null; 5478 Identifier id = null;
5489 var assemblyType = FileAssemblyType.NotAnAssembly; 5479 var assemblyType = AssemblyType.NotAnAssembly;
5490 string assemblyApplication = null; 5480 string assemblyApplication = null;
5491 string assemblyManifest = null; 5481 string assemblyManifest = null;
5492 string bindPath = null; 5482 string bindPath = null;
@@ -5538,13 +5528,13 @@ namespace WixToolset.Core
5538 switch (assemblyValue) 5528 switch (assemblyValue)
5539 { 5529 {
5540 case ".net": 5530 case ".net":
5541 assemblyType = FileAssemblyType.DotNetAssembly; 5531 assemblyType = AssemblyType.DotNetAssembly;
5542 break; 5532 break;
5543 case "no": 5533 case "no":
5544 assemblyType = FileAssemblyType.NotAnAssembly; 5534 assemblyType = AssemblyType.NotAnAssembly;
5545 break; 5535 break;
5546 case "win32": 5536 case "win32":
5547 assemblyType = FileAssemblyType.Win32Assembly; 5537 assemblyType = AssemblyType.Win32Assembly;
5548 break; 5538 break;
5549 default: 5539 default:
5550 this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "File", "Assembly", assemblyValue, "no", "win32", ".net")); 5540 this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, "File", "Assembly", assemblyValue, "no", "win32", ".net"));
@@ -5743,7 +5733,7 @@ namespace WixToolset.Core
5743 this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DefaultVersion", "CompanionFile", companionFile)); 5733 this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DefaultVersion", "CompanionFile", companionFile));
5744 } 5734 }
5745 5735
5746 if (FileAssemblyType.NotAnAssembly == assemblyType) 5736 if (AssemblyType.NotAnAssembly == assemblyType)
5747 { 5737 {
5748 if (null != assemblyManifest) 5738 if (null != assemblyManifest)
5749 { 5739 {
@@ -5757,7 +5747,7 @@ namespace WixToolset.Core
5757 } 5747 }
5758 else 5748 else
5759 { 5749 {
5760 if (FileAssemblyType.Win32Assembly == assemblyType && null == assemblyManifest) 5750 if (AssemblyType.Win32Assembly == assemblyType && null == assemblyManifest)
5761 { 5751 {
5762 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "AssemblyManifest", "Assembly", "win32")); 5752 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "AssemblyManifest", "Assembly", "win32"));
5763 } 5753 }
@@ -5765,7 +5755,7 @@ namespace WixToolset.Core
5765 // allow "*" guid components to omit explicit KeyPath as they can have only one file and therefore this file is the keypath 5755 // allow "*" guid components to omit explicit KeyPath as they can have only one file and therefore this file is the keypath
5766 if (YesNoType.Yes != keyPath && "*" != componentGuid) 5756 if (YesNoType.Yes != keyPath && "*" != componentGuid)
5767 { 5757 {
5768 this.Core.Write(ErrorMessages.IllegalAttributeValueWithoutOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Assembly", (FileAssemblyType.DotNetAssembly == assemblyType ? ".net" : "win32"), "KeyPath", "yes")); 5758 this.Core.Write(ErrorMessages.IllegalAttributeValueWithoutOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Assembly", (AssemblyType.DotNetAssembly == assemblyType ? ".net" : "win32"), "KeyPath", "yes"));
5769 } 5759 }
5770 } 5760 }
5771 5761
@@ -5852,90 +5842,72 @@ namespace WixToolset.Core
5852 5842
5853 if (String.IsNullOrEmpty(source)) 5843 if (String.IsNullOrEmpty(source))
5854 { 5844 {
5855 if (!this.useShortFileNames && null != name) 5845 source = name ?? shortName;
5856 {
5857 source = name;
5858 }
5859 else
5860 {
5861 source = shortName;
5862 }
5863 } 5846 }
5864 else if (source.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)) // if source relies on parent directories, append the file name 5847 else if (source.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)) // if source relies on parent directories, append the file name
5865 { 5848 {
5866 if (!this.useShortFileNames && null != name) 5849 source = null == name ? Path.Combine(source, shortName) : Path.Combine(source, name);
5867 {
5868 source = Path.Combine(source, name);
5869 }
5870 else
5871 {
5872 source = Path.Combine(source, shortName);
5873 }
5874 } 5850 }
5875 5851
5852 var attributes = FileTupleAttributes.None;
5853 attributes |= readOnly ? FileTupleAttributes.ReadOnly : 0;
5854 attributes |= hidden ? FileTupleAttributes.Hidden : 0;
5855 attributes |= system ? FileTupleAttributes.System : 0;
5856 attributes |= vital ? FileTupleAttributes.Vital : 0;
5857 attributes |= checksum ? FileTupleAttributes.Checksum : 0;
5858 attributes |= compressed.HasValue && compressed == true ? FileTupleAttributes.Compressed : 0;
5859 attributes |= compressed.HasValue && compressed == false ? FileTupleAttributes.Uncompressed : 0;
5860 attributes |= generatedShortFileName ? FileTupleAttributes.GeneratedShortFileName : 0;
5861
5876 var tuple = new FileTuple(sourceLineNumbers, id) 5862 var tuple = new FileTuple(sourceLineNumbers, id)
5877 { 5863 {
5878 ComponentRef = componentId, 5864 ComponentRef = componentId,
5879 ShortName = shortName,
5880 Name = name, 5865 Name = name,
5866 ShortName = shortName,
5881 FileSize = defaultSize, 5867 FileSize = defaultSize,
5882 Version = companionFile ?? defaultVersion, 5868 Version = companionFile ?? defaultVersion,
5883 Language = defaultLanguage, 5869 Language = defaultLanguage,
5884 ReadOnly = readOnly, 5870 Attributes = attributes,
5885 Hidden = hidden, 5871
5886 System = system, 5872 //ReadOnly = readOnly,
5887 Vital = vital, 5873 //Hidden = hidden,
5888 Checksum = checksum, 5874 //System = system,
5889 Compressed = compressed, 5875 //Vital = vital,
5876 //Checksum = checksum,
5877 //Compressed = compressed,
5878 //GeneratedShortFileName = generatedShortFileName,
5879
5880 DirectoryRef = directoryId,
5881 DiskId = (CompilerConstants.IntegerNotSet == diskId) ? null : (int?)diskId,
5882 Source = new IntermediateFieldPathValue { Path = source },
5883
5890 FontTitle = fontTitle, 5884 FontTitle = fontTitle,
5891 SelfRegCost = selfRegCost, 5885 SelfRegCost = selfRegCost,
5892 BindPath = bindPath, 5886 BindPath = bindPath,
5893 };
5894 5887
5895 this.Core.AddTuple(tuple); 5888 PatchGroup = (CompilerConstants.IntegerNotSet == patchGroup) ? null : (int?)patchGroup,
5889 PatchAttributes = patchAttributes,
5896 5890
5897 // TODO: Remove all this. 5891 // Delta patching information
5898 var wixFileRow = (WixFileTuple)this.Core.CreateTuple(sourceLineNumbers, TupleDefinitionType.WixFile, id);
5899 wixFileRow.AssemblyType = assemblyType;
5900 wixFileRow.AssemblyManifestFileRef = assemblyManifest;
5901 wixFileRow.AssemblyApplicationFileRef = assemblyApplication;
5902 wixFileRow.DirectoryRef = directoryId;
5903 wixFileRow.DiskId = (CompilerConstants.IntegerNotSet == diskId) ? 0 : diskId;
5904 wixFileRow.Source = new IntermediateFieldPathValue { Path = source };
5905 wixFileRow.ProcessorArchitecture = procArch;
5906 wixFileRow.PatchGroup = (CompilerConstants.IntegerNotSet != patchGroup ? patchGroup : -1);
5907 wixFileRow.Attributes = (generatedShortFileName ? 0x1 : 0x0);
5908 wixFileRow.PatchAttributes = patchAttributes;
5909
5910 // Always create a delta patch row for this file since other elements (like Component and Media) may
5911 // want to add symbol paths to it.
5912 this.Core.AddTuple(new WixDeltaPatchFileTuple(sourceLineNumbers, id)
5913 {
5914 RetainLengths = protectLengths, 5892 RetainLengths = protectLengths,
5915 IgnoreOffsets = ignoreOffsets, 5893 IgnoreOffsets = ignoreOffsets,
5916 IgnoreLengths = ignoreLengths, 5894 IgnoreLengths = ignoreLengths,
5917 RetainOffsets = protectOffsets 5895 RetainOffsets = protectOffsets,
5918 }); 5896 SymbolPaths = symbols
5897 };
5919 5898
5920 if (null != symbols) 5899 this.Core.AddTuple(tuple);
5921 {
5922 this.Core.AddTuple(new WixDeltaPatchSymbolPathsTuple(sourceLineNumbers)
5923 {
5924 SymbolType = SymbolPathType.File,
5925 SymbolId = id.Id,
5926 SymbolPaths = symbols
5927 });
5928 }
5929 5900
5930 if (FileAssemblyType.NotAnAssembly != assemblyType) 5901 if (AssemblyType.NotAnAssembly != assemblyType)
5931 { 5902 {
5932 this.Core.AddTuple(new MsiAssemblyTuple(sourceLineNumbers) 5903 this.Core.AddTuple(new AssemblyTuple(sourceLineNumbers, id)
5933 { 5904 {
5934 ComponentRef = componentId, 5905 ComponentRef = componentId,
5935 FeatureRef = Guid.Empty.ToString("B"), 5906 FeatureRef = Guid.Empty.ToString("B"),
5936 ManifestFileRef = assemblyManifest, 5907 ManifestFileRef = assemblyManifest,
5937 ApplicationFileRef = assemblyApplication, 5908 ApplicationFileRef = assemblyApplication,
5938 Type = assemblyType 5909 Type = assemblyType,
5910 ProcessorArchitecture = procArch,
5939 }); 5911 });
5940 } 5912 }
5941 } 5913 }
@@ -7599,7 +7571,7 @@ namespace WixToolset.Core
7599 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 7571 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
7600 Identifier id = null; 7572 Identifier id = null;
7601 var configData = String.Empty; 7573 var configData = String.Empty;
7602 bool? fileCompression = null; 7574 FileTupleAttributes attributes = 0;
7603 string language = null; 7575 string language = null;
7604 string sourceFile = null; 7576 string sourceFile = null;
7605 7577
@@ -7617,7 +7589,9 @@ namespace WixToolset.Core
7617 this.Core.CreateSimpleReference(sourceLineNumbers, "Media", diskId.ToString(CultureInfo.InvariantCulture.NumberFormat)); 7589 this.Core.CreateSimpleReference(sourceLineNumbers, "Media", diskId.ToString(CultureInfo.InvariantCulture.NumberFormat));
7618 break; 7590 break;
7619 case "FileCompression": 7591 case "FileCompression":
7620 fileCompression = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 7592 var compress = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
7593 attributes |= compress == YesNoType.Yes ? FileTupleAttributes.Compressed : 0;
7594 attributes |= compress == YesNoType.No ? FileTupleAttributes.Uncompressed : 0;
7621 break; 7595 break;
7622 case "Language": 7596 case "Language":
7623 language = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, Int16.MaxValue); 7597 language = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, Int16.MaxValue);
@@ -7692,7 +7666,7 @@ namespace WixToolset.Core
7692 SourceFile = sourceFile, 7666 SourceFile = sourceFile,
7693 DiskId = diskId, 7667 DiskId = diskId,
7694 ConfigurationData = configData, 7668 ConfigurationData = configData,
7695 FileCompression = fileCompression, 7669 FileAttributes = attributes,
7696 FeatureRef = Guid.Empty.ToString("B") 7670 FeatureRef = Guid.Empty.ToString("B")
7697 }; 7671 };
7698 7672
diff --git a/src/WixToolset.Core/Compiler_2.cs b/src/WixToolset.Core/Compiler_2.cs
index 9e965465..3ad8acf9 100644
--- a/src/WixToolset.Core/Compiler_2.cs
+++ b/src/WixToolset.Core/Compiler_2.cs
@@ -760,7 +760,6 @@ namespace WixToolset.Core
760 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 760 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
761 { 761 {
762 sourceBits |= 1; 762 sourceBits |= 1;
763 this.useShortFileNames = true;
764 } 763 }
765 break; 764 break;
766 case "SummaryCodepage": 765 case "SummaryCodepage":
diff --git a/src/WixToolset.Core/Linker.cs b/src/WixToolset.Core/Linker.cs
index 31b2ef8a..1f28802b 100644
--- a/src/WixToolset.Core/Linker.cs
+++ b/src/WixToolset.Core/Linker.cs
@@ -320,7 +320,7 @@ namespace WixToolset.Core
320 break; 320 break;
321#endif 321#endif
322 322
323 case TupleDefinitionType.MsiAssembly: 323 case TupleDefinitionType.Assembly:
324 if (SectionType.Product == resolvedSection.Type) 324 if (SectionType.Product == resolvedSection.Type)
325 { 325 {
326 this.ResolveFeatures(tuple, 0, 1, componentsToFeatures, multipleFeatureComponents); 326 this.ResolveFeatures(tuple, 0, 1, componentsToFeatures, multipleFeatureComponents);
diff --git a/src/test/WixToolsetTest.CoreIntegration/ExtensionFixture.cs b/src/test/WixToolsetTest.CoreIntegration/ExtensionFixture.cs
index 37ff1839..27256d41 100644
--- a/src/test/WixToolsetTest.CoreIntegration/ExtensionFixture.cs
+++ b/src/test/WixToolsetTest.CoreIntegration/ExtensionFixture.cs
@@ -58,9 +58,9 @@ namespace WixToolsetTest.CoreIntegration
58 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"extest.wir")); 58 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"extest.wir"));
59 var section = intermediate.Sections.Single(); 59 var section = intermediate.Sections.Single();
60 60
61 var wixFile = section.Tuples.OfType<WixFileTuple>().Single(); 61 var fileTuple = section.Tuples.OfType<FileTuple>().Single();
62 Assert.Equal(Path.Combine(folder, @"data\example.txt"), wixFile[WixFileTupleFields.Source].AsPath().Path); 62 Assert.Equal(Path.Combine(folder, @"data\example.txt"), fileTuple[FileTupleFields.Source].AsPath().Path);
63 Assert.Equal(@"example.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path); 63 Assert.Equal(@"example.txt", fileTuple[FileTupleFields.Source].PreviousValue.AsPath().Path);
64 64
65 var example = section.Tuples.Where(t => t.Definition.Type == TupleDefinitionType.MustBeFromAnExtension).Single(); 65 var example = section.Tuples.Where(t => t.Definition.Type == TupleDefinitionType.MustBeFromAnExtension).Single();
66 Assert.Equal("Foo", example.Id.Id); 66 Assert.Equal("Foo", example.Id.Id);
diff --git a/src/test/WixToolsetTest.CoreIntegration/MsiFixture.cs b/src/test/WixToolsetTest.CoreIntegration/MsiFixture.cs
index a329c16a..e30441bf 100644
--- a/src/test/WixToolsetTest.CoreIntegration/MsiFixture.cs
+++ b/src/test/WixToolsetTest.CoreIntegration/MsiFixture.cs
@@ -43,9 +43,9 @@ namespace WixToolsetTest.CoreIntegration
43 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir")); 43 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir"));
44 var section = intermediate.Sections.Single(); 44 var section = intermediate.Sections.Single();
45 45
46 var wixFile = section.Tuples.OfType<WixFileTuple>().First(); 46 var fileTuple = section.Tuples.OfType<FileTuple>().First();
47 Assert.Equal(Path.Combine(folder, @"data\test.txt"), wixFile[WixFileTupleFields.Source].AsPath().Path); 47 Assert.Equal(Path.Combine(folder, @"data\test.txt"), fileTuple[FileTupleFields.Source].AsPath().Path);
48 Assert.Equal(@"test.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path); 48 Assert.Equal(@"test.txt", fileTuple[FileTupleFields.Source].PreviousValue.AsPath().Path);
49 } 49 }
50 } 50 }
51 51
@@ -78,9 +78,9 @@ namespace WixToolsetTest.CoreIntegration
78 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir")); 78 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir"));
79 var section = intermediate.Sections.Single(); 79 var section = intermediate.Sections.Single();
80 80
81 var wixFile = section.Tuples.OfType<WixFileTuple>().Single(); 81 var fileTuple = section.Tuples.OfType<FileTuple>().Single();
82 Assert.Equal(Path.Combine(folder, @"data\test.txt"), wixFile[WixFileTupleFields.Source].AsPath().Path); 82 Assert.Equal(Path.Combine(folder, @"data\test.txt"), fileTuple[FileTupleFields.Source].AsPath().Path);
83 Assert.Equal(@"test.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path); 83 Assert.Equal(@"test.txt", fileTuple[FileTupleFields.Source].PreviousValue.AsPath().Path);
84 } 84 }
85 } 85 }
86 86
@@ -309,9 +309,9 @@ namespace WixToolsetTest.CoreIntegration
309 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir")); 309 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir"));
310 var section = intermediate.Sections.Single(); 310 var section = intermediate.Sections.Single();
311 311
312 var wixFile = section.Tuples.OfType<WixFileTuple>().Single(); 312 var fileTuple = section.Tuples.OfType<FileTuple>().Single();
313 Assert.Equal(Path.Combine(folder, @"data\test.txt"), wixFile[WixFileTupleFields.Source].AsPath().Path); 313 Assert.Equal(Path.Combine(folder, @"data\test.txt"), fileTuple[FileTupleFields.Source].AsPath().Path);
314 Assert.Equal(@"test.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path); 314 Assert.Equal(@"test.txt", fileTuple[FileTupleFields.Source].PreviousValue.AsPath().Path);
315 } 315 }
316 } 316 }
317 317
@@ -344,9 +344,9 @@ namespace WixToolsetTest.CoreIntegration
344 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir")); 344 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir"));
345 var section = intermediate.Sections.Single(); 345 var section = intermediate.Sections.Single();
346 346
347 var wixFile = section.Tuples.OfType<WixFileTuple>().Single(); 347 var fileTuple = section.Tuples.OfType<FileTuple>().Single();
348 Assert.Equal(Path.Combine(folder, @"data\test.txt"), wixFile[WixFileTupleFields.Source].AsPath().Path); 348 Assert.Equal(Path.Combine(folder, @"data\test.txt"), fileTuple[FileTupleFields.Source].AsPath().Path);
349 Assert.Equal(@"test.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path); 349 Assert.Equal(@"test.txt", fileTuple[FileTupleFields.Source].PreviousValue.AsPath().Path);
350 } 350 }
351 } 351 }
352 352
@@ -444,9 +444,9 @@ namespace WixToolsetTest.CoreIntegration
444 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir")); 444 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir"));
445 var section = intermediate.Sections.Single(); 445 var section = intermediate.Sections.Single();
446 446
447 var wixFile = section.Tuples.OfType<WixFileTuple>().Single(); 447 var fileTuple = section.Tuples.OfType<FileTuple>().Single();
448 Assert.Equal(Path.Combine(folder, @"data\test.txt"), wixFile[WixFileTupleFields.Source].AsPath().Path); 448 Assert.Equal(Path.Combine(folder, @"data\test.txt"), fileTuple[FileTupleFields.Source].AsPath().Path);
449 Assert.Equal(@"test.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path); 449 Assert.Equal(@"test.txt", fileTuple[FileTupleFields.Source].PreviousValue.AsPath().Path);
450 } 450 }
451 } 451 }
452 452
@@ -480,9 +480,9 @@ namespace WixToolsetTest.CoreIntegration
480 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir")); 480 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir"));
481 var section = intermediate.Sections.Single(); 481 var section = intermediate.Sections.Single();
482 482
483 var wixFile = section.Tuples.OfType<WixFileTuple>().Single(); 483 var fileTuple = section.Tuples.OfType<FileTuple>().Single();
484 Assert.Equal(Path.Combine(folder, @"data\candle.exe"), wixFile[WixFileTupleFields.Source].AsPath().Path); 484 Assert.Equal(Path.Combine(folder, @"data\candle.exe"), fileTuple[FileTupleFields.Source].AsPath().Path);
485 Assert.Equal(@"candle.exe", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path); 485 Assert.Equal(@"candle.exe", fileTuple[FileTupleFields.Source].PreviousValue.AsPath().Path);
486 486
487 var msiAssemblyNameTuples = section.Tuples.OfType<MsiAssemblyNameTuple>(); 487 var msiAssemblyNameTuples = section.Tuples.OfType<MsiAssemblyNameTuple>();
488 Assert.Equal(new[] 488 Assert.Equal(new[]
diff --git a/src/test/WixToolsetTest.CoreIntegration/WixiplFixture.cs b/src/test/WixToolsetTest.CoreIntegration/WixiplFixture.cs
index d915d02b..dd730501 100644
--- a/src/test/WixToolsetTest.CoreIntegration/WixiplFixture.cs
+++ b/src/test/WixToolsetTest.CoreIntegration/WixiplFixture.cs
@@ -50,9 +50,9 @@ namespace WixToolsetTest.CoreIntegration
50 var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"obj\test.wir")); 50 var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"obj\test.wir"));
51 var section = intermediate.Sections.Single(); 51 var section = intermediate.Sections.Single();
52 52
53 var wixFile = section.Tuples.OfType<WixFileTuple>().First(); 53 var fileTuple = section.Tuples.OfType<FileTuple>().First();
54 Assert.Equal(Path.Combine(folder, @"data\test.txt"), wixFile[WixFileTupleFields.Source].AsPath().Path); 54 Assert.Equal(Path.Combine(folder, @"data\test.txt"), fileTuple[FileTupleFields.Source].AsPath().Path);
55 Assert.Equal(@"test.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path); 55 Assert.Equal(@"test.txt", fileTuple[FileTupleFields.Source].PreviousValue.AsPath().Path);
56 } 56 }
57 } 57 }
58 58
@@ -120,9 +120,9 @@ namespace WixToolsetTest.CoreIntegration
120 var section = intermediate.Sections.Single(); 120 var section = intermediate.Sections.Single();
121 121
122 { 122 {
123 var wixFile = section.Tuples.OfType<WixFileTuple>().Single(); 123 var fileTuple = section.Tuples.OfType<FileTuple>().Single();
124 Assert.Equal(Path.Combine(folder, @"data\test.txt"), wixFile[WixFileTupleFields.Source].AsPath().Path); 124 Assert.Equal(Path.Combine(folder, @"data\test.txt"), fileTuple[FileTupleFields.Source].AsPath().Path);
125 Assert.Equal(@"test.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path); 125 Assert.Equal(@"test.txt", fileTuple[FileTupleFields.Source].PreviousValue.AsPath().Path);
126 } 126 }
127 127
128 { 128 {
@@ -175,9 +175,9 @@ namespace WixToolsetTest.CoreIntegration
175 var section = intermediate.Sections.Single(); 175 var section = intermediate.Sections.Single();
176 176
177 { 177 {
178 var wixFile = section.Tuples.OfType<WixFileTuple>().Single(); 178 var fileTuple = section.Tuples.OfType<FileTuple>().Single();
179 Assert.Equal(Path.Combine(folder, @"data\test.txt"), wixFile[WixFileTupleFields.Source].AsPath().Path); 179 Assert.Equal(Path.Combine(folder, @"data\test.txt"), fileTuple[FileTupleFields.Source].AsPath().Path);
180 Assert.Equal(@"test.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path); 180 Assert.Equal(@"test.txt", fileTuple[FileTupleFields.Source].PreviousValue.AsPath().Path);
181 } 181 }
182 182
183 { 183 {
diff --git a/src/test/WixToolsetTest.CoreIntegration/WixlibFixture.cs b/src/test/WixToolsetTest.CoreIntegration/WixlibFixture.cs
index 07044a1f..77daab06 100644
--- a/src/test/WixToolsetTest.CoreIntegration/WixlibFixture.cs
+++ b/src/test/WixToolsetTest.CoreIntegration/WixlibFixture.cs
@@ -50,9 +50,9 @@ namespace WixToolsetTest.CoreIntegration
50 var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"obj\test.wir")); 50 var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"obj\test.wir"));
51 var section = intermediate.Sections.Single(); 51 var section = intermediate.Sections.Single();
52 52
53 var wixFile = section.Tuples.OfType<WixFileTuple>().First(); 53 var wixFile = section.Tuples.OfType<FileTuple>().First();
54 Assert.Equal(Path.Combine(folder, @"data\test.txt"), wixFile[WixFileTupleFields.Source].AsPath().Path); 54 Assert.Equal(Path.Combine(folder, @"data\test.txt"), wixFile[FileTupleFields.Source].AsPath().Path);
55 Assert.Equal(@"test.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path); 55 Assert.Equal(@"test.txt", wixFile[FileTupleFields.Source].PreviousValue.AsPath().Path);
56 } 56 }
57 } 57 }
58 58
@@ -95,9 +95,9 @@ namespace WixToolsetTest.CoreIntegration
95 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir")); 95 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir"));
96 var section = intermediate.Sections.Single(); 96 var section = intermediate.Sections.Single();
97 97
98 var wixFile = section.Tuples.OfType<WixFileTuple>().Single(); 98 var fileTuple = section.Tuples.OfType<FileTuple>().Single();
99 Assert.Equal(Path.Combine(folder, @"data\example.txt"), wixFile[WixFileTupleFields.Source].AsPath().Path); 99 Assert.Equal(Path.Combine(folder, @"data\example.txt"), fileTuple[FileTupleFields.Source].AsPath().Path);
100 Assert.Equal(@"example.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path); 100 Assert.Equal(@"example.txt", fileTuple[FileTupleFields.Source].PreviousValue.AsPath().Path);
101 101
102 var example = section.Tuples.Where(t => t.Definition.Type == TupleDefinitionType.MustBeFromAnExtension).Single(); 102 var example = section.Tuples.Where(t => t.Definition.Type == TupleDefinitionType.MustBeFromAnExtension).Single();
103 Assert.Equal("Foo", example.Id.Id); 103 Assert.Equal("Foo", example.Id.Id);
@@ -157,11 +157,11 @@ namespace WixToolsetTest.CoreIntegration
157 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir")); 157 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"test.wir"));
158 var section = intermediate.Sections.Single(); 158 var section = intermediate.Sections.Single();
159 159
160 var wixFiles = section.Tuples.OfType<WixFileTuple>().OrderBy(t => Path.GetFileName(t.Source.Path)).ToArray(); 160 var fileTuples = section.Tuples.OfType<FileTuple>().OrderBy(t => Path.GetFileName(t.Source.Path)).ToArray();
161 Assert.Equal(Path.Combine(folder, @"data\example.txt"), wixFiles[0][WixFileTupleFields.Source].AsPath().Path); 161 Assert.Equal(Path.Combine(folder, @"data\example.txt"), fileTuples[0][FileTupleFields.Source].AsPath().Path);
162 Assert.Equal(@"example.txt", wixFiles[0][WixFileTupleFields.Source].PreviousValue.AsPath().Path); 162 Assert.Equal(@"example.txt", fileTuples[0][FileTupleFields.Source].PreviousValue.AsPath().Path);
163 Assert.Equal(Path.Combine(folder, @"data\other.txt"), wixFiles[1][WixFileTupleFields.Source].AsPath().Path); 163 Assert.Equal(Path.Combine(folder, @"data\other.txt"), fileTuples[1][FileTupleFields.Source].AsPath().Path);
164 Assert.Equal(@"other.txt", wixFiles[1][WixFileTupleFields.Source].PreviousValue.AsPath().Path); 164 Assert.Equal(@"other.txt", fileTuples[1][FileTupleFields.Source].PreviousValue.AsPath().Path);
165 165
166 var examples = section.Tuples.Where(t => t.Definition.Type == TupleDefinitionType.MustBeFromAnExtension).ToArray(); 166 var examples = section.Tuples.Where(t => t.Definition.Type == TupleDefinitionType.MustBeFromAnExtension).ToArray();
167 Assert.Equal(new[] { "Foo", "Other" }, examples.Select(t => t.Id.Id).ToArray()); 167 Assert.Equal(new[] { "Foo", "Other" }, examples.Select(t => t.Id.Id).ToArray());