1 | // ZipEntry.cs
|
---|
2 | // ------------------------------------------------------------------
|
---|
3 | //
|
---|
4 | // Copyright (c) 2006-2010 Dino Chiesa.
|
---|
5 | // All rights reserved.
|
---|
6 | //
|
---|
7 | // This code module is part of DotNetZip, a zipfile class library.
|
---|
8 | //
|
---|
9 | // ------------------------------------------------------------------
|
---|
10 | //
|
---|
11 | // This code is licensed under the Microsoft Public License.
|
---|
12 | // See the file License.txt for the license details.
|
---|
13 | // More info on: http://dotnetzip.codeplex.com
|
---|
14 | //
|
---|
15 | // ------------------------------------------------------------------
|
---|
16 | //
|
---|
17 | // last saved (in emacs):
|
---|
18 | // Time-stamp: <2011-August-06 17:25:53>
|
---|
19 | //
|
---|
20 | // ------------------------------------------------------------------
|
---|
21 | //
|
---|
22 | // This module defines the ZipEntry class, which models the entries within a zip file.
|
---|
23 | //
|
---|
24 | // Created: Tue, 27 Mar 2007 15:30
|
---|
25 | //
|
---|
26 | // ------------------------------------------------------------------
|
---|
27 |
|
---|
28 |
|
---|
29 | using System;
|
---|
30 | using System.IO;
|
---|
31 | using Interop = System.Runtime.InteropServices;
|
---|
32 |
|
---|
33 | namespace OfficeOpenXml.Packaging.Ionic.Zip
|
---|
34 | {
|
---|
35 | /// <summary>
|
---|
36 | /// Represents a single entry in a ZipFile. Typically, applications get a ZipEntry
|
---|
37 | /// by enumerating the entries within a ZipFile, or by adding an entry to a ZipFile.
|
---|
38 | /// </summary>
|
---|
39 |
|
---|
40 | [Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d00004")]
|
---|
41 | [Interop.ComVisible(true)]
|
---|
42 | #if !NETCF
|
---|
43 | [Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)] // AutoDual
|
---|
44 | #endif
|
---|
45 | internal partial class ZipEntry
|
---|
46 | {
|
---|
47 | /// <summary>
|
---|
48 | /// Default constructor.
|
---|
49 | /// </summary>
|
---|
50 | /// <remarks>
|
---|
51 | /// Applications should never need to call this directly. It is exposed to
|
---|
52 | /// support COM Automation environments.
|
---|
53 | /// </remarks>
|
---|
54 | public ZipEntry()
|
---|
55 | {
|
---|
56 | _CompressionMethod = (Int16)CompressionMethod.Deflate;
|
---|
57 | _CompressionLevel = Ionic.Zlib.CompressionLevel.Default;
|
---|
58 | _Encryption = EncryptionAlgorithm.None;
|
---|
59 | _Source = ZipEntrySource.None;
|
---|
60 | AlternateEncoding = System.Text.Encoding.GetEncoding("IBM437");
|
---|
61 | AlternateEncodingUsage = ZipOption.Never;
|
---|
62 | }
|
---|
63 |
|
---|
64 | /// <summary>
|
---|
65 | /// The time and date at which the file indicated by the <c>ZipEntry</c> was
|
---|
66 | /// last modified.
|
---|
67 | /// </summary>
|
---|
68 | ///
|
---|
69 | /// <remarks>
|
---|
70 | /// <para>
|
---|
71 | /// The DotNetZip library sets the LastModified value for an entry, equal to
|
---|
72 | /// the Last Modified time of the file in the filesystem. If an entry is
|
---|
73 | /// added from a stream, the library uses <c>System.DateTime.Now</c> for this
|
---|
74 | /// value, for the given entry.
|
---|
75 | /// </para>
|
---|
76 | ///
|
---|
77 | /// <para>
|
---|
78 | /// This property allows the application to retrieve and possibly set the
|
---|
79 | /// LastModified value on an entry, to an arbitrary value. <see
|
---|
80 | /// cref="System.DateTime"/> values with a <see cref="System.DateTimeKind" />
|
---|
81 | /// setting of <c>DateTimeKind.Unspecified</c> are taken to be expressed as
|
---|
82 | /// <c>DateTimeKind.Local</c>.
|
---|
83 | /// </para>
|
---|
84 | ///
|
---|
85 | /// <para>
|
---|
86 | /// Be aware that because of the way <see
|
---|
87 | /// href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">PKWare's
|
---|
88 | /// Zip specification</see> describes how times are stored in the zip file,
|
---|
89 | /// the full precision of the <c>System.DateTime</c> datatype is not stored
|
---|
90 | /// for the last modified time when saving zip files. For more information on
|
---|
91 | /// how times are formatted, see the PKZip specification.
|
---|
92 | /// </para>
|
---|
93 | ///
|
---|
94 | /// <para>
|
---|
95 | /// The actual last modified time of a file can be stored in multiple ways in
|
---|
96 | /// the zip file, and they are not mutually exclusive:
|
---|
97 | /// </para>
|
---|
98 | ///
|
---|
99 | /// <list type="bullet">
|
---|
100 | /// <item>
|
---|
101 | /// In the so-called "DOS" format, which has a 2-second precision. Values
|
---|
102 | /// are rounded to the nearest even second. For example, if the time on the
|
---|
103 | /// file is 12:34:43, then it will be stored as 12:34:44. This first value
|
---|
104 | /// is accessible via the <c>LastModified</c> property. This value is always
|
---|
105 | /// present in the metadata for each zip entry. In some cases the value is
|
---|
106 | /// invalid, or zero.
|
---|
107 | /// </item>
|
---|
108 | ///
|
---|
109 | /// <item>
|
---|
110 | /// In the so-called "Windows" or "NTFS" format, as an 8-byte integer
|
---|
111 | /// quantity expressed as the number of 1/10 milliseconds (in other words
|
---|
112 | /// the number of 100 nanosecond units) since January 1, 1601 (UTC). This
|
---|
113 | /// format is how Windows represents file times. This time is accessible
|
---|
114 | /// via the <c>ModifiedTime</c> property.
|
---|
115 | /// </item>
|
---|
116 | ///
|
---|
117 | /// <item>
|
---|
118 | /// In the "Unix" format, a 4-byte quantity specifying the number of seconds since
|
---|
119 | /// January 1, 1970 UTC.
|
---|
120 | /// </item>
|
---|
121 | ///
|
---|
122 | /// <item>
|
---|
123 | /// In an older format, now deprecated but still used by some current
|
---|
124 | /// tools. This format is also a 4-byte quantity specifying the number of
|
---|
125 | /// seconds since January 1, 1970 UTC.
|
---|
126 | /// </item>
|
---|
127 | ///
|
---|
128 | /// </list>
|
---|
129 | ///
|
---|
130 | /// <para>
|
---|
131 | /// Zip tools and libraries will always at least handle (read or write) the
|
---|
132 | /// DOS time, and may also handle the other time formats. Keep in mind that
|
---|
133 | /// while the names refer to particular operating systems, there is nothing in
|
---|
134 | /// the time formats themselves that prevents their use on other operating
|
---|
135 | /// systems.
|
---|
136 | /// </para>
|
---|
137 | ///
|
---|
138 | /// <para>
|
---|
139 | /// When reading ZIP files, the DotNetZip library reads the Windows-formatted
|
---|
140 | /// time, if it is stored in the entry, and sets both <c>LastModified</c> and
|
---|
141 | /// <c>ModifiedTime</c> to that value. When writing ZIP files, the DotNetZip
|
---|
142 | /// library by default will write both time quantities. It can also emit the
|
---|
143 | /// Unix-formatted time if desired (See <see
|
---|
144 | /// cref="EmitTimesInUnixFormatWhenSaving"/>.)
|
---|
145 | /// </para>
|
---|
146 | ///
|
---|
147 | /// <para>
|
---|
148 | /// The last modified time of the file created upon a call to
|
---|
149 | /// <c>ZipEntry.Extract()</c> may be adjusted during extraction to compensate
|
---|
150 | /// for differences in how the .NET Base Class Library deals with daylight
|
---|
151 | /// saving time (DST) versus how the Windows filesystem deals with daylight
|
---|
152 | /// saving time. Raymond Chen <see
|
---|
153 | /// href="http://blogs.msdn.com/oldnewthing/archive/2003/10/24/55413.aspx">provides
|
---|
154 | /// some good context</see>.
|
---|
155 | /// </para>
|
---|
156 | ///
|
---|
157 | /// <para>
|
---|
158 | /// In a nutshell: Daylight savings time rules change regularly. In 2007, for
|
---|
159 | /// example, the inception week of DST changed. In 1977, DST was in place all
|
---|
160 | /// year round. In 1945, likewise. And so on. Win32 does not attempt to
|
---|
161 | /// guess which time zone rules were in effect at the time in question. It
|
---|
162 | /// will render a time as "standard time" and allow the app to change to DST
|
---|
163 | /// as necessary. .NET makes a different choice.
|
---|
164 | /// </para>
|
---|
165 | ///
|
---|
166 | /// <para>
|
---|
167 | /// Compare the output of FileInfo.LastWriteTime.ToString("f") with what you
|
---|
168 | /// see in the Windows Explorer property sheet for a file that was last
|
---|
169 | /// written to on the other side of the DST transition. For example, suppose
|
---|
170 | /// the file was last modified on October 17, 2003, during DST but DST is not
|
---|
171 | /// currently in effect. Explorer's file properties reports Thursday, October
|
---|
172 | /// 17, 2003, 8:45:38 AM, but .NETs FileInfo reports Thursday, October 17,
|
---|
173 | /// 2003, 9:45 AM.
|
---|
174 | /// </para>
|
---|
175 | ///
|
---|
176 | /// <para>
|
---|
177 | /// Win32 says, "Thursday, October 17, 2002 8:45:38 AM PST". Note: Pacific
|
---|
178 | /// STANDARD Time. Even though October 17 of that year occurred during Pacific
|
---|
179 | /// Daylight Time, Win32 displays the time as standard time because that's
|
---|
180 | /// what time it is NOW.
|
---|
181 | /// </para>
|
---|
182 | ///
|
---|
183 | /// <para>
|
---|
184 | /// .NET BCL assumes that the current DST rules were in place at the time in
|
---|
185 | /// question. So, .NET says, "Well, if the rules in effect now were also in
|
---|
186 | /// effect on October 17, 2003, then that would be daylight time" so it
|
---|
187 | /// displays "Thursday, October 17, 2003, 9:45 AM PDT" - daylight time.
|
---|
188 | /// </para>
|
---|
189 | ///
|
---|
190 | /// <para>
|
---|
191 | /// So .NET gives a value which is more intuitively correct, but is also
|
---|
192 | /// potentially incorrect, and which is not invertible. Win32 gives a value
|
---|
193 | /// which is intuitively incorrect, but is strictly correct.
|
---|
194 | /// </para>
|
---|
195 | ///
|
---|
196 | /// <para>
|
---|
197 | /// Because of this funkiness, this library adds one hour to the LastModified
|
---|
198 | /// time on the extracted file, if necessary. That is to say, if the time in
|
---|
199 | /// question had occurred in what the .NET Base Class Library assumed to be
|
---|
200 | /// DST. This assumption may be wrong given the constantly changing DST rules,
|
---|
201 | /// but it is the best we can do.
|
---|
202 | /// </para>
|
---|
203 | ///
|
---|
204 | /// </remarks>
|
---|
205 | ///
|
---|
206 | public DateTime LastModified
|
---|
207 | {
|
---|
208 | get { return _LastModified.ToLocalTime(); }
|
---|
209 | set
|
---|
210 | {
|
---|
211 | _LastModified = (value.Kind == DateTimeKind.Unspecified)
|
---|
212 | ? DateTime.SpecifyKind(value, DateTimeKind.Local)
|
---|
213 | : value.ToLocalTime();
|
---|
214 | _Mtime = Ionic.Zip.SharedUtilities.AdjustTime_Reverse(_LastModified).ToUniversalTime();
|
---|
215 | _metadataChanged = true;
|
---|
216 | }
|
---|
217 | }
|
---|
218 |
|
---|
219 |
|
---|
220 | private int BufferSize
|
---|
221 | {
|
---|
222 | get
|
---|
223 | {
|
---|
224 | return this._container.BufferSize;
|
---|
225 | }
|
---|
226 | }
|
---|
227 |
|
---|
228 | /// <summary>
|
---|
229 | /// Last Modified time for the file represented by the entry.
|
---|
230 | /// </summary>
|
---|
231 | ///
|
---|
232 | /// <remarks>
|
---|
233 | ///
|
---|
234 | /// <para>
|
---|
235 | /// This value corresponds to the "last modified" time in the NTFS file times
|
---|
236 | /// as described in <see
|
---|
237 | /// href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">the Zip
|
---|
238 | /// specification</see>. When getting this property, the value may be
|
---|
239 | /// different from <see cref="LastModified" />. When setting the property,
|
---|
240 | /// the <see cref="LastModified"/> property also gets set, but with a lower
|
---|
241 | /// precision.
|
---|
242 | /// </para>
|
---|
243 | ///
|
---|
244 | /// <para>
|
---|
245 | /// Let me explain. It's going to take a while, so get
|
---|
246 | /// comfortable. Originally, waaaaay back in 1989 when the ZIP specification
|
---|
247 | /// was originally described by the esteemed Mr. Phil Katz, the dominant
|
---|
248 | /// operating system of the time was MS-DOS. MSDOS stored file times with a
|
---|
249 | /// 2-second precision, because, c'mon, <em>who is ever going to need better
|
---|
250 | /// resolution than THAT?</em> And so ZIP files, regardless of the platform on
|
---|
251 | /// which the zip file was created, store file times in exactly <see
|
---|
252 | /// href="http://www.vsft.com/hal/dostime.htm">the same format that DOS used
|
---|
253 | /// in 1989</see>.
|
---|
254 | /// </para>
|
---|
255 | ///
|
---|
256 | /// <para>
|
---|
257 | /// Since then, the ZIP spec has evolved, but the internal format for file
|
---|
258 | /// timestamps remains the same. Despite the fact that the way times are
|
---|
259 | /// stored in a zip file is rooted in DOS heritage, any program on any
|
---|
260 | /// operating system can format a time in this way, and most zip tools and
|
---|
261 | /// libraries DO - they round file times to the nearest even second and store
|
---|
262 | /// it just like DOS did 25+ years ago.
|
---|
263 | /// </para>
|
---|
264 | ///
|
---|
265 | /// <para>
|
---|
266 | /// PKWare extended the ZIP specification to allow a zip file to store what
|
---|
267 | /// are called "NTFS Times" and "Unix(tm) times" for a file. These are the
|
---|
268 | /// <em>last write</em>, <em>last access</em>, and <em>file creation</em>
|
---|
269 | /// times of a particular file. These metadata are not actually specific
|
---|
270 | /// to NTFS or Unix. They are tracked for each file by NTFS and by various
|
---|
271 | /// Unix filesystems, but they are also tracked by other filesystems, too.
|
---|
272 | /// The key point is that the times are <em>formatted in the zip file</em>
|
---|
273 | /// in the same way that NTFS formats the time (ticks since win32 epoch),
|
---|
274 | /// or in the same way that Unix formats the time (seconds since Unix
|
---|
275 | /// epoch). As with the DOS time, any tool or library running on any
|
---|
276 | /// operating system is capable of formatting a time in one of these ways
|
---|
277 | /// and embedding it into the zip file.
|
---|
278 | /// </para>
|
---|
279 | ///
|
---|
280 | /// <para>
|
---|
281 | /// These extended times are higher precision quantities than the DOS time.
|
---|
282 | /// As described above, the (DOS) LastModified has a precision of 2 seconds.
|
---|
283 | /// The Unix time is stored with a precision of 1 second. The NTFS time is
|
---|
284 | /// stored with a precision of 0.0000001 seconds. The quantities are easily
|
---|
285 | /// convertible, except for the loss of precision you may incur.
|
---|
286 | /// </para>
|
---|
287 | ///
|
---|
288 | /// <para>
|
---|
289 | /// A zip archive can store the {C,A,M} times in NTFS format, in Unix format,
|
---|
290 | /// or not at all. Often a tool running on Unix or Mac will embed the times
|
---|
291 | /// in Unix format (1 second precision), while WinZip running on Windows might
|
---|
292 | /// embed the times in NTFS format (precision of of 0.0000001 seconds). When
|
---|
293 | /// reading a zip file with these "extended" times, in either format,
|
---|
294 | /// DotNetZip represents the values with the
|
---|
295 | /// <c>ModifiedTime</c>, <c>AccessedTime</c> and <c>CreationTime</c>
|
---|
296 | /// properties on the <c>ZipEntry</c>.
|
---|
297 | /// </para>
|
---|
298 | ///
|
---|
299 | /// <para>
|
---|
300 | /// While any zip application or library, regardless of the platform it
|
---|
301 | /// runs on, could use any of the time formats allowed by the ZIP
|
---|
302 | /// specification, not all zip tools or libraries do support all these
|
---|
303 | /// formats. Storing the higher-precision times for each entry is
|
---|
304 | /// optional for zip files, and many tools and libraries don't use the
|
---|
305 | /// higher precision quantities at all. The old DOS time, represented by
|
---|
306 | /// <see cref="LastModified"/>, is guaranteed to be present, though it
|
---|
307 | /// sometimes unset.
|
---|
308 | /// </para>
|
---|
309 | ///
|
---|
310 | /// <para>
|
---|
311 | /// Ok, getting back to the question about how the <c>LastModified</c>
|
---|
312 | /// property relates to this <c>ModifiedTime</c>
|
---|
313 | /// property... <c>LastModified</c> is always set, while
|
---|
314 | /// <c>ModifiedTime</c> is not. (The other times stored in the <em>NTFS
|
---|
315 | /// times extension</em>, <c>CreationTime</c> and <c>AccessedTime</c> also
|
---|
316 | /// may not be set on an entry that is read from an existing zip file.)
|
---|
317 | /// When reading a zip file, then <c>LastModified</c> takes the DOS time
|
---|
318 | /// that is stored with the file. If the DOS time has been stored as zero
|
---|
319 | /// in the zipfile, then this library will use <c>DateTime.Now</c> for the
|
---|
320 | /// <c>LastModified</c> value. If the ZIP file was created by an evolved
|
---|
321 | /// tool, then there will also be higher precision NTFS or Unix times in
|
---|
322 | /// the zip file. In that case, this library will read those times, and
|
---|
323 | /// set <c>LastModified</c> and <c>ModifiedTime</c> to the same value, the
|
---|
324 | /// one corresponding to the last write time of the file. If there are no
|
---|
325 | /// higher precision times stored for the entry, then <c>ModifiedTime</c>
|
---|
326 | /// remains unset (likewise <c>AccessedTime</c> and <c>CreationTime</c>),
|
---|
327 | /// and <c>LastModified</c> keeps its DOS time.
|
---|
328 | /// </para>
|
---|
329 | ///
|
---|
330 | /// <para>
|
---|
331 | /// When creating zip files with this library, by default the extended time
|
---|
332 | /// properties (<c>ModifiedTime</c>, <c>AccessedTime</c>, and
|
---|
333 | /// <c>CreationTime</c>) are set on the ZipEntry instance, and these data are
|
---|
334 | /// stored in the zip archive for each entry, in NTFS format. If you add an
|
---|
335 | /// entry from an actual filesystem file, then the entry gets the actual file
|
---|
336 | /// times for that file, to NTFS-level precision. If you add an entry from a
|
---|
337 | /// stream, or a string, then the times get the value <c>DateTime.Now</c>. In
|
---|
338 | /// this case <c>LastModified</c> and <c>ModifiedTime</c> will be identical,
|
---|
339 | /// to 2 seconds of precision. You can explicitly set the
|
---|
340 | /// <c>CreationTime</c>, <c>AccessedTime</c>, and <c>ModifiedTime</c> of an
|
---|
341 | /// entry using the property setters. If you want to set all of those
|
---|
342 | /// quantities, it's more efficient to use the <see
|
---|
343 | /// cref="SetEntryTimes(DateTime, DateTime, DateTime)"/> method. Those
|
---|
344 | /// changes are not made permanent in the zip file until you call <see
|
---|
345 | /// cref="ZipFile.Save()"/> or one of its cousins.
|
---|
346 | /// </para>
|
---|
347 | ///
|
---|
348 | /// <para>
|
---|
349 | /// When creating a zip file, you can override the default behavior of
|
---|
350 | /// this library for formatting times in the zip file, disabling the
|
---|
351 | /// embedding of file times in NTFS format or enabling the storage of file
|
---|
352 | /// times in Unix format, or both. You may want to do this, for example,
|
---|
353 | /// when creating a zip file on Windows, that will be consumed on a Mac,
|
---|
354 | /// by an application that is not hip to the "NTFS times" format. To do
|
---|
355 | /// this, use the <see cref="EmitTimesInWindowsFormatWhenSaving"/> and
|
---|
356 | /// <see cref="EmitTimesInUnixFormatWhenSaving"/> properties. A valid zip
|
---|
357 | /// file may store the file times in both formats. But, there are no
|
---|
358 | /// guarantees that a program running on Mac or Linux will gracefully
|
---|
359 | /// handle the NTFS-formatted times when Unix times are present, or that a
|
---|
360 | /// non-DotNetZip-powered application running on Windows will be able to
|
---|
361 | /// handle file times in Unix format. DotNetZip will always do something
|
---|
362 | /// reasonable; other libraries or tools may not. When in doubt, test.
|
---|
363 | /// </para>
|
---|
364 | ///
|
---|
365 | /// <para>
|
---|
366 | /// I'll bet you didn't think one person could type so much about time, eh?
|
---|
367 | /// And reading it was so enjoyable, too! Well, in appreciation, <see
|
---|
368 | /// href="http://cheeso.members.winisp.net/DotNetZipDonate.aspx">maybe you
|
---|
369 | /// should donate</see>?
|
---|
370 | /// </para>
|
---|
371 | /// </remarks>
|
---|
372 | ///
|
---|
373 | /// <seealso cref="AccessedTime"/>
|
---|
374 | /// <seealso cref="CreationTime"/>
|
---|
375 | /// <seealso cref="Ionic.Zip.ZipEntry.LastModified"/>
|
---|
376 | /// <seealso cref="SetEntryTimes"/>
|
---|
377 | public DateTime ModifiedTime
|
---|
378 | {
|
---|
379 | get { return _Mtime; }
|
---|
380 | set
|
---|
381 | {
|
---|
382 | SetEntryTimes(_Ctime, _Atime, value);
|
---|
383 | }
|
---|
384 | }
|
---|
385 |
|
---|
386 | /// <summary>
|
---|
387 | /// Last Access time for the file represented by the entry.
|
---|
388 | /// </summary>
|
---|
389 | /// <remarks>
|
---|
390 | /// This value may or may not be meaningful. If the <c>ZipEntry</c> was read from an existing
|
---|
391 | /// Zip archive, this information may not be available. For an explanation of why, see
|
---|
392 | /// <see cref="ModifiedTime"/>.
|
---|
393 | /// </remarks>
|
---|
394 | /// <seealso cref="ModifiedTime"/>
|
---|
395 | /// <seealso cref="CreationTime"/>
|
---|
396 | /// <seealso cref="SetEntryTimes"/>
|
---|
397 | public DateTime AccessedTime
|
---|
398 | {
|
---|
399 | get { return _Atime; }
|
---|
400 | set
|
---|
401 | {
|
---|
402 | SetEntryTimes(_Ctime, value, _Mtime);
|
---|
403 | }
|
---|
404 | }
|
---|
405 |
|
---|
406 | /// <summary>
|
---|
407 | /// The file creation time for the file represented by the entry.
|
---|
408 | /// </summary>
|
---|
409 | ///
|
---|
410 | /// <remarks>
|
---|
411 | /// This value may or may not be meaningful. If the <c>ZipEntry</c> was read
|
---|
412 | /// from an existing zip archive, and the creation time was not set on the entry
|
---|
413 | /// when the zip file was created, then this property may be meaningless. For an
|
---|
414 | /// explanation of why, see <see cref="ModifiedTime"/>.
|
---|
415 | /// </remarks>
|
---|
416 | /// <seealso cref="ModifiedTime"/>
|
---|
417 | /// <seealso cref="AccessedTime"/>
|
---|
418 | /// <seealso cref="SetEntryTimes"/>
|
---|
419 | public DateTime CreationTime
|
---|
420 | {
|
---|
421 | get { return _Ctime; }
|
---|
422 | set
|
---|
423 | {
|
---|
424 | SetEntryTimes(value, _Atime, _Mtime);
|
---|
425 | }
|
---|
426 | }
|
---|
427 |
|
---|
428 | /// <summary>
|
---|
429 | /// Sets the NTFS Creation, Access, and Modified times for the given entry.
|
---|
430 | /// </summary>
|
---|
431 | ///
|
---|
432 | /// <remarks>
|
---|
433 | /// <para>
|
---|
434 | /// When adding an entry from a file or directory, the Creation, Access, and
|
---|
435 | /// Modified times for the given entry are automatically set from the
|
---|
436 | /// filesystem values. When adding an entry from a stream or string, the
|
---|
437 | /// values are implicitly set to DateTime.Now. The application may wish to
|
---|
438 | /// set these values to some arbitrary value, before saving the archive, and
|
---|
439 | /// can do so using the various setters. If you want to set all of the times,
|
---|
440 | /// this method is more efficient.
|
---|
441 | /// </para>
|
---|
442 | ///
|
---|
443 | /// <para>
|
---|
444 | /// The values you set here will be retrievable with the <see
|
---|
445 | /// cref="ModifiedTime"/>, <see cref="CreationTime"/> and <see
|
---|
446 | /// cref="AccessedTime"/> properties.
|
---|
447 | /// </para>
|
---|
448 | ///
|
---|
449 | /// <para>
|
---|
450 | /// When this method is called, if both <see
|
---|
451 | /// cref="EmitTimesInWindowsFormatWhenSaving"/> and <see
|
---|
452 | /// cref="EmitTimesInUnixFormatWhenSaving"/> are false, then the
|
---|
453 | /// <c>EmitTimesInWindowsFormatWhenSaving</c> flag is automatically set.
|
---|
454 | /// </para>
|
---|
455 | ///
|
---|
456 | /// <para>
|
---|
457 | /// DateTime values provided here without a DateTimeKind are assumed to be Local Time.
|
---|
458 | /// </para>
|
---|
459 | ///
|
---|
460 | /// </remarks>
|
---|
461 | /// <param name="created">the creation time of the entry.</param>
|
---|
462 | /// <param name="accessed">the last access time of the entry.</param>
|
---|
463 | /// <param name="modified">the last modified time of the entry.</param>
|
---|
464 | ///
|
---|
465 | /// <seealso cref="EmitTimesInWindowsFormatWhenSaving" />
|
---|
466 | /// <seealso cref="EmitTimesInUnixFormatWhenSaving" />
|
---|
467 | /// <seealso cref="AccessedTime"/>
|
---|
468 | /// <seealso cref="CreationTime"/>
|
---|
469 | /// <seealso cref="ModifiedTime"/>
|
---|
470 | public void SetEntryTimes(DateTime created, DateTime accessed, DateTime modified)
|
---|
471 | {
|
---|
472 | _ntfsTimesAreSet = true;
|
---|
473 | if (created == _zeroHour && created.Kind == _zeroHour.Kind) created = _win32Epoch;
|
---|
474 | if (accessed == _zeroHour && accessed.Kind == _zeroHour.Kind) accessed = _win32Epoch;
|
---|
475 | if (modified == _zeroHour && modified.Kind == _zeroHour.Kind) modified = _win32Epoch;
|
---|
476 | _Ctime = created.ToUniversalTime();
|
---|
477 | _Atime = accessed.ToUniversalTime();
|
---|
478 | _Mtime = modified.ToUniversalTime();
|
---|
479 | _LastModified = _Mtime;
|
---|
480 | if (!_emitUnixTimes && !_emitNtfsTimes)
|
---|
481 | _emitNtfsTimes = true;
|
---|
482 | _metadataChanged = true;
|
---|
483 | }
|
---|
484 |
|
---|
485 |
|
---|
486 |
|
---|
487 | /// <summary>
|
---|
488 | /// Specifies whether the Creation, Access, and Modified times for the given
|
---|
489 | /// entry will be emitted in "Windows format" when the zip archive is saved.
|
---|
490 | /// </summary>
|
---|
491 | ///
|
---|
492 | /// <remarks>
|
---|
493 | /// <para>
|
---|
494 | /// An application creating a zip archive can use this flag to explicitly
|
---|
495 | /// specify that the file times for the entry should or should not be stored
|
---|
496 | /// in the zip archive in the format used by Windows. The default value of
|
---|
497 | /// this property is <c>true</c>.
|
---|
498 | /// </para>
|
---|
499 | ///
|
---|
500 | /// <para>
|
---|
501 | /// When adding an entry from a file or directory, the Creation (<see
|
---|
502 | /// cref="CreationTime"/>), Access (<see cref="AccessedTime"/>), and Modified
|
---|
503 | /// (<see cref="ModifiedTime"/>) times for the given entry are automatically
|
---|
504 | /// set from the filesystem values. When adding an entry from a stream or
|
---|
505 | /// string, all three values are implicitly set to DateTime.Now. Applications
|
---|
506 | /// can also explicitly set those times by calling <see
|
---|
507 | /// cref="SetEntryTimes(DateTime, DateTime, DateTime)" />.
|
---|
508 | /// </para>
|
---|
509 | ///
|
---|
510 | /// <para>
|
---|
511 | /// <see
|
---|
512 | /// href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">PKWARE's
|
---|
513 | /// zip specification</see> describes multiple ways to format these times in a
|
---|
514 | /// zip file. One is the format Windows applications normally use: 100ns ticks
|
---|
515 | /// since Jan 1, 1601 UTC. The other is a format Unix applications typically
|
---|
516 | /// use: seconds since January 1, 1970 UTC. Each format can be stored in an
|
---|
517 | /// "extra field" in the zip entry when saving the zip archive. The former
|
---|
518 | /// uses an extra field with a Header Id of 0x000A, while the latter uses a
|
---|
519 | /// header ID of 0x5455.
|
---|
520 | /// </para>
|
---|
521 | ///
|
---|
522 | /// <para>
|
---|
523 | /// Not all zip tools and libraries can interpret these fields. Windows
|
---|
524 | /// compressed folders is one that can read the Windows Format timestamps,
|
---|
525 | /// while I believe the <see href="http://www.info-zip.org/">Infozip</see>
|
---|
526 | /// tools can read the Unix format timestamps. Although the time values are
|
---|
527 | /// easily convertible, subject to a loss of precision, some tools and
|
---|
528 | /// libraries may be able to read only one or the other. DotNetZip can read or
|
---|
529 | /// write times in either or both formats.
|
---|
530 | /// </para>
|
---|
531 | ///
|
---|
532 | /// <para>
|
---|
533 | /// The times stored are taken from <see cref="ModifiedTime"/>, <see
|
---|
534 | /// cref="AccessedTime"/>, and <see cref="CreationTime"/>.
|
---|
535 | /// </para>
|
---|
536 | ///
|
---|
537 | /// <para>
|
---|
538 | /// This property is not mutually exclusive from the <see
|
---|
539 | /// cref="ZipEntry.EmitTimesInUnixFormatWhenSaving"/> property. It is
|
---|
540 | /// possible that a zip entry can embed the timestamps in both forms, one
|
---|
541 | /// form, or neither. But, there are no guarantees that a program running on
|
---|
542 | /// Mac or Linux will gracefully handle NTFS Formatted times, or that a
|
---|
543 | /// non-DotNetZip-powered application running on Windows will be able to
|
---|
544 | /// handle file times in Unix format. When in doubt, test.
|
---|
545 | /// </para>
|
---|
546 | ///
|
---|
547 | /// <para>
|
---|
548 | /// Normally you will use the <see
|
---|
549 | /// cref="ZipFile.EmitTimesInWindowsFormatWhenSaving">ZipFile.EmitTimesInWindowsFormatWhenSaving</see>
|
---|
550 | /// property, to specify the behavior for all entries in a zip, rather than
|
---|
551 | /// the property on each individual entry.
|
---|
552 | /// </para>
|
---|
553 | ///
|
---|
554 | /// </remarks>
|
---|
555 | ///
|
---|
556 | /// <seealso cref="SetEntryTimes(DateTime, DateTime, DateTime)"/>
|
---|
557 | /// <seealso cref="EmitTimesInUnixFormatWhenSaving"/>
|
---|
558 | /// <seealso cref="CreationTime"/>
|
---|
559 | /// <seealso cref="AccessedTime"/>
|
---|
560 | /// <seealso cref="ModifiedTime"/>
|
---|
561 | public bool EmitTimesInWindowsFormatWhenSaving
|
---|
562 | {
|
---|
563 | get
|
---|
564 | {
|
---|
565 | return _emitNtfsTimes;
|
---|
566 | }
|
---|
567 | set
|
---|
568 | {
|
---|
569 | _emitNtfsTimes = value;
|
---|
570 | _metadataChanged = true;
|
---|
571 | }
|
---|
572 | }
|
---|
573 |
|
---|
574 | /// <summary>
|
---|
575 | /// Specifies whether the Creation, Access, and Modified times for the given
|
---|
576 | /// entry will be emitted in "Unix(tm) format" when the zip archive is saved.
|
---|
577 | /// </summary>
|
---|
578 | ///
|
---|
579 | /// <remarks>
|
---|
580 | /// <para>
|
---|
581 | /// An application creating a zip archive can use this flag to explicitly
|
---|
582 | /// specify that the file times for the entry should or should not be stored
|
---|
583 | /// in the zip archive in the format used by Unix. By default this flag is
|
---|
584 | /// <c>false</c>, meaning the Unix-format times are not stored in the zip
|
---|
585 | /// archive.
|
---|
586 | /// </para>
|
---|
587 | ///
|
---|
588 | /// <para>
|
---|
589 | /// When adding an entry from a file or directory, the Creation (<see
|
---|
590 | /// cref="CreationTime"/>), Access (<see cref="AccessedTime"/>), and Modified
|
---|
591 | /// (<see cref="ModifiedTime"/>) times for the given entry are automatically
|
---|
592 | /// set from the filesystem values. When adding an entry from a stream or
|
---|
593 | /// string, all three values are implicitly set to DateTime.Now. Applications
|
---|
594 | /// can also explicitly set those times by calling <see
|
---|
595 | /// cref="SetEntryTimes(DateTime, DateTime, DateTime)"/>.
|
---|
596 | /// </para>
|
---|
597 | ///
|
---|
598 | /// <para>
|
---|
599 | /// <see
|
---|
600 | /// href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">PKWARE's
|
---|
601 | /// zip specification</see> describes multiple ways to format these times in a
|
---|
602 | /// zip file. One is the format Windows applications normally use: 100ns ticks
|
---|
603 | /// since Jan 1, 1601 UTC. The other is a format Unix applications typically
|
---|
604 | /// use: seconds since Jan 1, 1970 UTC. Each format can be stored in an
|
---|
605 | /// "extra field" in the zip entry when saving the zip archive. The former
|
---|
606 | /// uses an extra field with a Header Id of 0x000A, while the latter uses a
|
---|
607 | /// header ID of 0x5455.
|
---|
608 | /// </para>
|
---|
609 | ///
|
---|
610 | /// <para>
|
---|
611 | /// Not all tools and libraries can interpret these fields. Windows
|
---|
612 | /// compressed folders is one that can read the Windows Format timestamps,
|
---|
613 | /// while I believe the <see href="http://www.info-zip.org/">Infozip</see>
|
---|
614 | /// tools can read the Unix format timestamps. Although the time values are
|
---|
615 | /// easily convertible, subject to a loss of precision, some tools and
|
---|
616 | /// libraries may be able to read only one or the other. DotNetZip can read or
|
---|
617 | /// write times in either or both formats.
|
---|
618 | /// </para>
|
---|
619 | ///
|
---|
620 | /// <para>
|
---|
621 | /// The times stored are taken from <see cref="ModifiedTime"/>, <see
|
---|
622 | /// cref="AccessedTime"/>, and <see cref="CreationTime"/>.
|
---|
623 | /// </para>
|
---|
624 | ///
|
---|
625 | /// <para>
|
---|
626 | /// This property is not mutually exclusive from the <see
|
---|
627 | /// cref="ZipEntry.EmitTimesInWindowsFormatWhenSaving"/> property. It is
|
---|
628 | /// possible that a zip entry can embed the timestamps in both forms, one
|
---|
629 | /// form, or neither. But, there are no guarantees that a program running on
|
---|
630 | /// Mac or Linux will gracefully handle NTFS Formatted times, or that a
|
---|
631 | /// non-DotNetZip-powered application running on Windows will be able to
|
---|
632 | /// handle file times in Unix format. When in doubt, test.
|
---|
633 | /// </para>
|
---|
634 | ///
|
---|
635 | /// <para>
|
---|
636 | /// Normally you will use the <see
|
---|
637 | /// cref="ZipFile.EmitTimesInUnixFormatWhenSaving">ZipFile.EmitTimesInUnixFormatWhenSaving</see>
|
---|
638 | /// property, to specify the behavior for all entries, rather than the
|
---|
639 | /// property on each individual entry.
|
---|
640 | /// </para>
|
---|
641 | /// </remarks>
|
---|
642 | ///
|
---|
643 | /// <seealso cref="SetEntryTimes(DateTime, DateTime, DateTime)"/>
|
---|
644 | /// <seealso cref="EmitTimesInWindowsFormatWhenSaving"/>
|
---|
645 | /// <seealso cref="ZipFile.EmitTimesInUnixFormatWhenSaving"/>
|
---|
646 | /// <seealso cref="CreationTime"/>
|
---|
647 | /// <seealso cref="AccessedTime"/>
|
---|
648 | /// <seealso cref="ModifiedTime"/>
|
---|
649 | public bool EmitTimesInUnixFormatWhenSaving
|
---|
650 | {
|
---|
651 | get
|
---|
652 | {
|
---|
653 | return _emitUnixTimes;
|
---|
654 | }
|
---|
655 | set
|
---|
656 | {
|
---|
657 | _emitUnixTimes = value;
|
---|
658 | _metadataChanged = true;
|
---|
659 | }
|
---|
660 | }
|
---|
661 |
|
---|
662 |
|
---|
663 | /// <summary>
|
---|
664 | /// The type of timestamp attached to the ZipEntry.
|
---|
665 | /// </summary>
|
---|
666 | ///
|
---|
667 | /// <remarks>
|
---|
668 | /// This property is valid only for a ZipEntry that was read from a zip archive.
|
---|
669 | /// It indicates the type of timestamp attached to the entry.
|
---|
670 | /// </remarks>
|
---|
671 | ///
|
---|
672 | /// <seealso cref="EmitTimesInWindowsFormatWhenSaving"/>
|
---|
673 | /// <seealso cref="EmitTimesInUnixFormatWhenSaving"/>
|
---|
674 | internal ZipEntryTimestamp Timestamp
|
---|
675 | {
|
---|
676 | get
|
---|
677 | {
|
---|
678 | return _timestamp;
|
---|
679 | }
|
---|
680 | }
|
---|
681 |
|
---|
682 | /// <summary>
|
---|
683 | /// The file attributes for the entry.
|
---|
684 | /// </summary>
|
---|
685 | ///
|
---|
686 | /// <remarks>
|
---|
687 | ///
|
---|
688 | /// <para>
|
---|
689 | /// The <see cref="System.IO.FileAttributes">attributes</see> in NTFS include
|
---|
690 | /// ReadOnly, Archive, Hidden, System, and Indexed. When adding a
|
---|
691 | /// <c>ZipEntry</c> to a ZipFile, these attributes are set implicitly when
|
---|
692 | /// adding an entry from the filesystem. When adding an entry from a stream
|
---|
693 | /// or string, the Attributes are not set implicitly. Regardless of the way
|
---|
694 | /// an entry was added to a <c>ZipFile</c>, you can set the attributes
|
---|
695 | /// explicitly if you like.
|
---|
696 | /// </para>
|
---|
697 | ///
|
---|
698 | /// <para>
|
---|
699 | /// When reading a <c>ZipEntry</c> from a <c>ZipFile</c>, the attributes are
|
---|
700 | /// set according to the data stored in the <c>ZipFile</c>. If you extract the
|
---|
701 | /// entry from the archive to a filesystem file, DotNetZip will set the
|
---|
702 | /// attributes on the resulting file accordingly.
|
---|
703 | /// </para>
|
---|
704 | ///
|
---|
705 | /// <para>
|
---|
706 | /// The attributes can be set explicitly by the application. For example the
|
---|
707 | /// application may wish to set the <c>FileAttributes.ReadOnly</c> bit for all
|
---|
708 | /// entries added to an archive, so that on unpack, this attribute will be set
|
---|
709 | /// on the extracted file. Any changes you make to this property are made
|
---|
710 | /// permanent only when you call a <c>Save()</c> method on the <c>ZipFile</c>
|
---|
711 | /// instance that contains the ZipEntry.
|
---|
712 | /// </para>
|
---|
713 | ///
|
---|
714 | /// <para>
|
---|
715 | /// For example, an application may wish to zip up a directory and set the
|
---|
716 | /// ReadOnly bit on every file in the archive, so that upon later extraction,
|
---|
717 | /// the resulting files will be marked as ReadOnly. Not every extraction tool
|
---|
718 | /// respects these attributes, but if you unpack with DotNetZip, as for
|
---|
719 | /// example in a self-extracting archive, then the attributes will be set as
|
---|
720 | /// they are stored in the <c>ZipFile</c>.
|
---|
721 | /// </para>
|
---|
722 | ///
|
---|
723 | /// <para>
|
---|
724 | /// These attributes may not be interesting or useful if the resulting archive
|
---|
725 | /// is extracted on a non-Windows platform. How these attributes get used
|
---|
726 | /// upon extraction depends on the platform and tool used.
|
---|
727 | /// </para>
|
---|
728 | ///
|
---|
729 | /// <para>
|
---|
730 | /// This property is only partially supported in the Silverlight version
|
---|
731 | /// of the library: applications can read attributes on entries within
|
---|
732 | /// ZipFiles. But extracting entries within Silverlight will not set the
|
---|
733 | /// attributes on the extracted files.
|
---|
734 | /// </para>
|
---|
735 | ///
|
---|
736 | /// </remarks>
|
---|
737 | public System.IO.FileAttributes Attributes
|
---|
738 | {
|
---|
739 | // workitem 7071
|
---|
740 | get { return (System.IO.FileAttributes)_ExternalFileAttrs; }
|
---|
741 | set
|
---|
742 | {
|
---|
743 | _ExternalFileAttrs = (int)value;
|
---|
744 | // Since the application is explicitly setting the attributes, overwriting
|
---|
745 | // whatever was there, we will explicitly set the Version made by field.
|
---|
746 | // workitem 7926 - "version made by" OS should be zero for compat with WinZip
|
---|
747 | _VersionMadeBy = (0 << 8) + 45; // v4.5 of the spec
|
---|
748 | _metadataChanged = true;
|
---|
749 | }
|
---|
750 | }
|
---|
751 |
|
---|
752 |
|
---|
753 | /// <summary>
|
---|
754 | /// The name of the filesystem file, referred to by the ZipEntry.
|
---|
755 | /// </summary>
|
---|
756 | ///
|
---|
757 | /// <remarks>
|
---|
758 | /// <para>
|
---|
759 | /// This property specifies the thing-to-be-zipped on disk, and is set only
|
---|
760 | /// when the <c>ZipEntry</c> is being created from a filesystem file. If the
|
---|
761 | /// <c>ZipFile</c> is instantiated by reading an existing .zip archive, then
|
---|
762 | /// the LocalFileName will be <c>null</c> (<c>Nothing</c> in VB).
|
---|
763 | /// </para>
|
---|
764 | ///
|
---|
765 | /// <para>
|
---|
766 | /// When it is set, the value of this property may be different than <see
|
---|
767 | /// cref="FileName"/>, which is the path used in the archive itself. If you
|
---|
768 | /// call <c>Zip.AddFile("foop.txt", AlternativeDirectory)</c>, then the path
|
---|
769 | /// used for the <c>ZipEntry</c> within the zip archive will be different
|
---|
770 | /// than this path.
|
---|
771 | /// </para>
|
---|
772 | ///
|
---|
773 | /// <para>
|
---|
774 | /// If the entry is being added from a stream, then this is null (Nothing in VB).
|
---|
775 | /// </para>
|
---|
776 | ///
|
---|
777 | /// </remarks>
|
---|
778 | /// <seealso cref="FileName"/>
|
---|
779 | internal string LocalFileName
|
---|
780 | {
|
---|
781 | get { return _LocalFileName; }
|
---|
782 | }
|
---|
783 |
|
---|
784 | /// <summary>
|
---|
785 | /// The name of the file contained in the ZipEntry.
|
---|
786 | /// </summary>
|
---|
787 | ///
|
---|
788 | /// <remarks>
|
---|
789 | ///
|
---|
790 | /// <para>
|
---|
791 | /// This is the name of the entry in the <c>ZipFile</c> itself. When creating
|
---|
792 | /// a zip archive, if the <c>ZipEntry</c> has been created from a filesystem
|
---|
793 | /// file, via a call to <see cref="ZipFile.AddFile(String,String)"/> or <see
|
---|
794 | /// cref="ZipFile.AddItem(String,String)"/>, or a related overload, the value
|
---|
795 | /// of this property is derived from the name of that file. The
|
---|
796 | /// <c>FileName</c> property does not include drive letters, and may include a
|
---|
797 | /// different directory path, depending on the value of the
|
---|
798 | /// <c>directoryPathInArchive</c> parameter used when adding the entry into
|
---|
799 | /// the <c>ZipFile</c>.
|
---|
800 | /// </para>
|
---|
801 | ///
|
---|
802 | /// <para>
|
---|
803 | /// In some cases there is no related filesystem file - for example when a
|
---|
804 | /// <c>ZipEntry</c> is created using <see cref="ZipFile.AddEntry(string,
|
---|
805 | /// string)"/> or one of the similar overloads. In this case, the value of
|
---|
806 | /// this property is derived from the fileName and the directory path passed
|
---|
807 | /// to that method.
|
---|
808 | /// </para>
|
---|
809 | ///
|
---|
810 | /// <para>
|
---|
811 | /// When reading a zip file, this property takes the value of the entry name
|
---|
812 | /// as stored in the zip file. If you extract such an entry, the extracted
|
---|
813 | /// file will take the name given by this property.
|
---|
814 | /// </para>
|
---|
815 | ///
|
---|
816 | /// <para>
|
---|
817 | /// Applications can set this property when creating new zip archives or when
|
---|
818 | /// reading existing archives. When setting this property, the actual value
|
---|
819 | /// that is set will replace backslashes with forward slashes, in accordance
|
---|
820 | /// with <see
|
---|
821 | /// href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">the Zip
|
---|
822 | /// specification</see>, for compatibility with Unix(tm) and ... get
|
---|
823 | /// this.... Amiga!
|
---|
824 | /// </para>
|
---|
825 | ///
|
---|
826 | /// <para>
|
---|
827 | /// If an application reads a <c>ZipFile</c> via <see
|
---|
828 | /// cref="ZipFile.Read(String)"/> or a related overload, and then explicitly
|
---|
829 | /// sets the FileName on an entry contained within the <c>ZipFile</c>, and
|
---|
830 | /// then calls <see cref="ZipFile.Save()"/>, the application will effectively
|
---|
831 | /// rename the entry within the zip archive.
|
---|
832 | /// </para>
|
---|
833 | ///
|
---|
834 | /// <para>
|
---|
835 | /// If an application sets the value of <c>FileName</c>, then calls
|
---|
836 | /// <c>Extract()</c> on the entry, the entry is extracted to a file using the
|
---|
837 | /// newly set value as the filename. The <c>FileName</c> value is made
|
---|
838 | /// permanent in the zip archive only <em>after</em> a call to one of the
|
---|
839 | /// <c>ZipFile.Save()</c> methods on the <c>ZipFile</c> that contains the
|
---|
840 | /// ZipEntry.
|
---|
841 | /// </para>
|
---|
842 | ///
|
---|
843 | /// <para>
|
---|
844 | /// If an application attempts to set the <c>FileName</c> to a value that
|
---|
845 | /// would result in a duplicate entry in the <c>ZipFile</c>, an exception is
|
---|
846 | /// thrown.
|
---|
847 | /// </para>
|
---|
848 | ///
|
---|
849 | /// <para>
|
---|
850 | /// When a <c>ZipEntry</c> is contained within a <c>ZipFile</c>, applications
|
---|
851 | /// cannot rename the entry within the context of a <c>foreach</c> (<c>For
|
---|
852 | /// Each</c> in VB) loop, because of the way the <c>ZipFile</c> stores
|
---|
853 | /// entries. If you need to enumerate through all the entries and rename one
|
---|
854 | /// or more of them, use <see
|
---|
855 | /// cref="ZipFile.EntriesSorted">ZipFile.EntriesSorted</see> as the
|
---|
856 | /// collection. See also, <see
|
---|
857 | /// cref="ZipFile.GetEnumerator()">ZipFile.GetEnumerator()</see>.
|
---|
858 | /// </para>
|
---|
859 | ///
|
---|
860 | /// </remarks>
|
---|
861 | public string FileName
|
---|
862 | {
|
---|
863 | get { return _FileNameInArchive; }
|
---|
864 | set
|
---|
865 | {
|
---|
866 | if (_container.ZipFile == null)
|
---|
867 | throw new ZipException("Cannot rename; this is not supported in ZipOutputStream/ZipInputStream.");
|
---|
868 |
|
---|
869 | // rename the entry!
|
---|
870 | if (String.IsNullOrEmpty(value)) throw new ZipException("The FileName must be non empty and non-null.");
|
---|
871 |
|
---|
872 | var filename = ZipEntry.NameInArchive(value, null);
|
---|
873 | // workitem 8180
|
---|
874 | if (_FileNameInArchive == filename) return; // nothing to do
|
---|
875 |
|
---|
876 | // workitem 8047 - when renaming, must remove old and then add a new entry
|
---|
877 | this._container.ZipFile.RemoveEntry(this);
|
---|
878 | this._container.ZipFile.InternalAddEntry(filename, this);
|
---|
879 |
|
---|
880 | _FileNameInArchive = filename;
|
---|
881 | _container.ZipFile.NotifyEntryChanged();
|
---|
882 | _metadataChanged = true;
|
---|
883 | }
|
---|
884 | }
|
---|
885 |
|
---|
886 |
|
---|
887 | /// <summary>
|
---|
888 | /// The stream that provides content for the ZipEntry.
|
---|
889 | /// </summary>
|
---|
890 | ///
|
---|
891 | /// <remarks>
|
---|
892 | ///
|
---|
893 | /// <para>
|
---|
894 | /// The application can use this property to set the input stream for an
|
---|
895 | /// entry on a just-in-time basis. Imagine a scenario where the application
|
---|
896 | /// creates a <c>ZipFile</c> comprised of content obtained from hundreds of
|
---|
897 | /// files, via calls to <c>AddFile()</c>. The DotNetZip library opens streams
|
---|
898 | /// on these files on a just-in-time basis, only when writing the entry out to
|
---|
899 | /// an external store within the scope of a <c>ZipFile.Save()</c> call. Only
|
---|
900 | /// one input stream is opened at a time, as each entry is being written out.
|
---|
901 | /// </para>
|
---|
902 | ///
|
---|
903 | /// <para>
|
---|
904 | /// Now imagine a different application that creates a <c>ZipFile</c>
|
---|
905 | /// with content obtained from hundreds of streams, added through <see
|
---|
906 | /// cref="ZipFile.AddEntry(string, System.IO.Stream)"/>. Normally the
|
---|
907 | /// application would supply an open stream to that call. But when large
|
---|
908 | /// numbers of streams are being added, this can mean many open streams at one
|
---|
909 | /// time, unnecessarily.
|
---|
910 | /// </para>
|
---|
911 | ///
|
---|
912 | /// <para>
|
---|
913 | /// To avoid this, call <see cref="ZipFile.AddEntry(String, OpenDelegate,
|
---|
914 | /// CloseDelegate)"/> and specify delegates that open and close the stream at
|
---|
915 | /// the time of Save.
|
---|
916 | /// </para>
|
---|
917 | ///
|
---|
918 | ///
|
---|
919 | /// <para>
|
---|
920 | /// Setting the value of this property when the entry was not added from a
|
---|
921 | /// stream (for example, when the <c>ZipEntry</c> was added with <see
|
---|
922 | /// cref="ZipFile.AddFile(String)"/> or <see
|
---|
923 | /// cref="ZipFile.AddDirectory(String)"/>, or when the entry was added by
|
---|
924 | /// reading an existing zip archive) will throw an exception.
|
---|
925 | /// </para>
|
---|
926 | ///
|
---|
927 | /// </remarks>
|
---|
928 | ///
|
---|
929 | public Stream InputStream
|
---|
930 | {
|
---|
931 | get { return _sourceStream; }
|
---|
932 |
|
---|
933 | set
|
---|
934 | {
|
---|
935 | if (this._Source != ZipEntrySource.Stream)
|
---|
936 | throw new ZipException("You must not set the input stream for this entry.");
|
---|
937 |
|
---|
938 | _sourceWasJitProvided = true;
|
---|
939 | _sourceStream = value;
|
---|
940 | }
|
---|
941 | }
|
---|
942 |
|
---|
943 |
|
---|
944 | /// <summary>
|
---|
945 | /// A flag indicating whether the InputStream was provided Just-in-time.
|
---|
946 | /// </summary>
|
---|
947 | ///
|
---|
948 | /// <remarks>
|
---|
949 | ///
|
---|
950 | /// <para>
|
---|
951 | /// When creating a zip archive, an application can obtain content for one or
|
---|
952 | /// more of the <c>ZipEntry</c> instances from streams, using the <see
|
---|
953 | /// cref="ZipFile.AddEntry(string, System.IO.Stream)"/> method. At the time
|
---|
954 | /// of calling that method, the application can supply null as the value of
|
---|
955 | /// the stream parameter. By doing so, the application indicates to the
|
---|
956 | /// library that it will provide a stream for the entry on a just-in-time
|
---|
957 | /// basis, at the time one of the <c>ZipFile.Save()</c> methods is called and
|
---|
958 | /// the data for the various entries are being compressed and written out.
|
---|
959 | /// </para>
|
---|
960 | ///
|
---|
961 | /// <para>
|
---|
962 | /// In this case, the application can set the <see cref="InputStream"/>
|
---|
963 | /// property, typically within the SaveProgress event (event type: <see
|
---|
964 | /// cref="ZipProgressEventType.Saving_BeforeWriteEntry"/>) for that entry.
|
---|
965 | /// </para>
|
---|
966 | ///
|
---|
967 | /// <para>
|
---|
968 | /// The application will later want to call Close() and Dispose() on that
|
---|
969 | /// stream. In the SaveProgress event, when the event type is <see
|
---|
970 | /// cref="ZipProgressEventType.Saving_AfterWriteEntry"/>, the application can
|
---|
971 | /// do so. This flag indicates that the stream has been provided by the
|
---|
972 | /// application on a just-in-time basis and that it is the application's
|
---|
973 | /// responsibility to call Close/Dispose on that stream.
|
---|
974 | /// </para>
|
---|
975 | ///
|
---|
976 | /// </remarks>
|
---|
977 | /// <seealso cref="InputStream"/>
|
---|
978 | public bool InputStreamWasJitProvided
|
---|
979 | {
|
---|
980 | get { return _sourceWasJitProvided; }
|
---|
981 | }
|
---|
982 |
|
---|
983 |
|
---|
984 |
|
---|
985 | /// <summary>
|
---|
986 | /// An enum indicating the source of the ZipEntry.
|
---|
987 | /// </summary>
|
---|
988 | internal ZipEntrySource Source
|
---|
989 | {
|
---|
990 | get { return _Source; }
|
---|
991 | }
|
---|
992 |
|
---|
993 |
|
---|
994 | /// <summary>
|
---|
995 | /// The version of the zip engine needed to read the ZipEntry.
|
---|
996 | /// </summary>
|
---|
997 | ///
|
---|
998 | /// <remarks>
|
---|
999 | /// <para>
|
---|
1000 | /// This is a readonly property, indicating the version of <a
|
---|
1001 | /// href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">the Zip
|
---|
1002 | /// specification</a> that the extracting tool or library must support to
|
---|
1003 | /// extract the given entry. Generally higher versions indicate newer
|
---|
1004 | /// features. Older zip engines obviously won't know about new features, and
|
---|
1005 | /// won't be able to extract entries that depend on those newer features.
|
---|
1006 | /// </para>
|
---|
1007 | ///
|
---|
1008 | /// <list type="table">
|
---|
1009 | /// <listheader>
|
---|
1010 | /// <term>value</term>
|
---|
1011 | /// <description>Features</description>
|
---|
1012 | /// </listheader>
|
---|
1013 | ///
|
---|
1014 | /// <item>
|
---|
1015 | /// <term>20</term>
|
---|
1016 | /// <description>a basic Zip Entry, potentially using PKZIP encryption.
|
---|
1017 | /// </description>
|
---|
1018 | /// </item>
|
---|
1019 | ///
|
---|
1020 | /// <item>
|
---|
1021 | /// <term>45</term>
|
---|
1022 | /// <description>The ZIP64 extension is used on the entry.
|
---|
1023 | /// </description>
|
---|
1024 | /// </item>
|
---|
1025 | ///
|
---|
1026 | /// <item>
|
---|
1027 | /// <term>46</term>
|
---|
1028 | /// <description> File is compressed using BZIP2 compression*</description>
|
---|
1029 | /// </item>
|
---|
1030 | ///
|
---|
1031 | /// <item>
|
---|
1032 | /// <term>50</term>
|
---|
1033 | /// <description> File is encrypted using PkWare's DES, 3DES, (broken) RC2 or RC4</description>
|
---|
1034 | /// </item>
|
---|
1035 | ///
|
---|
1036 | /// <item>
|
---|
1037 | /// <term>51</term>
|
---|
1038 | /// <description> File is encrypted using PKWare's AES encryption or corrected RC2 encryption.</description>
|
---|
1039 | /// </item>
|
---|
1040 | ///
|
---|
1041 | /// <item>
|
---|
1042 | /// <term>52</term>
|
---|
1043 | /// <description> File is encrypted using corrected RC2-64 encryption**</description>
|
---|
1044 | /// </item>
|
---|
1045 | ///
|
---|
1046 | /// <item>
|
---|
1047 | /// <term>61</term>
|
---|
1048 | /// <description> File is encrypted using non-OAEP key wrapping***</description>
|
---|
1049 | /// </item>
|
---|
1050 | ///
|
---|
1051 | /// <item>
|
---|
1052 | /// <term>63</term>
|
---|
1053 | /// <description> File is compressed using LZMA, PPMd+, Blowfish, or Twofish</description>
|
---|
1054 | /// </item>
|
---|
1055 | ///
|
---|
1056 | /// </list>
|
---|
1057 | ///
|
---|
1058 | /// <para>
|
---|
1059 | /// There are other values possible, not listed here. DotNetZip supports
|
---|
1060 | /// regular PKZip encryption, and ZIP64 extensions. DotNetZip cannot extract
|
---|
1061 | /// entries that require a zip engine higher than 45.
|
---|
1062 | /// </para>
|
---|
1063 | ///
|
---|
1064 | /// <para>
|
---|
1065 | /// This value is set upon reading an existing zip file, or after saving a zip
|
---|
1066 | /// archive.
|
---|
1067 | /// </para>
|
---|
1068 | /// </remarks>
|
---|
1069 | public Int16 VersionNeeded
|
---|
1070 | {
|
---|
1071 | get { return _VersionNeeded; }
|
---|
1072 | }
|
---|
1073 |
|
---|
1074 | /// <summary>
|
---|
1075 | /// The comment attached to the ZipEntry.
|
---|
1076 | /// </summary>
|
---|
1077 | ///
|
---|
1078 | /// <remarks>
|
---|
1079 | /// <para>
|
---|
1080 | /// Each entry in a zip file can optionally have a comment associated to
|
---|
1081 | /// it. The comment might be displayed by a zip tool during extraction, for
|
---|
1082 | /// example.
|
---|
1083 | /// </para>
|
---|
1084 | ///
|
---|
1085 | /// <para>
|
---|
1086 | /// By default, the <c>Comment</c> is encoded in IBM437 code page. You can
|
---|
1087 | /// specify an alternative with <see cref="AlternateEncoding"/> and
|
---|
1088 | /// <see cref="AlternateEncodingUsage"/>.
|
---|
1089 | /// </para>
|
---|
1090 | /// </remarks>
|
---|
1091 | /// <seealso cref="AlternateEncoding"/>
|
---|
1092 | /// <seealso cref="AlternateEncodingUsage"/>
|
---|
1093 | public string Comment
|
---|
1094 | {
|
---|
1095 | get { return _Comment; }
|
---|
1096 | set
|
---|
1097 | {
|
---|
1098 | _Comment = value;
|
---|
1099 | _metadataChanged = true;
|
---|
1100 | }
|
---|
1101 | }
|
---|
1102 |
|
---|
1103 |
|
---|
1104 | /// <summary>
|
---|
1105 | /// Indicates whether the entry requires ZIP64 extensions.
|
---|
1106 | /// </summary>
|
---|
1107 | ///
|
---|
1108 | /// <remarks>
|
---|
1109 | ///
|
---|
1110 | /// <para>
|
---|
1111 | /// This property is null (Nothing in VB) until a <c>Save()</c> method on the
|
---|
1112 | /// containing <see cref="ZipFile"/> instance has been called. The property is
|
---|
1113 | /// non-null (<c>HasValue</c> is true) only after a <c>Save()</c> method has
|
---|
1114 | /// been called.
|
---|
1115 | /// </para>
|
---|
1116 | ///
|
---|
1117 | /// <para>
|
---|
1118 | /// After the containing <c>ZipFile</c> has been saved, the Value of this
|
---|
1119 | /// property is true if any of the following three conditions holds: the
|
---|
1120 | /// uncompressed size of the entry is larger than 0xFFFFFFFF; the compressed
|
---|
1121 | /// size of the entry is larger than 0xFFFFFFFF; the relative offset of the
|
---|
1122 | /// entry within the zip archive is larger than 0xFFFFFFFF. These quantities
|
---|
1123 | /// are not known until a <c>Save()</c> is attempted on the zip archive and
|
---|
1124 | /// the compression is applied.
|
---|
1125 | /// </para>
|
---|
1126 | ///
|
---|
1127 | /// <para>
|
---|
1128 | /// If none of the three conditions holds, then the <c>Value</c> is false.
|
---|
1129 | /// </para>
|
---|
1130 | ///
|
---|
1131 | /// <para>
|
---|
1132 | /// A <c>Value</c> of false does not indicate that the entry, as saved in the
|
---|
1133 | /// zip archive, does not use ZIP64. It merely indicates that ZIP64 is
|
---|
1134 | /// <em>not required</em>. An entry may use ZIP64 even when not required if
|
---|
1135 | /// the <see cref="ZipFile.UseZip64WhenSaving"/> property on the containing
|
---|
1136 | /// <c>ZipFile</c> instance is set to <see cref="Zip64Option.Always"/>, or if
|
---|
1137 | /// the <see cref="ZipFile.UseZip64WhenSaving"/> property on the containing
|
---|
1138 | /// <c>ZipFile</c> instance is set to <see cref="Zip64Option.AsNecessary"/>
|
---|
1139 | /// and the output stream was not seekable.
|
---|
1140 | /// </para>
|
---|
1141 | ///
|
---|
1142 | /// </remarks>
|
---|
1143 | /// <seealso cref="OutputUsedZip64"/>
|
---|
1144 | public Nullable<bool> RequiresZip64
|
---|
1145 | {
|
---|
1146 | get
|
---|
1147 | {
|
---|
1148 | return _entryRequiresZip64;
|
---|
1149 | }
|
---|
1150 | }
|
---|
1151 |
|
---|
1152 | /// <summary>
|
---|
1153 | /// Indicates whether the entry actually used ZIP64 extensions, as it was most
|
---|
1154 | /// recently written to the output file or stream.
|
---|
1155 | /// </summary>
|
---|
1156 | ///
|
---|
1157 | /// <remarks>
|
---|
1158 | ///
|
---|
1159 | /// <para>
|
---|
1160 | /// This Nullable property is null (Nothing in VB) until a <c>Save()</c>
|
---|
1161 | /// method on the containing <see cref="ZipFile"/> instance has been
|
---|
1162 | /// called. <c>HasValue</c> is true only after a <c>Save()</c> method has been
|
---|
1163 | /// called.
|
---|
1164 | /// </para>
|
---|
1165 | ///
|
---|
1166 | /// <para>
|
---|
1167 | /// The value of this property for a particular <c>ZipEntry</c> may change
|
---|
1168 | /// over successive calls to <c>Save()</c> methods on the containing ZipFile,
|
---|
1169 | /// even if the file that corresponds to the <c>ZipEntry</c> does not. This
|
---|
1170 | /// may happen if other entries contained in the <c>ZipFile</c> expand,
|
---|
1171 | /// causing the offset for this particular entry to exceed 0xFFFFFFFF.
|
---|
1172 | /// </para>
|
---|
1173 | /// </remarks>
|
---|
1174 | /// <seealso cref="RequiresZip64"/>
|
---|
1175 | public Nullable<bool> OutputUsedZip64
|
---|
1176 | {
|
---|
1177 | get { return _OutputUsesZip64; }
|
---|
1178 | }
|
---|
1179 |
|
---|
1180 |
|
---|
1181 | /// <summary>
|
---|
1182 | /// The bitfield for the entry as defined in the zip spec. You probably
|
---|
1183 | /// never need to look at this.
|
---|
1184 | /// </summary>
|
---|
1185 | ///
|
---|
1186 | /// <remarks>
|
---|
1187 | /// <para>
|
---|
1188 | /// You probably do not need to concern yourself with the contents of this
|
---|
1189 | /// property, but in case you do:
|
---|
1190 | /// </para>
|
---|
1191 | ///
|
---|
1192 | /// <list type="table">
|
---|
1193 | /// <listheader>
|
---|
1194 | /// <term>bit</term>
|
---|
1195 | /// <description>meaning</description>
|
---|
1196 | /// </listheader>
|
---|
1197 | ///
|
---|
1198 | /// <item>
|
---|
1199 | /// <term>0</term>
|
---|
1200 | /// <description>set if encryption is used.</description>
|
---|
1201 | /// </item>
|
---|
1202 | ///
|
---|
1203 | /// <item>
|
---|
1204 | /// <term>1-2</term>
|
---|
1205 | /// <description>
|
---|
1206 | /// set to determine whether normal, max, fast deflation. DotNetZip library
|
---|
1207 | /// always leaves these bits unset when writing (indicating "normal"
|
---|
1208 | /// deflation"), but can read an entry with any value here.
|
---|
1209 | /// </description>
|
---|
1210 | /// </item>
|
---|
1211 | ///
|
---|
1212 | /// <item>
|
---|
1213 | /// <term>3</term>
|
---|
1214 | /// <description>
|
---|
1215 | /// Indicates that the Crc32, Compressed and Uncompressed sizes are zero in the
|
---|
1216 | /// local header. This bit gets set on an entry during writing a zip file, when
|
---|
1217 | /// it is saved to a non-seekable output stream.
|
---|
1218 | /// </description>
|
---|
1219 | /// </item>
|
---|
1220 | ///
|
---|
1221 | ///
|
---|
1222 | /// <item>
|
---|
1223 | /// <term>4</term>
|
---|
1224 | /// <description>reserved for "enhanced deflating". This library doesn't do enhanced deflating.</description>
|
---|
1225 | /// </item>
|
---|
1226 | ///
|
---|
1227 | /// <item>
|
---|
1228 | /// <term>5</term>
|
---|
1229 | /// <description>set to indicate the zip is compressed patched data. This library doesn't do that.</description>
|
---|
1230 | /// </item>
|
---|
1231 | ///
|
---|
1232 | /// <item>
|
---|
1233 | /// <term>6</term>
|
---|
1234 | /// <description>
|
---|
1235 | /// set if PKWare's strong encryption is used (must also set bit 1 if bit 6 is
|
---|
1236 | /// set). This bit is not set if WinZip's AES encryption is set.</description>
|
---|
1237 | /// </item>
|
---|
1238 | ///
|
---|
1239 | /// <item>
|
---|
1240 | /// <term>7</term>
|
---|
1241 | /// <description>not used</description>
|
---|
1242 | /// </item>
|
---|
1243 | ///
|
---|
1244 | /// <item>
|
---|
1245 | /// <term>8</term>
|
---|
1246 | /// <description>not used</description>
|
---|
1247 | /// </item>
|
---|
1248 | ///
|
---|
1249 | /// <item>
|
---|
1250 | /// <term>9</term>
|
---|
1251 | /// <description>not used</description>
|
---|
1252 | /// </item>
|
---|
1253 | ///
|
---|
1254 | /// <item>
|
---|
1255 | /// <term>10</term>
|
---|
1256 | /// <description>not used</description>
|
---|
1257 | /// </item>
|
---|
1258 | ///
|
---|
1259 | /// <item>
|
---|
1260 | /// <term>11</term>
|
---|
1261 | /// <description>
|
---|
1262 | /// Language encoding flag (EFS). If this bit is set, the filename and comment
|
---|
1263 | /// fields for this file must be encoded using UTF-8. This library currently
|
---|
1264 | /// does not support UTF-8.
|
---|
1265 | /// </description>
|
---|
1266 | /// </item>
|
---|
1267 | ///
|
---|
1268 | /// <item>
|
---|
1269 | /// <term>12</term>
|
---|
1270 | /// <description>Reserved by PKWARE for enhanced compression.</description>
|
---|
1271 | /// </item>
|
---|
1272 | ///
|
---|
1273 | /// <item>
|
---|
1274 | /// <term>13</term>
|
---|
1275 | /// <description>
|
---|
1276 | /// Used when encrypting the Central Directory to indicate selected data
|
---|
1277 | /// values in the Local Header are masked to hide their actual values. See
|
---|
1278 | /// the section in <a
|
---|
1279 | /// href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">the Zip
|
---|
1280 | /// specification</a> describing the Strong Encryption Specification for
|
---|
1281 | /// details.
|
---|
1282 | /// </description>
|
---|
1283 | /// </item>
|
---|
1284 | ///
|
---|
1285 | /// <item>
|
---|
1286 | /// <term>14</term>
|
---|
1287 | /// <description>Reserved by PKWARE.</description>
|
---|
1288 | /// </item>
|
---|
1289 | ///
|
---|
1290 | /// <item>
|
---|
1291 | /// <term>15</term>
|
---|
1292 | /// <description>Reserved by PKWARE.</description>
|
---|
1293 | /// </item>
|
---|
1294 | ///
|
---|
1295 | /// </list>
|
---|
1296 | ///
|
---|
1297 | /// </remarks>
|
---|
1298 | public Int16 BitField
|
---|
1299 | {
|
---|
1300 | get { return _BitField; }
|
---|
1301 | }
|
---|
1302 |
|
---|
1303 | /// <summary>
|
---|
1304 | /// The compression method employed for this ZipEntry.
|
---|
1305 | /// </summary>
|
---|
1306 | ///
|
---|
1307 | /// <remarks>
|
---|
1308 | ///
|
---|
1309 | /// <para>
|
---|
1310 | /// <see href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">The
|
---|
1311 | /// Zip specification</see> allows a variety of compression methods. This
|
---|
1312 | /// library supports just two: 0x08 = Deflate. 0x00 = Store (no compression),
|
---|
1313 | /// for reading or writing.
|
---|
1314 | /// </para>
|
---|
1315 | ///
|
---|
1316 | /// <para>
|
---|
1317 | /// When reading an entry from an existing zipfile, the value you retrieve
|
---|
1318 | /// here indicates the compression method used on the entry by the original
|
---|
1319 | /// creator of the zip. When writing a zipfile, you can specify either 0x08
|
---|
1320 | /// (Deflate) or 0x00 (None). If you try setting something else, you will get
|
---|
1321 | /// an exception.
|
---|
1322 | /// </para>
|
---|
1323 | ///
|
---|
1324 | /// <para>
|
---|
1325 | /// You may wish to set <c>CompressionMethod</c> to <c>CompressionMethod.None</c> (0)
|
---|
1326 | /// when zipping already-compressed data like a jpg, png, or mp3 file.
|
---|
1327 | /// This can save time and cpu cycles.
|
---|
1328 | /// </para>
|
---|
1329 | ///
|
---|
1330 | /// <para>
|
---|
1331 | /// When setting this property on a <c>ZipEntry</c> that is read from an
|
---|
1332 | /// existing zip file, calling <c>ZipFile.Save()</c> will cause the new
|
---|
1333 | /// CompressionMethod to be used on the entry in the newly saved zip file.
|
---|
1334 | /// </para>
|
---|
1335 | ///
|
---|
1336 | /// <para>
|
---|
1337 | /// Setting this property may have the side effect of modifying the
|
---|
1338 | /// <c>CompressionLevel</c> property. If you set the <c>CompressionMethod</c> to a
|
---|
1339 | /// value other than <c>None</c>, and <c>CompressionLevel</c> is previously
|
---|
1340 | /// set to <c>None</c>, then <c>CompressionLevel</c> will be set to
|
---|
1341 | /// <c>Default</c>.
|
---|
1342 | /// </para>
|
---|
1343 | /// </remarks>
|
---|
1344 | ///
|
---|
1345 | /// <seealso cref="CompressionMethod"/>
|
---|
1346 | ///
|
---|
1347 | /// <example>
|
---|
1348 | /// In this example, the first entry added to the zip archive uses the default
|
---|
1349 | /// behavior - compression is used where it makes sense. The second entry,
|
---|
1350 | /// the MP3 file, is added to the archive without being compressed.
|
---|
1351 | /// <code>
|
---|
1352 | /// using (ZipFile zip = new ZipFile(ZipFileToCreate))
|
---|
1353 | /// {
|
---|
1354 | /// ZipEntry e1= zip.AddFile(@"notes\Readme.txt");
|
---|
1355 | /// ZipEntry e2= zip.AddFile(@"music\StopThisTrain.mp3");
|
---|
1356 | /// e2.CompressionMethod = CompressionMethod.None;
|
---|
1357 | /// zip.Save();
|
---|
1358 | /// }
|
---|
1359 | /// </code>
|
---|
1360 | ///
|
---|
1361 | /// <code lang="VB">
|
---|
1362 | /// Using zip As New ZipFile(ZipFileToCreate)
|
---|
1363 | /// zip.AddFile("notes\Readme.txt")
|
---|
1364 | /// Dim e2 as ZipEntry = zip.AddFile("music\StopThisTrain.mp3")
|
---|
1365 | /// e2.CompressionMethod = CompressionMethod.None
|
---|
1366 | /// zip.Save
|
---|
1367 | /// End Using
|
---|
1368 | /// </code>
|
---|
1369 | /// </example>
|
---|
1370 | internal CompressionMethod CompressionMethod
|
---|
1371 | {
|
---|
1372 | get { return (CompressionMethod)_CompressionMethod; }
|
---|
1373 | set
|
---|
1374 | {
|
---|
1375 | if (value == (CompressionMethod)_CompressionMethod) return; // nothing to do.
|
---|
1376 |
|
---|
1377 | if (value != CompressionMethod.None && value != CompressionMethod.Deflate
|
---|
1378 | #if BZIP
|
---|
1379 | && value != CompressionMethod.BZip2
|
---|
1380 | #endif
|
---|
1381 | )
|
---|
1382 | throw new InvalidOperationException("Unsupported compression method.");
|
---|
1383 |
|
---|
1384 | // If the source is a zip archive and there was encryption on the
|
---|
1385 | // entry, changing the compression method is not supported.
|
---|
1386 | // if (this._Source == ZipEntrySource.ZipFile && _sourceIsEncrypted)
|
---|
1387 | // throw new InvalidOperationException("Cannot change compression method on encrypted entries read from archives.");
|
---|
1388 |
|
---|
1389 | _CompressionMethod = (Int16)value;
|
---|
1390 |
|
---|
1391 | if (_CompressionMethod == (Int16)Ionic.Zip.CompressionMethod.None)
|
---|
1392 | _CompressionLevel = Ionic.Zlib.CompressionLevel.None;
|
---|
1393 | else if (CompressionLevel == Ionic.Zlib.CompressionLevel.None)
|
---|
1394 | _CompressionLevel = Ionic.Zlib.CompressionLevel.Default;
|
---|
1395 |
|
---|
1396 | if (_container.ZipFile != null) _container.ZipFile.NotifyEntryChanged();
|
---|
1397 | _restreamRequiredOnSave = true;
|
---|
1398 | }
|
---|
1399 | }
|
---|
1400 |
|
---|
1401 |
|
---|
1402 | /// <summary>
|
---|
1403 | /// Sets the compression level to be used for the entry when saving the zip
|
---|
1404 | /// archive. This applies only for CompressionMethod = DEFLATE.
|
---|
1405 | /// </summary>
|
---|
1406 | ///
|
---|
1407 | /// <remarks>
|
---|
1408 | /// <para>
|
---|
1409 | /// When using the DEFLATE compression method, Varying the compression
|
---|
1410 | /// level used on entries can affect the size-vs-speed tradeoff when
|
---|
1411 | /// compression and decompressing data streams or files.
|
---|
1412 | /// </para>
|
---|
1413 | ///
|
---|
1414 | /// <para>
|
---|
1415 | /// If you do not set this property, the default compression level is used,
|
---|
1416 | /// which normally gives a good balance of compression efficiency and
|
---|
1417 | /// compression speed. In some tests, using <c>BestCompression</c> can
|
---|
1418 | /// double the time it takes to compress, while delivering just a small
|
---|
1419 | /// increase in compression efficiency. This behavior will vary with the
|
---|
1420 | /// type of data you compress. If you are in doubt, just leave this setting
|
---|
1421 | /// alone, and accept the default.
|
---|
1422 | /// </para>
|
---|
1423 | ///
|
---|
1424 | /// <para>
|
---|
1425 | /// When setting this property on a <c>ZipEntry</c> that is read from an
|
---|
1426 | /// existing zip file, calling <c>ZipFile.Save()</c> will cause the new
|
---|
1427 | /// <c>CompressionLevel</c> to be used on the entry in the newly saved zip file.
|
---|
1428 | /// </para>
|
---|
1429 | ///
|
---|
1430 | /// <para>
|
---|
1431 | /// Setting this property may have the side effect of modifying the
|
---|
1432 | /// <c>CompressionMethod</c> property. If you set the <c>CompressionLevel</c>
|
---|
1433 | /// to a value other than <c>None</c>, <c>CompressionMethod</c> will be set
|
---|
1434 | /// to <c>Deflate</c>, if it was previously <c>None</c>.
|
---|
1435 | /// </para>
|
---|
1436 | ///
|
---|
1437 | /// <para>
|
---|
1438 | /// Setting this property has no effect if the <c>CompressionMethod</c> is something
|
---|
1439 | /// other than <c>Deflate</c> or <c>None</c>.
|
---|
1440 | /// </para>
|
---|
1441 | /// </remarks>
|
---|
1442 | ///
|
---|
1443 | /// <seealso cref="CompressionMethod"/>
|
---|
1444 | public OfficeOpenXml.Packaging.Ionic.Zlib.CompressionLevel CompressionLevel
|
---|
1445 | {
|
---|
1446 | get
|
---|
1447 | {
|
---|
1448 | return _CompressionLevel;
|
---|
1449 | }
|
---|
1450 | set
|
---|
1451 | {
|
---|
1452 | if (_CompressionMethod != (short)CompressionMethod.Deflate &&
|
---|
1453 | _CompressionMethod != (short)CompressionMethod.None)
|
---|
1454 | return ; // no effect
|
---|
1455 |
|
---|
1456 | if (value == OfficeOpenXml.Packaging.Ionic.Zlib.CompressionLevel.Default &&
|
---|
1457 | _CompressionMethod == (short)CompressionMethod.Deflate) return; // nothing to do
|
---|
1458 | _CompressionLevel = value;
|
---|
1459 |
|
---|
1460 | if (value == OfficeOpenXml.Packaging.Ionic.Zlib.CompressionLevel.None &&
|
---|
1461 | _CompressionMethod == (short)CompressionMethod.None)
|
---|
1462 | return; // nothing more to do
|
---|
1463 |
|
---|
1464 | if (_CompressionLevel == OfficeOpenXml.Packaging.Ionic.Zlib.CompressionLevel.None)
|
---|
1465 | _CompressionMethod = (short)OfficeOpenXml.Packaging.Ionic.Zip.CompressionMethod.None;
|
---|
1466 | else
|
---|
1467 | _CompressionMethod = (short)OfficeOpenXml.Packaging.Ionic.Zip.CompressionMethod.Deflate;
|
---|
1468 |
|
---|
1469 | if (_container.ZipFile != null) _container.ZipFile.NotifyEntryChanged();
|
---|
1470 | _restreamRequiredOnSave = true;
|
---|
1471 | }
|
---|
1472 | }
|
---|
1473 |
|
---|
1474 |
|
---|
1475 |
|
---|
1476 | /// <summary>
|
---|
1477 | /// The compressed size of the file, in bytes, within the zip archive.
|
---|
1478 | /// </summary>
|
---|
1479 | ///
|
---|
1480 | /// <remarks>
|
---|
1481 | /// When reading a <c>ZipFile</c>, this value is read in from the existing
|
---|
1482 | /// zip file. When creating or updating a <c>ZipFile</c>, the compressed
|
---|
1483 | /// size is computed during compression. Therefore the value on a
|
---|
1484 | /// <c>ZipEntry</c> is valid after a call to <c>Save()</c> (or one of its
|
---|
1485 | /// overloads) in that case.
|
---|
1486 | /// </remarks>
|
---|
1487 | ///
|
---|
1488 | /// <seealso cref="ZipEntry.UncompressedSize"/>
|
---|
1489 | public Int64 CompressedSize
|
---|
1490 | {
|
---|
1491 | get { return _CompressedSize; }
|
---|
1492 | }
|
---|
1493 |
|
---|
1494 | /// <summary>
|
---|
1495 | /// The size of the file, in bytes, before compression, or after extraction.
|
---|
1496 | /// </summary>
|
---|
1497 | ///
|
---|
1498 | /// <remarks>
|
---|
1499 | /// When reading a <c>ZipFile</c>, this value is read in from the existing
|
---|
1500 | /// zip file. When creating or updating a <c>ZipFile</c>, the uncompressed
|
---|
1501 | /// size is computed during compression. Therefore the value on a
|
---|
1502 | /// <c>ZipEntry</c> is valid after a call to <c>Save()</c> (or one of its
|
---|
1503 | /// overloads) in that case.
|
---|
1504 | /// </remarks>
|
---|
1505 | ///
|
---|
1506 | /// <seealso cref="Ionic.Zip.ZipEntry.CompressedSize"/>
|
---|
1507 | public Int64 UncompressedSize
|
---|
1508 | {
|
---|
1509 | get { return _UncompressedSize; }
|
---|
1510 | }
|
---|
1511 |
|
---|
1512 | /// <summary>
|
---|
1513 | /// The ratio of compressed size to uncompressed size of the ZipEntry.
|
---|
1514 | /// </summary>
|
---|
1515 | ///
|
---|
1516 | /// <remarks>
|
---|
1517 | /// <para>
|
---|
1518 | /// This is a ratio of the compressed size to the uncompressed size of the
|
---|
1519 | /// entry, expressed as a double in the range of 0 to 100+. A value of 100
|
---|
1520 | /// indicates no compression at all. It could be higher than 100 when the
|
---|
1521 | /// compression algorithm actually inflates the data, as may occur for small
|
---|
1522 | /// files, or uncompressible data that is encrypted.
|
---|
1523 | /// </para>
|
---|
1524 | ///
|
---|
1525 | /// <para>
|
---|
1526 | /// You could format it for presentation to a user via a format string of
|
---|
1527 | /// "{3,5:F0}%" to see it as a percentage.
|
---|
1528 | /// </para>
|
---|
1529 | ///
|
---|
1530 | /// <para>
|
---|
1531 | /// If the size of the original uncompressed file is 0, implying a
|
---|
1532 | /// denominator of 0, the return value will be zero.
|
---|
1533 | /// </para>
|
---|
1534 | ///
|
---|
1535 | /// <para>
|
---|
1536 | /// This property is valid after reading in an existing zip file, or after
|
---|
1537 | /// saving the <c>ZipFile</c> that contains the ZipEntry. You cannot know the
|
---|
1538 | /// effect of a compression transform until you try it.
|
---|
1539 | /// </para>
|
---|
1540 | ///
|
---|
1541 | /// </remarks>
|
---|
1542 | public Double CompressionRatio
|
---|
1543 | {
|
---|
1544 | get
|
---|
1545 | {
|
---|
1546 | if (UncompressedSize == 0) return 0;
|
---|
1547 | return 100 * (1.0 - (1.0 * CompressedSize) / (1.0 * UncompressedSize));
|
---|
1548 | }
|
---|
1549 | }
|
---|
1550 |
|
---|
1551 | /// <summary>
|
---|
1552 | /// The 32-bit CRC (Cyclic Redundancy Check) on the contents of the ZipEntry.
|
---|
1553 | /// </summary>
|
---|
1554 | ///
|
---|
1555 | /// <remarks>
|
---|
1556 | ///
|
---|
1557 | /// <para> You probably don't need to concern yourself with this. It is used
|
---|
1558 | /// internally by DotNetZip to verify files or streams upon extraction. </para>
|
---|
1559 | ///
|
---|
1560 | /// <para> The value is a <see href="http://en.wikipedia.org/wiki/CRC32">32-bit
|
---|
1561 | /// CRC</see> using 0xEDB88320 for the polynomial. This is the same CRC-32 used in
|
---|
1562 | /// PNG, MPEG-2, and other protocols and formats. It is a read-only property; when
|
---|
1563 | /// creating a Zip archive, the CRC for each entry is set only after a call to
|
---|
1564 | /// <c>Save()</c> on the containing ZipFile. When reading an existing zip file, the value
|
---|
1565 | /// of this property reflects the stored CRC for the entry. </para>
|
---|
1566 | ///
|
---|
1567 | /// </remarks>
|
---|
1568 | public Int32 Crc
|
---|
1569 | {
|
---|
1570 | get { return _Crc32; }
|
---|
1571 | }
|
---|
1572 |
|
---|
1573 | /// <summary>
|
---|
1574 | /// True if the entry is a directory (not a file).
|
---|
1575 | /// This is a readonly property on the entry.
|
---|
1576 | /// </summary>
|
---|
1577 | public bool IsDirectory
|
---|
1578 | {
|
---|
1579 | get { return _IsDirectory; }
|
---|
1580 | }
|
---|
1581 |
|
---|
1582 | /// <summary>
|
---|
1583 | /// A derived property that is <c>true</c> if the entry uses encryption.
|
---|
1584 | /// </summary>
|
---|
1585 | ///
|
---|
1586 | /// <remarks>
|
---|
1587 | /// <para>
|
---|
1588 | /// This is a readonly property on the entry. When reading a zip file,
|
---|
1589 | /// the value for the <c>ZipEntry</c> is determined by the data read
|
---|
1590 | /// from the zip file. After saving a ZipFile, the value of this
|
---|
1591 | /// property for each <c>ZipEntry</c> indicates whether encryption was
|
---|
1592 | /// actually used (which will have been true if the <see
|
---|
1593 | /// cref="Password"/> was set and the <see cref="Encryption"/> property
|
---|
1594 | /// was something other than <see cref="EncryptionAlgorithm.None"/>.
|
---|
1595 | /// </para>
|
---|
1596 | /// </remarks>
|
---|
1597 | public bool UsesEncryption
|
---|
1598 | {
|
---|
1599 | get { return (_Encryption_FromZipFile != EncryptionAlgorithm.None); }
|
---|
1600 | }
|
---|
1601 |
|
---|
1602 |
|
---|
1603 | /// <summary>
|
---|
1604 | /// Set this to specify which encryption algorithm to use for the entry when
|
---|
1605 | /// saving it to a zip archive.
|
---|
1606 | /// </summary>
|
---|
1607 | ///
|
---|
1608 | /// <remarks>
|
---|
1609 | ///
|
---|
1610 | /// <para>
|
---|
1611 | /// Set this property in order to encrypt the entry when the <c>ZipFile</c> is
|
---|
1612 | /// saved. When setting this property, you must also set a <see
|
---|
1613 | /// cref="Password"/> on the entry. If you set a value other than <see
|
---|
1614 | /// cref="EncryptionAlgorithm.None"/> on this property and do not set a
|
---|
1615 | /// <c>Password</c> then the entry will not be encrypted. The <c>ZipEntry</c>
|
---|
1616 | /// data is encrypted as the <c>ZipFile</c> is saved, when you call <see
|
---|
1617 | /// cref="ZipFile.Save()"/> or one of its cousins on the containing
|
---|
1618 | /// <c>ZipFile</c> instance. You do not need to specify the <c>Encryption</c>
|
---|
1619 | /// when extracting entries from an archive.
|
---|
1620 | /// </para>
|
---|
1621 | ///
|
---|
1622 | /// <para>
|
---|
1623 | /// The Zip specification from PKWare defines a set of encryption algorithms,
|
---|
1624 | /// and the data formats for the zip archive that support them, and PKWare
|
---|
1625 | /// supports those algorithms in the tools it produces. Other vendors of tools
|
---|
1626 | /// and libraries, such as WinZip or Xceed, typically support <em>a
|
---|
1627 | /// subset</em> of the algorithms specified by PKWare. These tools can
|
---|
1628 | /// sometimes support additional different encryption algorithms and data
|
---|
1629 | /// formats, not specified by PKWare. The AES Encryption specified and
|
---|
1630 | /// supported by WinZip is the most popular example. This library supports a
|
---|
1631 | /// subset of the complete set of algorithms specified by PKWare and other
|
---|
1632 | /// vendors.
|
---|
1633 | /// </para>
|
---|
1634 | ///
|
---|
1635 | /// <para>
|
---|
1636 | /// There is no common, ubiquitous multi-vendor standard for strong encryption
|
---|
1637 | /// within zip files. There is broad support for so-called "traditional" Zip
|
---|
1638 | /// encryption, sometimes called Zip 2.0 encryption, as <see
|
---|
1639 | /// href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">specified
|
---|
1640 | /// by PKWare</see>, but this encryption is considered weak and
|
---|
1641 | /// breakable. This library currently supports the Zip 2.0 "weak" encryption,
|
---|
1642 | /// and also a stronger WinZip-compatible AES encryption, using either 128-bit
|
---|
1643 | /// or 256-bit key strength. If you want DotNetZip to support an algorithm
|
---|
1644 | /// that is not currently supported, call the author of this library and maybe
|
---|
1645 | /// we can talk business.
|
---|
1646 | /// </para>
|
---|
1647 | ///
|
---|
1648 | /// <para>
|
---|
1649 | /// The <see cref="ZipFile"/> class also has a <see
|
---|
1650 | /// cref="ZipFile.Encryption"/> property. In most cases you will use
|
---|
1651 | /// <em>that</em> property when setting encryption. This property takes
|
---|
1652 | /// precedence over any <c>Encryption</c> set on the <c>ZipFile</c> itself.
|
---|
1653 | /// Typically, you would use the per-entry Encryption when most entries in the
|
---|
1654 | /// zip archive use one encryption algorithm, and a few entries use a
|
---|
1655 | /// different one. If all entries in the zip file use the same Encryption,
|
---|
1656 | /// then it is simpler to just set this property on the ZipFile itself, when
|
---|
1657 | /// creating a zip archive.
|
---|
1658 | /// </para>
|
---|
1659 | ///
|
---|
1660 | /// <para>
|
---|
1661 | /// Some comments on updating archives: If you read a <c>ZipFile</c>, you can
|
---|
1662 | /// modify the Encryption on an encrypted entry: you can remove encryption
|
---|
1663 | /// from an entry that was encrypted; you can encrypt an entry that was not
|
---|
1664 | /// encrypted previously; or, you can change the encryption algorithm. The
|
---|
1665 | /// changes in encryption are not made permanent until you call Save() on the
|
---|
1666 | /// <c>ZipFile</c>. To effect changes in encryption, the entry content is
|
---|
1667 | /// streamed through several transformations, depending on the modification
|
---|
1668 | /// the application has requested. For example if the entry is not encrypted
|
---|
1669 | /// and the application sets <c>Encryption</c> to <c>PkzipWeak</c>, then at
|
---|
1670 | /// the time of <c>Save()</c>, the original entry is read and decompressed,
|
---|
1671 | /// then re-compressed and encrypted. Conversely, if the original entry is
|
---|
1672 | /// encrypted with <c>PkzipWeak</c> encryption, and the application sets the
|
---|
1673 | /// <c>Encryption</c> property to <c>WinZipAes128</c>, then at the time of
|
---|
1674 | /// <c>Save()</c>, the original entry is decrypted via PKZIP encryption and
|
---|
1675 | /// decompressed, then re-compressed and re-encrypted with AES. This all
|
---|
1676 | /// happens automatically within the library, but it can be time-consuming for
|
---|
1677 | /// large entries.
|
---|
1678 | /// </para>
|
---|
1679 | ///
|
---|
1680 | /// <para>
|
---|
1681 | /// Additionally, when updating archives, it is not possible to change the
|
---|
1682 | /// password when changing the encryption algorithm. To change both the
|
---|
1683 | /// algorithm and the password, you need to Save() the zipfile twice. First
|
---|
1684 | /// set the <c>Encryption</c> to None, then call <c>Save()</c>. Then set the
|
---|
1685 | /// <c>Encryption</c> to the new value (not "None"), then call <c>Save()</c>
|
---|
1686 | /// once again.
|
---|
1687 | /// </para>
|
---|
1688 | ///
|
---|
1689 | /// <para>
|
---|
1690 | /// The WinZip AES encryption algorithms are not supported on the .NET Compact
|
---|
1691 | /// Framework.
|
---|
1692 | /// </para>
|
---|
1693 | /// </remarks>
|
---|
1694 | ///
|
---|
1695 | /// <example>
|
---|
1696 | /// <para>
|
---|
1697 | /// This example creates a zip archive that uses encryption, and then extracts
|
---|
1698 | /// entries from the archive. When creating the zip archive, the ReadMe.txt
|
---|
1699 | /// file is zipped without using a password or encryption. The other file
|
---|
1700 | /// uses encryption.
|
---|
1701 | /// </para>
|
---|
1702 | /// <code>
|
---|
1703 | /// // Create a zip archive with AES Encryption.
|
---|
1704 | /// using (ZipFile zip = new ZipFile())
|
---|
1705 | /// {
|
---|
1706 | /// zip.AddFile("ReadMe.txt")
|
---|
1707 | /// ZipEntry e1= zip.AddFile("2008-Regional-Sales-Report.pdf");
|
---|
1708 | /// e1.Encryption= EncryptionAlgorithm.WinZipAes256;
|
---|
1709 | /// e1.Password= "Top.Secret.No.Peeking!";
|
---|
1710 | /// zip.Save("EncryptedArchive.zip");
|
---|
1711 | /// }
|
---|
1712 | ///
|
---|
1713 | /// // Extract a zip archive that uses AES Encryption.
|
---|
1714 | /// // You do not need to specify the algorithm during extraction.
|
---|
1715 | /// using (ZipFile zip = ZipFile.Read("EncryptedArchive.zip"))
|
---|
1716 | /// {
|
---|
1717 | /// // Specify the password that is used during extraction, for
|
---|
1718 | /// // all entries that require a password:
|
---|
1719 | /// zip.Password= "Top.Secret.No.Peeking!";
|
---|
1720 | /// zip.ExtractAll("extractDirectory");
|
---|
1721 | /// }
|
---|
1722 | /// </code>
|
---|
1723 | ///
|
---|
1724 | /// <code lang="VB">
|
---|
1725 | /// ' Create a zip that uses Encryption.
|
---|
1726 | /// Using zip As New ZipFile()
|
---|
1727 | /// zip.AddFile("ReadMe.txt")
|
---|
1728 | /// Dim e1 as ZipEntry
|
---|
1729 | /// e1= zip.AddFile("2008-Regional-Sales-Report.pdf")
|
---|
1730 | /// e1.Encryption= EncryptionAlgorithm.WinZipAes256
|
---|
1731 | /// e1.Password= "Top.Secret.No.Peeking!"
|
---|
1732 | /// zip.Save("EncryptedArchive.zip")
|
---|
1733 | /// End Using
|
---|
1734 | ///
|
---|
1735 | /// ' Extract a zip archive that uses AES Encryption.
|
---|
1736 | /// ' You do not need to specify the algorithm during extraction.
|
---|
1737 | /// Using (zip as ZipFile = ZipFile.Read("EncryptedArchive.zip"))
|
---|
1738 | /// ' Specify the password that is used during extraction, for
|
---|
1739 | /// ' all entries that require a password:
|
---|
1740 | /// zip.Password= "Top.Secret.No.Peeking!"
|
---|
1741 | /// zip.ExtractAll("extractDirectory")
|
---|
1742 | /// End Using
|
---|
1743 | /// </code>
|
---|
1744 | ///
|
---|
1745 | /// </example>
|
---|
1746 | ///
|
---|
1747 | /// <exception cref="System.InvalidOperationException">
|
---|
1748 | /// Thrown in the setter if EncryptionAlgorithm.Unsupported is specified.
|
---|
1749 | /// </exception>
|
---|
1750 | ///
|
---|
1751 | /// <seealso cref="Ionic.Zip.ZipEntry.Password">ZipEntry.Password</seealso>
|
---|
1752 | /// <seealso cref="Ionic.Zip.ZipFile.Encryption">ZipFile.Encryption</seealso>
|
---|
1753 | internal EncryptionAlgorithm Encryption
|
---|
1754 | {
|
---|
1755 | get
|
---|
1756 | {
|
---|
1757 | return _Encryption;
|
---|
1758 | }
|
---|
1759 | set
|
---|
1760 | {
|
---|
1761 | if (value == _Encryption) return; // no change
|
---|
1762 |
|
---|
1763 | if (value == EncryptionAlgorithm.Unsupported)
|
---|
1764 | throw new InvalidOperationException("You may not set Encryption to that value.");
|
---|
1765 |
|
---|
1766 | // If the source is a zip archive and there was encryption
|
---|
1767 | // on the entry, this will not work. <XXX>
|
---|
1768 | //if (this._Source == ZipEntrySource.ZipFile && _sourceIsEncrypted)
|
---|
1769 | // throw new InvalidOperationException("You cannot change the encryption method on encrypted entries read from archives.");
|
---|
1770 |
|
---|
1771 | _Encryption = value;
|
---|
1772 | _restreamRequiredOnSave = true;
|
---|
1773 | if (_container.ZipFile!=null)
|
---|
1774 | _container.ZipFile.NotifyEntryChanged();
|
---|
1775 | }
|
---|
1776 | }
|
---|
1777 |
|
---|
1778 |
|
---|
1779 | /// <summary>
|
---|
1780 | /// The Password to be used when encrypting a <c>ZipEntry</c> upon
|
---|
1781 | /// <c>ZipFile.Save()</c>, or when decrypting an entry upon Extract().
|
---|
1782 | /// </summary>
|
---|
1783 | ///
|
---|
1784 | /// <remarks>
|
---|
1785 | /// <para>
|
---|
1786 | /// This is a write-only property on the entry. Set this to request that the
|
---|
1787 | /// entry be encrypted when writing the zip archive, or set it to specify the
|
---|
1788 | /// password to be used when extracting an existing entry that is encrypted.
|
---|
1789 | /// </para>
|
---|
1790 | ///
|
---|
1791 | /// <para>
|
---|
1792 | /// The password set here is implicitly used to encrypt the entry during the
|
---|
1793 | /// <see cref="ZipFile.Save()"/> operation, or to decrypt during the <see
|
---|
1794 | /// cref="Extract()"/> or <see cref="OpenReader()"/> operation. If you set
|
---|
1795 | /// the Password on a <c>ZipEntry</c> after calling <c>Save()</c>, there is no
|
---|
1796 | /// effect.
|
---|
1797 | /// </para>
|
---|
1798 | ///
|
---|
1799 | /// <para>
|
---|
1800 | /// Consider setting the <see cref="Encryption"/> property when using a
|
---|
1801 | /// password. Answering concerns that the standard password protection
|
---|
1802 | /// supported by all zip tools is weak, WinZip has extended the ZIP
|
---|
1803 | /// specification with a way to use AES Encryption to protect entries in the
|
---|
1804 | /// Zip file. Unlike the "PKZIP 2.0" encryption specified in the PKZIP
|
---|
1805 | /// specification, <see href=
|
---|
1806 | /// "http://en.wikipedia.org/wiki/Advanced_Encryption_Standard">AES
|
---|
1807 | /// Encryption</see> uses a standard, strong, tested, encryption
|
---|
1808 | /// algorithm. DotNetZip can create zip archives that use WinZip-compatible
|
---|
1809 | /// AES encryption, if you set the <see cref="Encryption"/> property. But,
|
---|
1810 | /// archives created that use AES encryption may not be readable by all other
|
---|
1811 | /// tools and libraries. For example, Windows Explorer cannot read a
|
---|
1812 | /// "compressed folder" (a zip file) that uses AES encryption, though it can
|
---|
1813 | /// read a zip file that uses "PKZIP encryption."
|
---|
1814 | /// </para>
|
---|
1815 | ///
|
---|
1816 | /// <para>
|
---|
1817 | /// The <see cref="ZipFile"/> class also has a <see cref="ZipFile.Password"/>
|
---|
1818 | /// property. This property takes precedence over any password set on the
|
---|
1819 | /// ZipFile itself. Typically, you would use the per-entry Password when most
|
---|
1820 | /// entries in the zip archive use one password, and a few entries use a
|
---|
1821 | /// different password. If all entries in the zip file use the same password,
|
---|
1822 | /// then it is simpler to just set this property on the ZipFile itself,
|
---|
1823 | /// whether creating a zip archive or extracting a zip archive.
|
---|
1824 | /// </para>
|
---|
1825 | ///
|
---|
1826 | /// <para>
|
---|
1827 | /// Some comments on updating archives: If you read a <c>ZipFile</c>, you
|
---|
1828 | /// cannot modify the password on any encrypted entry, except by extracting
|
---|
1829 | /// the entry with the original password (if any), removing the original entry
|
---|
1830 | /// via <see cref="ZipFile.RemoveEntry(ZipEntry)"/>, and then adding a new
|
---|
1831 | /// entry with a new Password.
|
---|
1832 | /// </para>
|
---|
1833 | ///
|
---|
1834 | /// <para>
|
---|
1835 | /// For example, suppose you read a <c>ZipFile</c>, and there is an encrypted
|
---|
1836 | /// entry. Setting the Password property on that <c>ZipEntry</c> and then
|
---|
1837 | /// calling <c>Save()</c> on the <c>ZipFile</c> does not update the password
|
---|
1838 | /// on that entry in the archive. Neither is an exception thrown. Instead,
|
---|
1839 | /// what happens during the <c>Save()</c> is the existing entry is copied
|
---|
1840 | /// through to the new zip archive, in its original encrypted form. Upon
|
---|
1841 | /// re-reading that archive, the entry can be decrypted with its original
|
---|
1842 | /// password.
|
---|
1843 | /// </para>
|
---|
1844 | ///
|
---|
1845 | /// <para>
|
---|
1846 | /// If you read a ZipFile, and there is an un-encrypted entry, you can set the
|
---|
1847 | /// <c>Password</c> on the entry and then call Save() on the ZipFile, and get
|
---|
1848 | /// encryption on that entry.
|
---|
1849 | /// </para>
|
---|
1850 | ///
|
---|
1851 | /// </remarks>
|
---|
1852 | ///
|
---|
1853 | /// <example>
|
---|
1854 | /// <para>
|
---|
1855 | /// This example creates a zip file with two entries, and then extracts the
|
---|
1856 | /// entries from the zip file. When creating the zip file, the two files are
|
---|
1857 | /// added to the zip file using password protection. Each entry uses a
|
---|
1858 | /// different password. During extraction, each file is extracted with the
|
---|
1859 | /// appropriate password.
|
---|
1860 | /// </para>
|
---|
1861 | /// <code>
|
---|
1862 | /// // create a file with encryption
|
---|
1863 | /// using (ZipFile zip = new ZipFile())
|
---|
1864 | /// {
|
---|
1865 | /// ZipEntry entry;
|
---|
1866 | /// entry= zip.AddFile("Declaration.txt");
|
---|
1867 | /// entry.Password= "123456!";
|
---|
1868 | /// entry = zip.AddFile("Report.xls");
|
---|
1869 | /// entry.Password= "1Secret!";
|
---|
1870 | /// zip.Save("EncryptedArchive.zip");
|
---|
1871 | /// }
|
---|
1872 | ///
|
---|
1873 | /// // extract entries that use encryption
|
---|
1874 | /// using (ZipFile zip = ZipFile.Read("EncryptedArchive.zip"))
|
---|
1875 | /// {
|
---|
1876 | /// ZipEntry entry;
|
---|
1877 | /// entry = zip["Declaration.txt"];
|
---|
1878 | /// entry.Password = "123456!";
|
---|
1879 | /// entry.Extract("extractDir");
|
---|
1880 | /// entry = zip["Report.xls"];
|
---|
1881 | /// entry.Password = "1Secret!";
|
---|
1882 | /// entry.Extract("extractDir");
|
---|
1883 | /// }
|
---|
1884 | ///
|
---|
1885 | /// </code>
|
---|
1886 | ///
|
---|
1887 | /// <code lang="VB">
|
---|
1888 | /// Using zip As New ZipFile
|
---|
1889 | /// Dim entry as ZipEntry
|
---|
1890 | /// entry= zip.AddFile("Declaration.txt")
|
---|
1891 | /// entry.Password= "123456!"
|
---|
1892 | /// entry = zip.AddFile("Report.xls")
|
---|
1893 | /// entry.Password= "1Secret!"
|
---|
1894 | /// zip.Save("EncryptedArchive.zip")
|
---|
1895 | /// End Using
|
---|
1896 | ///
|
---|
1897 | ///
|
---|
1898 | /// ' extract entries that use encryption
|
---|
1899 | /// Using (zip as ZipFile = ZipFile.Read("EncryptedArchive.zip"))
|
---|
1900 | /// Dim entry as ZipEntry
|
---|
1901 | /// entry = zip("Declaration.txt")
|
---|
1902 | /// entry.Password = "123456!"
|
---|
1903 | /// entry.Extract("extractDir")
|
---|
1904 | /// entry = zip("Report.xls")
|
---|
1905 | /// entry.Password = "1Secret!"
|
---|
1906 | /// entry.Extract("extractDir")
|
---|
1907 | /// End Using
|
---|
1908 | ///
|
---|
1909 | /// </code>
|
---|
1910 | ///
|
---|
1911 | /// </example>
|
---|
1912 | ///
|
---|
1913 | /// <seealso cref="Ionic.Zip.ZipEntry.Encryption"/>
|
---|
1914 | /// <seealso cref="Ionic.Zip.ZipFile.Password">ZipFile.Password</seealso>
|
---|
1915 | public string Password
|
---|
1916 | {
|
---|
1917 | set
|
---|
1918 | {
|
---|
1919 | _Password = value;
|
---|
1920 | if (_Password == null)
|
---|
1921 | {
|
---|
1922 | _Encryption = EncryptionAlgorithm.None;
|
---|
1923 | }
|
---|
1924 | else
|
---|
1925 | {
|
---|
1926 | // We're setting a non-null password.
|
---|
1927 |
|
---|
1928 | // For entries obtained from a zip file that are encrypted, we cannot
|
---|
1929 | // simply restream (recompress, re-encrypt) the file data, because we
|
---|
1930 | // need the old password in order to decrypt the data, and then we
|
---|
1931 | // need the new password to encrypt. So, setting the password is
|
---|
1932 | // never going to work on an entry that is stored encrypted in a zipfile.
|
---|
1933 |
|
---|
1934 | // But it is not en error to set the password, obviously: callers will
|
---|
1935 | // set the password in order to Extract encrypted archives.
|
---|
1936 |
|
---|
1937 | // If the source is a zip archive and there was previously no encryption
|
---|
1938 | // on the entry, then we must re-stream the entry in order to encrypt it.
|
---|
1939 | if (this._Source == ZipEntrySource.ZipFile && !_sourceIsEncrypted)
|
---|
1940 | _restreamRequiredOnSave = true;
|
---|
1941 |
|
---|
1942 | if (Encryption == EncryptionAlgorithm.None)
|
---|
1943 | {
|
---|
1944 | _Encryption = EncryptionAlgorithm.PkzipWeak;
|
---|
1945 | }
|
---|
1946 | }
|
---|
1947 | }
|
---|
1948 | private get { return _Password; }
|
---|
1949 | }
|
---|
1950 |
|
---|
1951 |
|
---|
1952 |
|
---|
1953 | internal bool IsChanged
|
---|
1954 | {
|
---|
1955 | get
|
---|
1956 | {
|
---|
1957 | return _restreamRequiredOnSave | _metadataChanged;
|
---|
1958 | }
|
---|
1959 | }
|
---|
1960 |
|
---|
1961 |
|
---|
1962 | /// <summary>
|
---|
1963 | /// The action the library should take when extracting a file that already exists.
|
---|
1964 | /// </summary>
|
---|
1965 | ///
|
---|
1966 | /// <remarks>
|
---|
1967 | /// <para>
|
---|
1968 | /// This property affects the behavior of the Extract methods (one of the
|
---|
1969 | /// <c>Extract()</c> or <c>ExtractWithPassword()</c> overloads), when
|
---|
1970 | /// extraction would would overwrite an existing filesystem file. If you do
|
---|
1971 | /// not set this property, the library throws an exception when extracting
|
---|
1972 | /// an entry would overwrite an existing file.
|
---|
1973 | /// </para>
|
---|
1974 | ///
|
---|
1975 | /// <para>
|
---|
1976 | /// This property has no effect when extracting to a stream, or when the file to be
|
---|
1977 | /// extracted does not already exist.
|
---|
1978 | /// </para>
|
---|
1979 | ///
|
---|
1980 | /// </remarks>
|
---|
1981 | /// <seealso cref="Ionic.Zip.ZipFile.ExtractExistingFile"/>
|
---|
1982 | ///
|
---|
1983 | /// <example>
|
---|
1984 | /// This example shows how to set the <c>ExtractExistingFile</c> property in
|
---|
1985 | /// an <c>ExtractProgress</c> event, in response to user input. The
|
---|
1986 | /// <c>ExtractProgress</c> event is invoked if and only if the
|
---|
1987 | /// <c>ExtractExistingFile</c> property was previously set to
|
---|
1988 | /// <c>ExtractExistingFileAction.InvokeExtractProgressEvent</c>.
|
---|
1989 | /// <code lang="C#">
|
---|
1990 | /// public static void ExtractProgress(object sender, ExtractProgressEventArgs e)
|
---|
1991 | /// {
|
---|
1992 | /// if (e.EventType == ZipProgressEventType.Extracting_BeforeExtractEntry)
|
---|
1993 | /// Console.WriteLine("extract {0} ", e.CurrentEntry.FileName);
|
---|
1994 | ///
|
---|
1995 | /// else if (e.EventType == ZipProgressEventType.Extracting_ExtractEntryWouldOverwrite)
|
---|
1996 | /// {
|
---|
1997 | /// ZipEntry entry = e.CurrentEntry;
|
---|
1998 | /// string response = null;
|
---|
1999 | /// // Ask the user if he wants overwrite the file
|
---|
2000 | /// do
|
---|
2001 | /// {
|
---|
2002 | /// Console.Write("Overwrite {0} in {1} ? (y/n/C) ", entry.FileName, e.ExtractLocation);
|
---|
2003 | /// response = Console.ReadLine();
|
---|
2004 | /// Console.WriteLine();
|
---|
2005 | ///
|
---|
2006 | /// } while (response != null && response[0]!='Y' &&
|
---|
2007 | /// response[0]!='N' && response[0]!='C');
|
---|
2008 | ///
|
---|
2009 | /// if (response[0]=='C')
|
---|
2010 | /// e.Cancel = true;
|
---|
2011 | /// else if (response[0]=='Y')
|
---|
2012 | /// entry.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently;
|
---|
2013 | /// else
|
---|
2014 | /// entry.ExtractExistingFile= ExtractExistingFileAction.DoNotOverwrite;
|
---|
2015 | /// }
|
---|
2016 | /// }
|
---|
2017 | /// </code>
|
---|
2018 | /// </example>
|
---|
2019 | internal ExtractExistingFileAction ExtractExistingFile
|
---|
2020 | {
|
---|
2021 | get;
|
---|
2022 | set;
|
---|
2023 | }
|
---|
2024 |
|
---|
2025 |
|
---|
2026 | /// <summary>
|
---|
2027 | /// The action to take when an error is encountered while
|
---|
2028 | /// opening or reading files as they are saved into a zip archive.
|
---|
2029 | /// </summary>
|
---|
2030 | ///
|
---|
2031 | /// <remarks>
|
---|
2032 | /// <para>
|
---|
2033 | /// Errors can occur within a call to <see
|
---|
2034 | /// cref="ZipFile.Save()">ZipFile.Save</see>, as the various files contained
|
---|
2035 | /// in a ZipFile are being saved into the zip archive. During the
|
---|
2036 | /// <c>Save</c>, DotNetZip will perform a <c>File.Open</c> on the file
|
---|
2037 | /// associated to the ZipEntry, and then will read the entire contents of
|
---|
2038 | /// the file as it is zipped. Either the open or the Read may fail, because
|
---|
2039 | /// of lock conflicts or other reasons. Using this property, you can
|
---|
2040 | /// specify the action to take when such errors occur.
|
---|
2041 | /// </para>
|
---|
2042 | ///
|
---|
2043 | /// <para>
|
---|
2044 | /// Typically you will NOT set this property on individual ZipEntry
|
---|
2045 | /// instances. Instead, you will set the <see
|
---|
2046 | /// cref="ZipFile.ZipErrorAction">ZipFile.ZipErrorAction</see> property on
|
---|
2047 | /// the ZipFile instance, before adding any entries to the
|
---|
2048 | /// <c>ZipFile</c>. If you do this, errors encountered on behalf of any of
|
---|
2049 | /// the entries in the ZipFile will be handled the same way.
|
---|
2050 | /// </para>
|
---|
2051 | ///
|
---|
2052 | /// <para>
|
---|
2053 | /// But, if you use a <see cref="ZipFile.ZipError"/> handler, you will want
|
---|
2054 | /// to set this property on the <c>ZipEntry</c> within the handler, to
|
---|
2055 | /// communicate back to DotNetZip what you would like to do with the
|
---|
2056 | /// particular error.
|
---|
2057 | /// </para>
|
---|
2058 | ///
|
---|
2059 | /// </remarks>
|
---|
2060 | /// <seealso cref="Ionic.Zip.ZipFile.ZipErrorAction"/>
|
---|
2061 | /// <seealso cref="Ionic.Zip.ZipFile.ZipError"/>
|
---|
2062 | internal ZipErrorAction ZipErrorAction
|
---|
2063 | {
|
---|
2064 | get;
|
---|
2065 | set;
|
---|
2066 | }
|
---|
2067 |
|
---|
2068 |
|
---|
2069 | /// <summary>
|
---|
2070 | /// Indicates whether the entry was included in the most recent save.
|
---|
2071 | /// </summary>
|
---|
2072 | /// <remarks>
|
---|
2073 | /// An entry can be excluded or skipped from a save if there is an error
|
---|
2074 | /// opening or reading the entry.
|
---|
2075 | /// </remarks>
|
---|
2076 | /// <seealso cref="ZipErrorAction"/>
|
---|
2077 | internal bool IncludedInMostRecentSave
|
---|
2078 | {
|
---|
2079 | get
|
---|
2080 | {
|
---|
2081 | return !_skippedDuringSave;
|
---|
2082 | }
|
---|
2083 | }
|
---|
2084 |
|
---|
2085 |
|
---|
2086 | /// <summary>
|
---|
2087 | /// A callback that allows the application to specify the compression to use
|
---|
2088 | /// for a given entry that is about to be added to the zip archive.
|
---|
2089 | /// </summary>
|
---|
2090 | ///
|
---|
2091 | /// <remarks>
|
---|
2092 | /// <para>
|
---|
2093 | /// See <see cref="ZipFile.SetCompression" />
|
---|
2094 | /// </para>
|
---|
2095 | /// </remarks>
|
---|
2096 | public SetCompressionCallback SetCompression
|
---|
2097 | {
|
---|
2098 | get;
|
---|
2099 | set;
|
---|
2100 | }
|
---|
2101 |
|
---|
2102 |
|
---|
2103 |
|
---|
2104 | /// <summary>
|
---|
2105 | /// Set to indicate whether to use UTF-8 encoding for filenames and comments.
|
---|
2106 | /// </summary>
|
---|
2107 | ///
|
---|
2108 | /// <remarks>
|
---|
2109 | ///
|
---|
2110 | /// <para>
|
---|
2111 | /// If this flag is set, the comment and filename for the entry will be
|
---|
2112 | /// encoded with UTF-8, as described in <see
|
---|
2113 | /// href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">the Zip
|
---|
2114 | /// specification</see>, if necessary. "Necessary" means, the filename or
|
---|
2115 | /// entry comment (if any) cannot be reflexively encoded and decoded using the
|
---|
2116 | /// default code page, IBM437.
|
---|
2117 | /// </para>
|
---|
2118 | ///
|
---|
2119 | /// <para>
|
---|
2120 | /// Setting this flag to true is equivalent to setting <see
|
---|
2121 | /// cref="ProvisionalAlternateEncoding"/> to <c>System.Text.Encoding.UTF8</c>.
|
---|
2122 | /// </para>
|
---|
2123 | ///
|
---|
2124 | /// <para>
|
---|
2125 | /// This flag has no effect or relation to the text encoding used within the
|
---|
2126 | /// file itself.
|
---|
2127 | /// </para>
|
---|
2128 | ///
|
---|
2129 | /// </remarks>
|
---|
2130 | [Obsolete("Beginning with v1.9.1.6 of DotNetZip, this property is obsolete. It will be removed in a future version of the library. Your applications should use AlternateEncoding and AlternateEncodingUsage instead.")]
|
---|
2131 | public bool UseUnicodeAsNecessary
|
---|
2132 | {
|
---|
2133 | get
|
---|
2134 | {
|
---|
2135 | return (AlternateEncoding == System.Text.Encoding.GetEncoding("UTF-8")) &&
|
---|
2136 | (AlternateEncodingUsage == ZipOption.AsNecessary);
|
---|
2137 | }
|
---|
2138 | set
|
---|
2139 | {
|
---|
2140 | if (value)
|
---|
2141 | {
|
---|
2142 | AlternateEncoding = System.Text.Encoding.GetEncoding("UTF-8");
|
---|
2143 | AlternateEncodingUsage = ZipOption.AsNecessary;
|
---|
2144 |
|
---|
2145 | }
|
---|
2146 | else
|
---|
2147 | {
|
---|
2148 | AlternateEncoding = Ionic.Zip.ZipFile.DefaultEncoding;
|
---|
2149 | AlternateEncodingUsage = ZipOption.Never;
|
---|
2150 | }
|
---|
2151 | }
|
---|
2152 | }
|
---|
2153 |
|
---|
2154 | /// <summary>
|
---|
2155 | /// The text encoding to use for the FileName and Comment on this ZipEntry,
|
---|
2156 | /// when the default encoding is insufficient.
|
---|
2157 | /// </summary>
|
---|
2158 | ///
|
---|
2159 | /// <remarks>
|
---|
2160 | ///
|
---|
2161 | /// <para>
|
---|
2162 | /// Don't use this property. See <see cref='AlternateEncoding'/>.
|
---|
2163 | /// </para>
|
---|
2164 | ///
|
---|
2165 | /// </remarks>
|
---|
2166 | [Obsolete("This property is obsolete since v1.9.1.6. Use AlternateEncoding and AlternateEncodingUsage instead.", true)]
|
---|
2167 | public System.Text.Encoding ProvisionalAlternateEncoding
|
---|
2168 | {
|
---|
2169 | get; set;
|
---|
2170 | }
|
---|
2171 |
|
---|
2172 | /// <summary>
|
---|
2173 | /// Specifies the alternate text encoding used by this ZipEntry
|
---|
2174 | /// </summary>
|
---|
2175 | /// <remarks>
|
---|
2176 | /// <para>
|
---|
2177 | /// The default text encoding used in Zip files for encoding filenames and
|
---|
2178 | /// comments is IBM437, which is something like a superset of ASCII. In
|
---|
2179 | /// cases where this is insufficient, applications can specify an
|
---|
2180 | /// alternate encoding.
|
---|
2181 | /// </para>
|
---|
2182 | /// <para>
|
---|
2183 | /// When creating a zip file, the usage of the alternate encoding is
|
---|
2184 | /// governed by the <see cref="AlternateEncodingUsage"/> property.
|
---|
2185 | /// Typically you would set both properties to tell DotNetZip to employ an
|
---|
2186 | /// encoding that is not IBM437 in the zipfile you are creating.
|
---|
2187 | /// </para>
|
---|
2188 | /// <para>
|
---|
2189 | /// Keep in mind that because the ZIP specification states that the only
|
---|
2190 | /// valid encodings to use are IBM437 and UTF-8, if you use something
|
---|
2191 | /// other than that, then zip tools and libraries may not be able to
|
---|
2192 | /// successfully read the zip archive you generate.
|
---|
2193 | /// </para>
|
---|
2194 | /// <para>
|
---|
2195 | /// The zip specification states that applications should presume that
|
---|
2196 | /// IBM437 is in use, except when a special bit is set, which indicates
|
---|
2197 | /// UTF-8. There is no way to specify an arbitrary code page, within the
|
---|
2198 | /// zip file itself. When you create a zip file encoded with gb2312 or
|
---|
2199 | /// ibm861 or anything other than IBM437 or UTF-8, then the application
|
---|
2200 | /// that reads the zip file needs to "know" which code page to use. In
|
---|
2201 | /// some cases, the code page used when reading is chosen implicitly. For
|
---|
2202 | /// example, WinRar uses the ambient code page for the host desktop
|
---|
2203 | /// operating system. The pitfall here is that if you create a zip in
|
---|
2204 | /// Copenhagen and send it to Tokyo, the reader of the zipfile may not be
|
---|
2205 | /// able to decode successfully.
|
---|
2206 | /// </para>
|
---|
2207 | /// </remarks>
|
---|
2208 | /// <example>
|
---|
2209 | /// This example shows how to create a zipfile encoded with a
|
---|
2210 | /// language-specific encoding:
|
---|
2211 | /// <code>
|
---|
2212 | /// using (var zip = new ZipFile())
|
---|
2213 | /// {
|
---|
2214 | /// zip.AlternateEnoding = System.Text.Encoding.GetEncoding("ibm861");
|
---|
2215 | /// zip.AlternateEnodingUsage = ZipOption.Always;
|
---|
2216 | /// zip.AddFileS(arrayOfFiles);
|
---|
2217 | /// zip.Save("Myarchive-Encoded-in-IBM861.zip");
|
---|
2218 | /// }
|
---|
2219 | /// </code>
|
---|
2220 | /// </example>
|
---|
2221 | /// <seealso cref="ZipFile.AlternateEncodingUsage" />
|
---|
2222 | public System.Text.Encoding AlternateEncoding
|
---|
2223 | {
|
---|
2224 | get; set;
|
---|
2225 | }
|
---|
2226 |
|
---|
2227 |
|
---|
2228 | /// <summary>
|
---|
2229 | /// Describes if and when this instance should apply
|
---|
2230 | /// AlternateEncoding to encode the FileName and Comment, when
|
---|
2231 | /// saving.
|
---|
2232 | /// </summary>
|
---|
2233 | /// <seealso cref="ZipFile.AlternateEncoding" />
|
---|
2234 | internal ZipOption AlternateEncodingUsage
|
---|
2235 | {
|
---|
2236 | get; set;
|
---|
2237 | }
|
---|
2238 |
|
---|
2239 |
|
---|
2240 | // /// <summary>
|
---|
2241 | // /// The text encoding actually used for this ZipEntry.
|
---|
2242 | // /// </summary>
|
---|
2243 | // ///
|
---|
2244 | // /// <remarks>
|
---|
2245 | // ///
|
---|
2246 | // /// <para>
|
---|
2247 | // /// This read-only property describes the encoding used by the
|
---|
2248 | // /// <c>ZipEntry</c>. If the entry has been read in from an existing ZipFile,
|
---|
2249 | // /// then it may take the value UTF-8, if the entry is coded to specify UTF-8.
|
---|
2250 | // /// If the entry does not specify UTF-8, the typical case, then the encoding
|
---|
2251 | // /// used is whatever the application specified in the call to
|
---|
2252 | // /// <c>ZipFile.Read()</c>. If the application has used one of the overloads of
|
---|
2253 | // /// <c>ZipFile.Read()</c> that does not accept an encoding parameter, then the
|
---|
2254 | // /// encoding used is IBM437, which is the default encoding described in the
|
---|
2255 | // /// ZIP specification. </para>
|
---|
2256 | // ///
|
---|
2257 | // /// <para>
|
---|
2258 | // /// If the entry is being created, then the value of ActualEncoding is taken
|
---|
2259 | // /// according to the logic described in the documentation for <see
|
---|
2260 | // /// cref="ZipFile.ProvisionalAlternateEncoding" />. </para>
|
---|
2261 | // ///
|
---|
2262 | // /// <para>
|
---|
2263 | // /// An application might be interested in retrieving this property to see if
|
---|
2264 | // /// an entry read in from a file has used Unicode (UTF-8). </para>
|
---|
2265 | // ///
|
---|
2266 | // /// </remarks>
|
---|
2267 | // ///
|
---|
2268 | // /// <seealso cref="ZipFile.ProvisionalAlternateEncoding" />
|
---|
2269 | // public System.Text.Encoding ActualEncoding
|
---|
2270 | // {
|
---|
2271 | // get
|
---|
2272 | // {
|
---|
2273 | // return _actualEncoding;
|
---|
2274 | // }
|
---|
2275 | // }
|
---|
2276 |
|
---|
2277 |
|
---|
2278 |
|
---|
2279 |
|
---|
2280 | internal static string NameInArchive(String filename, string directoryPathInArchive)
|
---|
2281 | {
|
---|
2282 | string result = null;
|
---|
2283 | if (directoryPathInArchive == null)
|
---|
2284 | result = filename;
|
---|
2285 |
|
---|
2286 | else
|
---|
2287 | {
|
---|
2288 | if (String.IsNullOrEmpty(directoryPathInArchive))
|
---|
2289 | {
|
---|
2290 | result = Path.GetFileName(filename);
|
---|
2291 | }
|
---|
2292 | else
|
---|
2293 | {
|
---|
2294 | // explicitly specify a pathname for this file
|
---|
2295 | result = Path.Combine(directoryPathInArchive, Path.GetFileName(filename));
|
---|
2296 | }
|
---|
2297 | }
|
---|
2298 |
|
---|
2299 | //result = Path.GetFullPath(result);
|
---|
2300 | result = SharedUtilities.NormalizePathForUseInZipFile(result);
|
---|
2301 |
|
---|
2302 | return result;
|
---|
2303 | }
|
---|
2304 |
|
---|
2305 | // workitem 9073
|
---|
2306 | internal static ZipEntry CreateFromNothing(String nameInArchive)
|
---|
2307 | {
|
---|
2308 | return Create(nameInArchive, ZipEntrySource.None, null, null);
|
---|
2309 | }
|
---|
2310 |
|
---|
2311 | internal static ZipEntry CreateFromFile(String filename, string nameInArchive)
|
---|
2312 | {
|
---|
2313 | return Create(nameInArchive, ZipEntrySource.FileSystem, filename, null);
|
---|
2314 | }
|
---|
2315 |
|
---|
2316 | internal static ZipEntry CreateForStream(String entryName, Stream s)
|
---|
2317 | {
|
---|
2318 | return Create(entryName, ZipEntrySource.Stream, s, null);
|
---|
2319 | }
|
---|
2320 |
|
---|
2321 | internal static ZipEntry CreateForWriter(String entryName, WriteDelegate d)
|
---|
2322 | {
|
---|
2323 | return Create(entryName, ZipEntrySource.WriteDelegate, d, null);
|
---|
2324 | }
|
---|
2325 |
|
---|
2326 | internal static ZipEntry CreateForJitStreamProvider(string nameInArchive, OpenDelegate opener, CloseDelegate closer)
|
---|
2327 | {
|
---|
2328 | return Create(nameInArchive, ZipEntrySource.JitStream, opener, closer);
|
---|
2329 | }
|
---|
2330 |
|
---|
2331 | internal static ZipEntry CreateForZipOutputStream(string nameInArchive)
|
---|
2332 | {
|
---|
2333 | return Create(nameInArchive, ZipEntrySource.ZipOutputStream, null, null);
|
---|
2334 | }
|
---|
2335 |
|
---|
2336 |
|
---|
2337 | private static ZipEntry Create(string nameInArchive, ZipEntrySource source, Object arg1, Object arg2)
|
---|
2338 | {
|
---|
2339 | if (String.IsNullOrEmpty(nameInArchive))
|
---|
2340 | throw new Ionic.Zip.ZipException("The entry name must be non-null and non-empty.");
|
---|
2341 |
|
---|
2342 | ZipEntry entry = new ZipEntry();
|
---|
2343 |
|
---|
2344 | // workitem 7071
|
---|
2345 | // workitem 7926 - "version made by" OS should be zero for compat with WinZip
|
---|
2346 | entry._VersionMadeBy = (0 << 8) + 45; // indicates the attributes are FAT Attributes, and v4.5 of the spec
|
---|
2347 | entry._Source = source;
|
---|
2348 | entry._Mtime = entry._Atime = entry._Ctime = DateTime.UtcNow;
|
---|
2349 |
|
---|
2350 | if (source == ZipEntrySource.Stream)
|
---|
2351 | {
|
---|
2352 | entry._sourceStream = (arg1 as Stream); // may or may not be null
|
---|
2353 | }
|
---|
2354 | else if (source == ZipEntrySource.WriteDelegate)
|
---|
2355 | {
|
---|
2356 | entry._WriteDelegate = (arg1 as WriteDelegate); // may or may not be null
|
---|
2357 | }
|
---|
2358 | else if (source == ZipEntrySource.JitStream)
|
---|
2359 | {
|
---|
2360 | entry._OpenDelegate = (arg1 as OpenDelegate); // may or may not be null
|
---|
2361 | entry._CloseDelegate = (arg2 as CloseDelegate); // may or may not be null
|
---|
2362 | }
|
---|
2363 | else if (source == ZipEntrySource.ZipOutputStream)
|
---|
2364 | {
|
---|
2365 | }
|
---|
2366 | // workitem 9073
|
---|
2367 | else if (source == ZipEntrySource.None)
|
---|
2368 | {
|
---|
2369 | // make this a valid value, for later.
|
---|
2370 | entry._Source = ZipEntrySource.FileSystem;
|
---|
2371 | }
|
---|
2372 | else
|
---|
2373 | {
|
---|
2374 | String filename = (arg1 as String); // must not be null
|
---|
2375 |
|
---|
2376 | if (String.IsNullOrEmpty(filename))
|
---|
2377 | throw new Ionic.Zip.ZipException("The filename must be non-null and non-empty.");
|
---|
2378 |
|
---|
2379 | try
|
---|
2380 | {
|
---|
2381 | // The named file may or may not exist at this time. For
|
---|
2382 | // example, when adding a directory by name. We test existence
|
---|
2383 | // when necessary: when saving the ZipFile, or when getting the
|
---|
2384 | // attributes, and so on.
|
---|
2385 |
|
---|
2386 | #if NETCF
|
---|
2387 | // workitem 6878
|
---|
2388 | // Ionic.Zip.SharedUtilities.AdjustTime_Win32ToDotNet
|
---|
2389 | entry._Mtime = File.GetLastWriteTime(filename).ToUniversalTime();
|
---|
2390 | entry._Ctime = File.GetCreationTime(filename).ToUniversalTime();
|
---|
2391 | entry._Atime = File.GetLastAccessTime(filename).ToUniversalTime();
|
---|
2392 |
|
---|
2393 | // workitem 7071
|
---|
2394 | // can only get attributes of files that exist.
|
---|
2395 | if (File.Exists(filename) || Directory.Exists(filename))
|
---|
2396 | entry._ExternalFileAttrs = (int)NetCfFile.GetAttributes(filename);
|
---|
2397 |
|
---|
2398 | #elif SILVERLIGHT
|
---|
2399 | entry._Mtime =
|
---|
2400 | entry._Ctime =
|
---|
2401 | entry._Atime = System.DateTime.UtcNow;
|
---|
2402 | entry._ExternalFileAttrs = (int)0;
|
---|
2403 | #else
|
---|
2404 | // workitem 6878??
|
---|
2405 | entry._Mtime = File.GetLastWriteTime(filename).ToUniversalTime();
|
---|
2406 | entry._Ctime = File.GetCreationTime(filename).ToUniversalTime();
|
---|
2407 | entry._Atime = File.GetLastAccessTime(filename).ToUniversalTime();
|
---|
2408 |
|
---|
2409 | // workitem 7071
|
---|
2410 | // can only get attributes on files that exist.
|
---|
2411 | if (File.Exists(filename) || Directory.Exists(filename))
|
---|
2412 | entry._ExternalFileAttrs = (int)File.GetAttributes(filename);
|
---|
2413 |
|
---|
2414 | #endif
|
---|
2415 | entry._ntfsTimesAreSet = true;
|
---|
2416 |
|
---|
2417 | entry._LocalFileName = Path.GetFullPath(filename); // workitem 8813
|
---|
2418 |
|
---|
2419 | }
|
---|
2420 | catch (System.IO.PathTooLongException ptle)
|
---|
2421 | {
|
---|
2422 | // workitem 14035
|
---|
2423 | var msg = String.Format("The path is too long, filename={0}",
|
---|
2424 | filename);
|
---|
2425 | throw new ZipException(msg, ptle);
|
---|
2426 | }
|
---|
2427 |
|
---|
2428 | }
|
---|
2429 |
|
---|
2430 | entry._LastModified = entry._Mtime;
|
---|
2431 | entry._FileNameInArchive = SharedUtilities.NormalizePathForUseInZipFile(nameInArchive);
|
---|
2432 | // We don't actually slurp in the file data until the caller invokes Write on this entry.
|
---|
2433 |
|
---|
2434 | return entry;
|
---|
2435 | }
|
---|
2436 |
|
---|
2437 |
|
---|
2438 |
|
---|
2439 |
|
---|
2440 | internal void MarkAsDirectory()
|
---|
2441 | {
|
---|
2442 | _IsDirectory = true;
|
---|
2443 | // workitem 6279
|
---|
2444 | if (!_FileNameInArchive.EndsWith("/"))
|
---|
2445 | _FileNameInArchive += "/";
|
---|
2446 | }
|
---|
2447 |
|
---|
2448 |
|
---|
2449 |
|
---|
2450 | /// <summary>
|
---|
2451 | /// Indicates whether an entry is marked as a text file. Be careful when
|
---|
2452 | /// using on this property. Unless you have a good reason, you should
|
---|
2453 | /// probably ignore this property.
|
---|
2454 | /// </summary>
|
---|
2455 | ///
|
---|
2456 | /// <remarks>
|
---|
2457 | /// <para>
|
---|
2458 | /// The ZIP format includes a provision for specifying whether an entry in
|
---|
2459 | /// the zip archive is a text or binary file. This property exposes that
|
---|
2460 | /// metadata item. Be careful when using this property: It's not clear
|
---|
2461 | /// that this property as a firm meaning, across tools and libraries.
|
---|
2462 | /// </para>
|
---|
2463 | ///
|
---|
2464 | /// <para>
|
---|
2465 | /// To be clear, when reading a zip file, the property value may or may
|
---|
2466 | /// not be set, and its value may or may not be valid. Not all entries
|
---|
2467 | /// that you may think of as "text" entries will be so marked, and entries
|
---|
2468 | /// marked as "text" are not guaranteed in any way to be text entries.
|
---|
2469 | /// Whether the value is set and set correctly depends entirely on the
|
---|
2470 | /// application that produced the zip file.
|
---|
2471 | /// </para>
|
---|
2472 | ///
|
---|
2473 | /// <para>
|
---|
2474 | /// There are many zip tools available, and when creating zip files, some
|
---|
2475 | /// of them "respect" the IsText metadata field, and some of them do not.
|
---|
2476 | /// Unfortunately, even when an application tries to do "the right thing",
|
---|
2477 | /// it's not always clear what "the right thing" is.
|
---|
2478 | /// </para>
|
---|
2479 | ///
|
---|
2480 | /// <para>
|
---|
2481 | /// There's no firm definition of just what it means to be "a text file",
|
---|
2482 | /// and the zip specification does not help in this regard. Twenty years
|
---|
2483 | /// ago, text was ASCII, each byte was less than 127. IsText meant, all
|
---|
2484 | /// bytes in the file were less than 127. These days, it is not the case
|
---|
2485 | /// that all text files have all bytes less than 127. Any unicode file
|
---|
2486 | /// may have bytes that are above 0x7f. The zip specification has nothing
|
---|
2487 | /// to say on this topic. Therefore, it's not clear what IsText really
|
---|
2488 | /// means.
|
---|
2489 | /// </para>
|
---|
2490 | ///
|
---|
2491 | /// <para>
|
---|
2492 | /// This property merely tells a reading application what is stored in the
|
---|
2493 | /// metadata for an entry, without guaranteeing its validity or its
|
---|
2494 | /// meaning.
|
---|
2495 | /// </para>
|
---|
2496 | ///
|
---|
2497 | /// <para>
|
---|
2498 | /// When DotNetZip is used to create a zipfile, it attempts to set this
|
---|
2499 | /// field "correctly." For example, if a file ends in ".txt", this field
|
---|
2500 | /// will be set. Your application may override that default setting. When
|
---|
2501 | /// writing a zip file, you must set the property before calling
|
---|
2502 | /// <c>Save()</c> on the ZipFile.
|
---|
2503 | /// </para>
|
---|
2504 | ///
|
---|
2505 | /// <para>
|
---|
2506 | /// When reading a zip file, a more general way to decide just what kind
|
---|
2507 | /// of file is contained in a particular entry is to use the file type
|
---|
2508 | /// database stored in the operating system. The operating system stores
|
---|
2509 | /// a table that says, a file with .jpg extension is a JPG image file, a
|
---|
2510 | /// file with a .xml extension is an XML document, a file with a .txt is a
|
---|
2511 | /// pure ASCII text document, and so on. To get this information on
|
---|
2512 | /// Windows, <see
|
---|
2513 | /// href="http://www.codeproject.com/KB/cs/GetFileTypeAndIcon.aspx"> you
|
---|
2514 | /// need to read and parse the registry.</see> </para>
|
---|
2515 | /// </remarks>
|
---|
2516 | ///
|
---|
2517 | /// <example>
|
---|
2518 | /// <code>
|
---|
2519 | /// using (var zip = new ZipFile())
|
---|
2520 | /// {
|
---|
2521 | /// var e = zip.UpdateFile("Descriptions.mme", "");
|
---|
2522 | /// e.IsText = true;
|
---|
2523 | /// zip.Save(zipPath);
|
---|
2524 | /// }
|
---|
2525 | /// </code>
|
---|
2526 | ///
|
---|
2527 | /// <code lang="VB">
|
---|
2528 | /// Using zip As New ZipFile
|
---|
2529 | /// Dim e2 as ZipEntry = zip.AddFile("Descriptions.mme", "")
|
---|
2530 | /// e.IsText= True
|
---|
2531 | /// zip.Save(zipPath)
|
---|
2532 | /// End Using
|
---|
2533 | /// </code>
|
---|
2534 | /// </example>
|
---|
2535 | public bool IsText
|
---|
2536 | {
|
---|
2537 | // workitem 7801
|
---|
2538 | get { return _IsText; }
|
---|
2539 | set { _IsText = value; }
|
---|
2540 | }
|
---|
2541 |
|
---|
2542 |
|
---|
2543 |
|
---|
2544 | /// <summary>Provides a string representation of the instance.</summary>
|
---|
2545 | /// <returns>a string representation of the instance.</returns>
|
---|
2546 | public override String ToString()
|
---|
2547 | {
|
---|
2548 | return String.Format("ZipEntry::{0}", FileName);
|
---|
2549 | }
|
---|
2550 |
|
---|
2551 |
|
---|
2552 | internal Stream ArchiveStream
|
---|
2553 | {
|
---|
2554 | get
|
---|
2555 | {
|
---|
2556 | if (_archiveStream == null)
|
---|
2557 | {
|
---|
2558 | if (_container.ZipFile != null)
|
---|
2559 | {
|
---|
2560 | var zf = _container.ZipFile;
|
---|
2561 | zf.Reset(false);
|
---|
2562 | _archiveStream = zf.StreamForDiskNumber(_diskNumber);
|
---|
2563 | }
|
---|
2564 | else
|
---|
2565 | {
|
---|
2566 | _archiveStream = _container.ZipOutputStream.OutputStream;
|
---|
2567 | }
|
---|
2568 | }
|
---|
2569 | return _archiveStream;
|
---|
2570 | }
|
---|
2571 | }
|
---|
2572 |
|
---|
2573 |
|
---|
2574 | private void SetFdpLoh()
|
---|
2575 | {
|
---|
2576 | // The value for FileDataPosition has not yet been set.
|
---|
2577 | // Therefore, seek to the local header, and figure the start of file data.
|
---|
2578 | // workitem 8098: ok (restore)
|
---|
2579 | long origPosition = this.ArchiveStream.Position;
|
---|
2580 | try
|
---|
2581 | {
|
---|
2582 | this.ArchiveStream.Seek(this._RelativeOffsetOfLocalHeader, SeekOrigin.Begin);
|
---|
2583 |
|
---|
2584 | // workitem 10178
|
---|
2585 | Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
|
---|
2586 | }
|
---|
2587 | catch (System.IO.IOException exc1)
|
---|
2588 | {
|
---|
2589 | string description = String.Format("Exception seeking entry({0}) offset(0x{1:X8}) len(0x{2:X8})",
|
---|
2590 | this.FileName, this._RelativeOffsetOfLocalHeader,
|
---|
2591 | this.ArchiveStream.Length);
|
---|
2592 | throw new BadStateException(description, exc1);
|
---|
2593 | }
|
---|
2594 |
|
---|
2595 | byte[] block = new byte[30];
|
---|
2596 | this.ArchiveStream.Read(block, 0, block.Length);
|
---|
2597 |
|
---|
2598 | // At this point we could verify the contents read from the local header
|
---|
2599 | // with the contents read from the central header. We could, but don't need to.
|
---|
2600 | // So we won't.
|
---|
2601 |
|
---|
2602 | Int16 filenameLength = (short)(block[26] + block[27] * 256);
|
---|
2603 | Int16 extraFieldLength = (short)(block[28] + block[29] * 256);
|
---|
2604 |
|
---|
2605 | // Console.WriteLine(" pos 0x{0:X8} ({0})", this.ArchiveStream.Position);
|
---|
2606 | // Console.WriteLine(" seek 0x{0:X8} ({0})", filenameLength + extraFieldLength);
|
---|
2607 |
|
---|
2608 | this.ArchiveStream.Seek(filenameLength + extraFieldLength, SeekOrigin.Current);
|
---|
2609 | // workitem 10178
|
---|
2610 | Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
|
---|
2611 |
|
---|
2612 | this._LengthOfHeader = 30 + extraFieldLength + filenameLength +
|
---|
2613 | GetLengthOfCryptoHeaderBytes(_Encryption_FromZipFile);
|
---|
2614 |
|
---|
2615 | // Console.WriteLine(" ROLH 0x{0:X8} ({0})", _RelativeOffsetOfLocalHeader);
|
---|
2616 | // Console.WriteLine(" LOH 0x{0:X8} ({0})", _LengthOfHeader);
|
---|
2617 | // workitem 8098: ok (arithmetic)
|
---|
2618 | this.__FileDataPosition = _RelativeOffsetOfLocalHeader + _LengthOfHeader;
|
---|
2619 | // Console.WriteLine(" FDP 0x{0:X8} ({0})", __FileDataPosition);
|
---|
2620 |
|
---|
2621 | // restore file position:
|
---|
2622 | // workitem 8098: ok (restore)
|
---|
2623 | this.ArchiveStream.Seek(origPosition, SeekOrigin.Begin);
|
---|
2624 | // workitem 10178
|
---|
2625 | Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
|
---|
2626 | }
|
---|
2627 |
|
---|
2628 |
|
---|
2629 |
|
---|
2630 | #if AESCRYPTO
|
---|
2631 | private static int GetKeyStrengthInBits(EncryptionAlgorithm a)
|
---|
2632 | {
|
---|
2633 | if (a == EncryptionAlgorithm.WinZipAes256) return 256;
|
---|
2634 | else if (a == EncryptionAlgorithm.WinZipAes128) return 128;
|
---|
2635 | return -1;
|
---|
2636 | }
|
---|
2637 | #endif
|
---|
2638 |
|
---|
2639 | internal static int GetLengthOfCryptoHeaderBytes(EncryptionAlgorithm a)
|
---|
2640 | {
|
---|
2641 | //if ((_BitField & 0x01) != 0x01) return 0;
|
---|
2642 | if (a == EncryptionAlgorithm.None) return 0;
|
---|
2643 |
|
---|
2644 | #if AESCRYPTO
|
---|
2645 | if (a == EncryptionAlgorithm.WinZipAes128 ||
|
---|
2646 | a == EncryptionAlgorithm.WinZipAes256)
|
---|
2647 | {
|
---|
2648 | int KeyStrengthInBits = GetKeyStrengthInBits(a);
|
---|
2649 | int sizeOfSaltAndPv = ((KeyStrengthInBits / 8 / 2) + 2);
|
---|
2650 | return sizeOfSaltAndPv;
|
---|
2651 | }
|
---|
2652 | #endif
|
---|
2653 | if (a == EncryptionAlgorithm.PkzipWeak)
|
---|
2654 | return 12;
|
---|
2655 | throw new ZipException("internal error");
|
---|
2656 | }
|
---|
2657 |
|
---|
2658 |
|
---|
2659 | internal long FileDataPosition
|
---|
2660 | {
|
---|
2661 | get
|
---|
2662 | {
|
---|
2663 | if (__FileDataPosition == -1)
|
---|
2664 | SetFdpLoh();
|
---|
2665 |
|
---|
2666 | return __FileDataPosition;
|
---|
2667 | }
|
---|
2668 | }
|
---|
2669 |
|
---|
2670 | private int LengthOfHeader
|
---|
2671 | {
|
---|
2672 | get
|
---|
2673 | {
|
---|
2674 | if (_LengthOfHeader == 0)
|
---|
2675 | SetFdpLoh();
|
---|
2676 |
|
---|
2677 | return _LengthOfHeader;
|
---|
2678 | }
|
---|
2679 | }
|
---|
2680 |
|
---|
2681 |
|
---|
2682 |
|
---|
2683 | private ZipCrypto _zipCrypto_forExtract;
|
---|
2684 | private ZipCrypto _zipCrypto_forWrite;
|
---|
2685 | #if AESCRYPTO
|
---|
2686 | private WinZipAesCrypto _aesCrypto_forExtract;
|
---|
2687 | private WinZipAesCrypto _aesCrypto_forWrite;
|
---|
2688 | private Int16 _WinZipAesMethod;
|
---|
2689 | #endif
|
---|
2690 |
|
---|
2691 | internal DateTime _LastModified;
|
---|
2692 | private DateTime _Mtime, _Atime, _Ctime; // workitem 6878: NTFS quantities
|
---|
2693 | private bool _ntfsTimesAreSet;
|
---|
2694 | private bool _emitNtfsTimes = true;
|
---|
2695 | private bool _emitUnixTimes; // by default, false
|
---|
2696 | private bool _TrimVolumeFromFullyQualifiedPaths = true; // by default, trim them.
|
---|
2697 | internal string _LocalFileName;
|
---|
2698 | private string _FileNameInArchive;
|
---|
2699 | internal Int16 _VersionNeeded;
|
---|
2700 | internal Int16 _BitField;
|
---|
2701 | internal Int16 _CompressionMethod;
|
---|
2702 | private Int16 _CompressionMethod_FromZipFile;
|
---|
2703 | private Ionic.Zlib.CompressionLevel _CompressionLevel;
|
---|
2704 | internal string _Comment;
|
---|
2705 | private bool _IsDirectory;
|
---|
2706 | private byte[] _CommentBytes;
|
---|
2707 | internal Int64 _CompressedSize;
|
---|
2708 | internal Int64 _CompressedFileDataSize; // CompressedSize less 12 bytes for the encryption header, if any
|
---|
2709 | internal Int64 _UncompressedSize;
|
---|
2710 | internal Int32 _TimeBlob;
|
---|
2711 | private bool _crcCalculated;
|
---|
2712 | internal Int32 _Crc32;
|
---|
2713 | internal byte[] _Extra;
|
---|
2714 | private bool _metadataChanged;
|
---|
2715 | private bool _restreamRequiredOnSave;
|
---|
2716 | private bool _sourceIsEncrypted;
|
---|
2717 | private bool _skippedDuringSave;
|
---|
2718 | private UInt32 _diskNumber;
|
---|
2719 |
|
---|
2720 | private static System.Text.Encoding ibm437 = System.Text.Encoding.GetEncoding("IBM437");
|
---|
2721 | //private System.Text.Encoding _provisionalAlternateEncoding = System.Text.Encoding.GetEncoding("IBM437");
|
---|
2722 | private System.Text.Encoding _actualEncoding;
|
---|
2723 |
|
---|
2724 | internal ZipContainer _container;
|
---|
2725 |
|
---|
2726 | private long __FileDataPosition = -1;
|
---|
2727 | private byte[] _EntryHeader;
|
---|
2728 | internal Int64 _RelativeOffsetOfLocalHeader;
|
---|
2729 | private Int64 _future_ROLH;
|
---|
2730 | private Int64 _TotalEntrySize;
|
---|
2731 | private int _LengthOfHeader;
|
---|
2732 | private int _LengthOfTrailer;
|
---|
2733 | internal bool _InputUsesZip64;
|
---|
2734 | private UInt32 _UnsupportedAlgorithmId;
|
---|
2735 |
|
---|
2736 | internal string _Password;
|
---|
2737 | internal ZipEntrySource _Source;
|
---|
2738 | internal EncryptionAlgorithm _Encryption;
|
---|
2739 | internal EncryptionAlgorithm _Encryption_FromZipFile;
|
---|
2740 | internal byte[] _WeakEncryptionHeader;
|
---|
2741 | internal Stream _archiveStream;
|
---|
2742 | private Stream _sourceStream;
|
---|
2743 | private Nullable<Int64> _sourceStreamOriginalPosition;
|
---|
2744 | private bool _sourceWasJitProvided;
|
---|
2745 | private bool _ioOperationCanceled;
|
---|
2746 | private bool _presumeZip64;
|
---|
2747 | private Nullable<bool> _entryRequiresZip64;
|
---|
2748 | private Nullable<bool> _OutputUsesZip64;
|
---|
2749 | private bool _IsText; // workitem 7801
|
---|
2750 | private ZipEntryTimestamp _timestamp;
|
---|
2751 |
|
---|
2752 | private static System.DateTime _unixEpoch = new System.DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
---|
2753 | private static System.DateTime _win32Epoch = System.DateTime.FromFileTimeUtc(0L);
|
---|
2754 | private static System.DateTime _zeroHour = new System.DateTime(1, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
---|
2755 |
|
---|
2756 | private WriteDelegate _WriteDelegate;
|
---|
2757 | private OpenDelegate _OpenDelegate;
|
---|
2758 | private CloseDelegate _CloseDelegate;
|
---|
2759 |
|
---|
2760 |
|
---|
2761 | // summary
|
---|
2762 | // The default size of the IO buffer for ZipEntry instances. Currently it is 8192 bytes.
|
---|
2763 | // summary
|
---|
2764 | //public const int IO_BUFFER_SIZE_DEFAULT = 8192; // 0x8000; // 0x4400
|
---|
2765 |
|
---|
2766 | }
|
---|
2767 |
|
---|
2768 |
|
---|
2769 |
|
---|
2770 | /// <summary>
|
---|
2771 | /// An enum that specifies the type of timestamp available on the ZipEntry.
|
---|
2772 | /// </summary>
|
---|
2773 | ///
|
---|
2774 | /// <remarks>
|
---|
2775 | ///
|
---|
2776 | /// <para>
|
---|
2777 | /// The last modified time of a file can be stored in multiple ways in
|
---|
2778 | /// a zip file, and they are not mutually exclusive:
|
---|
2779 | /// </para>
|
---|
2780 | ///
|
---|
2781 | /// <list type="bullet">
|
---|
2782 | /// <item>
|
---|
2783 | /// In the so-called "DOS" format, which has a 2-second precision. Values
|
---|
2784 | /// are rounded to the nearest even second. For example, if the time on the
|
---|
2785 | /// file is 12:34:43, then it will be stored as 12:34:44. This first value
|
---|
2786 | /// is accessible via the <c>LastModified</c> property. This value is always
|
---|
2787 | /// present in the metadata for each zip entry. In some cases the value is
|
---|
2788 | /// invalid, or zero.
|
---|
2789 | /// </item>
|
---|
2790 | ///
|
---|
2791 | /// <item>
|
---|
2792 | /// In the so-called "Windows" or "NTFS" format, as an 8-byte integer
|
---|
2793 | /// quantity expressed as the number of 1/10 milliseconds (in other words
|
---|
2794 | /// the number of 100 nanosecond units) since January 1, 1601 (UTC). This
|
---|
2795 | /// format is how Windows represents file times. This time is accessible
|
---|
2796 | /// via the <c>ModifiedTime</c> property.
|
---|
2797 | /// </item>
|
---|
2798 | ///
|
---|
2799 | /// <item>
|
---|
2800 | /// In the "Unix" format, a 4-byte quantity specifying the number of seconds since
|
---|
2801 | /// January 1, 1970 UTC.
|
---|
2802 | /// </item>
|
---|
2803 | ///
|
---|
2804 | /// <item>
|
---|
2805 | /// In an older format, now deprecated but still used by some current
|
---|
2806 | /// tools. This format is also a 4-byte quantity specifying the number of
|
---|
2807 | /// seconds since January 1, 1970 UTC.
|
---|
2808 | /// </item>
|
---|
2809 | ///
|
---|
2810 | /// </list>
|
---|
2811 | ///
|
---|
2812 | /// <para>
|
---|
2813 | /// This bit field describes which of the formats were found in a <c>ZipEntry</c> that was read.
|
---|
2814 | /// </para>
|
---|
2815 | ///
|
---|
2816 | /// </remarks>
|
---|
2817 | [Flags]
|
---|
2818 | internal enum ZipEntryTimestamp
|
---|
2819 | {
|
---|
2820 | /// <summary>
|
---|
2821 | /// Default value.
|
---|
2822 | /// </summary>
|
---|
2823 | None = 0,
|
---|
2824 |
|
---|
2825 | /// <summary>
|
---|
2826 | /// A DOS timestamp with 2-second precision.
|
---|
2827 | /// </summary>
|
---|
2828 | DOS = 1,
|
---|
2829 |
|
---|
2830 | /// <summary>
|
---|
2831 | /// A Windows timestamp with 100-ns precision.
|
---|
2832 | /// </summary>
|
---|
2833 | Windows = 2,
|
---|
2834 |
|
---|
2835 | /// <summary>
|
---|
2836 | /// A Unix timestamp with 1-second precision.
|
---|
2837 | /// </summary>
|
---|
2838 | Unix = 4,
|
---|
2839 |
|
---|
2840 | /// <summary>
|
---|
2841 | /// A Unix timestamp with 1-second precision, stored in InfoZip v1 format. This
|
---|
2842 | /// format is outdated and is supported for reading archives only.
|
---|
2843 | /// </summary>
|
---|
2844 | InfoZip1 = 8,
|
---|
2845 | }
|
---|
2846 |
|
---|
2847 |
|
---|
2848 |
|
---|
2849 | /// <summary>
|
---|
2850 | /// The method of compression to use for a particular ZipEntry.
|
---|
2851 | /// </summary>
|
---|
2852 | ///
|
---|
2853 | /// <remarks>
|
---|
2854 | /// <see
|
---|
2855 | /// href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">PKWare's
|
---|
2856 | /// ZIP Specification</see> describes a number of distinct
|
---|
2857 | /// cmopression methods that can be used within a zip
|
---|
2858 | /// file. DotNetZip supports a subset of them.
|
---|
2859 | /// </remarks>
|
---|
2860 | internal enum CompressionMethod
|
---|
2861 | {
|
---|
2862 | /// <summary>
|
---|
2863 | /// No compression at all. For COM environments, the value is 0 (zero).
|
---|
2864 | /// </summary>
|
---|
2865 | None = 0,
|
---|
2866 |
|
---|
2867 | /// <summary>
|
---|
2868 | /// DEFLATE compression, as described in <see
|
---|
2869 | /// href="http://www.ietf.org/rfc/rfc1951.txt">IETF RFC
|
---|
2870 | /// 1951</see>. This is the "normal" compression used in zip
|
---|
2871 | /// files. For COM environments, the value is 8.
|
---|
2872 | /// </summary>
|
---|
2873 | Deflate = 8,
|
---|
2874 |
|
---|
2875 | #if BZIP
|
---|
2876 | /// <summary>
|
---|
2877 | /// BZip2 compression, a compression algorithm developed by Julian Seward.
|
---|
2878 | /// For COM environments, the value is 12.
|
---|
2879 | /// </summary>
|
---|
2880 | BZip2 = 12,
|
---|
2881 | #endif
|
---|
2882 | }
|
---|
2883 |
|
---|
2884 |
|
---|
2885 | #if NETCF
|
---|
2886 | internal class NetCfFile
|
---|
2887 | {
|
---|
2888 | public static int SetTimes(string filename, DateTime ctime, DateTime atime, DateTime mtime)
|
---|
2889 | {
|
---|
2890 | IntPtr hFile = (IntPtr) CreateFileCE(filename,
|
---|
2891 | (uint)0x40000000L, // (uint)FileAccess.Write,
|
---|
2892 | (uint)0x00000002L, // (uint)FileShare.Write,
|
---|
2893 | 0,
|
---|
2894 | (uint) 3, // == open existing
|
---|
2895 | (uint)0, // flagsAndAttributes
|
---|
2896 | 0);
|
---|
2897 |
|
---|
2898 | if((int)hFile == -1)
|
---|
2899 | {
|
---|
2900 | // workitem 7944: don't throw on failure to set file times
|
---|
2901 | // throw new ZipException("CreateFileCE Failed");
|
---|
2902 | return Interop.Marshal.GetLastWin32Error();
|
---|
2903 | }
|
---|
2904 |
|
---|
2905 | SetFileTime(hFile,
|
---|
2906 | BitConverter.GetBytes(ctime.ToFileTime()),
|
---|
2907 | BitConverter.GetBytes(atime.ToFileTime()),
|
---|
2908 | BitConverter.GetBytes(mtime.ToFileTime()));
|
---|
2909 |
|
---|
2910 | CloseHandle(hFile);
|
---|
2911 | return 0;
|
---|
2912 | }
|
---|
2913 |
|
---|
2914 |
|
---|
2915 | public static int SetLastWriteTime(string filename, DateTime mtime)
|
---|
2916 | {
|
---|
2917 | IntPtr hFile = (IntPtr) CreateFileCE(filename,
|
---|
2918 | (uint)0x40000000L, // (uint)FileAccess.Write,
|
---|
2919 | (uint)0x00000002L, // (uint)FileShare.Write,
|
---|
2920 | 0,
|
---|
2921 | (uint) 3, // == open existing
|
---|
2922 | (uint)0, // flagsAndAttributes
|
---|
2923 | 0);
|
---|
2924 |
|
---|
2925 | if((int)hFile == -1)
|
---|
2926 | {
|
---|
2927 | // workitem 7944: don't throw on failure to set file time
|
---|
2928 | // throw new ZipException(String.Format("CreateFileCE Failed ({0})",
|
---|
2929 | // Interop.Marshal.GetLastWin32Error()));
|
---|
2930 | return Interop.Marshal.GetLastWin32Error();
|
---|
2931 | }
|
---|
2932 |
|
---|
2933 | SetFileTime(hFile, null, null,
|
---|
2934 | BitConverter.GetBytes(mtime.ToFileTime()));
|
---|
2935 |
|
---|
2936 | CloseHandle(hFile);
|
---|
2937 | return 0;
|
---|
2938 | }
|
---|
2939 |
|
---|
2940 |
|
---|
2941 | [Interop.DllImport("coredll.dll", EntryPoint="CreateFile", SetLastError=true)]
|
---|
2942 | internal static extern int CreateFileCE(string lpFileName,
|
---|
2943 | uint dwDesiredAccess,
|
---|
2944 | uint dwShareMode,
|
---|
2945 | int lpSecurityAttributes,
|
---|
2946 | uint dwCreationDisposition,
|
---|
2947 | uint dwFlagsAndAttributes,
|
---|
2948 | int hTemplateFile);
|
---|
2949 |
|
---|
2950 |
|
---|
2951 | [Interop.DllImport("coredll", EntryPoint="GetFileAttributes", SetLastError=true)]
|
---|
2952 | internal static extern uint GetAttributes(string lpFileName);
|
---|
2953 |
|
---|
2954 | [Interop.DllImport("coredll", EntryPoint="SetFileAttributes", SetLastError=true)]
|
---|
2955 | internal static extern bool SetAttributes(string lpFileName, uint dwFileAttributes);
|
---|
2956 |
|
---|
2957 | [Interop.DllImport("coredll", EntryPoint="SetFileTime", SetLastError=true)]
|
---|
2958 | internal static extern bool SetFileTime(IntPtr hFile, byte[] lpCreationTime, byte[] lpLastAccessTime, byte[] lpLastWriteTime);
|
---|
2959 |
|
---|
2960 | [Interop.DllImport("coredll.dll", SetLastError=true)]
|
---|
2961 | internal static extern bool CloseHandle(IntPtr hObject);
|
---|
2962 |
|
---|
2963 | }
|
---|
2964 | #endif
|
---|
2965 |
|
---|
2966 |
|
---|
2967 |
|
---|
2968 | }
|
---|