// 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 false
namespace WixToolset.Cab.Interop
{
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)]
internal 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)]
internal 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)]
internal 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)]
internal static extern void CreateCabCancel(IntPtr contextHandle);
///
/// Initializes cabinet extraction.
///
[DllImport("winterop.dll", EntryPoint = "ExtractCabBegin", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
internal 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)]
internal 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)]
internal static extern void ExtractCabFinish();
///
/// Initializes cabinet enumeration.
///
[DllImport("winterop.dll", EntryPoint = "EnumerateCabBegin", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
internal 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)]
internal 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)]
internal 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)]
internal 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)]
internal 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)]
internal 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)]
internal static extern bool FileTimeToDosDateTime(ref long fileTime, out ushort wFatDate, out ushort wFatTime);
}
///
/// Interop class for the winterop.dll.
///
internal 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; }
}
}
}
}
#endif