From 3ccd5e439da4296d6f2b66ce47075ab20d039676 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Sun, 14 Mar 2021 07:38:48 -0700 Subject: Minimize public surface area of Core Fixes wixtoolset/issues#6374 --- src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs | 8 +- ...CreateBootstrapperApplicationManifestCommand.cs | 2 +- .../CreateBundleExtensionManifestCommand.cs | 2 +- .../Bundles/ProcessMsiPackageCommand.cs | 12 +- .../ExtensibilityServices/BurnBackendHelper.cs | 34 +- src/WixToolset.Core.Burn/RowIndexedList.cs | 21 +- src/WixToolset.Core.Burn/TableExtensions.cs | 24 - .../Bind/AssignMediaCommand.cs | 36 +- .../Bind/AttachPatchTransformsCommand.cs | 9 +- .../Bind/BindDatabaseCommand.cs | 31 +- .../Bind/BindSummaryInfoCommand.cs | 15 +- .../Bind/BindTransformCommand.cs | 4 +- .../Bind/CabinetResolver.cs | 5 +- .../Bind/CabinetWorkItem.cs | 6 +- .../Bind/CalculateComponentGuids.cs | 4 +- .../Bind/CopyTransformDataCommand.cs | 630 --------------------- .../Bind/CreateCabinetsCommand.cs | 4 +- .../Bind/CreateDeltaPatchesCommand.cs | 7 +- .../Bind/CreateInstanceTransformsCommand.cs | 2 +- .../Bind/CreatePatchTransformsCommand.cs | 9 +- .../CreateWindowsInstallerDataFromIRCommand.cs | 83 +-- .../Bind/ExtractMergeModuleFilesCommand.cs | 19 +- .../Bind/GetFileFacadesCommand.cs | 21 +- .../Bind/GetFileFacadesFromTransforms.cs | 21 +- .../Bind/MergeModulesCommand.cs | 6 +- .../Bind/ModularizeCommand.cs | 12 +- .../Bind/OptimizeFileFacadesOrderCommand.cs | 11 +- .../Bind/ProcessDependencyReferencesCommand.cs | 15 +- .../Bind/ProcessUncompressedFilesCommand.cs | 15 +- .../Bind/UpdateFileFacadesCommand.cs | 12 +- .../Bind/UpdateMediaSequencesCommand.cs | 14 +- .../Bind/UpdateTransformsWithFileFacades.cs | 12 +- .../Data/Xsd/actions.xsd | 73 --- .../Data/Xsd/tables.xsd | 248 -------- .../Decompile/DecompileMsiOrMsmCommand.cs | 9 +- .../Decompile/Decompiler.cs | 65 +-- .../WindowsInstallerBackendHelper.cs | 33 ++ .../Inscribe/InscribeMsiPackageCommand.cs | 5 +- src/WixToolset.Core.WindowsInstaller/Melter.cs | 2 +- src/WixToolset.Core.WindowsInstaller/MsiBackend.cs | 1 + src/WixToolset.Core.WindowsInstaller/MsmBackend.cs | 1 + src/WixToolset.Core.WindowsInstaller/MspBackend.cs | 6 +- .../PatchAPI/PatchInterop.cs | 202 +++---- .../RowDictionary.cs | 13 - .../Unbind/UnbindDatabaseCommand.cs | 10 +- .../Unbind/UnbindTranformCommand.cs | 9 +- .../UnbindContext.cs | 1 - src/WixToolset.Core.WindowsInstaller/Unbinder.cs | 4 +- src/WixToolset.Core.WindowsInstaller/Validator.cs | 13 +- .../ValidatorExtension.cs | 14 +- src/WixToolset.Core/AppCommon.cs | 45 -- .../Bind/ExtractEmbeddedFilesCommand.cs | 3 +- src/WixToolset.Core/Bind/FileFacade.cs | 172 ------ .../Bind/ResolveDelayedFieldsCommand.cs | 17 +- src/WixToolset.Core/CommandLine/CommandLine.cs | 10 +- src/WixToolset.Core/CommandLine/HelpCommand.cs | 8 +- src/WixToolset.Core/Common.cs | 324 +++++------ src/WixToolset.Core/Compiler.cs | 8 +- src/WixToolset.Core/CompilerCore.cs | 37 +- src/WixToolset.Core/Compiler_Package.cs | 10 +- src/WixToolset.Core/Compiler_Patch.cs | 14 +- .../ExtensibilityServices/BackendHelper.cs | 86 ++- .../ExtensibilityServices/FileFacade.cs | 172 ++++++ .../ExtensibilityServices/ParseHelper.cs | 111 +--- .../ExtensibilityServices/WixBranding.cs | 124 ++++ src/WixToolset.Core/LocalizationParser.cs | 26 +- src/WixToolset.Core/OptimizeCA.cs | 33 -- src/WixToolset.Core/PatchSymbolFlagsType.cs | 34 -- src/WixToolset.Core/ResolvedCabinet.cs | 2 +- src/WixToolset.Core/WixDistribution.cs | 109 ---- src/WixToolset.Core/WixToolsetServiceProvider.cs | 1 + 71 files changed, 1040 insertions(+), 2121 deletions(-) delete mode 100644 src/WixToolset.Core.Burn/TableExtensions.cs delete mode 100644 src/WixToolset.Core.WindowsInstaller/Bind/CopyTransformDataCommand.cs delete mode 100644 src/WixToolset.Core.WindowsInstaller/Data/Xsd/actions.xsd delete mode 100644 src/WixToolset.Core.WindowsInstaller/Data/Xsd/tables.xsd delete mode 100644 src/WixToolset.Core/AppCommon.cs delete mode 100644 src/WixToolset.Core/Bind/FileFacade.cs create mode 100644 src/WixToolset.Core/ExtensibilityServices/FileFacade.cs create mode 100644 src/WixToolset.Core/ExtensibilityServices/WixBranding.cs delete mode 100644 src/WixToolset.Core/OptimizeCA.cs delete mode 100644 src/WixToolset.Core/PatchSymbolFlagsType.cs delete mode 100644 src/WixToolset.Core/WixDistribution.cs diff --git a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs index e58e2464..afaf65ee 100644 --- a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs +++ b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs @@ -130,10 +130,9 @@ namespace WixToolset.Core.Burn // Extract files that come from binary .wixlibs and WixExtensions (this does not extract files from merge modules). { - var command = new ExtractEmbeddedFilesCommand(this.BackendHelper, this.ExpectedEmbeddedFiles); - command.Execute(); + var extractedFiles = this.BackendHelper.ExtractEmbeddedFiles(this.ExpectedEmbeddedFiles); - trackedFiles.AddRange(command.TrackedFiles); + trackedFiles.AddRange(extractedFiles); } // Get the explicit payloads. @@ -367,8 +366,7 @@ namespace WixToolset.Core.Burn // Resolve any delayed fields before generating the manifest. if (this.DelayedFields.Any()) { - var resolveDelayedFieldsCommand = new ResolveDelayedFieldsCommand(this.Messaging, this.DelayedFields, variableCache); - resolveDelayedFieldsCommand.Execute(); + this.BackendHelper.ResolveDelayedFields(this.DelayedFields, variableCache); } Dictionary dependencySymbolsByKey; diff --git a/src/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs b/src/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs index a24137f3..63a168a0 100644 --- a/src/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs +++ b/src/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs @@ -244,7 +244,7 @@ namespace WixToolset.Core.Burn.Bundles private WixBundlePayloadSymbol CreateBootstrapperApplicationManifestPayloadRow(string baManifestPath) { - var generatedId = Common.GenerateIdentifier("ux", BurnCommon.BADataFileName); + var generatedId = this.InternalBurnBackendHelper.GenerateIdentifier("ux", BurnCommon.BADataFileName); var symbol = this.Section.AddSymbol(new WixBundlePayloadSymbol(this.BundleSymbol.SourceLineNumbers, new Identifier(AccessModifier.Section, generatedId)) { diff --git a/src/WixToolset.Core.Burn/Bundles/CreateBundleExtensionManifestCommand.cs b/src/WixToolset.Core.Burn/Bundles/CreateBundleExtensionManifestCommand.cs index 9e1f85bc..7b5b9656 100644 --- a/src/WixToolset.Core.Burn/Bundles/CreateBundleExtensionManifestCommand.cs +++ b/src/WixToolset.Core.Burn/Bundles/CreateBundleExtensionManifestCommand.cs @@ -66,7 +66,7 @@ namespace WixToolset.Core.Burn.Bundles private WixBundlePayloadSymbol CreateBundleExtensionManifestPayloadRow(string bextManifestPath) { - var generatedId = Common.GenerateIdentifier("ux", BurnCommon.BundleExtensionDataFileName); + var generatedId = this.InternalBurnBackendHelper.GenerateIdentifier("ux", BurnCommon.BundleExtensionDataFileName); var symbol = this.Section.AddSymbol(new WixBundlePayloadSymbol(this.BundleSymbol.SourceLineNumbers, new Identifier(AccessModifier.Section, generatedId)) { diff --git a/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs b/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs index 5ba1ad07..dc1a1913 100644 --- a/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs +++ b/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs @@ -94,7 +94,7 @@ namespace WixToolset.Core.Burn.Bundles msiPackage.ProductLanguage = Convert.ToInt32(ProcessMsiPackageCommand.GetProperty(db, "ProductLanguage"), CultureInfo.InvariantCulture); msiPackage.ProductVersion = ProcessMsiPackageCommand.GetProperty(db, "ProductVersion"); - if (!Common.IsValidModuleOrBundleVersion(msiPackage.ProductVersion)) + if (!this.BackendHelper.IsValidFourPartVersion(msiPackage.ProductVersion)) { // not a proper .NET version (e.g., five fields); can we get a valid four-part version number? string version = null; @@ -109,7 +109,7 @@ namespace WixToolset.Core.Burn.Bundles } } - if (!String.IsNullOrEmpty(version) && Common.IsValidModuleOrBundleVersion(version)) + if (!String.IsNullOrEmpty(version) && this.BackendHelper.IsValidFourPartVersion(version)) { this.Messaging.Write(WarningMessages.VersionTruncated(this.Facade.PackageSymbol.SourceLineNumbers, msiPackage.ProductVersion, sourcePath, version)); msiPackage.ProductVersion = version; @@ -394,7 +394,7 @@ namespace WixToolset.Core.Burn.Bundles if (!payloadNames.Contains(cabinetName)) { - var generatedId = Common.GenerateIdentifier("cab", packagePayload.Id.Id, cabinet); + var generatedId = this.BackendHelper.GenerateIdentifier("cab", packagePayload.Id.Id, cabinet); var payloadSourceFile = this.ResolveRelatedFile(packagePayload.SourceFile.Path, packagePayload.UnresolvedSourceFile, cabinet, "Cabinet", this.Facade.PackageSymbol.SourceLineNumbers); this.Section.AddSymbol(new WixBundlePayloadSymbol(this.Facade.PackageSymbol.SourceLineNumbers, new Identifier(AccessModifier.Section, generatedId)) @@ -437,7 +437,7 @@ namespace WixToolset.Core.Burn.Bundles break; } - var sourceName = Common.GetName(record.GetString(3), true, longNamesInImage); + var sourceName = this.BackendHelper.GetMsiFileName(record.GetString(3), true, longNamesInImage); var resolvedDirectory = this.BackendHelper.CreateResolvedDirectory(record.GetString(2), sourceName); @@ -471,7 +471,7 @@ namespace WixToolset.Core.Burn.Bundles if (!payloadNames.Contains(name)) { - var generatedId = Common.GenerateIdentifier("f", packagePayload.Id.Id, record.GetString(2)); + var generatedId = this.BackendHelper.GenerateIdentifier("f", packagePayload.Id.Id, record.GetString(2)); var payloadSourceFile = this.ResolveRelatedFile(packagePayload.SourceFile.Path, packagePayload.UnresolvedSourceFile, fileSourcePath, "File", this.Facade.PackageSymbol.SourceLineNumbers); this.Section.AddSymbol(new WixBundlePayloadSymbol(this.Facade.PackageSymbol.SourceLineNumbers, new Identifier(AccessModifier.Section, generatedId)) @@ -526,7 +526,7 @@ namespace WixToolset.Core.Burn.Bundles break; } - var id = new Identifier(AccessModifier.Section, Common.GenerateIdentifier("dep", msiPackage.Id.Id, record.GetString(1))); + var id = new Identifier(AccessModifier.Section, this.BackendHelper.GenerateIdentifier("dep", msiPackage.Id.Id, record.GetString(1))); // Import the provider key and attributes. this.Section.AddSymbol(new ProvidesDependencySymbol(msiPackage.SourceLineNumbers, id) diff --git a/src/WixToolset.Core.Burn/ExtensibilityServices/BurnBackendHelper.cs b/src/WixToolset.Core.Burn/ExtensibilityServices/BurnBackendHelper.cs index 59efcbc9..5502b43b 100644 --- a/src/WixToolset.Core.Burn/ExtensibilityServices/BurnBackendHelper.cs +++ b/src/WixToolset.Core.Burn/ExtensibilityServices/BurnBackendHelper.cs @@ -9,6 +9,8 @@ namespace WixToolset.Core.Burn.ExtensibilityServices using System.Xml; using WixToolset.Core.Burn.Bundles; using WixToolset.Data; + using WixToolset.Data.Symbols; + using WixToolset.Data.WindowsInstaller.Rows; using WixToolset.Extensibility.Data; using WixToolset.Extensibility.Services; @@ -30,14 +32,44 @@ namespace WixToolset.Core.Burn.ExtensibilityServices #region IBackendHelper interfaces + public IFileFacade CreateFileFacade(FileSymbol file, AssemblySymbol assembly) => this.backendHelper.CreateFileFacade(file, assembly); + + public IFileFacade CreateFileFacade(FileRow fileRow) => this.backendHelper.CreateFileFacade(fileRow); + + public IFileFacade CreateFileFacadeFromMergeModule(FileSymbol fileSymbol) => this.backendHelper.CreateFileFacadeFromMergeModule(fileSymbol); + public IFileTransfer CreateFileTransfer(string source, string destination, bool move, SourceLineNumber sourceLineNumbers = null) => this.backendHelper.CreateFileTransfer(source, destination, move, sourceLineNumbers); + public string CreateGuid() => this.backendHelper.CreateGuid(); + public string CreateGuid(Guid namespaceGuid, string value) => this.backendHelper.CreateGuid(namespaceGuid, value); public IResolvedDirectory CreateResolvedDirectory(string directoryParent, string name) => this.backendHelper.CreateResolvedDirectory(directoryParent, name); + public IEnumerable ExtractEmbeddedFiles(IEnumerable embeddedFiles) => this.backendHelper.ExtractEmbeddedFiles(embeddedFiles); + + public string GenerateIdentifier(string prefix, params string[] args) => this.backendHelper.GenerateIdentifier(prefix, args); + public string GetCanonicalRelativePath(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string relativePath) => this.backendHelper.GetCanonicalRelativePath(sourceLineNumbers, elementName, attributeName, relativePath); + public int GetValidCodePage(string value, bool allowNoChange, bool onlyAnsi = false, SourceLineNumber sourceLineNumbers = null) => this.backendHelper.GetValidCodePage(value, allowNoChange, onlyAnsi, sourceLineNumbers); + + public string GetMsiFileName(string value, bool source, bool longName) => this.backendHelper.GetMsiFileName(value, source, longName); + + public bool IsValidBinderVariable(string variable) => this.backendHelper.IsValidBinderVariable(variable); + + public bool IsValidFourPartVersion(string version) => this.backendHelper.IsValidFourPartVersion(version); + + public bool IsValidIdentifier(string id) => this.backendHelper.IsValidIdentifier(id); + + public bool IsValidLongFilename(string filename, bool allowWildcards, bool allowRelative) => this.backendHelper.IsValidLongFilename(filename, allowWildcards, allowRelative); + + public bool IsValidShortFilename(string filename, bool allowWildcards) => this.backendHelper.IsValidShortFilename(filename, allowWildcards); + + public void ResolveDelayedFields(IEnumerable delayedFields, Dictionary variableCache) => this.backendHelper.ResolveDelayedFields(delayedFields, variableCache); + + public string[] SplitMsiFileName(string value) => this.backendHelper.SplitMsiFileName(value); + public ITrackedFile TrackFile(string path, TrackedFileType type, SourceLineNumber sourceLineNumbers = null) => this.backendHelper.TrackFile(path, type, sourceLineNumbers); #endregion @@ -87,7 +119,7 @@ namespace WixToolset.Core.Burn.ExtensibilityServices private ManifestData GetBundleExtensionManifestData(string extensionId) { - if (!Common.IsIdentifier(extensionId)) + if (!this.backendHelper.IsValidIdentifier(extensionId)) { throw new ArgumentException($"'{extensionId}' is not a valid extensionId"); } diff --git a/src/WixToolset.Core.Burn/RowIndexedList.cs b/src/WixToolset.Core.Burn/RowIndexedList.cs index 73172dc2..fd762a24 100644 --- a/src/WixToolset.Core.Burn/RowIndexedList.cs +++ b/src/WixToolset.Core.Burn/RowIndexedList.cs @@ -13,9 +13,9 @@ namespace WixToolset.Core.Burn /// internal sealed class RowIndexedList : IList where T : Row { - private Dictionary index; - private List rows; - private List duplicates; + private readonly Dictionary index; + private readonly List rows; + private readonly List duplicates; /// /// Creates an empty . @@ -34,7 +34,7 @@ namespace WixToolset.Core.Burn public RowIndexedList(IEnumerable rows) : this() { - foreach (T row in rows) + foreach (var row in rows) { this.Add(row); } @@ -81,8 +81,7 @@ namespace WixToolset.Core.Burn /// Row or null if key is not found. public T Get(string key) { - T result; - return this.TryGet(key, out result) ? result : null; + return this.TryGet(key, out var result) ? result : null; } /// @@ -169,12 +168,11 @@ namespace WixToolset.Core.Burn /// Index to remove the row at. public void RemoveAt(int index) { - T row = this.rows[index]; + var row = this.rows[index]; this.rows.RemoveAt(index); - T indexRow; - if (this.index.TryGetValue(row.GetKey(), out indexRow) && indexRow == row) + if (this.index.TryGetValue(row.GetKey(), out var indexRow) && indexRow == row) { this.index.Remove(row.GetKey()); } @@ -264,11 +262,10 @@ namespace WixToolset.Core.Burn /// public bool Remove(T row) { - bool removed = this.rows.Remove(row); + var removed = this.rows.Remove(row); if (removed) { - T indexRow; - if (this.index.TryGetValue(row.GetKey(), out indexRow) && indexRow == row) + if (this.index.TryGetValue(row.GetKey(), out var indexRow) && indexRow == row) { this.index.Remove(row.GetKey()); } diff --git a/src/WixToolset.Core.Burn/TableExtensions.cs b/src/WixToolset.Core.Burn/TableExtensions.cs deleted file mode 100644 index 465bf870..00000000 --- a/src/WixToolset.Core.Burn/TableExtensions.cs +++ /dev/null @@ -1,24 +0,0 @@ -// 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. - -namespace WixToolset.Core.Burn -{ - using System.Collections.Generic; - using System.Linq; - using WixToolset.Data.WindowsInstaller; - - /// - /// Methods that extend . - /// - public static class TableExtensions - { - /// - /// Gets the rows contained in the table as a particular row type. - /// - /// Table to get rows from. - /// If the is null, an empty enumerable will be returned. - public static IEnumerable RowsAs(this Table table) where T : Row - { - return (null == table) ? Enumerable.Empty() : table.Rows.Cast(); - } - } -} diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs index f6c61866..d7faa382 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs @@ -6,9 +6,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind using System.Collections.Generic; using System.Globalization; using System.Linq; - using WixToolset.Core.Bind; using WixToolset.Data; using WixToolset.Data.Symbols; + using WixToolset.Extensibility.Data; using WixToolset.Extensibility.Services; /// @@ -18,7 +18,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind { private const int DefaultMaximumUncompressedMediaSize = 200; // Default value is 200 MB - public AssignMediaCommand(IntermediateSection section, IMessaging messaging, IEnumerable fileFacades, bool compressed) + public AssignMediaCommand(IntermediateSection section, IMessaging messaging, IEnumerable fileFacades, bool compressed) { this.CabinetNameTemplate = "Cab{0}.cab"; this.Section = section; @@ -31,7 +31,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind private IMessaging Messaging { get; } - private IEnumerable FileFacades { get; } + private IEnumerable FileFacades { get; } private bool FilesCompressed { get; } @@ -40,13 +40,13 @@ namespace WixToolset.Core.WindowsInstaller.Bind /// /// Gets cabinets with their file rows. /// - public Dictionary> FileFacadesByCabinetMedia { get; private set; } + public Dictionary> FileFacadesByCabinetMedia { get; private set; } /// /// Get uncompressed file rows. This will contain file rows of File elements that are marked with compression=no. /// This contains all the files when Package element is marked with compression=no /// - public IEnumerable UncompressedFileFacades { get; private set; } + public IEnumerable UncompressedFileFacades { get; private set; } public void Execute() { @@ -79,34 +79,34 @@ namespace WixToolset.Core.WindowsInstaller.Bind Cabinet = "#MergeModule.CABinet", }); - this.FileFacadesByCabinetMedia = new Dictionary> + this.FileFacadesByCabinetMedia = new Dictionary> { { mergeModuleMediaSymbol, this.FileFacades } }; - this.UncompressedFileFacades = Array.Empty(); + this.UncompressedFileFacades = Array.Empty(); } else if (mediaTemplateSymbols.Count == 0) { - var filesByCabinetMedia = new Dictionary>(); + var filesByCabinetMedia = new Dictionary>(); - var uncompressedFiles = new List(); + var uncompressedFiles = new List(); this.ManuallyAssignFiles(mediaSymbols, filesByCabinetMedia, uncompressedFiles); - this.FileFacadesByCabinetMedia = filesByCabinetMedia.ToDictionary(kvp => kvp.Key, kvp => (IEnumerable)kvp.Value); + this.FileFacadesByCabinetMedia = filesByCabinetMedia.ToDictionary(kvp => kvp.Key, kvp => (IEnumerable)kvp.Value); this.UncompressedFileFacades = uncompressedFiles; } else { - var filesByCabinetMedia = new Dictionary>(); + var filesByCabinetMedia = new Dictionary>(); - var uncompressedFiles = new List(); + var uncompressedFiles = new List(); this.AutoAssignFiles(mediaSymbols, filesByCabinetMedia, uncompressedFiles); - this.FileFacadesByCabinetMedia = filesByCabinetMedia.ToDictionary(kvp => kvp.Key, kvp => (IEnumerable)kvp.Value); + this.FileFacadesByCabinetMedia = filesByCabinetMedia.ToDictionary(kvp => kvp.Key, kvp => (IEnumerable)kvp.Value); this.UncompressedFileFacades = uncompressedFiles; } @@ -115,7 +115,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind /// /// Assign files to cabinets based on MediaTemplate authoring. /// - private void AutoAssignFiles(List mediaTable, Dictionary> filesByCabinetMedia, List uncompressedFiles) + private void AutoAssignFiles(List mediaTable, Dictionary> filesByCabinetMedia, List uncompressedFiles) { const int MaxCabIndex = 999; @@ -194,7 +194,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind { currentMediaRow = this.AddMediaSymbol(mediaTemplateRow, ++currentCabIndex); mediaSymbolsByDiskId.Add(currentMediaRow.DiskId, currentMediaRow); - filesByCabinetMedia.Add(currentMediaRow, new List()); + filesByCabinetMedia.Add(currentMediaRow, new List()); // Now files larger than MaxUncompressedMediaSize will be the only file in its cabinet so as to respect MaxUncompressedMediaSize currentPreCabSize = (ulong)facade.FileSize; @@ -206,7 +206,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind // Create new cab and MediaRow currentMediaRow = this.AddMediaSymbol(mediaTemplateRow, ++currentCabIndex); mediaSymbolsByDiskId.Add(currentMediaRow.DiskId, currentMediaRow); - filesByCabinetMedia.Add(currentMediaRow, new List()); + filesByCabinetMedia.Add(currentMediaRow, new List()); } } } @@ -232,7 +232,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind /// /// Assign files to cabinets based on Media authoring. /// - private void ManuallyAssignFiles(List mediaSymbols, Dictionary> filesByCabinetMedia, List uncompressedFiles) + private void ManuallyAssignFiles(List mediaSymbols, Dictionary> filesByCabinetMedia, List uncompressedFiles) { var mediaSymbolsByDiskId = new Dictionary(); @@ -254,7 +254,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind cabinetMediaSymbols.Add(mediaSymbol.Cabinet, mediaSymbol); } - filesByCabinetMedia.Add(mediaSymbol, new List()); + filesByCabinetMedia.Add(mediaSymbol, new List()); } mediaSymbolsByDiskId.Add(mediaSymbol.DiskId, mediaSymbol); diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/AttachPatchTransformsCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/AttachPatchTransformsCommand.cs index 2249faf8..b2052b90 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/AttachPatchTransformsCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/AttachPatchTransformsCommand.cs @@ -55,16 +55,19 @@ namespace WixToolset.Core.WindowsInstaller.Bind private readonly TableDefinitionCollection tableDefinitions; - public AttachPatchTransformsCommand(IMessaging messaging, Intermediate intermediate, IEnumerable transforms) + public AttachPatchTransformsCommand(IMessaging messaging, IBackendHelper backendHelper, Intermediate intermediate, IEnumerable transforms) { this.tableDefinitions = new TableDefinitionCollection(WindowsInstallerTableDefinitions.All); this.Messaging = messaging; + this.BackendHelper = backendHelper; this.Intermediate = intermediate; this.Transforms = transforms; } private IMessaging Messaging { get; } + private IBackendHelper BackendHelper { get; } + private Intermediate Intermediate { get; } private IEnumerable Transforms { get; } @@ -797,7 +800,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind if (!deletedComponent.ContainsKey(componentId)) { var foundRemoveFileEntry = false; - var filename = Common.GetName(row.FieldAsString(2), false, true); + var filename = this.BackendHelper.GetMsiFileName(row.FieldAsString(2), false, true); if (transform.TryGetTable("RemoveFile", out var removeFileTable)) { @@ -813,7 +816,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind // Check if there is a RemoveFile entry for this file if (null != removeFileRow[2]) { - var removeFileName = Common.GetName(removeFileRow.FieldAsString(2), false, true); + var removeFileName = this.BackendHelper.GetMsiFileName(removeFileRow.FieldAsString(2), false, true); // Convert the MSI format for a wildcard string to Regex format. removeFileName = removeFileName.Replace('.', '|').Replace('?', '.').Replace("*", ".*").Replace("|", "\\."); diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs index 292f1572..b6244a6e 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs @@ -6,7 +6,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind using System.Collections.Generic; using System.IO; using System.Linq; - using WixToolset.Core.Bind; using WixToolset.Data; using WixToolset.Data.Symbols; using WixToolset.Data.WindowsInstaller; @@ -133,7 +132,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind Platform platform; string modularizationSuffix; { - var command = new BindSummaryInfoCommand(section); + var branding = this.ServiceProvider.GetService(); + + var command = new BindSummaryInfoCommand(section, this.WindowsInstallerBackendHelper, branding); command.Execute(); compressed = command.Compressed; @@ -151,7 +152,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind // Set the ProductCode if it is to be generated. if ("ProductCode".Equals(propertyRow.Id.Id, StringComparison.Ordinal) && "*".Equals(propertyRow.Value, StringComparison.Ordinal)) { - propertyRow.Value = Common.GenerateGuid(); + propertyRow.Value = this.WindowsInstallerBackendHelper.CreateGuid(); #if TODO_PATCHING // Is this still necessary? @@ -235,24 +236,23 @@ namespace WixToolset.Core.WindowsInstaller.Bind // Extract files that come from binary .wixlibs and WixExtensions (this does not extract files from merge modules). { - var command = new ExtractEmbeddedFilesCommand(this.WindowsInstallerBackendHelper, this.ExpectedEmbeddedFiles); - command.Execute(); + var extractedFiles = this.WindowsInstallerBackendHelper.ExtractEmbeddedFiles(this.ExpectedEmbeddedFiles); - trackedFiles.AddRange(command.TrackedFiles); + trackedFiles.AddRange(extractedFiles); } // This must occur after all variables and source paths have been resolved. - List fileFacades; + List fileFacades; if (SectionType.Patch == section.Type) { - var command = new GetFileFacadesFromTransforms(this.Messaging, this.FileSystemManager, this.SubStorages); + var command = new GetFileFacadesFromTransforms(this.Messaging, this.WindowsInstallerBackendHelper, this.FileSystemManager, this.SubStorages); command.Execute(); fileFacades = command.FileFacades; } else { - var command = new GetFileFacadesCommand(section); + var command = new GetFileFacadesCommand(section, this.WindowsInstallerBackendHelper); command.Execute(); fileFacades = command.FileFacades; @@ -267,7 +267,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind { containsMergeModules = true; - var command = new ExtractMergeModuleFilesCommand(this.Messaging, wixMergeSymbols, fileFacades, installerVersion, this.IntermediateFolder, this.SuppressLayout); + var command = new ExtractMergeModuleFilesCommand(this.Messaging, this.WindowsInstallerBackendHelper, wixMergeSymbols, fileFacades, installerVersion, this.IntermediateFolder, this.SuppressLayout); command.Execute(); fileFacades.AddRange(command.MergeModulesFileFacades); @@ -307,8 +307,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind // Now that the variable cache is populated, resolve any delayed fields. if (this.DelayedFields.Any()) { - var command = new ResolveDelayedFieldsCommand(this.Messaging, this.DelayedFields, variableCache); - command.Execute(); + this.WindowsInstallerBackendHelper.ResolveDelayedFields(this.DelayedFields, variableCache); } // Update symbols that reference text files on disk. @@ -330,7 +329,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind if (dependencyRefs.Any()) { - var command = new ProcessDependencyReferencesCommand(section, dependencyRefs); + var command = new ProcessDependencyReferencesCommand(this.WindowsInstallerBackendHelper, section, dependencyRefs); command.Execute(); } } @@ -379,8 +378,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind } // Assign files to media and update file sequences. - Dictionary> filesByCabinetMedia; - IEnumerable uncompressedFiles; + Dictionary> filesByCabinetMedia; + IEnumerable uncompressedFiles; { var order = new OptimizeFileFacadesOrderCommand(this.WindowsInstallerBackendHelper, this.PathResolver, section, platform, fileFacades); order.Execute(); @@ -414,7 +413,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind if (data.Type == OutputType.Module) { // Modularize identifiers. - var modularize = new ModularizeCommand(data, modularizationSuffix, section.Symbols.OfType()); + var modularize = new ModularizeCommand(this.WindowsInstallerBackendHelper, data, modularizationSuffix, section.Symbols.OfType()); modularize.Execute(); // Ensure all sequence tables in place because, mergemod.dll requires them. diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/BindSummaryInfoCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/BindSummaryInfoCommand.cs index a496c7ce..babe0c1b 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/BindSummaryInfoCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/BindSummaryInfoCommand.cs @@ -7,19 +7,26 @@ namespace WixToolset.Core.WindowsInstaller.Bind using System.Linq; using WixToolset.Data; using WixToolset.Data.Symbols; + using WixToolset.Extensibility.Services; /// /// Binds the summary information table of a database. /// internal class BindSummaryInfoCommand { - public BindSummaryInfoCommand(IntermediateSection section) + public BindSummaryInfoCommand(IntermediateSection section, IBackendHelper backendHelper, IWixBranding branding) { this.Section = section; + this.BackendHelper = backendHelper; + this.Branding = branding; } private IntermediateSection Section { get; } + private IBackendHelper BackendHelper { get; } + + private IWixBranding Branding { get; } + /// /// Returns a flag indicating if files are compressed by default. /// @@ -66,7 +73,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind } else { - summaryInformationSymbol.Value = Common.GetValidCodePage(codepage, false, false, summaryInformationSymbol.SourceLineNumbers).ToString(CultureInfo.InvariantCulture); + summaryInformationSymbol.Value = this.BackendHelper.GetValidCodePage(codepage, false, false, summaryInformationSymbol.SourceLineNumbers).ToString(CultureInfo.InvariantCulture); } break; case SummaryInformationType.PlatformAndLanguage: @@ -116,7 +123,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind this.Section.AddSymbol(new SummaryInformationSymbol(null) { PropertyId = SummaryInformationType.PackageCode, - Value = Common.GenerateGuid(), + Value = this.BackendHelper.CreateGuid(), }); } @@ -146,7 +153,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind this.Section.AddSymbol(new SummaryInformationSymbol(null) { PropertyId = SummaryInformationType.CreatingApplication, - Value = String.Format(CultureInfo.InvariantCulture, AppCommon.GetCreatingApplicationString()), + Value = this.Branding.GetCreatingApplication(), }); } } diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/BindTransformCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/BindTransformCommand.cs index bc5c6853..28e1d9ee 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/BindTransformCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/BindTransformCommand.cs @@ -99,7 +99,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind } else { - codePage = Common.GetValidCodePage(codePage).ToString(CultureInfo.InvariantCulture); + codePage = this.BackendHelper.GetValidCodePage(codePage).ToString(CultureInfo.InvariantCulture); } var previousCodePage = row.Fields[1].PreviousData; @@ -109,7 +109,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind } else { - previousCodePage = Common.GetValidCodePage(previousCodePage).ToString(CultureInfo.InvariantCulture); + previousCodePage = this.BackendHelper.GetValidCodePage(previousCodePage).ToString(CultureInfo.InvariantCulture); } var targetCodePageRow = targetSummaryInfo.CreateRow(null); diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CabinetResolver.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CabinetResolver.cs index 6dbcb1a1..e47e5b64 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/CabinetResolver.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/CabinetResolver.cs @@ -6,7 +6,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind using System.Collections.Generic; using System.IO; using System.Linq; - using WixToolset.Core.Bind; using WixToolset.Core.Native; using WixToolset.Data; using WixToolset.Extensibility; @@ -30,7 +29,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind private IEnumerable BackendExtensions { get; } - public IResolvedCabinet ResolveCabinet(string cabinetPath, IEnumerable fileFacades) + public IResolvedCabinet ResolveCabinet(string cabinetPath, IEnumerable fileFacades) { var filesWithPath = fileFacades.Select(this.CreateBindFileWithPath).ToList(); @@ -109,7 +108,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind return resolved; } - private IBindFileWithPath CreateBindFileWithPath(FileFacade facade) + private IBindFileWithPath CreateBindFileWithPath(IFileFacade facade) { var result = this.ServiceProvider.GetService(); result.Id = facade.Id; diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CabinetWorkItem.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CabinetWorkItem.cs index 48f0574e..1990ea78 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/CabinetWorkItem.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/CabinetWorkItem.cs @@ -3,8 +3,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind { using System.Collections.Generic; - using WixToolset.Core.Bind; using WixToolset.Data; + using WixToolset.Extensibility.Data; /// /// A cabinet builder work item. @@ -20,7 +20,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind /// The compression level of the cabinet. /// Modularization suffix used when building a Merge Module. /// - public CabinetWorkItem(IEnumerable fileFacades, string cabinetFile, int maxThreshold, CompressionLevel compressionLevel, string modularizationSuffix /*, BinderFileManager binderFileManager*/) + public CabinetWorkItem(IEnumerable fileFacades, string cabinetFile, int maxThreshold, CompressionLevel compressionLevel, string modularizationSuffix /*, BinderFileManager binderFileManager*/) { this.CabinetFile = cabinetFile; this.CompressionLevel = compressionLevel; @@ -51,7 +51,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind /// Gets the collection of files in this cabinet. /// /// The collection of files in this cabinet. - public IEnumerable FileFacades { get; } + public IEnumerable FileFacades { get; } // // Gets the binder file manager. diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CalculateComponentGuids.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CalculateComponentGuids.cs index 55cda9ea..5cb297e5 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/CalculateComponentGuids.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/CalculateComponentGuids.cs @@ -138,8 +138,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind if (fileRow.Id.Id == componentSymbol.KeyPath) { // calculate the key file's canonical target path - string directoryPath = this.PathResolver.GetCanonicalDirectoryPath(targetPathsByDirectoryId, componentIdGenSeeds, componentSymbol.DirectoryRef, this.Platform); - string fileName = Common.GetName(fileRow.Name, false, true).ToLowerInvariant(); + var directoryPath = this.PathResolver.GetCanonicalDirectoryPath(targetPathsByDirectoryId, componentIdGenSeeds, componentSymbol.DirectoryRef, this.Platform); + var fileName = this.BackendHelper.GetMsiFileName(fileRow.Name, false, true).ToLowerInvariant(); path = Path.Combine(directoryPath, fileName); // find paths that are not canonicalized diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CopyTransformDataCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CopyTransformDataCommand.cs deleted file mode 100644 index 8a85a975..00000000 --- a/src/WixToolset.Core.WindowsInstaller/Bind/CopyTransformDataCommand.cs +++ /dev/null @@ -1,630 +0,0 @@ -// 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. - -#if DELETE - -namespace WixToolset.Core.WindowsInstaller.Bind -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.IO; - using System.Linq; - using WixToolset.Core.Bind; - using WixToolset.Data; - using WixToolset.Data.Symbols; - using WixToolset.Data.WindowsInstaller; - using WixToolset.Data.WindowsInstaller.Rows; - using WixToolset.Extensibility; - using WixToolset.Extensibility.Services; - - internal class CopyTransformDataCommand - { - public CopyTransformDataCommand(IMessaging messaging, WindowsInstallerData output, TableDefinitionCollection tableDefinitions, bool copyOutFileRows) - { - this.Messaging = messaging; - this.Output = output; - this.TableDefinitions = tableDefinitions; - this.CopyOutFileRows = copyOutFileRows; - } - - private bool CopyOutFileRows { get; } - - public IEnumerable Extensions { get; } - - private IMessaging Messaging { get; } - - private WindowsInstallerData Output { get; } - - private TableDefinitionCollection TableDefinitions { get; } - - public IEnumerable FileFacades { get; private set; } - - public void Execute() - { - Debug.Assert(OutputType.Patch != this.Output.Type); - - var allFileRows = this.CopyOutFileRows ? new List() : null; - - var copyToPatch = (allFileRows != null); - var copyFromPatch = !copyToPatch; - - var patchMediaRows = new RowDictionary(); - - var patchMediaFileRows = new Dictionary>(); - - var patchActualFileTable = this.Output.EnsureTable(this.TableDefinitions["File"]); - var patchFileTable = this.Output.EnsureTable(this.TableDefinitions["WixFile"]); - - if (copyFromPatch) - { - // index patch files by diskId+fileId - foreach (WixFileRow patchFileRow in patchFileTable.Rows) - { - int diskId = patchFileRow.DiskId; - if (!patchMediaFileRows.TryGetValue(diskId, out var mediaFileRows)) - { - mediaFileRows = new RowDictionary(); - patchMediaFileRows.Add(diskId, mediaFileRows); - } - - mediaFileRows.Add(patchFileRow); - } - - var patchMediaTable = this.Output.EnsureTable(this.TableDefinitions["Media"]); - patchMediaRows = new RowDictionary(patchMediaTable); - } - - // Index paired transforms by name without the "#" prefix. - var pairedTransforms = this.Output.SubStorages.Where(s => s.Name.StartsWith("#")).ToDictionary(s => s.Name.Substring(1), s => s.Data); - //Dictionary pairedTransforms = new Dictionary(); - //foreach (SubStorage substorage in this.Output.SubStorages) - //{ - // if (substorage.Name.StartsWith("#")) - // { - // pairedTransforms.Add(substorage.Name.Substring(1), substorage.Data); - // } - //} - - try - { - // Copy File bind data into substorages - foreach (var substorage in this.Output.SubStorages) - { - if (substorage.Name.StartsWith("#")) - { - // no changes necessary for paired transforms - continue; - } - - var mainTransform = substorage.Data; - var mainWixFileTable = mainTransform.Tables["WixFile"]; - var mainMsiFileHashTable = mainTransform.Tables["MsiFileHash"]; - - this.FileManagerCore.ActiveSubStorage = substorage; - - var mainWixFiles = new RowDictionary(mainWixFileTable); - var mainMsiFileHashIndex = new RowDictionary(); - - var mainFileTable = mainTransform.Tables["File"]; - var pairedTransform = pairedTransforms[substorage.Name]; - - // copy Media.LastSequence and index the MsiFileHash table if it exists. - if (copyFromPatch) - { - var pairedMediaTable = pairedTransform.Tables["Media"]; - foreach (MediaRow pairedMediaRow in pairedMediaTable.Rows) - { - var patchMediaRow = patchMediaRows.Get(pairedMediaRow.DiskId); - pairedMediaRow.Fields[1] = patchMediaRow.Fields[1]; - } - - if (null != mainMsiFileHashTable) - { - mainMsiFileHashIndex = new RowDictionary(mainMsiFileHashTable); - } - - // Validate file row changes for keypath-related issues - this.ValidateFileRowChanges(mainTransform); - } - - // Index File table of pairedTransform - var pairedFileTable = pairedTransform.Tables["File"]; - var pairedFileRows = new RowDictionary(pairedFileTable); - - if (null != mainFileTable) - { - if (copyFromPatch) - { - // Remove the MsiFileHash table because it will be updated later with the final file hash for each file - mainTransform.Tables.Remove("MsiFileHash"); - } - - foreach (FileRow mainFileRow in mainFileTable.Rows) - { - if (RowOperation.Delete == mainFileRow.Operation) - { - continue; - } - else if (RowOperation.None == mainFileRow.Operation && !copyToPatch) - { - continue; - } - - var mainWixFileRow = mainWixFiles.Get(mainFileRow.File); - - if (copyToPatch) // when copying to the patch, we need compare the underlying files and include all file changes. - { - var objectField = (ObjectField)mainWixFileRow.Fields[6]; - var pairedFileRow = pairedFileRows.Get(mainFileRow.File); - - // If the file is new, we always need to add it to the patch. - if (mainFileRow.Operation != RowOperation.Add) - { - // If PreviousData doesn't exist, target and upgrade layout point to the same location. No need to compare. - if (null == objectField.PreviousData) - { - if (mainFileRow.Operation == RowOperation.None) - { - continue; - } - } - else - { - // TODO: should this entire condition be placed in the binder file manager? - if ((0 == (PatchAttributeType.Ignore & mainWixFileRow.PatchAttributes)) && - !this.CompareFiles(objectField.PreviousData.ToString(), objectField.Data.ToString())) - { - // If the file is different, we need to mark the mainFileRow and pairedFileRow as modified. - mainFileRow.Operation = RowOperation.Modify; - if (null != pairedFileRow) - { - // Always patch-added, but never non-compressed. - pairedFileRow.Attributes |= WindowsInstallerConstants.MsidbFileAttributesPatchAdded; - pairedFileRow.Attributes &= ~WindowsInstallerConstants.MsidbFileAttributesNoncompressed; - pairedFileRow.Fields[6].Modified = true; - pairedFileRow.Operation = RowOperation.Modify; - } - } - else - { - // The File is same. We need mark all the attributes as unchanged. - mainFileRow.Operation = RowOperation.None; - foreach (var field in mainFileRow.Fields) - { - field.Modified = false; - } - - if (null != pairedFileRow) - { - pairedFileRow.Attributes &= ~WindowsInstallerConstants.MsidbFileAttributesPatchAdded; - pairedFileRow.Fields[6].Modified = false; - pairedFileRow.Operation = RowOperation.None; - } - continue; - } - } - } - else if (null != pairedFileRow) // RowOperation.Add - { - // Always patch-added, but never non-compressed. - pairedFileRow.Attributes |= WindowsInstallerConstants.MsidbFileAttributesPatchAdded; - pairedFileRow.Attributes &= ~WindowsInstallerConstants.MsidbFileAttributesNoncompressed; - pairedFileRow.Fields[6].Modified = true; - pairedFileRow.Operation = RowOperation.Add; - } - } - - // index patch files by diskId+fileId - int diskId = mainWixFileRow.DiskId; - - if (!patchMediaFileRows.TryGetValue(diskId, out var mediaFileRows)) - { - mediaFileRows = new RowDictionary(); - patchMediaFileRows.Add(diskId, mediaFileRows); - } - - var fileId = mainFileRow.File; - var patchFileRow = mediaFileRows.Get(fileId); - if (copyToPatch) - { - if (null == patchFileRow) - { - var patchActualFileRow = (FileRow)patchFileTable.CreateRow(mainFileRow.SourceLineNumbers); - patchActualFileRow.CopyFrom(mainFileRow); - - patchFileRow = (WixFileRow)patchFileTable.CreateRow(mainFileRow.SourceLineNumbers); - patchFileRow.CopyFrom(mainWixFileRow); - - mediaFileRows.Add(patchFileRow); - - allFileRows.Add(new FileFacade(patchActualFileRow, patchFileRow, null)); // TODO: should we be passing along delta information? Probably, right? - } - else - { - // TODO: confirm the rest of data is identical? - - // make sure Source is same. Otherwise we are silently ignoring a file. - if (0 != String.Compare(patchFileRow.Source, mainWixFileRow.Source, StringComparison.OrdinalIgnoreCase)) - { - this.Messaging.Write(ErrorMessages.SameFileIdDifferentSource(mainFileRow.SourceLineNumbers, fileId, patchFileRow.Source, mainWixFileRow.Source)); - } - - // capture the previous file versions (and associated data) from this targeted instance of the baseline into the current filerow. - patchFileRow.AppendPreviousDataFrom(mainWixFileRow); - } - } - else - { - // copy data from the patch back to the transform - if (null != patchFileRow) - { - var pairedFileRow = pairedFileRows.Get(fileId); - for (var i = 0; i < patchFileRow.Fields.Length; i++) - { - var patchValue = patchFileRow[i] == null ? String.Empty : patchFileRow.FieldAsString(i); - var mainValue = mainFileRow[i] == null ? String.Empty : mainFileRow.FieldAsString(i); - - if (1 == i) - { - // File.Component_ changes should not come from the shared file rows - // that contain the file information as each individual transform might - // have different changes (or no changes at all). - } - // File.Attributes should not changed for binary deltas - else if (6 == i) - { - if (null != patchFileRow.Patch) - { - // File.Attribute should not change for binary deltas - pairedFileRow.Attributes = mainFileRow.Attributes; - mainFileRow.Fields[i].Modified = false; - } - } - // File.Sequence is updated in pairedTransform, not mainTransform - else if (7 == i) - { - // file sequence is updated in Patch table instead of File table for delta patches - if (null != patchFileRow.Patch) - { - pairedFileRow.Fields[i].Modified = false; - } - else - { - pairedFileRow[i] = patchFileRow[i]; - pairedFileRow.Fields[i].Modified = true; - } - mainFileRow.Fields[i].Modified = false; - } - else if (patchValue != mainValue) - { - mainFileRow[i] = patchFileRow[i]; - mainFileRow.Fields[i].Modified = true; - if (mainFileRow.Operation == RowOperation.None) - { - mainFileRow.Operation = RowOperation.Modify; - } - } - } - - // copy MsiFileHash row for this File - if (!mainMsiFileHashIndex.TryGetValue(patchFileRow.File, out var patchHashRow)) - { - patchHashRow = patchFileRow.Hash; - } - - if (null != patchHashRow) - { - var mainHashTable = mainTransform.EnsureTable(this.TableDefinitions["MsiFileHash"]); - var mainHashRow = mainHashTable.CreateRow(mainFileRow.SourceLineNumbers); - for (var i = 0; i < patchHashRow.Fields.Length; i++) - { - mainHashRow[i] = patchHashRow[i]; - if (i > 1) - { - // assume all hash fields have been modified - mainHashRow.Fields[i].Modified = true; - } - } - - // assume the MsiFileHash operation follows the File one - mainHashRow.Operation = mainFileRow.Operation; - } - - // copy MsiAssemblyName rows for this File - List patchAssemblyNameRows = patchFileRow.AssemblyNames; - if (null != patchAssemblyNameRows) - { - var mainAssemblyNameTable = mainTransform.EnsureTable(this.TableDefinitions["MsiAssemblyName"]); - foreach (var patchAssemblyNameRow in patchAssemblyNameRows) - { - // Copy if there isn't an identical modified/added row already in the transform. - var foundMatchingModifiedRow = false; - foreach (var mainAssemblyNameRow in mainAssemblyNameTable.Rows) - { - if (RowOperation.None != mainAssemblyNameRow.Operation && mainAssemblyNameRow.GetPrimaryKey('/').Equals(patchAssemblyNameRow.GetPrimaryKey('/'))) - { - foundMatchingModifiedRow = true; - break; - } - } - - if (!foundMatchingModifiedRow) - { - var mainAssemblyNameRow = mainAssemblyNameTable.CreateRow(mainFileRow.SourceLineNumbers); - for (var i = 0; i < patchAssemblyNameRow.Fields.Length; i++) - { - mainAssemblyNameRow[i] = patchAssemblyNameRow[i]; - } - - // assume value field has been modified - mainAssemblyNameRow.Fields[2].Modified = true; - mainAssemblyNameRow.Operation = mainFileRow.Operation; - } - } - } - - // Add patch header for this file - if (null != patchFileRow.Patch) - { - // Add the PatchFiles action automatically to the AdminExecuteSequence and InstallExecuteSequence tables. - this.AddPatchFilesActionToSequenceTable(SequenceTable.AdminExecuteSequence, mainTransform, pairedTransform, mainFileRow); - this.AddPatchFilesActionToSequenceTable(SequenceTable.InstallExecuteSequence, mainTransform, pairedTransform, mainFileRow); - - // Add to Patch table - var patchTable = pairedTransform.EnsureTable(this.TableDefinitions["Patch"]); - if (0 == patchTable.Rows.Count) - { - patchTable.Operation = TableOperation.Add; - } - - var patchRow = patchTable.CreateRow(mainFileRow.SourceLineNumbers); - patchRow[0] = patchFileRow.File; - patchRow[1] = patchFileRow.Sequence; - - var patchFile = new FileInfo(patchFileRow.Source); - patchRow[2] = (int)patchFile.Length; - patchRow[3] = 0 == (PatchAttributeType.AllowIgnoreOnError & patchFileRow.PatchAttributes) ? 0 : 1; - - var streamName = patchTable.Name + "." + patchRow[0] + "." + patchRow[1]; - if (Msi.MsiInterop.MsiMaxStreamNameLength < streamName.Length) - { - streamName = "_" + Guid.NewGuid().ToString("D").ToUpperInvariant().Replace('-', '_'); - - var patchHeadersTable = pairedTransform.EnsureTable(this.TableDefinitions["MsiPatchHeaders"]); - if (0 == patchHeadersTable.Rows.Count) - { - patchHeadersTable.Operation = TableOperation.Add; - } - - var patchHeadersRow = patchHeadersTable.CreateRow(mainFileRow.SourceLineNumbers); - patchHeadersRow[0] = streamName; - patchHeadersRow[1] = patchFileRow.Patch; - patchRow[5] = streamName; - patchHeadersRow.Operation = RowOperation.Add; - } - else - { - patchRow[4] = patchFileRow.Patch; - } - patchRow.Operation = RowOperation.Add; - } - } - else - { - // TODO: throw because all transform rows should have made it into the patch - } - } - } - } - - if (copyFromPatch) - { - this.Output.Tables.Remove("Media"); - this.Output.Tables.Remove("File"); - this.Output.Tables.Remove("MsiFileHash"); - this.Output.Tables.Remove("MsiAssemblyName"); - } - } - } - finally - { - this.FileManagerCore.ActiveSubStorage = null; - } - - this.FileFacades = allFileRows; - } - - /// - /// Adds the PatchFiles action to the sequence table if it does not already exist. - /// - /// The sequence table to check or modify. - /// The primary authoring transform. - /// The secondary patch transform. - /// The file row that contains information about the patched file. - private void AddPatchFilesActionToSequenceTable(SequenceTable table, WindowsInstallerData mainTransform, WindowsInstallerData pairedTransform, Row mainFileRow) - { - var tableName = table.ToString(); - - // Find/add PatchFiles action (also determine sequence for it). - // Search mainTransform first, then pairedTransform (pairedTransform overrides). - var hasPatchFilesAction = false; - var installFilesSequence = 0; - var duplicateFilesSequence = 0; - - TestSequenceTableForPatchFilesAction( - mainTransform.Tables[tableName], - ref hasPatchFilesAction, - ref installFilesSequence, - ref duplicateFilesSequence); - TestSequenceTableForPatchFilesAction( - pairedTransform.Tables[tableName], - ref hasPatchFilesAction, - ref installFilesSequence, - ref duplicateFilesSequence); - if (!hasPatchFilesAction) - { - WindowsInstallerStandard.TryGetStandardAction(tableName, "PatchFiles", out var patchFilesActionSymbol); - - var sequence = patchFilesActionSymbol.Sequence; - - // Test for default sequence value's appropriateness - if (installFilesSequence >= sequence || (0 != duplicateFilesSequence && duplicateFilesSequence <= sequence)) - { - if (0 != duplicateFilesSequence) - { - if (duplicateFilesSequence < installFilesSequence) - { - throw new WixException(ErrorMessages.InsertInvalidSequenceActionOrder(mainFileRow.SourceLineNumbers, tableName, "InstallFiles", "DuplicateFiles", patchFilesActionSymbol.Action)); - } - else - { - sequence = (duplicateFilesSequence + installFilesSequence) / 2; - if (installFilesSequence == sequence || duplicateFilesSequence == sequence) - { - throw new WixException(ErrorMessages.InsertSequenceNoSpace(mainFileRow.SourceLineNumbers, tableName, "InstallFiles", "DuplicateFiles", patchFilesActionSymbol.Action)); - } - } - } - else - { - sequence = installFilesSequence + 1; - } - } - - var sequenceTable = pairedTransform.EnsureTable(this.TableDefinitions[tableName]); - if (0 == sequenceTable.Rows.Count) - { - sequenceTable.Operation = TableOperation.Add; - } - - var patchAction = sequenceTable.CreateRow(null); - patchAction[0] = patchFilesActionSymbol.Action; - patchAction[1] = patchFilesActionSymbol.Condition; - patchAction[2] = sequence; - patchAction.Operation = RowOperation.Add; - } - } - - /// - /// Tests sequence table for PatchFiles and associated actions - /// - /// The table to test. - /// Set to true if PatchFiles action is found. Left unchanged otherwise. - /// Set to sequence value of InstallFiles action if found. Left unchanged otherwise. - /// Set to sequence value of DuplicateFiles action if found. Left unchanged otherwise. - private static void TestSequenceTableForPatchFilesAction(Table sequenceTable, ref bool hasPatchFilesAction, ref int installFilesSequence, ref int duplicateFilesSequence) - { - if (null != sequenceTable) - { - foreach (var row in sequenceTable.Rows) - { - var actionName = row.FieldAsString(0); - switch (actionName) - { - case "PatchFiles": - hasPatchFilesAction = true; - break; - - case "InstallFiles": - installFilesSequence = row.FieldAsInteger(2); - break; - - case "DuplicateFiles": - duplicateFilesSequence = row.FieldAsInteger(2); - break; - } - } - } - } - - /// - /// Signal a warning if a non-keypath file was changed in a patch without also changing the keypath file of the component. - /// - /// The output to validate. - private void ValidateFileRowChanges(WindowsInstallerData transform) - { - var componentTable = transform.Tables["Component"]; - var fileTable = transform.Tables["File"]; - - // There's no sense validating keypaths if the transform has no component or file table - if (componentTable == null || fileTable == null) - { - return; - } - - var componentKeyPath = new Dictionary(componentTable.Rows.Count); - - // Index the Component table for non-directory & non-registry key paths. - foreach (var row in componentTable.Rows) - { - var keyPath = row.FieldAsString(5); - if (keyPath != null && 0 != (row.FieldAsInteger(3) & WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath)) - { - componentKeyPath.Add(row.FieldAsString(0), keyPath); - } - } - - var componentWithChangedKeyPath = new Dictionary(); - var componentWithNonKeyPathChanged = new Dictionary(); - // Verify changes in the file table, now that file diffing has occurred - foreach (FileRow row in fileTable.Rows) - { - if (RowOperation.Modify != row.Operation) - { - continue; - } - - var fileId = row.FieldAsString(0); - var componentId = row.FieldAsString(1); - - // If this file is the keypath of a component - if (componentKeyPath.ContainsValue(fileId)) - { - if (!componentWithChangedKeyPath.ContainsKey(componentId)) - { - componentWithChangedKeyPath.Add(componentId, fileId); - } - } - else - { - if (!componentWithNonKeyPathChanged.ContainsKey(componentId)) - { - componentWithNonKeyPathChanged.Add(componentId, fileId); - } - } - } - - foreach (var componentFile in componentWithNonKeyPathChanged) - { - // Make sure all changes to non keypath files also had a change in the keypath. - if (!componentWithChangedKeyPath.ContainsKey(componentFile.Key) && componentKeyPath.TryGetValue(componentFile.Key, out var keyPath)) - { - this.Messaging.Write(WarningMessages.UpdateOfNonKeyPathFile(componentFile.Value, componentFile.Key, keyPath)); - } - } - } - - private bool CompareFiles(string targetFile, string updatedFile) - { - bool? compared = null; - foreach (var extension in this.Extensions) - { - compared = extension.CompareFiles(targetFile, updatedFile); - - if (compared.HasValue) - { - break; - } - } - - if (!compared.HasValue) - { - throw new InvalidOperationException(); // TODO: something needs to be said here that none of the binder file managers returned a result. - } - - return compared.Value; - } - } -} - -#endif diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs index 9f94b2c7..0a543650 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs @@ -80,7 +80,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind public string ModularizationSuffix { private get; set; } - public Dictionary> FileFacadesByCabinet { private get; set; } + public Dictionary> FileFacadesByCabinet { private get; set; } public Func ResolveMedia { private get; set; } @@ -177,7 +177,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind /// Desired compression level. /// Collection of files in this cabinet. /// created CabinetWorkItem object - private CabinetWorkItem CreateCabinetWorkItem(WindowsInstallerData data, string cabinetDir, MediaSymbol mediaSymbol, CompressionLevel compressionLevel, IEnumerable fileFacades) + private CabinetWorkItem CreateCabinetWorkItem(WindowsInstallerData data, string cabinetDir, MediaSymbol mediaSymbol, CompressionLevel compressionLevel, IEnumerable fileFacades) { CabinetWorkItem cabinetWorkItem = null; var tempCabinetFileX = Path.Combine(this.IntermediateFolder, mediaSymbol.Cabinet); diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CreateDeltaPatchesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CreateDeltaPatchesCommand.cs index 93ac50ff..640322e6 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/CreateDeltaPatchesCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/CreateDeltaPatchesCommand.cs @@ -9,20 +9,21 @@ namespace WixToolset.Core.WindowsInstaller.Bind using WixToolset.Core.Bind; using WixToolset.Data; using WixToolset.Data.Symbols; + using WixToolset.Extensibility.Data; /// /// Creates delta patches and updates the appropriate rows to point to the newly generated patches. /// internal class CreateDeltaPatchesCommand { - public CreateDeltaPatchesCommand(List fileFacades, string intermediateFolder, WixPatchIdSymbol wixPatchId) + public CreateDeltaPatchesCommand(List fileFacades, string intermediateFolder, WixPatchIdSymbol wixPatchId) { this.FileFacades = fileFacades; this.IntermediateFolder = intermediateFolder; this.WixPatchId = wixPatchId; } - private IEnumerable FileFacades { get; } + private IEnumerable FileFacades { get; } private WixPatchIdSymbol WixPatchId { get; } @@ -31,7 +32,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind public void Execute() { var optimizePatchSizeForLargeFiles = this.WixPatchId?.OptimizePatchSizeForLargeFiles ?? false; - var apiPatchingSymbolFlags = (PatchSymbolFlagsType)(this.WixPatchId?.ApiPatchingSymbolFlags ?? 0); + var apiPatchingSymbolFlags = (PatchSymbolFlags)(this.WixPatchId?.ApiPatchingSymbolFlags ?? 0); #if TODO_PATCHING_DELTA foreach (FileFacade facade in this.FileFacades) diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CreateInstanceTransformsCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CreateInstanceTransformsCommand.cs index 33afca77..9a631754 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/CreateInstanceTransformsCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/CreateInstanceTransformsCommand.cs @@ -110,7 +110,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind var productCode = instanceSymbol.ProductCode; if ("*" == productCode) { - productCode = Common.GenerateGuid(); + productCode = this.BackendHelper.CreateGuid(); } var productCodeRow = propertyTable.CreateRow(instanceSymbol.SourceLineNumbers); diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CreatePatchTransformsCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CreatePatchTransformsCommand.cs index 76e6dd56..7bc1a8bd 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/CreatePatchTransformsCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/CreatePatchTransformsCommand.cs @@ -15,15 +15,18 @@ namespace WixToolset.Core.WindowsInstaller.Bind internal class CreatePatchTransformsCommand { - public CreatePatchTransformsCommand(IMessaging messaging, Intermediate intermediate, string intermediateFolder) + public CreatePatchTransformsCommand(IMessaging messaging, IBackendHelper backendHelper, Intermediate intermediate, string intermediateFolder) { this.Messaging = messaging; + this.BackendHelper = backendHelper; this.Intermediate = intermediate; this.IntermediateFolder = intermediateFolder; } private IMessaging Messaging { get; } + private IBackendHelper BackendHelper { get; } + private Intermediate Intermediate { get; } private string IntermediateFolder { get; } @@ -52,7 +55,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind { var exportBasePath = Path.Combine(this.IntermediateFolder, "_trans"); // TODO: come up with a better path. - var command = new UnbindTransformCommand(this.Messaging, symbol.TransformFile.Path, exportBasePath, this.IntermediateFolder); + var command = new UnbindTransformCommand(this.Messaging, this.BackendHelper, symbol.TransformFile.Path, exportBasePath, this.IntermediateFolder); transform = command.Execute(); } @@ -76,7 +79,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind var isAdminImage = false; // TODO: need a better way to set this - var command = new UnbindDatabaseCommand(this.Messaging, database, path, OutputType.Product, exportBasePath, this.IntermediateFolder, isAdminImage, suppressDemodularization: true, skipSummaryInfo: true); + var command = new UnbindDatabaseCommand(this.Messaging, this.BackendHelper, database, path, OutputType.Product, exportBasePath, this.IntermediateFolder, isAdminImage, suppressDemodularization: true, skipSummaryInfo: true); return command.Execute(); } } diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs index 9ec26964..0ce67591 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs @@ -481,18 +481,18 @@ namespace WixToolset.Core.WindowsInstaller.Bind private void AddDirectorySymbol(DirectorySymbol symbol) { - if (String.IsNullOrEmpty(symbol.ShortName) && symbol.Name != null && !symbol.Name.Equals(".") && !symbol.Name.Equals("SourceDir") && !Common.IsValidShortFilename(symbol.Name, false)) + if (String.IsNullOrEmpty(symbol.ShortName) && symbol.Name != null && !symbol.Name.Equals(".") && !symbol.Name.Equals("SourceDir") && !this.BackendHelper.IsValidShortFilename(symbol.Name, false)) { - symbol.ShortName = CreateShortName(symbol.Name, false, false, "Directory", symbol.ParentDirectoryRef); + symbol.ShortName = this.CreateShortName(symbol.Name, false, "Directory", symbol.ParentDirectoryRef); } - if (String.IsNullOrEmpty(symbol.SourceShortName) && !String.IsNullOrEmpty(symbol.SourceName) && !Common.IsValidShortFilename(symbol.SourceName, false)) + if (String.IsNullOrEmpty(symbol.SourceShortName) && !String.IsNullOrEmpty(symbol.SourceName) && !this.BackendHelper.IsValidShortFilename(symbol.SourceName, false)) { - symbol.SourceShortName = CreateShortName(symbol.SourceName, false, false, "Directory", symbol.ParentDirectoryRef); + symbol.SourceShortName = this.CreateShortName(symbol.SourceName, false, "Directory", symbol.ParentDirectoryRef); } - var sourceName = GetMsiFilenameValue(symbol.SourceShortName, symbol.SourceName); - var targetName = GetMsiFilenameValue(symbol.ShortName, symbol.Name); + var sourceName = CreateMsiFilename(symbol.SourceShortName, symbol.SourceName); + var targetName = CreateMsiFilename(symbol.ShortName, symbol.Name); if (String.IsNullOrEmpty(targetName)) { @@ -542,16 +542,16 @@ namespace WixToolset.Core.WindowsInstaller.Bind private void AddDuplicateFileSymbol(DuplicateFileSymbol symbol) { var name = symbol.DestinationName; - if (null == symbol.DestinationShortName && null != name && !Common.IsValidShortFilename(name, false)) + if (null == symbol.DestinationShortName && null != name && !this.BackendHelper.IsValidShortFilename(name, false)) { - symbol.DestinationShortName = CreateShortName(name, true, false, "CopyFile", symbol.ComponentRef, symbol.FileRef); + symbol.DestinationShortName = this.CreateShortName(name, true, "CopyFile", symbol.ComponentRef, symbol.FileRef); } var row = this.CreateRow(symbol, "DuplicateFile"); row[0] = symbol.Id.Id; row[1] = symbol.ComponentRef; row[2] = symbol.FileRef; - row[3] = GetMsiFilenameValue(symbol.DestinationShortName, symbol.DestinationName); + row[3] = CreateMsiFilename(symbol.DestinationShortName, symbol.DestinationName); row[4] = symbol.DestinationFolder; } @@ -621,9 +621,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind private void AddFileSymbol(FileSymbol symbol) { var name = symbol.Name; - if (null == symbol.ShortName && null != name && !Common.IsValidShortFilename(name, false)) + if (null == symbol.ShortName && null != name && !this.BackendHelper.IsValidShortFilename(name, false)) { - symbol.ShortName = CreateShortName(name, true, false, "File", symbol.DirectoryRef); + symbol.ShortName = this.CreateShortName(name, true, "File", symbol.DirectoryRef); if (!this.GeneratedShortNames.TryGetValue(symbol.ShortName, out var potentialConflicts)) { @@ -637,7 +637,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind var row = (FileRow)this.CreateRow(symbol, "File"); row.File = symbol.Id.Id; row.Component = symbol.ComponentRef; - row.FileName = GetMsiFilenameValue(symbol.ShortName, name); + row.FileName = CreateMsiFilename(symbol.ShortName, name); row.FileSize = symbol.FileSize; row.Version = symbol.Version; row.Language = symbol.Language; @@ -674,14 +674,14 @@ namespace WixToolset.Core.WindowsInstaller.Bind var tableName = (IniFileActionType.AddLine == symbol.Action || IniFileActionType.AddTag == symbol.Action || IniFileActionType.CreateLine == symbol.Action) ? "IniFile" : "RemoveIniFile"; var name = symbol.FileName; - if (null == symbol.ShortFileName && null != name && !Common.IsValidShortFilename(name, false)) + if (null == symbol.ShortFileName && null != name && !this.BackendHelper.IsValidShortFilename(name, false)) { - symbol.ShortFileName = CreateShortName(name, true, false, "IniFile", symbol.ComponentRef); + symbol.ShortFileName = this.CreateShortName(name, true, "IniFile", symbol.ComponentRef); } var row = this.CreateRow(symbol, tableName); row[0] = symbol.Id.Id; - row[1] = GetMsiFilenameValue(symbol.ShortFileName, name); + row[1] = CreateMsiFilename(symbol.ShortFileName, name); row[2] = symbol.DirProperty; row[3] = symbol.Section; row[4] = symbol.Key; @@ -693,14 +693,14 @@ namespace WixToolset.Core.WindowsInstaller.Bind private void AddIniLocatorSymbol(IniLocatorSymbol symbol) { var name = symbol.FileName; - if (null == symbol.ShortFileName && null != name && !Common.IsValidShortFilename(name, false)) + if (null == symbol.ShortFileName && null != name && !this.BackendHelper.IsValidShortFilename(name, false)) { - symbol.ShortFileName = CreateShortName(name, true, false, "IniFileSearch"); + symbol.ShortFileName = this.CreateShortName(name, true, "IniFileSearch"); } var row = this.CreateRow(symbol, "IniLocator"); row[0] = symbol.Id.Id; - row[1] = GetMsiFilenameValue(symbol.ShortFileName, name); + row[1] = CreateMsiFilename(symbol.ShortFileName, name); row[2] = symbol.Section; row[3] = symbol.Key; row[4] = symbol.Field; @@ -786,16 +786,16 @@ namespace WixToolset.Core.WindowsInstaller.Bind private void AddMoveFileSymbol(MoveFileSymbol symbol) { var name = symbol.DestinationName; - if (null == symbol.DestinationShortName && null != name && !Common.IsValidShortFilename(name, false)) + if (null == symbol.DestinationShortName && null != name && !this.BackendHelper.IsValidShortFilename(name, false)) { - symbol.DestinationShortName = CreateShortName(name, true, false, "MoveFile", symbol.ComponentRef); + symbol.DestinationShortName = this.CreateShortName(name, true, "MoveFile", symbol.ComponentRef); } var row = this.CreateRow(symbol, "MoveFile"); row[0] = symbol.Id.Id; row[1] = symbol.ComponentRef; row[2] = symbol.SourceName; - row[3] = GetMsiFilenameValue(symbol.DestinationShortName, symbol.DestinationName); + row[3] = CreateMsiFilename(symbol.DestinationShortName, symbol.DestinationName); row[4] = symbol.SourceFolder; row[5] = symbol.DestFolder; row[6] = symbol.Delete ? WindowsInstallerConstants.MsidbMoveFileOptionsMove : 0; @@ -816,9 +816,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind private void AddRemoveFileSymbol(RemoveFileSymbol symbol) { var name = symbol.FileName; - if (null == symbol.ShortFileName && null != name && !Common.IsValidShortFilename(name, false)) + if (null == symbol.ShortFileName && null != name && !this.BackendHelper.IsValidShortFilename(name, false)) { - symbol.ShortFileName = CreateShortName(name, true, false, "RemoveFile", symbol.ComponentRef); + symbol.ShortFileName = this.CreateShortName(name, true, "RemoveFile", symbol.ComponentRef); } var installMode = symbol.OnInstall == true ? WindowsInstallerConstants.MsidbRemoveFileInstallModeOnInstall : 0; @@ -827,7 +827,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind var row = this.CreateRow(symbol, "RemoveFile"); row[0] = symbol.Id.Id; row[1] = symbol.ComponentRef; - row[2] = GetMsiFilenameValue(symbol.ShortFileName, symbol.FileName); + row[2] = CreateMsiFilename(symbol.ShortFileName, symbol.FileName); row[3] = symbol.DirPropertyRef; row[4] = installMode; } @@ -966,15 +966,15 @@ namespace WixToolset.Core.WindowsInstaller.Bind private void AddShortcutSymbol(ShortcutSymbol symbol) { var name = symbol.Name; - if (null == symbol.ShortName && null != name && !Common.IsValidShortFilename(name, false)) + if (null == symbol.ShortName && null != name && !this.BackendHelper.IsValidShortFilename(name, false)) { - symbol.ShortName = CreateShortName(name, true, false, "Shortcut", symbol.ComponentRef, symbol.DirectoryRef); + symbol.ShortName = this.CreateShortName(name, true, "Shortcut", symbol.ComponentRef, symbol.DirectoryRef); } var row = this.CreateRow(symbol, "Shortcut"); row[0] = symbol.Id.Id; row[1] = symbol.DirectoryRef; - row[2] = GetMsiFilenameValue(symbol.ShortName, name); + row[2] = CreateMsiFilename(symbol.ShortName, name); row[3] = symbol.ComponentRef; row[4] = symbol.Target; row[5] = symbol.Arguments; @@ -1177,7 +1177,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind } else if (rowField.Column.Category == ColumnCategory.Identifier) { - if (Common.IsIdentifier(data) || Common.IsValidBinderVariable(data) || ColumnCategory.Formatted == rowField.Column.Category) + if (this.BackendHelper.IsValidIdentifier(data) || this.BackendHelper.IsValidBinderVariable(data) || ColumnCategory.Formatted == rowField.Column.Category) { rowField.Data = data; } @@ -1488,19 +1488,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind private Row CreateRow(IntermediateSymbol symbol, TableDefinition tableDefinition) => this.BackendHelper.CreateRow(this.Section, symbol, this.Data, tableDefinition); - private static string GetMsiFilenameValue(string shortName, string longName) - { - if (String.IsNullOrEmpty(shortName) || String.Equals(shortName, longName, StringComparison.OrdinalIgnoreCase)) - { - return longName; - } - else - { - return shortName + "|" + longName; - } - } - private static string CreateShortName(string longName, bool keepExtension, bool allowWildcards, params string[] args) + private string CreateShortName(string longName, bool keepExtension, params string[] args) { longName = longName.ToLowerInvariant(); @@ -1537,7 +1526,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind shortName.Append(extension); // check the generated short name to ensure its still legal (the extension may not be legal) - if (!Common.IsValidShortFilename(shortName.ToString(), allowWildcards)) + if (!this.BackendHelper.IsValidShortFilename(shortName.ToString(), false)) { // remove the extension (by truncating the generated file name back to the generated characters) shortName.Length -= extension.Length; @@ -1546,5 +1535,17 @@ namespace WixToolset.Core.WindowsInstaller.Bind return shortName.ToString().ToLowerInvariant(); } + + private static string CreateMsiFilename(string shortName, string longName) + { + if (String.IsNullOrEmpty(shortName) || String.Equals(shortName, longName, StringComparison.OrdinalIgnoreCase)) + { + return longName; + } + else + { + return shortName + "|" + longName; + } + } } } diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs index e33b38b1..d4de2dd3 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs @@ -11,19 +11,20 @@ namespace WixToolset.Core.WindowsInstaller.Bind using System.Runtime.InteropServices; using WixToolset.Data; using WixToolset.Core.Native; - using WixToolset.Core.Bind; using WixToolset.Data.Symbols; using WixToolset.Extensibility.Services; using WixToolset.Core.WindowsInstaller.Msi; + using WixToolset.Extensibility.Data; /// /// Retrieve files information and extract them from merge modules. /// internal class ExtractMergeModuleFilesCommand { - public ExtractMergeModuleFilesCommand(IMessaging messaging, IEnumerable wixMergeSymbols, IEnumerable fileFacades, int installerVersion, string intermediateFolder, bool suppressLayout) + public ExtractMergeModuleFilesCommand(IMessaging messaging, IWindowsInstallerBackendHelper backendHelper, IEnumerable wixMergeSymbols, IEnumerable fileFacades, int installerVersion, string intermediateFolder, bool suppressLayout) { this.Messaging = messaging; + this.BackendHelper = backendHelper; this.WixMergeSymbols = wixMergeSymbols; this.FileFacades = fileFacades; this.OutputInstallerVersion = installerVersion; @@ -33,9 +34,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind private IMessaging Messaging { get; } + private IWindowsInstallerBackendHelper BackendHelper { get; } + private IEnumerable WixMergeSymbols { get; } - private IEnumerable FileFacades { get; } + private IEnumerable FileFacades { get; } private int OutputInstallerVersion { get; } @@ -43,11 +46,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind private bool SuppressLayout { get; } - public IEnumerable MergeModulesFileFacades { get; private set; } + public IEnumerable MergeModulesFileFacades { get; private set; } public void Execute() { - var mergeModulesFileFacades = new List(); + var mergeModulesFileFacades = new List(); var interop = new MsmInterop(); var merge = interop.GetMsmMerge(); @@ -75,7 +78,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind this.MergeModulesFileFacades = mergeModulesFileFacades; } - private bool CreateFacadesForMergeModuleFiles(WixMergeSymbol wixMergeRow, List mergeModulesFileFacades, Dictionary indexedFileFacades) + private bool CreateFacadesForMergeModuleFiles(WixMergeSymbol wixMergeRow, List mergeModulesFileFacades, Dictionary indexedFileFacades) { var containsFiles = false; @@ -86,7 +89,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind { if (db.TableExists("File") && db.TableExists("Component")) { - var uniqueModuleFileIdentifiers = new Dictionary(StringComparer.OrdinalIgnoreCase); + var uniqueModuleFileIdentifiers = new Dictionary(StringComparer.OrdinalIgnoreCase); using (var view = db.OpenExecuteView("SELECT `File`, `Directory_` FROM `File`, `Component` WHERE `Component_`=`Component`")) { @@ -102,7 +105,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind fileSymbol.DiskId = wixMergeRow.DiskId; fileSymbol.Source = new IntermediateFieldPathValue { Path = Path.Combine(this.IntermediateFolder, wixMergeRow.Id.Id, record[1]) }; - var mergeModuleFileFacade = new FileFacade(true, fileSymbol); + var mergeModuleFileFacade = this.BackendHelper.CreateFileFacadeFromMergeModule(fileSymbol); // If case-sensitive collision with another merge module or a user-authored file identifier. if (indexedFileFacades.TryGetValue(mergeModuleFileFacade.Id, out var collidingFacade)) diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesCommand.cs index c918e866..949d5e18 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesCommand.cs @@ -6,36 +6,45 @@ namespace WixToolset.Core.WindowsInstaller.Bind using System.Collections.Generic; using System.Globalization; using System.Linq; - using WixToolset.Core.Bind; using WixToolset.Data; using WixToolset.Data.Symbols; + using WixToolset.Extensibility.Data; + using WixToolset.Extensibility.Services; internal class GetFileFacadesCommand { - public GetFileFacadesCommand(IntermediateSection section) + public GetFileFacadesCommand(IntermediateSection section, IWindowsInstallerBackendHelper backendHelper) { this.Section = section; + this.BackendHelper = backendHelper; } private IntermediateSection Section { get; } - public List FileFacades { get; private set; } + private IWindowsInstallerBackendHelper BackendHelper { get; } + + public List FileFacades { get; private set; } public void Execute() { - var facades = new List(); + var facades = new List(); var assemblyFile = this.Section.Symbols.OfType().ToDictionary(t => t.Id.Id); +#if TODO_PATCHING_DELTA //var deltaPatchFiles = this.Section.Symbols.OfType().ToDictionary(t => t.Id.Id); +#endif foreach (var file in this.Section.Symbols.OfType()) { assemblyFile.TryGetValue(file.Id.Id, out var assembly); +#if TODO_PATCHING_DELTA //deltaPatchFiles.TryGetValue(file.Id.Id, out var deltaPatchFile); + // TODO: should we be passing along delta information to the file facade? Probably, right? +#endif + var fileFacade = this.BackendHelper.CreateFileFacade(file, assembly); - facades.Add(new FileFacade(file, assembly)); - //facades.Add(new FileFacade(file, wixFile, deltaPatchFile)); + facades.Add(fileFacade); } #if TODO_PATCHING_DELTA diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesFromTransforms.cs b/src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesFromTransforms.cs index 585bdac0..ca074631 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesFromTransforms.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/GetFileFacadesFromTransforms.cs @@ -5,35 +5,35 @@ namespace WixToolset.Core.WindowsInstaller.Bind using System; using System.Collections.Generic; using System.Linq; - using WixToolset.Core.Bind; using WixToolset.Data; using WixToolset.Data.WindowsInstaller; using WixToolset.Data.WindowsInstaller.Rows; - using WixToolset.Extensibility; + using WixToolset.Extensibility.Data; using WixToolset.Extensibility.Services; internal class GetFileFacadesFromTransforms { - public GetFileFacadesFromTransforms(IMessaging messaging, FileSystemManager fileSystemManager, IEnumerable subStorages) + public GetFileFacadesFromTransforms(IMessaging messaging, IWindowsInstallerBackendHelper backendHelper, FileSystemManager fileSystemManager, IEnumerable subStorages) { this.Messaging = messaging; + this.BackendHelper = backendHelper; this.FileSystemManager = fileSystemManager; this.SubStorages = subStorages; } private IMessaging Messaging { get; } + private IWindowsInstallerBackendHelper BackendHelper { get; } + private FileSystemManager FileSystemManager { get; } private IEnumerable SubStorages { get; } - public List FileFacades { get; private set; } + public List FileFacades { get; private set; } public void Execute() { - var allFileRows = new List(); - - var patchMediaRows = new RowDictionary(); + var allFileRows = new List(); var patchMediaFileRows = new Dictionary>(); @@ -143,7 +143,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind mediaFileRows.Add(patchFileRow); - allFileRows.Add(new FileFacade(patchFileRow)); // TODO: should we be passing along delta information? Probably, right? +#if TODO_PATCHING_DELTA + // TODO: should we be passing along delta information to the file facade? Probably, right? +#endif + var fileFacade = this.BackendHelper.CreateFileFacade(patchFileRow); + + allFileRows.Add(fileFacade); } else { diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs index 80684e7c..f8a1efd6 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs @@ -9,12 +9,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind using System.Linq; using System.Runtime.InteropServices; using System.Text; - using WixToolset.Core.Bind; using WixToolset.Core.Native; using WixToolset.Core.WindowsInstaller.Msi; using WixToolset.Data; using WixToolset.Data.Symbols; using WixToolset.Data.WindowsInstaller; + using WixToolset.Extensibility.Data; using WixToolset.Extensibility.Services; /// @@ -22,7 +22,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind /// internal class MergeModulesCommand { - public MergeModulesCommand(IMessaging messaging, IEnumerable fileFacades, IntermediateSection section, IEnumerable suppressedTableNames, string outputPath, string intermediateFolder) + public MergeModulesCommand(IMessaging messaging, IEnumerable fileFacades, IntermediateSection section, IEnumerable suppressedTableNames, string outputPath, string intermediateFolder) { this.Messaging = messaging; this.FileFacades = fileFacades; @@ -34,7 +34,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind private IMessaging Messaging { get; } - private IEnumerable FileFacades { get; } + private IEnumerable FileFacades { get; } private IntermediateSection Section { get; } diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/ModularizeCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/ModularizeCommand.cs index 49ef1adf..04f1b771 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/ModularizeCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/ModularizeCommand.cs @@ -12,11 +12,13 @@ namespace WixToolset.Core.WindowsInstaller.Bind using WixToolset.Data; using WixToolset.Data.Symbols; using WixToolset.Data.WindowsInstaller; + using WixToolset.Extensibility.Services; internal class ModularizeCommand { - public ModularizeCommand(WindowsInstallerData output, string modularizationSuffix, IEnumerable suppressSymbols) + public ModularizeCommand(IBackendHelper backendHelper, WindowsInstallerData output, string modularizationSuffix, IEnumerable suppressSymbols) { + this.BackendHelper = backendHelper; this.Output = output; this.ModularizationSuffix = modularizationSuffix; @@ -24,6 +26,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind this.SuppressModularizationIdentifiers = new HashSet(suppressSymbols.Select(s => s.SuppressIdentifier)); } + private IBackendHelper BackendHelper { get; } + private WindowsInstallerData Output { get; } private string ModularizationSuffix { get; } @@ -90,7 +94,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind case "SetTargetPath": case "SpawnDialog": case "SpawnWaitDialog": - if (Common.IsIdentifier(fieldData)) + if (this.BackendHelper.IsValidIdentifier(fieldData)) { modularizeType = ColumnModularizeType.Column; } @@ -107,7 +111,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind else if (ColumnModularizeType.ControlText == field.Column.ModularizeType) { // icons are stored in the Binary table, so they get column-type modularization - if (("Bitmap" == row[2].ToString() || "Icon" == row[2].ToString()) && Common.IsIdentifier(fieldData)) + if (("Bitmap" == row[2].ToString() || "Icon" == row[2].ToString()) && this.BackendHelper.IsValidIdentifier(fieldData)) { modularizeType = ColumnModularizeType.Column; } @@ -121,7 +125,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind { case ColumnModularizeType.Column: // ensure the value is an identifier (otherwise it shouldn't be modularized this way) - if (!Common.IsIdentifier(fieldData)) + if (!this.BackendHelper.IsValidIdentifier(fieldData)) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixDataStrings.EXP_CannotModularizeIllegalID, fieldData)); } diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/OptimizeFileFacadesOrderCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/OptimizeFileFacadesOrderCommand.cs index 67515154..5dd4d3ea 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/OptimizeFileFacadesOrderCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/OptimizeFileFacadesOrderCommand.cs @@ -5,7 +5,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind using System; using System.Collections.Generic; using System.Linq; - using WixToolset.Core.Bind; using WixToolset.Data; using WixToolset.Data.Symbols; using WixToolset.Extensibility.Data; @@ -13,7 +12,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind internal class OptimizeFileFacadesOrderCommand { - public OptimizeFileFacadesOrderCommand(IBackendHelper helper, IPathResolver pathResolver, IntermediateSection section, Platform platform, List fileFacades) + public OptimizeFileFacadesOrderCommand(IBackendHelper helper, IPathResolver pathResolver, IntermediateSection section, Platform platform, List fileFacades) { this.BackendHelper = helper; this.PathResolver = pathResolver; @@ -22,7 +21,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind this.FileFacades = fileFacades; } - public List FileFacades { get; private set; } + public List FileFacades { get; private set; } private IBackendHelper BackendHelper { get; } @@ -32,7 +31,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind private Platform Platform { get; } - public List Execute() + public List Execute() { var canonicalComponentTargetPaths = this.ComponentTargetPaths(); @@ -69,7 +68,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind return targetPathsByDirectoryId; } - private class FileFacadeOptimizer : IComparer + private class FileFacadeOptimizer : IComparer { public FileFacadeOptimizer(Dictionary componentTargetPaths, bool optimizingMergeModule) { @@ -81,7 +80,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind private bool OptimizingMergeModule { get; } - public int Compare(FileFacade x, FileFacade y) + public int Compare(IFileFacade x, IFileFacade y) { // First group files by DiskId but ignore if processing a Merge Module // because Merge Modules don't have separate disks. diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/ProcessDependencyReferencesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/ProcessDependencyReferencesCommand.cs index 7a7c2649..5ec93f49 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/ProcessDependencyReferencesCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/ProcessDependencyReferencesCommand.cs @@ -17,12 +17,15 @@ namespace WixToolset.Core.WindowsInstaller.Bind private const string DependencyRegistryRoot = @"Software\Classes\Installer\Dependencies\"; private const string RegistryDependents = "Dependents"; - public ProcessDependencyReferencesCommand(IntermediateSection section, IEnumerable dependencyRefSymbols) + public ProcessDependencyReferencesCommand(IBackendHelper backendHelper, IntermediateSection section, IEnumerable dependencyRefSymbols) { + this.BackendHelper = backendHelper; this.Section = section; this.DependencyRefSymbols = dependencyRefSymbols; } + private IBackendHelper BackendHelper { get; } + private IntermediateSection Section { get; } private IEnumerable DependencyRefSymbols { get; } @@ -57,7 +60,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind // Get the component ID from the provider. var componentId = wixDependencyProviderRow.ComponentRef; - var id = Common.GenerateIdentifier("reg", providesId, requiresId, "(Default)"); + var id = this.BackendHelper.GenerateIdentifier("reg", providesId, requiresId, "(Default)"); this.Section.AddSymbol(new RegistrySymbol(wixDependencyRefRow.SourceLineNumbers, new Identifier(AccessModifier.Section, id)) { ComponentRef = componentId, @@ -68,7 +71,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind if (!String.IsNullOrEmpty(wixDependencyRow.MinVersion)) { - id = Common.GenerateIdentifier("reg", providesId, requiresId, "MinVersion"); + id = this.BackendHelper.GenerateIdentifier("reg", providesId, requiresId, "MinVersion"); this.Section.AddSymbol(new RegistrySymbol(wixDependencyRefRow.SourceLineNumbers, new Identifier(AccessModifier.Section, id)) { ComponentRef = componentId, @@ -79,10 +82,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind }); } - string maxVersion = (string)wixDependencyRow[3]; + var maxVersion = (string)wixDependencyRow[3]; if (!String.IsNullOrEmpty(wixDependencyRow.MaxVersion)) { - id = Common.GenerateIdentifier("reg", providesId, requiresId, "MaxVersion"); + id = this.BackendHelper.GenerateIdentifier("reg", providesId, requiresId, "MaxVersion"); this.Section.AddSymbol(new RegistrySymbol(wixDependencyRefRow.SourceLineNumbers, new Identifier(AccessModifier.Section, id)) { ComponentRef = componentId, @@ -95,7 +98,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind if (wixDependencyRow.Attributes != WixDependencySymbolAttributes.None) { - id = Common.GenerateIdentifier("reg", providesId, requiresId, "Attributes"); + id = this.BackendHelper.GenerateIdentifier("reg", providesId, requiresId, "Attributes"); this.Section.AddSymbol(new RegistrySymbol(wixDependencyRefRow.SourceLineNumbers, new Identifier(AccessModifier.Section, id)) { ComponentRef = componentId, diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/ProcessUncompressedFilesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/ProcessUncompressedFilesCommand.cs index ab5ebd4b..8c66a9e1 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/ProcessUncompressedFilesCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/ProcessUncompressedFilesCommand.cs @@ -6,7 +6,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind using System.Collections.Generic; using System.IO; using System.Linq; - using WixToolset.Core.Bind; using WixToolset.Core.WindowsInstaller.Msi; using WixToolset.Data; using WixToolset.Data.Symbols; @@ -33,7 +32,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind public string DatabasePath { private get; set; } - public IEnumerable FileFacades { private get; set; } + public IEnumerable FileFacades { private get; set; } public string LayoutDirectory { private get; set; } @@ -63,7 +62,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind { foreach (var directoryRecord in directoryView.Records) { - var sourceName = Common.GetName(directoryRecord.GetString(3), true, this.LongNamesInImage); + var sourceName = this.BackendHelper.GetMsiFileName(directoryRecord.GetString(3), true, this.LongNamesInImage); var resolvedDirectory = this.BackendHelper.CreateResolvedDirectory(directoryRecord.GetString(2), sourceName); @@ -71,16 +70,16 @@ namespace WixToolset.Core.WindowsInstaller.Bind } } - using (View fileView = db.OpenView("SELECT `Directory_`, `FileName` FROM `Component`, `File` WHERE `Component`.`Component`=`File`.`Component_` AND `File`.`File`=?")) + using (var fileView = db.OpenView("SELECT `Directory_`, `FileName` FROM `Component`, `File` WHERE `Component`.`Component`=`File`.`Component_` AND `File`.`File`=?")) { - using (Record fileQueryRecord = new Record(1)) + using (var fileQueryRecord = new Record(1)) { // for each file in the array of uncompressed files - foreach (FileFacade facade in this.FileFacades) + foreach (var facade in this.FileFacades) { var mediaSymbol = mediaRows[facade.DiskId]; string relativeFileLayoutPath = null; - string mediaLayoutFolder = mediaSymbol.Layout; + var mediaLayoutFolder = mediaSymbol.Layout; var mediaLayoutDirectory = this.ResolveMedia(mediaSymbol, mediaLayoutFolder, this.LayoutDirectory); @@ -89,7 +88,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind fileQueryRecord[1] = facade.Id; fileView.Execute(fileQueryRecord); - using (Record fileRecord = fileView.Fetch()) + using (var fileRecord = fileView.Fetch()) { if (null == fileRecord) { diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs index f8819a0e..9cd14cfa 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs @@ -8,10 +8,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind using System.Globalization; using System.IO; using System.Linq; - using WixToolset.Core.Bind; using WixToolset.Core.WindowsInstaller.Msi; using WixToolset.Data; using WixToolset.Data.Symbols; + using WixToolset.Extensibility.Data; using WixToolset.Extensibility.Services; /// @@ -19,7 +19,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind /// internal class UpdateFileFacadesCommand { - public UpdateFileFacadesCommand(IMessaging messaging, IntermediateSection section, IEnumerable fileFacades, IEnumerable updateFileFacades, IDictionary variableCache, bool overwriteHash) + public UpdateFileFacadesCommand(IMessaging messaging, IntermediateSection section, IEnumerable fileFacades, IEnumerable updateFileFacades, IDictionary variableCache, bool overwriteHash) { this.Messaging = messaging; this.Section = section; @@ -33,9 +33,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind private IntermediateSection Section { get; } - private IEnumerable FileFacades { get; } + private IEnumerable FileFacades { get; } - private IEnumerable UpdateFileFacades { get; } + private IEnumerable UpdateFileFacades { get; } private bool OverwriteHash { get; } @@ -51,7 +51,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind } } - private void UpdateFileFacade(FileFacade facade, Dictionary assemblyNameSymbols) + private void UpdateFileFacade(IFileFacade facade, Dictionary assemblyNameSymbols) { FileInfo fileInfo = null; try @@ -314,7 +314,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind /// FileFacade containing the assembly read for the MsiAssemblyName row. /// MsiAssemblyName name. /// MsiAssemblyName value. - private void SetMsiAssemblyName(Dictionary assemblyNameSymbols, FileFacade facade, string name, string value) + private void SetMsiAssemblyName(Dictionary assemblyNameSymbols, IFileFacade facade, string name, string value) { // check for null value (this can occur when grabbing the file version from an assembly without one) if (String.IsNullOrEmpty(value)) diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/UpdateMediaSequencesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/UpdateMediaSequencesCommand.cs index d3f2b9ea..affec09f 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/UpdateMediaSequencesCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/UpdateMediaSequencesCommand.cs @@ -4,13 +4,13 @@ namespace WixToolset.Core.WindowsInstaller.Bind { using System.Collections.Generic; using System.Linq; - using WixToolset.Core.Bind; using WixToolset.Data; using WixToolset.Data.Symbols; + using WixToolset.Extensibility.Data; internal class UpdateMediaSequencesCommand { - public UpdateMediaSequencesCommand(IntermediateSection section, List fileFacades) + public UpdateMediaSequencesCommand(IntermediateSection section, IEnumerable fileFacades) { this.Section = section; this.FileFacades = fileFacades; @@ -18,7 +18,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind private IntermediateSection Section { get; } - private List FileFacades { get; } + private IEnumerable FileFacades { get; } public void Execute() { @@ -38,9 +38,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind { var lastSequence = 0; MediaSymbol mediaSymbol = null; - var patchGroups = new Dictionary>(); + var patchGroups = new Dictionary>(); - // sequence the non-patch-added files + // Sequence the non-patch-added files. foreach (var facade in this.FileFacades) { if (null == mediaSymbol) @@ -62,7 +62,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind { if (patchGroups.TryGetValue(facade.PatchGroup.Value, out var patchGroup)) { - patchGroup = new List(); + patchGroup = new List(); patchGroups.Add(facade.PatchGroup.Value, patchGroup); } @@ -80,7 +80,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind mediaSymbol = null; } - // sequence the patch-added files + // Sequence the patch-added files. foreach (var patchGroup in patchGroups.Values) { foreach (var facade in patchGroup) diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/UpdateTransformsWithFileFacades.cs b/src/WixToolset.Core.WindowsInstaller/Bind/UpdateTransformsWithFileFacades.cs index 4e716a47..981fa0a4 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/UpdateTransformsWithFileFacades.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/UpdateTransformsWithFileFacades.cs @@ -5,16 +5,16 @@ namespace WixToolset.Core.WindowsInstaller.Bind using System; using System.Collections.Generic; using System.Linq; - using WixToolset.Core.Bind; using WixToolset.Data; using WixToolset.Data.Symbols; using WixToolset.Data.WindowsInstaller; using WixToolset.Data.WindowsInstaller.Rows; + using WixToolset.Extensibility.Data; using WixToolset.Extensibility.Services; internal class UpdateTransformsWithFileFacades { - public UpdateTransformsWithFileFacades(IMessaging messaging, WindowsInstallerData output, IEnumerable subStorages, TableDefinitionCollection tableDefinitions, IEnumerable fileFacades) + public UpdateTransformsWithFileFacades(IMessaging messaging, WindowsInstallerData output, IEnumerable subStorages, TableDefinitionCollection tableDefinitions, IEnumerable fileFacades) { this.Messaging = messaging; this.Output = output; @@ -31,18 +31,18 @@ namespace WixToolset.Core.WindowsInstaller.Bind private TableDefinitionCollection TableDefinitions { get; } - private IEnumerable FileFacades { get; } + private IEnumerable FileFacades { get; } public void Execute() { - var fileFacadesByDiskId = new Dictionary>(); + var fileFacadesByDiskId = new Dictionary>(); // Index patch file facades by diskId+fileId. foreach (var facade in this.FileFacades) { if (!fileFacadesByDiskId.TryGetValue(facade.DiskId, out var mediaFacades)) { - mediaFacades = new Dictionary(); + mediaFacades = new Dictionary(); fileFacadesByDiskId.Add(facade.DiskId, mediaFacades); } @@ -97,7 +97,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind // Index patch files by diskId+fileId if (!fileFacadesByDiskId.TryGetValue(mainFileRow.DiskId, out var mediaFacades)) { - mediaFacades = new Dictionary(); + mediaFacades = new Dictionary(); fileFacadesByDiskId.Add(mainFileRow.DiskId, mediaFacades); } diff --git a/src/WixToolset.Core.WindowsInstaller/Data/Xsd/actions.xsd b/src/WixToolset.Core.WindowsInstaller/Data/Xsd/actions.xsd deleted file mode 100644 index bf0ccb95..00000000 --- a/src/WixToolset.Core.WindowsInstaller/Data/Xsd/actions.xsd +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - Schema for describing standard actions in the Windows Installer. - - - - - - - - - - - - - - - - Name of action - - - - - Default condition for action - - - - - Sequence of action - - - - - Specifies if action is allowed in AdminExecuteSequence - - - - - Specifies if action is allowed in AdminUISequence - - - - - Specifies if action is allowed in AdvtExecuteSequence - - - - - Specifies if action is allowed in InstallExecuteSequence - - - - - Specifies if action is allowed in InstallUISequence - - - - - - - - - - - - diff --git a/src/WixToolset.Core.WindowsInstaller/Data/Xsd/tables.xsd b/src/WixToolset.Core.WindowsInstaller/Data/Xsd/tables.xsd deleted file mode 100644 index f87471bb..00000000 --- a/src/WixToolset.Core.WindowsInstaller/Data/Xsd/tables.xsd +++ /dev/null @@ -1,248 +0,0 @@ - - - - - - - - Schema for describing table definitions in Windows Installer. - - - - - - - - - - - - - - - - - - - Boolean whether rows in this table create symbols - - - - - Name of table in Windows Installer database - - - - - Specifies if table is virtual or not - - - - - Specifies if the table is a part of the Bootstrapper Application Data manifest - - - - - - - - - - Name of column in Windows Installer table - - - - - - Whether this column was added by a transform. - - - - - - Type of column in Windows Installer table - - - - - - Type of column in Windows Installer table - - - - - - - - - - - - Boolean whether column is primary key of Windows Installer table - - - - - - Boolean whether column is nullable in Windows Installer table - - - - - - Boolean whether column is virtual in Windows Installer table - - - - - - Enumeration specifying how column should have the ModuleId appended - - - - - - Set to "yes" in order to allow substitution for localized variables. - - - - - - Minimum value for column in Windows Installer table - - - - - - Maximum value for column in Windows Installer table - - - - - - Foreign key table for column in Windows Installer table - - - - - - Maximum value for column in Windows Installer table - - - - - - - - - - - - Specific column data types for column - - - - - - List of permissible values for the column - - - - - - Description of column - - - - - - Set to "yes" in order to make the idt exporter escape whitespace characters \r, \n, and \t. - - - - - - Set to "yes" in order to make the Intermediate and Output objects wrap their data in a CDATA element to preserve whitespace. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/WixToolset.Core.WindowsInstaller/Decompile/DecompileMsiOrMsmCommand.cs b/src/WixToolset.Core.WindowsInstaller/Decompile/DecompileMsiOrMsmCommand.cs index 45b669b9..849cb361 100644 --- a/src/WixToolset.Core.WindowsInstaller/Decompile/DecompileMsiOrMsmCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Decompile/DecompileMsiOrMsmCommand.cs @@ -1,6 +1,6 @@ // 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. -namespace WixToolset.Core.WindowsInstaller.Unbind +namespace WixToolset.Core.WindowsInstaller.Decompile { using System; using System.Collections.Generic; @@ -8,6 +8,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind using System.IO; using System.Linq; using WixToolset.Core.WindowsInstaller.Msi; + using WixToolset.Core.WindowsInstaller.Unbind; using WixToolset.Data; using WixToolset.Data.WindowsInstaller; using WixToolset.Extensibility; @@ -43,11 +44,13 @@ namespace WixToolset.Core.WindowsInstaller.Unbind Directory.Delete(this.Context.ExtractFolder, true); } - 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); + var backendHelper = this.Context.ServiceProvider.GetService(); + + 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); var output = unbindCommand.Execute(); var extractedFilePaths = new List(unbindCommand.ExportedFiles); - var decompiler = new Decompiler(this.Messaging, this.Extensions, this.Context.BaseSourcePath, this.Context.SuppressCustomTables, this.Context.SuppressDroppingEmptyTables, this.Context.SuppressUI, this.Context.TreatProductAsModule); + var decompiler = new Decompiler(this.Messaging, backendHelper, this.Extensions, this.Context.BaseSourcePath, this.Context.SuppressCustomTables, this.Context.SuppressDroppingEmptyTables, this.Context.SuppressUI, this.Context.TreatProductAsModule); result.Document = decompiler.Decompile(output); result.Platform = GetPlatformFromOutput(output); diff --git a/src/WixToolset.Core.WindowsInstaller/Decompile/Decompiler.cs b/src/WixToolset.Core.WindowsInstaller/Decompile/Decompiler.cs index 2cc61666..8e477dd1 100644 --- a/src/WixToolset.Core.WindowsInstaller/Decompile/Decompiler.cs +++ b/src/WixToolset.Core.WindowsInstaller/Decompile/Decompiler.cs @@ -1,6 +1,6 @@ // 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. -namespace WixToolset.Core.WindowsInstaller +namespace WixToolset.Core.WindowsInstaller.Decompile { using System; using System.Collections.Generic; @@ -10,8 +10,6 @@ namespace WixToolset.Core.WindowsInstaller using System.Text; using System.Text.RegularExpressions; using System.Xml.Linq; - using WixToolset.Core; - using WixToolset.Core.WindowsInstaller.Decompile; using WixToolset.Data; using WixToolset.Data.Symbols; using WixToolset.Data.WindowsInstaller; @@ -45,9 +43,10 @@ namespace WixToolset.Core.WindowsInstaller /// /// Creates a new decompiler object with a default set of table definitions. /// - public Decompiler(IMessaging messaging, IEnumerable extensions, string baseSourcePath, bool suppressCustomTables, bool suppressDroppingEmptyTables, bool suppressUI, bool treatProductAsModule) + public Decompiler(IMessaging messaging, IBackendHelper backendHelper, IEnumerable extensions, string baseSourcePath, bool suppressCustomTables, bool suppressDroppingEmptyTables, bool suppressUI, bool treatProductAsModule) { this.Messaging = messaging; + this.BackendHelper = backendHelper; this.Extensions = extensions; this.BaseSourcePath = baseSourcePath ?? "SourceDir"; this.SuppressCustomTables = suppressCustomTables; @@ -63,6 +62,8 @@ namespace WixToolset.Core.WindowsInstaller private IMessaging Messaging { get; } + private IBackendHelper BackendHelper { get; } + private IEnumerable Extensions { get; } private Dictionary ExtensionsByTableName { get; } @@ -2196,11 +2197,11 @@ namespace WixToolset.Core.WindowsInstaller { foreach (var launchRow in launchConditionTable.Rows) { - if (Common.DowngradePreventedCondition == Convert.ToString(launchRow[0])) + if (WixUpgradeConstants.DowngradePreventedCondition == Convert.ToString(launchRow[0])) { downgradeErrorMessage = Convert.ToString(launchRow[1]); } - else if (Common.UpgradePreventedCondition == Convert.ToString(launchRow[0])) + else if (WixUpgradeConstants.UpgradePreventedCondition == Convert.ToString(launchRow[0])) { disallowUpgradeErrorMessage = Convert.ToString(launchRow[1]); } @@ -2213,7 +2214,7 @@ namespace WixToolset.Core.WindowsInstaller foreach (UpgradeRow upgradeRow in upgradeTable.Rows) { - if (Common.UpgradeDetectedProperty == upgradeRow.ActionProperty) + if (WixUpgradeConstants.UpgradeDetectedProperty == upgradeRow.ActionProperty) { var attr = upgradeRow.Attributes; var removeFeatures = upgradeRow.Remove; @@ -2239,7 +2240,7 @@ namespace WixToolset.Core.WindowsInstaller xMajorUpgrade.SetAttributeValue("RemoveFeatures", removeFeatures); } } - else if (Common.DowngradeDetectedProperty == upgradeRow.ActionProperty) + else if (WixUpgradeConstants.DowngradeDetectedProperty == upgradeRow.ActionProperty) { xMajorUpgrade = xMajorUpgrade ?? new XElement(Names.MajorUpgradeElement); xMajorUpgrade.SetAttributeValue("DowngradeErrorMessage", downgradeErrorMessage); @@ -4291,7 +4292,7 @@ namespace WixToolset.Core.WindowsInstaller var xDirectory = new XElement(Names.DirectoryElement, new XAttribute("Id", id)); - var names = Common.GetNames(row.FieldAsString(2)); + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(2)); if (String.Equals(id, "TARGETDIR", StringComparison.Ordinal) && !String.Equals(names[0], "SourceDir", StringComparison.Ordinal)) { @@ -4396,7 +4397,7 @@ namespace WixToolset.Core.WindowsInstaller if (!row.IsColumnNull(3)) { - var names = Common.GetNames(row.FieldAsString(3)); + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(3)); if (null != names[0] && null != names[1]) { xCopyFile.SetAttributeValue("DestinationShortName", names[0]); @@ -4782,7 +4783,7 @@ namespace WixToolset.Core.WindowsInstaller WindowsInstallerConstants.MsidbFileAttributesVital != (fileRow.Attributes & WindowsInstallerConstants.MsidbFileAttributesVital) ? new XAttribute("Vital", "no") : null, null != fileRow.Version && 0 < fileRow.Version.Length && !Char.IsDigit(fileRow.Version[0]) ? new XAttribute("CompanionFile", fileRow.Version) : null); - var names = Common.GetNames(fileRow.FileName); + var names = this.BackendHelper.SplitMsiFileName(fileRow.FileName); if (null != names[0] && null != names[1]) { xFile.SetAttributeValue("ShortName", names[0]); @@ -4904,7 +4905,7 @@ namespace WixToolset.Core.WindowsInstaller new XAttribute("Value", row.FieldAsString(5)), row.IsColumnNull(2) ? null : new XAttribute("Directory", row.FieldAsString(2))); - var names = Common.GetNames(row.FieldAsString(1)); + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(1)); if (null != names[0]) { @@ -4957,7 +4958,7 @@ namespace WixToolset.Core.WindowsInstaller new XAttribute("Key", row.FieldAsString(3)), row.IsColumnNull(4) || row.FieldAsInteger(4) == 0 ? null : new XAttribute("Field", row.FieldAsInteger(4))); - var names = Common.GetNames(row.FieldAsString(1)); + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(1)); if (null != names[0] && null != names[1]) { xIniFileSearch.SetAttributeValue("ShortName", names[0]); @@ -5014,7 +5015,7 @@ namespace WixToolset.Core.WindowsInstaller { foreach (var row in table.Rows) { - if (Common.DowngradePreventedCondition == row.FieldAsString(0) || Common.UpgradePreventedCondition == row.FieldAsString(0)) + if (WixUpgradeConstants.DowngradePreventedCondition == row.FieldAsString(0) || WixUpgradeConstants.UpgradePreventedCondition == row.FieldAsString(0)) { continue; // MajorUpgrade rows processed in FinalizeUpgradeTable } @@ -5101,13 +5102,13 @@ namespace WixToolset.Core.WindowsInstaller switch (row.FieldAsString(1)) { case "CreateFolder": - specialPermissions = Common.FolderPermissions; + specialPermissions = LockPermissionConstants.FolderPermissions; break; case "File": - specialPermissions = Common.FilePermissions; + specialPermissions = LockPermissionConstants.FilePermissions; break; case "Registry": - specialPermissions = Common.RegistryPermissions; + specialPermissions = LockPermissionConstants.RegistryPermissions; break; default: 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 { name = "SpecificRightsAll"; } - else if (28 > i && Common.StandardPermissions.Length > (i - 16)) + else if (28 > i && LockPermissionConstants.StandardPermissions.Length > (i - 16)) { - name = Common.StandardPermissions[i - 16]; + name = LockPermissionConstants.StandardPermissions[i - 16]; } - else if (0 <= (i - 28) && Common.GenericPermissions.Length > (i - 28)) + else if (0 <= (i - 28) && LockPermissionConstants.GenericPermissions.Length > (i - 28)) { - name = Common.GenericPermissions[i - 28]; + name = LockPermissionConstants.GenericPermissions[i - 28]; } if (null == name) @@ -5412,7 +5413,7 @@ namespace WixToolset.Core.WindowsInstaller if (!row.IsColumnNull(3)) { - var names = Common.GetNames(row.FieldAsString(3)); + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(3)); if (null != names[0] && null != names[1]) { xCopyFile.SetAttributeValue("DestinationShortName", names[0]); @@ -5922,17 +5923,17 @@ namespace WixToolset.Core.WindowsInstaller case "OptimizeCA": var xOptimizeCustomActions = new XElement(Names.OptimizeCustomActionsElement); var optimizeCA = Int32.Parse(value, CultureInfo.InvariantCulture); - if (0 != (Convert.ToInt32(OptimizeCA.SkipAssignment) & optimizeCA)) + if (0 != (Convert.ToInt32(OptimizeCAFlags.SkipAssignment) & optimizeCA)) { xOptimizeCustomActions.SetAttributeValue("SkipAssignment", "yes"); } - if (0 != (Convert.ToInt32(OptimizeCA.SkipImmediate) & optimizeCA)) + if (0 != (Convert.ToInt32(OptimizeCAFlags.SkipImmediate) & optimizeCA)) { xOptimizeCustomActions.SetAttributeValue("SkipImmediate", "yes"); } - if (0 != (Convert.ToInt32(OptimizeCA.SkipDeferred) & optimizeCA)) + if (0 != (Convert.ToInt32(OptimizeCAFlags.SkipDeferred) & optimizeCA)) { xOptimizeCustomActions.SetAttributeValue("SkipDeferred", "yes"); } @@ -6165,7 +6166,7 @@ namespace WixToolset.Core.WindowsInstaller { foreach (var propertyId in value.Split(';')) { - if (Common.DowngradeDetectedProperty == propertyId || Common.UpgradeDetectedProperty == propertyId) + if (WixUpgradeConstants.DowngradeDetectedProperty == propertyId || WixUpgradeConstants.UpgradeDetectedProperty == propertyId) { continue; } @@ -6547,7 +6548,7 @@ namespace WixToolset.Core.WindowsInstaller var xRemoveFile = new XElement(Names.RemoveFileElement, new XAttribute("Id", row.FieldAsString(0))); - var names = Common.GetNames(row.FieldAsString(2)); + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(2)); if (null != names[0] && null != names[1]) { xRemoveFile.SetAttributeValue("ShortName", names[0]); @@ -6597,7 +6598,7 @@ namespace WixToolset.Core.WindowsInstaller new XAttribute("Key", row.FieldAsString(4)), XAttributeIfNotNull("Value", row, 5)); - var names = Common.GetNames(row.FieldAsString(1)); + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(1)); if (null != names[0] && null != names[1]) { xIniFile.SetAttributeValue("ShortName", names[0]); @@ -6941,7 +6942,7 @@ namespace WixToolset.Core.WindowsInstaller XAttributeIfNotNull("IconIndex", row, 9), XAttributeIfNotNull("WorkingDirectory", row, 11)); - var names = Common.GetNames(row.FieldAsString(2)); + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(2)); if (null != names[0] && null != names[1]) { xShortcut.SetAttributeValue("ShortName", names[0]); @@ -7016,11 +7017,11 @@ namespace WixToolset.Core.WindowsInstaller XAttributeIfNotNull("MaxSize", row, 5), XAttributeIfNotNull("Languages", row, 8)); - var names = Common.GetNames(row.FieldAsString(1)); + var names = this.BackendHelper.SplitMsiFileName(row.FieldAsString(1)); if (null != names[0]) { // it is permissable to just have a long name - if (!Common.IsValidShortFilename(names[0], false) && null == names[1]) + if (!this.BackendHelper.IsValidShortFilename(names[0], false) && null == names[1]) { fileSearch.SetAttributeValue("Name", names[0]); } @@ -7248,7 +7249,7 @@ namespace WixToolset.Core.WindowsInstaller foreach (UpgradeRow upgradeRow in table.Rows) { - if (Common.UpgradeDetectedProperty == upgradeRow.ActionProperty || Common.DowngradeDetectedProperty == upgradeRow.ActionProperty) + if (WixUpgradeConstants.UpgradeDetectedProperty == upgradeRow.ActionProperty || WixUpgradeConstants.DowngradeDetectedProperty == upgradeRow.ActionProperty) { continue; // MajorUpgrade rows processed in FinalizeUpgradeTable } diff --git a/src/WixToolset.Core.WindowsInstaller/ExtensibilityServices/WindowsInstallerBackendHelper.cs b/src/WixToolset.Core.WindowsInstaller/ExtensibilityServices/WindowsInstallerBackendHelper.cs index 09194d4e..18060ca7 100644 --- a/src/WixToolset.Core.WindowsInstaller/ExtensibilityServices/WindowsInstallerBackendHelper.cs +++ b/src/WixToolset.Core.WindowsInstaller/ExtensibilityServices/WindowsInstallerBackendHelper.cs @@ -3,9 +3,12 @@ namespace WixToolset.Core.WindowsInstaller.ExtensibilityServices { using System; + using System.Collections.Generic; using System.Linq; using WixToolset.Data; + using WixToolset.Data.Symbols; using WixToolset.Data.WindowsInstaller; + using WixToolset.Data.WindowsInstaller.Rows; using WixToolset.Extensibility.Data; using WixToolset.Extensibility.Services; @@ -20,14 +23,44 @@ namespace WixToolset.Core.WindowsInstaller.ExtensibilityServices #region IBackendHelper interfaces + public IFileFacade CreateFileFacade(FileSymbol file, AssemblySymbol assembly) => this.backendHelper.CreateFileFacade(file, assembly); + + public IFileFacade CreateFileFacade(FileRow fileRow) => this.backendHelper.CreateFileFacade(fileRow); + + public IFileFacade CreateFileFacadeFromMergeModule(FileSymbol fileSymbol) => this.backendHelper.CreateFileFacadeFromMergeModule(fileSymbol); + public IFileTransfer CreateFileTransfer(string source, string destination, bool move, SourceLineNumber sourceLineNumbers = null) => this.backendHelper.CreateFileTransfer(source, destination, move, sourceLineNumbers); + public string CreateGuid() => this.backendHelper.CreateGuid(); + public string CreateGuid(Guid namespaceGuid, string value) => this.backendHelper.CreateGuid(namespaceGuid, value); public IResolvedDirectory CreateResolvedDirectory(string directoryParent, string name) => this.backendHelper.CreateResolvedDirectory(directoryParent, name); + public IEnumerable ExtractEmbeddedFiles(IEnumerable embeddedFiles) => this.backendHelper.ExtractEmbeddedFiles(embeddedFiles); + + public string GenerateIdentifier(string prefix, params string[] args) => this.backendHelper.GenerateIdentifier(prefix, args); + public string GetCanonicalRelativePath(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string relativePath) => this.backendHelper.GetCanonicalRelativePath(sourceLineNumbers, elementName, attributeName, relativePath); + public int GetValidCodePage(string value, bool allowNoChange, bool onlyAnsi = false, SourceLineNumber sourceLineNumbers = null) => this.backendHelper.GetValidCodePage(value, allowNoChange, onlyAnsi, sourceLineNumbers); + + public string GetMsiFileName(string value, bool source, bool longName) => this.backendHelper.GetMsiFileName(value, source, longName); + + public bool IsValidBinderVariable(string variable) => this.backendHelper.IsValidBinderVariable(variable); + + public bool IsValidFourPartVersion(string version) => this.backendHelper.IsValidFourPartVersion(version); + + public bool IsValidIdentifier(string id) => this.backendHelper.IsValidIdentifier(id); + + public bool IsValidLongFilename(string filename, bool allowWildcards, bool allowRelative) => this.backendHelper.IsValidLongFilename(filename, allowWildcards, allowRelative); + + public bool IsValidShortFilename(string filename, bool allowWildcards) => this.backendHelper.IsValidShortFilename(filename, allowWildcards); + + public void ResolveDelayedFields(IEnumerable delayedFields, Dictionary variableCache) => this.backendHelper.ResolveDelayedFields(delayedFields, variableCache); + + public string[] SplitMsiFileName(string value) => this.backendHelper.SplitMsiFileName(value); + public ITrackedFile TrackFile(string path, TrackedFileType type, SourceLineNumber sourceLineNumbers = null) => this.backendHelper.TrackFile(path, type, sourceLineNumbers); #endregion diff --git a/src/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs b/src/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs index 256d3476..19869cfa 100644 --- a/src/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs @@ -21,6 +21,7 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe { this.Context = context; this.Messaging = context.ServiceProvider.GetService(); + this.WindowsInstallerBackendHelper = context.ServiceProvider.GetService(); this.TableDefinitions = new TableDefinitionCollection(WindowsInstallerTableDefinitions.All); } @@ -28,6 +29,8 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe private IMessaging Messaging { get; } + private IWindowsInstallerBackendHelper WindowsInstallerBackendHelper { get; } + private TableDefinitionCollection TableDefinitions { get; } public bool Execute() @@ -197,7 +200,7 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe if (!certificates.ContainsKey(cert2.Thumbprint)) { // generate a stable identifier - var certificateGeneratedId = Common.GenerateIdentifier("cer", cert2.Thumbprint); + var certificateGeneratedId = this.WindowsInstallerBackendHelper.GenerateIdentifier("cer", cert2.Thumbprint); // Add it to our "add to MsiDigitalCertificate" table dictionary var digitalCertificateRow = digitalCertificateTable.CreateRow(null); diff --git a/src/WixToolset.Core.WindowsInstaller/Melter.cs b/src/WixToolset.Core.WindowsInstaller/Melter.cs index 4e4d9e4e..29e19e49 100644 --- a/src/WixToolset.Core.WindowsInstaller/Melter.cs +++ b/src/WixToolset.Core.WindowsInstaller/Melter.cs @@ -18,7 +18,7 @@ namespace WixToolset /// public sealed class Melter { -#if TODO +#if TODO_MELT private MelterCore core; private Decompiler decompiler; diff --git a/src/WixToolset.Core.WindowsInstaller/MsiBackend.cs b/src/WixToolset.Core.WindowsInstaller/MsiBackend.cs index cbd58381..a6cf4f60 100644 --- a/src/WixToolset.Core.WindowsInstaller/MsiBackend.cs +++ b/src/WixToolset.Core.WindowsInstaller/MsiBackend.cs @@ -3,6 +3,7 @@ namespace WixToolset.Core.WindowsInstaller { using WixToolset.Core.WindowsInstaller.Bind; + using WixToolset.Core.WindowsInstaller.Decompile; using WixToolset.Core.WindowsInstaller.Inscribe; using WixToolset.Core.WindowsInstaller.Unbind; using WixToolset.Data; diff --git a/src/WixToolset.Core.WindowsInstaller/MsmBackend.cs b/src/WixToolset.Core.WindowsInstaller/MsmBackend.cs index 4860bf81..96197d44 100644 --- a/src/WixToolset.Core.WindowsInstaller/MsmBackend.cs +++ b/src/WixToolset.Core.WindowsInstaller/MsmBackend.cs @@ -3,6 +3,7 @@ namespace WixToolset.Core.WindowsInstaller { using WixToolset.Core.WindowsInstaller.Bind; + using WixToolset.Core.WindowsInstaller.Decompile; using WixToolset.Core.WindowsInstaller.Unbind; using WixToolset.Data; using WixToolset.Extensibility; diff --git a/src/WixToolset.Core.WindowsInstaller/MspBackend.cs b/src/WixToolset.Core.WindowsInstaller/MspBackend.cs index 46ff7aa3..1caa9e29 100644 --- a/src/WixToolset.Core.WindowsInstaller/MspBackend.cs +++ b/src/WixToolset.Core.WindowsInstaller/MspBackend.cs @@ -22,6 +22,8 @@ namespace WixToolset.Core.WindowsInstaller { var messaging = context.ServiceProvider.GetService(); + var backendHelper = context.ServiceProvider.GetService(); + var extensionManager = context.ServiceProvider.GetService(); var backendExtensions = extensionManager.GetServices(); @@ -34,14 +36,14 @@ namespace WixToolset.Core.WindowsInstaller // Create transforms named in patch transforms. IEnumerable patchTransforms; { - var command = new CreatePatchTransformsCommand(messaging, context.IntermediateRepresentation, context.IntermediateFolder); + var command = new CreatePatchTransformsCommand(messaging, backendHelper, context.IntermediateRepresentation, context.IntermediateFolder); patchTransforms = command.Execute(); } // Enhance the intermediate by attaching the created patch transforms. IEnumerable subStorages; { - var command = new AttachPatchTransformsCommand(messaging, context.IntermediateRepresentation, patchTransforms); + var command = new AttachPatchTransformsCommand(messaging, backendHelper, context.IntermediateRepresentation, patchTransforms); subStorages = command.Execute(); } diff --git a/src/WixToolset.Core.WindowsInstaller/PatchAPI/PatchInterop.cs b/src/WixToolset.Core.WindowsInstaller/PatchAPI/PatchInterop.cs index fcd749d2..3874d8e7 100644 --- a/src/WixToolset.Core.WindowsInstaller/PatchAPI/PatchInterop.cs +++ b/src/WixToolset.Core.WindowsInstaller/PatchAPI/PatchInterop.cs @@ -7,7 +7,7 @@ namespace WixToolset.PatchAPI using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.InteropServices; - using WixToolset.Core; + using WixToolset.Data.Symbols; /// /// Interop class for the mspatchc.dll. @@ -25,7 +25,7 @@ namespace WixToolset.PatchAPI static internal UInt32 ParseHexOrDecimal(string source) { string value = source.Trim(); - if (String.Equals(value.Substring(0,2), "0x", StringComparison.OrdinalIgnoreCase)) + if (String.Equals(value.Substring(0, 2), "0x", StringComparison.OrdinalIgnoreCase)) { return UInt32.Parse(value.Substring(2), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture.NumberFormat); } @@ -63,13 +63,13 @@ namespace WixToolset.PatchAPI string[] basisIgnoreOffsets, string[] basisRetainLengths, string[] basisRetainOffsets, - PatchSymbolFlagsType apiPatchingSymbolFlags, + PatchSymbolFlags apiPatchingSymbolFlags, bool optimizePatchSizeForLargeFiles, out bool retainRangesIgnored ) { retainRangesIgnored = false; - if (0 != (apiPatchingSymbolFlags & ~(PatchSymbolFlagsType.PATCH_SYMBOL_NO_IMAGEHLP | PatchSymbolFlagsType.PATCH_SYMBOL_NO_FAILURES | PatchSymbolFlagsType.PATCH_SYMBOL_UNDECORATED_TOO))) + if (0 != (apiPatchingSymbolFlags & ~(PatchSymbolFlags.PatchSymbolNoImagehlp | PatchSymbolFlags.PatchSymbolNoFailures | PatchSymbolFlags.PatchSymbolUndecoratedToo))) { throw new ArgumentOutOfRangeException("apiPatchingSymbolFlags"); } @@ -88,13 +88,13 @@ namespace WixToolset.PatchAPI { return false; } - uint countOldFiles = (uint) basisFiles.Length; + uint countOldFiles = (uint)basisFiles.Length; if (null != basisSymbolPaths) { if (0 != basisSymbolPaths.Length) { - if ((uint) basisSymbolPaths.Length != countOldFiles) + if ((uint)basisSymbolPaths.Length != countOldFiles) { throw new ArgumentOutOfRangeException("basisSymbolPaths"); } @@ -106,7 +106,7 @@ namespace WixToolset.PatchAPI { if (0 != basisIgnoreLengths.Length) { - if ((uint) basisIgnoreLengths.Length != countOldFiles) + if ((uint)basisIgnoreLengths.Length != countOldFiles) { throw new ArgumentOutOfRangeException("basisIgnoreLengths"); } @@ -121,7 +121,7 @@ namespace WixToolset.PatchAPI { if (0 != basisIgnoreOffsets.Length) { - if ((uint) basisIgnoreOffsets.Length != countOldFiles) + if ((uint)basisIgnoreOffsets.Length != countOldFiles) { throw new ArgumentOutOfRangeException("basisIgnoreOffsets"); } @@ -136,7 +136,7 @@ namespace WixToolset.PatchAPI { if (0 != basisRetainLengths.Length) { - if ((uint) basisRetainLengths.Length != countOldFiles) + if ((uint)basisRetainLengths.Length != countOldFiles) { throw new ArgumentOutOfRangeException("basisRetainLengths"); } @@ -151,7 +151,7 @@ namespace WixToolset.PatchAPI { if (0 != basisRetainOffsets.Length) { - if ((uint) basisRetainOffsets.Length != countOldFiles) + if ((uint)basisRetainOffsets.Length != countOldFiles) { throw new ArgumentOutOfRangeException("basisRetainOffsets"); } @@ -253,15 +253,15 @@ namespace WixToolset.PatchAPI // determine if this is an error or a need to use whole file. int err = Marshal.GetLastWin32Error(); - switch(err) + switch (err) { - case unchecked((int) ERROR_PATCH_BIGGER_THAN_COMPRESSED): - break; + case unchecked((int)ERROR_PATCH_BIGGER_THAN_COMPRESSED): + break; - // too late to exclude this file -- should have been caught before - case unchecked((int) ERROR_PATCH_SAME_FILE): - default: - throw new System.ComponentModel.Win32Exception(err); + // too late to exclude this file -- should have been caught before + case unchecked((int)ERROR_PATCH_SAME_FILE): + default: + throw new System.ComponentModel.Win32Exception(err); } return false; } @@ -302,44 +302,44 @@ namespace WixToolset.PatchAPI // The following contants can be combined and used as the OptionFlags // parameter in the patch creation apis. - internal const uint PATCH_OPTION_USE_BEST = 0x00000000; // auto choose best (slower) + internal const uint PATCH_OPTION_USE_BEST = 0x00000000; // auto choose best (slower) - internal const uint PATCH_OPTION_USE_LZX_BEST = 0x00000003; // auto choose best of LXZ A/B (but not large) - internal const uint PATCH_OPTION_USE_LZX_A = 0x00000001; // normal - internal const uint PATCH_OPTION_USE_LXZ_B = 0x00000002; // better on some x86 binaries - internal const uint PATCH_OPTION_USE_LZX_LARGE = 0x00000004; // better support for large files (requires 5.1 or higher applyer) + internal const uint PATCH_OPTION_USE_LZX_BEST = 0x00000003; // auto choose best of LXZ A/B (but not large) + internal const uint PATCH_OPTION_USE_LZX_A = 0x00000001; // normal + internal const uint PATCH_OPTION_USE_LXZ_B = 0x00000002; // better on some x86 binaries + internal const uint PATCH_OPTION_USE_LZX_LARGE = 0x00000004; // better support for large files (requires 5.1 or higher applyer) - internal const uint PATCH_OPTION_NO_BINDFIX = 0x00010000; // PE bound imports - internal const uint PATCH_OPTION_NO_LOCKFIX = 0x00020000; // PE smashed locks - internal const uint PATCH_OPTION_NO_REBASE = 0x00040000; // PE rebased image + internal const uint PATCH_OPTION_NO_BINDFIX = 0x00010000; // PE bound imports + internal const uint PATCH_OPTION_NO_LOCKFIX = 0x00020000; // PE smashed locks + internal const uint PATCH_OPTION_NO_REBASE = 0x00040000; // PE rebased image internal const uint PATCH_OPTION_FAIL_IF_SAME_FILE = 0x00080000; // don't create if same - internal const uint PATCH_OPTION_FAIL_IF_BIGGER = 0x00100000; // fail if patch is larger than simply compressing new file (slower) - internal const uint PATCH_OPTION_NO_CHECKSUM = 0x00200000; // PE checksum zero - internal const uint PATCH_OPTION_NO_RESTIMEFIX = 0x00400000; // PE resource timestamps - internal const uint PATCH_OPTION_NO_TIMESTAMP = 0x00800000; // don't store new file timestamp in patch - internal const uint PATCH_OPTION_SIGNATURE_MD5 = 0x01000000; // use MD5 instead of CRC (reserved for future support) - internal const uint PATCH_OPTION_INTERLEAVE_FILES = 0x40000000; // better support for large files (requires 5.2 or higher applyer) - internal const uint PATCH_OPTION_RESERVED1 = 0x80000000; // (used internally) + internal const uint PATCH_OPTION_FAIL_IF_BIGGER = 0x00100000; // fail if patch is larger than simply compressing new file (slower) + internal const uint PATCH_OPTION_NO_CHECKSUM = 0x00200000; // PE checksum zero + internal const uint PATCH_OPTION_NO_RESTIMEFIX = 0x00400000; // PE resource timestamps + internal const uint PATCH_OPTION_NO_TIMESTAMP = 0x00800000; // don't store new file timestamp in patch + internal const uint PATCH_OPTION_SIGNATURE_MD5 = 0x01000000; // use MD5 instead of CRC (reserved for future support) + internal const uint PATCH_OPTION_INTERLEAVE_FILES = 0x40000000; // better support for large files (requires 5.2 or higher applyer) + internal const uint PATCH_OPTION_RESERVED1 = 0x80000000; // (used internally) - internal const uint PATCH_OPTION_VALID_FLAGS = 0xC0FF0007; + internal const uint PATCH_OPTION_VALID_FLAGS = 0xC0FF0007; // // The following flags are used with PATCH_OPTION_DATA ExtendedOptionFlags: // - internal const uint PATCH_TRANSFORM_PE_RESOURCE_2 = 0x00000100; // better handling of PE resources (requires 5.2 or higher applyer) - internal const uint PATCH_TRANSFORM_PE_IRELOC_2 = 0x00000200; // better handling of PE stripped relocs (requires 5.2 or higher applyer) + internal const uint PATCH_TRANSFORM_PE_RESOURCE_2 = 0x00000100; // better handling of PE resources (requires 5.2 or higher applyer) + internal const uint PATCH_TRANSFORM_PE_IRELOC_2 = 0x00000200; // better handling of PE stripped relocs (requires 5.2 or higher applyer) // // In addition to the standard Win32 error codes, the following error codes may // be returned via GetLastError() when one of the patch APIs fails. - internal const uint ERROR_PATCH_ENCODE_FAILURE = 0xC00E3101; // create - internal const uint ERROR_PATCH_INVALID_OPTIONS = 0xC00E3102; // create - internal const uint ERROR_PATCH_SAME_FILE = 0xC00E3103; // create - internal const uint ERROR_PATCH_RETAIN_RANGES_DIFFER = 0xC00E3104; // create + internal const uint ERROR_PATCH_ENCODE_FAILURE = 0xC00E3101; // create + internal const uint ERROR_PATCH_INVALID_OPTIONS = 0xC00E3102; // create + internal const uint ERROR_PATCH_SAME_FILE = 0xC00E3103; // create + internal const uint ERROR_PATCH_RETAIN_RANGES_DIFFER = 0xC00E3104; // create internal const uint ERROR_PATCH_BIGGER_THAN_COMPRESSED = 0xC00E3105; // create - internal const uint ERROR_PATCH_IMAGEHLP_FALURE = 0xC00E3106; // create + internal const uint ERROR_PATCH_IMAGEHLP_FALURE = 0xC00E3106; // create /// /// Delegate type that the PatchAPI calls for progress notification. @@ -441,14 +441,14 @@ namespace WixToolset.PatchAPI [BestFitMapping(false, ThrowOnUnmappableChar = true)] internal class PatchOptionData { - public PatchSymbolFlagsType symbolOptionFlags; // PATCH_SYMBOL_xxx flags - [MarshalAs(UnmanagedType.LPStr)] public string newFileSymbolPath; // always ANSI, never Unicode - [MarshalAs(UnmanagedType.LPStr)] public string[] oldFileSymbolPathArray; // array[ OldFileCount ] - public uint extendedOptionFlags; + public PatchSymbolFlags symbolOptionFlags; // PATCH_SYMBOL_xxx flags + [MarshalAs(UnmanagedType.LPStr)] public string newFileSymbolPath; // always ANSI, never Unicode + [MarshalAs(UnmanagedType.LPStr)] public string[] oldFileSymbolPathArray; // array[ OldFileCount ] + public uint extendedOptionFlags; public PatchSymloadCallback symLoadCallback = null; public IntPtr symLoadContext = IntPtr.Zero; public PatchInterleaveMap[] interleaveMapArray = null; // array[ OldFileCount ] (requires 5.2 or higher applyer) - public uint maxLzxWindowSize = 0; // limit memory requirements (requires 5.2 or higher applyer) + public uint maxLzxWindowSize = 0; // limit memory requirements (requires 5.2 or higher applyer) } // @@ -534,7 +534,7 @@ namespace WixToolset.PatchAPI private PatchAPIMarshaler(string cookie) { - this.marshalType = (PatchAPIMarshaler.MarshalType) Enum.Parse(typeof(PatchAPIMarshaler.MarshalType), cookie); + this.marshalType = (PatchAPIMarshaler.MarshalType)Enum.Parse(typeof(PatchAPIMarshaler.MarshalType), cookie); } // @@ -575,12 +575,12 @@ namespace WixToolset.PatchAPI switch (this.marshalType) { - case PatchAPIMarshaler.MarshalType.PATCH_OPTION_DATA: - this.CleanUpPOD(pNativeData); - break; - default: - this.CleanUpPOFI_A(pNativeData); - break; + case PatchAPIMarshaler.MarshalType.PATCH_OPTION_DATA: + this.CleanUpPOD(pNativeData); + break; + default: + this.CleanUpPOFI_A(pNativeData); + break; } } @@ -601,14 +601,14 @@ namespace WixToolset.PatchAPI return IntPtr.Zero; } - switch(this.marshalType) + switch (this.marshalType) { - case PatchAPIMarshaler.MarshalType.PATCH_OPTION_DATA: - return this.MarshalPOD(ManagedObj as PatchOptionData); - case PatchAPIMarshaler.MarshalType.PATCH_OLD_FILE_INFO_W: - return this.MarshalPOFIW_A(ManagedObj as PatchOldFileInfoW[]); - default: - throw new InvalidOperationException(); + case PatchAPIMarshaler.MarshalType.PATCH_OPTION_DATA: + return this.MarshalPOD(ManagedObj as PatchOptionData); + case PatchAPIMarshaler.MarshalType.PATCH_OLD_FILE_INFO_W: + return this.MarshalPOFIW_A(ManagedObj as PatchOldFileInfoW[]); + default: + throw new InvalidOperationException(); } } @@ -631,23 +631,23 @@ namespace WixToolset.PatchAPI // Implementation ************************************************* // PATCH_OPTION_DATA offsets - private static readonly int symbolOptionFlagsOffset = Marshal.SizeOf(typeof(Int32)); - private static readonly int newFileSymbolPathOffset = 2*Marshal.SizeOf(typeof(Int32)); - private static readonly int oldFileSymbolPathArrayOffset = 2*Marshal.SizeOf(typeof(Int32)) + Marshal.SizeOf(typeof(IntPtr)); - private static readonly int extendedOptionFlagsOffset = 2*Marshal.SizeOf(typeof(Int32)) + 2*Marshal.SizeOf(typeof(IntPtr)); - private static readonly int symLoadCallbackOffset = 3*Marshal.SizeOf(typeof(Int32)) + 2*Marshal.SizeOf(typeof(IntPtr)); - private static readonly int symLoadContextOffset = 3*Marshal.SizeOf(typeof(Int32)) + 3*Marshal.SizeOf(typeof(IntPtr)); - private static readonly int interleaveMapArrayOffset = 3*Marshal.SizeOf(typeof(Int32)) + 4*Marshal.SizeOf(typeof(IntPtr)); - private static readonly int maxLzxWindowSizeOffset = 3*Marshal.SizeOf(typeof(Int32)) + 5*Marshal.SizeOf(typeof(IntPtr)); - private static readonly int patchOptionDataSize = 4*Marshal.SizeOf(typeof(Int32)) + 5*Marshal.SizeOf(typeof(IntPtr)); + private static readonly int symbolOptionFlagsOffset = Marshal.SizeOf(typeof(Int32)); + private static readonly int newFileSymbolPathOffset = 2 * Marshal.SizeOf(typeof(Int32)); + private static readonly int oldFileSymbolPathArrayOffset = 2 * Marshal.SizeOf(typeof(Int32)) + Marshal.SizeOf(typeof(IntPtr)); + private static readonly int extendedOptionFlagsOffset = 2 * Marshal.SizeOf(typeof(Int32)) + 2 * Marshal.SizeOf(typeof(IntPtr)); + private static readonly int symLoadCallbackOffset = 3 * Marshal.SizeOf(typeof(Int32)) + 2 * Marshal.SizeOf(typeof(IntPtr)); + private static readonly int symLoadContextOffset = 3 * Marshal.SizeOf(typeof(Int32)) + 3 * Marshal.SizeOf(typeof(IntPtr)); + private static readonly int interleaveMapArrayOffset = 3 * Marshal.SizeOf(typeof(Int32)) + 4 * Marshal.SizeOf(typeof(IntPtr)); + private static readonly int maxLzxWindowSizeOffset = 3 * Marshal.SizeOf(typeof(Int32)) + 5 * Marshal.SizeOf(typeof(IntPtr)); + private static readonly int patchOptionDataSize = 4 * Marshal.SizeOf(typeof(Int32)) + 5 * Marshal.SizeOf(typeof(IntPtr)); // PATCH_OLD_FILE_INFO offsets - private static readonly int oldFileOffset = Marshal.SizeOf(typeof(Int32)); - private static readonly int ignoreRangeCountOffset = Marshal.SizeOf(typeof(Int32)) + Marshal.SizeOf(typeof(IntPtr)); - private static readonly int ignoreRangeArrayOffset = 2*Marshal.SizeOf(typeof(Int32)) + Marshal.SizeOf(typeof(IntPtr)); - private static readonly int retainRangeCountOffset = 2*Marshal.SizeOf(typeof(Int32)) + 2*Marshal.SizeOf(typeof(IntPtr)); - private static readonly int retainRangeArrayOffset = 3*Marshal.SizeOf(typeof(Int32)) + 2*Marshal.SizeOf(typeof(IntPtr)); - private static readonly int patchOldFileInfoSize = 3*Marshal.SizeOf(typeof(Int32)) + 3*Marshal.SizeOf(typeof(IntPtr)); + private static readonly int oldFileOffset = Marshal.SizeOf(typeof(Int32)); + private static readonly int ignoreRangeCountOffset = Marshal.SizeOf(typeof(Int32)) + Marshal.SizeOf(typeof(IntPtr)); + private static readonly int ignoreRangeArrayOffset = 2 * Marshal.SizeOf(typeof(Int32)) + Marshal.SizeOf(typeof(IntPtr)); + private static readonly int retainRangeCountOffset = 2 * Marshal.SizeOf(typeof(Int32)) + 2 * Marshal.SizeOf(typeof(IntPtr)); + private static readonly int retainRangeArrayOffset = 3 * Marshal.SizeOf(typeof(Int32)) + 2 * Marshal.SizeOf(typeof(IntPtr)); + private static readonly int patchOldFileInfoSize = 3 * Marshal.SizeOf(typeof(Int32)) + 3 * Marshal.SizeOf(typeof(IntPtr)); // Methods and data used to preserve data needed for cleanup @@ -658,16 +658,16 @@ namespace WixToolset.PatchAPI private IntPtr CreateMainStruct(int oldFileCount) { int nativeSize; - switch(this.marshalType) + switch (this.marshalType) { - case PatchAPIMarshaler.MarshalType.PATCH_OPTION_DATA: - nativeSize = patchOptionDataSize; - break; - case PatchAPIMarshaler.MarshalType.PATCH_OLD_FILE_INFO_W: - nativeSize = oldFileCount*patchOldFileInfoSize; - break; - default: - throw new InvalidOperationException(); + case PatchAPIMarshaler.MarshalType.PATCH_OPTION_DATA: + nativeSize = patchOptionDataSize; + break; + case PatchAPIMarshaler.MarshalType.PATCH_OLD_FILE_INFO_W: + nativeSize = oldFileCount * patchOldFileInfoSize; + break; + default: + throw new InvalidOperationException(); } IntPtr native = Marshal.AllocCoTaskMem(nativeSize); @@ -722,7 +722,7 @@ namespace WixToolset.PatchAPI for (int i = 0; i < managed.Length; ++i) { - Marshal.WriteIntPtr(native, i*Marshal.SizeOf(typeof(IntPtr)), OptionalAnsiString(managed[i])); + Marshal.WriteIntPtr(native, i * Marshal.SizeOf(typeof(IntPtr)), OptionalAnsiString(managed[i])); } return native; @@ -741,7 +741,7 @@ namespace WixToolset.PatchAPI for (int i = 0; i < managed.Length; ++i) { - Marshal.WriteIntPtr(native, i*Marshal.SizeOf(typeof(IntPtr)), OptionalUnicodeString(managed[i])); + Marshal.WriteIntPtr(native, i * Marshal.SizeOf(typeof(IntPtr)), OptionalUnicodeString(managed[i])); } return native; @@ -765,12 +765,12 @@ namespace WixToolset.PatchAPI } IntPtr native = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(UInt32)) - + managed.ranges.Length*(Marshal.SizeOf(typeof(PatchInterleaveMap)))); - WriteUInt32(native, (uint) managed.ranges.Length); + + managed.ranges.Length * (Marshal.SizeOf(typeof(PatchInterleaveMap)))); + WriteUInt32(native, (uint)managed.ranges.Length); for (int i = 0; i < managed.ranges.Length; ++i) { - Marshal.StructureToPtr(managed.ranges[i], (IntPtr)((Int64)native + i*Marshal.SizeOf(typeof(PatchInterleaveMap))), false); + Marshal.StructureToPtr(managed.ranges[i], (IntPtr)((Int64)native + i * Marshal.SizeOf(typeof(PatchInterleaveMap))), false); } return native; } @@ -786,7 +786,7 @@ namespace WixToolset.PatchAPI for (int i = 0; i < managed.Length; ++i) { - Marshal.WriteIntPtr(native, i*Marshal.SizeOf(typeof(IntPtr)), CreateInterleaveMapRange(managed[i])); + Marshal.WriteIntPtr(native, i * Marshal.SizeOf(typeof(IntPtr)), CreateInterleaveMapRange(managed[i])); } return native; @@ -794,12 +794,12 @@ namespace WixToolset.PatchAPI private static void WriteUInt32(IntPtr native, uint data) { - Marshal.WriteInt32(native, unchecked((int) data)); + Marshal.WriteInt32(native, unchecked((int)data)); } private static void WriteUInt32(IntPtr native, int offset, uint data) { - Marshal.WriteInt32(native, offset, unchecked((int) data)); + Marshal.WriteInt32(native, offset, unchecked((int)data)); } // Marshal operations @@ -813,7 +813,7 @@ namespace WixToolset.PatchAPI IntPtr native = this.CreateMainStruct(managed.oldFileSymbolPathArray.Length); Marshal.WriteInt32(native, patchOptionDataSize); // SizeOfThisStruct - WriteUInt32(native, symbolOptionFlagsOffset, (uint) managed.symbolOptionFlags); + WriteUInt32(native, symbolOptionFlagsOffset, (uint)managed.symbolOptionFlags); Marshal.WriteIntPtr(native, newFileSymbolPathOffset, PatchAPIMarshaler.OptionalAnsiString(managed.newFileSymbolPath)); Marshal.WriteIntPtr(native, oldFileSymbolPathArrayOffset, PatchAPIMarshaler.CreateArrayOfStringA(managed.oldFileSymbolPathArray)); WriteUInt32(native, extendedOptionFlagsOffset, managed.extendedOptionFlags); @@ -866,10 +866,10 @@ namespace WixToolset.PatchAPI { Marshal.WriteInt32(native, patchOldFileInfoSize); // SizeOfThisStruct WriteUInt32(native, ignoreRangeCountOffset, - (null == managed.ignoreRange) ? 0 : (uint) managed.ignoreRange.Length); // IgnoreRangeCount // maximum 255 + (null == managed.ignoreRange) ? 0 : (uint)managed.ignoreRange.Length); // IgnoreRangeCount // maximum 255 Marshal.WriteIntPtr(native, ignoreRangeArrayOffset, MarshalPIRArray(managed.ignoreRange)); // IgnoreRangeArray WriteUInt32(native, retainRangeCountOffset, - (null == managed.retainRange) ? 0 : (uint) managed.retainRange.Length); // RetainRangeCount // maximum 255 + (null == managed.retainRange) ? 0 : (uint)managed.retainRange.Length); // RetainRangeCount // maximum 255 Marshal.WriteIntPtr(native, retainRangeArrayOffset, MarshalPRRArray(managed.retainRange)); // RetainRangeArray } @@ -885,11 +885,11 @@ namespace WixToolset.PatchAPI return IntPtr.Zero; } - IntPtr native = Marshal.AllocCoTaskMem(array.Length*Marshal.SizeOf(typeof(PatchIgnoreRange))); + IntPtr native = Marshal.AllocCoTaskMem(array.Length * Marshal.SizeOf(typeof(PatchIgnoreRange))); for (int i = 0; i < array.Length; ++i) { - Marshal.StructureToPtr(array[i], (IntPtr)((Int64)native + (i*Marshal.SizeOf(typeof(PatchIgnoreRange)))), false); + Marshal.StructureToPtr(array[i], (IntPtr)((Int64)native + (i * Marshal.SizeOf(typeof(PatchIgnoreRange)))), false); } return native; @@ -907,11 +907,11 @@ namespace WixToolset.PatchAPI return IntPtr.Zero; } - IntPtr native = Marshal.AllocCoTaskMem(array.Length*Marshal.SizeOf(typeof(PatchRetainRange))); + IntPtr native = Marshal.AllocCoTaskMem(array.Length * Marshal.SizeOf(typeof(PatchRetainRange))); for (int i = 0; i < array.Length; ++i) { - Marshal.StructureToPtr(array[i], (IntPtr)((Int64)native + (i*Marshal.SizeOf(typeof(PatchRetainRange)))), false); + Marshal.StructureToPtr(array[i], (IntPtr)((Int64)native + (i * Marshal.SizeOf(typeof(PatchRetainRange)))), false); } return native; @@ -930,7 +930,7 @@ namespace WixToolset.PatchAPI Marshal.FreeCoTaskMem( Marshal.ReadIntPtr( Marshal.ReadIntPtr(native, oldFileSymbolPathArrayOffset), - i*Marshal.SizeOf(typeof(IntPtr)))); + i * Marshal.SizeOf(typeof(IntPtr)))); } Marshal.FreeCoTaskMem(Marshal.ReadIntPtr(native, oldFileSymbolPathArrayOffset)); @@ -943,7 +943,7 @@ namespace WixToolset.PatchAPI Marshal.FreeCoTaskMem( Marshal.ReadIntPtr( Marshal.ReadIntPtr(native, interleaveMapArrayOffset), - i*Marshal.SizeOf(typeof(IntPtr)))); + i * Marshal.SizeOf(typeof(IntPtr)))); } Marshal.FreeCoTaskMem(Marshal.ReadIntPtr(native, interleaveMapArrayOffset)); @@ -956,7 +956,7 @@ namespace WixToolset.PatchAPI { for (int i = 0; i < GetOldFileCount(native); ++i) { - PatchAPIMarshaler.CleanUpPOFI((IntPtr)((Int64)native + i*patchOldFileInfoSize)); + PatchAPIMarshaler.CleanUpPOFI((IntPtr)((Int64)native + i * patchOldFileInfoSize)); } PatchAPIMarshaler.ReleaseMainStruct(native); diff --git a/src/WixToolset.Core.WindowsInstaller/RowDictionary.cs b/src/WixToolset.Core.WindowsInstaller/RowDictionary.cs index bbb97c25..ad7764bc 100644 --- a/src/WixToolset.Core.WindowsInstaller/RowDictionary.cs +++ b/src/WixToolset.Core.WindowsInstaller/RowDictionary.cs @@ -20,19 +20,6 @@ namespace WixToolset.Core.WindowsInstaller { } - /// - /// Creates and populates a with the rows from the given enumerator. - /// - /// Rows to add. - public RowDictionary(IEnumerable rows) - : this() - { - foreach (T row in rows) - { - this.Add(row); - } - } - /// /// Creates and populates a with the rows from the given . /// diff --git a/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs b/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs index 36172b5e..9a55dc77 100644 --- a/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs @@ -11,16 +11,16 @@ namespace WixToolset.Core.WindowsInstaller.Unbind using WixToolset.Core.WindowsInstaller.Msi; using WixToolset.Data; using WixToolset.Data.WindowsInstaller; - using WixToolset.Data.WindowsInstaller.Rows; using WixToolset.Extensibility.Services; internal class UnbindDatabaseCommand { private List exportedFiles; - public UnbindDatabaseCommand(IMessaging messaging, Database database, string databasePath, OutputType outputType, string exportBasePath, string intermediateFolder, bool isAdminImage, bool suppressDemodularization, bool skipSummaryInfo) + public UnbindDatabaseCommand(IMessaging messaging, IBackendHelper backendHelper, Database database, string databasePath, OutputType outputType, string exportBasePath, string intermediateFolder, bool isAdminImage, bool suppressDemodularization, bool skipSummaryInfo) { this.Messaging = messaging; + this.BackendHelper = backendHelper; this.Database = database; this.DatabasePath = databasePath; this.OutputType = outputType; @@ -35,6 +35,8 @@ namespace WixToolset.Core.WindowsInstaller.Unbind public IMessaging Messaging { get; } + public IBackendHelper BackendHelper { get; } + public Database Database { get; } public string DatabasePath { get; } @@ -527,7 +529,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind /// /// The Filename value. /// The source name of the directory in an admin image. - private static string GetAdminSourceName(string value) + private string GetAdminSourceName(string value) { string name = null; string[] names; @@ -535,7 +537,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind string shortsourcename = null; string sourcename = null; - names = Common.GetNames(value); + names = this.BackendHelper.SplitMsiFileName(value); if (null != names[0] && "." != names[0]) { diff --git a/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindTranformCommand.cs b/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindTranformCommand.cs index de2c5e37..bde29405 100644 --- a/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindTranformCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindTranformCommand.cs @@ -17,9 +17,10 @@ namespace WixToolset.Core.WindowsInstaller.Unbind internal class UnbindTransformCommand { - public UnbindTransformCommand(IMessaging messaging, string transformFile, string exportBasePath, string intermediateFolder) + public UnbindTransformCommand(IMessaging messaging, IBackendHelper backendHelper, string transformFile, string exportBasePath, string intermediateFolder) { this.Messaging = messaging; + this.BackendHelper = backendHelper; this.TransformFile = transformFile; this.ExportBasePath = exportBasePath; this.IntermediateFolder = intermediateFolder; @@ -29,6 +30,8 @@ namespace WixToolset.Core.WindowsInstaller.Unbind private IMessaging Messaging { get; } + private IBackendHelper BackendHelper { get; } + private string TransformFile { get; } private string ExportBasePath { get; } @@ -87,7 +90,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind msiDatabase.ApplyTransform(this.TransformFile, TransformErrorConditions.All | TransformErrorConditions.ViewTransform); // unbind the database - var unbindCommand = new UnbindDatabaseCommand(this.Messaging, msiDatabase, msiDatabaseFile, OutputType.Product, this.ExportBasePath, this.IntermediateFolder, false, false, skipSummaryInfo: true); + var unbindCommand = new UnbindDatabaseCommand(this.Messaging, this.BackendHelper, msiDatabase, msiDatabaseFile, OutputType.Product, this.ExportBasePath, this.IntermediateFolder, false, false, skipSummaryInfo: true); var transformViewOutput = unbindCommand.Execute(); // index the added and possibly modified rows (added rows may also appears as modified rows) @@ -157,7 +160,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind } // unbind the database - var unbindCommand = new UnbindDatabaseCommand(this.Messaging, msiDatabase, msiDatabaseFile, OutputType.Product, this.ExportBasePath, this.IntermediateFolder, false, false, skipSummaryInfo: true); + var unbindCommand = new UnbindDatabaseCommand(this.Messaging, this.BackendHelper, msiDatabase, msiDatabaseFile, OutputType.Product, this.ExportBasePath, this.IntermediateFolder, false, false, skipSummaryInfo: true); var output = unbindCommand.Execute(); // index all the rows to easily find modified rows diff --git a/src/WixToolset.Core.WindowsInstaller/UnbindContext.cs b/src/WixToolset.Core.WindowsInstaller/UnbindContext.cs index f60a0e1a..acfb8f1e 100644 --- a/src/WixToolset.Core.WindowsInstaller/UnbindContext.cs +++ b/src/WixToolset.Core.WindowsInstaller/UnbindContext.cs @@ -2,7 +2,6 @@ namespace WixToolset.Core { - using System; using WixToolset.Extensibility.Data; using WixToolset.Extensibility.Services; diff --git a/src/WixToolset.Core.WindowsInstaller/Unbinder.cs b/src/WixToolset.Core.WindowsInstaller/Unbinder.cs index 99caaba9..f712ec3f 100644 --- a/src/WixToolset.Core.WindowsInstaller/Unbinder.cs +++ b/src/WixToolset.Core.WindowsInstaller/Unbinder.cs @@ -21,6 +21,8 @@ namespace WixToolset.Core this.BackendFactories = extensionManager.GetServices(); } + public IWixToolsetServiceProvider ServiceProvider { get; } + public IEnumerable BackendFactories { get; } /// @@ -29,8 +31,6 @@ namespace WixToolset.Core /// Set to true if the input msi is part of an admin image. public bool IsAdminImage { get; set; } - public IWixToolsetServiceProvider ServiceProvider { get; } - /// /// Gets or sets the option to suppress demodularizing values. /// diff --git a/src/WixToolset.Core.WindowsInstaller/Validator.cs b/src/WixToolset.Core.WindowsInstaller/Validator.cs index e8117de7..a6a41bd7 100644 --- a/src/WixToolset.Core.WindowsInstaller/Validator.cs +++ b/src/WixToolset.Core.WindowsInstaller/Validator.cs @@ -25,10 +25,10 @@ namespace WixToolset.Core.WindowsInstaller internal sealed class Validator { private string actionName; - private StringCollection cubeFiles; + private readonly StringCollection cubeFiles; private ValidatorExtension extension; private WindowsInstallerData output; - private InstallUIHandler validationUIHandler; + private readonly InstallUIHandler validationUIHandler; private bool validationSessionComplete; private readonly IMessaging messaging; @@ -57,7 +57,6 @@ namespace WixToolset.Core.WindowsInstaller /// Gets or sets the list of ICEs to run. /// /// The list of ICEs. - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public ISet ICEs { get; set; } /// @@ -75,7 +74,6 @@ namespace WixToolset.Core.WindowsInstaller /// Gets or sets the suppressed ICEs. /// /// The suppressed ICEs. - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public ISet SuppressedICEs { get; set; } /// @@ -103,13 +101,8 @@ namespace WixToolset.Core.WindowsInstaller IntPtr previousHwnd = IntPtr.Zero; InstallUIHandler previousUIHandler = null; - if (null == databaseFile) - { - throw new ArgumentNullException("databaseFile"); - } - // initialize the validator extension - this.extension.DatabaseFile = databaseFile; + this.extension.DatabaseFile = databaseFile ?? throw new ArgumentNullException(nameof(databaseFile)); this.extension.Output = this.output; this.extension.InitializeValidator(); diff --git a/src/WixToolset.Core.WindowsInstaller/ValidatorExtension.cs b/src/WixToolset.Core.WindowsInstaller/ValidatorExtension.cs index 968ab387..20606a77 100644 --- a/src/WixToolset.Core.WindowsInstaller/ValidatorExtension.cs +++ b/src/WixToolset.Core.WindowsInstaller/ValidatorExtension.cs @@ -181,7 +181,7 @@ namespace WixToolset.Extensibility throw new ArgumentNullException("message"); } - string[] messageParts = message.Split('\t'); + var messageParts = message.Split('\t'); if (3 > messageParts.Length) { if (null == action) @@ -194,10 +194,10 @@ namespace WixToolset.Extensibility } } - SourceLineNumber messageSourceLineNumbers = null; + SourceLineNumber messageSourceLineNumbers; if (6 < messageParts.Length) { - string[] primaryKeys = new string[messageParts.Length - 6]; + var primaryKeys = new string[messageParts.Length - 6]; Array.Copy(messageParts, 6, primaryKeys, 0, primaryKeys.Length); @@ -242,7 +242,7 @@ namespace WixToolset.Extensibility this.indexedSourceLineNumbers = new Hashtable(); // index each real table - foreach (Table table in this.output.Tables) + foreach (var table in this.output.Tables) { // skip unreal tables if (table.Definition.Unreal) @@ -251,7 +251,7 @@ namespace WixToolset.Extensibility } // index each row - foreach (Row row in table.Rows) + foreach (var row in table.Rows) { // skip rows that don't contain source line information if (null == row.SourceLineNumbers) @@ -260,10 +260,10 @@ namespace WixToolset.Extensibility } // index the row using its table name and primary key - string primaryKey = row.GetPrimaryKey(';'); + var primaryKey = row.GetPrimaryKey(';'); if (null != primaryKey) { - string key = String.Concat(table.Name, ":", primaryKey); + var key = String.Concat(table.Name, ":", primaryKey); if (this.indexedSourceLineNumbers.ContainsKey(key)) { diff --git a/src/WixToolset.Core/AppCommon.cs b/src/WixToolset.Core/AppCommon.cs deleted file mode 100644 index 7f54b057..00000000 --- a/src/WixToolset.Core/AppCommon.cs +++ /dev/null @@ -1,45 +0,0 @@ -// 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. - -namespace WixToolset.Core -{ - using System; - using System.Reflection; - - /// - /// Common utilities for Wix applications. - /// - public static class AppCommon - { - /// - /// Creates and returns the string for CreatingApplication field (MSI Summary Information Stream). - /// - /// It reads the AssemblyProductAttribute and AssemblyVersionAttribute of executing assembly - /// and builds the CreatingApplication string of the form "[ProductName] ([ProductVersion])". - /// Returns value for PID_APPNAME." - public static string GetCreatingApplicationString() - { - var assembly = Assembly.GetExecutingAssembly(); - return WixDistribution.ReplacePlaceholders("[AssemblyProduct] ([FileVersion])", assembly); - } - - /// - /// Displays help message header on Console for caller tool. - /// - public static void DisplayToolHeader() - { - var assembly = Assembly.GetCallingAssembly(); - Console.WriteLine(WixDistribution.ReplacePlaceholders("[AssemblyProduct] [AssemblyDescription] version [FileVersion]", assembly)); - Console.WriteLine(WixDistribution.ReplacePlaceholders("[AssemblyCopyright]", assembly)); - } - - /// - /// Displays help message header on Console for caller tool. - /// - public static void DisplayToolFooter() - { - var assembly = Assembly.GetCallingAssembly(); - Console.WriteLine(); - Console.WriteLine(WixDistribution.ReplacePlaceholders("For more information see: [SupportUrl]", assembly)); - } - } -} diff --git a/src/WixToolset.Core/Bind/ExtractEmbeddedFilesCommand.cs b/src/WixToolset.Core/Bind/ExtractEmbeddedFilesCommand.cs index 29fba6b2..981a991f 100644 --- a/src/WixToolset.Core/Bind/ExtractEmbeddedFilesCommand.cs +++ b/src/WixToolset.Core/Bind/ExtractEmbeddedFilesCommand.cs @@ -9,8 +9,7 @@ namespace WixToolset.Core.Bind using WixToolset.Extensibility.Data; using WixToolset.Extensibility.Services; -#pragma warning disable 1591 // TODO: this shouldn't be public, need interface in Extensibility - public class ExtractEmbeddedFilesCommand + internal class ExtractEmbeddedFilesCommand { public ExtractEmbeddedFilesCommand(IBackendHelper backendHelper, IEnumerable embeddedFiles) { diff --git a/src/WixToolset.Core/Bind/FileFacade.cs b/src/WixToolset.Core/Bind/FileFacade.cs deleted file mode 100644 index d1e5ae60..00000000 --- a/src/WixToolset.Core/Bind/FileFacade.cs +++ /dev/null @@ -1,172 +0,0 @@ -// 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. - -namespace WixToolset.Core.Bind -{ - using System; - using System.Collections.Generic; - using WixToolset.Data; - using WixToolset.Data.Symbols; - using WixToolset.Data.WindowsInstaller; - using WixToolset.Data.WindowsInstaller.Rows; - -#pragma warning disable 1591 // TODO: this shouldn't be public, need interface in Extensibility - public class FileFacade - { - public FileFacade(FileSymbol file, AssemblySymbol assembly) - { - this.FileSymbol = file; - this.AssemblySymbol = assembly; - - this.Identifier = file.Id; - this.ComponentRef = file.ComponentRef; - } - - public FileFacade(bool fromModule, FileSymbol file) - { - this.FromModule = fromModule; - this.FileSymbol = file; - - this.Identifier = file.Id; - this.ComponentRef = file.ComponentRef; - } - - public FileFacade(FileRow row) - { - this.FromTransform = true; - this.FileRow = row; - - this.Identifier = new Identifier(AccessModifier.Section, row.File); - this.ComponentRef = row.Component; - } - - public bool FromModule { get; } - - public bool FromTransform { get; } - - private FileRow FileRow { get; } - - private FileSymbol FileSymbol { get; } - - private AssemblySymbol AssemblySymbol { get; } - - public string Id => this.Identifier.Id; - - public Identifier Identifier { get; } - - public string ComponentRef { get; } - - public int DiskId - { - get => this.FileRow == null ? this.FileSymbol.DiskId ?? 1 : this.FileRow.DiskId; - set - { - if (this.FileRow == null) - { - this.FileSymbol.DiskId = value; - } - else - { - this.FileRow.DiskId = value; - } - } - } - - public string FileName => this.FileRow == null ? this.FileSymbol.Name : this.FileRow.FileName; - - public int FileSize - { - get => this.FileRow == null ? this.FileSymbol.FileSize : this.FileRow.FileSize; - set - { - if (this.FileRow == null) - { - this.FileSymbol.FileSize = value; - } - else - { - this.FileRow.FileSize = value; - } - } - } - - public string Language - { - get => this.FileRow == null ? this.FileSymbol.Language : this.FileRow.Language; - set - { - if (this.FileRow == null) - { - this.FileSymbol.Language = value; - } - else - { - this.FileRow.Language = value; - } - } - } - - public int? PatchGroup => this.FileRow == null ? this.FileSymbol.PatchGroup : null; - - public int Sequence - { - get => this.FileRow == null ? this.FileSymbol.Sequence : this.FileRow.Sequence; - set - { - if (this.FileRow == null) - { - this.FileSymbol.Sequence = value; - } - else - { - this.FileRow.Sequence = value; - } - } - } - - public SourceLineNumber SourceLineNumber => this.FileRow == null ? this.FileSymbol.SourceLineNumbers : this.FileRow.SourceLineNumbers; - - public string SourcePath => this.FileRow == null ? this.FileSymbol.Source?.Path : this.FileRow.Source; - - public bool Compressed => this.FileRow == null ? (this.FileSymbol.Attributes & FileSymbolAttributes.Compressed) == FileSymbolAttributes.Compressed : (this.FileRow.Attributes & WindowsInstallerConstants.MsidbFileAttributesCompressed) == WindowsInstallerConstants.MsidbFileAttributesCompressed; - - public bool Uncompressed => this.FileRow == null ? (this.FileSymbol.Attributes & FileSymbolAttributes.Uncompressed) == FileSymbolAttributes.Uncompressed : (this.FileRow.Attributes & WindowsInstallerConstants.MsidbFileAttributesNoncompressed) == WindowsInstallerConstants.MsidbFileAttributesNoncompressed; - - public string Version - { - get => this.FileRow == null ? this.FileSymbol.Version : this.FileRow.Version; - set - { - if (this.FileRow == null) - { - this.FileSymbol.Version = value; - } - else - { - this.FileRow.Version = value; - } - } - } - - public AssemblyType? AssemblyType => this.FileRow == null ? this.AssemblySymbol?.Type : null; - - public string AssemblyApplicationFileRef => this.FileRow == null ? this.AssemblySymbol?.ApplicationFileRef : throw new NotImplementedException(); - - public string AssemblyManifestFileRef => this.FileRow == null ? this.AssemblySymbol?.ManifestFileRef : throw new NotImplementedException(); - - /// - /// Gets the set of MsiAssemblyName rows created for this file. - /// - /// RowCollection of MsiAssemblyName table. - public List AssemblyNames { get; set; } - - /// - /// Gets or sets the MsiFileHash row for this file. - /// - public MsiFileHashSymbol Hash { get; set; } - - /// - /// Allows direct access to the underlying FileRow as requried for patching. - /// - public FileRow GetFileRow() => this.FileRow ?? throw new NotImplementedException(); - } -} diff --git a/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs b/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs index 14b6d011..0afcc2b3 100644 --- a/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs +++ b/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs @@ -10,19 +10,18 @@ namespace WixToolset.Core.Bind using WixToolset.Extensibility.Data; using WixToolset.Extensibility.Services; -#pragma warning disable 1591 // TODO: this shouldn't be public, need interface in Extensibility /// /// Resolves the fields which had variables that needed to be resolved after the file information /// was loaded. /// - public class ResolveDelayedFieldsCommand + internal class ResolveDelayedFieldsCommand { /// /// Resolve delayed fields. /// /// /// The fields which had resolution delayed. - /// The file information to use when resolving variables. + /// The cached variable values used when resolving delayed fields. public ResolveDelayedFieldsCommand(IMessaging messaging, IEnumerable delayedFields, Dictionary variableCache) { this.Messaging = messaging; @@ -49,7 +48,7 @@ namespace WixToolset.Core.Bind // process properties first in case they refer to other binder variables if (delayedField.Symbol.Definition.Type == SymbolDefinitionType.Property) { - var value = ResolveDelayedVariables(propertySymbol.SourceLineNumbers, delayedField.Field.AsString(), this.VariableCache); + var value = this.ResolveDelayedVariables(propertySymbol.SourceLineNumbers, delayedField.Field.AsString()); // update the variable cache with the new value var key = String.Concat("property.", propertySymbol.Id.Id); @@ -72,7 +71,7 @@ namespace WixToolset.Core.Bind // add specialization for ProductVersion fields var keyProductVersion = "property.ProductVersion"; - if (this.VariableCache.TryGetValue(keyProductVersion, out var versionValue) && Version.TryParse(versionValue, out Version productVersion)) + if (this.VariableCache.TryGetValue(keyProductVersion, out var versionValue) && Version.TryParse(versionValue, out var productVersion)) { // Don't add the variable if it already exists (developer defined a property with the same name). var fieldKey = String.Concat(keyProductVersion, ".Major"); @@ -105,7 +104,7 @@ namespace WixToolset.Core.Bind { try { - var value = ResolveDelayedVariables(delayedField.Symbol.SourceLineNumbers, delayedField.Field.AsString(), this.VariableCache); + var value = this.ResolveDelayedVariables(delayedField.Symbol.SourceLineNumbers, delayedField.Field.AsString()); delayedField.Field.Set(value); } catch (WixException we) @@ -115,7 +114,7 @@ namespace WixToolset.Core.Bind } } - private static string ResolveDelayedVariables(SourceLineNumber sourceLineNumbers, string value, IDictionary resolutionData) + private string ResolveDelayedVariables(SourceLineNumber sourceLineNumbers, string value) { var start = 0; @@ -125,7 +124,7 @@ namespace WixToolset.Core.Bind { var key = String.Concat(parsed.Name, ".", parsed.Scope); - if (!resolutionData.TryGetValue(key, out var resolvedValue)) + if (!this.VariableCache.TryGetValue(key, out var resolvedValue)) { resolvedValue = parsed.DefaultValue; } @@ -149,7 +148,7 @@ namespace WixToolset.Core.Bind } else { - throw new WixException(ErrorMessages.UnresolvedBindReference(sourceLineNumbers, value)); + this.Messaging.Write(ErrorMessages.UnresolvedBindReference(sourceLineNumbers, value)); } } else diff --git a/src/WixToolset.Core/CommandLine/CommandLine.cs b/src/WixToolset.Core/CommandLine/CommandLine.cs index 0c21eaaa..7371628b 100644 --- a/src/WixToolset.Core/CommandLine/CommandLine.cs +++ b/src/WixToolset.Core/CommandLine/CommandLine.cs @@ -55,7 +55,9 @@ namespace WixToolset.Core.CommandLine if (command.ShowLogo) { - AppCommon.DisplayToolHeader(); + var branding = this.ServiceProvider.GetService(); + Console.WriteLine(branding.ReplacePlaceholders("[AssemblyProduct] [AssemblyDescription] version [FileVersion]")); + Console.WriteLine(branding.ReplacePlaceholders("[AssemblyCopyright]")); } return command; @@ -73,6 +75,7 @@ namespace WixToolset.Core.CommandLine private ICommandLineCommand Parse(ICommandLineContext context) { + var branding = context.ServiceProvider.GetService(); var extensions = context.ExtensionManager.GetServices(); foreach (var extension in extensions) @@ -118,7 +121,7 @@ namespace WixToolset.Core.CommandLine extension.PostParse(); } - return command ?? new HelpCommand(extensions); + return command ?? new HelpCommand(extensions, branding); } private bool TryParseCommand(string arg, ICommandLineParser parser, IEnumerable extensions, out ICommandLineCommand command) @@ -134,7 +137,8 @@ namespace WixToolset.Core.CommandLine case "h": case "help": case "-help": - command = new HelpCommand(extensions); + var branding = this.ServiceProvider.GetService(); + command = new HelpCommand(extensions, branding); break; case "version": diff --git a/src/WixToolset.Core/CommandLine/HelpCommand.cs b/src/WixToolset.Core/CommandLine/HelpCommand.cs index 3af442aa..6a5ac183 100644 --- a/src/WixToolset.Core/CommandLine/HelpCommand.cs +++ b/src/WixToolset.Core/CommandLine/HelpCommand.cs @@ -19,9 +19,10 @@ namespace WixToolset.Core.CommandLine new ExtensionCommandLineSwitch { Switch = "decompile", Description = "Decompile a package or bundle into source code." }, }; - public HelpCommand(IEnumerable extensions) + public HelpCommand(IEnumerable extensions, IWixBranding branding) { this.Extensions = extensions; + this.Branding = branding; } public bool ShowLogo => true; @@ -30,6 +31,8 @@ namespace WixToolset.Core.CommandLine private IEnumerable Extensions { get; } + private IWixBranding Branding { get; } + public Task ExecuteAsync(CancellationToken _) { var commandLineSwitches = new List(BuiltInSwitches); @@ -52,7 +55,8 @@ namespace WixToolset.Core.CommandLine Console.WriteLine(); Console.WriteLine("Run 'wix [command] --help' for more information on a command."); - AppCommon.DisplayToolFooter(); + Console.WriteLine(); + Console.WriteLine(this.Branding.ReplacePlaceholders("For more information see: [SupportUrl]")); return Task.FromResult(-1); } diff --git a/src/WixToolset.Core/Common.cs b/src/WixToolset.Core/Common.cs index 79f06135..848f009a 100644 --- a/src/WixToolset.Core/Common.cs +++ b/src/WixToolset.Core/Common.cs @@ -18,124 +18,35 @@ namespace WixToolset.Core /// /// Common Wix utility methods and types. /// - public static class Common + internal static class Common { - // TODO: Find a place to put all of these so they doesn't have to be public and exposed by WixToolset.Core.dll - /// - /// - /// - public const string UpgradeDetectedProperty = "WIX_UPGRADE_DETECTED"; - /// - /// - /// - public const string UpgradePreventedCondition = "NOT WIX_UPGRADE_DETECTED"; - /// - /// - /// - public const string DowngradeDetectedProperty = "WIX_DOWNGRADE_DETECTED"; - /// - /// - /// - public const string DowngradePreventedCondition = "NOT WIX_DOWNGRADE_DETECTED"; - - //------------------------------------------------------------------------------------------------- - // Layout of an Access Mask (from http://technet.microsoft.com/en-us/library/cc783530(WS.10).aspx) - // - // ------------------------------------------------------------------------------------------------- - // |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| - // ------------------------------------------------------------------------------------------------- - // |GR|GW|GE|GA| Reserved |AS|StandardAccessRights| Object-Specific Access Rights | - // - // Key - // GR = Generic Read - // GW = Generic Write - // GE = Generic Execute - // GA = Generic All - // AS = Right to access SACL - // - // TODO: what is the expected decompile behavior if a bit is found that is not explicitly enumerated - // - //------------------------------------------------------------------------------------------------- - // Generic Access Rights (per WinNT.h) - // --------------------- - // GENERIC_ALL (0x10000000L) - // GENERIC_EXECUTE (0x20000000L) - // GENERIC_WRITE (0x40000000L) - // GENERIC_READ (0x80000000L) - // TODO: Find a place to put this that it doesn't have to be public and exposed by WixToolset.Core.dll - /// - /// - /// - public static readonly string[] GenericPermissions = { "GenericAll", "GenericExecute", "GenericWrite", "GenericRead" }; - - // Standard Access Rights (per WinNT.h) - // ---------------------- - // DELETE (0x00010000L) - // READ_CONTROL (0x00020000L) - // WRITE_DAC (0x00040000L) - // WRITE_OWNER (0x00080000L) - // SYNCHRONIZE (0x00100000L) - // TODO: Find a place to put this that it doesn't have to be public and exposed by WixToolset.Core.dll - /// - /// - /// - public static readonly string[] StandardPermissions = { "Delete", "ReadPermission", "ChangePermission", "TakeOwnership", "Synchronize" }; - - // Object-Specific Access Rights - // ============================= - // Directory Access Rights (per WinNT.h) - // ----------------------- - // FILE_LIST_DIRECTORY ( 0x0001 ) - // FILE_ADD_FILE ( 0x0002 ) - // FILE_ADD_SUBDIRECTORY ( 0x0004 ) - // FILE_READ_EA ( 0x0008 ) - // FILE_WRITE_EA ( 0x0010 ) - // FILE_TRAVERSE ( 0x0020 ) - // FILE_DELETE_CHILD ( 0x0040 ) - // FILE_READ_ATTRIBUTES ( 0x0080 ) - // FILE_WRITE_ATTRIBUTES ( 0x0100 ) - // TODO: Find a place to put this that it doesn't have to be public and exposed by WixToolset.Core.dll - /// - /// - /// - public static readonly string[] FolderPermissions = { "Read", "CreateFile", "CreateChild", "ReadExtendedAttributes", "WriteExtendedAttributes", "Traverse", "DeleteChild", "ReadAttributes", "WriteAttributes" }; - - // Registry Access Rights (per TODO) - // ---------------------- - // TODO: Find a place to put this that it doesn't have to be public and exposed by WixToolset.Core.dll - /// - /// - /// - public static readonly string[] RegistryPermissions = { "Read", "Write", "CreateSubkeys", "EnumerateSubkeys", "Notify", "CreateLink" }; - - // File Access Rights (per WinNT.h) - // ------------------ - // FILE_READ_DATA ( 0x0001 ) - // FILE_WRITE_DATA ( 0x0002 ) - // FILE_APPEND_DATA ( 0x0004 ) - // FILE_READ_EA ( 0x0008 ) - // FILE_WRITE_EA ( 0x0010 ) - // FILE_EXECUTE ( 0x0020 ) - // via mask FILE_ALL_ACCESS ( 0x0040 ) - // FILE_READ_ATTRIBUTES ( 0x0080 ) - // FILE_WRITE_ATTRIBUTES ( 0x0100 ) - // - // STANDARD_RIGHTS_REQUIRED (0x000F0000L) - // FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF) - // TODO: Find a place to put this that it doesn't have to be public and exposed by WixToolset.Core.dll - /// - /// - /// - public static readonly string[] FilePermissions = { "Read", "Write", "Append", "ReadExtendedAttributes", "WriteExtendedAttributes", "Execute", "FileAllRights", "ReadAttributes", "WriteAttributes" }; + private static readonly char[] IllegalShortFilenameCharacters = new[] { '\\', '?', '|', '>', '<', ':', '/', '*', '\"', '+', ',', ';', '=', '[', ']', '.', ' ' }; + private static readonly char[] IllegalWildcardShortFilenameCharacters = new[] { '\\', '|', '>', '<', ':', '/', '\"', '+', ',', ';', '=', '[', ']', '.', ' ' }; internal static readonly char[] IllegalLongFilenameCharacters = new[] { '\\', '/', '?', '*', '|', '>', '<', ':', '\"' }; // illegal: \ / ? | > < : / * " internal static readonly char[] IllegalRelativeLongFilenameCharacters = new[] { '?', '*', '|', '>', '<', ':', '\"' }; // like illegal, but we allow '\' and '/' internal static readonly char[] IllegalWildcardLongFilenameCharacters = new[] { '\\', '/', '|', '>', '<', ':', '\"' }; // like illegal: but we allow '*' and '?' - private static readonly char[] IllegalShortFilenameCharacters = new[] { '\\', '?', '|', '>', '<', ':', '/', '*', '\"', '+', ',', ';', '=', '[', ']', '.', ' ' }; - private static readonly char[] IllegalWildcardShortFilenameCharacters = new[] { '\\', '|', '>', '<', ':', '/', '\"', '+', ',', ';', '=', '[', ']', '.', ' ' }; - + public static string GetCanonicalRelativePath(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string relativePath, IMessaging messageHandler) + { + const string root = @"C:\"; + if (!Path.IsPathRooted(relativePath)) + { + var normalizedPath = Path.GetFullPath(root + relativePath); + if (normalizedPath.StartsWith(root)) + { + var canonicalizedPath = normalizedPath.Substring(root.Length); + if (canonicalizedPath != relativePath) + { + messageHandler.Write(WarningMessages.PathCanonicalized(sourceLineNumbers, elementName, attributeName, relativePath, canonicalizedPath)); + } + return canonicalizedPath; + } + } + messageHandler.Write(ErrorMessages.PayloadMustBeRelativeToCache(sourceLineNumbers, elementName, attributeName, relativePath)); + return relativePath; + } /// /// Gets a valid code page from the given web name or integer value. @@ -157,8 +68,8 @@ namespace WixToolset.Core { Encoding encoding; - // check if a integer as a string was passed - if (Int32.TryParse(value, out int codePage)) + // Check if a integer as a string was passed. + if (Int32.TryParse(value, out var codePage)) { if (0 == codePage) { @@ -198,18 +109,91 @@ namespace WixToolset.Core } catch (ArgumentException ex) { - // rethrow as NotSupportedException since either can be thrown - // if the system does not support the specified code page + // Rethrow as NotSupportedException since either can be thrown + // if the system does not support the specified code page. throw new NotSupportedException(ex.Message, ex); } } /// - /// Verifies if a filename is a valid short filename. + /// Verifies if an identifier is a valid binder variable name. + /// + /// Binder variable name to verify. + /// True if the identifier is a valid binder variable name. + public static bool IsValidBinderVariable(string variable) + { + return TryParseWixVariable(variable, 0, out var parsed) && parsed.Index == 0 && parsed.Length == variable.Length && (parsed.Namespace == "bind" || parsed.Namespace == "wix"); + } + + /// + /// Verifies if a string contains a valid binder variable name. + /// + /// String to verify. + /// True if the string contains a valid binder variable name. + public static bool ContainsValidBinderVariable(string verify) + { + return TryParseWixVariable(verify, 0, out var parsed) && (parsed.Namespace == "bind" || parsed.Namespace == "wix"); + } + + /// + /// Verifies the given string is a valid 4-part version module or bundle version. /// - /// Filename to verify. - /// true if wildcards are allowed in the filename. - /// True if the filename is a valid short filename + /// The version to verify. + /// True if version is a valid module or bundle version. + public static bool IsValidFourPartVersion(string version) + { + if (!Common.IsValidBinderVariable(version)) + { + if (!Version.TryParse(version, out var ver) || 65535 < ver.Major || 65535 < ver.Minor || 65535 < ver.Build || 65535 < ver.Revision) + { + return false; + } + } + + return true; + } + + public static bool IsValidLongFilename(string filename, bool allowWildcards, bool allowRelative) + { + if (String.IsNullOrEmpty(filename)) + { + return false; + } + else if (filename.Length > 259) + { + return false; + } + + // Check for a non-period character (all periods is not legal) + var allPeriods = true; + foreach (var character in filename) + { + if ('.' != character) + { + allPeriods = false; + break; + } + } + + if (allPeriods) + { + return false; + } + + if (allowWildcards) + { + return filename.IndexOfAny(Common.IllegalWildcardLongFilenameCharacters) == -1; + } + else if (allowRelative) + { + return filename.IndexOfAny(Common.IllegalRelativeLongFilenameCharacters) == -1; + } + else + { + return filename.IndexOfAny(Common.IllegalLongFilenameCharacters) == -1; + } + } + public static bool IsValidShortFilename(string filename, bool allowWildcards) { if (String.IsNullOrEmpty(filename)) @@ -290,55 +274,6 @@ namespace WixToolset.Core } } - /// - /// Verifies if an identifier is a valid binder variable name. - /// - /// Binder variable name to verify. - /// True if the identifier is a valid binder variable name. - public static bool IsValidBinderVariable(string variable) - { - return TryParseWixVariable(variable, 0, out var parsed) && parsed.Index == 0 && parsed.Length == variable.Length && (parsed.Namespace == "bind" || parsed.Namespace == "wix"); - } - - /// - /// Verifies if a string contains a valid binder variable name. - /// - /// String to verify. - /// True if the string contains a valid binder variable name. - public static bool ContainsValidBinderVariable(string verify) - { - return TryParseWixVariable(verify, 0, out var parsed) && (parsed.Namespace == "bind" || parsed.Namespace == "wix"); - } - - /// - /// Verifies the given string is a valid module or bundle version. - /// - /// The version to verify. - /// True if version is a valid module or bundle version. - public static bool IsValidModuleOrBundleVersion(string version) - { - if (!Common.IsValidBinderVariable(version)) - { - Version ver; - - try - { - ver = new Version(version); - } - catch (ArgumentException) - { - return false; - } - - if (65535 < ver.Major || 65535 < ver.Minor || 65535 < ver.Build || 65535 < ver.Revision) - { - return false; - } - } - - return true; - } - /// /// Generate a new Windows Installer-friendly guid. /// @@ -451,14 +386,14 @@ namespace WixToolset.Core /// If true, add the attribute to each file. If false, remove it. private static void RecursiveFileAttributes(string path, FileAttributes fileAttribute, bool markAttribute, IMessaging messageHandler) { - foreach (string subDirectory in Directory.GetDirectories(path)) + foreach (var subDirectory in Directory.GetDirectories(path)) { RecursiveFileAttributes(subDirectory, fileAttribute, markAttribute, messageHandler); } - foreach (string filePath in Directory.GetFiles(path)) + foreach (var filePath in Directory.GetFiles(path)) { - FileAttributes attributes = File.GetAttributes(filePath); + var attributes = File.GetAttributes(filePath); if (markAttribute) { attributes = attributes | fileAttribute; // add to list of attributes @@ -506,16 +441,15 @@ namespace WixToolset.Core /// An array of strings of length 4. The contents are: short target, long target, short source, and long source. /// /// If any particular file name part is not parsed, its set to null in the appropriate location of the returned array of strings. - /// However, the returned array will always be of length 4. + /// Thus the returned array will always be of length 4. /// public static string[] GetNames(string value) { - string[] names = new string[4]; - int targetSeparator = value.IndexOf(':'); + var targetSeparator = value.IndexOf(':'); // split source and target string sourceName = null; - string targetName = value; + var targetName = value; if (0 <= targetSeparator) { sourceName = value.Substring(targetSeparator + 1); @@ -526,7 +460,7 @@ namespace WixToolset.Core string sourceLongName = null; if (null != sourceName) { - int sourceLongNameSeparator = sourceName.IndexOf('|'); + var sourceLongNameSeparator = sourceName.IndexOf('|'); if (0 <= sourceLongNameSeparator) { sourceLongName = sourceName.Substring(sourceLongNameSeparator + 1); @@ -535,7 +469,7 @@ namespace WixToolset.Core } // split the target short and long names - int targetLongNameSeparator = targetName.IndexOf('|'); + var targetLongNameSeparator = targetName.IndexOf('|'); string targetLongName = null; if (0 <= targetLongNameSeparator) { @@ -543,19 +477,19 @@ namespace WixToolset.Core targetName = targetName.Substring(0, targetLongNameSeparator); } - // remove the long source name when its identical to the long source name + // Remove the long source name when its identical to the short source name. if (null != sourceName && sourceName == sourceLongName) { sourceLongName = null; } - // remove the long target name when its identical to the long target name + // Remove the long target name when its identical to the long target name. if (null != targetName && targetName == targetLongName) { targetLongName = null; } - // remove the source names when they are identical to the target names + // Remove the source names when they are identical to the target names. if (sourceName == targetName && sourceLongName == targetLongName) { sourceName = null; @@ -563,28 +497,28 @@ namespace WixToolset.Core } // target name(s) - if ("." != targetName) + if ("." == targetName) { - names[0] = targetName; + targetName = null; } - if (null != targetLongName && "." != targetLongName) + if ("." == targetLongName) { - names[1] = targetLongName; + targetLongName = null; } // source name(s) - if (null != sourceName) + if ("." == sourceName) { - names[2] = sourceName; + sourceName = null; } - if (null != sourceLongName && "." != sourceLongName) + if ("." == sourceLongName) { - names[3] = sourceLongName; + sourceLongName = null; } - return names; + return new[] { targetName, targetLongName, sourceName, sourceLongName }; } /// @@ -596,7 +530,7 @@ namespace WixToolset.Core /// The name. public static string GetName(string value, bool source, bool longName) { - string[] names = GetNames(value); + var names = GetNames(value); if (source) { @@ -674,7 +608,7 @@ namespace WixToolset.Core /// The attribute's identifier value or a special value if an error occurred. internal static string GetAttributeIdentifierValue(IMessaging messaging, SourceLineNumber sourceLineNumbers, XAttribute attribute) { - string value = Common.GetAttributeValue(messaging, sourceLineNumbers, attribute, EmptyRule.CanBeWhitespaceOnly); + var value = Common.GetAttributeValue(messaging, sourceLineNumbers, attribute, EmptyRule.CanBeWhitespaceOnly); if (Common.IsIdentifier(value)) { @@ -713,8 +647,8 @@ namespace WixToolset.Core { Debug.Assert(minimum > CompilerConstants.IntegerNotSet && minimum > CompilerConstants.IllegalInteger, "The legal values for this attribute collide with at least one sentinel used during parsing."); - string value = Common.GetAttributeValue(messaging, sourceLineNumbers, attribute, EmptyRule.CanBeWhitespaceOnly); - int integer = CompilerConstants.IllegalInteger; + var value = Common.GetAttributeValue(messaging, sourceLineNumbers, attribute, EmptyRule.CanBeWhitespaceOnly); + var integer = CompilerConstants.IllegalInteger; if (0 < value.Length) { @@ -748,8 +682,8 @@ namespace WixToolset.Core /// The attribute's YesNoType value. internal static YesNoType GetAttributeYesNoValue(IMessaging messaging, SourceLineNumber sourceLineNumbers, XAttribute attribute) { - string value = Common.GetAttributeValue(messaging, sourceLineNumbers, attribute, EmptyRule.CanBeWhitespaceOnly); - YesNoType yesNo = YesNoType.IllegalValue; + var value = Common.GetAttributeValue(messaging, sourceLineNumbers, attribute, EmptyRule.CanBeWhitespaceOnly); + var yesNo = YesNoType.IllegalValue; if ("yes".Equals(value) || "true".Equals(value)) { diff --git a/src/WixToolset.Core/Compiler.cs b/src/WixToolset.Core/Compiler.cs index f311a5f6..2aa25141 100644 --- a/src/WixToolset.Core/Compiler.cs +++ b/src/WixToolset.Core/Compiler.cs @@ -7073,7 +7073,7 @@ namespace WixToolset.Core Remove = removeFeatures, MigrateFeatures = migrateFeatures, IgnoreRemoveFailures = ignoreRemoveFailure, - ActionProperty = Common.UpgradeDetectedProperty + ActionProperty = WixUpgradeConstants.UpgradeDetectedProperty }); if (allowDowngrades) @@ -7094,7 +7094,7 @@ namespace WixToolset.Core { this.Core.AddSymbol(new LaunchConditionSymbol(sourceLineNumbers) { - Condition = Common.UpgradePreventedCondition, + Condition = WixUpgradeConstants.UpgradePreventedCondition, Description = downgradeErrorMessage }); } @@ -7109,12 +7109,12 @@ namespace WixToolset.Core Language = productLanguage, OnlyDetect = true, IgnoreRemoveFailures = ignoreRemoveFailure, - ActionProperty = Common.DowngradeDetectedProperty + ActionProperty = WixUpgradeConstants.DowngradeDetectedProperty }); this.Core.AddSymbol(new LaunchConditionSymbol(sourceLineNumbers) { - Condition = Common.DowngradePreventedCondition, + Condition = WixUpgradeConstants.DowngradePreventedCondition, Description = downgradeErrorMessage }); } diff --git a/src/WixToolset.Core/CompilerCore.cs b/src/WixToolset.Core/CompilerCore.cs index cfe3082e..ec22a8ec 100644 --- a/src/WixToolset.Core/CompilerCore.cs +++ b/src/WixToolset.Core/CompilerCore.cs @@ -296,20 +296,6 @@ namespace WixToolset.Core return sb?.ToString() ?? filename; } - /// - /// Creates a short file/directory name using an identifier and long file/directory name as input. - /// - /// The long file/directory name. - /// The option to keep the extension on generated short names. - /// true if wildcards are allowed in the filename. - /// Any additional information to include in the hash for the generated short name. - /// The generated 8.3-compliant short file/directory name. - [Obsolete] - public string CreateShortName(string longName, bool keepExtension, bool allowWildcards, params string[] args) - { - return this.parseHelper.CreateShortName(longName, keepExtension, allowWildcards, args); - } - /// /// Verifies the given string is a valid product version. /// @@ -337,7 +323,7 @@ namespace WixToolset.Core /// True if version is a valid module or bundle version. public static bool IsValidModuleOrBundleVersion(string version) { - return Common.IsValidModuleOrBundleVersion(version); + return Common.IsValidFourPartVersion(version); } /// @@ -547,15 +533,14 @@ namespace WixToolset.Core { if (null == attribute) { - throw new ArgumentNullException("attribute"); + throw new ArgumentNullException(nameof(attribute)); } - string value = this.GetAttributeValue(sourceLineNumbers, attribute); + var value = this.GetAttributeValue(sourceLineNumbers, attribute); try { - int codePage = Common.GetValidCodePage(value); - return codePage; + return Common.GetValidCodePage(value); } catch (NotSupportedException) { @@ -576,12 +561,12 @@ namespace WixToolset.Core { if (null == attribute) { - throw new ArgumentNullException("attribute"); + throw new ArgumentNullException(nameof(attribute)); } - string value = this.GetAttributeValue(sourceLineNumbers, attribute); + var value = this.GetAttributeValue(sourceLineNumbers, attribute); - // allow for localization of code page names and values + // Allow for localization of code page names and values. if (this.IsValidLocIdentifier(value)) { return value; @@ -589,13 +574,13 @@ namespace WixToolset.Core try { - int codePage = Common.GetValidCodePage(value, false, onlyAnsi, sourceLineNumbers); + var codePage = Common.GetValidCodePage(value, false, onlyAnsi, sourceLineNumbers); return codePage.ToString(CultureInfo.InvariantCulture); } catch (NotSupportedException) { - // not a valid windows code page - this.Write(ErrorMessages.IllegalCodepageAttribute(sourceLineNumbers, value, attribute.Parent.Name.LocalName, attribute.Name.LocalName)); + // Not a valid windows code page. + this.messaging.Write(ErrorMessages.IllegalCodepageAttribute(sourceLineNumbers, value, attribute.Parent.Name.LocalName, attribute.Name.LocalName)); } catch (WixException e) { @@ -805,7 +790,7 @@ namespace WixToolset.Core if (0 < value.Length) { - if (!this.IsValidShortFilename(value, allowWildcards) && !Common.ContainsValidBinderVariable(value)) + if (!this.parseHelper.IsValidShortFilename(value, allowWildcards) && !Common.ContainsValidBinderVariable(value)) { this.Write(ErrorMessages.IllegalShortFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); } diff --git a/src/WixToolset.Core/Compiler_Package.cs b/src/WixToolset.Core/Compiler_Package.cs index 03ba1c40..1dac5399 100644 --- a/src/WixToolset.Core/Compiler_Package.cs +++ b/src/WixToolset.Core/Compiler_Package.cs @@ -1024,13 +1024,13 @@ namespace WixToolset.Core switch (tableName) { case "CreateFolder": - specialPermissions = Common.FolderPermissions; + specialPermissions = LockPermissionConstants.FolderPermissions; break; case "File": - specialPermissions = Common.FilePermissions; + specialPermissions = LockPermissionConstants.FilePermissions; break; case "Registry": - specialPermissions = Common.RegistryPermissions; + specialPermissions = LockPermissionConstants.RegistryPermissions; break; default: this.Core.UnexpectedElement(node.Parent, node); @@ -1059,9 +1059,9 @@ namespace WixToolset.Core break; default: var attribValue = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); - if (!this.Core.TrySetBitFromName(Common.StandardPermissions, attrib.Name.LocalName, attribValue, bits, 16)) + if (!this.Core.TrySetBitFromName(LockPermissionConstants.StandardPermissions, attrib.Name.LocalName, attribValue, bits, 16)) { - if (!this.Core.TrySetBitFromName(Common.GenericPermissions, attrib.Name.LocalName, attribValue, bits, 28)) + if (!this.Core.TrySetBitFromName(LockPermissionConstants.GenericPermissions, attrib.Name.LocalName, attribValue, bits, 28)) { if (!this.Core.TrySetBitFromName(specialPermissions, attrib.Name.LocalName, attribValue, bits, 0)) { diff --git a/src/WixToolset.Core/Compiler_Patch.cs b/src/WixToolset.Core/Compiler_Patch.cs index 998894d8..a2cadd67 100644 --- a/src/WixToolset.Core/Compiler_Patch.cs +++ b/src/WixToolset.Core/Compiler_Patch.cs @@ -95,13 +95,13 @@ namespace WixToolset.Core targetProductName = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "ApiPatchingSymbolNoImagehlpFlag": - apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_NO_IMAGEHLP : 0; + apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlags.PatchSymbolNoImagehlp : 0; break; case "ApiPatchingSymbolNoFailuresFlag": - apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_NO_FAILURES : 0; + apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlags.PatchSymbolNoFailures : 0; break; case "ApiPatchingSymbolUndecoratedTooFlag": - apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_UNDECORATED_TOO : 0; + apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlags.PatchSymbolUndecoratedToo : 0; break; case "OptimizePatchSizeForLargeFiles": optimizePatchSizeForLargeFiles = (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)); @@ -275,7 +275,7 @@ namespace WixToolset.Core private int ParseOptimizeCustomActionsElement(XElement node) { var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); - var optimizeCA = OptimizeCA.None; + var optimizeCA = OptimizeCAFlags.None; foreach (var attrib in node.Attributes()) { @@ -286,19 +286,19 @@ namespace WixToolset.Core case "SkipAssignment": if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { - optimizeCA |= OptimizeCA.SkipAssignment; + optimizeCA |= OptimizeCAFlags.SkipAssignment; } break; case "SkipImmediate": if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { - optimizeCA |= OptimizeCA.SkipImmediate; + optimizeCA |= OptimizeCAFlags.SkipImmediate; } break; case "SkipDeferred": if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { - optimizeCA |= OptimizeCA.SkipDeferred; + optimizeCA |= OptimizeCAFlags.SkipDeferred; } break; default: diff --git a/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs b/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs index 7b20286c..3dcc0ce9 100644 --- a/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs +++ b/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs @@ -3,8 +3,12 @@ namespace WixToolset.Core.ExtensibilityServices { using System; + using System.Collections.Generic; using System.IO; + using WixToolset.Core.Bind; using WixToolset.Data; + using WixToolset.Data.Symbols; + using WixToolset.Data.WindowsInstaller.Rows; using WixToolset.Extensibility.Data; using WixToolset.Extensibility.Services; @@ -15,12 +19,24 @@ namespace WixToolset.Core.ExtensibilityServices public BackendHelper(IWixToolsetServiceProvider serviceProvider) { this.Messaging = serviceProvider.GetService(); - this.ParseHelper = serviceProvider.GetService(); } private IMessaging Messaging { get; } - private IParseHelper ParseHelper { get; } + public IFileFacade CreateFileFacade(FileSymbol file, AssemblySymbol assembly) + { + return new FileFacade(file, assembly); + } + + public IFileFacade CreateFileFacade(FileRow fileRow) + { + return new FileFacade(fileRow); + } + + public IFileFacade CreateFileFacadeFromMergeModule(FileSymbol fileSymbol) + { + return new FileFacade(true, fileSymbol); + } public IFileTransfer CreateFileTransfer(string source, string destination, bool move, SourceLineNumber sourceLineNumbers = null) { @@ -38,6 +54,11 @@ namespace WixToolset.Core.ExtensibilityServices }; } + public string CreateGuid() + { + return Common.GenerateGuid(); + } + public string CreateGuid(Guid namespaceGuid, string value) { return Uuid.NewUuid(namespaceGuid, value).ToString("B").ToUpperInvariant(); @@ -52,9 +73,43 @@ namespace WixToolset.Core.ExtensibilityServices }; } + public IEnumerable ExtractEmbeddedFiles(IEnumerable embeddedFiles) + { + var command = new ExtractEmbeddedFilesCommand(this, embeddedFiles); + command.Execute(); + + return command.TrackedFiles; + } + + public string GenerateIdentifier(string prefix, params string[] args) + { + return Common.GenerateIdentifier(prefix, args); + } + public string GetCanonicalRelativePath(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string relativePath) { - return this.ParseHelper.GetCanonicalRelativePath(sourceLineNumbers, elementName, attributeName, relativePath); + return Common.GetCanonicalRelativePath(sourceLineNumbers, elementName, attributeName, relativePath, this.Messaging); + } + + public int GetValidCodePage(string value, bool allowNoChange = false, bool onlyAnsi = false, SourceLineNumber sourceLineNumbers = null) + { + return Common.GetValidCodePage(value, allowNoChange, onlyAnsi, sourceLineNumbers); + } + + public string GetMsiFileName(string value, bool source, bool longName) + { + return Common.GetName(value, source, longName); + } + + public void ResolveDelayedFields(IEnumerable delayedFields, Dictionary variableCache) + { + var command = new ResolveDelayedFieldsCommand(this.Messaging, delayedFields, variableCache); + command.Execute(); + } + + public string[] SplitMsiFileName(string value) + { + return Common.GetNames(value); } public ITrackedFile TrackFile(string path, TrackedFileType type, SourceLineNumber sourceLineNumbers = null) @@ -62,6 +117,31 @@ namespace WixToolset.Core.ExtensibilityServices return new TrackedFile(path, type, sourceLineNumbers); } + public bool IsValidBinderVariable(string variable) + { + return Common.IsValidBinderVariable(variable); + } + + public bool IsValidFourPartVersion(string version) + { + return Common.IsValidFourPartVersion(version); + } + + public bool IsValidIdentifier(string id) + { + return Common.IsIdentifier(id); + } + + public bool IsValidLongFilename(string filename, bool allowWildcards, bool allowRelative) + { + return Common.IsValidLongFilename(filename, allowWildcards, allowRelative); + } + + public bool IsValidShortFilename(string filename, bool allowWildcards) + { + return Common.IsValidShortFilename(filename, allowWildcards); + } + private string GetValidatedFullPath(SourceLineNumber sourceLineNumbers, string path) { try diff --git a/src/WixToolset.Core/ExtensibilityServices/FileFacade.cs b/src/WixToolset.Core/ExtensibilityServices/FileFacade.cs new file mode 100644 index 00000000..f85d4842 --- /dev/null +++ b/src/WixToolset.Core/ExtensibilityServices/FileFacade.cs @@ -0,0 +1,172 @@ +// 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. + +namespace WixToolset.Core.ExtensibilityServices +{ + using System; + using System.Collections.Generic; + using WixToolset.Data; + using WixToolset.Data.Symbols; + using WixToolset.Data.WindowsInstaller; + using WixToolset.Data.WindowsInstaller.Rows; + using WixToolset.Extensibility.Data; + + internal class FileFacade : IFileFacade + { + public FileFacade(FileSymbol file, AssemblySymbol assembly) + { + this.FileSymbol = file; + this.AssemblySymbol = assembly; + + this.Identifier = file.Id; + this.ComponentRef = file.ComponentRef; + } + + public FileFacade(bool fromModule, FileSymbol file) + { + this.FromModule = fromModule; + this.FileSymbol = file; + + this.Identifier = file.Id; + this.ComponentRef = file.ComponentRef; + } + + public FileFacade(FileRow row) + { + this.FromTransform = true; + this.FileRow = row; + + this.Identifier = new Identifier(AccessModifier.Section, row.File); + this.ComponentRef = row.Component; + } + + public bool FromModule { get; } + + public bool FromTransform { get; } + + private FileRow FileRow { get; } + + private FileSymbol FileSymbol { get; } + + private AssemblySymbol AssemblySymbol { get; } + + public string Id => this.Identifier.Id; + + public Identifier Identifier { get; } + + public string ComponentRef { get; } + + public int DiskId + { + get => this.FileRow == null ? this.FileSymbol.DiskId ?? 1 : this.FileRow.DiskId; + set + { + if (this.FileRow == null) + { + this.FileSymbol.DiskId = value; + } + else + { + this.FileRow.DiskId = value; + } + } + } + + public string FileName => this.FileRow == null ? this.FileSymbol.Name : this.FileRow.FileName; + + public int FileSize + { + get => this.FileRow == null ? this.FileSymbol.FileSize : this.FileRow.FileSize; + set + { + if (this.FileRow == null) + { + this.FileSymbol.FileSize = value; + } + else + { + this.FileRow.FileSize = value; + } + } + } + + public string Language + { + get => this.FileRow == null ? this.FileSymbol.Language : this.FileRow.Language; + set + { + if (this.FileRow == null) + { + this.FileSymbol.Language = value; + } + else + { + this.FileRow.Language = value; + } + } + } + + public int? PatchGroup => this.FileRow == null ? this.FileSymbol.PatchGroup : null; + + public int Sequence + { + get => this.FileRow == null ? this.FileSymbol.Sequence : this.FileRow.Sequence; + set + { + if (this.FileRow == null) + { + this.FileSymbol.Sequence = value; + } + else + { + this.FileRow.Sequence = value; + } + } + } + + public SourceLineNumber SourceLineNumber => this.FileRow == null ? this.FileSymbol.SourceLineNumbers : this.FileRow.SourceLineNumbers; + + public string SourcePath => this.FileRow == null ? this.FileSymbol.Source?.Path : this.FileRow.Source; + + public bool Compressed => this.FileRow == null ? (this.FileSymbol.Attributes & FileSymbolAttributes.Compressed) == FileSymbolAttributes.Compressed : (this.FileRow.Attributes & WindowsInstallerConstants.MsidbFileAttributesCompressed) == WindowsInstallerConstants.MsidbFileAttributesCompressed; + + public bool Uncompressed => this.FileRow == null ? (this.FileSymbol.Attributes & FileSymbolAttributes.Uncompressed) == FileSymbolAttributes.Uncompressed : (this.FileRow.Attributes & WindowsInstallerConstants.MsidbFileAttributesNoncompressed) == WindowsInstallerConstants.MsidbFileAttributesNoncompressed; + + public string Version + { + get => this.FileRow == null ? this.FileSymbol.Version : this.FileRow.Version; + set + { + if (this.FileRow == null) + { + this.FileSymbol.Version = value; + } + else + { + this.FileRow.Version = value; + } + } + } + + public AssemblyType? AssemblyType => this.FileRow == null ? this.AssemblySymbol?.Type : null; + + public string AssemblyApplicationFileRef => this.FileRow == null ? this.AssemblySymbol?.ApplicationFileRef : throw new NotImplementedException(); + + public string AssemblyManifestFileRef => this.FileRow == null ? this.AssemblySymbol?.ManifestFileRef : throw new NotImplementedException(); + + /// + /// Gets the set of MsiAssemblyName rows created for this file. + /// + /// RowCollection of MsiAssemblyName table. + public List AssemblyNames { get; set; } + + /// + /// Gets or sets the MsiFileHash row for this file. + /// + public MsiFileHashSymbol Hash { get; set; } + + /// + /// Allows direct access to the underlying FileRow as requried for patching. + /// + public FileRow GetFileRow() => this.FileRow ?? throw new NotImplementedException(); + } +} diff --git a/src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs b/src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs index 7894ce8e..3c040b35 100644 --- a/src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs +++ b/src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs @@ -6,9 +6,6 @@ namespace WixToolset.Core.ExtensibilityServices using System.Collections.Generic; using System.Diagnostics; using System.Globalization; - using System.IO; - using System.Security.Cryptography; - using System.Text; using System.Xml.Linq; using WixToolset.Data; using WixToolset.Data.Symbols; @@ -292,56 +289,6 @@ namespace WixToolset.Core.ExtensibilityServices return section.AddSymbol(symbolDefinition.CreateSymbol(sourceLineNumbers, identifier)); } - public string CreateShortName(string longName, bool keepExtension, bool allowWildcards, params string[] args) - { - // canonicalize the long name if its not a localization identifier (they are case-sensitive) - if (!this.IsValidLocIdentifier(longName)) - { - longName = longName.ToLowerInvariant(); - } - - // collect all the data - var strings = new List(1 + args.Length); - strings.Add(longName); - strings.AddRange(args); - - // prepare for hashing - var stringData = String.Join("|", strings); - var data = Encoding.UTF8.GetBytes(stringData); - - // hash the data - byte[] hash; - using (var sha1 = new SHA1CryptoServiceProvider()) - { - hash = sha1.ComputeHash(data); - } - - // generate the short file/directory name without an extension - var shortName = new StringBuilder(Convert.ToBase64String(hash)); - shortName.Remove(8, shortName.Length - 8).Replace('+', '-').Replace('/', '_'); - - if (keepExtension) - { - var extension = Path.GetExtension(longName); - - if (4 < extension.Length) - { - extension = extension.Substring(0, 4); - } - - shortName.Append(extension); - - // check the generated short name to ensure its still legal (the extension may not be legal) - if (!this.IsValidShortFilename(shortName.ToString(), allowWildcards)) - { - // remove the extension (by truncating the generated file name back to the generated characters) - shortName.Length -= extension.Length; - } - } - - return shortName.ToString().ToLowerInvariant(); - } - public void EnsureTable(IntermediateSection section, SourceLineNumber sourceLineNumbers, TableDefinition tableDefinition) { section.AddSymbol(new WixEnsureTableSymbol(sourceLineNumbers) @@ -673,23 +620,7 @@ namespace WixToolset.Core.ExtensibilityServices public string GetCanonicalRelativePath(SourceLineNumber sourceLineNumbers, string elementName, string attributeName, string relativePath) { - const string root = @"C:\"; - if (!Path.IsPathRooted(relativePath)) - { - var normalizedPath = Path.GetFullPath(root + relativePath); - if (normalizedPath.StartsWith(root)) - { - var canonicalizedPath = normalizedPath.Substring(root.Length); - if (canonicalizedPath != relativePath) - { - this.Messaging.Write(WarningMessages.PathCanonicalized(sourceLineNumbers, elementName, attributeName, relativePath, canonicalizedPath)); - } - return canonicalizedPath; - } - } - - this.Messaging.Write(ErrorMessages.PayloadMustBeRelativeToCache(sourceLineNumbers, elementName, attributeName, relativePath)); - return relativePath; + return Common.GetCanonicalRelativePath(sourceLineNumbers, elementName, attributeName, relativePath, this.Messaging); } public SourceLineNumber GetSourceLineNumbers(XElement element) @@ -723,46 +654,10 @@ namespace WixToolset.Core.ExtensibilityServices public bool IsValidLongFilename(string filename, bool allowWildcards, bool allowRelative) { - if (String.IsNullOrEmpty(filename)) - { - return false; - } - else if (filename.Length > 259) - { - return false; - } - - // Check for a non-period character (all periods is not legal) - var allPeriods = true; - foreach (var character in filename) - { - if ('.' != character) - { - allPeriods = false; - break; - } - } - - if (allPeriods) - { - return false; - } - - if (allowWildcards) - { - return filename.IndexOfAny(Common.IllegalWildcardLongFilenameCharacters) == -1; - } - else if (allowRelative) - { - return filename.IndexOfAny(Common.IllegalRelativeLongFilenameCharacters) == -1; - } - else - { - return filename.IndexOfAny(Common.IllegalLongFilenameCharacters) == -1; - } + return Common.IsValidLongFilename(filename, allowWildcards, allowRelative); } - public bool IsValidShortFilename(string filename, bool allowWildcards = false) + public bool IsValidShortFilename(string filename, bool allowWildcards) { return Common.IsValidShortFilename(filename, allowWildcards); } diff --git a/src/WixToolset.Core/ExtensibilityServices/WixBranding.cs b/src/WixToolset.Core/ExtensibilityServices/WixBranding.cs new file mode 100644 index 00000000..56300400 --- /dev/null +++ b/src/WixToolset.Core/ExtensibilityServices/WixBranding.cs @@ -0,0 +1,124 @@ +// 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. + +using System.Resources; + +[assembly: NeutralResourcesLanguage("en-US")] + +namespace WixToolset.Core.ExtensibilityServices +{ + using System; + using System.Diagnostics; + using System.IO; + using System.Reflection; + using WixToolset.Extensibility.Services; + + /// + /// Branding strings. + /// + internal class WixBranding : IWixBranding + { + /// + /// News URL for the distribution. + /// + public static string NewsUrl = "http://wixtoolset.org/news/"; + + /// + /// Short product name for the distribution. + /// + public static string ShortProduct = "WiX Toolset"; + + /// + /// Support URL for the distribution. + /// + public static string SupportUrl = "http://wixtoolset.org/"; + + /// + /// Telemetry URL format for the distribution. + /// + public static string TelemetryUrlFormat = "http://wixtoolset.org/telemetry/v{0}/?r={1}"; + + /// + /// VS Extensions Landing page Url for the distribution. + /// + public static string VSExtensionsLandingUrl = "http://wixtoolset.org/releases/"; + + public string GetCreatingApplication() + { + return this.ReplacePlaceholders("[AssemblyProduct] ([FileVersion])"); + } + + public string ReplacePlaceholders(string original, Assembly assembly = null) + { + if (assembly == null) + { + assembly = typeof(WixBranding).Assembly; + } + + var commonVersionPath = Path.Combine(Path.GetDirectoryName(typeof(WixBranding).Assembly.Location), "wixver.dll"); + if (File.Exists(commonVersionPath)) + { + var commonFileVersion = FileVersionInfo.GetVersionInfo(commonVersionPath); + + original = original.Replace("[FileCopyright]", commonFileVersion.LegalCopyright); + original = original.Replace("[FileVersion]", commonFileVersion.FileVersion); + } + + var fileVersion = FileVersionInfo.GetVersionInfo(assembly.Location); + + original = original.Replace("[FileComments]", fileVersion.Comments); + original = original.Replace("[FileCopyright]", fileVersion.LegalCopyright); + original = original.Replace("[FileProductName]", fileVersion.ProductName); + original = original.Replace("[FileVersion]", fileVersion.FileVersion); + + if (original.Contains("[FileVersionMajorMinor]")) + { + var version = new Version(fileVersion.FileVersion); + original = original.Replace("[FileVersionMajorMinor]", String.Concat(version.Major, ".", version.Minor)); + } + + if (TryGetAttribute(assembly, out AssemblyCompanyAttribute company)) + { + original = original.Replace("[AssemblyCompany]", company.Company); + } + + if (TryGetAttribute(assembly, out AssemblyCopyrightAttribute copyright)) + { + original = original.Replace("[AssemblyCopyright]", copyright.Copyright); + } + + if (TryGetAttribute(assembly, out AssemblyDescriptionAttribute description)) + { + original = original.Replace("[AssemblyDescription]", description.Description); + } + + if (TryGetAttribute(assembly, out AssemblyProductAttribute product)) + { + original = original.Replace("[AssemblyProduct]", product.Product); + } + + if (TryGetAttribute(assembly, out AssemblyTitleAttribute title)) + { + original = original.Replace("[AssemblyTitle]", title.Title); + } + + original = original.Replace("[NewsUrl]", NewsUrl); + original = original.Replace("[ShortProduct]", ShortProduct); + original = original.Replace("[SupportUrl]", SupportUrl); + + return original; + } + + private static bool TryGetAttribute(Assembly assembly, out T attribute) where T : Attribute + { + attribute = null; + + var customAttributes = assembly.GetCustomAttributes(typeof(T), false); + if (null != customAttributes && 0 < customAttributes.Length) + { + attribute = customAttributes[0] as T; + } + + return null != attribute; + } + } +} diff --git a/src/WixToolset.Core/LocalizationParser.cs b/src/WixToolset.Core/LocalizationParser.cs index a0cf38a9..aaf4c425 100644 --- a/src/WixToolset.Core/LocalizationParser.cs +++ b/src/WixToolset.Core/LocalizationParser.cs @@ -30,10 +30,10 @@ namespace WixToolset.Core public Localization ParseLocalization(XDocument document) { - XElement root = document.Root; + var root = document.Root; Localization localization = null; - SourceLineNumber sourceLineNumbers = SourceLineNumber.CreateFromXObject(root); + var sourceLineNumbers = SourceLineNumber.CreateFromXObject(root); if (LocalizationParser.XmlElementName == root.Name.LocalName) { if (LocalizationParser.WxlNamespace == root.Name.Namespace) @@ -85,11 +85,11 @@ namespace WixToolset.Core /// Element to parse. private static Localization ParseWixLocalizationElement(IMessaging messaging, XElement node) { - int codepage = -1; + var sourceLineNumbers = SourceLineNumber.CreateFromXObject(node); + var codepage = -1; string culture = null; - SourceLineNumber sourceLineNumbers = SourceLineNumber.CreateFromXObject(node); - foreach (XAttribute attrib in node.Attributes()) + foreach (var attrib in node.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || LocalizationParser.WxlNamespace == attrib.Name.Namespace) { @@ -115,10 +115,10 @@ namespace WixToolset.Core } } - Dictionary variables = new Dictionary(); - Dictionary localizedControls = new Dictionary(); + var variables = new Dictionary(); + var localizedControls = new Dictionary(); - foreach (XElement child in node.Elements()) + foreach (var child in node.Elements()) { if (LocalizationParser.WxlNamespace == child.Name.Namespace) { @@ -155,10 +155,10 @@ namespace WixToolset.Core private static void ParseString(IMessaging messaging, XElement node, IDictionary variables) { string id = null; - bool overridable = false; - SourceLineNumber sourceLineNumbers = SourceLineNumber.CreateFromXObject(node); + var overridable = false; + var sourceLineNumbers = SourceLineNumber.CreateFromXObject(node); - foreach (XAttribute attrib in node.Attributes()) + foreach (var attrib in node.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || LocalizationParser.WxlNamespace == attrib.Name.Namespace) { @@ -184,7 +184,7 @@ namespace WixToolset.Core } } - string value = Common.GetInnerText(node); + var value = Common.GetInnerText(node); if (null == id) { @@ -228,7 +228,7 @@ namespace WixToolset.Core var rightAligned = false; var leftScroll = false; - foreach (XAttribute attrib in node.Attributes()) + foreach (var attrib in node.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || LocalizationParser.WxlNamespace == attrib.Name.Namespace) { diff --git a/src/WixToolset.Core/OptimizeCA.cs b/src/WixToolset.Core/OptimizeCA.cs deleted file mode 100644 index 0d7b5e1a..00000000 --- a/src/WixToolset.Core/OptimizeCA.cs +++ /dev/null @@ -1,33 +0,0 @@ -// 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. - -namespace WixToolset.Core -{ - using System; - - /// - /// Values for the OptimizeCA MsiPatchMetdata property, which indicates whether custom actions can be skipped when applying the patch. - /// - [Flags] - public enum OptimizeCA // TODO: review where to place this data so it can not be exposed by WixToolset.Core - { - /// - /// No custom actions are skipped. - /// - None = 0, - - /// - /// Skip property (type 51) and directory (type 35) assignment custom actions. - /// - SkipAssignment = 1, - - /// - /// Skip immediate custom actions that are not property or directory assignment custom actions. - /// - SkipImmediate = 2, - - /// - /// Skip custom actions that run within the script. - /// - SkipDeferred = 4, - } -} diff --git a/src/WixToolset.Core/PatchSymbolFlagsType.cs b/src/WixToolset.Core/PatchSymbolFlagsType.cs deleted file mode 100644 index e751fd18..00000000 --- a/src/WixToolset.Core/PatchSymbolFlagsType.cs +++ /dev/null @@ -1,34 +0,0 @@ -// 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. - -namespace WixToolset.Core -{ - using System; - - /// - /// The following flags are used with PATCH_OPTION_DATA SymbolOptionFlags: - /// - [Flags] - public enum PatchSymbolFlagsType : uint - { - /// - /// don't use imagehlp.dll - /// - PATCH_SYMBOL_NO_IMAGEHLP = 0x00000001, - /// - /// don't fail patch due to imagehlp failures - /// - PATCH_SYMBOL_NO_FAILURES = 0x00000002, - /// - /// after matching decorated symbols, try to match remaining by undecorated names - /// - PATCH_SYMBOL_UNDECORATED_TOO = 0x00000004, - /// - /// (used internally) - /// - PATCH_SYMBOL_RESERVED1 = 0x80000000, - /// - /// - /// - MaxValue = PATCH_SYMBOL_NO_IMAGEHLP | PATCH_SYMBOL_NO_FAILURES | PATCH_SYMBOL_UNDECORATED_TOO - } -} diff --git a/src/WixToolset.Core/ResolvedCabinet.cs b/src/WixToolset.Core/ResolvedCabinet.cs index 9304b413..be04831f 100644 --- a/src/WixToolset.Core/ResolvedCabinet.cs +++ b/src/WixToolset.Core/ResolvedCabinet.cs @@ -7,7 +7,7 @@ namespace WixToolset.Core /// /// Data returned from build file manager ResolveCabinet callback. /// - public class ResolvedCabinet : IResolvedCabinet + internal class ResolvedCabinet : IResolvedCabinet { /// /// Gets or sets the build option for the resolved cabinet. diff --git a/src/WixToolset.Core/WixDistribution.cs b/src/WixToolset.Core/WixDistribution.cs deleted file mode 100644 index 4ceb8982..00000000 --- a/src/WixToolset.Core/WixDistribution.cs +++ /dev/null @@ -1,109 +0,0 @@ -// 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. - -using System; -using System.Diagnostics; -using System.Reflection; -using System.Resources; - -[assembly: NeutralResourcesLanguage("en-US")] - -namespace WixToolset -{ - /// - /// Distribution specific strings. - /// - internal static class WixDistribution - { - /// - /// News URL for the distribution. - /// - public static string NewsUrl = "http://wixtoolset.org/news/"; - - /// - /// Short product name for the distribution. - /// - public static string ShortProduct = "WiX Toolset"; - - /// - /// Support URL for the distribution. - /// - public static string SupportUrl = "http://wixtoolset.org/"; - - /// - /// Telemetry URL format for the distribution. - /// - public static string TelemetryUrlFormat = "http://wixtoolset.org/telemetry/v{0}/?r={1}"; - - /// - /// VS Extensions Landing page Url for the distribution. - /// - public static string VSExtensionsLandingUrl = "http://wixtoolset.org/releases/"; - - public static string ReplacePlaceholders(string original, Assembly assembly) - { - if (null != assembly) - { - FileVersionInfo fileVersion = FileVersionInfo.GetVersionInfo(assembly.Location); - - original = original.Replace("[FileComments]", fileVersion.Comments); - original = original.Replace("[FileCopyright]", fileVersion.LegalCopyright); - original = original.Replace("[FileProductName]", fileVersion.ProductName); - original = original.Replace("[FileVersion]", fileVersion.FileVersion); - - if (original.Contains("[FileVersionMajorMinor]")) - { - Version version = new Version(fileVersion.FileVersion); - original = original.Replace("[FileVersionMajorMinor]", String.Concat(version.Major, ".", version.Minor)); - } - - AssemblyCompanyAttribute company; - if (WixDistribution.TryGetAttribute(assembly, out company)) - { - original = original.Replace("[AssemblyCompany]", company.Company); - } - - AssemblyCopyrightAttribute copyright; - if (WixDistribution.TryGetAttribute(assembly, out copyright)) - { - original = original.Replace("[AssemblyCopyright]", copyright.Copyright); - } - - AssemblyDescriptionAttribute description; - if (WixDistribution.TryGetAttribute(assembly, out description)) - { - original = original.Replace("[AssemblyDescription]", description.Description); - } - - AssemblyProductAttribute product; - if (WixDistribution.TryGetAttribute(assembly, out product)) - { - original = original.Replace("[AssemblyProduct]", product.Product); - } - - AssemblyTitleAttribute title; - if (WixDistribution.TryGetAttribute(assembly, out title)) - { - original = original.Replace("[AssemblyTitle]", title.Title); - } - } - - original = original.Replace("[NewsUrl]", WixDistribution.NewsUrl); - original = original.Replace("[ShortProduct]", WixDistribution.ShortProduct); - original = original.Replace("[SupportUrl]", WixDistribution.SupportUrl); - return original; - } - - private static bool TryGetAttribute(Assembly assembly, out T attribute) where T : Attribute - { - attribute = null; - - object[] customAttributes = assembly.GetCustomAttributes(typeof(T), false); - if (null != customAttributes && 0 < customAttributes.Length) - { - attribute = customAttributes[0] as T; - } - - return null != attribute; - } - } -} diff --git a/src/WixToolset.Core/WixToolsetServiceProvider.cs b/src/WixToolset.Core/WixToolsetServiceProvider.cs index 646b21fa..d4f186de 100644 --- a/src/WixToolset.Core/WixToolsetServiceProvider.cs +++ b/src/WixToolset.Core/WixToolsetServiceProvider.cs @@ -25,6 +25,7 @@ namespace WixToolset.Core this.AddService((provider, singletons) => AddSingleton(singletons, new PreprocessHelper(provider))); this.AddService((provider, singletons) => AddSingleton(singletons, new BackendHelper(provider))); this.AddService((provider, singletons) => AddSingleton(singletons, new PathResolver())); + this.AddService((provider, singletons) => AddSingleton(singletons, new WixBranding())); // Transients. this.AddService((provider, singletons) => new CommandLineArguments(provider)); -- cgit v1.2.3-55-g6feb