diff options
author | Rob Mensching <rob@firegiant.com> | 2017-11-29 22:03:26 -0800 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2017-11-29 22:03:26 -0800 |
commit | 71c52d5af2293d3eb79882ce36b0411f81185c11 (patch) | |
tree | 23dd116bdd6abc2b0f7b488f490d1b77faa41812 /src/WixToolset.Core/Cab | |
parent | 0fa198ed8c6c6fc81e649466879752a99fe37d08 (diff) | |
download | wix-71c52d5af2293d3eb79882ce36b0411f81185c11.tar.gz wix-71c52d5af2293d3eb79882ce36b0411f81185c11.tar.bz2 wix-71c52d5af2293d3eb79882ce36b0411f81185c11.zip |
Fix source path and cabinet processing
Diffstat (limited to 'src/WixToolset.Core/Cab')
-rw-r--r-- | src/WixToolset.Core/Cab/CabinetFileInfo.cs | 45 | ||||
-rw-r--r-- | src/WixToolset.Core/Cab/Interop/CabInterop.cs | 316 | ||||
-rw-r--r-- | src/WixToolset.Core/Cab/WixCreateCab.cs | 249 | ||||
-rw-r--r-- | src/WixToolset.Core/Cab/WixEnumerateCab.cs | 89 | ||||
-rw-r--r-- | src/WixToolset.Core/Cab/WixExtractCab.cs | 75 |
5 files changed, 0 insertions, 774 deletions
diff --git a/src/WixToolset.Core/Cab/CabinetFileInfo.cs b/src/WixToolset.Core/Cab/CabinetFileInfo.cs deleted file mode 100644 index 816f9e3e..00000000 --- a/src/WixToolset.Core/Cab/CabinetFileInfo.cs +++ /dev/null | |||
@@ -1,45 +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 | |||
3 | namespace WixToolset.Core.Cab | ||
4 | { | ||
5 | /// <summary> | ||
6 | /// Properties of a file in a cabinet. | ||
7 | /// </summary> | ||
8 | public sealed class CabinetFileInfo | ||
9 | { | ||
10 | /// <summary> | ||
11 | /// Constructs CabinetFileInfo | ||
12 | /// </summary> | ||
13 | /// <param name="fileId">File Id</param> | ||
14 | /// <param name="date">Last modified date (MS-DOS time)</param> | ||
15 | /// <param name="time">Last modified time (MS-DOS time)</param> | ||
16 | public CabinetFileInfo(string fileId, ushort date, ushort time, int size) | ||
17 | { | ||
18 | this.FileId = fileId; | ||
19 | this.Date = date; | ||
20 | this.Time = time; | ||
21 | this.Size = size; | ||
22 | } | ||
23 | |||
24 | /// <summary> | ||
25 | /// Gets the file Id of the file. | ||
26 | /// </summary> | ||
27 | /// <value>file Id</value> | ||
28 | public string FileId { get; } | ||
29 | |||
30 | /// <summary> | ||
31 | /// Gets modified date (DOS format). | ||
32 | /// </summary> | ||
33 | public ushort Date { get; } | ||
34 | |||
35 | /// <summary> | ||
36 | /// Gets modified time (DOS format). | ||
37 | /// </summary> | ||
38 | public ushort Time { get; } | ||
39 | |||
40 | /// <summary> | ||
41 | /// Gets the size of the file in bytes. | ||
42 | /// </summary> | ||
43 | public int Size { get; } | ||
44 | } | ||
45 | } | ||
diff --git a/src/WixToolset.Core/Cab/Interop/CabInterop.cs b/src/WixToolset.Core/Cab/Interop/CabInterop.cs deleted file mode 100644 index 6c1ae2c1..00000000 --- a/src/WixToolset.Core/Cab/Interop/CabInterop.cs +++ /dev/null | |||
@@ -1,316 +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 | |||
3 | #if false | ||
4 | |||
5 | namespace WixToolset.Cab.Interop | ||
6 | { | ||
7 | using System; | ||
8 | using System.Diagnostics.CodeAnalysis; | ||
9 | using System.Text; | ||
10 | using System.Runtime.InteropServices; | ||
11 | using WixToolset.Msi; | ||
12 | using WixToolset.Msi.Interop; | ||
13 | |||
14 | /// <summary> | ||
15 | /// The native methods. | ||
16 | /// </summary> | ||
17 | public sealed class NativeMethods | ||
18 | { | ||
19 | /// <summary> | ||
20 | /// Starts creating a cabinet. | ||
21 | /// </summary> | ||
22 | /// <param name="cabinetName">Name of cabinet to create.</param> | ||
23 | /// <param name="cabinetDirectory">Directory to create cabinet in.</param> | ||
24 | /// <param name="maxFiles">Maximum number of files that will be added to cabinet.</param> | ||
25 | /// <param name="maxSize">Maximum size of the cabinet.</param> | ||
26 | /// <param name="maxThreshold">Maximum threshold in the cabinet.</param> | ||
27 | /// <param name="compressionType">Type of compression to use in the cabinet.</param> | ||
28 | /// <param name="contextHandle">Handle to opened cabinet.</param> | ||
29 | [DllImport("winterop.dll", EntryPoint = "CreateCabBegin", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] | ||
30 | internal static extern void CreateCabBegin(string cabinetName, string cabinetDirectory, uint maxFiles, uint maxSize, uint maxThreshold, uint compressionType, out IntPtr contextHandle); | ||
31 | |||
32 | /// <summary> | ||
33 | /// Adds a file to an open cabinet. | ||
34 | /// </summary> | ||
35 | /// <param name="file">Full path to file to add to cabinet.</param> | ||
36 | /// <param name="token">Name of file in cabinet.</param> | ||
37 | /// <param name="contextHandle">Handle to open cabinet.</param> | ||
38 | [DllImport("winterop.dll", EntryPoint = "CreateCabAddFile", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] | ||
39 | internal static extern void CreateCabAddFile(string file, string token, MsiInterop.MSIFILEHASHINFO fileHash, IntPtr contextHandle); | ||
40 | |||
41 | /// <summary> | ||
42 | /// Closes a cabinet. | ||
43 | /// </summary> | ||
44 | /// <param name="contextHandle">Handle to open cabinet to close.</param> | ||
45 | /// <param name="newCabNamesCallBackAddress">Address of Binder's cabinet split callback</param> | ||
46 | [DllImport("winterop.dll", EntryPoint = "CreateCabFinish", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] | ||
47 | internal static extern void CreateCabFinish(IntPtr contextHandle, IntPtr newCabNamesCallBackAddress); | ||
48 | |||
49 | /// <summary> | ||
50 | /// Cancels cabinet creation. | ||
51 | /// </summary> | ||
52 | /// <param name="contextHandle">Handle to open cabinet to cancel.</param> | ||
53 | [DllImport("winterop.dll", EntryPoint = "CreateCabCancel", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] | ||
54 | internal static extern void CreateCabCancel(IntPtr contextHandle); | ||
55 | |||
56 | /// <summary> | ||
57 | /// Initializes cabinet extraction. | ||
58 | /// </summary> | ||
59 | [DllImport("winterop.dll", EntryPoint = "ExtractCabBegin", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] | ||
60 | internal static extern void ExtractCabBegin(); | ||
61 | |||
62 | /// <summary> | ||
63 | /// Extracts files from cabinet. | ||
64 | /// </summary> | ||
65 | /// <param name="cabinet">Path to cabinet to extract files from.</param> | ||
66 | /// <param name="extractDirectory">Directory to extract files to.</param> | ||
67 | [DllImport("winterop.dll", EntryPoint = "ExtractCab", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true, PreserveSig = false)] | ||
68 | internal static extern void ExtractCab(string cabinet, string extractDirectory); | ||
69 | |||
70 | /// <summary> | ||
71 | /// Cleans up after cabinet extraction. | ||
72 | /// </summary> | ||
73 | [DllImport("winterop.dll", EntryPoint = "ExtractCabFinish", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] | ||
74 | internal static extern void ExtractCabFinish(); | ||
75 | |||
76 | /// <summary> | ||
77 | /// Initializes cabinet enumeration. | ||
78 | /// </summary> | ||
79 | [DllImport("winterop.dll", EntryPoint = "EnumerateCabBegin", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] | ||
80 | internal static extern void EnumerateCabBegin(); | ||
81 | |||
82 | /// <summary> | ||
83 | /// Enumerates files from cabinet. | ||
84 | /// </summary> | ||
85 | /// <param name="cabinet">Path to cabinet to enumerate files from.</param> | ||
86 | /// <param name="notify">callback that gets each file.</param> | ||
87 | [DllImport("winterop.dll", EntryPoint = "EnumerateCab", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true, PreserveSig = false)] | ||
88 | internal static extern void EnumerateCab(string cabinet, CabInterop.PFNNOTIFY notify); | ||
89 | |||
90 | /// <summary> | ||
91 | /// Cleans up after cabinet enumeration. | ||
92 | /// </summary> | ||
93 | [DllImport("winterop.dll", EntryPoint = "EnumerateCabFinish", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] | ||
94 | internal static extern void EnumerateCabFinish(); | ||
95 | |||
96 | /// <summary> | ||
97 | /// Resets the DACL on an array of files to "empty". | ||
98 | /// </summary> | ||
99 | /// <param name="files">Array of file reset ACL to "empty".</param> | ||
100 | /// <param name="fileCount">Number of file paths in array.</param> | ||
101 | [DllImport("winterop.dll", EntryPoint = "ResetAcls", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] | ||
102 | internal static extern void ResetAcls(string[] files, uint fileCount); | ||
103 | |||
104 | /// <summary> | ||
105 | /// Gets the hash of the pCertContext->pCertInfo->SubjectPublicKeyInfo using ::CryptHashPublicKeyInfo() which does not seem | ||
106 | /// to be exposed by .NET Frameowkr. | ||
107 | /// </summary> | ||
108 | /// <param name="certContext">Pointer to a CERT_CONTEXT struct with public key information to hash.</param> | ||
109 | /// <param name="fileCount">Number of file paths in array.</param> | ||
110 | [DllImport("winterop.dll", EntryPoint = "HashPublicKeyInfo", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] | ||
111 | internal static extern void HashPublicKeyInfo(IntPtr certContext, byte[] publicKeyInfoHashed, ref uint sizePublicKeyInfoHashed); | ||
112 | |||
113 | /// <summary> | ||
114 | /// Converts file time to a local file time. | ||
115 | /// </summary> | ||
116 | /// <param name="fileTime">file time</param> | ||
117 | /// <param name="localTime">local file time</param> | ||
118 | /// <returns>true if successful, false otherwise</returns> | ||
119 | [DllImport("kernel32.dll", SetLastError = true)] | ||
120 | [return: MarshalAs(UnmanagedType.Bool)] | ||
121 | internal static extern bool FileTimeToLocalFileTime(ref long fileTime, ref long localTime); | ||
122 | |||
123 | /// <summary> | ||
124 | /// Converts file time to a MS-DOS time. | ||
125 | /// </summary> | ||
126 | /// <param name="fileTime">file time</param> | ||
127 | /// <param name="wFatDate">MS-DOS date</param> | ||
128 | /// <param name="wFatTime">MS-DOS time</param> | ||
129 | /// <returns>true if successful, false otherwise</returns> | ||
130 | [DllImport("kernel32.dll", SetLastError = true)] | ||
131 | [return: MarshalAs(UnmanagedType.Bool)] | ||
132 | internal static extern bool FileTimeToDosDateTime(ref long fileTime, out ushort wFatDate, out ushort wFatTime); | ||
133 | } | ||
134 | |||
135 | /// <summary> | ||
136 | /// Interop class for the winterop.dll. | ||
137 | /// </summary> | ||
138 | internal static class CabInterop | ||
139 | { | ||
140 | /// <summary> | ||
141 | /// Delegate type that's called by cabinet api for every file in cabinet. | ||
142 | /// </summary> | ||
143 | /// <param name="fdint">NOTIFICATIONTYPE</param> | ||
144 | /// <param name="pfdin">NOTIFICATION</param> | ||
145 | /// <returns>0 for success, -1 otherwise</returns> | ||
146 | public delegate Int32 PFNNOTIFY(NOTIFICATIONTYPE fdint, NOTIFICATION pfdin); | ||
147 | |||
148 | /// <summary> | ||
149 | /// Wraps FDINOTIFICATIONTYPE. | ||
150 | /// </summary> | ||
151 | public enum NOTIFICATIONTYPE : int | ||
152 | { | ||
153 | /// <summary>Info about the cabinet.</summary> | ||
154 | CABINET_INFO, | ||
155 | /// <summary>One or more files are continued.</summary> | ||
156 | PARTIAL_FILE, | ||
157 | /// <summary>Called for each file in cabinet.</summary> | ||
158 | COPY_FILE, | ||
159 | /// <summary>Called after all of the data has been written to a target file.</summary> | ||
160 | CLOSE_FILE_INFO, | ||
161 | /// <summary>A file is continued to the next cabinet.</summary> | ||
162 | NEXT_CABINET, | ||
163 | /// <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> | ||
164 | ENUMERATE, | ||
165 | } | ||
166 | |||
167 | /// <summary> | ||
168 | /// Converts DateTime to MS-DOS date and time which cabinet uses. | ||
169 | /// </summary> | ||
170 | /// <param name="dateTime">DateTime</param> | ||
171 | /// <param name="cabDate">MS-DOS date</param> | ||
172 | /// <param name="cabTime">MS-DOS time</param> | ||
173 | public static void DateTimeToCabDateAndTime(DateTime dateTime, out ushort cabDate, out ushort cabTime) | ||
174 | { | ||
175 | // dateTime.ToLocalTime() does not match FileTimeToLocalFileTime() for some reason. | ||
176 | // so we need to call FileTimeToLocalFileTime() from kernel32.dll. | ||
177 | long filetime = dateTime.ToFileTime(); | ||
178 | long localTime = 0; | ||
179 | NativeMethods.FileTimeToLocalFileTime(ref filetime, ref localTime); | ||
180 | NativeMethods.FileTimeToDosDateTime(ref localTime, out cabDate, out cabTime); | ||
181 | } | ||
182 | |||
183 | /// <summary> | ||
184 | /// Wraps FDINOTIFICATION. | ||
185 | /// </summary> | ||
186 | [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")] | ||
187 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] | ||
188 | public class NOTIFICATION | ||
189 | { | ||
190 | private int cb; | ||
191 | [MarshalAs(UnmanagedType.LPStr)] | ||
192 | private string psz1; | ||
193 | [MarshalAs(UnmanagedType.LPStr)] | ||
194 | private string psz2; | ||
195 | [MarshalAs(UnmanagedType.LPStr)] | ||
196 | private string psz3; | ||
197 | private IntPtr pv; | ||
198 | |||
199 | private IntPtr hf; | ||
200 | |||
201 | private ushort date; | ||
202 | private ushort time; | ||
203 | private ushort attribs; | ||
204 | private ushort setID; | ||
205 | private ushort cabinet; | ||
206 | private ushort folder; | ||
207 | private int fdie; | ||
208 | |||
209 | /// <summary> | ||
210 | /// Uncompressed size of file. | ||
211 | /// </summary> | ||
212 | public int Cb | ||
213 | { | ||
214 | get { return this.cb; } | ||
215 | } | ||
216 | |||
217 | /// <summary> | ||
218 | /// File name in cabinet. | ||
219 | /// </summary> | ||
220 | public String Psz1 | ||
221 | { | ||
222 | get { return this.psz1; } | ||
223 | } | ||
224 | |||
225 | /// <summary> | ||
226 | /// Name of next disk. | ||
227 | /// </summary> | ||
228 | public string Psz2 | ||
229 | { | ||
230 | get { return this.psz2; } | ||
231 | } | ||
232 | |||
233 | /// <summary> | ||
234 | /// Points to a 256 character buffer. | ||
235 | /// </summary> | ||
236 | public string Psz3 | ||
237 | { | ||
238 | get { return this.psz3; } | ||
239 | } | ||
240 | |||
241 | /// <summary> | ||
242 | /// Value for client. | ||
243 | /// </summary> | ||
244 | public IntPtr Pv | ||
245 | { | ||
246 | get { return this.pv; } | ||
247 | } | ||
248 | |||
249 | /// <summary> | ||
250 | /// Not used. | ||
251 | /// </summary> | ||
252 | public Int32 Hf | ||
253 | { | ||
254 | get { return (Int32)this.hf; } | ||
255 | } | ||
256 | |||
257 | /// <summary> | ||
258 | /// Last modified MS-DOS date. | ||
259 | /// </summary> | ||
260 | public ushort Date | ||
261 | { | ||
262 | get { return this.date; } | ||
263 | } | ||
264 | |||
265 | /// <summary> | ||
266 | /// Last modified MS-DOS time. | ||
267 | /// </summary> | ||
268 | public ushort Time | ||
269 | { | ||
270 | get { return this.time; } | ||
271 | } | ||
272 | |||
273 | /// <summary> | ||
274 | /// File attributes. | ||
275 | /// </summary> | ||
276 | public ushort Attribs | ||
277 | { | ||
278 | get { return this.attribs; } | ||
279 | } | ||
280 | |||
281 | /// <summary> | ||
282 | /// Cabinet set ID (a random 16-bit number). | ||
283 | /// </summary> | ||
284 | public ushort SetID | ||
285 | { | ||
286 | get { return this.setID; } | ||
287 | } | ||
288 | |||
289 | /// <summary> | ||
290 | /// Cabinet number within cabinet set (0-based). | ||
291 | /// </summary> | ||
292 | public ushort Cabinet | ||
293 | { | ||
294 | get { return this.cabinet; } | ||
295 | } | ||
296 | |||
297 | /// <summary> | ||
298 | /// File's folder index. | ||
299 | /// </summary> | ||
300 | public ushort Folder | ||
301 | { | ||
302 | get { return this.folder; } | ||
303 | } | ||
304 | |||
305 | /// <summary> | ||
306 | /// Error code. | ||
307 | /// </summary> | ||
308 | public int Fdie | ||
309 | { | ||
310 | get { return this.fdie; } | ||
311 | } | ||
312 | } | ||
313 | } | ||
314 | } | ||
315 | |||
316 | #endif | ||
diff --git a/src/WixToolset.Core/Cab/WixCreateCab.cs b/src/WixToolset.Core/Cab/WixCreateCab.cs deleted file mode 100644 index 4ebdd1c0..00000000 --- a/src/WixToolset.Core/Cab/WixCreateCab.cs +++ /dev/null | |||
@@ -1,249 +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 | |||
3 | namespace WixToolset.Core.Cab | ||
4 | { | ||
5 | using System; | ||
6 | using System.Globalization; | ||
7 | using System.IO; | ||
8 | using System.Runtime.InteropServices; | ||
9 | using WixToolset.Core.Bind; | ||
10 | using WixToolset.Core.Native; | ||
11 | using WixToolset.Data; | ||
12 | |||
13 | /// <summary> | ||
14 | /// Wrapper class around interop with wixcab.dll to compress files into a cabinet. | ||
15 | /// </summary> | ||
16 | public sealed class WixCreateCab : IDisposable | ||
17 | { | ||
18 | private static readonly string CompressionLevelVariable = "WIX_COMPRESSION_LEVEL"; | ||
19 | private IntPtr handle = IntPtr.Zero; | ||
20 | private bool disposed; | ||
21 | private int maxSize; | ||
22 | |||
23 | /// <summary> | ||
24 | /// Creates a cabinet. | ||
25 | /// </summary> | ||
26 | /// <param name="cabName">Name of cabinet to create.</param> | ||
27 | /// <param name="cabDir">Directory to create cabinet in.</param> | ||
28 | /// <param name="maxFiles">Maximum number of files that will be added to cabinet.</param> | ||
29 | /// <param name="maxSize">Maximum size of cabinet.</param> | ||
30 | /// <param name="maxThresh">Maximum threshold for each cabinet.</param> | ||
31 | /// <param name="compressionLevel">Level of compression to apply.</param> | ||
32 | public WixCreateCab(string cabName, string cabDir, int maxFiles, int maxSize, int maxThresh, CompressionLevel compressionLevel) | ||
33 | { | ||
34 | string compressionLevelVariable = Environment.GetEnvironmentVariable(CompressionLevelVariable); | ||
35 | this.maxSize = maxSize; | ||
36 | |||
37 | try | ||
38 | { | ||
39 | // Override authored compression level if environment variable is present. | ||
40 | if (!String.IsNullOrEmpty(compressionLevelVariable)) | ||
41 | { | ||
42 | compressionLevel = WixCreateCab.CompressionLevelFromString(compressionLevelVariable); | ||
43 | } | ||
44 | } | ||
45 | catch (WixException) | ||
46 | { | ||
47 | throw new WixException(WixErrors.IllegalEnvironmentVariable(CompressionLevelVariable, compressionLevelVariable)); | ||
48 | } | ||
49 | |||
50 | if (String.IsNullOrEmpty(cabDir)) | ||
51 | { | ||
52 | cabDir = Directory.GetCurrentDirectory(); | ||
53 | } | ||
54 | |||
55 | try | ||
56 | { | ||
57 | NativeMethods.CreateCabBegin(cabName, cabDir, (uint)maxFiles, (uint)maxSize, (uint)maxThresh, (uint)compressionLevel, out this.handle); | ||
58 | } | ||
59 | catch (COMException ce) | ||
60 | { | ||
61 | // If we get a "the file exists" error, we must have a full temp directory - so report the issue | ||
62 | if (0x80070050 == unchecked((uint)ce.ErrorCode)) | ||
63 | { | ||
64 | throw new WixException(WixErrors.FullTempDirectory("WSC", Path.GetTempPath())); | ||
65 | } | ||
66 | |||
67 | throw; | ||
68 | } | ||
69 | } | ||
70 | |||
71 | /// <summary> | ||
72 | /// Destructor for cabinet creation. | ||
73 | /// </summary> | ||
74 | ~WixCreateCab() | ||
75 | { | ||
76 | this.Dispose(); | ||
77 | } | ||
78 | |||
79 | /// <summary> | ||
80 | /// Converts a compression level from its string to its enum value. | ||
81 | /// </summary> | ||
82 | /// <param name="compressionLevel">Compression level as a string.</param> | ||
83 | /// <returns>CompressionLevel enum value</returns> | ||
84 | public static CompressionLevel CompressionLevelFromString(string compressionLevel) | ||
85 | { | ||
86 | switch (compressionLevel.ToLower(CultureInfo.InvariantCulture)) | ||
87 | { | ||
88 | case "low": | ||
89 | return CompressionLevel.Low; | ||
90 | case "medium": | ||
91 | return CompressionLevel.Medium; | ||
92 | case "high": | ||
93 | return CompressionLevel.High; | ||
94 | case "none": | ||
95 | return CompressionLevel.None; | ||
96 | case "mszip": | ||
97 | return CompressionLevel.Mszip; | ||
98 | default: | ||
99 | throw new WixException(WixErrors.IllegalCompressionLevel(compressionLevel)); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | /// <summary> | ||
104 | /// Adds a file to the cabinet. | ||
105 | /// </summary> | ||
106 | /// <param name="fileFacade">The file facade of the file to add.</param> | ||
107 | public void AddFile(FileFacade fileFacade) | ||
108 | { | ||
109 | MsiInterop.MSIFILEHASHINFO hashInterop = new MsiInterop.MSIFILEHASHINFO(); | ||
110 | |||
111 | if (null != fileFacade.Hash) | ||
112 | { | ||
113 | hashInterop.FileHashInfoSize = 20; | ||
114 | hashInterop.Data0 = (int)fileFacade.Hash[2]; | ||
115 | hashInterop.Data1 = (int)fileFacade.Hash[3]; | ||
116 | hashInterop.Data2 = (int)fileFacade.Hash[4]; | ||
117 | hashInterop.Data3 = (int)fileFacade.Hash[5]; | ||
118 | |||
119 | this.AddFile(fileFacade.WixFile.Source, fileFacade.File.File, hashInterop); | ||
120 | } | ||
121 | else | ||
122 | { | ||
123 | this.AddFile(fileFacade.WixFile.Source, fileFacade.File.File); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | /// <summary> | ||
128 | /// Adds a file to the cabinet. | ||
129 | /// </summary> | ||
130 | /// <param name="file">The file to add.</param> | ||
131 | /// <param name="token">The token for the file.</param> | ||
132 | public void AddFile(string file, string token) | ||
133 | { | ||
134 | this.AddFile(file, token, null); | ||
135 | } | ||
136 | |||
137 | /// <summary> | ||
138 | /// Adds a file to the cabinet with an optional MSI file hash. | ||
139 | /// </summary> | ||
140 | /// <param name="file">The file to add.</param> | ||
141 | /// <param name="token">The token for the file.</param> | ||
142 | /// <param name="fileHash">The MSI file hash of the file.</param> | ||
143 | private void AddFile(string file, string token, MsiInterop.MSIFILEHASHINFO fileHash) | ||
144 | { | ||
145 | try | ||
146 | { | ||
147 | NativeMethods.CreateCabAddFile(file, token, fileHash, this.handle); | ||
148 | } | ||
149 | catch (COMException ce) | ||
150 | { | ||
151 | if (0x80004005 == unchecked((uint)ce.ErrorCode)) // E_FAIL | ||
152 | { | ||
153 | throw new WixException(WixErrors.CreateCabAddFileFailed()); | ||
154 | } | ||
155 | else if (0x80070070 == unchecked((uint)ce.ErrorCode)) // ERROR_DISK_FULL | ||
156 | { | ||
157 | throw new WixException(WixErrors.CreateCabInsufficientDiskSpace()); | ||
158 | } | ||
159 | else | ||
160 | { | ||
161 | throw; | ||
162 | } | ||
163 | } | ||
164 | catch (DirectoryNotFoundException) | ||
165 | { | ||
166 | throw new WixFileNotFoundException(file); | ||
167 | } | ||
168 | catch (FileNotFoundException) | ||
169 | { | ||
170 | throw new WixFileNotFoundException(file); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | /// <summary> | ||
175 | /// Complete/commit the cabinet - this must be called before Dispose so that errors will be | ||
176 | /// reported on the same thread. | ||
177 | /// This Complete should be used with no Cabinet splitting as it has the split cabinet names callback address as Zero | ||
178 | /// </summary> | ||
179 | public void Complete() | ||
180 | { | ||
181 | this.Complete(IntPtr.Zero); | ||
182 | } | ||
183 | |||
184 | /// <summary> | ||
185 | /// Complete/commit the cabinet - this must be called before Dispose so that errors will be | ||
186 | /// reported on the same thread. | ||
187 | /// </summary> | ||
188 | /// <param name="newCabNamesCallBackAddress">Address of Binder's callback function for Cabinet Splitting</param> | ||
189 | public void Complete(IntPtr newCabNamesCallBackAddress) | ||
190 | { | ||
191 | if (IntPtr.Zero != this.handle) | ||
192 | { | ||
193 | try | ||
194 | { | ||
195 | if (newCabNamesCallBackAddress != IntPtr.Zero && this.maxSize != 0) | ||
196 | { | ||
197 | NativeMethods.CreateCabFinish(this.handle, newCabNamesCallBackAddress); | ||
198 | } | ||
199 | else | ||
200 | { | ||
201 | NativeMethods.CreateCabFinish(this.handle, IntPtr.Zero); | ||
202 | } | ||
203 | |||
204 | GC.SuppressFinalize(this); | ||
205 | this.disposed = true; | ||
206 | } | ||
207 | catch (COMException ce) | ||
208 | { | ||
209 | if (0x80004005 == unchecked((uint)ce.ErrorCode)) // E_FAIL | ||
210 | { | ||
211 | // This error seems to happen, among other situations, when cabbing more than 0xFFFF files | ||
212 | throw new WixException(WixErrors.FinishCabFailed()); | ||
213 | } | ||
214 | else if (0x80070070 == unchecked((uint)ce.ErrorCode)) // ERROR_DISK_FULL | ||
215 | { | ||
216 | throw new WixException(WixErrors.CreateCabInsufficientDiskSpace()); | ||
217 | } | ||
218 | else | ||
219 | { | ||
220 | throw; | ||
221 | } | ||
222 | } | ||
223 | finally | ||
224 | { | ||
225 | this.handle = IntPtr.Zero; | ||
226 | } | ||
227 | } | ||
228 | } | ||
229 | |||
230 | /// <summary> | ||
231 | /// Cancels ("rolls back") the creation of the cabinet. | ||
232 | /// Don't throw WiX errors from here, because we're in a different thread, and they won't be reported correctly. | ||
233 | /// </summary> | ||
234 | public void Dispose() | ||
235 | { | ||
236 | if (!this.disposed) | ||
237 | { | ||
238 | if (IntPtr.Zero != this.handle) | ||
239 | { | ||
240 | NativeMethods.CreateCabCancel(this.handle); | ||
241 | this.handle = IntPtr.Zero; | ||
242 | } | ||
243 | |||
244 | GC.SuppressFinalize(this); | ||
245 | this.disposed = true; | ||
246 | } | ||
247 | } | ||
248 | } | ||
249 | } | ||
diff --git a/src/WixToolset.Core/Cab/WixEnumerateCab.cs b/src/WixToolset.Core/Cab/WixEnumerateCab.cs deleted file mode 100644 index 0b4055d6..00000000 --- a/src/WixToolset.Core/Cab/WixEnumerateCab.cs +++ /dev/null | |||
@@ -1,89 +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 | |||
3 | namespace WixToolset.Core.Cab | ||
4 | { | ||
5 | using System; | ||
6 | using System.Collections.Generic; | ||
7 | using WixToolset.Core.Native; | ||
8 | using Handle = System.Int32; | ||
9 | |||
10 | /// <summary> | ||
11 | /// Wrapper class around interop with wixcab.dll to enumerate files from a cabinet. | ||
12 | /// </summary> | ||
13 | public sealed class WixEnumerateCab : IDisposable | ||
14 | { | ||
15 | private bool disposed; | ||
16 | private List<CabinetFileInfo> fileInfoList; | ||
17 | private CabInterop.PFNNOTIFY pfnNotify; | ||
18 | |||
19 | /// <summary> | ||
20 | /// Creates a cabinet enumerator. | ||
21 | /// </summary> | ||
22 | public WixEnumerateCab() | ||
23 | { | ||
24 | this.pfnNotify = new CabInterop.PFNNOTIFY(this.Notify); | ||
25 | NativeMethods.EnumerateCabBegin(); | ||
26 | } | ||
27 | |||
28 | /// <summary> | ||
29 | /// Destructor for cabinet enumeration. | ||
30 | /// </summary> | ||
31 | ~WixEnumerateCab() | ||
32 | { | ||
33 | this.Dispose(); | ||
34 | } | ||
35 | |||
36 | /// <summary> | ||
37 | /// Enumerates all files in a cabinet. | ||
38 | /// </summary> | ||
39 | /// <param name="cabinetFile">path to cabinet</param> | ||
40 | /// <returns>list of CabinetFileInfo</returns> | ||
41 | public List<CabinetFileInfo> Enumerate(string cabinetFile) | ||
42 | { | ||
43 | this.fileInfoList = new List<CabinetFileInfo>(); | ||
44 | |||
45 | // the callback (this.Notify) will populate the list for each file in cabinet | ||
46 | NativeMethods.EnumerateCab(cabinetFile, this.pfnNotify); | ||
47 | |||
48 | return this.fileInfoList; | ||
49 | } | ||
50 | |||
51 | /// <summary> | ||
52 | /// Disposes the managed and unmanaged objects in this object. | ||
53 | /// </summary> | ||
54 | public void Dispose() | ||
55 | { | ||
56 | if (!this.disposed) | ||
57 | { | ||
58 | NativeMethods.EnumerateCabFinish(); | ||
59 | |||
60 | GC.SuppressFinalize(this); | ||
61 | this.disposed = true; | ||
62 | } | ||
63 | } | ||
64 | |||
65 | /// <summary> | ||
66 | /// Delegate that's called for every file in cabinet. | ||
67 | /// </summary> | ||
68 | /// <param name="fdint">NOTIFICATIONTYPE</param> | ||
69 | /// <param name="pfdin">NOTIFICATION</param> | ||
70 | /// <returns>System.Int32</returns> | ||
71 | internal Handle Notify(CabInterop.NOTIFICATIONTYPE fdint, CabInterop.NOTIFICATION pfdin) | ||
72 | { | ||
73 | // This is FDI's way of notifying us of how many files total are in the cab, accurate even | ||
74 | // if the files are split into multiple folders - use it to allocate the precise size we need | ||
75 | if (CabInterop.NOTIFICATIONTYPE.ENUMERATE == fdint && 0 == this.fileInfoList.Count) | ||
76 | { | ||
77 | this.fileInfoList.Capacity = pfdin.Folder; | ||
78 | } | ||
79 | |||
80 | if (fdint == CabInterop.NOTIFICATIONTYPE.COPY_FILE) | ||
81 | { | ||
82 | CabinetFileInfo fileInfo = new CabinetFileInfo(pfdin.Psz1, pfdin.Date, pfdin.Time, pfdin.Cb); | ||
83 | this.fileInfoList.Add(fileInfo); | ||
84 | } | ||
85 | |||
86 | return 0; // tell cabinet api to skip this file. | ||
87 | } | ||
88 | } | ||
89 | } | ||
diff --git a/src/WixToolset.Core/Cab/WixExtractCab.cs b/src/WixToolset.Core/Cab/WixExtractCab.cs deleted file mode 100644 index e776b08e..00000000 --- a/src/WixToolset.Core/Cab/WixExtractCab.cs +++ /dev/null | |||
@@ -1,75 +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 | |||
3 | namespace WixToolset.Core.Cab | ||
4 | { | ||
5 | using System; | ||
6 | using WixToolset.Core.Native; | ||
7 | |||
8 | /// <summary> | ||
9 | /// Wrapper class around interop with wixcab.dll to extract files from a cabinet. | ||
10 | /// </summary> | ||
11 | public sealed class WixExtractCab : IDisposable | ||
12 | { | ||
13 | private bool disposed; | ||
14 | |||
15 | /// <summary> | ||
16 | /// Creates a cabinet extractor. | ||
17 | /// </summary> | ||
18 | public WixExtractCab() | ||
19 | { | ||
20 | NativeMethods.ExtractCabBegin(); | ||
21 | } | ||
22 | |||
23 | /// <summary> | ||
24 | /// Destructor for cabinet extraction. | ||
25 | /// </summary> | ||
26 | ~WixExtractCab() | ||
27 | { | ||
28 | this.Dispose(); | ||
29 | } | ||
30 | |||
31 | /// <summary> | ||
32 | /// Extracts all the files from a cabinet to a directory. | ||
33 | /// </summary> | ||
34 | /// <param name="cabinetFile">Cabinet file to extract from.</param> | ||
35 | /// <param name="extractDir">Directory to extract files to.</param> | ||
36 | public void Extract(string cabinetFile, string extractDir) | ||
37 | { | ||
38 | if (null == cabinetFile) | ||
39 | { | ||
40 | throw new ArgumentNullException("cabinetFile"); | ||
41 | } | ||
42 | |||
43 | if (null == extractDir) | ||
44 | { | ||
45 | throw new ArgumentNullException("extractDir"); | ||
46 | } | ||
47 | |||
48 | if (this.disposed) | ||
49 | { | ||
50 | throw new ObjectDisposedException("WixExtractCab"); | ||
51 | } | ||
52 | |||
53 | if (!extractDir.EndsWith("\\", StringComparison.Ordinal)) | ||
54 | { | ||
55 | extractDir = String.Concat(extractDir, "\\"); | ||
56 | } | ||
57 | |||
58 | NativeMethods.ExtractCab(cabinetFile, extractDir); | ||
59 | } | ||
60 | |||
61 | /// <summary> | ||
62 | /// Disposes the managed and unmanaged objects in this object. | ||
63 | /// </summary> | ||
64 | public void Dispose() | ||
65 | { | ||
66 | if (!this.disposed) | ||
67 | { | ||
68 | NativeMethods.ExtractCabFinish(); | ||
69 | |||
70 | GC.SuppressFinalize(this); | ||
71 | this.disposed = true; | ||
72 | } | ||
73 | } | ||
74 | } | ||
75 | } | ||