// 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.Bind { using System; using System.IO; using WixToolset; using WixToolset.Data; /// /// Structure used for all file transfer information. /// internal class FileTransfer { /// Source path to file. public string Source { get; set; } /// Destination path for file. public string Destination { get; set; } /// Flag if file should be moved (optimal). public bool Move { get; set; } /// Optional source line numbers where this file transfer orginated. public SourceLineNumber SourceLineNumbers { get; set; } /// Optional type of file this transfer is moving or copying. public string Type { get; set; } /// Indicates whether the file transer was a built by this build or copied from other some build. internal bool Built { get; set; } /// Set during layout of media when the file transfer when the source and target resolve to the same path. internal bool Redundant { get; set; } /// /// Prefer the TryCreate() method to create FileTransfer objects. /// /// Source path to file. /// Destination path for file. /// File if file should be moved (optimal). /// Optional type of file this transfer is transferring. /// Optional source line numbers wher this transfer originated. public FileTransfer(string source, string destination, bool move, string type = null, SourceLineNumber sourceLineNumbers = null) { this.Source = source; this.Destination = destination; this.Move = move; this.Type = type; this.SourceLineNumbers = sourceLineNumbers; } /// /// Creates a file transfer if the source and destination are different. /// /// Source path to file. /// Destination path for file. /// File if file should be moved (optimal). /// Optional type of file this transfer is transferring. /// Optional source line numbers wher this transfer originated. /// true if the source and destination are the different, false if no file transfer is created. public static bool TryCreate(string source, string destination, bool move, string type, SourceLineNumber sourceLineNumbers, out FileTransfer transfer) { string sourceFullPath = GetValidatedFullPath(sourceLineNumbers, source); string fileLayoutFullPath = GetValidatedFullPath(sourceLineNumbers, destination); // if the current source path (where we know that the file already exists) and the resolved // path as dictated by the Directory table are not the same, then propagate the file. The // image that we create may have already been done by some other process other than the linker, so // there is no reason to copy the files to the resolved source if they are already there. if (String.Equals(sourceFullPath, fileLayoutFullPath, StringComparison.OrdinalIgnoreCase)) { transfer = null; return false; } transfer = new FileTransfer(source, destination, move, type, sourceLineNumbers); return true; } private static string GetValidatedFullPath(SourceLineNumber sourceLineNumbers, string path) { string result; try { result = Path.GetFullPath(path); string filename = Path.GetFileName(result); foreach (string reservedName in Common.ReservedFileNames) { if (reservedName.Equals(filename, StringComparison.OrdinalIgnoreCase)) { throw new WixException(WixErrors.InvalidFileName(sourceLineNumbers, path)); } } } catch (System.ArgumentException) { throw new WixException(WixErrors.InvalidFileName(sourceLineNumbers, path)); } catch (System.IO.PathTooLongException) { throw new WixException(WixErrors.PathTooLong(sourceLineNumbers, path)); } return result; } } }