@joebigelow / wix / commits / 3ccd5e43

Minimize public surface area of Core

Fixes wixtoolset/issues#6374

Rob Mensching committed Mar 14, 2021 at 07:38 UTC 3ccd5e439da4296d6f2b66ce47075ab20d039676
70 files changed +871 -1952
src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
+3 -5
@@ -130,10 +130,9 @@ namespace WixToolset.Core.Burn
130
131 // Extract files that come from binary .wixlibs and WixExtensions (this does not extract files from merge modules).
132 {
133 - var command = new ExtractEmbeddedFilesCommand(this.BackendHelper, this.ExpectedEmbeddedFiles);
134 - command.Execute();
133 + var extractedFiles = this.BackendHelper.ExtractEmbeddedFiles(this.ExpectedEmbeddedFiles);
134
136 - trackedFiles.AddRange(command.TrackedFiles);
135 + trackedFiles.AddRange(extractedFiles);
136 }
137
138 // Get the explicit payloads.
@@ -367,8 +366,7 @@ namespace WixToolset.Core.Burn
366 // Resolve any delayed fields before generating the manifest.
367 if (this.DelayedFields.Any())
368 {
370 - var resolveDelayedFieldsCommand = new ResolveDelayedFieldsCommand(this.Messaging, this.DelayedFields, variableCache);
371 - resolveDelayedFieldsCommand.Execute();
369 + this.BackendHelper.ResolveDelayedFields(this.DelayedFields, variableCache);
370 }
371
372 Dictionary<string, ProvidesDependencySymbol> dependencySymbolsByKey;
src/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs
+1 -1
@@ -244,7 +244,7 @@ namespace WixToolset.Core.Burn.Bundles
244
245 private WixBundlePayloadSymbol CreateBootstrapperApplicationManifestPayloadRow(string baManifestPath)
246 {
247 - var generatedId = Common.GenerateIdentifier("ux", BurnCommon.BADataFileName);
247 + var generatedId = this.InternalBurnBackendHelper.GenerateIdentifier("ux", BurnCommon.BADataFileName);
248
249 var symbol = this.Section.AddSymbol(new WixBundlePayloadSymbol(this.BundleSymbol.SourceLineNumbers, new Identifier(AccessModifier.Section, generatedId))
250 {
src/WixToolset.Core.Burn/Bundles/CreateBundleExtensionManifestCommand.cs
+1 -1
@@ -66,7 +66,7 @@ namespace WixToolset.Core.Burn.Bundles
66
67 private WixBundlePayloadSymbol CreateBundleExtensionManifestPayloadRow(string bextManifestPath)
68 {
69 - var generatedId = Common.GenerateIdentifier("ux", BurnCommon.BundleExtensionDataFileName);
69 + var generatedId = this.InternalBurnBackendHelper.GenerateIdentifier("ux", BurnCommon.BundleExtensionDataFileName);
70
71 var symbol = this.Section.AddSymbol(new WixBundlePayloadSymbol(this.BundleSymbol.SourceLineNumbers, new Identifier(AccessModifier.Section, generatedId))
72 {
src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs
+6 -6
@@ -94,7 +94,7 @@ namespace WixToolset.Core.Burn.Bundles
94 msiPackage.ProductLanguage = Convert.ToInt32(ProcessMsiPackageCommand.GetProperty(db, "ProductLanguage"), CultureInfo.InvariantCulture);
95 msiPackage.ProductVersion = ProcessMsiPackageCommand.GetProperty(db, "ProductVersion");
96
97 - if (!Common.IsValidModuleOrBundleVersion(msiPackage.ProductVersion))
97 + if (!this.BackendHelper.IsValidFourPartVersion(msiPackage.ProductVersion))
98 {
99 // not a proper .NET version (e.g., five fields); can we get a valid four-part version number?
100 string version = null;
@@ -109,7 +109,7 @@ namespace WixToolset.Core.Burn.Bundles
109 }
110 }
111
112 - if (!String.IsNullOrEmpty(version) && Common.IsValidModuleOrBundleVersion(version))
112 + if (!String.IsNullOrEmpty(version) && this.BackendHelper.IsValidFourPartVersion(version))
113 {
114 this.Messaging.Write(WarningMessages.VersionTruncated(this.Facade.PackageSymbol.SourceLineNumbers, msiPackage.ProductVersion, sourcePath, version));
115 msiPackage.ProductVersion = version;
@@ -394,7 +394,7 @@ namespace WixToolset.Core.Burn.Bundles
394
395 if (!payloadNames.Contains(cabinetName))
396 {
397 - var generatedId = Common.GenerateIdentifier("cab", packagePayload.Id.Id, cabinet);
397 + var generatedId = this.BackendHelper.GenerateIdentifier("cab", packagePayload.Id.Id, cabinet);
398 var payloadSourceFile = this.ResolveRelatedFile(packagePayload.SourceFile.Path, packagePayload.UnresolvedSourceFile, cabinet, "Cabinet", this.Facade.PackageSymbol.SourceLineNumbers);
399
400 this.Section.AddSymbol(new WixBundlePayloadSymbol(this.Facade.PackageSymbol.SourceLineNumbers, new Identifier(AccessModifier.Section, generatedId))
@@ -437,7 +437,7 @@ namespace WixToolset.Core.Burn.Bundles
437 break;
438 }
439
440 - var sourceName = Common.GetName(record.GetString(3), true, longNamesInImage);
440 + var sourceName = this.BackendHelper.GetMsiFileName(record.GetString(3), true, longNamesInImage);
441
442 var resolvedDirectory = this.BackendHelper.CreateResolvedDirectory(record.GetString(2), sourceName);
443
@@ -471,7 +471,7 @@ namespace WixToolset.Core.Burn.Bundles
471
472 if (!payloadNames.Contains(name))
473 {
474 - var generatedId = Common.GenerateIdentifier("f", packagePayload.Id.Id, record.GetString(2));
474 + var generatedId = this.BackendHelper.GenerateIdentifier("f", packagePayload.Id.Id, record.GetString(2));
475 var payloadSourceFile = this.ResolveRelatedFile(packagePayload.SourceFile.Path, packagePayload.UnresolvedSourceFile, fileSourcePath, "File", this.Facade.PackageSymbol.SourceLineNumbers);
476
477 this.Section.AddSymbol(new WixBundlePayloadSymbol(this.Facade.PackageSymbol.SourceLineNumbers, new Identifier(AccessModifier.Section, generatedId))
@@ -526,7 +526,7 @@ namespace WixToolset.Core.Burn.Bundles
526 break;
527 }
528
529 - var id = new Identifier(AccessModifier.Section, Common.GenerateIdentifier("dep", msiPackage.Id.Id, record.GetString(1)));
529 + var id = new Identifier(AccessModifier.Section, this.BackendHelper.GenerateIdentifier("dep", msiPackage.Id.Id, record.GetString(1)));
530
531 // Import the provider key and attributes.
532 this.Section.AddSymbol(new ProvidesDependencySymbol(msiPackage.SourceLineNumbers, id)
src/WixToolset.Core.Burn/ExtensibilityServices/BurnBackendHelper.cs
+33 -1
@@ -9,6 +9,8 @@ namespace WixToolset.Core.Burn.ExtensibilityServices
9 using System.Xml;
10 using WixToolset.Core.Burn.Bundles;
11 using WixToolset.Data;
12 + using WixToolset.Data.Symbols;
13 + using WixToolset.Data.WindowsInstaller.Rows;
14 using WixToolset.Extensibility.Data;
15 using WixToolset.Extensibility.Services;
16
@@ -30,14 +32,44 @@ namespace WixToolset.Core.Burn.ExtensibilityServices
32
33 #region IBackendHelper interfaces
34
35 + public IFileFacade CreateFileFacade(FileSymbol file, AssemblySymbol assembly) => this.backendHelper.CreateFileFacade(file, assembly);
36 +
37 + public IFileFacade CreateFileFacade(FileRow fileRow) => this.backendHelper.CreateFileFacade(fileRow);
38 +
39 + public IFileFacade CreateFileFacadeFromMergeModule(FileSymbol fileSymbol) => this.backendHelper.CreateFileFacadeFromMergeModule(fileSymbol);
40 +
41 public IFileTransfer CreateFileTransfer(string source, string destination, bool move, SourceLineNumber sourceLineNumbers = null) => this.backendHelper.CreateFileTransfer(source, destination, move, sourceLineNumbers);
42
43 + public string CreateGuid() => this.backendHelper.CreateGuid();
44 +
45 public string CreateGuid(Guid namespaceGuid, string value) => this.backendHelper.CreateGuid(namespaceGuid, value);
46
47 public IResolvedDirectory CreateResolvedDirectory(string directoryParent, string name) => this.backendHelper.CreateResolvedDirectory(directoryParent, name);
48
49 + public IEnumerable<ITrackedFile> ExtractEmbeddedFiles(IEnumerable<IExpectedExtractFile> embeddedFiles) => this.backendHelper.ExtractEmbeddedFiles(embeddedFiles);
50 +
51 + public string GenerateIdentifier(string prefix, params string[] args) => this.backendHelper.GenerateIdentifier(prefix, args);
52 +
53 public string GetCanonicalRelativePath(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string relativePath) => this.backendHelper.GetCanonicalRelativePath(sourceLineNumbers, elementName, attributeName, relativePath);
54
55 + public int GetValidCodePage(string value, bool allowNoChange, bool onlyAnsi = false, SourceLineNumber sourceLineNumbers = null) => this.backendHelper.GetValidCodePage(value, allowNoChange, onlyAnsi, sourceLineNumbers);
56 +
57 + public string GetMsiFileName(string value, bool source, bool longName) => this.backendHelper.GetMsiFileName(value, source, longName);
58 +
59 + public bool IsValidBinderVariable(string variable) => this.backendHelper.IsValidBinderVariable(variable);
60 +
61 + public bool IsValidFourPartVersion(string version) => this.backendHelper.IsValidFourPartVersion(version);
62 +
63 + public bool IsValidIdentifier(string id) => this.backendHelper.IsValidIdentifier(id);
64 +
65 + public bool IsValidLongFilename(string filename, bool allowWildcards, bool allowRelative) => this.backendHelper.IsValidLongFilename(filename, allowWildcards, allowRelative);
66 +
67 + public bool IsValidShortFilename(string filename, bool allowWildcards) => this.backendHelper.IsValidShortFilename(filename, allowWildcards);
68 +
69 + public void ResolveDelayedFields(IEnumerable<IDelayedField> delayedFields, Dictionary<string, string> variableCache) => this.backendHelper.ResolveDelayedFields(delayedFields, variableCache);
70 +
71 + public string[] SplitMsiFileName(string value) => this.backendHelper.SplitMsiFileName(value);
72 +
73 public ITrackedFile TrackFile(string path, TrackedFileType type, SourceLineNumber sourceLineNumbers = null) => this.backendHelper.TrackFile(path, type, sourceLineNumbers);
74
75 #endregion
@@ -87,7 +119,7 @@ namespace WixToolset.Core.Burn.ExtensibilityServices
119
120 private ManifestData GetBundleExtensionManifestData(string extensionId)
121 {
90 - if (!Common.IsIdentifier(extensionId))
122 + if (!this.backendHelper.IsValidIdentifier(extensionId))
123 {
124 throw new ArgumentException($"'{extensionId}' is not a valid extensionId");
125 }
src/WixToolset.Core.Burn/RowIndexedList.cs
+9 -12
@@ -13,9 +13,9 @@ namespace WixToolset.Core.Burn
13 /// </summary>
14 internal sealed class RowIndexedList<T> : IList<T> where T : Row
15 {
16 - private Dictionary<string, T> index;
17 - private List<T> rows;
18 - private List<T> duplicates;
16 + private readonly Dictionary<string, T> index;
17 + private readonly List<T> rows;
18 + private readonly List<T> duplicates;
19
20 /// <summary>
21 /// Creates an empty <see cref="RowIndexedList{T}"/>.
@@ -34,7 +34,7 @@ namespace WixToolset.Core.Burn
34 public RowIndexedList(IEnumerable<T> rows)
35 : this()
36 {
37 - foreach (T row in rows)
37 + foreach (var row in rows)
38 {
39 this.Add(row);
40 }
@@ -81,8 +81,7 @@ namespace WixToolset.Core.Burn
81 /// <returns>Row or null if key is not found.</returns>
82 public T Get(string key)
83 {
84 - T result;
85 - return this.TryGet(key, out result) ? result : null;
84 + return this.TryGet(key, out var result) ? result : null;
85 }
86
87 /// <summary>
@@ -169,12 +168,11 @@ namespace WixToolset.Core.Burn
168 /// <param name="index">Index to remove the row at.</param>
169 public void RemoveAt(int index)
170 {
172 - T row = this.rows[index];
171 + var row = this.rows[index];
172
173 this.rows.RemoveAt(index);
174
176 - T indexRow;
177 - if (this.index.TryGetValue(row.GetKey(), out indexRow) && indexRow == row)
175 + if (this.index.TryGetValue(row.GetKey(), out var indexRow) && indexRow == row)
176 {
177 this.index.Remove(row.GetKey());
178 }
@@ -264,11 +262,10 @@ namespace WixToolset.Core.Burn
262 /// <returns></returns>
263 public bool Remove(T row)
264 {
267 - bool removed = this.rows.Remove(row);
265 + var removed = this.rows.Remove(row);
266 if (removed)
267 {
270 - T indexRow;
271 - if (this.index.TryGetValue(row.GetKey(), out indexRow) && indexRow == row)
268 + if (this.index.TryGetValue(row.GetKey(), out var indexRow) && indexRow == row)
269 {
270 this.index.Remove(row.GetKey());
271 }
src/WixToolset.Core.Burn/TableExtensions.cs deleted
-24
@@ -1,24 +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.Burn
4 -{
5 - using System.Collections.Generic;
6 - using System.Linq;
7 - using WixToolset.Data.WindowsInstaller;
8 -
9 - /// <summary>
10 - /// Methods that extend <see cref="Table"/>.
11 - /// </summary>
12 - public static class TableExtensions
13 - {
14 - /// <summary>
15 - /// Gets the rows contained in the table as a particular row type.
16 - /// </summary>
17 - /// <param name="table">Table to get rows from.</param>
18 - /// <remarks>If the <paramref name="table"/> is null, an empty enumerable will be returned.</remarks>
19 - public static IEnumerable<T> RowsAs<T>(this Table table) where T : Row
20 - {
21 - return (null == table) ? Enumerable.Empty<T>() : table.Rows.Cast<T>();
22 - }
23 - }
24 -}
src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs
+18 -18
@@ -6,9 +6,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind
6 using System.Collections.Generic;
7 using System.Globalization;
8 using System.Linq;
9 - using WixToolset.Core.Bind;
9 using WixToolset.Data;
10 using WixToolset.Data.Symbols;
11 + using WixToolset.Extensibility.Data;
12 using WixToolset.Extensibility.Services;
13
14 /// <summary>
@@ -18,7 +18,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
18 {
19 private const int DefaultMaximumUncompressedMediaSize = 200; // Default value is 200 MB
20
21 - public AssignMediaCommand(IntermediateSection section, IMessaging messaging, IEnumerable<FileFacade> fileFacades, bool compressed)
21 + public AssignMediaCommand(IntermediateSection section, IMessaging messaging, IEnumerable<IFileFacade> fileFacades, bool compressed)
22 {
23 this.CabinetNameTemplate = "Cab{0}.cab";
24 this.Section = section;
@@ -31,7 +31,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
31
32 private IMessaging Messaging { get; }
33
34 - private IEnumerable<FileFacade> FileFacades { get; }
34 + private IEnumerable<IFileFacade> FileFacades { get; }
35
36 private bool FilesCompressed { get; }
37
@@ -40,13 +40,13 @@ namespace WixToolset.Core.WindowsInstaller.Bind
40 /// <summary>
41 /// Gets cabinets with their file rows.
42 /// </summary>
43 - public Dictionary<MediaSymbol, IEnumerable<FileFacade>> FileFacadesByCabinetMedia { get; private set; }
43 + public Dictionary<MediaSymbol, IEnumerable<IFileFacade>> FileFacadesByCabinetMedia { get; private set; }
44
45 /// <summary>
46 /// Get uncompressed file rows. This will contain file rows of File elements that are marked with compression=no.
47 /// This contains all the files when Package element is marked with compression=no
48 /// </summary>
49 - public IEnumerable<FileFacade> UncompressedFileFacades { get; private set; }
49 + public IEnumerable<IFileFacade> UncompressedFileFacades { get; private set; }
50
51 public void Execute()
52 {
@@ -79,34 +79,34 @@ namespace WixToolset.Core.WindowsInstaller.Bind
79 Cabinet = "#MergeModule.CABinet",
80 });
81
82 - this.FileFacadesByCabinetMedia = new Dictionary<MediaSymbol, IEnumerable<FileFacade>>
82 + this.FileFacadesByCabinetMedia = new Dictionary<MediaSymbol, IEnumerable<IFileFacade>>
83 {
84 { mergeModuleMediaSymbol, this.FileFacades }
85 };
86
87 - this.UncompressedFileFacades = Array.Empty<FileFacade>();
87 + this.UncompressedFileFacades = Array.Empty<IFileFacade>();
88 }
89 else if (mediaTemplateSymbols.Count == 0)
90 {
91 - var filesByCabinetMedia = new Dictionary<MediaSymbol, List<FileFacade>>();
91 + var filesByCabinetMedia = new Dictionary<MediaSymbol, List<IFileFacade>>();
92
93 - var uncompressedFiles = new List<FileFacade>();
93 + var uncompressedFiles = new List<IFileFacade>();
94
95 this.ManuallyAssignFiles(mediaSymbols, filesByCabinetMedia, uncompressedFiles);
96
97 - this.FileFacadesByCabinetMedia = filesByCabinetMedia.ToDictionary(kvp => kvp.Key, kvp => (IEnumerable<FileFacade>)kvp.Value);
97 + this.FileFacadesByCabinetMedia = filesByCabinetMedia.ToDictionary(kvp => kvp.Key, kvp => (IEnumerable<IFileFacade>)kvp.Value);
98
99 this.UncompressedFileFacades = uncompressedFiles;
100 }
101 else
102 {
103 - var filesByCabinetMedia = new Dictionary<MediaSymbol, List<FileFacade>>();
103 + var filesByCabinetMedia = new Dictionary<MediaSymbol, List<IFileFacade>>();
104
105 - var uncompressedFiles = new List<FileFacade>();
105 + var uncompressedFiles = new List<IFileFacade>();
106
107 this.AutoAssignFiles(mediaSymbols, filesByCabinetMedia, uncompressedFiles);
108
109 - this.FileFacadesByCabinetMedia = filesByCabinetMedia.ToDictionary(kvp => kvp.Key, kvp => (IEnumerable<FileFacade>)kvp.Value);
109 + this.FileFacadesByCabinetMedia = filesByCabinetMedia.ToDictionary(kvp => kvp.Key, kvp => (IEnumerable<IFileFacade>)kvp.Value);
110
111 this.UncompressedFileFacades = uncompressedFiles;
112 }
@@ -115,7 +115,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
115 /// <summary>
116 /// Assign files to cabinets based on MediaTemplate authoring.
117 /// </summary>
118 - private void AutoAssignFiles(List<MediaSymbol> mediaTable, Dictionary<MediaSymbol, List<FileFacade>> filesByCabinetMedia, List<FileFacade> uncompressedFiles)
118 + private void AutoAssignFiles(List<MediaSymbol> mediaTable, Dictionary<MediaSymbol, List<IFileFacade>> filesByCabinetMedia, List<IFileFacade> uncompressedFiles)
119 {
120 const int MaxCabIndex = 999;
121
@@ -194,7 +194,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
194 {
195 currentMediaRow = this.AddMediaSymbol(mediaTemplateRow, ++currentCabIndex);
196 mediaSymbolsByDiskId.Add(currentMediaRow.DiskId, currentMediaRow);
197 - filesByCabinetMedia.Add(currentMediaRow, new List<FileFacade>());
197 + filesByCabinetMedia.Add(currentMediaRow, new List<IFileFacade>());
198
199 // Now files larger than MaxUncompressedMediaSize will be the only file in its cabinet so as to respect MaxUncompressedMediaSize
200 currentPreCabSize = (ulong)facade.FileSize;
@@ -206,7 +206,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
206 // Create new cab and MediaRow
207 currentMediaRow = this.AddMediaSymbol(mediaTemplateRow, ++currentCabIndex);
208 mediaSymbolsByDiskId.Add(currentMediaRow.DiskId, currentMediaRow);
209 - filesByCabinetMedia.Add(currentMediaRow, new List<FileFacade>());
209 + filesByCabinetMedia.Add(currentMediaRow, new List<IFileFacade>());
210 }
211 }
212 }
@@ -232,7 +232,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
232 /// <summary>
233 /// Assign files to cabinets based on Media authoring.
234 /// </summary>
235 - private void ManuallyAssignFiles(List<MediaSymbol> mediaSymbols, Dictionary<MediaSymbol, List<FileFacade>> filesByCabinetMedia, List<FileFacade> uncompressedFiles)
235 + private void ManuallyAssignFiles(List<MediaSymbol> mediaSymbols, Dictionary<MediaSymbol, List<IFileFacade>> filesByCabinetMedia, List<IFileFacade> uncompressedFiles)
236 {
237 var mediaSymbolsByDiskId = new Dictionary<int, MediaSymbol>();
238
@@ -254,7 +254,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
254 cabinetMediaSymbols.Add(mediaSymbol.Cabinet, mediaSymbol);
255 }
256
257 - filesByCabinetMedia.Add(mediaSymbol, new List<FileFacade>());
257 + filesByCabinetMedia.Add(mediaSymbol, new List<IFileFacade>());
258 }
259
260 mediaSymbolsByDiskId.Add(mediaSymbol.DiskId, mediaSymbol);
src/WixToolset.Core.WindowsInstaller/Bind/AttachPatchTransformsCommand.cs
+6 -3
@@ -55,16 +55,19 @@ namespace WixToolset.Core.WindowsInstaller.Bind
55
56 private readonly TableDefinitionCollection tableDefinitions;
57
58 - public AttachPatchTransformsCommand(IMessaging messaging, Intermediate intermediate, IEnumerable<PatchTransform> transforms)
58 + public AttachPatchTransformsCommand(IMessaging messaging, IBackendHelper backendHelper, Intermediate intermediate, IEnumerable<PatchTransform> transforms)
59 {
60 this.tableDefinitions = new TableDefinitionCollection(WindowsInstallerTableDefinitions.All);
61 this.Messaging = messaging;
62 + this.BackendHelper = backendHelper;
63 this.Intermediate = intermediate;
64 this.Transforms = transforms;
65 }
66
67 private IMessaging Messaging { get; }
68
69 + private IBackendHelper BackendHelper { get; }
70 +
71 private Intermediate Intermediate { get; }
72
73 private IEnumerable<PatchTransform> Transforms { get; }
@@ -797,7 +800,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
800 if (!deletedComponent.ContainsKey(componentId))
801 {
802 var foundRemoveFileEntry = false;
800 - var filename = Common.GetName(row.FieldAsString(2), false, true);
803 + var filename = this.BackendHelper.GetMsiFileName(row.FieldAsString(2), false, true);
804
805 if (transform.TryGetTable("RemoveFile", out var removeFileTable))
806 {
@@ -813,7 +816,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
816 // Check if there is a RemoveFile entry for this file
817 if (null != removeFileRow[2])
818 {
816 - var removeFileName = Common.GetName(removeFileRow.FieldAsString(2), false, true);
819 + var removeFileName = this.BackendHelper.GetMsiFileName(removeFileRow.FieldAsString(2), false, true);
820
821 // Convert the MSI format for a wildcard string to Regex format.
822 removeFileName = removeFileName.Replace('.', '|').Replace('?', '.').Replace("*", ".*").Replace("|", "\\.");
src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
+15 -16
@@ -6,7 +6,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
6 using System.Collections.Generic;
7 using System.IO;
8 using System.Linq;
9 - using WixToolset.Core.Bind;
9 using WixToolset.Data;
10 using WixToolset.Data.Symbols;
11 using WixToolset.Data.WindowsInstaller;
@@ -133,7 +132,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind
132 Platform platform;
133 string modularizationSuffix;
134 {
136 - var command = new BindSummaryInfoCommand(section);
135 + var branding = this.ServiceProvider.GetService<IWixBranding>();
136 +
137 + var command = new BindSummaryInfoCommand(section, this.WindowsInstallerBackendHelper, branding);
138 command.Execute();
139
140 compressed = command.Compressed;
@@ -151,7 +152,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
152 // Set the ProductCode if it is to be generated.
153 if ("ProductCode".Equals(propertyRow.Id.Id, StringComparison.Ordinal) && "*".Equals(propertyRow.Value, StringComparison.Ordinal))
154 {
154 - propertyRow.Value = Common.GenerateGuid();
155 + propertyRow.Value = this.WindowsInstallerBackendHelper.CreateGuid();
156
157 #if TODO_PATCHING // Is this still necessary?
158
@@ -235,24 +236,23 @@ namespace WixToolset.Core.WindowsInstaller.Bind
236
237 // Extract files that come from binary .wixlibs and WixExtensions (this does not extract files from merge modules).
238 {
238 - var command = new ExtractEmbeddedFilesCommand(this.WindowsInstallerBackendHelper, this.ExpectedEmbeddedFiles);
239 - command.Execute();
239 + var extractedFiles = this.WindowsInstallerBackendHelper.ExtractEmbeddedFiles(this.ExpectedEmbeddedFiles);
240
241 - trackedFiles.AddRange(command.TrackedFiles);
241 + trackedFiles.AddRange(extractedFiles);
242 }
243
244 // This must occur after all variables and source paths have been resolved.
245 - List<FileFacade> fileFacades;
245 + List<IFileFacade> fileFacades;
246 if (SectionType.Patch == section.Type)
247 {
248 - var command = new GetFileFacadesFromTransforms(this.Messaging, this.FileSystemManager, this.SubStorages);
248 + var command = new GetFileFacadesFromTransforms(this.Messaging, this.WindowsInstallerBackendHelper, this.FileSystemManager, this.SubStorages);
249 command.Execute();
250
251 fileFacades = command.FileFacades;
252 }
253 else
254 {
255 - var command = new GetFileFacadesCommand(section);
255 + var command = new GetFileFacadesCommand(section, this.WindowsInstallerBackendHelper);
256 command.Execute();
257
258 fileFacades = command.FileFacades;
@@ -267,7 +267,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
267 {
268 containsMergeModules = true;
269
270 - var command = new ExtractMergeModuleFilesCommand(this.Messaging, wixMergeSymbols, fileFacades, installerVersion, this.IntermediateFolder, this.SuppressLayout);
270 + var command = new ExtractMergeModuleFilesCommand(this.Messaging, this.WindowsInstallerBackendHelper, wixMergeSymbols, fileFacades, installerVersion, this.IntermediateFolder, this.SuppressLayout);
271 command.Execute();
272
273 fileFacades.AddRange(command.MergeModulesFileFacades);
@@ -307,8 +307,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
307 // Now that the variable cache is populated, resolve any delayed fields.
308 if (this.DelayedFields.Any())
309 {
310 - var command = new ResolveDelayedFieldsCommand(this.Messaging, this.DelayedFields, variableCache);
311 - command.Execute();
310 + this.WindowsInstallerBackendHelper.ResolveDelayedFields(this.DelayedFields, variableCache);
311 }
312
313 // Update symbols that reference text files on disk.
@@ -330,7 +329,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
329
330 if (dependencyRefs.Any())
331 {
333 - var command = new ProcessDependencyReferencesCommand(section, dependencyRefs);
332 + var command = new ProcessDependencyReferencesCommand(this.WindowsInstallerBackendHelper, section, dependencyRefs);
333 command.Execute();
334 }
335 }
@@ -379,8 +378,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
378 }
379
380 // Assign files to media and update file sequences.
382 - Dictionary<MediaSymbol, IEnumerable<FileFacade>> filesByCabinetMedia;
383 - IEnumerable<FileFacade> uncompressedFiles;
381 + Dictionary<MediaSymbol, IEnumerable<IFileFacade>> filesByCabinetMedia;
382 + IEnumerable<IFileFacade> uncompressedFiles;
383 {
384 var order = new OptimizeFileFacadesOrderCommand(this.WindowsInstallerBackendHelper, this.PathResolver, section, platform, fileFacades);
385 order.Execute();
@@ -414,7 +413,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
413 if (data.Type == OutputType.Module)
414 {
415 // Modularize identifiers.
417 - var modularize = new ModularizeCommand(data, modularizationSuffix, section.Symbols.OfType<WixSuppressModularizationSymbol>());
416 + var modularize = new ModularizeCommand(this.WindowsInstallerBackendHelper, data, modularizationSuffix, section.Symbols.OfType<WixSuppressModularizationSymbol>());
417 modularize.Execute();
418
419 // Ensure all sequence tables in place because, mergemod.dll requires them.
src/WixToolset.Core.WindowsInstaller/Bind/BindSummaryInfoCommand.cs
+11 -4
@@ -7,19 +7,26 @@ namespace WixToolset.Core.WindowsInstaller.Bind
7 using System.Linq;
8 using WixToolset.Data;
9 using WixToolset.Data.Symbols;
10 + using WixToolset.Extensibility.Services;
11
12 /// <summary>
13 /// Binds the summary information table of a database.
14 /// </summary>
15 internal class BindSummaryInfoCommand
16 {
16 - public BindSummaryInfoCommand(IntermediateSection section)
17 + public BindSummaryInfoCommand(IntermediateSection section, IBackendHelper backendHelper, IWixBranding branding)
18 {
19 this.Section = section;
20 + this.BackendHelper = backendHelper;
21 + this.Branding = branding;
22 }
23
24 private IntermediateSection Section { get; }
25
26 + private IBackendHelper BackendHelper { get; }
27 +
28 + private IWixBranding Branding { get; }
29 +
30 /// <summary>
31 /// Returns a flag indicating if files are compressed by default.
32 /// </summary>
@@ -66,7 +73,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
73 }
74 else
75 {
69 - summaryInformationSymbol.Value = Common.GetValidCodePage(codepage, false, false, summaryInformationSymbol.SourceLineNumbers).ToString(CultureInfo.InvariantCulture);
76 + summaryInformationSymbol.Value = this.BackendHelper.GetValidCodePage(codepage, false, false, summaryInformationSymbol.SourceLineNumbers).ToString(CultureInfo.InvariantCulture);
77 }
78 break;
79 case SummaryInformationType.PlatformAndLanguage:
@@ -116,7 +123,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
123 this.Section.AddSymbol(new SummaryInformationSymbol(null)
124 {
125 PropertyId = SummaryInformationType.PackageCode,
119 - Value = Common.GenerateGuid(),
126 + Value = this.BackendHelper.CreateGuid(),
127 });
128 }
129
@@ -146,7 +153,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
153 this.Section.AddSymbol(new SummaryInformationSymbol(null)
154 {
155 PropertyId = SummaryInformationType.CreatingApplication,
149 - Value = String.Format(CultureInfo.InvariantCulture, AppCommon.GetCreatingApplicationString()),
156 + Value = this.Branding.GetCreatingApplication(),
157 });
158 }
159 }
src/WixToolset.Core.WindowsInstaller/Bind/BindTransformCommand.cs
+2 -2
@@ -99,7 +99,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
99 }
100 else
101 {
102 - codePage = Common.GetValidCodePage(codePage).ToString(CultureInfo.InvariantCulture);
102 + codePage = this.BackendHelper.GetValidCodePage(codePage).ToString(CultureInfo.InvariantCulture);
103 }
104
105 var previousCodePage = row.Fields[1].PreviousData;
@@ -109,7 +109,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
109 }
110 else
111 {
112 - previousCodePage = Common.GetValidCodePage(previousCodePage).ToString(CultureInfo.InvariantCulture);
112 + previousCodePage = this.BackendHelper.GetValidCodePage(previousCodePage).ToString(CultureInfo.InvariantCulture);
113 }
114
115 var targetCodePageRow = targetSummaryInfo.CreateRow(null);
src/WixToolset.Core.WindowsInstaller/Bind/CabinetResolver.cs
+2 -3
@@ -6,7 +6,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
6 using System.Collections.Generic;
7 using System.IO;
8 using System.Linq;
9 - using WixToolset.Core.Bind;
9 using WixToolset.Core.Native;
10 using WixToolset.Data;
11 using WixToolset.Extensibility;
@@ -30,7 +29,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
29
30 private IEnumerable<IWindowsInstallerBackendBinderExtension> BackendExtensions { get; }
31
33 - public IResolvedCabinet ResolveCabinet(string cabinetPath, IEnumerable<FileFacade> fileFacades)
32 + public IResolvedCabinet ResolveCabinet(string cabinetPath, IEnumerable<IFileFacade> fileFacades)
33 {
34 var filesWithPath = fileFacades.Select(this.CreateBindFileWithPath).ToList();
35
@@ -109,7 +108,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
108 return resolved;
109 }
110
112 - private IBindFileWithPath CreateBindFileWithPath(FileFacade facade)
111 + private IBindFileWithPath CreateBindFileWithPath(IFileFacade facade)
112 {
113 var result = this.ServiceProvider.GetService<IBindFileWithPath>();
114 result.Id = facade.Id;
src/WixToolset.Core.WindowsInstaller/Bind/CabinetWorkItem.cs
+3 -3
@@ -3,8 +3,8 @@
3 namespace WixToolset.Core.WindowsInstaller.Bind
4 {
5 using System.Collections.Generic;
6 - using WixToolset.Core.Bind;
6 using WixToolset.Data;
7 + using WixToolset.Extensibility.Data;
8
9 /// <summary>
10 /// A cabinet builder work item.
@@ -20,7 +20,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
20 /// <param name="compressionLevel">The compression level of the cabinet.</param>
21 /// <param name="modularizationSuffix">Modularization suffix used when building a Merge Module.</param>
22 /// <!--<param name="binderFileManager">The binder file manager.</param>-->
23 - public CabinetWorkItem(IEnumerable<FileFacade> fileFacades, string cabinetFile, int maxThreshold, CompressionLevel compressionLevel, string modularizationSuffix /*, BinderFileManager binderFileManager*/)
23 + public CabinetWorkItem(IEnumerable<IFileFacade> fileFacades, string cabinetFile, int maxThreshold, CompressionLevel compressionLevel, string modularizationSuffix /*, BinderFileManager binderFileManager*/)
24 {
25 this.CabinetFile = cabinetFile;
26 this.CompressionLevel = compressionLevel;
@@ -51,7 +51,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
51 /// Gets the collection of files in this cabinet.
52 /// </summary>
53 /// <value>The collection of files in this cabinet.</value>
54 - public IEnumerable<FileFacade> FileFacades { get; }
54 + public IEnumerable<IFileFacade> FileFacades { get; }
55
56 // <summary>
57 // Gets the binder file manager.
src/WixToolset.Core.WindowsInstaller/Bind/CalculateComponentGuids.cs
+2 -2
@@ -138,8 +138,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
138 if (fileRow.Id.Id == componentSymbol.KeyPath)
139 {
140 // calculate the key file's canonical target path
141 - string directoryPath = this.PathResolver.GetCanonicalDirectoryPath(targetPathsByDirectoryId, componentIdGenSeeds, componentSymbol.DirectoryRef, this.Platform);
142 - string fileName = Common.GetName(fileRow.Name, false, true).ToLowerInvariant();
141 + var directoryPath = this.PathResolver.GetCanonicalDirectoryPath(targetPathsByDirectoryId, componentIdGenSeeds, componentSymbol.DirectoryRef, this.Platform);
142 + var fileName = this.BackendHelper.GetMsiFileName(fileRow.Name, false, true).ToLowerInvariant();
143 path = Path.Combine(directoryPath, fileName);
144
145 // find paths that are not canonicalized
src/WixToolset.Core.WindowsInstaller/Bind/CopyTransformDataCommand.cs deleted
-630
@@ -1,630 +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 -#if DELETE
4 -
5 -namespace WixToolset.Core.WindowsInstaller.Bind
6 -{
7 - using System;
8 - using System.Collections.Generic;
9 - using System.Diagnostics;
10 - using System.IO;
11 - using System.Linq;
12 - using WixToolset.Core.Bind;
13 - using WixToolset.Data;
14 - using WixToolset.Data.Symbols;
15 - using WixToolset.Data.WindowsInstaller;
16 - using WixToolset.Data.WindowsInstaller.Rows;
17 - using WixToolset.Extensibility;
18 - using WixToolset.Extensibility.Services;
19 -
20 - internal class CopyTransformDataCommand
21 - {
22 - public CopyTransformDataCommand(IMessaging messaging, WindowsInstallerData output, TableDefinitionCollection tableDefinitions, bool copyOutFileRows)
23 - {
24 - this.Messaging = messaging;
25 - this.Output = output;
26 - this.TableDefinitions = tableDefinitions;
27 - this.CopyOutFileRows = copyOutFileRows;
28 - }
29 -
30 - private bool CopyOutFileRows { get; }
31 -
32 - public IEnumerable<IFileSystemExtension> Extensions { get; }
33 -
34 - private IMessaging Messaging { get; }
35 -
36 - private WindowsInstallerData Output { get; }
37 -
38 - private TableDefinitionCollection TableDefinitions { get; }
39 -
40 - public IEnumerable<FileFacade> FileFacades { get; private set; }
41 -
42 - public void Execute()
43 - {
44 - Debug.Assert(OutputType.Patch != this.Output.Type);
45 -
46 - var allFileRows = this.CopyOutFileRows ? new List<FileFacade>() : null;
47 -
48 - var copyToPatch = (allFileRows != null);
49 - var copyFromPatch = !copyToPatch;
50 -
51 - var patchMediaRows = new RowDictionary<MediaRow>();
52 -
53 - var patchMediaFileRows = new Dictionary<int, RowDictionary<WixFileRow>>();
54 -
55 - var patchActualFileTable = this.Output.EnsureTable(this.TableDefinitions["File"]);
56 - var patchFileTable = this.Output.EnsureTable(this.TableDefinitions["WixFile"]);
57 -
58 - if (copyFromPatch)
59 - {
60 - // index patch files by diskId+fileId
61 - foreach (WixFileRow patchFileRow in patchFileTable.Rows)
62 - {
63 - int diskId = patchFileRow.DiskId;
64 - if (!patchMediaFileRows.TryGetValue(diskId, out var mediaFileRows))
65 - {
66 - mediaFileRows = new RowDictionary<WixFileRow>();
67 - patchMediaFileRows.Add(diskId, mediaFileRows);
68 - }
69 -
70 - mediaFileRows.Add(patchFileRow);
71 - }
72 -
73 - var patchMediaTable = this.Output.EnsureTable(this.TableDefinitions["Media"]);
74 - patchMediaRows = new RowDictionary<MediaRow>(patchMediaTable);
75 - }
76 -
77 - // Index paired transforms by name without the "#" prefix.
78 - var pairedTransforms = this.Output.SubStorages.Where(s => s.Name.StartsWith("#")).ToDictionary(s => s.Name.Substring(1), s => s.Data);
79 - //Dictionary<string, Output> pairedTransforms = new Dictionary<string, Output>();
80 - //foreach (SubStorage substorage in this.Output.SubStorages)
81 - //{
82 - // if (substorage.Name.StartsWith("#"))
83 - // {
84 - // pairedTransforms.Add(substorage.Name.Substring(1), substorage.Data);
85 - // }
86 - //}
87 -
88 - try
89 - {
90 - // Copy File bind data into substorages
91 - foreach (var substorage in this.Output.SubStorages)
92 - {
93 - if (substorage.Name.StartsWith("#"))
94 - {
95 - // no changes necessary for paired transforms
96 - continue;
97 - }
98 -
99 - var mainTransform = substorage.Data;
100 - var mainWixFileTable = mainTransform.Tables["WixFile"];
101 - var mainMsiFileHashTable = mainTransform.Tables["MsiFileHash"];
102 -
103 - this.FileManagerCore.ActiveSubStorage = substorage;
104 -
105 - var mainWixFiles = new RowDictionary<WixFileRow>(mainWixFileTable);
106 - var mainMsiFileHashIndex = new RowDictionary<Row>();
107 -
108 - var mainFileTable = mainTransform.Tables["File"];
109 - var pairedTransform = pairedTransforms[substorage.Name];
110 -
111 - // copy Media.LastSequence and index the MsiFileHash table if it exists.
112 - if (copyFromPatch)
113 - {
114 - var pairedMediaTable = pairedTransform.Tables["Media"];
115 - foreach (MediaRow pairedMediaRow in pairedMediaTable.Rows)
116 - {
117 - var patchMediaRow = patchMediaRows.Get(pairedMediaRow.DiskId);
118 - pairedMediaRow.Fields[1] = patchMediaRow.Fields[1];
119 - }
120 -
121 - if (null != mainMsiFileHashTable)
122 - {
123 - mainMsiFileHashIndex = new RowDictionary<Row>(mainMsiFileHashTable);
124 - }
125 -
126 - // Validate file row changes for keypath-related issues
127 - this.ValidateFileRowChanges(mainTransform);
128 - }
129 -
130 - // Index File table of pairedTransform
131 - var pairedFileTable = pairedTransform.Tables["File"];
132 - var pairedFileRows = new RowDictionary<FileRow>(pairedFileTable);
133 -
134 - if (null != mainFileTable)
135 - {
136 - if (copyFromPatch)
137 - {
138 - // Remove the MsiFileHash table because it will be updated later with the final file hash for each file
139 - mainTransform.Tables.Remove("MsiFileHash");
140 - }
141 -
142 - foreach (FileRow mainFileRow in mainFileTable.Rows)
143 - {
144 - if (RowOperation.Delete == mainFileRow.Operation)
145 - {
146 - continue;
147 - }
148 - else if (RowOperation.None == mainFileRow.Operation && !copyToPatch)
149 - {
150 - continue;
151 - }
152 -
153 - var mainWixFileRow = mainWixFiles.Get(mainFileRow.File);
154 -
155 - if (copyToPatch) // when copying to the patch, we need compare the underlying files and include all file changes.
156 - {
157 - var objectField = (ObjectField)mainWixFileRow.Fields[6];
158 - var pairedFileRow = pairedFileRows.Get(mainFileRow.File);
159 -
160 - // If the file is new, we always need to add it to the patch.
161 - if (mainFileRow.Operation != RowOperation.Add)
162 - {
163 - // If PreviousData doesn't exist, target and upgrade layout point to the same location. No need to compare.
164 - if (null == objectField.PreviousData)
165 - {
166 - if (mainFileRow.Operation == RowOperation.None)
167 - {
168 - continue;
169 - }
170 - }
171 - else
172 - {
173 - // TODO: should this entire condition be placed in the binder file manager?
174 - if ((0 == (PatchAttributeType.Ignore & mainWixFileRow.PatchAttributes)) &&
175 - !this.CompareFiles(objectField.PreviousData.ToString(), objectField.Data.ToString()))
176 - {
177 - // If the file is different, we need to mark the mainFileRow and pairedFileRow as modified.
178 - mainFileRow.Operation = RowOperation.Modify;
179 - if (null != pairedFileRow)
180 - {
181 - // Always patch-added, but never non-compressed.
182 - pairedFileRow.Attributes |= WindowsInstallerConstants.MsidbFileAttributesPatchAdded;
183 - pairedFileRow.Attributes &= ~WindowsInstallerConstants.MsidbFileAttributesNoncompressed;
184 - pairedFileRow.Fields[6].Modified = true;
185 - pairedFileRow.Operation = RowOperation.Modify;
186 - }
187 - }
188 - else
189 - {
190 - // The File is same. We need mark all the attributes as unchanged.
191 - mainFileRow.Operation = RowOperation.None;
192 - foreach (var field in mainFileRow.Fields)
193 - {
194 - field.Modified = false;
195 - }
196 -
197 - if (null != pairedFileRow)
198 - {
199 - pairedFileRow.Attributes &= ~WindowsInstallerConstants.MsidbFileAttributesPatchAdded;
200 - pairedFileRow.Fields[6].Modified = false;
201 - pairedFileRow.Operation = RowOperation.None;
202 - }
203 - continue;
204 - }
205 - }
206 - }
207 - else if (null != pairedFileRow) // RowOperation.Add
208 - {
209 - // Always patch-added, but never non-compressed.
210 - pairedFileRow.Attributes |= WindowsInstallerConstants.MsidbFileAttributesPatchAdded;
211 - pairedFileRow.Attributes &= ~WindowsInstallerConstants.MsidbFileAttributesNoncompressed;
212 - pairedFileRow.Fields[6].Modified = true;
213 - pairedFileRow.Operation = RowOperation.Add;
214 - }
215 - }
216 -
217 - // index patch files by diskId+fileId
218 - int diskId = mainWixFileRow.DiskId;
219 -
220 - if (!patchMediaFileRows.TryGetValue(diskId, out var mediaFileRows))
221 - {
222 - mediaFileRows = new RowDictionary<WixFileRow>();
223 - patchMediaFileRows.Add(diskId, mediaFileRows);
224 - }
225 -
226 - var fileId = mainFileRow.File;
227 - var patchFileRow = mediaFileRows.Get(fileId);
228 - if (copyToPatch)
229 - {
230 - if (null == patchFileRow)
231 - {
232 - var patchActualFileRow = (FileRow)patchFileTable.CreateRow(mainFileRow.SourceLineNumbers);
233 - patchActualFileRow.CopyFrom(mainFileRow);
234 -
235 - patchFileRow = (WixFileRow)patchFileTable.CreateRow(mainFileRow.SourceLineNumbers);
236 - patchFileRow.CopyFrom(mainWixFileRow);
237 -
238 - mediaFileRows.Add(patchFileRow);
239 -
240 - allFileRows.Add(new FileFacade(patchActualFileRow, patchFileRow, null)); // TODO: should we be passing along delta information? Probably, right?
241 - }
242 - else
243 - {
244 - // TODO: confirm the rest of data is identical?
245 -
246 - // make sure Source is same. Otherwise we are silently ignoring a file.
247 - if (0 != String.Compare(patchFileRow.Source, mainWixFileRow.Source, StringComparison.OrdinalIgnoreCase))
248 - {
249 - this.Messaging.Write(ErrorMessages.SameFileIdDifferentSource(mainFileRow.SourceLineNumbers, fileId, patchFileRow.Source, mainWixFileRow.Source));
250 - }
251 -
252 - // capture the previous file versions (and associated data) from this targeted instance of the baseline into the current filerow.
253 - patchFileRow.AppendPreviousDataFrom(mainWixFileRow);
254 - }
255 - }
256 - else
257 - {
258 - // copy data from the patch back to the transform
259 - if (null != patchFileRow)
260 - {
261 - var pairedFileRow = pairedFileRows.Get(fileId);
262 - for (var i = 0; i < patchFileRow.Fields.Length; i++)
263 - {
264 - var patchValue = patchFileRow[i] == null ? String.Empty : patchFileRow.FieldAsString(i);
265 - var mainValue = mainFileRow[i] == null ? String.Empty : mainFileRow.FieldAsString(i);
266 -
267 - if (1 == i)
268 - {
269 - // File.Component_ changes should not come from the shared file rows
270 - // that contain the file information as each individual transform might
271 - // have different changes (or no changes at all).
272 - }
273 - // File.Attributes should not changed for binary deltas
274 - else if (6 == i)
275 - {
276 - if (null != patchFileRow.Patch)
277 - {
278 - // File.Attribute should not change for binary deltas
279 - pairedFileRow.Attributes = mainFileRow.Attributes;
280 - mainFileRow.Fields[i].Modified = false;
281 - }
282 - }
283 - // File.Sequence is updated in pairedTransform, not mainTransform
284 - else if (7 == i)
285 - {
286 - // file sequence is updated in Patch table instead of File table for delta patches
287 - if (null != patchFileRow.Patch)
288 - {
289 - pairedFileRow.Fields[i].Modified = false;
290 - }
291 - else
292 - {
293 - pairedFileRow[i] = patchFileRow[i];
294 - pairedFileRow.Fields[i].Modified = true;
295 - }
296 - mainFileRow.Fields[i].Modified = false;
297 - }
298 - else if (patchValue != mainValue)
299 - {
300 - mainFileRow[i] = patchFileRow[i];
301 - mainFileRow.Fields[i].Modified = true;
302 - if (mainFileRow.Operation == RowOperation.None)
303 - {
304 - mainFileRow.Operation = RowOperation.Modify;
305 - }
306 - }
307 - }
308 -
309 - // copy MsiFileHash row for this File
310 - if (!mainMsiFileHashIndex.TryGetValue(patchFileRow.File, out var patchHashRow))
311 - {
312 - patchHashRow = patchFileRow.Hash;
313 - }
314 -
315 - if (null != patchHashRow)
316 - {
317 - var mainHashTable = mainTransform.EnsureTable(this.TableDefinitions["MsiFileHash"]);
318 - var mainHashRow = mainHashTable.CreateRow(mainFileRow.SourceLineNumbers);
319 - for (var i = 0; i < patchHashRow.Fields.Length; i++)
320 - {
321 - mainHashRow[i] = patchHashRow[i];
322 - if (i > 1)
323 - {
324 - // assume all hash fields have been modified
325 - mainHashRow.Fields[i].Modified = true;
326 - }
327 - }
328 -
329 - // assume the MsiFileHash operation follows the File one
330 - mainHashRow.Operation = mainFileRow.Operation;
331 - }
332 -
333 - // copy MsiAssemblyName rows for this File
334 - List<Row> patchAssemblyNameRows = patchFileRow.AssemblyNames;
335 - if (null != patchAssemblyNameRows)
336 - {
337 - var mainAssemblyNameTable = mainTransform.EnsureTable(this.TableDefinitions["MsiAssemblyName"]);
338 - foreach (var patchAssemblyNameRow in patchAssemblyNameRows)
339 - {
340 - // Copy if there isn't an identical modified/added row already in the transform.
341 - var foundMatchingModifiedRow = false;
342 - foreach (var mainAssemblyNameRow in mainAssemblyNameTable.Rows)
343 - {
344 - if (RowOperation.None != mainAssemblyNameRow.Operation && mainAssemblyNameRow.GetPrimaryKey('/').Equals(patchAssemblyNameRow.GetPrimaryKey('/')))
345 - {
346 - foundMatchingModifiedRow = true;
347 - break;
348 - }
349 - }
350 -
351 - if (!foundMatchingModifiedRow)
352 - {
353 - var mainAssemblyNameRow = mainAssemblyNameTable.CreateRow(mainFileRow.SourceLineNumbers);
354 - for (var i = 0; i < patchAssemblyNameRow.Fields.Length; i++)
355 - {
356 - mainAssemblyNameRow[i] = patchAssemblyNameRow[i];
357 - }
358 -
359 - // assume value field has been modified
360 - mainAssemblyNameRow.Fields[2].Modified = true;
361 - mainAssemblyNameRow.Operation = mainFileRow.Operation;
362 - }
363 - }
364 - }
365 -
366 - // Add patch header for this file
367 - if (null != patchFileRow.Patch)
368 - {
369 - // Add the PatchFiles action automatically to the AdminExecuteSequence and InstallExecuteSequence tables.
370 - this.AddPatchFilesActionToSequenceTable(SequenceTable.AdminExecuteSequence, mainTransform, pairedTransform, mainFileRow);
371 - this.AddPatchFilesActionToSequenceTable(SequenceTable.InstallExecuteSequence, mainTransform, pairedTransform, mainFileRow);
372 -
373 - // Add to Patch table
374 - var patchTable = pairedTransform.EnsureTable(this.TableDefinitions["Patch"]);
375 - if (0 == patchTable.Rows.Count)
376 - {
377 - patchTable.Operation = TableOperation.Add;
378 - }
379 -
380 - var patchRow = patchTable.CreateRow(mainFileRow.SourceLineNumbers);
381 - patchRow[0] = patchFileRow.File;
382 - patchRow[1] = patchFileRow.Sequence;
383 -
384 - var patchFile = new FileInfo(patchFileRow.Source);
385 - patchRow[2] = (int)patchFile.Length;
386 - patchRow[3] = 0 == (PatchAttributeType.AllowIgnoreOnError & patchFileRow.PatchAttributes) ? 0 : 1;
387 -
388 - var streamName = patchTable.Name + "." + patchRow[0] + "." + patchRow[1];
389 - if (Msi.MsiInterop.MsiMaxStreamNameLength < streamName.Length)
390 - {
391 - streamName = "_" + Guid.NewGuid().ToString("D").ToUpperInvariant().Replace('-', '_');
392 -
393 - var patchHeadersTable = pairedTransform.EnsureTable(this.TableDefinitions["MsiPatchHeaders"]);
394 - if (0 == patchHeadersTable.Rows.Count)
395 - {
396 - patchHeadersTable.Operation = TableOperation.Add;
397 - }
398 -
399 - var patchHeadersRow = patchHeadersTable.CreateRow(mainFileRow.SourceLineNumbers);
400 - patchHeadersRow[0] = streamName;
401 - patchHeadersRow[1] = patchFileRow.Patch;
402 - patchRow[5] = streamName;
403 - patchHeadersRow.Operation = RowOperation.Add;
404 - }
405 - else
406 - {
407 - patchRow[4] = patchFileRow.Patch;
408 - }
409 - patchRow.Operation = RowOperation.Add;
410 - }
411 - }
412 - else
413 - {
414 - // TODO: throw because all transform rows should have made it into the patch
415 - }
416 - }
417 - }
418 - }
419 -
420 - if (copyFromPatch)
421 - {
422 - this.Output.Tables.Remove("Media");
423 - this.Output.Tables.Remove("File");
424 - this.Output.Tables.Remove("MsiFileHash");
425 - this.Output.Tables.Remove("MsiAssemblyName");
426 - }
427 - }
428 - }
429 - finally
430 - {
431 - this.FileManagerCore.ActiveSubStorage = null;
432 - }
433 -
434 - this.FileFacades = allFileRows;
435 - }
436 -
437 - /// <summary>
438 - /// Adds the PatchFiles action to the sequence table if it does not already exist.
439 - /// </summary>
440 - /// <param name="table">The sequence table to check or modify.</param>
441 - /// <param name="mainTransform">The primary authoring transform.</param>
442 - /// <param name="pairedTransform">The secondary patch transform.</param>
443 - /// <param name="mainFileRow">The file row that contains information about the patched file.</param>
444 - private void AddPatchFilesActionToSequenceTable(SequenceTable table, WindowsInstallerData mainTransform, WindowsInstallerData pairedTransform, Row mainFileRow)
445 - {
446 - var tableName = table.ToString();
447 -
448 - // Find/add PatchFiles action (also determine sequence for it).
449 - // Search mainTransform first, then pairedTransform (pairedTransform overrides).
450 - var hasPatchFilesAction = false;
451 - var installFilesSequence = 0;
452 - var duplicateFilesSequence = 0;
453 -
454 - TestSequenceTableForPatchFilesAction(
455 - mainTransform.Tables[tableName],
456 - ref hasPatchFilesAction,
457 - ref installFilesSequence,
458 - ref duplicateFilesSequence);
459 - TestSequenceTableForPatchFilesAction(
460 - pairedTransform.Tables[tableName],
461 - ref hasPatchFilesAction,
462 - ref installFilesSequence,
463 - ref duplicateFilesSequence);
464 - if (!hasPatchFilesAction)
465 - {
466 - WindowsInstallerStandard.TryGetStandardAction(tableName, "PatchFiles", out var patchFilesActionSymbol);
467 -
468 - var sequence = patchFilesActionSymbol.Sequence;
469 -
470 - // Test for default sequence value's appropriateness
471 - if (installFilesSequence >= sequence || (0 != duplicateFilesSequence && duplicateFilesSequence <= sequence))
472 - {
473 - if (0 != duplicateFilesSequence)
474 - {
475 - if (duplicateFilesSequence < installFilesSequence)
476 - {
477 - throw new WixException(ErrorMessages.InsertInvalidSequenceActionOrder(mainFileRow.SourceLineNumbers, tableName, "InstallFiles", "DuplicateFiles", patchFilesActionSymbol.Action));
478 - }
479 - else
480 - {
481 - sequence = (duplicateFilesSequence + installFilesSequence) / 2;
482 - if (installFilesSequence == sequence || duplicateFilesSequence == sequence)
483 - {
484 - throw new WixException(ErrorMessages.InsertSequenceNoSpace(mainFileRow.SourceLineNumbers, tableName, "InstallFiles", "DuplicateFiles", patchFilesActionSymbol.Action));
485 - }
486 - }
487 - }
488 - else
489 - {
490 - sequence = installFilesSequence + 1;
491 - }
492 - }
493 -
494 - var sequenceTable = pairedTransform.EnsureTable(this.TableDefinitions[tableName]);
495 - if (0 == sequenceTable.Rows.Count)
496 - {
497 - sequenceTable.Operation = TableOperation.Add;
498 - }
499 -
500 - var patchAction = sequenceTable.CreateRow(null);
501 - patchAction[0] = patchFilesActionSymbol.Action;
502 - patchAction[1] = patchFilesActionSymbol.Condition;
503 - patchAction[2] = sequence;
504 - patchAction.Operation = RowOperation.Add;
505 - }
506 - }
507 -
508 - /// <summary>
509 - /// Tests sequence table for PatchFiles and associated actions
510 - /// </summary>
511 - /// <param name="sequenceTable">The table to test.</param>
512 - /// <param name="hasPatchFilesAction">Set to true if PatchFiles action is found. Left unchanged otherwise.</param>
513 - /// <param name="installFilesSequence">Set to sequence value of InstallFiles action if found. Left unchanged otherwise.</param>
514 - /// <param name="duplicateFilesSequence">Set to sequence value of DuplicateFiles action if found. Left unchanged otherwise.</param>
515 - private static void TestSequenceTableForPatchFilesAction(Table sequenceTable, ref bool hasPatchFilesAction, ref int installFilesSequence, ref int duplicateFilesSequence)
516 - {
517 - if (null != sequenceTable)
518 - {
519 - foreach (var row in sequenceTable.Rows)
520 - {
521 - var actionName = row.FieldAsString(0);
522 - switch (actionName)
523 - {
524 - case "PatchFiles":
525 - hasPatchFilesAction = true;
526 - break;
527 -
528 - case "InstallFiles":
529 - installFilesSequence = row.FieldAsInteger(2);
530 - break;
531 -
532 - case "DuplicateFiles":
533 - duplicateFilesSequence = row.FieldAsInteger(2);
534 - break;
535 - }
536 - }
537 - }
538 - }
539 -
540 - /// <summary>
541 - /// Signal a warning if a non-keypath file was changed in a patch without also changing the keypath file of the component.
542 - /// </summary>
543 - /// <param name="output">The output to validate.</param>
544 - private void ValidateFileRowChanges(WindowsInstallerData transform)
545 - {
546 - var componentTable = transform.Tables["Component"];
547 - var fileTable = transform.Tables["File"];
548 -
549 - // There's no sense validating keypaths if the transform has no component or file table
550 - if (componentTable == null || fileTable == null)
551 - {
552 - return;
553 - }
554 -
555 - var componentKeyPath = new Dictionary<string, string>(componentTable.Rows.Count);
556 -
557 - // Index the Component table for non-directory & non-registry key paths.
558 - foreach (var row in componentTable.Rows)
559 - {
560 - var keyPath = row.FieldAsString(5);
561 - if (keyPath != null && 0 != (row.FieldAsInteger(3) & WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath))
562 - {
563 - componentKeyPath.Add(row.FieldAsString(0), keyPath);
564 - }
565 - }
566 -
567 - var componentWithChangedKeyPath = new Dictionary<string, string>();
568 - var componentWithNonKeyPathChanged = new Dictionary<string, string>();
569 - // Verify changes in the file table, now that file diffing has occurred
570 - foreach (FileRow row in fileTable.Rows)
571 - {
572 - if (RowOperation.Modify != row.Operation)
573 - {
574 - continue;
575 - }
576 -
577 - var fileId = row.FieldAsString(0);
578 - var componentId = row.FieldAsString(1);
579 -
580 - // If this file is the keypath of a component
581 - if (componentKeyPath.ContainsValue(fileId))
582 - {
583 - if (!componentWithChangedKeyPath.ContainsKey(componentId))
584 - {
585 - componentWithChangedKeyPath.Add(componentId, fileId);
586 - }
587 - }
588 - else
589 - {
590 - if (!componentWithNonKeyPathChanged.ContainsKey(componentId))
591 - {
592 - componentWithNonKeyPathChanged.Add(componentId, fileId);
593 - }
594 - }
595 - }
596 -
597 - foreach (var componentFile in componentWithNonKeyPathChanged)
598 - {
599 - // Make sure all changes to non keypath files also had a change in the keypath.
600 - if (!componentWithChangedKeyPath.ContainsKey(componentFile.Key) && componentKeyPath.TryGetValue(componentFile.Key, out var keyPath))
601 - {
602 - this.Messaging.Write(WarningMessages.UpdateOfNonKeyPathFile(componentFile.Value, componentFile.Key, keyPath));
603 - }
604 - }
605 - }
606 -
607 - private bool CompareFiles(string targetFile, string updatedFile)
608 - {
609 - bool? compared = null;
610 - foreach (var extension in this.Extensions)
611 - {
612 - compared = extension.CompareFiles(targetFile, updatedFile);
613 -
614 - if (compared.HasValue)
615 - {
616 - break;
617 - }
618 - }
619 -
620 - if (!compared.HasValue)
621 - {
622 - throw new InvalidOperationException(); // TODO: something needs to be said here that none of the binder file managers returned a result.
623 - }
624 -
625 - return compared.Value;
626 - }
627 - }
628 -}
629 -
630 -#endif
src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs
+2 -2
@@ -80,7 +80,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
80
81 public string ModularizationSuffix { private get; set; }
82
83 - public Dictionary<MediaSymbol, IEnumerable<FileFacade>> FileFacadesByCabinet { private get; set; }
83 + public Dictionary<MediaSymbol, IEnumerable<IFileFacade>> FileFacadesByCabinet { private get; set; }
84
85 public Func<MediaSymbol, string, string, string> ResolveMedia { private get; set; }
86
@@ -177,7 +177,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
177 /// <param name="compressionLevel">Desired compression level.</param>
178 /// <param name="fileFacades">Collection of files in this cabinet.</param>
179 /// <returns>created CabinetWorkItem object</returns>
180 - private CabinetWorkItem CreateCabinetWorkItem(WindowsInstallerData data, string cabinetDir, MediaSymbol mediaSymbol, CompressionLevel compressionLevel, IEnumerable<FileFacade> fileFacades)
180 + private CabinetWorkItem CreateCabinetWorkItem(WindowsInstallerData data, string cabinetDir, MediaSymbol mediaSymbol, CompressionLevel compressionLevel, IEnumerable<IFileFacade> fileFacades)
181 {
182 CabinetWorkItem cabinetWorkItem = null;
183 var tempCabinetFileX = Path.Combine(this.IntermediateFolder, mediaSymbol.Cabinet);
src/WixToolset.Core.WindowsInstaller/Bind/CreateDeltaPatchesCommand.cs
+4 -3
@@ -9,20 +9,21 @@ namespace WixToolset.Core.WindowsInstaller.Bind
9 using WixToolset.Core.Bind;
10 using WixToolset.Data;
11 using WixToolset.Data.Symbols;
12 + using WixToolset.Extensibility.Data;
13
14 /// <summary>
15 /// Creates delta patches and updates the appropriate rows to point to the newly generated patches.
16 /// </summary>
17 internal class CreateDeltaPatchesCommand
18 {
18 - public CreateDeltaPatchesCommand(List<FileFacade> fileFacades, string intermediateFolder, WixPatchIdSymbol wixPatchId)
19 + public CreateDeltaPatchesCommand(List<IFileFacade> fileFacades, string intermediateFolder, WixPatchIdSymbol wixPatchId)
20 {
21 this.FileFacades = fileFacades;
22 this.IntermediateFolder = intermediateFolder;
23 this.WixPatchId = wixPatchId;
24 }
25
25 - private IEnumerable<FileFacade> FileFacades { get; }
26 + private IEnumerable<IFileFacade> FileFacades { get; }
27
28 private WixPatchIdSymbol WixPatchId { get; }
29
@@ -31,7 +32,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
32 public void Execute()
33 {
34 var optimizePatchSizeForLargeFiles = this.WixPatchId?.OptimizePatchSizeForLargeFiles ?? false;
34 - var apiPatchingSymbolFlags = (PatchSymbolFlagsType)(this.WixPatchId?.ApiPatchingSymbolFlags ?? 0);
35 + var apiPatchingSymbolFlags = (PatchSymbolFlags)(this.WixPatchId?.ApiPatchingSymbolFlags ?? 0);
36
37 #if TODO_PATCHING_DELTA
38 foreach (FileFacade facade in this.FileFacades)
src/WixToolset.Core.WindowsInstaller/Bind/CreateInstanceTransformsCommand.cs
+1 -1
@@ -110,7 +110,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
110 var productCode = instanceSymbol.ProductCode;
111 if ("*" == productCode)
112 {
113 - productCode = Common.GenerateGuid();
113 + productCode = this.BackendHelper.CreateGuid();
114 }
115
116 var productCodeRow = propertyTable.CreateRow(instanceSymbol.SourceLineNumbers);
src/WixToolset.Core.WindowsInstaller/Bind/CreatePatchTransformsCommand.cs
+6 -3
@@ -15,15 +15,18 @@ namespace WixToolset.Core.WindowsInstaller.Bind
15
16 internal class CreatePatchTransformsCommand
17 {
18 - public CreatePatchTransformsCommand(IMessaging messaging, Intermediate intermediate, string intermediateFolder)
18 + public CreatePatchTransformsCommand(IMessaging messaging, IBackendHelper backendHelper, Intermediate intermediate, string intermediateFolder)
19 {
20 this.Messaging = messaging;
21 + this.BackendHelper = backendHelper;
22 this.Intermediate = intermediate;
23 this.IntermediateFolder = intermediateFolder;
24 }
25
26 private IMessaging Messaging { get; }
27
28 + private IBackendHelper BackendHelper { get; }
29 +
30 private Intermediate Intermediate { get; }
31
32 private string IntermediateFolder { get; }
@@ -52,7 +55,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
55 {
56 var exportBasePath = Path.Combine(this.IntermediateFolder, "_trans"); // TODO: come up with a better path.
57
55 - var command = new UnbindTransformCommand(this.Messaging, symbol.TransformFile.Path, exportBasePath, this.IntermediateFolder);
58 + var command = new UnbindTransformCommand(this.Messaging, this.BackendHelper, symbol.TransformFile.Path, exportBasePath, this.IntermediateFolder);
59 transform = command.Execute();
60 }
61
@@ -76,7 +79,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
79
80 var isAdminImage = false; // TODO: need a better way to set this
81
79 - var command = new UnbindDatabaseCommand(this.Messaging, database, path, OutputType.Product, exportBasePath, this.IntermediateFolder, isAdminImage, suppressDemodularization: true, skipSummaryInfo: true);
82 + var command = new UnbindDatabaseCommand(this.Messaging, this.BackendHelper, database, path, OutputType.Product, exportBasePath, this.IntermediateFolder, isAdminImage, suppressDemodularization: true, skipSummaryInfo: true);
83 return command.Execute();
84 }
85 }
src/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs
+42 -41
@@ -481,18 +481,18 @@ namespace WixToolset.Core.WindowsInstaller.Bind
481
482 private void AddDirectorySymbol(DirectorySymbol symbol)
483 {
484 - if (String.IsNullOrEmpty(symbol.ShortName) && symbol.Name != null && !symbol.Name.Equals(".") && !symbol.Name.Equals("SourceDir") && !Common.IsValidShortFilename(symbol.Name, false))
484 + if (String.IsNullOrEmpty(symbol.ShortName) && symbol.Name != null && !symbol.Name.Equals(".") && !symbol.Name.Equals("SourceDir") && !this.BackendHelper.IsValidShortFilename(symbol.Name, false))
485 {
486 - symbol.ShortName = CreateShortName(symbol.Name, false, false, "Directory", symbol.ParentDirectoryRef);
486 + symbol.ShortName = this.CreateShortName(symbol.Name, false, "Directory", symbol.ParentDirectoryRef);
487 }
488
489 - if (String.IsNullOrEmpty(symbol.SourceShortName) && !String.IsNullOrEmpty(symbol.SourceName) && !Common.IsValidShortFilename(symbol.SourceName, false))
489 + if (String.IsNullOrEmpty(symbol.SourceShortName) && !String.IsNullOrEmpty(symbol.SourceName) && !this.BackendHelper.IsValidShortFilename(symbol.SourceName, false))
490 {
491 - symbol.SourceShortName = CreateShortName(symbol.SourceName, false, false, "Directory", symbol.ParentDirectoryRef);
491 + symbol.SourceShortName = this.CreateShortName(symbol.SourceName, false, "Directory", symbol.ParentDirectoryRef);
492 }
493
494 - var sourceName = GetMsiFilenameValue(symbol.SourceShortName, symbol.SourceName);
495 - var targetName = GetMsiFilenameValue(symbol.ShortName, symbol.Name);
494 + var sourceName = CreateMsiFilename(symbol.SourceShortName, symbol.SourceName);
495 + var targetName = CreateMsiFilename(symbol.ShortName, symbol.Name);
496
497 if (String.IsNullOrEmpty(targetName))
498 {
@@ -542,16 +542,16 @@ namespace WixToolset.Core.WindowsInstaller.Bind
542 private void AddDuplicateFileSymbol(DuplicateFileSymbol symbol)
543 {
544 var name = symbol.DestinationName;
545 - if (null == symbol.DestinationShortName && null != name && !Common.IsValidShortFilename(name, false))
545 + if (null == symbol.DestinationShortName && null != name && !this.BackendHelper.IsValidShortFilename(name, false))
546 {
547 - symbol.DestinationShortName = CreateShortName(name, true, false, "CopyFile", symbol.ComponentRef, symbol.FileRef);
547 + symbol.DestinationShortName = this.CreateShortName(name, true, "CopyFile", symbol.ComponentRef, symbol.FileRef);
548 }
549
550 var row = this.CreateRow(symbol, "DuplicateFile");
551 row[0] = symbol.Id.Id;
552 row[1] = symbol.ComponentRef;
553 row[2] = symbol.FileRef;
554 - row[3] = GetMsiFilenameValue(symbol.DestinationShortName, symbol.DestinationName);
554 + row[3] = CreateMsiFilename(symbol.DestinationShortName, symbol.DestinationName);
555 row[4] = symbol.DestinationFolder;
556 }
557
@@ -621,9 +621,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind
621 private void AddFileSymbol(FileSymbol symbol)
622 {
623 var name = symbol.Name;
624 - if (null == symbol.ShortName && null != name && !Common.IsValidShortFilename(name, false))
624 + if (null == symbol.ShortName && null != name && !this.BackendHelper.IsValidShortFilename(name, false))
625 {
626 - symbol.ShortName = CreateShortName(name, true, false, "File", symbol.DirectoryRef);
626 + symbol.ShortName = this.CreateShortName(name, true, "File", symbol.DirectoryRef);
627
628 if (!this.GeneratedShortNames.TryGetValue(symbol.ShortName, out var potentialConflicts))
629 {
@@ -637,7 +637,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
637 var row = (FileRow)this.CreateRow(symbol, "File");
638 row.File = symbol.Id.Id;
639 row.Component = symbol.ComponentRef;
640 - row.FileName = GetMsiFilenameValue(symbol.ShortName, name);
640 + row.FileName = CreateMsiFilename(symbol.ShortName, name);
641 row.FileSize = symbol.FileSize;
642 row.Version = symbol.Version;
643 row.Language = symbol.Language;
@@ -674,14 +674,14 @@ namespace WixToolset.Core.WindowsInstaller.Bind
674 var tableName = (IniFileActionType.AddLine == symbol.Action || IniFileActionType.AddTag == symbol.Action || IniFileActionType.CreateLine == symbol.Action) ? "IniFile" : "RemoveIniFile";
675
676 var name = symbol.FileName;
677 - if (null == symbol.ShortFileName && null != name && !Common.IsValidShortFilename(name, false))
677 + if (null == symbol.ShortFileName && null != name && !this.BackendHelper.IsValidShortFilename(name, false))
678 {
679 - symbol.ShortFileName = CreateShortName(name, true, false, "IniFile", symbol.ComponentRef);
679 + symbol.ShortFileName = this.CreateShortName(name, true, "IniFile", symbol.ComponentRef);
680 }
681
682 var row = this.CreateRow(symbol, tableName);
683 row[0] = symbol.Id.Id;
684 - row[1] = GetMsiFilenameValue(symbol.ShortFileName, name);
684 + row[1] = CreateMsiFilename(symbol.ShortFileName, name);
685 row[2] = symbol.DirProperty;
686 row[3] = symbol.Section;
687 row[4] = symbol.Key;
@@ -693,14 +693,14 @@ namespace WixToolset.Core.WindowsInstaller.Bind
693 private void AddIniLocatorSymbol(IniLocatorSymbol symbol)
694 {
695 var name = symbol.FileName;
696 - if (null == symbol.ShortFileName && null != name && !Common.IsValidShortFilename(name, false))
696 + if (null == symbol.ShortFileName && null != name && !this.BackendHelper.IsValidShortFilename(name, false))
697 {
698 - symbol.ShortFileName = CreateShortName(name, true, false, "IniFileSearch");
698 + symbol.ShortFileName = this.CreateShortName(name, true, "IniFileSearch");
699 }
700
701 var row = this.CreateRow(symbol, "IniLocator");
702 row[0] = symbol.Id.Id;
703 - row[1] = GetMsiFilenameValue(symbol.ShortFileName, name);
703 + row[1] = CreateMsiFilename(symbol.ShortFileName, name);
704 row[2] = symbol.Section;
705 row[3] = symbol.Key;
706 row[4] = symbol.Field;
@@ -786,16 +786,16 @@ namespace WixToolset.Core.WindowsInstaller.Bind
786 private void AddMoveFileSymbol(MoveFileSymbol symbol)
787 {
788 var name = symbol.DestinationName;
789 - if (null == symbol.DestinationShortName && null != name && !Common.IsValidShortFilename(name, false))
789 + if (null == symbol.DestinationShortName && null != name && !this.BackendHelper.IsValidShortFilename(name, false))
790 {
791 - symbol.DestinationShortName = CreateShortName(name, true, false, "MoveFile", symbol.ComponentRef);
791 + symbol.DestinationShortName = this.CreateShortName(name, true, "MoveFile", symbol.ComponentRef);
792 }
793
794 var row = this.CreateRow(symbol, "MoveFile");
795 row[0] = symbol.Id.Id;
796 row[1] = symbol.ComponentRef;
797 row[2] = symbol.SourceName;
798 - row[3] = GetMsiFilenameValue(symbol.DestinationShortName, symbol.DestinationName);
798 + row[3] = CreateMsiFilename(symbol.DestinationShortName, symbol.DestinationName);
799 row[4] = symbol.SourceFolder;
800 row[5] = symbol.DestFolder;
801 row[6] = symbol.Delete ? WindowsInstallerConstants.MsidbMoveFileOptionsMove : 0;
@@ -816,9 +816,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind
816 private void AddRemoveFileSymbol(RemoveFileSymbol symbol)
817 {
818 var name = symbol.FileName;
819 - if (null == symbol.ShortFileName && null != name && !Common.IsValidShortFilename(name, false))
819 + if (null == symbol.ShortFileName && null != name && !this.BackendHelper.IsValidShortFilename(name, false))
820 {
821 - symbol.ShortFileName = CreateShortName(name, true, false, "RemoveFile", symbol.ComponentRef);
821 + symbol.ShortFileName = this.CreateShortName(name, true, "RemoveFile", symbol.ComponentRef);
822 }
823
824 var installMode = symbol.OnInstall == true ? WindowsInstallerConstants.MsidbRemoveFileInstallModeOnInstall : 0;
@@ -827,7 +827,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
827 var row = this.CreateRow(symbol, "RemoveFile");
828 row[0] = symbol.Id.Id;
829 row[1] = symbol.ComponentRef;
830 - row[2] = GetMsiFilenameValue(symbol.ShortFileName, symbol.FileName);
830 + row[2] = CreateMsiFilename(symbol.ShortFileName, symbol.FileName);
831 row[3] = symbol.DirPropertyRef;
832 row[4] = installMode;
833 }
@@ -966,15 +966,15 @@ namespace WixToolset.Core.WindowsInstaller.Bind
966 private void AddShortcutSymbol(ShortcutSymbol symbol)
967 {
968 var name = symbol.Name;
969 - if (null == symbol.ShortName && null != name && !Common.IsValidShortFilename(name, false))
969 + if (null == symbol.ShortName && null != name && !this.BackendHelper.IsValidShortFilename(name, false))
970 {
971 - symbol.ShortName = CreateShortName(name, true, false, "Shortcut", symbol.ComponentRef, symbol.DirectoryRef);
971 + symbol.ShortName = this.CreateShortName(name, true, "Shortcut", symbol.ComponentRef, symbol.DirectoryRef);
972 }
973
974 var row = this.CreateRow(symbol, "Shortcut");
975 row[0] = symbol.Id.Id;
976 row[1] = symbol.DirectoryRef;
977 - row[2] = GetMsiFilenameValue(symbol.ShortName, name);
977 + row[2] = CreateMsiFilename(symbol.ShortName, name);
978 row[3] = symbol.ComponentRef;
979 row[4] = symbol.Target;
980 row[5] = symbol.Arguments;
@@ -1177,7 +1177,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
1177 }
1178 else if (rowField.Column.Category == ColumnCategory.Identifier)
1179 {
1180 - if (Common.IsIdentifier(data) || Common.IsValidBinderVariable(data) || ColumnCategory.Formatted == rowField.Column.Category)
1180 + if (this.BackendHelper.IsValidIdentifier(data) || this.BackendHelper.IsValidBinderVariable(data) || ColumnCategory.Formatted == rowField.Column.Category)
1181 {
1182 rowField.Data = data;
1183 }
@@ -1488,19 +1488,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
1488 private Row CreateRow(IntermediateSymbol symbol, TableDefinition tableDefinition) =>
1489 this.BackendHelper.CreateRow(this.Section, symbol, this.Data, tableDefinition);
1490
1491 - private static string GetMsiFilenameValue(string shortName, string longName)
1492 - {
1493 - if (String.IsNullOrEmpty(shortName) || String.Equals(shortName, longName, StringComparison.OrdinalIgnoreCase))
1494 - {
1495 - return longName;
1496 - }
1497 - else
1498 - {
1499 - return shortName + "|" + longName;
1500 - }
1501 - }
1491
1503 - private static string CreateShortName(string longName, bool keepExtension, bool allowWildcards, params string[] args)
1492 + private string CreateShortName(string longName, bool keepExtension, params string[] args)
1493 {
1494 longName = longName.ToLowerInvariant();
1495
@@ -1537,7 +1526,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
1526 shortName.Append(extension);
1527
1528 // check the generated short name to ensure its still legal (the extension may not be legal)
1540 - if (!Common.IsValidShortFilename(shortName.ToString(), allowWildcards))
1529 + if (!this.BackendHelper.IsValidShortFilename(shortName.ToString(), false))
1530 {
1531 // remove the extension (by truncating the generated file name back to the generated characters)
1532 shortName.Length -= extension.Length;
@@ -1546,5 +1535,17 @@ namespace WixToolset.Core.WindowsInstaller.Bind
1535
1536 return shortName.ToString().ToLowerInvariant();
1537 }
1538 +
1539 + private static string CreateMsiFilename(string shortName, string longName)
1540 + {
1541 + if (String.IsNullOrEmpty(shortName) || String.Equals(shortName, longName, StringComparison.OrdinalIgnoreCase))
1542 + {
1543 + return longName;
1544 + }
1545 + else
1546 + {
1547 + return shortName + "|" + longName;
1548 + }
1549 + }
1550 }
1551 }
src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs
+11 -8
@@ -11,19 +11,20 @@ namespace WixToolset.Core.WindowsInstaller.Bind
11 using System.Runtime.InteropServices;
12 using WixToolset.Data;
13 using WixToolset.Core.Native;
14 - using WixToolset.Core.Bind;
14 using WixToolset.Data.Symbols;
15 using WixToolset.Extensibility.Services;
16 using WixToolset.Core.WindowsInstaller.Msi;
17 + using WixToolset.Extensibility.Data;
18
19 /// <summary>
20 /// Retrieve files information and extract them from merge modules.
21 /// </summary>
22 internal class ExtractMergeModuleFilesCommand
23 {
24 - public ExtractMergeModuleFilesCommand(IMessaging messaging, IEnumerable<WixMergeSymbol> wixMergeSymbols, IEnumerable<FileFacade> fileFacades, int installerVersion, string intermediateFolder, bool suppressLayout)
24 + public ExtractMergeModuleFilesCommand(IMessaging messaging, IWindowsInstallerBackendHelper backendHelper, IEnumerable<WixMergeSymbol> wixMergeSymbols, IEnumerable<IFileFacade> fileFacades, int installerVersion, string intermediateFolder, bool suppressLayout)
25 {
26 this.Messaging = messaging;
27 + this.BackendHelper = backendHelper;
28 this.WixMergeSymbols = wixMergeSymbols;
29 this.FileFacades = fileFacades;
30 this.OutputInstallerVersion = installerVersion;
@@ -33,9 +34,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind
34
35 private IMessaging Messaging { get; }
36
37 + private IWindowsInstallerBackendHelper BackendHelper { get; }
38 +
39 private IEnumerable<WixMergeSymbol> WixMergeSymbols { get; }
40
38 - private IEnumerable<FileFacade> FileFacades { get; }
41 + private IEnumerable<IFileFacade> FileFacades { get; }
42
43 private int OutputInstallerVersion { get; }
44
@@ -43,11 +46,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind
46
47 private bool SuppressLayout { get; }
48
46 - public IEnumerable<FileFacade> MergeModulesFileFacades { get; private set; }
49 + public IEnumerable<IFileFacade> MergeModulesFileFacades { get; private set; }
50
51 public void Execute()
52 {
50 - var mergeModulesFileFacades = new List<FileFacade>();
53 + var mergeModulesFileFacades = new List<IFileFacade>();
54
55 var interop = new MsmInterop();
56 var merge = interop.GetMsmMerge();
@@ -75,7 +78,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
78 this.MergeModulesFileFacades = mergeModulesFileFacades;
79 }
80
78 - private bool CreateFacadesForMergeModuleFiles(WixMergeSymbol wixMergeRow, List<FileFacade> mergeModulesFileFacades, Dictionary<string, FileFacade> indexedFileFacades)
81 + private bool CreateFacadesForMergeModuleFiles(WixMergeSymbol wixMergeRow, List<IFileFacade> mergeModulesFileFacades, Dictionary<string, IFileFacade> indexedFileFacades)
82 {
83 var containsFiles = false;
84
@@ -86,7 +89,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
89 {
90 if (db.TableExists("File") && db.TableExists("Component"))
91 {
89 - var uniqueModuleFileIdentifiers = new Dictionary<string, FileFacade>(StringComparer.OrdinalIgnoreCase);
92 + var uniqueModuleFileIdentifiers = new Dictionary<string, IFileFacade>(StringComparer.OrdinalIgnoreCase);
93
94 using (var view = db.OpenExecuteView("SELECT `File`, `Directory_` FROM `File`, `Component` WHERE `Component_`=`Component`"))
95 {
@@ -102,7 +105,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
105 fileSymbol.DiskId = wixMergeRow.DiskId;
106 fileSymbol.Source = new IntermediateFieldPathValue { Path = Path.Combine(this.IntermediateFolder, wixMergeRow.Id.Id, record[1]) };
107
105 - var mergeModuleFileFacade = new FileFacade(true, fileSymbol);
108 + var mergeModuleFileFacade = this.BackendHelper.CreateFileFacadeFromMergeModule(fileSymbol);
109
110 // If case-sensitive collision with another merge module or a user-authored file identifier.
111 if (indexedFileFacades.TryGetValue(mergeModuleFileFacade.Id, out var collidingFacade))
src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesCommand.cs
+15 -6
@@ -6,36 +6,45 @@ namespace WixToolset.Core.WindowsInstaller.Bind
6 using System.Collections.Generic;
7 using System.Globalization;
8 using System.Linq;
9 - using WixToolset.Core.Bind;
9 using WixToolset.Data;
10 using WixToolset.Data.Symbols;
11 + using WixToolset.Extensibility.Data;
12 + using WixToolset.Extensibility.Services;
13
14 internal class GetFileFacadesCommand
15 {
15 - public GetFileFacadesCommand(IntermediateSection section)
16 + public GetFileFacadesCommand(IntermediateSection section, IWindowsInstallerBackendHelper backendHelper)
17 {
18 this.Section = section;
19 + this.BackendHelper = backendHelper;
20 }
21
22 private IntermediateSection Section { get; }
23
22 - public List<FileFacade> FileFacades { get; private set; }
24 + private IWindowsInstallerBackendHelper BackendHelper { get; }
25 +
26 + public List<IFileFacade> FileFacades { get; private set; }
27
28 public void Execute()
29 {
26 - var facades = new List<FileFacade>();
30 + var facades = new List<IFileFacade>();
31
32 var assemblyFile = this.Section.Symbols.OfType<AssemblySymbol>().ToDictionary(t => t.Id.Id);
33 +#if TODO_PATCHING_DELTA
34 //var deltaPatchFiles = this.Section.Symbols.OfType<WixDeltaPatchFileSymbol>().ToDictionary(t => t.Id.Id);
35 +#endif
36
37 foreach (var file in this.Section.Symbols.OfType<FileSymbol>())
38 {
39 assemblyFile.TryGetValue(file.Id.Id, out var assembly);
40
41 +#if TODO_PATCHING_DELTA
42 //deltaPatchFiles.TryGetValue(file.Id.Id, out var deltaPatchFile);
43 + // TODO: should we be passing along delta information to the file facade? Probably, right?
44 +#endif
45 + var fileFacade = this.BackendHelper.CreateFileFacade(file, assembly);
46
37 - facades.Add(new FileFacade(file, assembly));
38 - //facades.Add(new FileFacade(file, wixFile, deltaPatchFile));
47 + facades.Add(fileFacade);
48 }
49
50 #if TODO_PATCHING_DELTA
src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesFromTransforms.cs
+13 -8
@@ -5,35 +5,35 @@ namespace WixToolset.Core.WindowsInstaller.Bind
5 using System;
6 using System.Collections.Generic;
7 using System.Linq;
8 - using WixToolset.Core.Bind;
8 using WixToolset.Data;
9 using WixToolset.Data.WindowsInstaller;
10 using WixToolset.Data.WindowsInstaller.Rows;
12 - using WixToolset.Extensibility;
11 + using WixToolset.Extensibility.Data;
12 using WixToolset.Extensibility.Services;
13
14 internal class GetFileFacadesFromTransforms
15 {
17 - public GetFileFacadesFromTransforms(IMessaging messaging, FileSystemManager fileSystemManager, IEnumerable<SubStorage> subStorages)
16 + public GetFileFacadesFromTransforms(IMessaging messaging, IWindowsInstallerBackendHelper backendHelper, FileSystemManager fileSystemManager, IEnumerable<SubStorage> subStorages)
17 {
18 this.Messaging = messaging;
19 + this.BackendHelper = backendHelper;
20 this.FileSystemManager = fileSystemManager;
21 this.SubStorages = subStorages;
22 }
23
24 private IMessaging Messaging { get; }
25
26 + private IWindowsInstallerBackendHelper BackendHelper { get; }
27 +
28 private FileSystemManager FileSystemManager { get; }
29
30 private IEnumerable<SubStorage> SubStorages { get; }
31
30 - public List<FileFacade> FileFacades { get; private set; }
32 + public List<IFileFacade> FileFacades { get; private set; }
33
34 public void Execute()
35 {
34 - var allFileRows = new List<FileFacade>();
35 -
36 - var patchMediaRows = new RowDictionary<MediaRow>();
36 + var allFileRows = new List<IFileFacade>();
37
38 var patchMediaFileRows = new Dictionary<int, RowDictionary<FileRow>>();
39
@@ -143,7 +143,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind
143
144 mediaFileRows.Add(patchFileRow);
145
146 - allFileRows.Add(new FileFacade(patchFileRow)); // TODO: should we be passing along delta information? Probably, right?
146 +#if TODO_PATCHING_DELTA
147 + // TODO: should we be passing along delta information to the file facade? Probably, right?
148 +#endif
149 + var fileFacade = this.BackendHelper.CreateFileFacade(patchFileRow);
150 +
151 + allFileRows.Add(fileFacade);
152 }
153 else
154 {
src/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs
+3 -3
@@ -9,12 +9,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind
9 using System.Linq;
10 using System.Runtime.InteropServices;
11 using System.Text;
12 - using WixToolset.Core.Bind;
12 using WixToolset.Core.Native;
13 using WixToolset.Core.WindowsInstaller.Msi;
14 using WixToolset.Data;
15 using WixToolset.Data.Symbols;
16 using WixToolset.Data.WindowsInstaller;
17 + using WixToolset.Extensibility.Data;
18 using WixToolset.Extensibility.Services;
19
20 /// <summary>
@@ -22,7 +22,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
22 /// </summary>
23 internal class MergeModulesCommand
24 {
25 - public MergeModulesCommand(IMessaging messaging, IEnumerable<FileFacade> fileFacades, IntermediateSection section, IEnumerable<string> suppressedTableNames, string outputPath, string intermediateFolder)
25 + public MergeModulesCommand(IMessaging messaging, IEnumerable<IFileFacade> fileFacades, IntermediateSection section, IEnumerable<string> suppressedTableNames, string outputPath, string intermediateFolder)
26 {
27 this.Messaging = messaging;
28 this.FileFacades = fileFacades;
@@ -34,7 +34,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
34
35 private IMessaging Messaging { get; }
36
37 - private IEnumerable<FileFacade> FileFacades { get; }
37 + private IEnumerable<IFileFacade> FileFacades { get; }
38
39 private IntermediateSection Section { get; }
40
src/WixToolset.Core.WindowsInstaller/Bind/ModularizeCommand.cs
+8 -4
@@ -12,11 +12,13 @@ namespace WixToolset.Core.WindowsInstaller.Bind
12 using WixToolset.Data;
13 using WixToolset.Data.Symbols;
14 using WixToolset.Data.WindowsInstaller;
15 + using WixToolset.Extensibility.Services;
16
17 internal class ModularizeCommand
18 {
18 - public ModularizeCommand(WindowsInstallerData output, string modularizationSuffix, IEnumerable<WixSuppressModularizationSymbol> suppressSymbols)
19 + public ModularizeCommand(IBackendHelper backendHelper, WindowsInstallerData output, string modularizationSuffix, IEnumerable<WixSuppressModularizationSymbol> suppressSymbols)
20 {
21 + this.BackendHelper = backendHelper;
22 this.Output = output;
23 this.ModularizationSuffix = modularizationSuffix;
24
@@ -24,6 +26,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
26 this.SuppressModularizationIdentifiers = new HashSet<string>(suppressSymbols.Select(s => s.SuppressIdentifier));
27 }
28
29 + private IBackendHelper BackendHelper { get; }
30 +
31 private WindowsInstallerData Output { get; }
32
33 private string ModularizationSuffix { get; }
@@ -90,7 +94,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
94 case "SetTargetPath":
95 case "SpawnDialog":
96 case "SpawnWaitDialog":
93 - if (Common.IsIdentifier(fieldData))
97 + if (this.BackendHelper.IsValidIdentifier(fieldData))
98 {
99 modularizeType = ColumnModularizeType.Column;
100 }
@@ -107,7 +111,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
111 else if (ColumnModularizeType.ControlText == field.Column.ModularizeType)
112 {
113 // icons are stored in the Binary table, so they get column-type modularization
110 - if (("Bitmap" == row[2].ToString() || "Icon" == row[2].ToString()) && Common.IsIdentifier(fieldData))
114 + if (("Bitmap" == row[2].ToString() || "Icon" == row[2].ToString()) && this.BackendHelper.IsValidIdentifier(fieldData))
115 {
116 modularizeType = ColumnModularizeType.Column;
117 }
@@ -121,7 +125,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
125 {
126 case ColumnModularizeType.Column:
127 // ensure the value is an identifier (otherwise it shouldn't be modularized this way)
124 - if (!Common.IsIdentifier(fieldData))
128 + if (!this.BackendHelper.IsValidIdentifier(fieldData))
129 {
130 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixDataStrings.EXP_CannotModularizeIllegalID, fieldData));
131 }
src/WixToolset.Core.WindowsInstaller/Bind/OptimizeFileFacadesOrderCommand.cs
+5 -6
@@ -5,7 +5,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
5 using System;
6 using System.Collections.Generic;
7 using System.Linq;
8 - using WixToolset.Core.Bind;
8 using WixToolset.Data;
9 using WixToolset.Data.Symbols;
10 using WixToolset.Extensibility.Data;
@@ -13,7 +12,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
12
13 internal class OptimizeFileFacadesOrderCommand
14 {
16 - public OptimizeFileFacadesOrderCommand(IBackendHelper helper, IPathResolver pathResolver, IntermediateSection section, Platform platform, List<FileFacade> fileFacades)
15 + public OptimizeFileFacadesOrderCommand(IBackendHelper helper, IPathResolver pathResolver, IntermediateSection section, Platform platform, List<IFileFacade> fileFacades)
16 {
17 this.BackendHelper = helper;
18 this.PathResolver = pathResolver;
@@ -22,7 +21,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
21 this.FileFacades = fileFacades;
22 }
23
25 - public List<FileFacade> FileFacades { get; private set; }
24 + public List<IFileFacade> FileFacades { get; private set; }
25
26 private IBackendHelper BackendHelper { get; }
27
@@ -32,7 +31,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
31
32 private Platform Platform { get; }
33
35 - public List<FileFacade> Execute()
34 + public List<IFileFacade> Execute()
35 {
36 var canonicalComponentTargetPaths = this.ComponentTargetPaths();
37
@@ -69,7 +68,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
68 return targetPathsByDirectoryId;
69 }
70
72 - private class FileFacadeOptimizer : IComparer<FileFacade>
71 + private class FileFacadeOptimizer : IComparer<IFileFacade>
72 {
73 public FileFacadeOptimizer(Dictionary<string, string> componentTargetPaths, bool optimizingMergeModule)
74 {
@@ -81,7 +80,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
80
81 private bool OptimizingMergeModule { get; }
82
84 - public int Compare(FileFacade x, FileFacade y)
83 + public int Compare(IFileFacade x, IFileFacade y)
84 {
85 // First group files by DiskId but ignore if processing a Merge Module
86 // because Merge Modules don't have separate disks.
src/WixToolset.Core.WindowsInstaller/Bind/ProcessDependencyReferencesCommand.cs
+9 -6
@@ -17,12 +17,15 @@ namespace WixToolset.Core.WindowsInstaller.Bind
17 private const string DependencyRegistryRoot = @"Software\Classes\Installer\Dependencies\";
18 private const string RegistryDependents = "Dependents";
19
20 - public ProcessDependencyReferencesCommand(IntermediateSection section, IEnumerable<WixDependencyRefSymbol> dependencyRefSymbols)
20 + public ProcessDependencyReferencesCommand(IBackendHelper backendHelper, IntermediateSection section, IEnumerable<WixDependencyRefSymbol> dependencyRefSymbols)
21 {
22 + this.BackendHelper = backendHelper;
23 this.Section = section;
24 this.DependencyRefSymbols = dependencyRefSymbols;
25 }
26
27 + private IBackendHelper BackendHelper { get; }
28 +
29 private IntermediateSection Section { get; }
30
31 private IEnumerable<WixDependencyRefSymbol> DependencyRefSymbols { get; }
@@ -57,7 +60,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
60 // Get the component ID from the provider.
61 var componentId = wixDependencyProviderRow.ComponentRef;
62
60 - var id = Common.GenerateIdentifier("reg", providesId, requiresId, "(Default)");
63 + var id = this.BackendHelper.GenerateIdentifier("reg", providesId, requiresId, "(Default)");
64 this.Section.AddSymbol(new RegistrySymbol(wixDependencyRefRow.SourceLineNumbers, new Identifier(AccessModifier.Section, id))
65 {
66 ComponentRef = componentId,
@@ -68,7 +71,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
71
72 if (!String.IsNullOrEmpty(wixDependencyRow.MinVersion))
73 {
71 - id = Common.GenerateIdentifier("reg", providesId, requiresId, "MinVersion");
74 + id = this.BackendHelper.GenerateIdentifier("reg", providesId, requiresId, "MinVersion");
75 this.Section.AddSymbol(new RegistrySymbol(wixDependencyRefRow.SourceLineNumbers, new Identifier(AccessModifier.Section, id))
76 {
77 ComponentRef = componentId,
@@ -79,10 +82,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind
82 });
83 }
84
82 - string maxVersion = (string)wixDependencyRow[3];
85 + var maxVersion = (string)wixDependencyRow[3];
86 if (!String.IsNullOrEmpty(wixDependencyRow.MaxVersion))
87 {
85 - id = Common.GenerateIdentifier("reg", providesId, requiresId, "MaxVersion");
88 + id = this.BackendHelper.GenerateIdentifier("reg", providesId, requiresId, "MaxVersion");
89 this.Section.AddSymbol(new RegistrySymbol(wixDependencyRefRow.SourceLineNumbers, new Identifier(AccessModifier.Section, id))
90 {
91 ComponentRef = componentId,
@@ -95,7 +98,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
98
99 if (wixDependencyRow.Attributes != WixDependencySymbolAttributes.None)
100 {
98 - id = Common.GenerateIdentifier("reg", providesId, requiresId, "Attributes");
101 + id = this.BackendHelper.GenerateIdentifier("reg", providesId, requiresId, "Attributes");
102 this.Section.AddSymbol(new RegistrySymbol(wixDependencyRefRow.SourceLineNumbers, new Identifier(AccessModifier.Section, id))
103 {
104 ComponentRef = componentId,
src/WixToolset.Core.WindowsInstaller/Bind/ProcessUncompressedFilesCommand.cs
+7 -8
@@ -6,7 +6,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
6 using System.Collections.Generic;
7 using System.IO;
8 using System.Linq;
9 - using WixToolset.Core.Bind;
9 using WixToolset.Core.WindowsInstaller.Msi;
10 using WixToolset.Data;
11 using WixToolset.Data.Symbols;
@@ -33,7 +32,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
32
33 public string DatabasePath { private get; set; }
34
36 - public IEnumerable<FileFacade> FileFacades { private get; set; }
35 + public IEnumerable<IFileFacade> FileFacades { private get; set; }
36
37 public string LayoutDirectory { private get; set; }
38
@@ -63,7 +62,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
62 {
63 foreach (var directoryRecord in directoryView.Records)
64 {
66 - var sourceName = Common.GetName(directoryRecord.GetString(3), true, this.LongNamesInImage);
65 + var sourceName = this.BackendHelper.GetMsiFileName(directoryRecord.GetString(3), true, this.LongNamesInImage);
66
67 var resolvedDirectory = this.BackendHelper.CreateResolvedDirectory(directoryRecord.GetString(2), sourceName);
68
@@ -71,16 +70,16 @@ namespace WixToolset.Core.WindowsInstaller.Bind
70 }
71 }
72
74 - using (View fileView = db.OpenView("SELECT `Directory_`, `FileName` FROM `Component`, `File` WHERE `Component`.`Component`=`File`.`Component_` AND `File`.`File`=?"))
73 + using (var fileView = db.OpenView("SELECT `Directory_`, `FileName` FROM `Component`, `File` WHERE `Component`.`Component`=`File`.`Component_` AND `File`.`File`=?"))
74 {
76 - using (Record fileQueryRecord = new Record(1))
75 + using (var fileQueryRecord = new Record(1))
76 {
77 // for each file in the array of uncompressed files
79 - foreach (FileFacade facade in this.FileFacades)
78 + foreach (var facade in this.FileFacades)
79 {
80 var mediaSymbol = mediaRows[facade.DiskId];
81 string relativeFileLayoutPath = null;
83 - string mediaLayoutFolder = mediaSymbol.Layout;
82 + var mediaLayoutFolder = mediaSymbol.Layout;
83
84 var mediaLayoutDirectory = this.ResolveMedia(mediaSymbol, mediaLayoutFolder, this.LayoutDirectory);
85
@@ -89,7 +88,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
88 fileQueryRecord[1] = facade.Id;
89 fileView.Execute(fileQueryRecord);
90
92 - using (Record fileRecord = fileView.Fetch())
91 + using (var fileRecord = fileView.Fetch())
92 {
93 if (null == fileRecord)
94 {
src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs
+6 -6
@@ -8,10 +8,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind
8 using System.Globalization;
9 using System.IO;
10 using System.Linq;
11 - using WixToolset.Core.Bind;
11 using WixToolset.Core.WindowsInstaller.Msi;
12 using WixToolset.Data;
13 using WixToolset.Data.Symbols;
14 + using WixToolset.Extensibility.Data;
15 using WixToolset.Extensibility.Services;
16
17 /// <summary>
@@ -19,7 +19,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
19 /// </summary>
20 internal class UpdateFileFacadesCommand
21 {
22 - public UpdateFileFacadesCommand(IMessaging messaging, IntermediateSection section, IEnumerable<FileFacade> fileFacades, IEnumerable<FileFacade> updateFileFacades, IDictionary<string, string> variableCache, bool overwriteHash)
22 + public UpdateFileFacadesCommand(IMessaging messaging, IntermediateSection section, IEnumerable<IFileFacade> fileFacades, IEnumerable<IFileFacade> updateFileFacades, IDictionary<string, string> variableCache, bool overwriteHash)
23 {
24 this.Messaging = messaging;
25 this.Section = section;
@@ -33,9 +33,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind
33
34 private IntermediateSection Section { get; }
35
36 - private IEnumerable<FileFacade> FileFacades { get; }
36 + private IEnumerable<IFileFacade> FileFacades { get; }
37
38 - private IEnumerable<FileFacade> UpdateFileFacades { get; }
38 + private IEnumerable<IFileFacade> UpdateFileFacades { get; }
39
40 private bool OverwriteHash { get; }
41
@@ -51,7 +51,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
51 }
52 }
53
54 - private void UpdateFileFacade(FileFacade facade, Dictionary<string, MsiAssemblyNameSymbol> assemblyNameSymbols)
54 + private void UpdateFileFacade(IFileFacade facade, Dictionary<string, MsiAssemblyNameSymbol> assemblyNameSymbols)
55 {
56 FileInfo fileInfo = null;
57 try
@@ -314,7 +314,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
314 /// <param name="facade">FileFacade containing the assembly read for the MsiAssemblyName row.</param>
315 /// <param name="name">MsiAssemblyName name.</param>
316 /// <param name="value">MsiAssemblyName value.</param>
317 - private void SetMsiAssemblyName(Dictionary<string, MsiAssemblyNameSymbol> assemblyNameSymbols, FileFacade facade, string name, string value)
317 + private void SetMsiAssemblyName(Dictionary<string, MsiAssemblyNameSymbol> assemblyNameSymbols, IFileFacade facade, string name, string value)
318 {
319 // check for null value (this can occur when grabbing the file version from an assembly without one)
320 if (String.IsNullOrEmpty(value))
src/WixToolset.Core.WindowsInstaller/Bind/UpdateMediaSequencesCommand.cs
+7 -7
@@ -4,13 +4,13 @@ namespace WixToolset.Core.WindowsInstaller.Bind
4 {
5 using System.Collections.Generic;
6 using System.Linq;
7 - using WixToolset.Core.Bind;
7 using WixToolset.Data;
8 using WixToolset.Data.Symbols;
9 + using WixToolset.Extensibility.Data;
10
11 internal class UpdateMediaSequencesCommand
12 {
13 - public UpdateMediaSequencesCommand(IntermediateSection section, List<FileFacade> fileFacades)
13 + public UpdateMediaSequencesCommand(IntermediateSection section, IEnumerable<IFileFacade> fileFacades)
14 {
15 this.Section = section;
16 this.FileFacades = fileFacades;
@@ -18,7 +18,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
18
19 private IntermediateSection Section { get; }
20
21 - private List<FileFacade> FileFacades { get; }
21 + private IEnumerable<IFileFacade> FileFacades { get; }
22
23 public void Execute()
24 {
@@ -38,9 +38,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind
38 {
39 var lastSequence = 0;
40 MediaSymbol mediaSymbol = null;
41 - var patchGroups = new Dictionary<int, List<FileFacade>>();
41 + var patchGroups = new Dictionary<int, List<IFileFacade>>();
42
43 - // sequence the non-patch-added files
43 + // Sequence the non-patch-added files.
44 foreach (var facade in this.FileFacades)
45 {
46 if (null == mediaSymbol)
@@ -62,7 +62,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
62 {
63 if (patchGroups.TryGetValue(facade.PatchGroup.Value, out var patchGroup))
64 {
65 - patchGroup = new List<FileFacade>();
65 + patchGroup = new List<IFileFacade>();
66 patchGroups.Add(facade.PatchGroup.Value, patchGroup);
67 }
68
@@ -80,7 +80,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
80 mediaSymbol = null;
81 }
82
83 - // sequence the patch-added files
83 + // Sequence the patch-added files.
84 foreach (var patchGroup in patchGroups.Values)
85 {
86 foreach (var facade in patchGroup)
src/WixToolset.Core.WindowsInstaller/Bind/UpdateTransformsWithFileFacades.cs
+6 -6
@@ -5,16 +5,16 @@ namespace WixToolset.Core.WindowsInstaller.Bind
5 using System;
6 using System.Collections.Generic;
7 using System.Linq;
8 - using WixToolset.Core.Bind;
8 using WixToolset.Data;
9 using WixToolset.Data.Symbols;
10 using WixToolset.Data.WindowsInstaller;
11 using WixToolset.Data.WindowsInstaller.Rows;
12 + using WixToolset.Extensibility.Data;
13 using WixToolset.Extensibility.Services;
14
15 internal class UpdateTransformsWithFileFacades
16 {
17 - public UpdateTransformsWithFileFacades(IMessaging messaging, WindowsInstallerData output, IEnumerable<SubStorage> subStorages, TableDefinitionCollection tableDefinitions, IEnumerable<FileFacade> fileFacades)
17 + public UpdateTransformsWithFileFacades(IMessaging messaging, WindowsInstallerData output, IEnumerable<SubStorage> subStorages, TableDefinitionCollection tableDefinitions, IEnumerable<IFileFacade> fileFacades)
18 {
19 this.Messaging = messaging;
20 this.Output = output;
@@ -31,18 +31,18 @@ namespace WixToolset.Core.WindowsInstaller.Bind
31
32 private TableDefinitionCollection TableDefinitions { get; }
33
34 - private IEnumerable<FileFacade> FileFacades { get; }
34 + private IEnumerable<IFileFacade> FileFacades { get; }
35
36 public void Execute()
37 {
38 - var fileFacadesByDiskId = new Dictionary<int, Dictionary<string, FileFacade>>();
38 + var fileFacadesByDiskId = new Dictionary<int, Dictionary<string, IFileFacade>>();
39
40 // Index patch file facades by diskId+fileId.
41 foreach (var facade in this.FileFacades)
42 {
43 if (!fileFacadesByDiskId.TryGetValue(facade.DiskId, out var mediaFacades))
44 {
45 - mediaFacades = new Dictionary<string, FileFacade>();
45 + mediaFacades = new Dictionary<string, IFileFacade>();
46 fileFacadesByDiskId.Add(facade.DiskId, mediaFacades);
47 }
48
@@ -97,7 +97,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
97 // Index patch files by diskId+fileId
98 if (!fileFacadesByDiskId.TryGetValue(mainFileRow.DiskId, out var mediaFacades))
99 {
100 - mediaFacades = new Dictionary<string, FileFacade>();
100 + mediaFacades = new Dictionary<string, IFileFacade>();
101 fileFacadesByDiskId.Add(mainFileRow.DiskId, mediaFacades);
102 }
103
src/WixToolset.Core.WindowsInstaller/Data/Xsd/actions.xsd deleted
-73
@@ -1,73 +0,0 @@
1 -<?xml version="1.0" encoding="utf-8"?>
2 -<!-- 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. -->
3 -
4 -
5 -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
6 - targetNamespace="http://wixtoolset.org/schemas/v4/wi/actions"
7 - xmlns="http://wixtoolset.org/schemas/v4/wi/actions">
8 - <xs:annotation>
9 - <xs:documentation>
10 - Schema for describing standard actions in the Windows Installer.
11 - </xs:documentation>
12 - </xs:annotation>
13 -
14 - <xs:element name="actions">
15 - <xs:complexType>
16 - <xs:sequence maxOccurs="unbounded">
17 - <xs:element ref="action" />
18 - </xs:sequence>
19 - </xs:complexType>
20 - </xs:element>
21 -
22 - <xs:element name="action">
23 - <xs:complexType>
24 - <xs:attribute name="name" type="xs:string" use="required">
25 - <xs:annotation>
26 - <xs:documentation>Name of action</xs:documentation>
27 - </xs:annotation>
28 - </xs:attribute>
29 - <xs:attribute name="condition" type="xs:string">
30 - <xs:annotation>
31 - <xs:documentation>Default condition for action</xs:documentation>
32 - </xs:annotation>
33 - </xs:attribute>
34 - <xs:attribute name="sequence" type="xs:integer" use="required">
35 - <xs:annotation>
36 - <xs:documentation>Sequence of action</xs:documentation>
37 - </xs:annotation>
38 - </xs:attribute>
39 - <xs:attribute name="AdminExecuteSequence" type="ActionsYesNoType">
40 - <xs:annotation>
41 - <xs:documentation>Specifies if action is allowed in AdminExecuteSequence</xs:documentation>
42 - </xs:annotation>
43 - </xs:attribute>
44 - <xs:attribute name="AdminUISequence" type="ActionsYesNoType">
45 - <xs:annotation>
46 - <xs:documentation>Specifies if action is allowed in AdminUISequence</xs:documentation>
47 - </xs:annotation>
48 - </xs:attribute>
49 - <xs:attribute name="AdvtExecuteSequence" type="ActionsYesNoType">
50 - <xs:annotation>
51 - <xs:documentation>Specifies if action is allowed in AdvtExecuteSequence</xs:documentation>
52 - </xs:annotation>
53 - </xs:attribute>
54 - <xs:attribute name="InstallExecuteSequence" type="ActionsYesNoType">
55 - <xs:annotation>
56 - <xs:documentation>Specifies if action is allowed in InstallExecuteSequence</xs:documentation>
57 - </xs:annotation>
58 - </xs:attribute>
59 - <xs:attribute name="InstallUISequence" type="ActionsYesNoType">
60 - <xs:annotation>
61 - <xs:documentation>Specifies if action is allowed in InstallUISequence</xs:documentation>
62 - </xs:annotation>
63 - </xs:attribute>
64 - </xs:complexType>
65 - </xs:element>
66 -
67 - <xs:simpleType name="ActionsYesNoType">
68 - <xs:restriction base="xs:NMTOKEN">
69 - <xs:enumeration value="no" />
70 - <xs:enumeration value="yes" />
71 - </xs:restriction>
72 - </xs:simpleType>
73 -</xs:schema>
src/WixToolset.Core.WindowsInstaller/Data/Xsd/tables.xsd deleted
-248
@@ -1,248 +0,0 @@
1 -<?xml version="1.0" encoding="utf-8"?>
2 -<!-- 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. -->
3 -
4 -
5 -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
6 - targetNamespace="http://wixtoolset.org/schemas/v4/wi/tables"
7 - xmlns="http://wixtoolset.org/schemas/v4/wi/tables">
8 - <xs:annotation>
9 - <xs:documentation>
10 - Schema for describing table definitions in Windows Installer.
11 - </xs:documentation>
12 - </xs:annotation>
13 -
14 - <xs:element name="tableDefinitions">
15 - <xs:complexType>
16 - <xs:sequence maxOccurs="unbounded">
17 - <xs:element ref="tableDefinition" />
18 - </xs:sequence>
19 - </xs:complexType>
20 - </xs:element>
21 -
22 - <xs:element name="tableDefinition">
23 - <xs:complexType>
24 - <xs:sequence maxOccurs="unbounded">
25 - <xs:element ref="columnDefinition" />
26 - </xs:sequence>
27 - <xs:attribute name="createSymbols" type="TablesYesNoType">
28 - <xs:annotation>
29 - <xs:documentation>Boolean whether rows in this table create symbols</xs:documentation>
30 - </xs:annotation>
31 - </xs:attribute>
32 - <xs:attribute name="name" type="NameType" use="required">
33 - <xs:annotation>
34 - <xs:documentation>Name of table in Windows Installer database</xs:documentation>
35 - </xs:annotation>
36 - </xs:attribute>
37 - <xs:attribute name="unreal" type="TablesYesNoType">
38 - <xs:annotation>
39 - <xs:documentation>Specifies if table is virtual or not</xs:documentation>
40 - </xs:annotation>
41 - </xs:attribute>
42 - <xs:attribute name="bootstrapperApplicationData" type="TablesYesNoType">
43 - <xs:annotation>
44 - <xs:documentation>Specifies if the table is a part of the Bootstrapper Application Data manifest</xs:documentation>
45 - </xs:annotation>
46 - </xs:attribute>
47 - </xs:complexType>
48 - </xs:element>
49 -
50 - <xs:element name="columnDefinition">
51 - <xs:complexType>
52 - <xs:attribute name="name" type="NameType" use="required">
53 - <xs:annotation>
54 - <xs:documentation>Name of column in Windows Installer table</xs:documentation>
55 - </xs:annotation>
56 - </xs:attribute>
57 -
58 - <xs:attribute name="added" type="TablesYesNoType">
59 - <xs:annotation>
60 - <xs:documentation>Whether this column was added by a transform.</xs:documentation>
61 - </xs:annotation>
62 - </xs:attribute>
63 -
64 - <xs:attribute name="type" type="ColumnDefinitionType" use="required">
65 - <xs:annotation>
66 - <xs:documentation>Type of column in Windows Installer table</xs:documentation>
67 - </xs:annotation>
68 - </xs:attribute>
69 -
70 - <xs:attribute name="length" use="required">
71 - <xs:annotation>
72 - <xs:documentation>Type of column in Windows Installer table</xs:documentation>
73 - </xs:annotation>
74 - <xs:simpleType>
75 - <xs:restriction base="xs:integer">
76 - <xs:minInclusive value="0" />
77 - <xs:maxInclusive value="255" />
78 - </xs:restriction>
79 - </xs:simpleType>
80 - </xs:attribute>
81 -
82 - <xs:attribute name="primaryKey" type="TablesYesNoType">
83 - <xs:annotation>
84 - <xs:documentation>Boolean whether column is primary key of Windows Installer table</xs:documentation>
85 - </xs:annotation>
86 - </xs:attribute>
87 -
88 - <xs:attribute name="nullable" type="TablesYesNoType">
89 - <xs:annotation>
90 - <xs:documentation>Boolean whether column is nullable in Windows Installer table</xs:documentation>
91 - </xs:annotation>
92 - </xs:attribute>
93 -
94 - <xs:attribute name="unreal" type="TablesYesNoType">
95 - <xs:annotation>
96 - <xs:documentation>Boolean whether column is virtual in Windows Installer table</xs:documentation>
97 - </xs:annotation>
98 - </xs:attribute>
99 -
100 - <xs:attribute name="modularize" type="TablesModularizeType">
101 - <xs:annotation>
102 - <xs:documentation>Enumeration specifying how column should have the ModuleId appended</xs:documentation>
103 - </xs:annotation>
104 - </xs:attribute>
105 -
106 - <xs:attribute name="localizable" type="TablesYesNoType">
107 - <xs:annotation>
108 - <xs:documentation>Set to "yes" in order to allow substitution for localized variables.</xs:documentation>
109 - </xs:annotation>
110 - </xs:attribute>
111 -
112 - <xs:attribute name="minValue" type="xs:long">
113 - <xs:annotation>
114 - <xs:documentation>Minimum value for column in Windows Installer table</xs:documentation>
115 - </xs:annotation>
116 - </xs:attribute>
117 -
118 - <xs:attribute name="maxValue" type="xs:long">
119 - <xs:annotation>
120 - <xs:documentation>Maximum value for column in Windows Installer table</xs:documentation>
121 - </xs:annotation>
122 - </xs:attribute>
123 -
124 - <xs:attribute name="keyTable" type="NameType">
125 - <xs:annotation>
126 - <xs:documentation>Foreign key table for column in Windows Installer table</xs:documentation>
127 - </xs:annotation>
128 - </xs:attribute>
129 -
130 - <xs:attribute name="keyColumn">
131 - <xs:annotation>
132 - <xs:documentation>Maximum value for column in Windows Installer table</xs:documentation>
133 - </xs:annotation>
134 - <xs:simpleType>
135 - <xs:restriction base="xs:integer">
136 - <xs:minInclusive value="1" />
137 - <xs:maxInclusive value="32" />
138 - </xs:restriction>
139 - </xs:simpleType>
140 - </xs:attribute>
141 -
142 - <xs:attribute name="category" type="TablesCategoryType">
143 - <xs:annotation>
144 - <xs:documentation>Specific column data types for column</xs:documentation>
145 - </xs:annotation>
146 - </xs:attribute>
147 -
148 - <xs:attribute name="set" type="TablesSetType">
149 - <xs:annotation>
150 - <xs:documentation>List of permissible values for the column</xs:documentation>
151 - </xs:annotation>
152 - </xs:attribute>
153 -
154 - <xs:attribute name="description" type="xs:string">
155 - <xs:annotation>
156 - <xs:documentation>Description of column</xs:documentation>
157 - </xs:annotation>
158 - </xs:attribute>
159 -
160 - <xs:attribute name="escapeIdtCharacters" type="TablesYesNoType">
161 - <xs:annotation>
162 - <xs:documentation>Set to "yes" in order to make the idt exporter escape whitespace characters \r, \n, and \t.</xs:documentation>
163 - </xs:annotation>
164 - </xs:attribute>
165 -
166 - <xs:attribute name="useCData" type="TablesYesNoType">
167 - <xs:annotation>
168 - <xs:documentation>Set to "yes" in order to make the Intermediate and Output objects wrap their data in a CDATA element to preserve whitespace.</xs:documentation>
169 - </xs:annotation>
170 - </xs:attribute>
171 - </xs:complexType>
172 - </xs:element>
173 -
174 - <xs:simpleType name="NameType">
175 - <xs:restriction base="xs:string">
176 - <xs:minLength value="1" />
177 - <xs:maxLength value="64" />
178 - </xs:restriction>
179 - </xs:simpleType>
180 -
181 - <xs:simpleType name="ColumnDefinitionType">
182 - <xs:restriction base="xs:NMTOKEN">
183 - <xs:enumeration value="string" />
184 - <xs:enumeration value="localized" />
185 - <xs:enumeration value="number" />
186 - <xs:enumeration value="object" />
187 - <xs:enumeration value="preserved" />
188 - </xs:restriction>
189 - </xs:simpleType>
190 -
191 - <xs:simpleType name="TablesYesNoType">
192 - <xs:restriction base="xs:NMTOKEN">
193 - <xs:enumeration value="yes" />
194 - <xs:enumeration value="no" />
195 - </xs:restriction>
196 - </xs:simpleType>
197 -
198 - <xs:simpleType name="TablesModularizeType">
199 - <xs:restriction base="xs:NMTOKEN">
200 - <xs:enumeration value="column" />
201 - <xs:enumeration value="companionFile" />
202 - <xs:enumeration value="condition" />
203 - <xs:enumeration value="controlEventArgument" />
204 - <xs:enumeration value="controlText" />
205 - <xs:enumeration value="icon" />
206 - <xs:enumeration value="none" />
207 - <xs:enumeration value="property" />
208 - <xs:enumeration value="semicolonDelimited" />
209 - </xs:restriction>
210 - </xs:simpleType>
211 -
212 - <xs:simpleType name="TablesCategoryType">
213 - <xs:restriction base="xs:NMTOKEN">
214 - <xs:enumeration value="text" />
215 - <xs:enumeration value="upperCase" />
216 - <xs:enumeration value="lowerCase" />
217 - <xs:enumeration value="integer" />
218 - <xs:enumeration value="doubleInteger" />
219 - <xs:enumeration value="timeDate" />
220 - <xs:enumeration value="identifier" />
221 - <xs:enumeration value="property" />
222 - <xs:enumeration value="filename" />
223 - <xs:enumeration value="wildCardFilename" />
224 - <xs:enumeration value="path" />
225 - <xs:enumeration value="paths" />
226 - <xs:enumeration value="anyPath" />
227 - <xs:enumeration value="defaultDir" />
228 - <xs:enumeration value="regPath" />
229 - <xs:enumeration value="formatted" />
230 - <xs:enumeration value="formattedSddl" />
231 - <xs:enumeration value="template" />
232 - <xs:enumeration value="condition" />
233 - <xs:enumeration value="guid" />
234 - <xs:enumeration value="version" />
235 - <xs:enumeration value="language" />
236 - <xs:enumeration value="binary" />
237 - <xs:enumeration value="customSource" />
238 - <xs:enumeration value="cabinet" />
239 - <xs:enumeration value="shortcut" />
240 - </xs:restriction>
241 - </xs:simpleType>
242 -
243 - <xs:simpleType name="TablesSetType">
244 - <xs:restriction base="xs:string">
245 - <xs:pattern value="\w+(;\w+)*" />
246 - </xs:restriction>
247 - </xs:simpleType>
248 -</xs:schema>
src/WixToolset.Core.WindowsInstaller/Decompile/DecompileMsiOrMsmCommand.cs
+6 -3
@@ -1,6 +1,6 @@
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.Unbind
3 +namespace WixToolset.Core.WindowsInstaller.Decompile
4 {
5 using System;
6 using System.Collections.Generic;
@@ -8,6 +8,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
8 using System.IO;
9 using System.Linq;
10 using WixToolset.Core.WindowsInstaller.Msi;
11 + using WixToolset.Core.WindowsInstaller.Unbind;
12 using WixToolset.Data;
13 using WixToolset.Data.WindowsInstaller;
14 using WixToolset.Extensibility;
@@ -43,11 +44,13 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
44 Directory.Delete(this.Context.ExtractFolder, true);
45 }
46
46 - var unbindCommand = new UnbindDatabaseCommand(this.Messaging, database, this.Context.DecompilePath, this.Context.DecompileType, this.Context.ExtractFolder, this.Context.IntermediateFolder, this.Context.IsAdminImage, suppressDemodularization: false, skipSummaryInfo: false);
47 + var backendHelper = this.Context.ServiceProvider.GetService<IBackendHelper>();
48 +
49 + var unbindCommand = new UnbindDatabaseCommand(this.Messaging, backendHelper, database, this.Context.DecompilePath, this.Context.DecompileType, this.Context.ExtractFolder, this.Context.IntermediateFolder, this.Context.IsAdminImage, suppressDemodularization: false, skipSummaryInfo: false);
50 var output = unbindCommand.Execute();
51 var extractedFilePaths = new List<string>(unbindCommand.ExportedFiles);
52
50 - var decompiler = new Decompiler(this.Messaging, this.Extensions, this.Context.BaseSourcePath, this.Context.SuppressCustomTables, this.Context.SuppressDroppingEmptyTables, this.Context.SuppressUI, this.Context.TreatProductAsModule);
53 + var decompiler = new Decompiler(this.Messaging, backendHelper, this.Extensions, this.Context.BaseSourcePath, this.Context.SuppressCustomTables, this.Context.SuppressDroppingEmptyTables, this.Context.SuppressUI, this.Context.TreatProductAsModule);
54 result.Document = decompiler.Decompile(output);
55
56 result.Platform = GetPlatformFromOutput(output);
src/WixToolset.Core.WindowsInstaller/Decompile/Decompiler.cs
+33 -32
@@ -1,6 +1,6 @@
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
3 +namespace WixToolset.Core.WindowsInstaller.Decompile
4 {
5 using System;
6 using System.Collections.Generic;
@@ -10,8 +10,6 @@ namespace WixToolset.Core.WindowsInstaller
10 using System.Text;
11 using System.Text.RegularExpressions;
12 using System.Xml.Linq;
13 - using WixToolset.Core;
14 - using WixToolset.Core.WindowsInstaller.Decompile;
13 using WixToolset.Data;
14 using WixToolset.Data.Symbols;
15 using WixToolset.Data.WindowsInstaller;
@@ -45,9 +43,10 @@ namespace WixToolset.Core.WindowsInstaller
43 /// <summary>
44 /// Creates a new decompiler object with a default set of table definitions.
45 /// </summary>
48 - public Decompiler(IMessaging messaging, IEnumerable<IWindowsInstallerBackendDecompilerExtension> extensions, string baseSourcePath, bool suppressCustomTables, bool suppressDroppingEmptyTables, bool suppressUI, bool treatProductAsModule)
46 + public Decompiler(IMessaging messaging, IBackendHelper backendHelper, IEnumerable<IWindowsInstallerBackendDecompilerExtension> extensions, string baseSourcePath, bool suppressCustomTables, bool suppressDroppingEmptyTables, bool suppressUI, bool treatProductAsModule)
47 {
48 this.Messaging = messaging;
49 + this.BackendHelper = backendHelper;
50 this.Extensions = extensions;
51 this.BaseSourcePath = baseSourcePath ?? "SourceDir";
52 this.SuppressCustomTables = suppressCustomTables;
@@ -63,6 +62,8 @@ namespace WixToolset.Core.WindowsInstaller
62
63 private IMessaging Messaging { get; }
64
65 + private IBackendHelper BackendHelper { get; }
66 +
67 private IEnumerable<IWindowsInstallerBackendDecompilerExtension> Extensions { get; }
68
69 private Dictionary<string, IWindowsInstallerBackendDecompilerExtension> ExtensionsByTableName { get; }
@@ -2196,11 +2197,11 @@ namespace WixToolset.Core.WindowsInstaller
2197 {
2198 foreach (var launchRow in launchConditionTable.Rows)
2199 {
2199 - if (Common.DowngradePreventedCondition == Convert.ToString(launchRow[0]))
2200 + if (WixUpgradeConstants.DowngradePreventedCondition == Convert.ToString(launchRow[0]))
2201 {
2202 downgradeErrorMessage = Convert.ToString(launchRow[1]);
2203 }
2203 - else if (Common.UpgradePreventedCondition == Convert.ToString(launchRow[0]))
2204 + else if (WixUpgradeConstants.UpgradePreventedCondition == Convert.ToString(launchRow[0]))
2205 {
2206 disallowUpgradeErrorMessage = Convert.ToString(launchRow[1]);
2207 }
@@ -2213,7 +2214,7 @@ namespace WixToolset.Core.WindowsInstaller
2214
2215 foreach (UpgradeRow upgradeRow in upgradeTable.Rows)
2216 {
2216 - if (Common.UpgradeDetectedProperty == upgradeRow.ActionProperty)
2217 + if (WixUpgradeConstants.UpgradeDetectedProperty == upgradeRow.ActionProperty)
2218 {
2219 var attr = upgradeRow.Attributes;
2220 var removeFeatures = upgradeRow.Remove;
@@ -2239,7 +2240,7 @@ namespace WixToolset.Core.WindowsInstaller
2240 xMajorUpgrade.SetAttributeValue("RemoveFeatures", removeFeatures);
2241 }
2242 }
2242 - else if (Common.DowngradeDetectedProperty == upgradeRow.ActionProperty)
2243 + else if (WixUpgradeConstants.DowngradeDetectedProperty == upgradeRow.ActionProperty)
2244 {
2245 xMajorUpgrade = xMajorUpgrade ?? new XElement(Names.MajorUpgradeElement);
2246 xMajorUpgrade.SetAttributeValue("DowngradeErrorMessage", downgradeErrorMessage);
@@ -4291,7 +4292,7 @@ namespace WixToolset.Core.WindowsInstaller
4292 var xDirectory = new XElement(Names.DirectoryElement,
4293 new XAttribute("Id", id));
4294
4294 - var names = Common.GetNames(row.FieldAsString(2));
4295 + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(2));
4296
4297 if (String.Equals(id, "TARGETDIR", StringComparison.Ordinal) && !String.Equals(names[0], "SourceDir", StringComparison.Ordinal))
4298 {
@@ -4396,7 +4397,7 @@ namespace WixToolset.Core.WindowsInstaller
4397
4398 if (!row.IsColumnNull(3))
4399 {
4399 - var names = Common.GetNames(row.FieldAsString(3));
4400 + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(3));
4401 if (null != names[0] && null != names[1])
4402 {
4403 xCopyFile.SetAttributeValue("DestinationShortName", names[0]);
@@ -4782,7 +4783,7 @@ namespace WixToolset.Core.WindowsInstaller
4783 WindowsInstallerConstants.MsidbFileAttributesVital != (fileRow.Attributes & WindowsInstallerConstants.MsidbFileAttributesVital) ? new XAttribute("Vital", "no") : null,
4784 null != fileRow.Version && 0 < fileRow.Version.Length && !Char.IsDigit(fileRow.Version[0]) ? new XAttribute("CompanionFile", fileRow.Version) : null);
4785
4785 - var names = Common.GetNames(fileRow.FileName);
4786 + var names = this.BackendHelper.SplitMsiFileName(fileRow.FileName);
4787 if (null != names[0] && null != names[1])
4788 {
4789 xFile.SetAttributeValue("ShortName", names[0]);
@@ -4904,7 +4905,7 @@ namespace WixToolset.Core.WindowsInstaller
4905 new XAttribute("Value", row.FieldAsString(5)),
4906 row.IsColumnNull(2) ? null : new XAttribute("Directory", row.FieldAsString(2)));
4907
4907 - var names = Common.GetNames(row.FieldAsString(1));
4908 + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(1));
4909
4910 if (null != names[0])
4911 {
@@ -4957,7 +4958,7 @@ namespace WixToolset.Core.WindowsInstaller
4958 new XAttribute("Key", row.FieldAsString(3)),
4959 row.IsColumnNull(4) || row.FieldAsInteger(4) == 0 ? null : new XAttribute("Field", row.FieldAsInteger(4)));
4960
4960 - var names = Common.GetNames(row.FieldAsString(1));
4961 + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(1));
4962 if (null != names[0] && null != names[1])
4963 {
4964 xIniFileSearch.SetAttributeValue("ShortName", names[0]);
@@ -5014,7 +5015,7 @@ namespace WixToolset.Core.WindowsInstaller
5015 {
5016 foreach (var row in table.Rows)
5017 {
5017 - if (Common.DowngradePreventedCondition == row.FieldAsString(0) || Common.UpgradePreventedCondition == row.FieldAsString(0))
5018 + if (WixUpgradeConstants.DowngradePreventedCondition == row.FieldAsString(0) || WixUpgradeConstants.UpgradePreventedCondition == row.FieldAsString(0))
5019 {
5020 continue; // MajorUpgrade rows processed in FinalizeUpgradeTable
5021 }
@@ -5101,13 +5102,13 @@ namespace WixToolset.Core.WindowsInstaller
5102 switch (row.FieldAsString(1))
5103 {
5104 case "CreateFolder":
5104 - specialPermissions = Common.FolderPermissions;
5105 + specialPermissions = LockPermissionConstants.FolderPermissions;
5106 break;
5107 case "File":
5107 - specialPermissions = Common.FilePermissions;
5108 + specialPermissions = LockPermissionConstants.FilePermissions;
5109 break;
5110 case "Registry":
5110 - specialPermissions = Common.RegistryPermissions;
5111 + specialPermissions = LockPermissionConstants.RegistryPermissions;
5112 break;
5113 default:
5114 this.Messaging.Write(WarningMessages.IllegalColumnValue(row.SourceLineNumbers, row.Table.Name, row.Fields[1].Column.Name, row[1]));
@@ -5129,13 +5130,13 @@ namespace WixToolset.Core.WindowsInstaller
5130 {
5131 name = "SpecificRightsAll";
5132 }
5132 - else if (28 > i && Common.StandardPermissions.Length > (i - 16))
5133 + else if (28 > i && LockPermissionConstants.StandardPermissions.Length > (i - 16))
5134 {
5134 - name = Common.StandardPermissions[i - 16];
5135 + name = LockPermissionConstants.StandardPermissions[i - 16];
5136 }
5136 - else if (0 <= (i - 28) && Common.GenericPermissions.Length > (i - 28))
5137 + else if (0 <= (i - 28) && LockPermissionConstants.GenericPermissions.Length > (i - 28))
5138 {
5138 - name = Common.GenericPermissions[i - 28];
5139 + name = LockPermissionConstants.GenericPermissions[i - 28];
5140 }
5141
5142 if (null == name)
@@ -5412,7 +5413,7 @@ namespace WixToolset.Core.WindowsInstaller
5413
5414 if (!row.IsColumnNull(3))
5415 {
5415 - var names = Common.GetNames(row.FieldAsString(3));
5416 + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(3));
5417 if (null != names[0] && null != names[1])
5418 {
5419 xCopyFile.SetAttributeValue("DestinationShortName", names[0]);
@@ -5922,17 +5923,17 @@ namespace WixToolset.Core.WindowsInstaller
5923 case "OptimizeCA":
5924 var xOptimizeCustomActions = new XElement(Names.OptimizeCustomActionsElement);
5925 var optimizeCA = Int32.Parse(value, CultureInfo.InvariantCulture);
5925 - if (0 != (Convert.ToInt32(OptimizeCA.SkipAssignment) & optimizeCA))
5926 + if (0 != (Convert.ToInt32(OptimizeCAFlags.SkipAssignment) & optimizeCA))
5927 {
5928 xOptimizeCustomActions.SetAttributeValue("SkipAssignment", "yes");
5929 }
5930
5930 - if (0 != (Convert.ToInt32(OptimizeCA.SkipImmediate) & optimizeCA))
5931 + if (0 != (Convert.ToInt32(OptimizeCAFlags.SkipImmediate) & optimizeCA))
5932 {
5933 xOptimizeCustomActions.SetAttributeValue("SkipImmediate", "yes");
5934 }
5935
5935 - if (0 != (Convert.ToInt32(OptimizeCA.SkipDeferred) & optimizeCA))
5936 + if (0 != (Convert.ToInt32(OptimizeCAFlags.SkipDeferred) & optimizeCA))
5937 {
5938 xOptimizeCustomActions.SetAttributeValue("SkipDeferred", "yes");
5939 }
@@ -6165,7 +6166,7 @@ namespace WixToolset.Core.WindowsInstaller
6166 {
6167 foreach (var propertyId in value.Split(';'))
6168 {
6168 - if (Common.DowngradeDetectedProperty == propertyId || Common.UpgradeDetectedProperty == propertyId)
6169 + if (WixUpgradeConstants.DowngradeDetectedProperty == propertyId || WixUpgradeConstants.UpgradeDetectedProperty == propertyId)
6170 {
6171 continue;
6172 }
@@ -6547,7 +6548,7 @@ namespace WixToolset.Core.WindowsInstaller
6548 var xRemoveFile = new XElement(Names.RemoveFileElement,
6549 new XAttribute("Id", row.FieldAsString(0)));
6550
6550 - var names = Common.GetNames(row.FieldAsString(2));
6551 + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(2));
6552 if (null != names[0] && null != names[1])
6553 {
6554 xRemoveFile.SetAttributeValue("ShortName", names[0]);
@@ -6597,7 +6598,7 @@ namespace WixToolset.Core.WindowsInstaller
6598 new XAttribute("Key", row.FieldAsString(4)),
6599 XAttributeIfNotNull("Value", row, 5));
6600
6600 - var names = Common.GetNames(row.FieldAsString(1));
6601 + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(1));
6602 if (null != names[0] && null != names[1])
6603 {
6604 xIniFile.SetAttributeValue("ShortName", names[0]);
@@ -6941,7 +6942,7 @@ namespace WixToolset.Core.WindowsInstaller
6942 XAttributeIfNotNull("IconIndex", row, 9),
6943 XAttributeIfNotNull("WorkingDirectory", row, 11));
6944
6944 - var names = Common.GetNames(row.FieldAsString(2));
6945 + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(2));
6946 if (null != names[0] && null != names[1])
6947 {
6948 xShortcut.SetAttributeValue("ShortName", names[0]);
@@ -7016,11 +7017,11 @@ namespace WixToolset.Core.WindowsInstaller
7017 XAttributeIfNotNull("MaxSize", row, 5),
7018 XAttributeIfNotNull("Languages", row, 8));
7019
7019 - var names = Common.GetNames(row.FieldAsString(1));
7020 + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(1));
7021 if (null != names[0])
7022 {
7023 // it is permissable to just have a long name
7023 - if (!Common.IsValidShortFilename(names[0], false) && null == names[1])
7024 + if (!this.BackendHelper.IsValidShortFilename(names[0], false) && null == names[1])
7025 {
7026 fileSearch.SetAttributeValue("Name", names[0]);
7027 }
@@ -7248,7 +7249,7 @@ namespace WixToolset.Core.WindowsInstaller
7249
7250 foreach (UpgradeRow upgradeRow in table.Rows)
7251 {
7251 - if (Common.UpgradeDetectedProperty == upgradeRow.ActionProperty || Common.DowngradeDetectedProperty == upgradeRow.ActionProperty)
7252 + if (WixUpgradeConstants.UpgradeDetectedProperty == upgradeRow.ActionProperty || WixUpgradeConstants.DowngradeDetectedProperty == upgradeRow.ActionProperty)
7253 {
7254 continue; // MajorUpgrade rows processed in FinalizeUpgradeTable
7255 }
src/WixToolset.Core.WindowsInstaller/ExtensibilityServices/WindowsInstallerBackendHelper.cs
+33
@@ -3,9 +3,12 @@
3 namespace WixToolset.Core.WindowsInstaller.ExtensibilityServices
4 {
5 using System;
6 + using System.Collections.Generic;
7 using System.Linq;
8 using WixToolset.Data;
9 + using WixToolset.Data.Symbols;
10 using WixToolset.Data.WindowsInstaller;
11 + using WixToolset.Data.WindowsInstaller.Rows;
12 using WixToolset.Extensibility.Data;
13 using WixToolset.Extensibility.Services;
14
@@ -20,14 +23,44 @@ namespace WixToolset.Core.WindowsInstaller.ExtensibilityServices
23
24 #region IBackendHelper interfaces
25
26 + public IFileFacade CreateFileFacade(FileSymbol file, AssemblySymbol assembly) => this.backendHelper.CreateFileFacade(file, assembly);
27 +
28 + public IFileFacade CreateFileFacade(FileRow fileRow) => this.backendHelper.CreateFileFacade(fileRow);
29 +
30 + public IFileFacade CreateFileFacadeFromMergeModule(FileSymbol fileSymbol) => this.backendHelper.CreateFileFacadeFromMergeModule(fileSymbol);
31 +
32 public IFileTransfer CreateFileTransfer(string source, string destination, bool move, SourceLineNumber sourceLineNumbers = null) => this.backendHelper.CreateFileTransfer(source, destination, move, sourceLineNumbers);
33
34 + public string CreateGuid() => this.backendHelper.CreateGuid();
35 +
36 public string CreateGuid(Guid namespaceGuid, string value) => this.backendHelper.CreateGuid(namespaceGuid, value);
37
38 public IResolvedDirectory CreateResolvedDirectory(string directoryParent, string name) => this.backendHelper.CreateResolvedDirectory(directoryParent, name);
39
40 + public IEnumerable<ITrackedFile> ExtractEmbeddedFiles(IEnumerable<IExpectedExtractFile> embeddedFiles) => this.backendHelper.ExtractEmbeddedFiles(embeddedFiles);
41 +
42 + public string GenerateIdentifier(string prefix, params string[] args) => this.backendHelper.GenerateIdentifier(prefix, args);
43 +
44 public string GetCanonicalRelativePath(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string relativePath) => this.backendHelper.GetCanonicalRelativePath(sourceLineNumbers, elementName, attributeName, relativePath);
45
46 + public int GetValidCodePage(string value, bool allowNoChange, bool onlyAnsi = false, SourceLineNumber sourceLineNumbers = null) => this.backendHelper.GetValidCodePage(value, allowNoChange, onlyAnsi, sourceLineNumbers);
47 +
48 + public string GetMsiFileName(string value, bool source, bool longName) => this.backendHelper.GetMsiFileName(value, source, longName);
49 +
50 + public bool IsValidBinderVariable(string variable) => this.backendHelper.IsValidBinderVariable(variable);
51 +
52 + public bool IsValidFourPartVersion(string version) => this.backendHelper.IsValidFourPartVersion(version);
53 +
54 + public bool IsValidIdentifier(string id) => this.backendHelper.IsValidIdentifier(id);
55 +
56 + public bool IsValidLongFilename(string filename, bool allowWildcards, bool allowRelative) => this.backendHelper.IsValidLongFilename(filename, allowWildcards, allowRelative);
57 +
58 + public bool IsValidShortFilename(string filename, bool allowWildcards) => this.backendHelper.IsValidShortFilename(filename, allowWildcards);
59 +
60 + public void ResolveDelayedFields(IEnumerable<IDelayedField> delayedFields, Dictionary<string, string> variableCache) => this.backendHelper.ResolveDelayedFields(delayedFields, variableCache);
61 +
62 + public string[] SplitMsiFileName(string value) => this.backendHelper.SplitMsiFileName(value);
63 +
64 public ITrackedFile TrackFile(string path, TrackedFileType type, SourceLineNumber sourceLineNumbers = null) => this.backendHelper.TrackFile(path, type, sourceLineNumbers);
65
66 #endregion
src/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs
+4 -1
@@ -21,6 +21,7 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe
21 {
22 this.Context = context;
23 this.Messaging = context.ServiceProvider.GetService<IMessaging>();
24 + this.WindowsInstallerBackendHelper = context.ServiceProvider.GetService<IWindowsInstallerBackendHelper>();
25 this.TableDefinitions = new TableDefinitionCollection(WindowsInstallerTableDefinitions.All);
26 }
27
@@ -28,6 +29,8 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe
29
30 private IMessaging Messaging { get; }
31
32 + private IWindowsInstallerBackendHelper WindowsInstallerBackendHelper { get; }
33 +
34 private TableDefinitionCollection TableDefinitions { get; }
35
36 public bool Execute()
@@ -197,7 +200,7 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe
200 if (!certificates.ContainsKey(cert2.Thumbprint))
201 {
202 // generate a stable identifier
200 - var certificateGeneratedId = Common.GenerateIdentifier("cer", cert2.Thumbprint);
203 + var certificateGeneratedId = this.WindowsInstallerBackendHelper.GenerateIdentifier("cer", cert2.Thumbprint);
204
205 // Add it to our "add to MsiDigitalCertificate" table dictionary
206 var digitalCertificateRow = digitalCertificateTable.CreateRow(null);
src/WixToolset.Core.WindowsInstaller/Melter.cs
+1 -1
@@ -18,7 +18,7 @@ namespace WixToolset
18 /// </summary>
19 public sealed class Melter
20 {
21 -#if TODO
21 +#if TODO_MELT
22 private MelterCore core;
23 private Decompiler decompiler;
24
src/WixToolset.Core.WindowsInstaller/MsiBackend.cs
+1
@@ -3,6 +3,7 @@
3 namespace WixToolset.Core.WindowsInstaller
4 {
5 using WixToolset.Core.WindowsInstaller.Bind;
6 + using WixToolset.Core.WindowsInstaller.Decompile;
7 using WixToolset.Core.WindowsInstaller.Inscribe;
8 using WixToolset.Core.WindowsInstaller.Unbind;
9 using WixToolset.Data;
src/WixToolset.Core.WindowsInstaller/MsmBackend.cs
+1
@@ -3,6 +3,7 @@
3 namespace WixToolset.Core.WindowsInstaller
4 {
5 using WixToolset.Core.WindowsInstaller.Bind;
6 + using WixToolset.Core.WindowsInstaller.Decompile;
7 using WixToolset.Core.WindowsInstaller.Unbind;
8 using WixToolset.Data;
9 using WixToolset.Extensibility;
src/WixToolset.Core.WindowsInstaller/MspBackend.cs
+4 -2
@@ -22,6 +22,8 @@ namespace WixToolset.Core.WindowsInstaller
22 {
23 var messaging = context.ServiceProvider.GetService<IMessaging>();
24
25 + var backendHelper = context.ServiceProvider.GetService<IBackendHelper>();
26 +
27 var extensionManager = context.ServiceProvider.GetService<IExtensionManager>();
28
29 var backendExtensions = extensionManager.GetServices<IWindowsInstallerBackendBinderExtension>();
@@ -34,14 +36,14 @@ namespace WixToolset.Core.WindowsInstaller
36 // Create transforms named in patch transforms.
37 IEnumerable<PatchTransform> patchTransforms;
38 {
37 - var command = new CreatePatchTransformsCommand(messaging, context.IntermediateRepresentation, context.IntermediateFolder);
39 + var command = new CreatePatchTransformsCommand(messaging, backendHelper, context.IntermediateRepresentation, context.IntermediateFolder);
40 patchTransforms = command.Execute();
41 }
42
43 // Enhance the intermediate by attaching the created patch transforms.
44 IEnumerable<SubStorage> subStorages;
45 {
44 - var command = new AttachPatchTransformsCommand(messaging, context.IntermediateRepresentation, patchTransforms);
46 + var command = new AttachPatchTransformsCommand(messaging, backendHelper, context.IntermediateRepresentation, patchTransforms);
47 subStorages = command.Execute();
48 }
49
src/WixToolset.Core.WindowsInstaller/PatchAPI/PatchInterop.cs
+101 -101
@@ -7,7 +7,7 @@ namespace WixToolset.PatchAPI
7 using System.Diagnostics.CodeAnalysis;
8 using System.Globalization;
9 using System.Runtime.InteropServices;
10 - using WixToolset.Core;
10 + using WixToolset.Data.Symbols;
11
12 /// <summary>
13 /// Interop class for the mspatchc.dll.
@@ -25,7 +25,7 @@ namespace WixToolset.PatchAPI
25 static internal UInt32 ParseHexOrDecimal(string source)
26 {
27 string value = source.Trim();
28 - if (String.Equals(value.Substring(0,2), "0x", StringComparison.OrdinalIgnoreCase))
28 + if (String.Equals(value.Substring(0, 2), "0x", StringComparison.OrdinalIgnoreCase))
29 {
30 return UInt32.Parse(value.Substring(2), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture.NumberFormat);
31 }
@@ -63,13 +63,13 @@ namespace WixToolset.PatchAPI
63 string[] basisIgnoreOffsets,
64 string[] basisRetainLengths,
65 string[] basisRetainOffsets,
66 - PatchSymbolFlagsType apiPatchingSymbolFlags,
66 + PatchSymbolFlags apiPatchingSymbolFlags,
67 bool optimizePatchSizeForLargeFiles,
68 out bool retainRangesIgnored
69 )
70 {
71 retainRangesIgnored = false;
72 - if (0 != (apiPatchingSymbolFlags & ~(PatchSymbolFlagsType.PATCH_SYMBOL_NO_IMAGEHLP | PatchSymbolFlagsType.PATCH_SYMBOL_NO_FAILURES | PatchSymbolFlagsType.PATCH_SYMBOL_UNDECORATED_TOO)))
72 + if (0 != (apiPatchingSymbolFlags & ~(PatchSymbolFlags.PatchSymbolNoImagehlp | PatchSymbolFlags.PatchSymbolNoFailures | PatchSymbolFlags.PatchSymbolUndecoratedToo)))
73 {
74 throw new ArgumentOutOfRangeException("apiPatchingSymbolFlags");
75 }
@@ -88,13 +88,13 @@ namespace WixToolset.PatchAPI
88 {
89 return false;
90 }
91 - uint countOldFiles = (uint) basisFiles.Length;
91 + uint countOldFiles = (uint)basisFiles.Length;
92
93 if (null != basisSymbolPaths)
94 {
95 if (0 != basisSymbolPaths.Length)
96 {
97 - if ((uint) basisSymbolPaths.Length != countOldFiles)
97 + if ((uint)basisSymbolPaths.Length != countOldFiles)
98 {
99 throw new ArgumentOutOfRangeException("basisSymbolPaths");
100 }
@@ -106,7 +106,7 @@ namespace WixToolset.PatchAPI
106 {
107 if (0 != basisIgnoreLengths.Length)
108 {
109 - if ((uint) basisIgnoreLengths.Length != countOldFiles)
109 + if ((uint)basisIgnoreLengths.Length != countOldFiles)
110 {
111 throw new ArgumentOutOfRangeException("basisIgnoreLengths");
112 }
@@ -121,7 +121,7 @@ namespace WixToolset.PatchAPI
121 {
122 if (0 != basisIgnoreOffsets.Length)
123 {
124 - if ((uint) basisIgnoreOffsets.Length != countOldFiles)
124 + if ((uint)basisIgnoreOffsets.Length != countOldFiles)
125 {
126 throw new ArgumentOutOfRangeException("basisIgnoreOffsets");
127 }
@@ -136,7 +136,7 @@ namespace WixToolset.PatchAPI
136 {
137 if (0 != basisRetainLengths.Length)
138 {
139 - if ((uint) basisRetainLengths.Length != countOldFiles)
139 + if ((uint)basisRetainLengths.Length != countOldFiles)
140 {
141 throw new ArgumentOutOfRangeException("basisRetainLengths");
142 }
@@ -151,7 +151,7 @@ namespace WixToolset.PatchAPI
151 {
152 if (0 != basisRetainOffsets.Length)
153 {
154 - if ((uint) basisRetainOffsets.Length != countOldFiles)
154 + if ((uint)basisRetainOffsets.Length != countOldFiles)
155 {
156 throw new ArgumentOutOfRangeException("basisRetainOffsets");
157 }
@@ -253,15 +253,15 @@ namespace WixToolset.PatchAPI
253
254 // determine if this is an error or a need to use whole file.
255 int err = Marshal.GetLastWin32Error();
256 - switch(err)
256 + switch (err)
257 {
258 - case unchecked((int) ERROR_PATCH_BIGGER_THAN_COMPRESSED):
259 - break;
258 + case unchecked((int)ERROR_PATCH_BIGGER_THAN_COMPRESSED):
259 + break;
260
261 - // too late to exclude this file -- should have been caught before
262 - case unchecked((int) ERROR_PATCH_SAME_FILE):
263 - default:
264 - throw new System.ComponentModel.Win32Exception(err);
261 + // too late to exclude this file -- should have been caught before
262 + case unchecked((int)ERROR_PATCH_SAME_FILE):
263 + default:
264 + throw new System.ComponentModel.Win32Exception(err);
265 }
266 return false;
267 }
@@ -302,44 +302,44 @@ namespace WixToolset.PatchAPI
302 // The following contants can be combined and used as the OptionFlags
303 // parameter in the patch creation apis.
304
305 - internal const uint PATCH_OPTION_USE_BEST = 0x00000000; // auto choose best (slower)
305 + internal const uint PATCH_OPTION_USE_BEST = 0x00000000; // auto choose best (slower)
306
307 - internal const uint PATCH_OPTION_USE_LZX_BEST = 0x00000003; // auto choose best of LXZ A/B (but not large)
308 - internal const uint PATCH_OPTION_USE_LZX_A = 0x00000001; // normal
309 - internal const uint PATCH_OPTION_USE_LXZ_B = 0x00000002; // better on some x86 binaries
310 - internal const uint PATCH_OPTION_USE_LZX_LARGE = 0x00000004; // better support for large files (requires 5.1 or higher applyer)
307 + internal const uint PATCH_OPTION_USE_LZX_BEST = 0x00000003; // auto choose best of LXZ A/B (but not large)
308 + internal const uint PATCH_OPTION_USE_LZX_A = 0x00000001; // normal
309 + internal const uint PATCH_OPTION_USE_LXZ_B = 0x00000002; // better on some x86 binaries
310 + internal const uint PATCH_OPTION_USE_LZX_LARGE = 0x00000004; // better support for large files (requires 5.1 or higher applyer)
311
312 - internal const uint PATCH_OPTION_NO_BINDFIX = 0x00010000; // PE bound imports
313 - internal const uint PATCH_OPTION_NO_LOCKFIX = 0x00020000; // PE smashed locks
314 - internal const uint PATCH_OPTION_NO_REBASE = 0x00040000; // PE rebased image
312 + internal const uint PATCH_OPTION_NO_BINDFIX = 0x00010000; // PE bound imports
313 + internal const uint PATCH_OPTION_NO_LOCKFIX = 0x00020000; // PE smashed locks
314 + internal const uint PATCH_OPTION_NO_REBASE = 0x00040000; // PE rebased image
315 internal const uint PATCH_OPTION_FAIL_IF_SAME_FILE = 0x00080000; // don't create if same
316 - internal const uint PATCH_OPTION_FAIL_IF_BIGGER = 0x00100000; // fail if patch is larger than simply compressing new file (slower)
317 - internal const uint PATCH_OPTION_NO_CHECKSUM = 0x00200000; // PE checksum zero
318 - internal const uint PATCH_OPTION_NO_RESTIMEFIX = 0x00400000; // PE resource timestamps
319 - internal const uint PATCH_OPTION_NO_TIMESTAMP = 0x00800000; // don't store new file timestamp in patch
320 - internal const uint PATCH_OPTION_SIGNATURE_MD5 = 0x01000000; // use MD5 instead of CRC (reserved for future support)
321 - internal const uint PATCH_OPTION_INTERLEAVE_FILES = 0x40000000; // better support for large files (requires 5.2 or higher applyer)
322 - internal const uint PATCH_OPTION_RESERVED1 = 0x80000000; // (used internally)
316 + internal const uint PATCH_OPTION_FAIL_IF_BIGGER = 0x00100000; // fail if patch is larger than simply compressing new file (slower)
317 + internal const uint PATCH_OPTION_NO_CHECKSUM = 0x00200000; // PE checksum zero
318 + internal const uint PATCH_OPTION_NO_RESTIMEFIX = 0x00400000; // PE resource timestamps
319 + internal const uint PATCH_OPTION_NO_TIMESTAMP = 0x00800000; // don't store new file timestamp in patch
320 + internal const uint PATCH_OPTION_SIGNATURE_MD5 = 0x01000000; // use MD5 instead of CRC (reserved for future support)
321 + internal const uint PATCH_OPTION_INTERLEAVE_FILES = 0x40000000; // better support for large files (requires 5.2 or higher applyer)
322 + internal const uint PATCH_OPTION_RESERVED1 = 0x80000000; // (used internally)
323
324 - internal const uint PATCH_OPTION_VALID_FLAGS = 0xC0FF0007;
324 + internal const uint PATCH_OPTION_VALID_FLAGS = 0xC0FF0007;
325
326 //
327 // The following flags are used with PATCH_OPTION_DATA ExtendedOptionFlags:
328 //
329
330 - internal const uint PATCH_TRANSFORM_PE_RESOURCE_2 = 0x00000100; // better handling of PE resources (requires 5.2 or higher applyer)
331 - internal const uint PATCH_TRANSFORM_PE_IRELOC_2 = 0x00000200; // better handling of PE stripped relocs (requires 5.2 or higher applyer)
330 + internal const uint PATCH_TRANSFORM_PE_RESOURCE_2 = 0x00000100; // better handling of PE resources (requires 5.2 or higher applyer)
331 + internal const uint PATCH_TRANSFORM_PE_IRELOC_2 = 0x00000200; // better handling of PE stripped relocs (requires 5.2 or higher applyer)
332
333 //
334 // In addition to the standard Win32 error codes, the following error codes may
335 // be returned via GetLastError() when one of the patch APIs fails.
336
337 - internal const uint ERROR_PATCH_ENCODE_FAILURE = 0xC00E3101; // create
338 - internal const uint ERROR_PATCH_INVALID_OPTIONS = 0xC00E3102; // create
339 - internal const uint ERROR_PATCH_SAME_FILE = 0xC00E3103; // create
340 - internal const uint ERROR_PATCH_RETAIN_RANGES_DIFFER = 0xC00E3104; // create
337 + internal const uint ERROR_PATCH_ENCODE_FAILURE = 0xC00E3101; // create
338 + internal const uint ERROR_PATCH_INVALID_OPTIONS = 0xC00E3102; // create
339 + internal const uint ERROR_PATCH_SAME_FILE = 0xC00E3103; // create
340 + internal const uint ERROR_PATCH_RETAIN_RANGES_DIFFER = 0xC00E3104; // create
341 internal const uint ERROR_PATCH_BIGGER_THAN_COMPRESSED = 0xC00E3105; // create
342 - internal const uint ERROR_PATCH_IMAGEHLP_FALURE = 0xC00E3106; // create
342 + internal const uint ERROR_PATCH_IMAGEHLP_FALURE = 0xC00E3106; // create
343
344 /// <summary>
345 /// Delegate type that the PatchAPI calls for progress notification.
@@ -441,14 +441,14 @@ namespace WixToolset.PatchAPI
441 [BestFitMapping(false, ThrowOnUnmappableChar = true)]
442 internal class PatchOptionData
443 {
444 - public PatchSymbolFlagsType symbolOptionFlags; // PATCH_SYMBOL_xxx flags
445 - [MarshalAs(UnmanagedType.LPStr)] public string newFileSymbolPath; // always ANSI, never Unicode
446 - [MarshalAs(UnmanagedType.LPStr)] public string[] oldFileSymbolPathArray; // array[ OldFileCount ]
447 - public uint extendedOptionFlags;
444 + public PatchSymbolFlags symbolOptionFlags; // PATCH_SYMBOL_xxx flags
445 + [MarshalAs(UnmanagedType.LPStr)] public string newFileSymbolPath; // always ANSI, never Unicode
446 + [MarshalAs(UnmanagedType.LPStr)] public string[] oldFileSymbolPathArray; // array[ OldFileCount ]
447 + public uint extendedOptionFlags;
448 public PatchSymloadCallback symLoadCallback = null;
449 public IntPtr symLoadContext = IntPtr.Zero;
450 public PatchInterleaveMap[] interleaveMapArray = null; // array[ OldFileCount ] (requires 5.2 or higher applyer)
451 - public uint maxLzxWindowSize = 0; // limit memory requirements (requires 5.2 or higher applyer)
451 + public uint maxLzxWindowSize = 0; // limit memory requirements (requires 5.2 or higher applyer)
452 }
453
454 //
@@ -534,7 +534,7 @@ namespace WixToolset.PatchAPI
534
535 private PatchAPIMarshaler(string cookie)
536 {
537 - this.marshalType = (PatchAPIMarshaler.MarshalType) Enum.Parse(typeof(PatchAPIMarshaler.MarshalType), cookie);
537 + this.marshalType = (PatchAPIMarshaler.MarshalType)Enum.Parse(typeof(PatchAPIMarshaler.MarshalType), cookie);
538 }
539
540 //
@@ -575,12 +575,12 @@ namespace WixToolset.PatchAPI
575
576 switch (this.marshalType)
577 {
578 - case PatchAPIMarshaler.MarshalType.PATCH_OPTION_DATA:
579 - this.CleanUpPOD(pNativeData);
580 - break;
581 - default:
582 - this.CleanUpPOFI_A(pNativeData);
583 - break;
578 + case PatchAPIMarshaler.MarshalType.PATCH_OPTION_DATA:
579 + this.CleanUpPOD(pNativeData);
580 + break;
581 + default:
582 + this.CleanUpPOFI_A(pNativeData);
583 + break;
584 }
585 }
586
@@ -601,14 +601,14 @@ namespace WixToolset.PatchAPI
601 return IntPtr.Zero;
602 }
603
604 - switch(this.marshalType)
604 + switch (this.marshalType)
605 {
606 - case PatchAPIMarshaler.MarshalType.PATCH_OPTION_DATA:
607 - return this.MarshalPOD(ManagedObj as PatchOptionData);
608 - case PatchAPIMarshaler.MarshalType.PATCH_OLD_FILE_INFO_W:
609 - return this.MarshalPOFIW_A(ManagedObj as PatchOldFileInfoW[]);
610 - default:
611 - throw new InvalidOperationException();
606 + case PatchAPIMarshaler.MarshalType.PATCH_OPTION_DATA:
607 + return this.MarshalPOD(ManagedObj as PatchOptionData);
608 + case PatchAPIMarshaler.MarshalType.PATCH_OLD_FILE_INFO_W:
609 + return this.MarshalPOFIW_A(ManagedObj as PatchOldFileInfoW[]);
610 + default:
611 + throw new InvalidOperationException();
612 }
613 }
614
@@ -631,23 +631,23 @@ namespace WixToolset.PatchAPI
631 // Implementation *************************************************
632
633 // PATCH_OPTION_DATA offsets
634 - private static readonly int symbolOptionFlagsOffset = Marshal.SizeOf(typeof(Int32));
635 - private static readonly int newFileSymbolPathOffset = 2*Marshal.SizeOf(typeof(Int32));
636 - private static readonly int oldFileSymbolPathArrayOffset = 2*Marshal.SizeOf(typeof(Int32)) + Marshal.SizeOf(typeof(IntPtr));
637 - private static readonly int extendedOptionFlagsOffset = 2*Marshal.SizeOf(typeof(Int32)) + 2*Marshal.SizeOf(typeof(IntPtr));
638 - private static readonly int symLoadCallbackOffset = 3*Marshal.SizeOf(typeof(Int32)) + 2*Marshal.SizeOf(typeof(IntPtr));
639 - private static readonly int symLoadContextOffset = 3*Marshal.SizeOf(typeof(Int32)) + 3*Marshal.SizeOf(typeof(IntPtr));
640 - private static readonly int interleaveMapArrayOffset = 3*Marshal.SizeOf(typeof(Int32)) + 4*Marshal.SizeOf(typeof(IntPtr));
641 - private static readonly int maxLzxWindowSizeOffset = 3*Marshal.SizeOf(typeof(Int32)) + 5*Marshal.SizeOf(typeof(IntPtr));
642 - private static readonly int patchOptionDataSize = 4*Marshal.SizeOf(typeof(Int32)) + 5*Marshal.SizeOf(typeof(IntPtr));
634 + private static readonly int symbolOptionFlagsOffset = Marshal.SizeOf(typeof(Int32));
635 + private static readonly int newFileSymbolPathOffset = 2 * Marshal.SizeOf(typeof(Int32));
636 + private static readonly int oldFileSymbolPathArrayOffset = 2 * Marshal.SizeOf(typeof(Int32)) + Marshal.SizeOf(typeof(IntPtr));
637 + private static readonly int extendedOptionFlagsOffset = 2 * Marshal.SizeOf(typeof(Int32)) + 2 * Marshal.SizeOf(typeof(IntPtr));
638 + private static readonly int symLoadCallbackOffset = 3 * Marshal.SizeOf(typeof(Int32)) + 2 * Marshal.SizeOf(typeof(IntPtr));
639 + private static readonly int symLoadContextOffset = 3 * Marshal.SizeOf(typeof(Int32)) + 3 * Marshal.SizeOf(typeof(IntPtr));
640 + private static readonly int interleaveMapArrayOffset = 3 * Marshal.SizeOf(typeof(Int32)) + 4 * Marshal.SizeOf(typeof(IntPtr));
641 + private static readonly int maxLzxWindowSizeOffset = 3 * Marshal.SizeOf(typeof(Int32)) + 5 * Marshal.SizeOf(typeof(IntPtr));
642 + private static readonly int patchOptionDataSize = 4 * Marshal.SizeOf(typeof(Int32)) + 5 * Marshal.SizeOf(typeof(IntPtr));
643
644 // PATCH_OLD_FILE_INFO offsets
645 - private static readonly int oldFileOffset = Marshal.SizeOf(typeof(Int32));
646 - private static readonly int ignoreRangeCountOffset = Marshal.SizeOf(typeof(Int32)) + Marshal.SizeOf(typeof(IntPtr));
647 - private static readonly int ignoreRangeArrayOffset = 2*Marshal.SizeOf(typeof(Int32)) + Marshal.SizeOf(typeof(IntPtr));
648 - private static readonly int retainRangeCountOffset = 2*Marshal.SizeOf(typeof(Int32)) + 2*Marshal.SizeOf(typeof(IntPtr));
649 - private static readonly int retainRangeArrayOffset = 3*Marshal.SizeOf(typeof(Int32)) + 2*Marshal.SizeOf(typeof(IntPtr));
650 - private static readonly int patchOldFileInfoSize = 3*Marshal.SizeOf(typeof(Int32)) + 3*Marshal.SizeOf(typeof(IntPtr));
645 + private static readonly int oldFileOffset = Marshal.SizeOf(typeof(Int32));
646 + private static readonly int ignoreRangeCountOffset = Marshal.SizeOf(typeof(Int32)) + Marshal.SizeOf(typeof(IntPtr));
647 + private static readonly int ignoreRangeArrayOffset = 2 * Marshal.SizeOf(typeof(Int32)) + Marshal.SizeOf(typeof(IntPtr));
648 + private static readonly int retainRangeCountOffset = 2 * Marshal.SizeOf(typeof(Int32)) + 2 * Marshal.SizeOf(typeof(IntPtr));
649 + private static readonly int retainRangeArrayOffset = 3 * Marshal.SizeOf(typeof(Int32)) + 2 * Marshal.SizeOf(typeof(IntPtr));
650 + private static readonly int patchOldFileInfoSize = 3 * Marshal.SizeOf(typeof(Int32)) + 3 * Marshal.SizeOf(typeof(IntPtr));
651
652 // Methods and data used to preserve data needed for cleanup
653
@@ -658,16 +658,16 @@ namespace WixToolset.PatchAPI
658 private IntPtr CreateMainStruct(int oldFileCount)
659 {
660 int nativeSize;
661 - switch(this.marshalType)
661 + switch (this.marshalType)
662 {
663 - case PatchAPIMarshaler.MarshalType.PATCH_OPTION_DATA:
664 - nativeSize = patchOptionDataSize;
665 - break;
666 - case PatchAPIMarshaler.MarshalType.PATCH_OLD_FILE_INFO_W:
667 - nativeSize = oldFileCount*patchOldFileInfoSize;
668 - break;
669 - default:
670 - throw new InvalidOperationException();
663 + case PatchAPIMarshaler.MarshalType.PATCH_OPTION_DATA:
664 + nativeSize = patchOptionDataSize;
665 + break;
666 + case PatchAPIMarshaler.MarshalType.PATCH_OLD_FILE_INFO_W:
667 + nativeSize = oldFileCount * patchOldFileInfoSize;
668 + break;
669 + default:
670 + throw new InvalidOperationException();
671 }
672
673 IntPtr native = Marshal.AllocCoTaskMem(nativeSize);
@@ -722,7 +722,7 @@ namespace WixToolset.PatchAPI
722
723 for (int i = 0; i < managed.Length; ++i)
724 {
725 - Marshal.WriteIntPtr(native, i*Marshal.SizeOf(typeof(IntPtr)), OptionalAnsiString(managed[i]));
725 + Marshal.WriteIntPtr(native, i * Marshal.SizeOf(typeof(IntPtr)), OptionalAnsiString(managed[i]));
726 }
727
728 return native;
@@ -741,7 +741,7 @@ namespace WixToolset.PatchAPI
741
742 for (int i = 0; i < managed.Length; ++i)
743 {
744 - Marshal.WriteIntPtr(native, i*Marshal.SizeOf(typeof(IntPtr)), OptionalUnicodeString(managed[i]));
744 + Marshal.WriteIntPtr(native, i * Marshal.SizeOf(typeof(IntPtr)), OptionalUnicodeString(managed[i]));
745 }
746
747 return native;
@@ -765,12 +765,12 @@ namespace WixToolset.PatchAPI
765 }
766
767 IntPtr native = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(UInt32))
768 - + managed.ranges.Length*(Marshal.SizeOf(typeof(PatchInterleaveMap))));
769 - WriteUInt32(native, (uint) managed.ranges.Length);
768 + + managed.ranges.Length * (Marshal.SizeOf(typeof(PatchInterleaveMap))));
769 + WriteUInt32(native, (uint)managed.ranges.Length);
770
771 for (int i = 0; i < managed.ranges.Length; ++i)
772 {
773 - Marshal.StructureToPtr(managed.ranges[i], (IntPtr)((Int64)native + i*Marshal.SizeOf(typeof(PatchInterleaveMap))), false);
773 + Marshal.StructureToPtr(managed.ranges[i], (IntPtr)((Int64)native + i * Marshal.SizeOf(typeof(PatchInterleaveMap))), false);
774 }
775 return native;
776 }
@@ -786,7 +786,7 @@ namespace WixToolset.PatchAPI
786
787 for (int i = 0; i < managed.Length; ++i)
788 {
789 - Marshal.WriteIntPtr(native, i*Marshal.SizeOf(typeof(IntPtr)), CreateInterleaveMapRange(managed[i]));
789 + Marshal.WriteIntPtr(native, i * Marshal.SizeOf(typeof(IntPtr)), CreateInterleaveMapRange(managed[i]));
790 }
791
792 return native;
@@ -794,12 +794,12 @@ namespace WixToolset.PatchAPI
794
795 private static void WriteUInt32(IntPtr native, uint data)
796 {
797 - Marshal.WriteInt32(native, unchecked((int) data));
797 + Marshal.WriteInt32(native, unchecked((int)data));
798 }
799
800 private static void WriteUInt32(IntPtr native, int offset, uint data)
801 {
802 - Marshal.WriteInt32(native, offset, unchecked((int) data));
802 + Marshal.WriteInt32(native, offset, unchecked((int)data));
803 }
804
805 // Marshal operations
@@ -813,7 +813,7 @@ namespace WixToolset.PatchAPI
813
814 IntPtr native = this.CreateMainStruct(managed.oldFileSymbolPathArray.Length);
815 Marshal.WriteInt32(native, patchOptionDataSize); // SizeOfThisStruct
816 - WriteUInt32(native, symbolOptionFlagsOffset, (uint) managed.symbolOptionFlags);
816 + WriteUInt32(native, symbolOptionFlagsOffset, (uint)managed.symbolOptionFlags);
817 Marshal.WriteIntPtr(native, newFileSymbolPathOffset, PatchAPIMarshaler.OptionalAnsiString(managed.newFileSymbolPath));
818 Marshal.WriteIntPtr(native, oldFileSymbolPathArrayOffset, PatchAPIMarshaler.CreateArrayOfStringA(managed.oldFileSymbolPathArray));
819 WriteUInt32(native, extendedOptionFlagsOffset, managed.extendedOptionFlags);
@@ -866,10 +866,10 @@ namespace WixToolset.PatchAPI
866 {
867 Marshal.WriteInt32(native, patchOldFileInfoSize); // SizeOfThisStruct
868 WriteUInt32(native, ignoreRangeCountOffset,
869 - (null == managed.ignoreRange) ? 0 : (uint) managed.ignoreRange.Length); // IgnoreRangeCount // maximum 255
869 + (null == managed.ignoreRange) ? 0 : (uint)managed.ignoreRange.Length); // IgnoreRangeCount // maximum 255
870 Marshal.WriteIntPtr(native, ignoreRangeArrayOffset, MarshalPIRArray(managed.ignoreRange)); // IgnoreRangeArray
871 WriteUInt32(native, retainRangeCountOffset,
872 - (null == managed.retainRange) ? 0 : (uint) managed.retainRange.Length); // RetainRangeCount // maximum 255
872 + (null == managed.retainRange) ? 0 : (uint)managed.retainRange.Length); // RetainRangeCount // maximum 255
873 Marshal.WriteIntPtr(native, retainRangeArrayOffset, MarshalPRRArray(managed.retainRange)); // RetainRangeArray
874 }
875
@@ -885,11 +885,11 @@ namespace WixToolset.PatchAPI
885 return IntPtr.Zero;
886 }
887
888 - IntPtr native = Marshal.AllocCoTaskMem(array.Length*Marshal.SizeOf(typeof(PatchIgnoreRange)));
888 + IntPtr native = Marshal.AllocCoTaskMem(array.Length * Marshal.SizeOf(typeof(PatchIgnoreRange)));
889
890 for (int i = 0; i < array.Length; ++i)
891 {
892 - Marshal.StructureToPtr(array[i], (IntPtr)((Int64)native + (i*Marshal.SizeOf(typeof(PatchIgnoreRange)))), false);
892 + Marshal.StructureToPtr(array[i], (IntPtr)((Int64)native + (i * Marshal.SizeOf(typeof(PatchIgnoreRange)))), false);
893 }
894
895 return native;
@@ -907,11 +907,11 @@ namespace WixToolset.PatchAPI
907 return IntPtr.Zero;
908 }
909
910 - IntPtr native = Marshal.AllocCoTaskMem(array.Length*Marshal.SizeOf(typeof(PatchRetainRange)));
910 + IntPtr native = Marshal.AllocCoTaskMem(array.Length * Marshal.SizeOf(typeof(PatchRetainRange)));
911
912 for (int i = 0; i < array.Length; ++i)
913 {
914 - Marshal.StructureToPtr(array[i], (IntPtr)((Int64)native + (i*Marshal.SizeOf(typeof(PatchRetainRange)))), false);
914 + Marshal.StructureToPtr(array[i], (IntPtr)((Int64)native + (i * Marshal.SizeOf(typeof(PatchRetainRange)))), false);
915 }
916
917 return native;
@@ -930,7 +930,7 @@ namespace WixToolset.PatchAPI
930 Marshal.FreeCoTaskMem(
931 Marshal.ReadIntPtr(
932 Marshal.ReadIntPtr(native, oldFileSymbolPathArrayOffset),
933 - i*Marshal.SizeOf(typeof(IntPtr))));
933 + i * Marshal.SizeOf(typeof(IntPtr))));
934 }
935
936 Marshal.FreeCoTaskMem(Marshal.ReadIntPtr(native, oldFileSymbolPathArrayOffset));
@@ -943,7 +943,7 @@ namespace WixToolset.PatchAPI
943 Marshal.FreeCoTaskMem(
944 Marshal.ReadIntPtr(
945 Marshal.ReadIntPtr(native, interleaveMapArrayOffset),
946 - i*Marshal.SizeOf(typeof(IntPtr))));
946 + i * Marshal.SizeOf(typeof(IntPtr))));
947 }
948
949 Marshal.FreeCoTaskMem(Marshal.ReadIntPtr(native, interleaveMapArrayOffset));
@@ -956,7 +956,7 @@ namespace WixToolset.PatchAPI
956 {
957 for (int i = 0; i < GetOldFileCount(native); ++i)
958 {
959 - PatchAPIMarshaler.CleanUpPOFI((IntPtr)((Int64)native + i*patchOldFileInfoSize));
959 + PatchAPIMarshaler.CleanUpPOFI((IntPtr)((Int64)native + i * patchOldFileInfoSize));
960 }
961
962 PatchAPIMarshaler.ReleaseMainStruct(native);
src/WixToolset.Core.WindowsInstaller/RowDictionary.cs
-13
@@ -20,19 +20,6 @@ namespace WixToolset.Core.WindowsInstaller
20 {
21 }
22
23 - /// <summary>
24 - /// Creates and populates a <see cref="RowDictionary{T}"/> with the rows from the given enumerator.
25 - /// </summary>
26 - /// <param name="rows">Rows to add.</param>
27 - public RowDictionary(IEnumerable<T> rows)
28 - : this()
29 - {
30 - foreach (T row in rows)
31 - {
32 - this.Add(row);
33 - }
34 - }
35 -
23 /// <summary>
24 /// Creates and populates a <see cref="RowDictionary{T}"/> with the rows from the given <see cref="Table"/>.
25 /// </summary>
src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs
+6 -4
@@ -11,16 +11,16 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
11 using WixToolset.Core.WindowsInstaller.Msi;
12 using WixToolset.Data;
13 using WixToolset.Data.WindowsInstaller;
14 - using WixToolset.Data.WindowsInstaller.Rows;
14 using WixToolset.Extensibility.Services;
15
16 internal class UnbindDatabaseCommand
17 {
18 private List<string> exportedFiles;
19
21 - public UnbindDatabaseCommand(IMessaging messaging, Database database, string databasePath, OutputType outputType, string exportBasePath, string intermediateFolder, bool isAdminImage, bool suppressDemodularization, bool skipSummaryInfo)
20 + public UnbindDatabaseCommand(IMessaging messaging, IBackendHelper backendHelper, Database database, string databasePath, OutputType outputType, string exportBasePath, string intermediateFolder, bool isAdminImage, bool suppressDemodularization, bool skipSummaryInfo)
21 {
22 this.Messaging = messaging;
23 + this.BackendHelper = backendHelper;
24 this.Database = database;
25 this.DatabasePath = databasePath;
26 this.OutputType = outputType;
@@ -35,6 +35,8 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
35
36 public IMessaging Messaging { get; }
37
38 + public IBackendHelper BackendHelper { get; }
39 +
40 public Database Database { get; }
41
42 public string DatabasePath { get; }
@@ -527,7 +529,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
529 /// </summary>
530 /// <param name="value">The Filename value.</param>
531 /// <returns>The source name of the directory in an admin image.</returns>
530 - private static string GetAdminSourceName(string value)
532 + private string GetAdminSourceName(string value)
533 {
534 string name = null;
535 string[] names;
@@ -535,7 +537,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
537 string shortsourcename = null;
538 string sourcename = null;
539
538 - names = Common.GetNames(value);
540 + names = this.BackendHelper.SplitMsiFileName(value);
541
542 if (null != names[0] && "." != names[0])
543 {
src/WixToolset.Core.WindowsInstaller/Unbind/UnbindTranformCommand.cs
+6 -3
@@ -17,9 +17,10 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
17
18 internal class UnbindTransformCommand
19 {
20 - public UnbindTransformCommand(IMessaging messaging, string transformFile, string exportBasePath, string intermediateFolder)
20 + public UnbindTransformCommand(IMessaging messaging, IBackendHelper backendHelper, string transformFile, string exportBasePath, string intermediateFolder)
21 {
22 this.Messaging = messaging;
23 + this.BackendHelper = backendHelper;
24 this.TransformFile = transformFile;
25 this.ExportBasePath = exportBasePath;
26 this.IntermediateFolder = intermediateFolder;
@@ -29,6 +30,8 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
30
31 private IMessaging Messaging { get; }
32
33 + private IBackendHelper BackendHelper { get; }
34 +
35 private string TransformFile { get; }
36
37 private string ExportBasePath { get; }
@@ -87,7 +90,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
90 msiDatabase.ApplyTransform(this.TransformFile, TransformErrorConditions.All | TransformErrorConditions.ViewTransform);
91
92 // unbind the database
90 - var unbindCommand = new UnbindDatabaseCommand(this.Messaging, msiDatabase, msiDatabaseFile, OutputType.Product, this.ExportBasePath, this.IntermediateFolder, false, false, skipSummaryInfo: true);
93 + var unbindCommand = new UnbindDatabaseCommand(this.Messaging, this.BackendHelper, msiDatabase, msiDatabaseFile, OutputType.Product, this.ExportBasePath, this.IntermediateFolder, false, false, skipSummaryInfo: true);
94 var transformViewOutput = unbindCommand.Execute();
95
96 // index the added and possibly modified rows (added rows may also appears as modified rows)
@@ -157,7 +160,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
160 }
161
162 // unbind the database
160 - var unbindCommand = new UnbindDatabaseCommand(this.Messaging, msiDatabase, msiDatabaseFile, OutputType.Product, this.ExportBasePath, this.IntermediateFolder, false, false, skipSummaryInfo: true);
163 + var unbindCommand = new UnbindDatabaseCommand(this.Messaging, this.BackendHelper, msiDatabase, msiDatabaseFile, OutputType.Product, this.ExportBasePath, this.IntermediateFolder, false, false, skipSummaryInfo: true);
164 var output = unbindCommand.Execute();
165
166 // index all the rows to easily find modified rows
src/WixToolset.Core.WindowsInstaller/UnbindContext.cs
-1
@@ -2,7 +2,6 @@
2
3 namespace WixToolset.Core
4 {
5 - using System;
5 using WixToolset.Extensibility.Data;
6 using WixToolset.Extensibility.Services;
7
src/WixToolset.Core.WindowsInstaller/Unbinder.cs
+2 -2
@@ -21,6 +21,8 @@ namespace WixToolset.Core
21 this.BackendFactories = extensionManager.GetServices<IBackendFactory>();
22 }
23
24 + public IWixToolsetServiceProvider ServiceProvider { get; }
25 +
26 public IEnumerable<IBackendFactory> BackendFactories { get; }
27
28 /// <summary>
@@ -29,8 +31,6 @@ namespace WixToolset.Core
31 /// <value>Set to true if the input msi is part of an admin image.</value>
32 public bool IsAdminImage { get; set; }
33
32 - public IWixToolsetServiceProvider ServiceProvider { get; }
33 -
34 /// <summary>
35 /// Gets or sets the option to suppress demodularizing values.
36 /// </summary>
src/WixToolset.Core.WindowsInstaller/Validator.cs
+3 -10
@@ -25,10 +25,10 @@ namespace WixToolset.Core.WindowsInstaller
25 internal sealed class Validator
26 {
27 private string actionName;
28 - private StringCollection cubeFiles;
28 + private readonly StringCollection cubeFiles;
29 private ValidatorExtension extension;
30 private WindowsInstallerData output;
31 - private InstallUIHandler validationUIHandler;
31 + private readonly InstallUIHandler validationUIHandler;
32 private bool validationSessionComplete;
33 private readonly IMessaging messaging;
34
@@ -57,7 +57,6 @@ namespace WixToolset.Core.WindowsInstaller
57 /// Gets or sets the list of ICEs to run.
58 /// </summary>
59 /// <value>The list of ICEs.</value>
60 - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
60 public ISet<string> ICEs { get; set; }
61
62 /// <summary>
@@ -75,7 +74,6 @@ namespace WixToolset.Core.WindowsInstaller
74 /// Gets or sets the suppressed ICEs.
75 /// </summary>
76 /// <value>The suppressed ICEs.</value>
78 - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
77 public ISet<string> SuppressedICEs { get; set; }
78
79 /// <summary>
@@ -103,13 +101,8 @@ namespace WixToolset.Core.WindowsInstaller
101 IntPtr previousHwnd = IntPtr.Zero;
102 InstallUIHandler previousUIHandler = null;
103
106 - if (null == databaseFile)
107 - {
108 - throw new ArgumentNullException("databaseFile");
109 - }
110 -
104 // initialize the validator extension
112 - this.extension.DatabaseFile = databaseFile;
105 + this.extension.DatabaseFile = databaseFile ?? throw new ArgumentNullException(nameof(databaseFile));
106 this.extension.Output = this.output;
107 this.extension.InitializeValidator();
108
src/WixToolset.Core.WindowsInstaller/ValidatorExtension.cs
+7 -7
@@ -181,7 +181,7 @@ namespace WixToolset.Extensibility
181 throw new ArgumentNullException("message");
182 }
183
184 - string[] messageParts = message.Split('\t');
184 + var messageParts = message.Split('\t');
185 if (3 > messageParts.Length)
186 {
187 if (null == action)
@@ -194,10 +194,10 @@ namespace WixToolset.Extensibility
194 }
195 }
196
197 - SourceLineNumber messageSourceLineNumbers = null;
197 + SourceLineNumber messageSourceLineNumbers;
198 if (6 < messageParts.Length)
199 {
200 - string[] primaryKeys = new string[messageParts.Length - 6];
200 + var primaryKeys = new string[messageParts.Length - 6];
201
202 Array.Copy(messageParts, 6, primaryKeys, 0, primaryKeys.Length);
203
@@ -242,7 +242,7 @@ namespace WixToolset.Extensibility
242 this.indexedSourceLineNumbers = new Hashtable();
243
244 // index each real table
245 - foreach (Table table in this.output.Tables)
245 + foreach (var table in this.output.Tables)
246 {
247 // skip unreal tables
248 if (table.Definition.Unreal)
@@ -251,7 +251,7 @@ namespace WixToolset.Extensibility
251 }
252
253 // index each row
254 - foreach (Row row in table.Rows)
254 + foreach (var row in table.Rows)
255 {
256 // skip rows that don't contain source line information
257 if (null == row.SourceLineNumbers)
@@ -260,10 +260,10 @@ namespace WixToolset.Extensibility
260 }
261
262 // index the row using its table name and primary key
263 - string primaryKey = row.GetPrimaryKey(';');
263 + var primaryKey = row.GetPrimaryKey(';');
264 if (null != primaryKey)
265 {
266 - string key = String.Concat(table.Name, ":", primaryKey);
266 + var key = String.Concat(table.Name, ":", primaryKey);
267
268 if (this.indexedSourceLineNumbers.ContainsKey(key))
269 {
src/WixToolset.Core/AppCommon.cs deleted
-45
@@ -1,45 +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.Reflection;
7 -
8 - /// <summary>
9 - /// Common utilities for Wix applications.
10 - /// </summary>
11 - public static class AppCommon
12 - {
13 - /// <summary>
14 - /// Creates and returns the string for CreatingApplication field (MSI Summary Information Stream).
15 - /// </summary>
16 - /// <remarks>It reads the AssemblyProductAttribute and AssemblyVersionAttribute of executing assembly
17 - /// and builds the CreatingApplication string of the form "[ProductName] ([ProductVersion])".</remarks>
18 - /// <returns>Returns value for PID_APPNAME."</returns>
19 - public static string GetCreatingApplicationString()
20 - {
21 - var assembly = Assembly.GetExecutingAssembly();
22 - return WixDistribution.ReplacePlaceholders("[AssemblyProduct] ([FileVersion])", assembly);
23 - }
24 -
25 - /// <summary>
26 - /// Displays help message header on Console for caller tool.
27 - /// </summary>
28 - public static void DisplayToolHeader()
29 - {
30 - var assembly = Assembly.GetCallingAssembly();
31 - Console.WriteLine(WixDistribution.ReplacePlaceholders("[AssemblyProduct] [AssemblyDescription] version [FileVersion]", assembly));
32 - Console.WriteLine(WixDistribution.ReplacePlaceholders("[AssemblyCopyright]", assembly));
33 - }
34 -
35 - /// <summary>
36 - /// Displays help message header on Console for caller tool.
37 - /// </summary>
38 - public static void DisplayToolFooter()
39 - {
40 - var assembly = Assembly.GetCallingAssembly();
41 - Console.WriteLine();
42 - Console.WriteLine(WixDistribution.ReplacePlaceholders("For more information see: [SupportUrl]", assembly));
43 - }
44 - }
45 -}
src/WixToolset.Core/Bind/ExtractEmbeddedFilesCommand.cs
+1 -2
@@ -9,8 +9,7 @@ namespace WixToolset.Core.Bind
9 using WixToolset.Extensibility.Data;
10 using WixToolset.Extensibility.Services;
11
12 -#pragma warning disable 1591 // TODO: this shouldn't be public, need interface in Extensibility
13 - public class ExtractEmbeddedFilesCommand
12 + internal class ExtractEmbeddedFilesCommand
13 {
14 public ExtractEmbeddedFilesCommand(IBackendHelper backendHelper, IEnumerable<IExpectedExtractFile> embeddedFiles)
15 {
src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs
+8 -9
@@ -10,19 +10,18 @@ namespace WixToolset.Core.Bind
10 using WixToolset.Extensibility.Data;
11 using WixToolset.Extensibility.Services;
12
13 -#pragma warning disable 1591 // TODO: this shouldn't be public, need interface in Extensibility
13 /// <summary>
14 /// Resolves the fields which had variables that needed to be resolved after the file information
15 /// was loaded.
16 /// </summary>
18 - public class ResolveDelayedFieldsCommand
17 + internal class ResolveDelayedFieldsCommand
18 {
19 /// <summary>
20 /// Resolve delayed fields.
21 /// </summary>
22 /// <param name="messaging"></param>
23 /// <param name="delayedFields">The fields which had resolution delayed.</param>
25 - /// <param name="variableCache">The file information to use when resolving variables.</param>
24 + /// <param name="variableCache">The cached variable values used when resolving delayed fields.</param>
25 public ResolveDelayedFieldsCommand(IMessaging messaging, IEnumerable<IDelayedField> delayedFields, Dictionary<string, string> variableCache)
26 {
27 this.Messaging = messaging;
@@ -49,7 +48,7 @@ namespace WixToolset.Core.Bind
48 // process properties first in case they refer to other binder variables
49 if (delayedField.Symbol.Definition.Type == SymbolDefinitionType.Property)
50 {
52 - var value = ResolveDelayedVariables(propertySymbol.SourceLineNumbers, delayedField.Field.AsString(), this.VariableCache);
51 + var value = this.ResolveDelayedVariables(propertySymbol.SourceLineNumbers, delayedField.Field.AsString());
52
53 // update the variable cache with the new value
54 var key = String.Concat("property.", propertySymbol.Id.Id);
@@ -72,7 +71,7 @@ namespace WixToolset.Core.Bind
71
72 // add specialization for ProductVersion fields
73 var keyProductVersion = "property.ProductVersion";
75 - if (this.VariableCache.TryGetValue(keyProductVersion, out var versionValue) && Version.TryParse(versionValue, out Version productVersion))
74 + if (this.VariableCache.TryGetValue(keyProductVersion, out var versionValue) && Version.TryParse(versionValue, out var productVersion))
75 {
76 // Don't add the variable if it already exists (developer defined a property with the same name).
77 var fieldKey = String.Concat(keyProductVersion, ".Major");
@@ -105,7 +104,7 @@ namespace WixToolset.Core.Bind
104 {
105 try
106 {
108 - var value = ResolveDelayedVariables(delayedField.Symbol.SourceLineNumbers, delayedField.Field.AsString(), this.VariableCache);
107 + var value = this.ResolveDelayedVariables(delayedField.Symbol.SourceLineNumbers, delayedField.Field.AsString());
108 delayedField.Field.Set(value);
109 }
110 catch (WixException we)
@@ -115,7 +114,7 @@ namespace WixToolset.Core.Bind
114 }
115 }
116
118 - private static string ResolveDelayedVariables(SourceLineNumber sourceLineNumbers, string value, IDictionary<string, string> resolutionData)
117 + private string ResolveDelayedVariables(SourceLineNumber sourceLineNumbers, string value)
118 {
119 var start = 0;
120
@@ -125,7 +124,7 @@ namespace WixToolset.Core.Bind
124 {
125 var key = String.Concat(parsed.Name, ".", parsed.Scope);
126
128 - if (!resolutionData.TryGetValue(key, out var resolvedValue))
127 + if (!this.VariableCache.TryGetValue(key, out var resolvedValue))
128 {
129 resolvedValue = parsed.DefaultValue;
130 }
@@ -149,7 +148,7 @@ namespace WixToolset.Core.Bind
148 }
149 else
150 {
152 - throw new WixException(ErrorMessages.UnresolvedBindReference(sourceLineNumbers, value));
151 + this.Messaging.Write(ErrorMessages.UnresolvedBindReference(sourceLineNumbers, value));
152 }
153 }
154 else
src/WixToolset.Core/CommandLine/CommandLine.cs
+7 -3
@@ -55,7 +55,9 @@ namespace WixToolset.Core.CommandLine
55
56 if (command.ShowLogo)
57 {
58 - AppCommon.DisplayToolHeader();
58 + var branding = this.ServiceProvider.GetService<IWixBranding>();
59 + Console.WriteLine(branding.ReplacePlaceholders("[AssemblyProduct] [AssemblyDescription] version [FileVersion]"));
60 + Console.WriteLine(branding.ReplacePlaceholders("[AssemblyCopyright]"));
61 }
62
63 return command;
@@ -73,6 +75,7 @@ namespace WixToolset.Core.CommandLine
75
76 private ICommandLineCommand Parse(ICommandLineContext context)
77 {
78 + var branding = context.ServiceProvider.GetService<IWixBranding>();
79 var extensions = context.ExtensionManager.GetServices<IExtensionCommandLine>();
80
81 foreach (var extension in extensions)
@@ -118,7 +121,7 @@ namespace WixToolset.Core.CommandLine
121 extension.PostParse();
122 }
123
121 - return command ?? new HelpCommand(extensions);
124 + return command ?? new HelpCommand(extensions, branding);
125 }
126
127 private bool TryParseCommand(string arg, ICommandLineParser parser, IEnumerable<IExtensionCommandLine> extensions, out ICommandLineCommand command)
@@ -134,7 +137,8 @@ namespace WixToolset.Core.CommandLine
137 case "h":
138 case "help":
139 case "-help":
137 - command = new HelpCommand(extensions);
140 + var branding = this.ServiceProvider.GetService<IWixBranding>();
141 + command = new HelpCommand(extensions, branding);
142 break;
143
144 case "version":
src/WixToolset.Core/CommandLine/HelpCommand.cs
+6 -2
@@ -19,9 +19,10 @@ namespace WixToolset.Core.CommandLine
19 new ExtensionCommandLineSwitch { Switch = "decompile", Description = "Decompile a package or bundle into source code." },
20 };
21
22 - public HelpCommand(IEnumerable<IExtensionCommandLine> extensions)
22 + public HelpCommand(IEnumerable<IExtensionCommandLine> extensions, IWixBranding branding)
23 {
24 this.Extensions = extensions;
25 + this.Branding = branding;
26 }
27
28 public bool ShowLogo => true;
@@ -30,6 +31,8 @@ namespace WixToolset.Core.CommandLine
31
32 private IEnumerable<IExtensionCommandLine> Extensions { get; }
33
34 + private IWixBranding Branding { get; }
35 +
36 public Task<int> ExecuteAsync(CancellationToken _)
37 {
38 var commandLineSwitches = new List<ExtensionCommandLineSwitch>(BuiltInSwitches);
@@ -52,7 +55,8 @@ namespace WixToolset.Core.CommandLine
55
56 Console.WriteLine();
57 Console.WriteLine("Run 'wix [command] --help' for more information on a command.");
55 - AppCommon.DisplayToolFooter();
58 + Console.WriteLine();
59 + Console.WriteLine(this.Branding.ReplacePlaceholders("For more information see: [SupportUrl]"));
60
61 return Task.FromResult(-1);
62 }
src/WixToolset.Core/Common.cs
+129 -195
@@ -18,124 +18,35 @@ namespace WixToolset.Core
18 /// <summary>
19 /// Common Wix utility methods and types.
20 /// </summary>
21 - public static class Common
21 + internal static class Common
22 {
23 - // TODO: Find a place to put all of these so they doesn't have to be public and exposed by WixToolset.Core.dll
24 - /// <summary>
25 - ///
26 - /// </summary>
27 - public const string UpgradeDetectedProperty = "WIX_UPGRADE_DETECTED";
28 - /// <summary>
29 - ///
30 - /// </summary>
31 - public const string UpgradePreventedCondition = "NOT WIX_UPGRADE_DETECTED";
32 - /// <summary>
33 - ///
34 - /// </summary>
35 - public const string DowngradeDetectedProperty = "WIX_DOWNGRADE_DETECTED";
36 - /// <summary>
37 - ///
38 - /// </summary>
39 - public const string DowngradePreventedCondition = "NOT WIX_DOWNGRADE_DETECTED";
40 -
41 - //-------------------------------------------------------------------------------------------------
42 - // Layout of an Access Mask (from http://technet.microsoft.com/en-us/library/cc783530(WS.10).aspx)
43 - //
44 - // -------------------------------------------------------------------------------------------------
45 - // |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
46 - // -------------------------------------------------------------------------------------------------
47 - // |GR|GW|GE|GA| Reserved |AS|StandardAccessRights| Object-Specific Access Rights |
48 - //
49 - // Key
50 - // GR = Generic Read
51 - // GW = Generic Write
52 - // GE = Generic Execute
53 - // GA = Generic All
54 - // AS = Right to access SACL
55 - //
56 - // TODO: what is the expected decompile behavior if a bit is found that is not explicitly enumerated
57 - //
58 - //-------------------------------------------------------------------------------------------------
59 - // Generic Access Rights (per WinNT.h)
60 - // ---------------------
61 - // GENERIC_ALL (0x10000000L)
62 - // GENERIC_EXECUTE (0x20000000L)
63 - // GENERIC_WRITE (0x40000000L)
64 - // GENERIC_READ (0x80000000L)
65 - // TODO: Find a place to put this that it doesn't have to be public and exposed by WixToolset.Core.dll
66 - /// <summary>
67 - ///
68 - /// </summary>
69 - public static readonly string[] GenericPermissions = { "GenericAll", "GenericExecute", "GenericWrite", "GenericRead" };
70 -
71 - // Standard Access Rights (per WinNT.h)
72 - // ----------------------
73 - // DELETE (0x00010000L)
74 - // READ_CONTROL (0x00020000L)
75 - // WRITE_DAC (0x00040000L)
76 - // WRITE_OWNER (0x00080000L)
77 - // SYNCHRONIZE (0x00100000L)
78 - // TODO: Find a place to put this that it doesn't have to be public and exposed by WixToolset.Core.dll
79 - /// <summary>
80 - ///
81 - /// </summary>
82 - public static readonly string[] StandardPermissions = { "Delete", "ReadPermission", "ChangePermission", "TakeOwnership", "Synchronize" };
83 -
84 - // Object-Specific Access Rights
85 - // =============================
86 - // Directory Access Rights (per WinNT.h)
87 - // -----------------------
88 - // FILE_LIST_DIRECTORY ( 0x0001 )
89 - // FILE_ADD_FILE ( 0x0002 )
90 - // FILE_ADD_SUBDIRECTORY ( 0x0004 )
91 - // FILE_READ_EA ( 0x0008 )
92 - // FILE_WRITE_EA ( 0x0010 )
93 - // FILE_TRAVERSE ( 0x0020 )
94 - // FILE_DELETE_CHILD ( 0x0040 )
95 - // FILE_READ_ATTRIBUTES ( 0x0080 )
96 - // FILE_WRITE_ATTRIBUTES ( 0x0100 )
97 - // TODO: Find a place to put this that it doesn't have to be public and exposed by WixToolset.Core.dll
98 - /// <summary>
99 - ///
100 - /// </summary>
101 - public static readonly string[] FolderPermissions = { "Read", "CreateFile", "CreateChild", "ReadExtendedAttributes", "WriteExtendedAttributes", "Traverse", "DeleteChild", "ReadAttributes", "WriteAttributes" };
102 -
103 - // Registry Access Rights (per TODO)
104 - // ----------------------
105 - // TODO: Find a place to put this that it doesn't have to be public and exposed by WixToolset.Core.dll
106 - /// <summary>
107 - ///
108 - /// </summary>
109 - public static readonly string[] RegistryPermissions = { "Read", "Write", "CreateSubkeys", "EnumerateSubkeys", "Notify", "CreateLink" };
110 -
111 - // File Access Rights (per WinNT.h)
112 - // ------------------
113 - // FILE_READ_DATA ( 0x0001 )
114 - // FILE_WRITE_DATA ( 0x0002 )
115 - // FILE_APPEND_DATA ( 0x0004 )
116 - // FILE_READ_EA ( 0x0008 )
117 - // FILE_WRITE_EA ( 0x0010 )
118 - // FILE_EXECUTE ( 0x0020 )
119 - // via mask FILE_ALL_ACCESS ( 0x0040 )
120 - // FILE_READ_ATTRIBUTES ( 0x0080 )
121 - // FILE_WRITE_ATTRIBUTES ( 0x0100 )
122 - //
123 - // STANDARD_RIGHTS_REQUIRED (0x000F0000L)
124 - // FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)
125 - // TODO: Find a place to put this that it doesn't have to be public and exposed by WixToolset.Core.dll
126 - /// <summary>
127 - ///
128 - /// </summary>
129 - public static readonly string[] FilePermissions = { "Read", "Write", "Append", "ReadExtendedAttributes", "WriteExtendedAttributes", "Execute", "FileAllRights", "ReadAttributes", "WriteAttributes" };
23 + private static readonly char[] IllegalShortFilenameCharacters = new[] { '\\', '?', '|', '>', '<', ':', '/', '*', '\"', '+', ',', ';', '=', '[', ']', '.', ' ' };
24 + private static readonly char[] IllegalWildcardShortFilenameCharacters = new[] { '\\', '|', '>', '<', ':', '/', '\"', '+', ',', ';', '=', '[', ']', '.', ' ' };
25
26 internal static readonly char[] IllegalLongFilenameCharacters = new[] { '\\', '/', '?', '*', '|', '>', '<', ':', '\"' }; // illegal: \ / ? | > < : / * "
27 internal static readonly char[] IllegalRelativeLongFilenameCharacters = new[] { '?', '*', '|', '>', '<', ':', '\"' }; // like illegal, but we allow '\' and '/'
28 internal static readonly char[] IllegalWildcardLongFilenameCharacters = new[] { '\\', '/', '|', '>', '<', ':', '\"' }; // like illegal: but we allow '*' and '?'
29
135 - private static readonly char[] IllegalShortFilenameCharacters = new[] { '\\', '?', '|', '>', '<', ':', '/', '*', '\"', '+', ',', ';', '=', '[', ']', '.', ' ' };
136 - private static readonly char[] IllegalWildcardShortFilenameCharacters = new[] { '\\', '|', '>', '<', ':', '/', '\"', '+', ',', ';', '=', '[', ']', '.', ' ' };
137 -
30 + public static string GetCanonicalRelativePath(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string relativePath, IMessaging messageHandler)
31 + {
32 + const string root = @"C:\";
33 + if (!Path.IsPathRooted(relativePath))
34 + {
35 + var normalizedPath = Path.GetFullPath(root + relativePath);
36 + if (normalizedPath.StartsWith(root))
37 + {
38 + var canonicalizedPath = normalizedPath.Substring(root.Length);
39 + if (canonicalizedPath != relativePath)
40 + {
41 + messageHandler.Write(WarningMessages.PathCanonicalized(sourceLineNumbers, elementName, attributeName, relativePath, canonicalizedPath));
42 + }
43 + return canonicalizedPath;
44 + }
45 + }
46
47 + messageHandler.Write(ErrorMessages.PayloadMustBeRelativeToCache(sourceLineNumbers, elementName, attributeName, relativePath));
48 + return relativePath;
49 + }
50
51 /// <summary>
52 /// Gets a valid code page from the given web name or integer value.
@@ -157,8 +68,8 @@ namespace WixToolset.Core
68 {
69 Encoding encoding;
70
160 - // check if a integer as a string was passed
161 - if (Int32.TryParse(value, out int codePage))
71 + // Check if a integer as a string was passed.
72 + if (Int32.TryParse(value, out var codePage))
73 {
74 if (0 == codePage)
75 {
@@ -198,18 +109,91 @@ namespace WixToolset.Core
109 }
110 catch (ArgumentException ex)
111 {
201 - // rethrow as NotSupportedException since either can be thrown
202 - // if the system does not support the specified code page
112 + // Rethrow as NotSupportedException since either can be thrown
113 + // if the system does not support the specified code page.
114 throw new NotSupportedException(ex.Message, ex);
115 }
116 }
117
118 /// <summary>
208 - /// Verifies if a filename is a valid short filename.
119 + /// Verifies if an identifier is a valid binder variable name.
120 + /// </summary>
121 + /// <param name="variable">Binder variable name to verify.</param>
122 + /// <returns>True if the identifier is a valid binder variable name.</returns>
123 + public static bool IsValidBinderVariable(string variable)
124 + {
125 + return TryParseWixVariable(variable, 0, out var parsed) && parsed.Index == 0 && parsed.Length == variable.Length && (parsed.Namespace == "bind" || parsed.Namespace == "wix");
126 + }
127 +
128 + /// <summary>
129 + /// Verifies if a string contains a valid binder variable name.
130 + /// </summary>
131 + /// <param name="verify">String to verify.</param>
132 + /// <returns>True if the string contains a valid binder variable name.</returns>
133 + public static bool ContainsValidBinderVariable(string verify)
134 + {
135 + return TryParseWixVariable(verify, 0, out var parsed) && (parsed.Namespace == "bind" || parsed.Namespace == "wix");
136 + }
137 +
138 + /// <summary>
139 + /// Verifies the given string is a valid 4-part version module or bundle version.
140 /// </summary>
210 - /// <param name="filename">Filename to verify.</param>
211 - /// <param name="allowWildcards">true if wildcards are allowed in the filename.</param>
212 - /// <returns>True if the filename is a valid short filename</returns>
141 + /// <param name="version">The version to verify.</param>
142 + /// <returns>True if version is a valid module or bundle version.</returns>
143 + public static bool IsValidFourPartVersion(string version)
144 + {
145 + if (!Common.IsValidBinderVariable(version))
146 + {
147 + if (!Version.TryParse(version, out var ver) || 65535 < ver.Major || 65535 < ver.Minor || 65535 < ver.Build || 65535 < ver.Revision)
148 + {
149 + return false;
150 + }
151 + }
152 +
153 + return true;
154 + }
155 +
156 + public static bool IsValidLongFilename(string filename, bool allowWildcards, bool allowRelative)
157 + {
158 + if (String.IsNullOrEmpty(filename))
159 + {
160 + return false;
161 + }
162 + else if (filename.Length > 259)
163 + {
164 + return false;
165 + }
166 +
167 + // Check for a non-period character (all periods is not legal)
168 + var allPeriods = true;
169 + foreach (var character in filename)
170 + {
171 + if ('.' != character)
172 + {
173 + allPeriods = false;
174 + break;
175 + }
176 + }
177 +
178 + if (allPeriods)
179 + {
180 + return false;
181 + }
182 +
183 + if (allowWildcards)
184 + {
185 + return filename.IndexOfAny(Common.IllegalWildcardLongFilenameCharacters) == -1;
186 + }
187 + else if (allowRelative)
188 + {
189 + return filename.IndexOfAny(Common.IllegalRelativeLongFilenameCharacters) == -1;
190 + }
191 + else
192 + {
193 + return filename.IndexOfAny(Common.IllegalLongFilenameCharacters) == -1;
194 + }
195 + }
196 +
197 public static bool IsValidShortFilename(string filename, bool allowWildcards)
198 {
199 if (String.IsNullOrEmpty(filename))
@@ -290,55 +274,6 @@ namespace WixToolset.Core
274 }
275 }
276
293 - /// <summary>
294 - /// Verifies if an identifier is a valid binder variable name.
295 - /// </summary>
296 - /// <param name="variable">Binder variable name to verify.</param>
297 - /// <returns>True if the identifier is a valid binder variable name.</returns>
298 - public static bool IsValidBinderVariable(string variable)
299 - {
300 - return TryParseWixVariable(variable, 0, out var parsed) && parsed.Index == 0 && parsed.Length == variable.Length && (parsed.Namespace == "bind" || parsed.Namespace == "wix");
301 - }
302 -
303 - /// <summary>
304 - /// Verifies if a string contains a valid binder variable name.
305 - /// </summary>
306 - /// <param name="verify">String to verify.</param>
307 - /// <returns>True if the string contains a valid binder variable name.</returns>
308 - public static bool ContainsValidBinderVariable(string verify)
309 - {
310 - return TryParseWixVariable(verify, 0, out var parsed) && (parsed.Namespace == "bind" || parsed.Namespace == "wix");
311 - }
312 -
313 - /// <summary>
314 - /// Verifies the given string is a valid module or bundle version.
315 - /// </summary>
316 - /// <param name="version">The version to verify.</param>
317 - /// <returns>True if version is a valid module or bundle version.</returns>
318 - public static bool IsValidModuleOrBundleVersion(string version)
319 - {
320 - if (!Common.IsValidBinderVariable(version))
321 - {
322 - Version ver;
323 -
324 - try
325 - {
326 - ver = new Version(version);
327 - }
328 - catch (ArgumentException)
329 - {
330 - return false;
331 - }
332 -
333 - if (65535 < ver.Major || 65535 < ver.Minor || 65535 < ver.Build || 65535 < ver.Revision)
334 - {
335 - return false;
336 - }
337 - }
338 -
339 - return true;
340 - }
341 -
277 /// <summary>
278 /// Generate a new Windows Installer-friendly guid.
279 /// </summary>
@@ -451,14 +386,14 @@ namespace WixToolset.Core
386 /// <param name="markAttribute">If true, add the attribute to each file. If false, remove it.</param>
387 private static void RecursiveFileAttributes(string path, FileAttributes fileAttribute, bool markAttribute, IMessaging messageHandler)
388 {
454 - foreach (string subDirectory in Directory.GetDirectories(path))
389 + foreach (var subDirectory in Directory.GetDirectories(path))
390 {
391 RecursiveFileAttributes(subDirectory, fileAttribute, markAttribute, messageHandler);
392 }
393
459 - foreach (string filePath in Directory.GetFiles(path))
394 + foreach (var filePath in Directory.GetFiles(path))
395 {
461 - FileAttributes attributes = File.GetAttributes(filePath);
396 + var attributes = File.GetAttributes(filePath);
397 if (markAttribute)
398 {
399 attributes = attributes | fileAttribute; // add to list of attributes
@@ -506,16 +441,15 @@ namespace WixToolset.Core
441 /// <returns>An array of strings of length 4. The contents are: short target, long target, short source, and long source.</returns>
442 /// <remarks>
443 /// If any particular file name part is not parsed, its set to null in the appropriate location of the returned array of strings.
509 - /// However, the returned array will always be of length 4.
444 + /// Thus the returned array will always be of length 4.
445 /// </remarks>
446 public static string[] GetNames(string value)
447 {
513 - string[] names = new string[4];
514 - int targetSeparator = value.IndexOf(':');
448 + var targetSeparator = value.IndexOf(':');
449
450 // split source and target
451 string sourceName = null;
518 - string targetName = value;
452 + var targetName = value;
453 if (0 <= targetSeparator)
454 {
455 sourceName = value.Substring(targetSeparator + 1);
@@ -526,7 +460,7 @@ namespace WixToolset.Core
460 string sourceLongName = null;
461 if (null != sourceName)
462 {
529 - int sourceLongNameSeparator = sourceName.IndexOf('|');
463 + var sourceLongNameSeparator = sourceName.IndexOf('|');
464 if (0 <= sourceLongNameSeparator)
465 {
466 sourceLongName = sourceName.Substring(sourceLongNameSeparator + 1);
@@ -535,7 +469,7 @@ namespace WixToolset.Core
469 }
470
471 // split the target short and long names
538 - int targetLongNameSeparator = targetName.IndexOf('|');
472 + var targetLongNameSeparator = targetName.IndexOf('|');
473 string targetLongName = null;
474 if (0 <= targetLongNameSeparator)
475 {
@@ -543,19 +477,19 @@ namespace WixToolset.Core
477 targetName = targetName.Substring(0, targetLongNameSeparator);
478 }
479
546 - // remove the long source name when its identical to the long source name
480 + // Remove the long source name when its identical to the short source name.
481 if (null != sourceName && sourceName == sourceLongName)
482 {
483 sourceLongName = null;
484 }
485
552 - // remove the long target name when its identical to the long target name
486 + // Remove the long target name when its identical to the long target name.
487 if (null != targetName && targetName == targetLongName)
488 {
489 targetLongName = null;
490 }
491
558 - // remove the source names when they are identical to the target names
492 + // Remove the source names when they are identical to the target names.
493 if (sourceName == targetName && sourceLongName == targetLongName)
494 {
495 sourceName = null;
@@ -563,28 +497,28 @@ namespace WixToolset.Core
497 }
498
499 // target name(s)
566 - if ("." != targetName)
500 + if ("." == targetName)
501 {
568 - names[0] = targetName;
502 + targetName = null;
503 }
504
571 - if (null != targetLongName && "." != targetLongName)
505 + if ("." == targetLongName)
506 {
573 - names[1] = targetLongName;
507 + targetLongName = null;
508 }
509
510 // source name(s)
577 - if (null != sourceName)
511 + if ("." == sourceName)
512 {
579 - names[2] = sourceName;
513 + sourceName = null;
514 }
515
582 - if (null != sourceLongName && "." != sourceLongName)
516 + if ("." == sourceLongName)
517 {
584 - names[3] = sourceLongName;
518 + sourceLongName = null;
519 }
520
587 - return names;
521 + return new[] { targetName, targetLongName, sourceName, sourceLongName };
522 }
523
524 /// <summary>
@@ -596,7 +530,7 @@ namespace WixToolset.Core
530 /// <returns>The name.</returns>
531 public static string GetName(string value, bool source, bool longName)
532 {
599 - string[] names = GetNames(value);
533 + var names = GetNames(value);
534
535 if (source)
536 {
@@ -674,7 +608,7 @@ namespace WixToolset.Core
608 /// <returns>The attribute's identifier value or a special value if an error occurred.</returns>
609 internal static string GetAttributeIdentifierValue(IMessaging messaging, SourceLineNumber sourceLineNumbers, XAttribute attribute)
610 {
677 - string value = Common.GetAttributeValue(messaging, sourceLineNumbers, attribute, EmptyRule.CanBeWhitespaceOnly);
611 + var value = Common.GetAttributeValue(messaging, sourceLineNumbers, attribute, EmptyRule.CanBeWhitespaceOnly);
612
613 if (Common.IsIdentifier(value))
614 {
@@ -713,8 +647,8 @@ namespace WixToolset.Core
647 {
648 Debug.Assert(minimum > CompilerConstants.IntegerNotSet && minimum > CompilerConstants.IllegalInteger, "The legal values for this attribute collide with at least one sentinel used during parsing.");
649
716 - string value = Common.GetAttributeValue(messaging, sourceLineNumbers, attribute, EmptyRule.CanBeWhitespaceOnly);
717 - int integer = CompilerConstants.IllegalInteger;
650 + var value = Common.GetAttributeValue(messaging, sourceLineNumbers, attribute, EmptyRule.CanBeWhitespaceOnly);
651 + var integer = CompilerConstants.IllegalInteger;
652
653 if (0 < value.Length)
654 {
@@ -748,8 +682,8 @@ namespace WixToolset.Core
682 /// <returns>The attribute's YesNoType value.</returns>
683 internal static YesNoType GetAttributeYesNoValue(IMessaging messaging, SourceLineNumber sourceLineNumbers, XAttribute attribute)
684 {
751 - string value = Common.GetAttributeValue(messaging, sourceLineNumbers, attribute, EmptyRule.CanBeWhitespaceOnly);
752 - YesNoType yesNo = YesNoType.IllegalValue;
685 + var value = Common.GetAttributeValue(messaging, sourceLineNumbers, attribute, EmptyRule.CanBeWhitespaceOnly);
686 + var yesNo = YesNoType.IllegalValue;
687
688 if ("yes".Equals(value) || "true".Equals(value))
689 {
src/WixToolset.Core/Compiler.cs
+4 -4
@@ -7073,7 +7073,7 @@ namespace WixToolset.Core
7073 Remove = removeFeatures,
7074 MigrateFeatures = migrateFeatures,
7075 IgnoreRemoveFailures = ignoreRemoveFailure,
7076 - ActionProperty = Common.UpgradeDetectedProperty
7076 + ActionProperty = WixUpgradeConstants.UpgradeDetectedProperty
7077 });
7078
7079 if (allowDowngrades)
@@ -7094,7 +7094,7 @@ namespace WixToolset.Core
7094 {
7095 this.Core.AddSymbol(new LaunchConditionSymbol(sourceLineNumbers)
7096 {
7097 - Condition = Common.UpgradePreventedCondition,
7097 + Condition = WixUpgradeConstants.UpgradePreventedCondition,
7098 Description = downgradeErrorMessage
7099 });
7100 }
@@ -7109,12 +7109,12 @@ namespace WixToolset.Core
7109 Language = productLanguage,
7110 OnlyDetect = true,
7111 IgnoreRemoveFailures = ignoreRemoveFailure,
7112 - ActionProperty = Common.DowngradeDetectedProperty
7112 + ActionProperty = WixUpgradeConstants.DowngradeDetectedProperty
7113 });
7114
7115 this.Core.AddSymbol(new LaunchConditionSymbol(sourceLineNumbers)
7116 {
7117 - Condition = Common.DowngradePreventedCondition,
7117 + Condition = WixUpgradeConstants.DowngradePreventedCondition,
7118 Description = downgradeErrorMessage
7119 });
7120 }
src/WixToolset.Core/CompilerCore.cs
+11 -26
@@ -296,20 +296,6 @@ namespace WixToolset.Core
296 return sb?.ToString() ?? filename;
297 }
298
299 - /// <summary>
300 - /// Creates a short file/directory name using an identifier and long file/directory name as input.
301 - /// </summary>
302 - /// <param name="longName">The long file/directory name.</param>
303 - /// <param name="keepExtension">The option to keep the extension on generated short names.</param>
304 - /// <param name="allowWildcards">true if wildcards are allowed in the filename.</param>
305 - /// <param name="args">Any additional information to include in the hash for the generated short name.</param>
306 - /// <returns>The generated 8.3-compliant short file/directory name.</returns>
307 - [Obsolete]
308 - public string CreateShortName(string longName, bool keepExtension, bool allowWildcards, params string[] args)
309 - {
310 - return this.parseHelper.CreateShortName(longName, keepExtension, allowWildcards, args);
311 - }
312 -
299 /// <summary>
300 /// Verifies the given string is a valid product version.
301 /// </summary>
@@ -337,7 +323,7 @@ namespace WixToolset.Core
323 /// <returns>True if version is a valid module or bundle version.</returns>
324 public static bool IsValidModuleOrBundleVersion(string version)
325 {
340 - return Common.IsValidModuleOrBundleVersion(version);
326 + return Common.IsValidFourPartVersion(version);
327 }
328
329 /// <summary>
@@ -547,15 +533,14 @@ namespace WixToolset.Core
533 {
534 if (null == attribute)
535 {
550 - throw new ArgumentNullException("attribute");
536 + throw new ArgumentNullException(nameof(attribute));
537 }
538
553 - string value = this.GetAttributeValue(sourceLineNumbers, attribute);
539 + var value = this.GetAttributeValue(sourceLineNumbers, attribute);
540
541 try
542 {
557 - int codePage = Common.GetValidCodePage(value);
558 - return codePage;
543 + return Common.GetValidCodePage(value);
544 }
545 catch (NotSupportedException)
546 {
@@ -576,12 +561,12 @@ namespace WixToolset.Core
561 {
562 if (null == attribute)
563 {
579 - throw new ArgumentNullException("attribute");
564 + throw new ArgumentNullException(nameof(attribute));
565 }
566
582 - string value = this.GetAttributeValue(sourceLineNumbers, attribute);
567 + var value = this.GetAttributeValue(sourceLineNumbers, attribute);
568
584 - // allow for localization of code page names and values
569 + // Allow for localization of code page names and values.
570 if (this.IsValidLocIdentifier(value))
571 {
572 return value;
@@ -589,13 +574,13 @@ namespace WixToolset.Core
574
575 try
576 {
592 - int codePage = Common.GetValidCodePage(value, false, onlyAnsi, sourceLineNumbers);
577 + var codePage = Common.GetValidCodePage(value, false, onlyAnsi, sourceLineNumbers);
578 return codePage.ToString(CultureInfo.InvariantCulture);
579 }
580 catch (NotSupportedException)
581 {
597 - // not a valid windows code page
598 - this.Write(ErrorMessages.IllegalCodepageAttribute(sourceLineNumbers, value, attribute.Parent.Name.LocalName, attribute.Name.LocalName));
582 + // Not a valid windows code page.
583 + this.messaging.Write(ErrorMessages.IllegalCodepageAttribute(sourceLineNumbers, value, attribute.Parent.Name.LocalName, attribute.Name.LocalName));
584 }
585 catch (WixException e)
586 {
@@ -805,7 +790,7 @@ namespace WixToolset.Core
790
791 if (0 < value.Length)
792 {
808 - if (!this.IsValidShortFilename(value, allowWildcards) && !Common.ContainsValidBinderVariable(value))
793 + if (!this.parseHelper.IsValidShortFilename(value, allowWildcards) && !Common.ContainsValidBinderVariable(value))
794 {
795 this.Write(ErrorMessages.IllegalShortFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value));
796 }
src/WixToolset.Core/Compiler_Package.cs
+5 -5
@@ -1024,13 +1024,13 @@ namespace WixToolset.Core
1024 switch (tableName)
1025 {
1026 case "CreateFolder":
1027 - specialPermissions = Common.FolderPermissions;
1027 + specialPermissions = LockPermissionConstants.FolderPermissions;
1028 break;
1029 case "File":
1030 - specialPermissions = Common.FilePermissions;
1030 + specialPermissions = LockPermissionConstants.FilePermissions;
1031 break;
1032 case "Registry":
1033 - specialPermissions = Common.RegistryPermissions;
1033 + specialPermissions = LockPermissionConstants.RegistryPermissions;
1034 break;
1035 default:
1036 this.Core.UnexpectedElement(node.Parent, node);
@@ -1059,9 +1059,9 @@ namespace WixToolset.Core
1059 break;
1060 default:
1061 var attribValue = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
1062 - if (!this.Core.TrySetBitFromName(Common.StandardPermissions, attrib.Name.LocalName, attribValue, bits, 16))
1062 + if (!this.Core.TrySetBitFromName(LockPermissionConstants.StandardPermissions, attrib.Name.LocalName, attribValue, bits, 16))
1063 {
1064 - if (!this.Core.TrySetBitFromName(Common.GenericPermissions, attrib.Name.LocalName, attribValue, bits, 28))
1064 + if (!this.Core.TrySetBitFromName(LockPermissionConstants.GenericPermissions, attrib.Name.LocalName, attribValue, bits, 28))
1065 {
1066 if (!this.Core.TrySetBitFromName(specialPermissions, attrib.Name.LocalName, attribValue, bits, 0))
1067 {
src/WixToolset.Core/Compiler_Patch.cs
+7 -7
@@ -95,13 +95,13 @@ namespace WixToolset.Core
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;
98 + apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlags.PatchSymbolNoImagehlp : 0;
99 break;
100 case "ApiPatchingSymbolNoFailuresFlag":
101 - apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_NO_FAILURES : 0;
101 + apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlags.PatchSymbolNoFailures : 0;
102 break;
103 case "ApiPatchingSymbolUndecoratedTooFlag":
104 - apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_UNDECORATED_TOO : 0;
104 + apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlags.PatchSymbolUndecoratedToo : 0;
105 break;
106 case "OptimizePatchSizeForLargeFiles":
107 optimizePatchSizeForLargeFiles = (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib));
@@ -275,7 +275,7 @@ namespace WixToolset.Core
275 private int ParseOptimizeCustomActionsElement(XElement node)
276 {
277 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
278 - var optimizeCA = OptimizeCA.None;
278 + var optimizeCA = OptimizeCAFlags.None;
279
280 foreach (var attrib in node.Attributes())
281 {
@@ -286,19 +286,19 @@ namespace WixToolset.Core
286 case "SkipAssignment":
287 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
288 {
289 - optimizeCA |= OptimizeCA.SkipAssignment;
289 + optimizeCA |= OptimizeCAFlags.SkipAssignment;
290 }
291 break;
292 case "SkipImmediate":
293 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
294 {
295 - optimizeCA |= OptimizeCA.SkipImmediate;
295 + optimizeCA |= OptimizeCAFlags.SkipImmediate;
296 }
297 break;
298 case "SkipDeferred":
299 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
300 {
301 - optimizeCA |= OptimizeCA.SkipDeferred;
301 + optimizeCA |= OptimizeCAFlags.SkipDeferred;
302 }
303 break;
304 default:
src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs
+83 -3
@@ -3,8 +3,12 @@
3 namespace WixToolset.Core.ExtensibilityServices
4 {
5 using System;
6 + using System.Collections.Generic;
7 using System.IO;
8 + using WixToolset.Core.Bind;
9 using WixToolset.Data;
10 + using WixToolset.Data.Symbols;
11 + using WixToolset.Data.WindowsInstaller.Rows;
12 using WixToolset.Extensibility.Data;
13 using WixToolset.Extensibility.Services;
14
@@ -15,12 +19,24 @@ namespace WixToolset.Core.ExtensibilityServices
19 public BackendHelper(IWixToolsetServiceProvider serviceProvider)
20 {
21 this.Messaging = serviceProvider.GetService<IMessaging>();
18 - this.ParseHelper = serviceProvider.GetService<IParseHelper>();
22 }
23
24 private IMessaging Messaging { get; }
25
23 - private IParseHelper ParseHelper { get; }
26 + public IFileFacade CreateFileFacade(FileSymbol file, AssemblySymbol assembly)
27 + {
28 + return new FileFacade(file, assembly);
29 + }
30 +
31 + public IFileFacade CreateFileFacade(FileRow fileRow)
32 + {
33 + return new FileFacade(fileRow);
34 + }
35 +
36 + public IFileFacade CreateFileFacadeFromMergeModule(FileSymbol fileSymbol)
37 + {
38 + return new FileFacade(true, fileSymbol);
39 + }
40
41 public IFileTransfer CreateFileTransfer(string source, string destination, bool move, SourceLineNumber sourceLineNumbers = null)
42 {
@@ -38,6 +54,11 @@ namespace WixToolset.Core.ExtensibilityServices
54 };
55 }
56
57 + public string CreateGuid()
58 + {
59 + return Common.GenerateGuid();
60 + }
61 +
62 public string CreateGuid(Guid namespaceGuid, string value)
63 {
64 return Uuid.NewUuid(namespaceGuid, value).ToString("B").ToUpperInvariant();
@@ -52,9 +73,43 @@ namespace WixToolset.Core.ExtensibilityServices
73 };
74 }
75
76 + public IEnumerable<ITrackedFile> ExtractEmbeddedFiles(IEnumerable<IExpectedExtractFile> embeddedFiles)
77 + {
78 + var command = new ExtractEmbeddedFilesCommand(this, embeddedFiles);
79 + command.Execute();
80 +
81 + return command.TrackedFiles;
82 + }
83 +
84 + public string GenerateIdentifier(string prefix, params string[] args)
85 + {
86 + return Common.GenerateIdentifier(prefix, args);
87 + }
88 +
89 public string GetCanonicalRelativePath(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string relativePath)
90 {
57 - return this.ParseHelper.GetCanonicalRelativePath(sourceLineNumbers, elementName, attributeName, relativePath);
91 + return Common.GetCanonicalRelativePath(sourceLineNumbers, elementName, attributeName, relativePath, this.Messaging);
92 + }
93 +
94 + public int GetValidCodePage(string value, bool allowNoChange = false, bool onlyAnsi = false, SourceLineNumber sourceLineNumbers = null)
95 + {
96 + return Common.GetValidCodePage(value, allowNoChange, onlyAnsi, sourceLineNumbers);
97 + }
98 +
99 + public string GetMsiFileName(string value, bool source, bool longName)
100 + {
101 + return Common.GetName(value, source, longName);
102 + }
103 +
104 + public void ResolveDelayedFields(IEnumerable<IDelayedField> delayedFields, Dictionary<string, string> variableCache)
105 + {
106 + var command = new ResolveDelayedFieldsCommand(this.Messaging, delayedFields, variableCache);
107 + command.Execute();
108 + }
109 +
110 + public string[] SplitMsiFileName(string value)
111 + {
112 + return Common.GetNames(value);
113 }
114
115 public ITrackedFile TrackFile(string path, TrackedFileType type, SourceLineNumber sourceLineNumbers = null)
@@ -62,6 +117,31 @@ namespace WixToolset.Core.ExtensibilityServices
117 return new TrackedFile(path, type, sourceLineNumbers);
118 }
119
120 + public bool IsValidBinderVariable(string variable)
121 + {
122 + return Common.IsValidBinderVariable(variable);
123 + }
124 +
125 + public bool IsValidFourPartVersion(string version)
126 + {
127 + return Common.IsValidFourPartVersion(version);
128 + }
129 +
130 + public bool IsValidIdentifier(string id)
131 + {
132 + return Common.IsIdentifier(id);
133 + }
134 +
135 + public bool IsValidLongFilename(string filename, bool allowWildcards, bool allowRelative)
136 + {
137 + return Common.IsValidLongFilename(filename, allowWildcards, allowRelative);
138 + }
139 +
140 + public bool IsValidShortFilename(string filename, bool allowWildcards)
141 + {
142 + return Common.IsValidShortFilename(filename, allowWildcards);
143 + }
144 +
145 private string GetValidatedFullPath(SourceLineNumber sourceLineNumbers, string path)
146 {
147 try
src/WixToolset.Core/ExtensibilityServices/FileFacade.cs renamed
+3 -3
@@ -1,6 +1,6 @@
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.Bind
3 +namespace WixToolset.Core.ExtensibilityServices
4 {
5 using System;
6 using System.Collections.Generic;
@@ -8,9 +8,9 @@ namespace WixToolset.Core.Bind
8 using WixToolset.Data.Symbols;
9 using WixToolset.Data.WindowsInstaller;
10 using WixToolset.Data.WindowsInstaller.Rows;
11 + using WixToolset.Extensibility.Data;
12
12 -#pragma warning disable 1591 // TODO: this shouldn't be public, need interface in Extensibility
13 - public class FileFacade
13 + internal class FileFacade : IFileFacade
14 {
15 public FileFacade(FileSymbol file, AssemblySymbol assembly)
16 {
src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
+3 -108
@@ -6,9 +6,6 @@ namespace WixToolset.Core.ExtensibilityServices
6 using System.Collections.Generic;
7 using System.Diagnostics;
8 using System.Globalization;
9 - using System.IO;
10 - using System.Security.Cryptography;
11 - using System.Text;
9 using System.Xml.Linq;
10 using WixToolset.Data;
11 using WixToolset.Data.Symbols;
@@ -292,56 +289,6 @@ namespace WixToolset.Core.ExtensibilityServices
289 return section.AddSymbol(symbolDefinition.CreateSymbol(sourceLineNumbers, identifier));
290 }
291
295 - public string CreateShortName(string longName, bool keepExtension, bool allowWildcards, params string[] args)
296 - {
297 - // canonicalize the long name if its not a localization identifier (they are case-sensitive)
298 - if (!this.IsValidLocIdentifier(longName))
299 - {
300 - longName = longName.ToLowerInvariant();
301 - }
302 -
303 - // collect all the data
304 - var strings = new List<string>(1 + args.Length);
305 - strings.Add(longName);
306 - strings.AddRange(args);
307 -
308 - // prepare for hashing
309 - var stringData = String.Join("|", strings);
310 - var data = Encoding.UTF8.GetBytes(stringData);
311 -
312 - // hash the data
313 - byte[] hash;
314 - using (var sha1 = new SHA1CryptoServiceProvider())
315 - {
316 - hash = sha1.ComputeHash(data);
317 - }
318 -
319 - // generate the short file/directory name without an extension
320 - var shortName = new StringBuilder(Convert.ToBase64String(hash));
321 - shortName.Remove(8, shortName.Length - 8).Replace('+', '-').Replace('/', '_');
322 -
323 - if (keepExtension)
324 - {
325 - var extension = Path.GetExtension(longName);
326 -
327 - if (4 < extension.Length)
328 - {
329 - extension = extension.Substring(0, 4);
330 - }
331 -
332 - shortName.Append(extension);
333 -
334 - // check the generated short name to ensure its still legal (the extension may not be legal)
335 - if (!this.IsValidShortFilename(shortName.ToString(), allowWildcards))
336 - {
337 - // remove the extension (by truncating the generated file name back to the generated characters)
338 - shortName.Length -= extension.Length;
339 - }
340 - }
341 -
342 - return shortName.ToString().ToLowerInvariant();
343 - }
344 -
292 public void EnsureTable(IntermediateSection section, SourceLineNumber sourceLineNumbers, TableDefinition tableDefinition)
293 {
294 section.AddSymbol(new WixEnsureTableSymbol(sourceLineNumbers)
@@ -673,23 +620,7 @@ namespace WixToolset.Core.ExtensibilityServices
620
621 public string GetCanonicalRelativePath(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string relativePath)
622 {
676 - const string root = @"C:\";
677 - if (!Path.IsPathRooted(relativePath))
678 - {
679 - var normalizedPath = Path.GetFullPath(root + relativePath);
680 - if (normalizedPath.StartsWith(root))
681 - {
682 - var canonicalizedPath = normalizedPath.Substring(root.Length);
683 - if (canonicalizedPath != relativePath)
684 - {
685 - this.Messaging.Write(WarningMessages.PathCanonicalized(sourceLineNumbers, elementName, attributeName, relativePath, canonicalizedPath));
686 - }
687 - return canonicalizedPath;
688 - }
689 - }
690 -
691 - this.Messaging.Write(ErrorMessages.PayloadMustBeRelativeToCache(sourceLineNumbers, elementName, attributeName, relativePath));
692 - return relativePath;
623 + return Common.GetCanonicalRelativePath(sourceLineNumbers, elementName, attributeName, relativePath, this.Messaging);
624 }
625
626 public SourceLineNumber GetSourceLineNumbers(XElement element)
@@ -723,46 +654,10 @@ namespace WixToolset.Core.ExtensibilityServices
654
655 public bool IsValidLongFilename(string filename, bool allowWildcards, bool allowRelative)
656 {
726 - if (String.IsNullOrEmpty(filename))
727 - {
728 - return false;
729 - }
730 - else if (filename.Length > 259)
731 - {
732 - return false;
733 - }
734 -
735 - // Check for a non-period character (all periods is not legal)
736 - var allPeriods = true;
737 - foreach (var character in filename)
738 - {
739 - if ('.' != character)
740 - {
741 - allPeriods = false;
742 - break;
743 - }
744 - }
745 -
746 - if (allPeriods)
747 - {
748 - return false;
749 - }
750 -
751 - if (allowWildcards)
752 - {
753 - return filename.IndexOfAny(Common.IllegalWildcardLongFilenameCharacters) == -1;
754 - }
755 - else if (allowRelative)
756 - {
757 - return filename.IndexOfAny(Common.IllegalRelativeLongFilenameCharacters) == -1;
758 - }
759 - else
760 - {
761 - return filename.IndexOfAny(Common.IllegalLongFilenameCharacters) == -1;
762 - }
657 + return Common.IsValidLongFilename(filename, allowWildcards, allowRelative);
658 }
659
765 - public bool IsValidShortFilename(string filename, bool allowWildcards = false)
660 + public bool IsValidShortFilename(string filename, bool allowWildcards)
661 {
662 return Common.IsValidShortFilename(filename, allowWildcards);
663 }
src/WixToolset.Core/ExtensibilityServices/WixBranding.cs new
+124
@@ -0,0 +1,124 @@
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 +using System.Resources;
4 +
5 +[assembly: NeutralResourcesLanguage("en-US")]
6 +
7 +namespace WixToolset.Core.ExtensibilityServices
8 +{
9 + using System;
10 + using System.Diagnostics;
11 + using System.IO;
12 + using System.Reflection;
13 + using WixToolset.Extensibility.Services;
14 +
15 + /// <summary>
16 + /// Branding strings.
17 + /// </summary>
18 + internal class WixBranding : IWixBranding
19 + {
20 + /// <summary>
21 + /// News URL for the distribution.
22 + /// </summary>
23 + public static string NewsUrl = "http://wixtoolset.org/news/";
24 +
25 + /// <summary>
26 + /// Short product name for the distribution.
27 + /// </summary>
28 + public static string ShortProduct = "WiX Toolset";
29 +
30 + /// <summary>
31 + /// Support URL for the distribution.
32 + /// </summary>
33 + public static string SupportUrl = "http://wixtoolset.org/";
34 +
35 + /// <summary>
36 + /// Telemetry URL format for the distribution.
37 + /// </summary>
38 + public static string TelemetryUrlFormat = "http://wixtoolset.org/telemetry/v{0}/?r={1}";
39 +
40 + /// <summary>
41 + /// VS Extensions Landing page Url for the distribution.
42 + /// </summary>
43 + public static string VSExtensionsLandingUrl = "http://wixtoolset.org/releases/";
44 +
45 + public string GetCreatingApplication()
46 + {
47 + return this.ReplacePlaceholders("[AssemblyProduct] ([FileVersion])");
48 + }
49 +
50 + public string ReplacePlaceholders(string original, Assembly assembly = null)
51 + {
52 + if (assembly == null)
53 + {
54 + assembly = typeof(WixBranding).Assembly;
55 + }
56 +
57 + var commonVersionPath = Path.Combine(Path.GetDirectoryName(typeof(WixBranding).Assembly.Location), "wixver.dll");
58 + if (File.Exists(commonVersionPath))
59 + {
60 + var commonFileVersion = FileVersionInfo.GetVersionInfo(commonVersionPath);
61 +
62 + original = original.Replace("[FileCopyright]", commonFileVersion.LegalCopyright);
63 + original = original.Replace("[FileVersion]", commonFileVersion.FileVersion);
64 + }
65 +
66 + var fileVersion = FileVersionInfo.GetVersionInfo(assembly.Location);
67 +
68 + original = original.Replace("[FileComments]", fileVersion.Comments);
69 + original = original.Replace("[FileCopyright]", fileVersion.LegalCopyright);
70 + original = original.Replace("[FileProductName]", fileVersion.ProductName);
71 + original = original.Replace("[FileVersion]", fileVersion.FileVersion);
72 +
73 + if (original.Contains("[FileVersionMajorMinor]"))
74 + {
75 + var version = new Version(fileVersion.FileVersion);
76 + original = original.Replace("[FileVersionMajorMinor]", String.Concat(version.Major, ".", version.Minor));
77 + }
78 +
79 + if (TryGetAttribute(assembly, out AssemblyCompanyAttribute company))
80 + {
81 + original = original.Replace("[AssemblyCompany]", company.Company);
82 + }
83 +
84 + if (TryGetAttribute(assembly, out AssemblyCopyrightAttribute copyright))
85 + {
86 + original = original.Replace("[AssemblyCopyright]", copyright.Copyright);
87 + }
88 +
89 + if (TryGetAttribute(assembly, out AssemblyDescriptionAttribute description))
90 + {
91 + original = original.Replace("[AssemblyDescription]", description.Description);
92 + }
93 +
94 + if (TryGetAttribute(assembly, out AssemblyProductAttribute product))
95 + {
96 + original = original.Replace("[AssemblyProduct]", product.Product);
97 + }
98 +
99 + if (TryGetAttribute(assembly, out AssemblyTitleAttribute title))
100 + {
101 + original = original.Replace("[AssemblyTitle]", title.Title);
102 + }
103 +
104 + original = original.Replace("[NewsUrl]", NewsUrl);
105 + original = original.Replace("[ShortProduct]", ShortProduct);
106 + original = original.Replace("[SupportUrl]", SupportUrl);
107 +
108 + return original;
109 + }
110 +
111 + private static bool TryGetAttribute<T>(Assembly assembly, out T attribute) where T : Attribute
112 + {
113 + attribute = null;
114 +
115 + var customAttributes = assembly.GetCustomAttributes(typeof(T), false);
116 + if (null != customAttributes && 0 < customAttributes.Length)
117 + {
118 + attribute = customAttributes[0] as T;
119 + }
120 +
121 + return null != attribute;
122 + }
123 + }
124 +}
src/WixToolset.Core/LocalizationParser.cs
+13 -13
@@ -30,10 +30,10 @@ namespace WixToolset.Core
30
31 public Localization ParseLocalization(XDocument document)
32 {
33 - XElement root = document.Root;
33 + var root = document.Root;
34 Localization localization = null;
35
36 - SourceLineNumber sourceLineNumbers = SourceLineNumber.CreateFromXObject(root);
36 + var sourceLineNumbers = SourceLineNumber.CreateFromXObject(root);
37 if (LocalizationParser.XmlElementName == root.Name.LocalName)
38 {
39 if (LocalizationParser.WxlNamespace == root.Name.Namespace)
@@ -85,11 +85,11 @@ namespace WixToolset.Core
85 /// <param name="node">Element to parse.</param>
86 private static Localization ParseWixLocalizationElement(IMessaging messaging, XElement node)
87 {
88 - int codepage = -1;
88 + var sourceLineNumbers = SourceLineNumber.CreateFromXObject(node);
89 + var codepage = -1;
90 string culture = null;
90 - SourceLineNumber sourceLineNumbers = SourceLineNumber.CreateFromXObject(node);
91
92 - foreach (XAttribute attrib in node.Attributes())
92 + foreach (var attrib in node.Attributes())
93 {
94 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || LocalizationParser.WxlNamespace == attrib.Name.Namespace)
95 {
@@ -115,10 +115,10 @@ namespace WixToolset.Core
115 }
116 }
117
118 - Dictionary<string, BindVariable> variables = new Dictionary<string, BindVariable>();
119 - Dictionary<string, LocalizedControl> localizedControls = new Dictionary<string, LocalizedControl>();
118 + var variables = new Dictionary<string, BindVariable>();
119 + var localizedControls = new Dictionary<string, LocalizedControl>();
120
121 - foreach (XElement child in node.Elements())
121 + foreach (var child in node.Elements())
122 {
123 if (LocalizationParser.WxlNamespace == child.Name.Namespace)
124 {
@@ -155,10 +155,10 @@ namespace WixToolset.Core
155 private static void ParseString(IMessaging messaging, XElement node, IDictionary<string, BindVariable> variables)
156 {
157 string id = null;
158 - bool overridable = false;
159 - SourceLineNumber sourceLineNumbers = SourceLineNumber.CreateFromXObject(node);
158 + var overridable = false;
159 + var sourceLineNumbers = SourceLineNumber.CreateFromXObject(node);
160
161 - foreach (XAttribute attrib in node.Attributes())
161 + foreach (var attrib in node.Attributes())
162 {
163 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || LocalizationParser.WxlNamespace == attrib.Name.Namespace)
164 {
@@ -184,7 +184,7 @@ namespace WixToolset.Core
184 }
185 }
186
187 - string value = Common.GetInnerText(node);
187 + var value = Common.GetInnerText(node);
188
189 if (null == id)
190 {
@@ -228,7 +228,7 @@ namespace WixToolset.Core
228 var rightAligned = false;
229 var leftScroll = false;
230
231 - foreach (XAttribute attrib in node.Attributes())
231 + foreach (var attrib in node.Attributes())
232 {
233 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || LocalizationParser.WxlNamespace == attrib.Name.Namespace)
234 {
src/WixToolset.Core/OptimizeCA.cs deleted
-33
@@ -1,33 +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 -
7 - /// <summary>
8 - /// Values for the OptimizeCA MsiPatchMetdata property, which indicates whether custom actions can be skipped when applying the patch.
9 - /// </summary>
10 - [Flags]
11 - public enum OptimizeCA // TODO: review where to place this data so it can not be exposed by WixToolset.Core
12 - {
13 - /// <summary>
14 - /// No custom actions are skipped.
15 - /// </summary>
16 - None = 0,
17 -
18 - /// <summary>
19 - /// Skip property (type 51) and directory (type 35) assignment custom actions.
20 - /// </summary>
21 - SkipAssignment = 1,
22 -
23 - /// <summary>
24 - /// Skip immediate custom actions that are not property or directory assignment custom actions.
25 - /// </summary>
26 - SkipImmediate = 2,
27 -
28 - /// <summary>
29 - /// Skip custom actions that run within the script.
30 - /// </summary>
31 - SkipDeferred = 4,
32 - }
33 -}
src/WixToolset.Core/PatchSymbolFlagsType.cs deleted
-34
@@ -1,34 +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 -
7 - /// <summary>
8 - /// The following flags are used with PATCH_OPTION_DATA SymbolOptionFlags:
9 - /// </summary>
10 - [Flags]
11 - public enum PatchSymbolFlagsType : uint
12 - {
13 - /// <summary>
14 - /// don't use imagehlp.dll
15 - /// </summary>
16 - PATCH_SYMBOL_NO_IMAGEHLP = 0x00000001,
17 - /// <summary>
18 - /// don't fail patch due to imagehlp failures
19 - /// </summary>
20 - PATCH_SYMBOL_NO_FAILURES = 0x00000002,
21 - /// <summary>
22 - /// after matching decorated symbols, try to match remaining by undecorated names
23 - /// </summary>
24 - PATCH_SYMBOL_UNDECORATED_TOO = 0x00000004,
25 - /// <summary>
26 - /// (used internally)
27 - /// </summary>
28 - PATCH_SYMBOL_RESERVED1 = 0x80000000,
29 - /// <summary>
30 - ///
31 - /// </summary>
32 - MaxValue = PATCH_SYMBOL_NO_IMAGEHLP | PATCH_SYMBOL_NO_FAILURES | PATCH_SYMBOL_UNDECORATED_TOO
33 - }
34 -}
src/WixToolset.Core/ResolvedCabinet.cs
+1 -1
@@ -7,7 +7,7 @@ namespace WixToolset.Core
7 /// <summary>
8 /// Data returned from build file manager ResolveCabinet callback.
9 /// </summary>
10 - public class ResolvedCabinet : IResolvedCabinet
10 + internal class ResolvedCabinet : IResolvedCabinet
11 {
12 /// <summary>
13 /// Gets or sets the build option for the resolved cabinet.
src/WixToolset.Core/WixDistribution.cs deleted
-109
@@ -1,109 +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 -using System;
4 -using System.Diagnostics;
5 -using System.Reflection;
6 -using System.Resources;
7 -
8 -[assembly: NeutralResourcesLanguage("en-US")]
9 -
10 -namespace WixToolset
11 -{
12 - /// <summary>
13 - /// Distribution specific strings.
14 - /// </summary>
15 - internal static class WixDistribution
16 - {
17 - /// <summary>
18 - /// News URL for the distribution.
19 - /// </summary>
20 - public static string NewsUrl = "http://wixtoolset.org/news/";
21 -
22 - /// <summary>
23 - /// Short product name for the distribution.
24 - /// </summary>
25 - public static string ShortProduct = "WiX Toolset";
26 -
27 - /// <summary>
28 - /// Support URL for the distribution.
29 - /// </summary>
30 - public static string SupportUrl = "http://wixtoolset.org/";
31 -
32 - /// <summary>
33 - /// Telemetry URL format for the distribution.
34 - /// </summary>
35 - public static string TelemetryUrlFormat = "http://wixtoolset.org/telemetry/v{0}/?r={1}";
36 -
37 - /// <summary>
38 - /// VS Extensions Landing page Url for the distribution.
39 - /// </summary>
40 - public static string VSExtensionsLandingUrl = "http://wixtoolset.org/releases/";
41 -
42 - public static string ReplacePlaceholders(string original, Assembly assembly)
43 - {
44 - if (null != assembly)
45 - {
46 - FileVersionInfo fileVersion = FileVersionInfo.GetVersionInfo(assembly.Location);
47 -
48 - original = original.Replace("[FileComments]", fileVersion.Comments);
49 - original = original.Replace("[FileCopyright]", fileVersion.LegalCopyright);
50 - original = original.Replace("[FileProductName]", fileVersion.ProductName);
51 - original = original.Replace("[FileVersion]", fileVersion.FileVersion);
52 -
53 - if (original.Contains("[FileVersionMajorMinor]"))
54 - {
55 - Version version = new Version(fileVersion.FileVersion);
56 - original = original.Replace("[FileVersionMajorMinor]", String.Concat(version.Major, ".", version.Minor));
57 - }
58 -
59 - AssemblyCompanyAttribute company;
60 - if (WixDistribution.TryGetAttribute(assembly, out company))
61 - {
62 - original = original.Replace("[AssemblyCompany]", company.Company);
63 - }
64 -
65 - AssemblyCopyrightAttribute copyright;
66 - if (WixDistribution.TryGetAttribute(assembly, out copyright))
67 - {
68 - original = original.Replace("[AssemblyCopyright]", copyright.Copyright);
69 - }
70 -
71 - AssemblyDescriptionAttribute description;
72 - if (WixDistribution.TryGetAttribute(assembly, out description))
73 - {
74 - original = original.Replace("[AssemblyDescription]", description.Description);
75 - }
76 -
77 - AssemblyProductAttribute product;
78 - if (WixDistribution.TryGetAttribute(assembly, out product))
79 - {
80 - original = original.Replace("[AssemblyProduct]", product.Product);
81 - }
82 -
83 - AssemblyTitleAttribute title;
84 - if (WixDistribution.TryGetAttribute(assembly, out title))
85 - {
86 - original = original.Replace("[AssemblyTitle]", title.Title);
87 - }
88 - }
89 -
90 - original = original.Replace("[NewsUrl]", WixDistribution.NewsUrl);
91 - original = original.Replace("[ShortProduct]", WixDistribution.ShortProduct);
92 - original = original.Replace("[SupportUrl]", WixDistribution.SupportUrl);
93 - return original;
94 - }
95 -
96 - private static bool TryGetAttribute<T>(Assembly assembly, out T attribute) where T : Attribute
97 - {
98 - attribute = null;
99 -
100 - object[] customAttributes = assembly.GetCustomAttributes(typeof(T), false);
101 - if (null != customAttributes && 0 < customAttributes.Length)
102 - {
103 - attribute = customAttributes[0] as T;
104 - }
105 -
106 - return null != attribute;
107 - }
108 - }
109 -}
src/WixToolset.Core/WixToolsetServiceProvider.cs
+1
@@ -25,6 +25,7 @@ namespace WixToolset.Core
25 this.AddService((provider, singletons) => AddSingleton<IPreprocessHelper>(singletons, new PreprocessHelper(provider)));
26 this.AddService((provider, singletons) => AddSingleton<IBackendHelper>(singletons, new BackendHelper(provider)));
27 this.AddService((provider, singletons) => AddSingleton<IPathResolver>(singletons, new PathResolver()));
28 + this.AddService((provider, singletons) => AddSingleton<IWixBranding>(singletons, new WixBranding()));
29
30 // Transients.
31 this.AddService<ICommandLineArguments>((provider, singletons) => new CommandLineArguments(provider));