aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core.Native
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core.Native')
-rw-r--r--src/WixToolset.Core.Native/CabInterop.cs309
-rw-r--r--src/WixToolset.Core.Native/Cabinet.cs89
-rw-r--r--src/WixToolset.Core.Native/CabinetFileInfo.cs2
-rw-r--r--src/WixToolset.Core.Native/DateTimeInterop.cs48
-rw-r--r--src/WixToolset.Core.Native/Msi/MSIFILEHASHINFO.cs (renamed from src/WixToolset.Core.Native/MSIFILEHASHINFO.cs)2
5 files changed, 52 insertions, 398 deletions
diff --git a/src/WixToolset.Core.Native/CabInterop.cs b/src/WixToolset.Core.Native/CabInterop.cs
deleted file mode 100644
index e08c1b90..00000000
--- a/src/WixToolset.Core.Native/CabInterop.cs
+++ /dev/null
@@ -1,309 +0,0 @@
1// 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.
2
3namespace WixToolset.Core.Native
4{
5 using System;
6 using System.Runtime.InteropServices;
7
8 /// <summary>
9 /// Interop class for the winterop.dll.
10 /// </summary>
11 public static class CabInterop
12 {
13 /// <summary>
14 /// Delegate type that's called by cabinet api for every file in cabinet.
15 /// </summary>
16 /// <param name="fdint">NOTIFICATIONTYPE</param>
17 /// <param name="pfdin">NOTIFICATION</param>
18 /// <returns>0 for success, -1 otherwise</returns>
19 public delegate Int32 PFNNOTIFY(NOTIFICATIONTYPE fdint, NOTIFICATION pfdin);
20
21 /// <summary>
22 /// Wraps FDINOTIFICATIONTYPE.
23 /// </summary>
24 public enum NOTIFICATIONTYPE : int
25 {
26 /// <summary>Info about the cabinet.</summary>
27 CABINET_INFO,
28 /// <summary>One or more files are continued.</summary>
29 PARTIAL_FILE,
30 /// <summary>Called for each file in cabinet.</summary>
31 COPY_FILE,
32 /// <summary>Called after all of the data has been written to a target file.</summary>
33 CLOSE_FILE_INFO,
34 /// <summary>A file is continued to the next cabinet.</summary>
35 NEXT_CABINET,
36 /// <summary>Called once after a call to FDICopy() starts scanning a CAB's CFFILE entries, and again when there are no more CFFILE entries.</summary>
37 ENUMERATE,
38 }
39
40 /// <summary>
41 /// Converts DateTime to MS-DOS date and time which cabinet uses.
42 /// </summary>
43 /// <param name="dateTime">DateTime</param>
44 /// <param name="cabDate">MS-DOS date</param>
45 /// <param name="cabTime">MS-DOS time</param>
46 public static void DateTimeToCabDateAndTime(DateTime dateTime, out ushort cabDate, out ushort cabTime)
47 {
48 // dateTime.ToLocalTime() does not match FileTimeToLocalFileTime() for some reason.
49 // so we need to call FileTimeToLocalFileTime() from kernel32.dll.
50 long filetime = dateTime.ToFileTime();
51 long localTime = 0;
52 NativeMethods.FileTimeToLocalFileTime(ref filetime, ref localTime);
53 NativeMethods.FileTimeToDosDateTime(ref localTime, out cabDate, out cabTime);
54 }
55
56 /// <summary>
57 /// Wraps FDINOTIFICATION.
58 /// </summary>
59 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
60 public class NOTIFICATION
61 {
62 private int cb;
63 [MarshalAs(UnmanagedType.LPStr)]
64 private string psz1;
65 [MarshalAs(UnmanagedType.LPStr)]
66 private string psz2;
67 [MarshalAs(UnmanagedType.LPStr)]
68 private string psz3;
69 private IntPtr pv;
70
71 private IntPtr hf;
72
73 private ushort date;
74 private ushort time;
75 private ushort attribs;
76 private ushort setID;
77 private ushort cabinet;
78 private ushort folder;
79 private int fdie;
80
81 /// <summary>
82 /// Uncompressed size of file.
83 /// </summary>
84 public int Cb
85 {
86 get { return this.cb; }
87 }
88
89 /// <summary>
90 /// File name in cabinet.
91 /// </summary>
92 public String Psz1
93 {
94 get { return this.psz1; }
95 }
96
97 /// <summary>
98 /// Name of next disk.
99 /// </summary>
100 public string Psz2
101 {
102 get { return this.psz2; }
103 }
104
105 /// <summary>
106 /// Points to a 256 character buffer.
107 /// </summary>
108 public string Psz3
109 {
110 get { return this.psz3; }
111 }
112
113 /// <summary>
114 /// Value for client.
115 /// </summary>
116 public IntPtr Pv
117 {
118 get { return this.pv; }
119 }
120
121 /// <summary>
122 /// Not used.
123 /// </summary>
124 public Int32 Hf
125 {
126 get { return (Int32)this.hf; }
127 }
128
129 /// <summary>
130 /// Last modified MS-DOS date.
131 /// </summary>
132 public ushort Date
133 {
134 get { return this.date; }
135 }
136
137 /// <summary>
138 /// Last modified MS-DOS time.
139 /// </summary>
140 public ushort Time
141 {
142 get { return this.time; }
143 }
144
145 /// <summary>
146 /// File attributes.
147 /// </summary>
148 public ushort Attribs
149 {
150 get { return this.attribs; }
151 }
152
153 /// <summary>
154 /// Cabinet set ID (a random 16-bit number).
155 /// </summary>
156 public ushort SetID
157 {
158 get { return this.setID; }
159 }
160
161 /// <summary>
162 /// Cabinet number within cabinet set (0-based).
163 /// </summary>
164 public ushort Cabinet
165 {
166 get { return this.cabinet; }
167 }
168
169 /// <summary>
170 /// File's folder index.
171 /// </summary>
172 public ushort Folder
173 {
174 get { return this.folder; }
175 }
176
177 /// <summary>
178 /// Error code.
179 /// </summary>
180 public int Fdie
181 {
182 get { return this.fdie; }
183 }
184 }
185
186 /// <summary>
187 /// The native methods.
188 /// </summary>
189 private class NativeMethods
190 {
191 /// <summary>
192 /// Starts creating a cabinet.
193 /// </summary>
194 /// <param name="cabinetName">Name of cabinet to create.</param>
195 /// <param name="cabinetDirectory">Directory to create cabinet in.</param>
196 /// <param name="maxFiles">Maximum number of files that will be added to cabinet.</param>
197 /// <param name="maxSize">Maximum size of the cabinet.</param>
198 /// <param name="maxThreshold">Maximum threshold in the cabinet.</param>
199 /// <param name="compressionType">Type of compression to use in the cabinet.</param>
200 /// <param name="contextHandle">Handle to opened cabinet.</param>
201 [DllImport("winterop.dll", EntryPoint = "CreateCabBegin", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
202 public static extern void CreateCabBegin(string cabinetName, string cabinetDirectory, uint maxFiles, uint maxSize, uint maxThreshold, uint compressionType, out IntPtr contextHandle);
203
204 /// <summary>
205 /// Adds a file to an open cabinet.
206 /// </summary>
207 /// <param name="file">Full path to file to add to cabinet.</param>
208 /// <param name="token">Name of file in cabinet.</param>
209 /// <param name="fileHash"></param>
210 /// <param name="contextHandle">Handle to open cabinet.</param>
211 [DllImport("winterop.dll", EntryPoint = "CreateCabAddFile", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
212 public static extern void CreateCabAddFile(string file, string token, MSIFILEHASHINFO fileHash, IntPtr contextHandle);
213
214 /// <summary>
215 /// Closes a cabinet.
216 /// </summary>
217 /// <param name="contextHandle">Handle to open cabinet to close.</param>
218 /// <param name="newCabNamesCallBackAddress">Address of Binder's cabinet split callback</param>
219 [DllImport("winterop.dll", EntryPoint = "CreateCabFinish", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
220 public static extern void CreateCabFinish(IntPtr contextHandle, IntPtr newCabNamesCallBackAddress);
221
222 /// <summary>
223 /// Cancels cabinet creation.
224 /// </summary>
225 /// <param name="contextHandle">Handle to open cabinet to cancel.</param>
226 [DllImport("winterop.dll", EntryPoint = "CreateCabCancel", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
227 public static extern void CreateCabCancel(IntPtr contextHandle);
228
229 /// <summary>
230 /// Initializes cabinet extraction.
231 /// </summary>
232 [DllImport("winterop.dll", EntryPoint = "ExtractCabBegin", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
233 public static extern void ExtractCabBegin();
234
235 /// <summary>
236 /// Extracts files from cabinet.
237 /// </summary>
238 /// <param name="cabinet">Path to cabinet to extract files from.</param>
239 /// <param name="extractDirectory">Directory to extract files to.</param>
240 [DllImport("winterop.dll", EntryPoint = "ExtractCab", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true, PreserveSig = false)]
241 public static extern void ExtractCab(string cabinet, string extractDirectory);
242
243 /// <summary>
244 /// Cleans up after cabinet extraction.
245 /// </summary>
246 [DllImport("winterop.dll", EntryPoint = "ExtractCabFinish", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
247 public static extern void ExtractCabFinish();
248
249 /// <summary>
250 /// Initializes cabinet enumeration.
251 /// </summary>
252 [DllImport("winterop.dll", EntryPoint = "EnumerateCabBegin", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
253 public static extern void EnumerateCabBegin();
254
255 /// <summary>
256 /// Enumerates files from cabinet.
257 /// </summary>
258 /// <param name="cabinet">Path to cabinet to enumerate files from.</param>
259 /// <param name="notify">callback that gets each file.</param>
260 [DllImport("winterop.dll", EntryPoint = "EnumerateCab", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true, PreserveSig = false)]
261 public static extern void EnumerateCab(string cabinet, CabInterop.PFNNOTIFY notify);
262
263 /// <summary>
264 /// Cleans up after cabinet enumeration.
265 /// </summary>
266 [DllImport("winterop.dll", EntryPoint = "EnumerateCabFinish", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
267 public static extern void EnumerateCabFinish();
268
269 /// <summary>
270 /// Resets the DACL on an array of files to "empty".
271 /// </summary>
272 /// <param name="files">Array of file reset ACL to "empty".</param>
273 /// <param name="fileCount">Number of file paths in array.</param>
274 [DllImport("winterop.dll", EntryPoint = "ResetAcls", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
275 public static extern void ResetAcls(string[] files, uint fileCount);
276
277 /// <summary>
278 /// Gets the hash of the pCertContext->pCertInfo->SubjectPublicKeyInfo using ::CryptHashPublicKeyInfo() which does not seem
279 /// to be exposed by .NET Frameowkr.
280 /// </summary>
281 /// <param name="certContext">Pointer to a CERT_CONTEXT struct with public key information to hash.</param>
282 /// <param name="publicKeyInfoHashed"></param>
283 /// <param name="sizePublicKeyInfoHashed"></param>
284 [DllImport("winterop.dll", EntryPoint = "HashPublicKeyInfo", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
285 public static extern void HashPublicKeyInfo(IntPtr certContext, byte[] publicKeyInfoHashed, ref uint sizePublicKeyInfoHashed);
286
287 /// <summary>
288 /// Converts file time to a local file time.
289 /// </summary>
290 /// <param name="fileTime">file time</param>
291 /// <param name="localTime">local file time</param>
292 /// <returns>true if successful, false otherwise</returns>
293 [DllImport("kernel32.dll", SetLastError = true)]
294 [return: MarshalAs(UnmanagedType.Bool)]
295 public static extern bool FileTimeToLocalFileTime(ref long fileTime, ref long localTime);
296
297 /// <summary>
298 /// Converts file time to a MS-DOS time.
299 /// </summary>
300 /// <param name="fileTime">file time</param>
301 /// <param name="wFatDate">MS-DOS date</param>
302 /// <param name="wFatTime">MS-DOS time</param>
303 /// <returns>true if successful, false otherwise</returns>
304 [DllImport("kernel32.dll", SetLastError = true)]
305 [return: MarshalAs(UnmanagedType.Bool)]
306 public static extern bool FileTimeToDosDateTime(ref long fileTime, out ushort wFatDate, out ushort wFatTime);
307 }
308 }
309}
diff --git a/src/WixToolset.Core.Native/Cabinet.cs b/src/WixToolset.Core.Native/Cabinet.cs
index 7e04cbc5..9b77bd37 100644
--- a/src/WixToolset.Core.Native/Cabinet.cs
+++ b/src/WixToolset.Core.Native/Cabinet.cs
@@ -8,7 +8,7 @@ namespace WixToolset.Core.Native
8 using WixToolset.Data; 8 using WixToolset.Data;
9 9
10 /// <summary> 10 /// <summary>
11 /// Wrapper class around interop with wixcab.dll to compress files into a cabinet. 11 /// Cabinet create, enumerate and extract mechanism.
12 /// </summary> 12 /// </summary>
13 public sealed class Cabinet 13 public sealed class Cabinet
14 { 14 {
@@ -16,7 +16,7 @@ namespace WixToolset.Core.Native
16 private static readonly char[] TextLineSplitter = new[] { '\t' }; 16 private static readonly char[] TextLineSplitter = new[] { '\t' };
17 17
18 /// <summary> 18 /// <summary>
19 /// 19 /// Creates a cabinet creation, enumeration, extraction mechanism.
20 /// </summary> 20 /// </summary>
21 /// <param name="path">Path of cabinet</param> 21 /// <param name="path">Path of cabinet</param>
22 public Cabinet(string path) 22 public Cabinet(string path)
@@ -116,90 +116,5 @@ namespace WixToolset.Core.Native
116 var wixnative = new WixNativeExe("extractcab", this.Path, outputFolder); 116 var wixnative = new WixNativeExe("extractcab", this.Path, outputFolder);
117 return wixnative.Run().Where(output => !String.IsNullOrWhiteSpace(output)); 117 return wixnative.Run().Where(output => !String.IsNullOrWhiteSpace(output));
118 } 118 }
119
120#if TOOD_ERROR_HANDLING
121 /// <summary>
122 /// Adds a file to the cabinet with an optional MSI file hash.
123 /// </summary>
124 /// <param name="file">The file to add.</param>
125 /// <param name="token">The token for the file.</param>
126 /// <param name="fileHash">The MSI file hash of the file.</param>
127 //private void AddFile(string file, string token, MsiInterop.MSIFILEHASHINFO fileHash)
128 //{
129 // try
130 // {
131 // NativeMethods.CreateCabAddFile(file, token, fileHash, this.handle);
132 // }
133 // catch (COMException ce)
134 // {
135 // if (0x80004005 == unchecked((uint)ce.ErrorCode)) // E_FAIL
136 // {
137 // throw new WixException(WixErrors.CreateCabAddFileFailed());
138 // }
139 // else if (0x80070070 == unchecked((uint)ce.ErrorCode)) // ERROR_DISK_FULL
140 // {
141 // throw new WixException(WixErrors.CreateCabInsufficientDiskSpace());
142 // }
143 // else
144 // {
145 // throw;
146 // }
147 // }
148 // catch (DirectoryNotFoundException)
149 // {
150 // throw new WixFileNotFoundException(file);
151 // }
152 // catch (FileNotFoundException)
153 // {
154 // throw new WixFileNotFoundException(file);
155 // }
156 //}
157
158 /// <summary>
159 /// Complete/commit the cabinet - this must be called before Dispose so that errors will be
160 /// reported on the same thread.
161 /// </summary>
162 /// <param name="newCabNamesCallBackAddress">Address of Binder's callback function for Cabinet Splitting</param>
163 public void Complete(IntPtr newCabNamesCallBackAddress)
164 {
165 if (IntPtr.Zero != this.handle)
166 {
167 try
168 {
169 if (newCabNamesCallBackAddress != IntPtr.Zero && this.maxSize != 0)
170 {
171 NativeMethods.CreateCabFinish(this.handle, newCabNamesCallBackAddress);
172 }
173 else
174 {
175 NativeMethods.CreateCabFinish(this.handle, IntPtr.Zero);
176 }
177
178 GC.SuppressFinalize(this);
179 this.disposed = true;
180 }
181 catch (COMException ce)
182 {
183 //if (0x80004005 == unchecked((uint)ce.ErrorCode)) // E_FAIL
184 //{
185 // // This error seems to happen, among other situations, when cabbing more than 0xFFFF files
186 // throw new WixException(WixErrors.FinishCabFailed());
187 //}
188 //else if (0x80070070 == unchecked((uint)ce.ErrorCode)) // ERROR_DISK_FULL
189 //{
190 // throw new WixException(WixErrors.CreateCabInsufficientDiskSpace());
191 //}
192 //else
193 //{
194 // throw;
195 //}
196 }
197 finally
198 {
199 this.handle = IntPtr.Zero;
200 }
201 }
202 }
203#endif
204 } 119 }
205} 120}
diff --git a/src/WixToolset.Core.Native/CabinetFileInfo.cs b/src/WixToolset.Core.Native/CabinetFileInfo.cs
index 52f28ad4..07387191 100644
--- a/src/WixToolset.Core.Native/CabinetFileInfo.cs
+++ b/src/WixToolset.Core.Native/CabinetFileInfo.cs
@@ -56,7 +56,7 @@ namespace WixToolset.Core.Native
56 /// </returns> 56 /// </returns>
57 public bool SameAsDateTime(DateTime dateTime) 57 public bool SameAsDateTime(DateTime dateTime)
58 { 58 {
59 CabInterop.DateTimeToCabDateAndTime(dateTime, out var cabDate, out var cabTime); 59 DateTimeInterop.DateTimeToCabDateAndTime(dateTime, out var cabDate, out var cabTime);
60 return this.Date == cabDate && this.Time == cabTime; 60 return this.Date == cabDate && this.Time == cabTime;
61 } 61 }
62 } 62 }
diff --git a/src/WixToolset.Core.Native/DateTimeInterop.cs b/src/WixToolset.Core.Native/DateTimeInterop.cs
new file mode 100644
index 00000000..d2a0ba2b
--- /dev/null
+++ b/src/WixToolset.Core.Native/DateTimeInterop.cs
@@ -0,0 +1,48 @@
1// 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.
2
3namespace WixToolset.Core.Native
4{
5 using System;
6 using System.Runtime.InteropServices;
7
8 /// <summary>
9 /// Interop class for the date/time handling.
10 /// </summary>
11 internal static class DateTimeInterop
12 {
13 /// <summary>
14 /// Converts DateTime to MS-DOS date and time which cabinet uses.
15 /// </summary>
16 /// <param name="dateTime">DateTime</param>
17 /// <param name="cabDate">MS-DOS date</param>
18 /// <param name="cabTime">MS-DOS time</param>
19 public static void DateTimeToCabDateAndTime(DateTime dateTime, out ushort cabDate, out ushort cabTime)
20 {
21 // dateTime.ToLocalTime() does not match FileTimeToLocalFileTime() for some reason.
22 // so we need to call FileTimeToLocalFileTime() from kernel32.dll.
23 long filetime = dateTime.ToFileTime();
24 long localTime = 0;
25 FileTimeToLocalFileTime(ref filetime, ref localTime);
26 FileTimeToDosDateTime(ref localTime, out cabDate, out cabTime);
27 }
28
29 /// <summary>
30 /// Converts file time to a local file time.
31 /// </summary>
32 /// <param name="fileTime">file time</param>
33 /// <param name="localTime">local file time</param>
34 /// <returns>true if successful, false otherwise</returns>
35 [DllImport("kernel32.dll", SetLastError = true)]
36 private static extern bool FileTimeToLocalFileTime(ref long fileTime, ref long localTime);
37
38 /// <summary>
39 /// Converts file time to a MS-DOS time.
40 /// </summary>
41 /// <param name="fileTime">file time</param>
42 /// <param name="wFatDate">MS-DOS date</param>
43 /// <param name="wFatTime">MS-DOS time</param>
44 /// <returns>true if successful, false otherwise</returns>
45 [DllImport("kernel32.dll", SetLastError = true)]
46 private static extern bool FileTimeToDosDateTime(ref long fileTime, out ushort wFatDate, out ushort wFatTime);
47 }
48}
diff --git a/src/WixToolset.Core.Native/MSIFILEHASHINFO.cs b/src/WixToolset.Core.Native/Msi/MSIFILEHASHINFO.cs
index d5ac1bc0..ae88ec7e 100644
--- a/src/WixToolset.Core.Native/MSIFILEHASHINFO.cs
+++ b/src/WixToolset.Core.Native/Msi/MSIFILEHASHINFO.cs
@@ -1,6 +1,6 @@
1// 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. 1// 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.
2 2
3namespace WixToolset.Core.Native 3namespace WixToolset.Core.Native.Msi
4{ 4{
5 using System.Runtime.InteropServices; 5 using System.Runtime.InteropServices;
6 6