From 088dc648a3478e2cacdbdab1cb1782556642ee69 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Sun, 3 Sep 2017 16:51:39 -0700 Subject: Initial commit --- src/WixToolset.Core.Native/CabInterop.cs | 312 +++++++++++++++++++++ .../WixToolset.Core.Native.csproj | 23 ++ .../WixToolset.Core.Native.nuspec | 24 ++ 3 files changed, 359 insertions(+) create mode 100644 src/WixToolset.Core.Native/CabInterop.cs create mode 100644 src/WixToolset.Core.Native/WixToolset.Core.Native.csproj create mode 100644 src/WixToolset.Core.Native/WixToolset.Core.Native.nuspec (limited to 'src/WixToolset.Core.Native') diff --git a/src/WixToolset.Core.Native/CabInterop.cs b/src/WixToolset.Core.Native/CabInterop.cs new file mode 100644 index 00000000..6ad11c67 --- /dev/null +++ b/src/WixToolset.Core.Native/CabInterop.cs @@ -0,0 +1,312 @@ +// 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.Native +{ + using System; + using System.Diagnostics.CodeAnalysis; + using System.Text; + using System.Runtime.InteropServices; + // using WixToolset.Msi; + // using WixToolset.Msi.Interop; + + /// + /// The native methods. + /// + public sealed class NativeMethods + { + /// + /// Starts creating a cabinet. + /// + /// Name of cabinet to create. + /// Directory to create cabinet in. + /// Maximum number of files that will be added to cabinet. + /// Maximum size of the cabinet. + /// Maximum threshold in the cabinet. + /// Type of compression to use in the cabinet. + /// Handle to opened cabinet. + [DllImport("winterop.dll", EntryPoint = "CreateCabBegin", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] + public static extern void CreateCabBegin(string cabinetName, string cabinetDirectory, uint maxFiles, uint maxSize, uint maxThreshold, uint compressionType, out IntPtr contextHandle); + + /// + /// Adds a file to an open cabinet. + /// + /// Full path to file to add to cabinet. + /// Name of file in cabinet. + /// Handle to open cabinet. + // [DllImport("winterop.dll", EntryPoint = "CreateCabAddFile", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] + // public static extern void CreateCabAddFile(string file, string token, MsiInterop.MSIFILEHASHINFO fileHash, IntPtr contextHandle); + + /// + /// Closes a cabinet. + /// + /// Handle to open cabinet to close. + /// Address of Binder's cabinet split callback + [DllImport("winterop.dll", EntryPoint = "CreateCabFinish", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] + public static extern void CreateCabFinish(IntPtr contextHandle, IntPtr newCabNamesCallBackAddress); + + /// + /// Cancels cabinet creation. + /// + /// Handle to open cabinet to cancel. + [DllImport("winterop.dll", EntryPoint = "CreateCabCancel", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] + public static extern void CreateCabCancel(IntPtr contextHandle); + + /// + /// Initializes cabinet extraction. + /// + [DllImport("winterop.dll", EntryPoint = "ExtractCabBegin", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] + public static extern void ExtractCabBegin(); + + /// + /// Extracts files from cabinet. + /// + /// Path to cabinet to extract files from. + /// Directory to extract files to. + [DllImport("winterop.dll", EntryPoint = "ExtractCab", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true, PreserveSig = false)] + public static extern void ExtractCab(string cabinet, string extractDirectory); + + /// + /// Cleans up after cabinet extraction. + /// + [DllImport("winterop.dll", EntryPoint = "ExtractCabFinish", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] + public static extern void ExtractCabFinish(); + + /// + /// Initializes cabinet enumeration. + /// + [DllImport("winterop.dll", EntryPoint = "EnumerateCabBegin", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] + public static extern void EnumerateCabBegin(); + + /// + /// Enumerates files from cabinet. + /// + /// Path to cabinet to enumerate files from. + /// callback that gets each file. + [DllImport("winterop.dll", EntryPoint = "EnumerateCab", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true, PreserveSig = false)] + public static extern void EnumerateCab(string cabinet, CabInterop.PFNNOTIFY notify); + + /// + /// Cleans up after cabinet enumeration. + /// + [DllImport("winterop.dll", EntryPoint = "EnumerateCabFinish", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] + public static extern void EnumerateCabFinish(); + + /// + /// Resets the DACL on an array of files to "empty". + /// + /// Array of file reset ACL to "empty". + /// Number of file paths in array. + [DllImport("winterop.dll", EntryPoint = "ResetAcls", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] + public static extern void ResetAcls(string[] files, uint fileCount); + + /// + /// Gets the hash of the pCertContext->pCertInfo->SubjectPublicKeyInfo using ::CryptHashPublicKeyInfo() which does not seem + /// to be exposed by .NET Frameowkr. + /// + /// Pointer to a CERT_CONTEXT struct with public key information to hash. + /// Number of file paths in array. + [DllImport("winterop.dll", EntryPoint = "HashPublicKeyInfo", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] + public static extern void HashPublicKeyInfo(IntPtr certContext, byte[] publicKeyInfoHashed, ref uint sizePublicKeyInfoHashed); + + /// + /// Converts file time to a local file time. + /// + /// file time + /// local file time + /// true if successful, false otherwise + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool FileTimeToLocalFileTime(ref long fileTime, ref long localTime); + + /// + /// Converts file time to a MS-DOS time. + /// + /// file time + /// MS-DOS date + /// MS-DOS time + /// true if successful, false otherwise + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool FileTimeToDosDateTime(ref long fileTime, out ushort wFatDate, out ushort wFatTime); + } + + /// + /// Interop class for the winterop.dll. + /// + public static class CabInterop + { + /// + /// Delegate type that's called by cabinet api for every file in cabinet. + /// + /// NOTIFICATIONTYPE + /// NOTIFICATION + /// 0 for success, -1 otherwise + public delegate Int32 PFNNOTIFY(NOTIFICATIONTYPE fdint, NOTIFICATION pfdin); + + /// + /// Wraps FDINOTIFICATIONTYPE. + /// + public enum NOTIFICATIONTYPE : int + { + /// Info about the cabinet. + CABINET_INFO, + /// One or more files are continued. + PARTIAL_FILE, + /// Called for each file in cabinet. + COPY_FILE, + /// Called after all of the data has been written to a target file. + CLOSE_FILE_INFO, + /// A file is continued to the next cabinet. + NEXT_CABINET, + /// Called once after a call to FDICopy() starts scanning a CAB's CFFILE entries, and again when there are no more CFFILE entries. + ENUMERATE, + } + + /// + /// Converts DateTime to MS-DOS date and time which cabinet uses. + /// + /// DateTime + /// MS-DOS date + /// MS-DOS time + public static void DateTimeToCabDateAndTime(DateTime dateTime, out ushort cabDate, out ushort cabTime) + { + // dateTime.ToLocalTime() does not match FileTimeToLocalFileTime() for some reason. + // so we need to call FileTimeToLocalFileTime() from kernel32.dll. + long filetime = dateTime.ToFileTime(); + long localTime = 0; + NativeMethods.FileTimeToLocalFileTime(ref filetime, ref localTime); + NativeMethods.FileTimeToDosDateTime(ref localTime, out cabDate, out cabTime); + } + + /// + /// Wraps FDINOTIFICATION. + /// + [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public class NOTIFICATION + { + private int cb; + [MarshalAs(UnmanagedType.LPStr)] + private string psz1; + [MarshalAs(UnmanagedType.LPStr)] + private string psz2; + [MarshalAs(UnmanagedType.LPStr)] + private string psz3; + private IntPtr pv; + + private IntPtr hf; + + private ushort date; + private ushort time; + private ushort attribs; + private ushort setID; + private ushort cabinet; + private ushort folder; + private int fdie; + + /// + /// Uncompressed size of file. + /// + public int Cb + { + get { return this.cb; } + } + + /// + /// File name in cabinet. + /// + public String Psz1 + { + get { return this.psz1; } + } + + /// + /// Name of next disk. + /// + public string Psz2 + { + get { return this.psz2; } + } + + /// + /// Points to a 256 character buffer. + /// + public string Psz3 + { + get { return this.psz3; } + } + + /// + /// Value for client. + /// + public IntPtr Pv + { + get { return this.pv; } + } + + /// + /// Not used. + /// + public Int32 Hf + { + get { return (Int32)this.hf; } + } + + /// + /// Last modified MS-DOS date. + /// + public ushort Date + { + get { return this.date; } + } + + /// + /// Last modified MS-DOS time. + /// + public ushort Time + { + get { return this.time; } + } + + /// + /// File attributes. + /// + public ushort Attribs + { + get { return this.attribs; } + } + + /// + /// Cabinet set ID (a random 16-bit number). + /// + public ushort SetID + { + get { return this.setID; } + } + + /// + /// Cabinet number within cabinet set (0-based). + /// + public ushort Cabinet + { + get { return this.cabinet; } + } + + /// + /// File's folder index. + /// + public ushort Folder + { + get { return this.folder; } + } + + /// + /// Error code. + /// + public int Fdie + { + get { return this.fdie; } + } + } + } +} diff --git a/src/WixToolset.Core.Native/WixToolset.Core.Native.csproj b/src/WixToolset.Core.Native/WixToolset.Core.Native.csproj new file mode 100644 index 00000000..858b9be2 --- /dev/null +++ b/src/WixToolset.Core.Native/WixToolset.Core.Native.csproj @@ -0,0 +1,23 @@ + + + + netstandard2.0 + $(MSBuildThisFileName).nuspec + + + + + + + + + + + $(OutputPath) + Configuration=$(Configuration);Id=$(MSBuildThisFileName);Version=$(BuildVersionSimple);Authors=$(Authors);Copyright=$(Copyright);Description=$(Description) + + + diff --git a/src/WixToolset.Core.Native/WixToolset.Core.Native.nuspec b/src/WixToolset.Core.Native/WixToolset.Core.Native.nuspec new file mode 100644 index 00000000..68d154c8 --- /dev/null +++ b/src/WixToolset.Core.Native/WixToolset.Core.Native.nuspec @@ -0,0 +1,24 @@ + + + + $id$ + $version$ + $authors$ + $authors$ + https://github.com/wixtoolset/Core.Native/blob/master/LICENSE.TXT + https://github.com/wixtoolset/Core.Native + false + $description$ + $copyright$ + + + + + + + + + + + + -- cgit v1.2.3-55-g6feb