You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

642 lines
22 KiB

  1. // ZipConstants.cs
  2. //
  3. // Copyright (C) 2001 Mike Krueger
  4. // Copyright (C) 2004 John Reilly
  5. //
  6. // This file was translated from java, it was part of the GNU Classpath
  7. // Copyright (C) 2001 Free Software Foundation, Inc.
  8. //
  9. // This program is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU General Public License
  11. // as published by the Free Software Foundation; either version 2
  12. // of the License, or (at your option) any later version.
  13. //
  14. // This program is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. // GNU General Public License for more details.
  18. //
  19. // You should have received a copy of the GNU General Public License
  20. // along with this program; if not, write to the Free Software
  21. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  22. //
  23. // Linking this library statically or dynamically with other modules is
  24. // making a combined work based on this library. Thus, the terms and
  25. // conditions of the GNU General Public License cover the whole
  26. // combination.
  27. //
  28. // As a special exception, the copyright holders of this library give you
  29. // permission to link this library with independent modules to produce an
  30. // executable, regardless of the license terms of these independent
  31. // modules, and to copy and distribute the resulting executable under
  32. // terms of your choice, provided that you also meet, for each linked
  33. // independent module, the terms and conditions of the license of that
  34. // module. An independent module is a module which is not derived from
  35. // or based on this library. If you modify this library, you may extend
  36. // this exception to your version of the library, but you are not
  37. // obligated to do so. If you do not wish to do so, delete this
  38. // exception statement from your version.
  39. // HISTORY
  40. // 22-12-2009 DavidPierson Added AES support
  41. using System;
  42. using System.Text;
  43. #if NETCF_1_0 || NETCF_2_0
  44. using System.Globalization;
  45. #endif
  46. namespace Externals.Compression.Zip
  47. {
  48. #region Enumerations
  49. /// <summary>
  50. /// Determines how entries are tested to see if they should use Zip64 extensions or not.
  51. /// </summary>
  52. internal enum UseZip64
  53. {
  54. /// <summary>
  55. /// Zip64 will not be forced on entries during processing.
  56. /// </summary>
  57. /// <remarks>An entry can have this overridden if required <see cref="ZipEntry.ForceZip64"></see></remarks>
  58. Off,
  59. /// <summary>
  60. /// Zip64 should always be used.
  61. /// </summary>
  62. On,
  63. /// <summary>
  64. /// #ZipLib will determine use based on entry values when added to archive.
  65. /// </summary>
  66. Dynamic,
  67. }
  68. /// <summary>
  69. /// The kind of compression used for an entry in an archive
  70. /// </summary>
  71. internal enum CompressionMethod
  72. {
  73. /// <summary>
  74. /// A direct copy of the file contents is held in the archive
  75. /// </summary>
  76. Stored = 0,
  77. /// <summary>
  78. /// Common Zip compression method using a sliding dictionary
  79. /// of up to 32KB and secondary compression from Huffman/Shannon-Fano trees
  80. /// </summary>
  81. Deflated = 8,
  82. /// <summary>
  83. /// An extension to deflate with a 64KB window. Not supported by #Zip currently
  84. /// </summary>
  85. Deflate64 = 9,
  86. /// <summary>
  87. /// BZip2 compression. Not supported by #Zip.
  88. /// </summary>
  89. BZip2 = 11,
  90. /// <summary>
  91. /// WinZip special for AES encryption, Now supported by #Zip.
  92. /// </summary>
  93. WinZipAES = 99,
  94. }
  95. /// <summary>
  96. /// Identifies the encryption algorithm used for an entry
  97. /// </summary>
  98. internal enum EncryptionAlgorithm
  99. {
  100. /// <summary>
  101. /// No encryption has been used.
  102. /// </summary>
  103. None = 0,
  104. /// <summary>
  105. /// Encrypted using PKZIP 2.0 or 'classic' encryption.
  106. /// </summary>
  107. PkzipClassic = 1,
  108. /// <summary>
  109. /// DES encryption has been used.
  110. /// </summary>
  111. Des = 0x6601,
  112. /// <summary>
  113. /// RCS encryption has been used for encryption.
  114. /// </summary>
  115. RC2 = 0x6602,
  116. /// <summary>
  117. /// Triple DES encryption with 168 bit keys has been used for this entry.
  118. /// </summary>
  119. TripleDes168 = 0x6603,
  120. /// <summary>
  121. /// Triple DES with 112 bit keys has been used for this entry.
  122. /// </summary>
  123. TripleDes112 = 0x6609,
  124. /// <summary>
  125. /// AES 128 has been used for encryption.
  126. /// </summary>
  127. Aes128 = 0x660e,
  128. /// <summary>
  129. /// AES 192 has been used for encryption.
  130. /// </summary>
  131. Aes192 = 0x660f,
  132. /// <summary>
  133. /// AES 256 has been used for encryption.
  134. /// </summary>
  135. Aes256 = 0x6610,
  136. /// <summary>
  137. /// RC2 corrected has been used for encryption.
  138. /// </summary>
  139. RC2Corrected = 0x6702,
  140. /// <summary>
  141. /// Blowfish has been used for encryption.
  142. /// </summary>
  143. Blowfish = 0x6720,
  144. /// <summary>
  145. /// Twofish has been used for encryption.
  146. /// </summary>
  147. Twofish = 0x6721,
  148. /// <summary>
  149. /// RC4 has been used for encryption.
  150. /// </summary>
  151. RC4 = 0x6801,
  152. /// <summary>
  153. /// An unknown algorithm has been used for encryption.
  154. /// </summary>
  155. Unknown = 0xffff
  156. }
  157. /// <summary>
  158. /// Defines the contents of the general bit flags field for an archive entry.
  159. /// </summary>
  160. [Flags]
  161. internal enum GeneralBitFlags : int
  162. {
  163. /// <summary>
  164. /// Bit 0 if set indicates that the file is encrypted
  165. /// </summary>
  166. Encrypted = 0x0001,
  167. /// <summary>
  168. /// Bits 1 and 2 - Two bits defining the compression method (only for Method 6 Imploding and 8,9 Deflating)
  169. /// </summary>
  170. Method = 0x0006,
  171. /// <summary>
  172. /// Bit 3 if set indicates a trailing data desciptor is appended to the entry data
  173. /// </summary>
  174. Descriptor = 0x0008,
  175. /// <summary>
  176. /// Bit 4 is reserved for use with method 8 for enhanced deflation
  177. /// </summary>
  178. ReservedPKware4 = 0x0010,
  179. /// <summary>
  180. /// Bit 5 if set indicates the file contains Pkzip compressed patched data.
  181. /// Requires version 2.7 or greater.
  182. /// </summary>
  183. Patched = 0x0020,
  184. /// <summary>
  185. /// Bit 6 if set indicates strong encryption has been used for this entry.
  186. /// </summary>
  187. StrongEncryption = 0x0040,
  188. /// <summary>
  189. /// Bit 7 is currently unused
  190. /// </summary>
  191. Unused7 = 0x0080,
  192. /// <summary>
  193. /// Bit 8 is currently unused
  194. /// </summary>
  195. Unused8 = 0x0100,
  196. /// <summary>
  197. /// Bit 9 is currently unused
  198. /// </summary>
  199. Unused9 = 0x0200,
  200. /// <summary>
  201. /// Bit 10 is currently unused
  202. /// </summary>
  203. Unused10 = 0x0400,
  204. /// <summary>
  205. /// Bit 11 if set indicates the filename and
  206. /// comment fields for this file must be encoded using UTF-8.
  207. /// </summary>
  208. UnicodeText = 0x0800,
  209. /// <summary>
  210. /// Bit 12 is documented as being reserved by PKware for enhanced compression.
  211. /// </summary>
  212. EnhancedCompress = 0x1000,
  213. /// <summary>
  214. /// Bit 13 if set indicates that values in the local header are masked to hide
  215. /// their actual values, and the central directory is encrypted.
  216. /// </summary>
  217. /// <remarks>
  218. /// Used when encrypting the central directory contents.
  219. /// </remarks>
  220. HeaderMasked = 0x2000,
  221. /// <summary>
  222. /// Bit 14 is documented as being reserved for use by PKware
  223. /// </summary>
  224. ReservedPkware14 = 0x4000,
  225. /// <summary>
  226. /// Bit 15 is documented as being reserved for use by PKware
  227. /// </summary>
  228. ReservedPkware15 = 0x8000
  229. }
  230. #endregion
  231. /// <summary>
  232. /// This class contains constants used for Zip format files
  233. /// </summary>
  234. internal sealed class ZipConstants
  235. {
  236. #region Versions
  237. /// <summary>
  238. /// The version made by field for entries in the central header when created by this library
  239. /// </summary>
  240. /// <remarks>
  241. /// This is also the Zip version for the library when comparing against the version required to extract
  242. /// for an entry. See <see cref="ZipEntry.CanDecompress"/>.
  243. /// </remarks>
  244. public const int VersionMadeBy = 51; // was 45 before AES
  245. /// <summary>
  246. /// The version made by field for entries in the central header when created by this library
  247. /// </summary>
  248. /// <remarks>
  249. /// This is also the Zip version for the library when comparing against the version required to extract
  250. /// for an entry. See <see cref="ZipInputStream.CanDecompressEntry">ZipInputStream.CanDecompressEntry</see>.
  251. /// </remarks>
  252. [Obsolete("Use VersionMadeBy instead")]
  253. public const int VERSION_MADE_BY = 51;
  254. /// <summary>
  255. /// The minimum version required to support strong encryption
  256. /// </summary>
  257. public const int VersionStrongEncryption = 50;
  258. /// <summary>
  259. /// The minimum version required to support strong encryption
  260. /// </summary>
  261. [Obsolete("Use VersionStrongEncryption instead")]
  262. public const int VERSION_STRONG_ENCRYPTION = 50;
  263. /// <summary>
  264. /// Version indicating AES encryption
  265. /// </summary>
  266. public const int VERSION_AES = 51;
  267. /// <summary>
  268. /// The version required for Zip64 extensions (4.5 or higher)
  269. /// </summary>
  270. public const int VersionZip64 = 45;
  271. #endregion
  272. #region Header Sizes
  273. /// <summary>
  274. /// Size of local entry header (excluding variable length fields at end)
  275. /// </summary>
  276. public const int LocalHeaderBaseSize = 30;
  277. /// <summary>
  278. /// Size of local entry header (excluding variable length fields at end)
  279. /// </summary>
  280. [Obsolete("Use LocalHeaderBaseSize instead")]
  281. public const int LOCHDR = 30;
  282. /// <summary>
  283. /// Size of Zip64 data descriptor
  284. /// </summary>
  285. public const int Zip64DataDescriptorSize = 24;
  286. /// <summary>
  287. /// Size of data descriptor
  288. /// </summary>
  289. public const int DataDescriptorSize = 16;
  290. /// <summary>
  291. /// Size of data descriptor
  292. /// </summary>
  293. [Obsolete("Use DataDescriptorSize instead")]
  294. public const int EXTHDR = 16;
  295. /// <summary>
  296. /// Size of central header entry (excluding variable fields)
  297. /// </summary>
  298. public const int CentralHeaderBaseSize = 46;
  299. /// <summary>
  300. /// Size of central header entry
  301. /// </summary>
  302. [Obsolete("Use CentralHeaderBaseSize instead")]
  303. public const int CENHDR = 46;
  304. /// <summary>
  305. /// Size of end of central record (excluding variable fields)
  306. /// </summary>
  307. public const int EndOfCentralRecordBaseSize = 22;
  308. /// <summary>
  309. /// Size of end of central record (excluding variable fields)
  310. /// </summary>
  311. [Obsolete("Use EndOfCentralRecordBaseSize instead")]
  312. public const int ENDHDR = 22;
  313. /// <summary>
  314. /// Size of 'classic' cryptographic header stored before any entry data
  315. /// </summary>
  316. public const int CryptoHeaderSize = 12;
  317. /// <summary>
  318. /// Size of cryptographic header stored before entry data
  319. /// </summary>
  320. [Obsolete("Use CryptoHeaderSize instead")]
  321. public const int CRYPTO_HEADER_SIZE = 12;
  322. #endregion
  323. #region Header Signatures
  324. /// <summary>
  325. /// Signature for local entry header
  326. /// </summary>
  327. public const int LocalHeaderSignature = 'P' | ('K' << 8) | (3 << 16) | (4 << 24);
  328. /// <summary>
  329. /// Signature for local entry header
  330. /// </summary>
  331. [Obsolete("Use LocalHeaderSignature instead")]
  332. public const int LOCSIG = 'P' | ('K' << 8) | (3 << 16) | (4 << 24);
  333. /// <summary>
  334. /// Signature for spanning entry
  335. /// </summary>
  336. public const int SpanningSignature = 'P' | ('K' << 8) | (7 << 16) | (8 << 24);
  337. /// <summary>
  338. /// Signature for spanning entry
  339. /// </summary>
  340. [Obsolete("Use SpanningSignature instead")]
  341. public const int SPANNINGSIG = 'P' | ('K' << 8) | (7 << 16) | (8 << 24);
  342. /// <summary>
  343. /// Signature for temporary spanning entry
  344. /// </summary>
  345. public const int SpanningTempSignature = 'P' | ('K' << 8) | ('0' << 16) | ('0' << 24);
  346. /// <summary>
  347. /// Signature for temporary spanning entry
  348. /// </summary>
  349. [Obsolete("Use SpanningTempSignature instead")]
  350. public const int SPANTEMPSIG = 'P' | ('K' << 8) | ('0' << 16) | ('0' << 24);
  351. /// <summary>
  352. /// Signature for data descriptor
  353. /// </summary>
  354. /// <remarks>
  355. /// This is only used where the length, Crc, or compressed size isnt known when the
  356. /// entry is created and the output stream doesnt support seeking.
  357. /// The local entry cannot be 'patched' with the correct values in this case
  358. /// so the values are recorded after the data prefixed by this header, as well as in the central directory.
  359. /// </remarks>
  360. public const int DataDescriptorSignature = 'P' | ('K' << 8) | (7 << 16) | (8 << 24);
  361. /// <summary>
  362. /// Signature for data descriptor
  363. /// </summary>
  364. /// <remarks>
  365. /// This is only used where the length, Crc, or compressed size isnt known when the
  366. /// entry is created and the output stream doesnt support seeking.
  367. /// The local entry cannot be 'patched' with the correct values in this case
  368. /// so the values are recorded after the data prefixed by this header, as well as in the central directory.
  369. /// </remarks>
  370. [Obsolete("Use DataDescriptorSignature instead")]
  371. public const int EXTSIG = 'P' | ('K' << 8) | (7 << 16) | (8 << 24);
  372. /// <summary>
  373. /// Signature for central header
  374. /// </summary>
  375. [Obsolete("Use CentralHeaderSignature instead")]
  376. public const int CENSIG = 'P' | ('K' << 8) | (1 << 16) | (2 << 24);
  377. /// <summary>
  378. /// Signature for central header
  379. /// </summary>
  380. public const int CentralHeaderSignature = 'P' | ('K' << 8) | (1 << 16) | (2 << 24);
  381. /// <summary>
  382. /// Signature for Zip64 central file header
  383. /// </summary>
  384. public const int Zip64CentralFileHeaderSignature = 'P' | ('K' << 8) | (6 << 16) | (6 << 24);
  385. /// <summary>
  386. /// Signature for Zip64 central file header
  387. /// </summary>
  388. [Obsolete("Use Zip64CentralFileHeaderSignature instead")]
  389. public const int CENSIG64 = 'P' | ('K' << 8) | (6 << 16) | (6 << 24);
  390. /// <summary>
  391. /// Signature for Zip64 central directory locator
  392. /// </summary>
  393. public const int Zip64CentralDirLocatorSignature = 'P' | ('K' << 8) | (6 << 16) | (7 << 24);
  394. /// <summary>
  395. /// Signature for archive extra data signature (were headers are encrypted).
  396. /// </summary>
  397. public const int ArchiveExtraDataSignature = 'P' | ('K' << 8) | (6 << 16) | (7 << 24);
  398. /// <summary>
  399. /// Central header digitial signature
  400. /// </summary>
  401. public const int CentralHeaderDigitalSignature = 'P' | ('K' << 8) | (5 << 16) | (5 << 24);
  402. /// <summary>
  403. /// Central header digitial signature
  404. /// </summary>
  405. [Obsolete("Use CentralHeaderDigitalSignaure instead")]
  406. public const int CENDIGITALSIG = 'P' | ('K' << 8) | (5 << 16) | (5 << 24);
  407. /// <summary>
  408. /// End of central directory record signature
  409. /// </summary>
  410. public const int EndOfCentralDirectorySignature = 'P' | ('K' << 8) | (5 << 16) | (6 << 24);
  411. /// <summary>
  412. /// End of central directory record signature
  413. /// </summary>
  414. [Obsolete("Use EndOfCentralDirectorySignature instead")]
  415. public const int ENDSIG = 'P' | ('K' << 8) | (5 << 16) | (6 << 24);
  416. #endregion
  417. #if NETCF_1_0 || NETCF_2_0
  418. // This isnt so great but is better than nothing.
  419. // Trying to work out an appropriate OEM code page would be good.
  420. // 850 is a good default for english speakers particularly in Europe.
  421. // static int defaultCodePage = CultureInfo.CurrentCulture.TextInfo.ANSICodePage;
  422. #else
  423. // static int defaultCodePage = Thread.CurrentThread.CurrentCulture.TextInfo.OEMCodePage;
  424. #endif
  425. // /// <summary>
  426. // /// Default encoding used for string conversion. 0 gives the default system OEM code page.
  427. // /// Dont use unicode encodings if you want to be Zip compatible!
  428. // /// Using the default code page isnt the full solution neccessarily
  429. // /// there are many variable factors, codepage 850 is often a good choice for
  430. // /// European users, however be careful about compatability.
  431. // /// </summary>
  432. // public static int DefaultCodePage
  433. // {
  434. // get { return defaultCodePage; }
  435. // set { defaultCodePage = value; }
  436. // }
  437. /// <summary>
  438. /// Convert a portion of a byte array to a string.
  439. /// </summary>
  440. /// <param name="data">
  441. /// Data to convert to string
  442. /// </param>
  443. /// <param name="count">
  444. /// Number of bytes to convert starting from index 0
  445. /// </param>
  446. /// <returns>
  447. /// data[0]..data[length - 1] converted to a string
  448. /// </returns>
  449. public static string ConvertToString(byte[] data, int count)
  450. {
  451. if (data == null)
  452. {
  453. return string.Empty;
  454. }
  455. // return Encoding.GetEncoding(DefaultCodePage).GetString(data, 0, count);
  456. return Fixed.GetEncoding(data).GetString(data, 0, count);
  457. }
  458. /// <summary>
  459. /// Convert a byte array to string
  460. /// </summary>
  461. /// <param name="data">
  462. /// Byte array to convert
  463. /// </param>
  464. /// <returns>
  465. /// <paramref name="data">data</paramref>converted to a string
  466. /// </returns>
  467. public static string ConvertToString(byte[] data)
  468. {
  469. if (data == null)
  470. {
  471. return string.Empty;
  472. }
  473. return ConvertToString(data, data.Length);
  474. }
  475. /// <summary>
  476. /// Convert a byte array to string
  477. /// </summary>
  478. /// <param name="flags">The applicable general purpose bits flags</param>
  479. /// <param name="data">
  480. /// Byte array to convert
  481. /// </param>
  482. /// <param name="count">The number of bytes to convert.</param>
  483. /// <returns>
  484. /// <paramref name="data">data</paramref>converted to a string
  485. /// </returns>
  486. public static string ConvertToStringExt(int flags, byte[] data, int count)
  487. {
  488. if (data == null)
  489. {
  490. return string.Empty;
  491. }
  492. if ((flags & (int)GeneralBitFlags.UnicodeText) != 0)
  493. {
  494. return Encoding.UTF8.GetString(data, 0, count);
  495. }
  496. else
  497. {
  498. return ConvertToString(data, count);
  499. }
  500. }
  501. /// <summary>
  502. /// Convert a byte array to string
  503. /// </summary>
  504. /// <param name="data">
  505. /// Byte array to convert
  506. /// </param>
  507. /// <param name="flags">The applicable general purpose bits flags</param>
  508. /// <returns>
  509. /// <paramref name="data">data</paramref>converted to a string
  510. /// </returns>
  511. public static string ConvertToStringExt(int flags, byte[] data)
  512. {
  513. if (data == null)
  514. {
  515. return string.Empty;
  516. }
  517. if ((flags & (int)GeneralBitFlags.UnicodeText) != 0)
  518. {
  519. return Encoding.UTF8.GetString(data, 0, data.Length);
  520. }
  521. else
  522. {
  523. return ConvertToString(data, data.Length);
  524. }
  525. }
  526. /// <summary>
  527. /// Convert a string to a byte array
  528. /// </summary>
  529. /// <param name="str">
  530. /// String to convert to an array
  531. /// </param>
  532. /// <returns>Converted array</returns>
  533. public static byte[] ConvertToArray(string str)
  534. {
  535. if (str == null)
  536. {
  537. return new byte[0];
  538. }
  539. // return Encoding.GetEncoding(DefaultCodePage).GetBytes(str);
  540. return Fixed.GetEncoding().GetBytes(str);
  541. }
  542. /// <summary>
  543. /// Convert a string to a byte array
  544. /// </summary>
  545. /// <param name="flags">The applicable <see cref="GeneralBitFlags">general purpose bits flags</see></param>
  546. /// <param name="str">
  547. /// String to convert to an array
  548. /// </param>
  549. /// <returns>Converted array</returns>
  550. public static byte[] ConvertToArray(int flags, string str)
  551. {
  552. if (str == null)
  553. {
  554. return new byte[0];
  555. }
  556. if ((flags & (int)GeneralBitFlags.UnicodeText) != 0)
  557. {
  558. return Encoding.UTF8.GetBytes(str);
  559. }
  560. else
  561. {
  562. return ConvertToArray(str);
  563. }
  564. }
  565. /// <summary>
  566. /// Initialise default instance of <see cref="ZipConstants">ZipConstants</see>
  567. /// </summary>
  568. /// <remarks>
  569. /// Private to prevent instances being created.
  570. /// </remarks>
  571. ZipConstants()
  572. {
  573. // Do nothing
  574. }
  575. }
  576. }