aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2017-11-29 22:03:26 -0800
committerRob Mensching <rob@firegiant.com>2017-11-29 22:03:26 -0800
commit71c52d5af2293d3eb79882ce36b0411f81185c11 (patch)
tree23dd116bdd6abc2b0f7b488f490d1b77faa41812 /src/WixToolset.Core
parent0fa198ed8c6c6fc81e649466879752a99fe37d08 (diff)
downloadwix-71c52d5af2293d3eb79882ce36b0411f81185c11.tar.gz
wix-71c52d5af2293d3eb79882ce36b0411f81185c11.tar.bz2
wix-71c52d5af2293d3eb79882ce36b0411f81185c11.zip
Fix source path and cabinet processing
Diffstat (limited to 'src/WixToolset.Core')
-rw-r--r--src/WixToolset.Core/Cab/CabinetFileInfo.cs45
-rw-r--r--src/WixToolset.Core/Cab/Interop/CabInterop.cs316
-rw-r--r--src/WixToolset.Core/Cab/WixCreateCab.cs249
-rw-r--r--src/WixToolset.Core/Cab/WixEnumerateCab.cs89
-rw-r--r--src/WixToolset.Core/Cab/WixExtractCab.cs75
-rw-r--r--src/WixToolset.Core/Compiler.cs2
-rw-r--r--src/WixToolset.Core/Link/ResolveReferencesCommand.cs2
-rw-r--r--src/WixToolset.Core/Preprocess/IfContext.cs56
-rw-r--r--src/WixToolset.Core/Preprocess/IfState.cs22
-rw-r--r--src/WixToolset.Core/Preprocessor.cs2
10 files changed, 35 insertions, 823 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
3namespace 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
5namespace 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
3namespace 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
3namespace 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
3namespace 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}
diff --git a/src/WixToolset.Core/Compiler.cs b/src/WixToolset.Core/Compiler.cs
index 4b1ef033..406bc46a 100644
--- a/src/WixToolset.Core/Compiler.cs
+++ b/src/WixToolset.Core/Compiler.cs
@@ -5803,7 +5803,7 @@ namespace WixToolset.Core
5803 wixFileRow.File_AssemblyApplication = assemblyApplication; 5803 wixFileRow.File_AssemblyApplication = assemblyApplication;
5804 wixFileRow.Directory_ = directoryId; 5804 wixFileRow.Directory_ = directoryId;
5805 wixFileRow.DiskId = (CompilerConstants.IntegerNotSet == diskId) ? 0 : diskId; 5805 wixFileRow.DiskId = (CompilerConstants.IntegerNotSet == diskId) ? 0 : diskId;
5806 wixFileRow.Source = source; 5806 wixFileRow.Source = new IntermediateFieldPathValue { Path = source };
5807 wixFileRow.ProcessorArchitecture = procArch; 5807 wixFileRow.ProcessorArchitecture = procArch;
5808 wixFileRow.PatchGroup = (CompilerConstants.IntegerNotSet != patchGroup ? patchGroup : -1); 5808 wixFileRow.PatchGroup = (CompilerConstants.IntegerNotSet != patchGroup ? patchGroup : -1);
5809 wixFileRow.Attributes = (generatedShortFileName ? 0x1 : 0x0); 5809 wixFileRow.Attributes = (generatedShortFileName ? 0x1 : 0x0);
diff --git a/src/WixToolset.Core/Link/ResolveReferencesCommand.cs b/src/WixToolset.Core/Link/ResolveReferencesCommand.cs
index 9c3b2765..266871bd 100644
--- a/src/WixToolset.Core/Link/ResolveReferencesCommand.cs
+++ b/src/WixToolset.Core/Link/ResolveReferencesCommand.cs
@@ -62,7 +62,7 @@ namespace WixToolset.Link
62 { 62 {
63 // If we're building a Merge Module, ignore all references to the Media table 63 // If we're building a Merge Module, ignore all references to the Media table
64 // because Merge Modules don't have Media tables. 64 // because Merge Modules don't have Media tables.
65 if (this.BuildingMergeModule && wixSimpleReferenceRow.Definition.Type == TupleDefinitionType.Media) 65 if (this.BuildingMergeModule && wixSimpleReferenceRow.Table== "Media")
66 { 66 {
67 continue; 67 continue;
68 } 68 }
diff --git a/src/WixToolset.Core/Preprocess/IfContext.cs b/src/WixToolset.Core/Preprocess/IfContext.cs
index 64b5bd91..e7c6e6f5 100644
--- a/src/WixToolset.Core/Preprocess/IfContext.cs
+++ b/src/WixToolset.Core/Preprocess/IfContext.cs
@@ -1,46 +1,21 @@
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.Preprocess 3namespace WixToolset.Core.Preprocess
4{ 4{
5 using System;
6
7 /// <summary>
8 /// Current state of the if context.
9 /// </summary>
10 internal enum IfState
11 {
12 /// <summary>Context currently in unknown state.</summary>
13 Unknown,
14
15 /// <summary>Context currently inside if statement.</summary>
16 If,
17
18 /// <summary>Context currently inside elseif statement..</summary>
19 ElseIf,
20
21 /// <summary>Conext currently inside else statement.</summary>
22 Else,
23 }
24
25 /// <summary> 5 /// <summary>
26 /// Context for an if statement in the preprocessor. 6 /// Context for an if statement in the preprocessor.
27 /// </summary> 7 /// </summary>
28 internal sealed class IfContext 8 internal sealed class IfContext
29 { 9 {
30 private bool active;
31 private bool keep; 10 private bool keep;
32 private bool everKept;
33 private IfState state;
34 11
35 /// <summary> 12 /// <summary>
36 /// Creates a default if context object, which are used for if's within an inactive preprocessor block 13 /// Creates a default if context object, which are used for if's within an inactive preprocessor block
37 /// </summary> 14 /// </summary>
38 public IfContext() 15 public IfContext()
39 { 16 {
40 this.active = false; 17 this.WasEverTrue = true;
41 this.keep = false; 18 this.IfState = IfState.If;
42 this.everKept = true;
43 this.state = IfState.If;
44 } 19 }
45 20
46 /// <summary> 21 /// <summary>
@@ -51,21 +26,17 @@ namespace WixToolset.Preprocess
51 /// <param name="state">State of context to start in.</param> 26 /// <param name="state">State of context to start in.</param>
52 public IfContext(bool active, bool keep, IfState state) 27 public IfContext(bool active, bool keep, IfState state)
53 { 28 {
54 this.active = active; 29 this.Active = active;
55 this.keep = keep; 30 this.keep = keep;
56 this.everKept = keep; 31 this.WasEverTrue = keep;
57 this.state = state; 32 this.IfState = IfState.If;
58 } 33 }
59 34
60 /// <summary> 35 /// <summary>
61 /// Gets and sets if this if context is currently active. 36 /// Gets and sets if this if context is currently active.
62 /// </summary> 37 /// </summary>
63 /// <value>true if context is active.</value> 38 /// <value>true if context is active.</value>
64 public bool Active 39 public bool Active { get; set; }
65 {
66 get { return this.active; }
67 set { this.active = value; }
68 }
69 40
70 /// <summary> 41 /// <summary>
71 /// Gets and sets if context is current true. 42 /// Gets and sets if context is current true.
@@ -83,7 +54,7 @@ namespace WixToolset.Preprocess
83 this.keep = value; 54 this.keep = value;
84 if (this.keep) 55 if (this.keep)
85 { 56 {
86 this.everKept = true; 57 this.WasEverTrue = true;
87 } 58 }
88 } 59 }
89 } 60 }
@@ -92,19 +63,12 @@ namespace WixToolset.Preprocess
92 /// Gets if the context was ever true. 63 /// Gets if the context was ever true.
93 /// </summary> 64 /// </summary>
94 /// <value>True if context was ever true.</value> 65 /// <value>True if context was ever true.</value>
95 public bool WasEverTrue 66 public bool WasEverTrue { get; private set; }
96 {
97 get { return this.everKept; }
98 }
99 67
100 /// <summary> 68 /// <summary>
101 /// Gets the current state of the if context. 69 /// Gets the current state of the if context.
102 /// </summary> 70 /// </summary>
103 /// <value>Current state of context.</value> 71 /// <value>Current state of context.</value>
104 public IfState IfState 72 public IfState IfState { get; set; }
105 {
106 get { return this.state; }
107 set { this.state = value; }
108 }
109 } 73 }
110} 74}
diff --git a/src/WixToolset.Core/Preprocess/IfState.cs b/src/WixToolset.Core/Preprocess/IfState.cs
new file mode 100644
index 00000000..f5bb3e87
--- /dev/null
+++ b/src/WixToolset.Core/Preprocess/IfState.cs
@@ -0,0 +1,22 @@
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.Preprocess
4{
5 /// <summary>
6 /// Current state of the if context.
7 /// </summary>
8 internal enum IfState
9 {
10 /// <summary>Context currently in unknown state.</summary>
11 Unknown,
12
13 /// <summary>Context currently inside if statement.</summary>
14 If,
15
16 /// <summary>Context currently inside elseif statement..</summary>
17 ElseIf,
18
19 /// <summary>Conext currently inside else statement.</summary>
20 Else,
21 }
22}
diff --git a/src/WixToolset.Core/Preprocessor.cs b/src/WixToolset.Core/Preprocessor.cs
index 23f568a8..3aed0735 100644
--- a/src/WixToolset.Core/Preprocessor.cs
+++ b/src/WixToolset.Core/Preprocessor.cs
@@ -13,7 +13,7 @@ namespace WixToolset.Core
13 using System.Xml.Linq; 13 using System.Xml.Linq;
14 using WixToolset.Data; 14 using WixToolset.Data;
15 using WixToolset.Extensibility; 15 using WixToolset.Extensibility;
16 using WixToolset.Preprocess; 16 using WixToolset.Core.Preprocess;
17 17
18 /// <summary> 18 /// <summary>
19 /// Preprocessor object 19 /// Preprocessor object