From 854e616eb3516c7405691b679617aa08c1dd1cdd Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Thu, 26 Jul 2018 23:52:12 -0700 Subject: Support change of FileTransfer to interface --- src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs | 2 +- .../Bind/BindDatabaseCommand.cs | 23 +++---- .../Bind/CreateCabinetsCommand.cs | 38 ++++++------ .../Bind/ProcessUncompressedFilesCommand.cs | 18 +++--- src/WixToolset.Core/Bind/TransferFilesCommand.cs | 4 +- .../ExtensibilityServices/BackendHelper.cs | 70 ++++++++++++++++++++++ src/WixToolset.Core/FileTransfer.cs | 22 +++++++ src/WixToolset.Core/Layout.cs | 12 ++-- src/WixToolset.Core/LayoutContext.cs | 2 +- src/WixToolset.Core/WixToolsetServiceProvider.cs | 1 + 10 files changed, 143 insertions(+), 49 deletions(-) create mode 100644 src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs create mode 100644 src/WixToolset.Core/FileTransfer.cs (limited to 'src') diff --git a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs index 8846cc83..bd282f54 100644 --- a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs +++ b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs @@ -99,7 +99,7 @@ namespace WixToolset.Core.Burn public IVariableResolver VariableResolver { private get; set; } - public IEnumerable FileTransfers { get; private set; } + public IEnumerable FileTransfers { get; private set; } public IEnumerable ContentFilePaths { get; private set; } diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs index 119cbd55..3aad0709 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs @@ -26,6 +26,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind { this.Messaging = context.ServiceProvider.GetService(); + this.BackendHelper = context.ServiceProvider.GetService(); + this.TableDefinitions = WindowsInstallerStandardInternal.GetTableDefinitions(); this.CabbingThreadCount = context.CabbingThreadCount; @@ -43,6 +45,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind this.BackendExtensions = backendExtension; } + private IMessaging Messaging { get; } + + private IBackendHelper BackendHelper { get; } + private int Codepage { get; } private int CabbingThreadCount { get; } @@ -63,8 +69,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind private Intermediate Intermediate { get; } - private IMessaging Messaging { get; } - private string OutputPath { get; } private bool SuppressAddingValidationRows { get; } @@ -77,7 +81,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind private Validator Validator { get; } - public IEnumerable FileTransfers { get; private set; } + public IEnumerable FileTransfers { get; private set; } public IEnumerable ContentFilePaths { get; private set; } @@ -87,7 +91,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind { var section = this.Intermediate.Sections.Single(); - var fileTransfers = new List(); + var fileTransfers = new List(); var containsMergeModules = false; var suppressedTableNames = new HashSet(); @@ -375,7 +379,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind { this.Messaging.Write(VerboseMessages.CreatingCabinetFiles()); - var command = new CreateCabinetsCommand(); + var command = new CreateCabinetsCommand(this.BackendHelper); command.CabbingThreadCount = this.CabbingThreadCount; command.CabCachePath = this.CabCachePath; command.DefaultCompressionLevel = this.DefaultCompressionLevel; @@ -415,11 +419,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind string tempDatabaseFile = Path.Combine(this.IntermediateFolder, Path.GetFileName(this.OutputPath)); this.GenerateDatabase(output, tempDatabaseFile, false, false); - if (FileTransfer.TryCreate(tempDatabaseFile, this.OutputPath, true, output.Type.ToString(), null, out var transfer)) // note where this database needs to move in the future - { - transfer.Built = true; - fileTransfers.Add(transfer); - } + var transfer = this.BackendHelper.CreateFileTransfer(tempDatabaseFile, this.OutputPath, true, FileTransferType.Built); // note where this database needs to move in the future + fileTransfers.Add(transfer); // Stop processing if an error previously occurred. if (this.Messaging.EncounteredError) @@ -491,7 +492,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind // Process uncompressed files. if (!this.Messaging.EncounteredError && !this.SuppressLayout && uncompressedFiles.Any()) { - var command = new ProcessUncompressedFilesCommand(section); + var command = new ProcessUncompressedFilesCommand(section, this.BackendHelper); command.Compressed = compressed; command.FileFacades = uncompressedFiles; command.LayoutDirectory = layoutDirectory; diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs index 328bb082..ed8f0ece 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs @@ -26,19 +26,23 @@ namespace WixToolset.Core.WindowsInstaller.Bind public const int DefaultMaximumUncompressedMediaSize = 200; // Default value is 200 MB public const int MaxValueOfMaxCabSizeForLargeFileSplitting = 2 * 1024; // 2048 MB (i.e. 2 GB) - private List fileTransfers; + private List fileTransfers; private FileSplitCabNamesCallback newCabNamesCallBack; private Dictionary lastCabinetAddedToMediaTable; // Key is First Cabinet Name, Value is Last Cabinet Added in the Split Sequence - public CreateCabinetsCommand() + public CreateCabinetsCommand(IBackendHelper backendHelper) { - this.fileTransfers = new List(); + this.fileTransfers = new List(); this.newCabNamesCallBack = this.NewCabNamesCallBack; + + this.BackendHelper = backendHelper; } + public IBackendHelper BackendHelper { get; } + /// /// Sets the number of threads to use for cabinet creation. /// @@ -72,7 +76,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind public IEnumerable WixMediaTuples { private get; set; } - public IEnumerable FileTransfers => this.fileTransfers; + public IEnumerable FileTransfers => this.fileTransfers; /// Output to generate image for. /// Array of files to be transfered. @@ -186,7 +190,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind /// Collection of files in this cabinet. /// Array of files to be transfered. /// created CabinetWorkItem object - private CabinetWorkItem CreateCabinetWorkItem(Output output, string cabinetDir, MediaTuple mediaRow, CompressionLevel compressionLevel, IEnumerable fileFacades, List fileTransfers) + private CabinetWorkItem CreateCabinetWorkItem(Output output, string cabinetDir, MediaTuple mediaRow, CompressionLevel compressionLevel, IEnumerable fileFacades, List fileTransfers) { CabinetWorkItem cabinetWorkItem = null; string tempCabinetFileX = Path.Combine(this.TempFilesLocation, mediaRow.Cabinet); @@ -254,12 +258,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind } else { - string destinationPath = Path.Combine(cabinetDir, mediaRow.Cabinet); - if (FileTransfer.TryCreate(resolvedCabinet.Path, destinationPath, CabinetBuildOption.BuildAndMove == resolvedCabinet.BuildOption, "Cabinet", mediaRow.SourceLineNumbers, out var transfer)) - { - transfer.Built = true; - fileTransfers.Add(transfer); - } + var destinationPath = Path.Combine(cabinetDir, mediaRow.Cabinet); + var transfer = this.BackendHelper.CreateFileTransfer(resolvedCabinet.Path, destinationPath, CabinetBuildOption.BuildAndMove == resolvedCabinet.BuildOption, FileTransferType.Built, mediaRow.SourceLineNumbers); + fileTransfers.Add(transfer); } return cabinetWorkItem; @@ -315,21 +316,18 @@ namespace WixToolset.Core.WindowsInstaller.Bind bool transferAdded = false; // Used for Error Handling // Create File Transfer for new Cabinet using transfer of Base Cabinet - foreach (FileTransfer transfer in this.FileTransfers) + foreach (var transfer in this.FileTransfers) { if (firstCabinetName.Equals(Path.GetFileName(transfer.Source), StringComparison.InvariantCultureIgnoreCase)) { string newCabSourcePath = Path.Combine(Path.GetDirectoryName(transfer.Source), newCabinetName); string newCabTargetPath = Path.Combine(Path.GetDirectoryName(transfer.Destination), newCabinetName); - FileTransfer newTransfer; - if (FileTransfer.TryCreate(newCabSourcePath, newCabTargetPath, transfer.Move, "Cabinet", transfer.SourceLineNumbers, out newTransfer)) - { - newTransfer.Built = true; - this.fileTransfers.Add(newTransfer); - transferAdded = true; - break; - } + var newTransfer = this.BackendHelper.CreateFileTransfer(newCabSourcePath, newCabTargetPath, transfer.Move, FileTransferType.Built, transfer.SourceLineNumbers); + this.fileTransfers.Add(newTransfer); + + transferAdded = true; + break; } } diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/ProcessUncompressedFilesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/ProcessUncompressedFilesCommand.cs index 4b143ead..b09f92bb 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/ProcessUncompressedFilesCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/ProcessUncompressedFilesCommand.cs @@ -11,6 +11,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind using WixToolset.Data; using WixToolset.Data.Tuples; using WixToolset.Extensibility.Data; + using WixToolset.Extensibility.Services; using WixToolset.Msi; /// @@ -18,13 +19,16 @@ namespace WixToolset.Core.WindowsInstaller.Bind /// internal class ProcessUncompressedFilesCommand { - public ProcessUncompressedFilesCommand(IntermediateSection section) + public ProcessUncompressedFilesCommand(IntermediateSection section, IBackendHelper backendHelper) { this.Section = section; + this.BackendHelper = backendHelper; } private IntermediateSection Section { get; } + public IBackendHelper BackendHelper { get; } + public string DatabasePath { private get; set; } public IEnumerable FileFacades { private get; set; } @@ -37,11 +41,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind public Func ResolveMedia { private get; set; } - public IEnumerable FileTransfers { get; private set; } + public IEnumerable FileTransfers { get; private set; } public void Execute() { - var fileTransfers = new List(); + var fileTransfers = new List(); var directories = new Dictionary(); @@ -103,11 +107,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind } // finally put together the base media layout path and the relative file layout path - string fileLayoutPath = Path.Combine(mediaLayoutDirectory, relativeFileLayoutPath); - if (FileTransfer.TryCreate(facade.WixFile.Source.Path, fileLayoutPath, false, "File", facade.File.SourceLineNumbers, out var transfer)) - { - fileTransfers.Add(transfer); - } + var fileLayoutPath = Path.Combine(mediaLayoutDirectory, relativeFileLayoutPath); + var transfer = this.BackendHelper.CreateFileTransfer(facade.WixFile.Source.Path, fileLayoutPath, false, FileTransferType.Content, facade.File.SourceLineNumbers); + fileTransfers.Add(transfer); } } } diff --git a/src/WixToolset.Core/Bind/TransferFilesCommand.cs b/src/WixToolset.Core/Bind/TransferFilesCommand.cs index 79f0cd81..b89d3d03 100644 --- a/src/WixToolset.Core/Bind/TransferFilesCommand.cs +++ b/src/WixToolset.Core/Bind/TransferFilesCommand.cs @@ -13,7 +13,7 @@ namespace WixToolset.Core.Bind internal class TransferFilesCommand { - public TransferFilesCommand(IMessaging messaging, IEnumerable extensions, IEnumerable fileTransfers, bool suppressAclReset) + public TransferFilesCommand(IMessaging messaging, IEnumerable extensions, IEnumerable fileTransfers, bool suppressAclReset) { this.FileSystem = new FileSystem(extensions); this.Messaging = messaging; @@ -25,7 +25,7 @@ namespace WixToolset.Core.Bind private IMessaging Messaging { get; } - private IEnumerable FileTransfers { get; } + private IEnumerable FileTransfers { get; } private bool SuppressAclReset { get; } diff --git a/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs b/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs new file mode 100644 index 00000000..0e5c4b5b --- /dev/null +++ b/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs @@ -0,0 +1,70 @@ +// 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.IO; + using WixToolset.Data; + using WixToolset.Extensibility.Data; + using WixToolset.Extensibility.Services; + + internal class BackendHelper : IBackendHelper + { + private static readonly string[] ReservedFileNames = { "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9" }; + + public BackendHelper(IServiceProvider serviceProvider) + { + this.Messaging = serviceProvider.GetService(); + } + + private IMessaging Messaging { get; } + + public IFileTransfer CreateFileTransfer(string source, string destination, bool move, FileTransferType type, SourceLineNumber sourceLineNumbers) + { + var sourceFullPath = GetValidatedFullPath(sourceLineNumbers, source); + + var destinationFullPath = GetValidatedFullPath(sourceLineNumbers, destination); + + return (String.IsNullOrEmpty(sourceFullPath) || String.IsNullOrEmpty(destinationFullPath)) ? null : new FileTransfer + { + Source = sourceFullPath, + Destination = destinationFullPath, + Move = move, + Type = type, + SourceLineNumbers = sourceLineNumbers, + Redundant = String.Equals(sourceFullPath, destinationFullPath, StringComparison.OrdinalIgnoreCase) + }; + } + + private string GetValidatedFullPath(SourceLineNumber sourceLineNumbers, string path) + { + try + { + var result = Path.GetFullPath(path); + + var filename = Path.GetFileName(result); + + foreach (var reservedName in ReservedFileNames) + { + if (reservedName.Equals(filename, StringComparison.OrdinalIgnoreCase)) + { + this.Messaging.Write(ErrorMessages.InvalidFileName(sourceLineNumbers, path)); + return null; + } + } + + return result; + } + catch (ArgumentException) + { + this.Messaging.Write(ErrorMessages.InvalidFileName(sourceLineNumbers, path)); + } + catch (PathTooLongException) + { + this.Messaging.Write(ErrorMessages.PathTooLong(sourceLineNumbers, path)); + } + + return null; + } + } +} diff --git a/src/WixToolset.Core/FileTransfer.cs b/src/WixToolset.Core/FileTransfer.cs new file mode 100644 index 00000000..9da406eb --- /dev/null +++ b/src/WixToolset.Core/FileTransfer.cs @@ -0,0 +1,22 @@ +// 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 WixToolset.Data; + using WixToolset.Extensibility.Data; + + internal class FileTransfer : IFileTransfer + { + public string Source { get; set; } + + public string Destination { get; set; } + + public bool Move { get; set; } + + public SourceLineNumber SourceLineNumbers { get; set; } + + public FileTransferType Type { get; set; } + + public bool Redundant { get; set; } + } +} diff --git a/src/WixToolset.Core/Layout.cs b/src/WixToolset.Core/Layout.cs index a5e885e5..28c9d5fc 100644 --- a/src/WixToolset.Core/Layout.cs +++ b/src/WixToolset.Core/Layout.cs @@ -28,7 +28,7 @@ namespace WixToolset.Core private IMessaging Messaging { get; } - public IEnumerable FileTransfers { get; set; } + public IEnumerable FileTransfers { get; set; } public IEnumerable ContentFilePaths { get; set; } @@ -124,14 +124,14 @@ namespace WixToolset.Core /// /// Path to write file. /// Collection of files that were transferred to the output directory. - private void CreateOutputsFile(string path, IEnumerable fileTransfers) + private void CreateOutputsFile(string path, IEnumerable fileTransfers) { var directory = Path.GetDirectoryName(path); Directory.CreateDirectory(directory); using (var outputs = new StreamWriter(path, false)) { - foreach (FileTransfer fileTransfer in fileTransfers) + foreach (var fileTransfer in fileTransfers) { // Don't list files where the source is the same as the destination since // that might be the only place the file exists. The outputs file is often @@ -149,18 +149,18 @@ namespace WixToolset.Core /// /// Path to write file. /// Collection of files that were transferred to the output directory. - private void CreateBuiltOutputsFile(string path, IEnumerable fileTransfers) + private void CreateBuiltOutputsFile(string path, IEnumerable fileTransfers) { var directory = Path.GetDirectoryName(path); Directory.CreateDirectory(directory); using (var outputs = new StreamWriter(path, false)) { - foreach (FileTransfer fileTransfer in fileTransfers) + foreach (var fileTransfer in fileTransfers) { // Only write the built file transfers. Also, skip redundant // files for the same reason spelled out in this.CreateOutputsFile(). - if (fileTransfer.Built && !fileTransfer.Redundant) + if (fileTransfer.Type == FileTransferType.Built && !fileTransfer.Redundant) { outputs.WriteLine(fileTransfer.Destination); } diff --git a/src/WixToolset.Core/LayoutContext.cs b/src/WixToolset.Core/LayoutContext.cs index af0df518..172cea65 100644 --- a/src/WixToolset.Core/LayoutContext.cs +++ b/src/WixToolset.Core/LayoutContext.cs @@ -20,7 +20,7 @@ namespace WixToolset.Core public IEnumerable FileSystemExtensions { get; set; } - public IEnumerable FileTransfers { get; set; } + public IEnumerable FileTransfers { get; set; } public IEnumerable ContentFilePaths { get; set; } diff --git a/src/WixToolset.Core/WixToolsetServiceProvider.cs b/src/WixToolset.Core/WixToolsetServiceProvider.cs index dd6da8c8..ffcdbdd1 100644 --- a/src/WixToolset.Core/WixToolsetServiceProvider.cs +++ b/src/WixToolset.Core/WixToolsetServiceProvider.cs @@ -22,6 +22,7 @@ namespace WixToolset.Core { typeof(ITupleDefinitionCreator), (provider, singletons) => AddSingleton(singletons, typeof(ITupleDefinitionCreator), new TupleDefinitionCreator(provider)) }, { typeof(IParseHelper), (provider, singletons) => AddSingleton(singletons, typeof(IParseHelper), new ParseHelper(provider)) }, { typeof(IPreprocessHelper), (provider, singletons) => AddSingleton(singletons, typeof(IPreprocessHelper), new PreprocessHelper(provider)) }, + { typeof(IBackendHelper), (provider, singletons) => AddSingleton(singletons, typeof(IBackendHelper), new BackendHelper(provider)) }, { typeof(IWindowsInstallerBackendHelper), (provider, singletons) => AddSingleton(singletons, typeof(IWindowsInstallerBackendHelper), new WindowsInstallerBackendHelper(provider)) }, // Transients. -- cgit v1.2.3-55-g6feb