123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254 |
- using System;
- using System.IO;
- namespace CommonMPQ.SharpZipLib.Zip
- {
-
-
-
- public enum HostSystemID
- {
-
-
-
- Msdos = 0,
-
-
-
- Amiga = 1,
-
-
-
- OpenVms = 2,
-
-
-
- Unix = 3,
-
-
-
- VMCms = 4,
-
-
-
- AtariST = 5,
-
-
-
- OS2 = 6,
-
-
-
- Macintosh = 7,
-
-
-
- ZSystem = 8,
-
-
-
- Cpm = 9,
-
-
-
- WindowsNT = 10,
-
-
-
- MVS = 11,
-
-
-
- Vse = 12,
-
-
-
- AcornRisc = 13,
-
-
-
- Vfat = 14,
-
-
-
- AlternateMvs = 15,
-
-
-
- BeOS = 16,
-
-
-
- Tandem = 17,
-
-
-
- OS400 = 18,
-
-
-
- OSX = 19,
-
-
-
- WinZipAES = 99,
- }
-
-
-
-
-
-
-
-
-
-
- public class ZipEntry : ICloneable
- {
- [Flags]
- enum Known : byte
- {
- None = 0,
- Size = 0x01,
- CompressedSize = 0x02,
- Crc = 0x04,
- Time = 0x08,
- ExternalAttributes = 0x10,
- }
-
- #region Constructors
-
-
-
-
-
-
-
-
-
-
-
- public ZipEntry(string name)
- : this(name, 0, ZipConstants.VersionMadeBy, CompressionMethod.Deflated)
- {
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- internal ZipEntry(string name, int versionRequiredToExtract)
- : this(name, versionRequiredToExtract, ZipConstants.VersionMadeBy,
- CompressionMethod.Deflated)
- {
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- internal ZipEntry(string name, int versionRequiredToExtract, int madeByInfo,
- CompressionMethod method)
- {
- if (name == null) {
- throw new ArgumentNullException("name");
- }
- if ( name.Length > 0xffff ) {
- throw new ArgumentException("Name is too long", "name");
- }
- if ( (versionRequiredToExtract != 0) && (versionRequiredToExtract < 10) ) {
- throw new ArgumentOutOfRangeException("versionRequiredToExtract");
- }
-
- this.DateTime = DateTime.Now;
- this.name = CleanName(name);
- this.versionMadeBy = (ushort)madeByInfo;
- this.versionToExtract = (ushort)versionRequiredToExtract;
- this.method = method;
- }
-
-
-
-
-
-
-
- [Obsolete("Use Clone instead")]
- public ZipEntry(ZipEntry entry)
- {
- if ( entry == null ) {
- throw new ArgumentNullException("entry");
- }
- known = entry.known;
- name = entry.name;
- size = entry.size;
- compressedSize = entry.compressedSize;
- crc = entry.crc;
- dosTime = entry.dosTime;
- method = entry.method;
- comment = entry.comment;
- versionToExtract = entry.versionToExtract;
- versionMadeBy = entry.versionMadeBy;
- externalFileAttributes = entry.externalFileAttributes;
- flags = entry.flags;
- zipFileIndex = entry.zipFileIndex;
- offset = entry.offset;
- forceZip64_ = entry.forceZip64_;
- if ( entry.extra != null ) {
- extra = new byte[entry.extra.Length];
- Array.Copy(entry.extra, 0, extra, 0, entry.extra.Length);
- }
- }
- #endregion
-
-
-
-
- public bool HasCrc
- {
- get {
- return (known & Known.Crc) != 0;
- }
- }
-
-
-
-
-
- public bool IsCrypted
- {
- get {
- return (flags & 1) != 0;
- }
- set {
- if (value) {
- flags |= 1;
- }
- else {
- flags &= ~1;
- }
- }
- }
-
-
-
-
-
- public bool IsUnicodeText
- {
- get {
- return ( flags & (int)GeneralBitFlags.UnicodeText ) != 0;
- }
- set {
- if ( value ) {
- flags |= (int)GeneralBitFlags.UnicodeText;
- }
- else {
- flags &= ~(int)GeneralBitFlags.UnicodeText;
- }
- }
- }
-
-
-
-
- internal byte CryptoCheckValue
- {
- get {
- return cryptoCheckValue_;
- }
- set {
- cryptoCheckValue_ = value;
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public int Flags
- {
- get {
- return flags;
- }
- set {
- flags = value;
- }
- }
-
-
-
-
- public long ZipFileIndex
- {
- get {
- return zipFileIndex;
- }
- set {
- zipFileIndex = value;
- }
- }
-
-
-
-
- public long Offset
- {
- get {
- return offset;
- }
- set {
- offset = value;
- }
- }
-
-
-
-
-
- public int ExternalFileAttributes
- {
- get {
- if ((known & Known.ExternalAttributes) == 0) {
- return -1;
- }
- else {
- return externalFileAttributes;
- }
- }
-
- set {
- externalFileAttributes = value;
- known |= Known.ExternalAttributes;
- }
- }
-
-
-
-
-
- public int VersionMadeBy
- {
- get {
- return (versionMadeBy & 0xff);
- }
- }
-
-
-
- public bool IsDOSEntry
- {
- get {
- return ((HostSystem == ( int )HostSystemID.Msdos) ||
- (HostSystem == ( int )HostSystemID.WindowsNT));
- }
- }
-
-
-
-
-
-
-
-
- bool HasDosAttributes(int attributes)
- {
- bool result = false;
- if ( (known & Known.ExternalAttributes) != 0 ) {
- if ( ((HostSystem == (int)HostSystemID.Msdos) ||
- (HostSystem == (int)HostSystemID.WindowsNT)) &&
- (ExternalFileAttributes & attributes) == attributes) {
- result = true;
- }
- }
- return result;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public int HostSystem
- {
- get {
- return (versionMadeBy >> 8) & 0xff;
- }
- set {
- versionMadeBy &= 0xff;
- versionMadeBy |= (ushort)((value & 0xff) << 8);
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public int Version
- {
- get {
-
- if (versionToExtract != 0) {
- return versionToExtract & 0x00ff;
- }
- else {
- int result = 10;
- if (AESKeySize > 0) {
- result = ZipConstants.VERSION_AES;
- }
- else if (CentralHeaderRequiresZip64) {
- result = ZipConstants.VersionZip64;
- }
- else if (CompressionMethod.Deflated == method) {
- result = 20;
- }
- else if (IsDirectory == true) {
- result = 20;
- }
- else if (IsCrypted == true) {
- result = 20;
- }
- else if (HasDosAttributes(0x08) ) {
- result = 11;
- }
- return result;
- }
- }
- }
-
-
-
-
-
- public bool CanDecompress
- {
- get {
- return (Version <= ZipConstants.VersionMadeBy) &&
- ((Version == 10) ||
- (Version == 11) ||
- (Version == 20) ||
- (Version == 45) ||
- (Version == 51)) &&
- IsCompressionMethodSupported();
- }
- }
-
-
-
- public void ForceZip64()
- {
- forceZip64_ = true;
- }
-
-
-
-
-
- public bool IsZip64Forced()
- {
- return forceZip64_;
- }
-
-
-
-
-
- public bool LocalHeaderRequiresZip64
- {
- get {
- bool result = forceZip64_;
- if ( !result ) {
- ulong trueCompressedSize = compressedSize;
- if ( (versionToExtract == 0) && IsCrypted ) {
- trueCompressedSize += ZipConstants.CryptoHeaderSize;
- }
-
-
- result =
- ((this.size >= uint.MaxValue) || (trueCompressedSize >= uint.MaxValue)) &&
- ((versionToExtract == 0) || (versionToExtract >= ZipConstants.VersionZip64));
- }
- return result;
- }
- }
-
-
-
-
- public bool CentralHeaderRequiresZip64
- {
- get {
- return LocalHeaderRequiresZip64 || (offset >= uint.MaxValue);
- }
- }
-
-
-
-
-
-
-
- public long DosTime
- {
- get {
- if ((known & Known.Time) == 0) {
- return 0;
- }
- else {
- return dosTime;
- }
- }
-
- set {
- unchecked {
- dosTime = (uint)value;
- }
- known |= Known.Time;
- }
- }
-
-
-
-
-
-
-
- public DateTime DateTime
- {
- get {
- uint sec = Math.Min(59, 2 * (dosTime & 0x1f));
- uint min = Math.Min(59, (dosTime >> 5) & 0x3f);
- uint hrs = Math.Min(23, (dosTime >> 11) & 0x1f);
- uint mon = Math.Max(1, Math.Min(12, ((dosTime >> 21) & 0xf)));
- uint year = ((dosTime >> 25) & 0x7f) + 1980;
- int day = Math.Max(1, Math.Min(DateTime.DaysInMonth((int)year, (int)mon), (int)((dosTime >> 16) & 0x1f)));
- return new System.DateTime((int)year, (int)mon, day, (int)hrs, (int)min, (int)sec);
- }
- set {
- uint year = (uint) value.Year;
- uint month = (uint) value.Month;
- uint day = (uint) value.Day;
- uint hour = (uint) value.Hour;
- uint minute = (uint) value.Minute;
- uint second = (uint) value.Second;
-
- if ( year < 1980 ) {
- year = 1980;
- month = 1;
- day = 1;
- hour = 0;
- minute = 0;
- second = 0;
- }
- else if ( year > 2107 ) {
- year = 2107;
- month = 12;
- day = 31;
- hour = 23;
- minute = 59;
- second = 59;
- }
-
- DosTime = ((year - 1980) & 0x7f) << 25 |
- (month << 21) |
- (day << 16) |
- (hour << 11) |
- (minute << 5) |
- (second >> 1);
- }
- }
-
-
-
-
-
-
-
-
-
-
- public string Name
- {
- get {
- return name;
- }
- }
-
-
-
-
-
-
-
-
-
- public long Size
- {
- get {
- return (known & Known.Size) != 0 ? (long)size : -1L;
- }
- set {
- this.size = (ulong)value;
- this.known |= Known.Size;
- }
- }
-
-
-
-
-
-
-
- public long CompressedSize
- {
- get {
- return (known & Known.CompressedSize) != 0 ? (long)compressedSize : -1L;
- }
- set {
- this.compressedSize = (ulong)value;
- this.known |= Known.CompressedSize;
- }
- }
-
-
-
-
-
-
-
-
-
- public long Crc
- {
- get {
- return (known & Known.Crc) != 0 ? crc & 0xffffffffL : -1L;
- }
- set {
- if (((ulong)crc & 0xffffffff00000000L) != 0) {
- throw new ArgumentOutOfRangeException("value");
- }
- this.crc = (uint)value;
- this.known |= Known.Crc;
- }
- }
-
-
-
-
-
-
-
-
-
- public CompressionMethod CompressionMethod {
- get {
- return method;
- }
- set {
- if ( !IsCompressionMethodSupported(value) ) {
- throw new NotSupportedException("Compression method not supported");
- }
- this.method = value;
- }
- }
-
-
-
-
-
- internal CompressionMethod CompressionMethodForHeader {
- get {
- return (AESKeySize > 0) ? CompressionMethod.WinZipAES : method;
- }
- }
-
-
-
-
-
-
-
-
-
- public byte[] ExtraData {
-
- get {
- return extra;
- }
- set {
- if (value == null) {
- extra = null;
- }
- else {
- if (value.Length > 0xffff) {
- throw new System.ArgumentOutOfRangeException("value");
- }
-
- extra = new byte[value.Length];
- Array.Copy(value, 0, extra, 0, value.Length);
- }
- }
- }
- #if !NET_1_1 && !NETCF_2_0
-
-
-
-
- public int AESKeySize {
- get {
-
- switch (_aesEncryptionStrength) {
- case 0: return 0;
- case 1: return 128;
- case 2: return 192;
- case 3: return 256;
- default: throw new ZipException("Invalid AESEncryptionStrength " + _aesEncryptionStrength);
- }
- }
- set {
- switch (value) {
- case 0: _aesEncryptionStrength = 0; break;
- case 128: _aesEncryptionStrength = 1; break;
- case 256: _aesEncryptionStrength = 3; break;
- default: throw new ZipException("AESKeySize must be 0, 128 or 256: " + value);
- }
- }
- }
-
-
-
-
- internal byte AESEncryptionStrength {
- get {
- return (byte)_aesEncryptionStrength;
- }
- }
- #else
-
-
-
- internal int AESKeySize;
- #endif
-
-
-
- internal int AESSaltLen {
- get {
-
- return AESKeySize / 16;
- }
- }
-
-
-
- internal int AESOverheadSize {
- get {
-
-
-
-
-
-
- return 12 + AESSaltLen;
- }
- }
-
-
-
-
-
-
- internal void ProcessExtraData(bool localHeader)
- {
- ZipExtraData extraData = new ZipExtraData(this.extra);
- if ( extraData.Find(0x0001) ) {
-
-
-
- forceZip64_ = true;
- if ( extraData.ValueLength < 4 ) {
- throw new ZipException("Extra data extended Zip64 information length is invalid");
- }
- if ( localHeader || (size == uint.MaxValue) ) {
- size = (ulong)extraData.ReadLong();
- }
- if ( localHeader || (compressedSize == uint.MaxValue) ) {
- compressedSize = (ulong)extraData.ReadLong();
- }
- if ( !localHeader && (offset == uint.MaxValue) ) {
- offset = extraData.ReadLong();
- }
-
- }
- else {
- if (
- ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) &&
- ((size == uint.MaxValue) || (compressedSize == uint.MaxValue))
- ) {
- throw new ZipException("Zip64 Extended information required but is missing.");
- }
- }
- if ( extraData.Find(10) ) {
-
- if ( extraData.ValueLength < 4 ) {
- throw new ZipException("NTFS Extra data invalid");
- }
- extraData.ReadInt();
- while ( extraData.UnreadCount >= 4 ) {
- int ntfsTag = extraData.ReadShort();
- int ntfsLength = extraData.ReadShort();
- if ( ntfsTag == 1 ) {
- if ( ntfsLength >= 24 ) {
- long lastModification = extraData.ReadLong();
- long lastAccess = extraData.ReadLong();
- long createTime = extraData.ReadLong();
- DateTime = System.DateTime.FromFileTime(lastModification);
- }
- break;
- }
- else {
-
- extraData.Skip(ntfsLength);
- }
- }
- }
- else if ( extraData.Find(0x5455) ) {
- int length = extraData.ValueLength;
- int flags = extraData.ReadByte();
-
-
-
- if ( ((flags & 1) != 0) && (length >= 5) ) {
- int iTime = extraData.ReadInt();
- DateTime = (new System.DateTime ( 1970, 1, 1, 0, 0, 0 ).ToUniversalTime() +
- new TimeSpan ( 0, 0, 0, iTime, 0 )).ToLocalTime();
- }
- }
- if (method == CompressionMethod.WinZipAES) {
- ProcessAESExtraData(extraData);
- }
- }
-
-
- private void ProcessAESExtraData(ZipExtraData extraData) {
- #if !NET_1_1 && !NETCF_2_0
- if (extraData.Find(0x9901)) {
-
- versionToExtract = ZipConstants.VERSION_AES;
-
- Flags = Flags | (int)GeneralBitFlags.StrongEncryption;
-
-
- int length = extraData.ValueLength;
- if (length < 7)
- throw new ZipException("AES Extra Data Length " + length + " invalid.");
- int ver = extraData.ReadShort();
- int vendorId = extraData.ReadShort();
- int encrStrength = extraData.ReadByte();
- int actualCompress = extraData.ReadShort();
- _aesVer = ver;
- _aesEncryptionStrength = encrStrength;
- method = (CompressionMethod)actualCompress;
- } else
- throw new ZipException("AES Extra Data missing");
- #else
- throw new ZipException("AES unsupported");
- #endif
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
- public string Comment {
- get {
- return comment;
- }
- set {
-
-
-
-
-
-
-
- if ( (value != null) && (value.Length > 0xffff) ) {
- #if NETCF_1_0
- throw new ArgumentOutOfRangeException("value");
- #else
- throw new ArgumentOutOfRangeException("value", "cannot exceed 65535");
- #endif
- }
-
- comment = value;
- }
- }
-
-
-
-
-
-
-
-
-
-
-
- public bool IsDirectory
- {
- get {
- int nameLength = name.Length;
- bool result =
- ((nameLength > 0) &&
- ((name[nameLength - 1] == '/') || (name[nameLength - 1] == '\\'))) ||
- HasDosAttributes(16)
- ;
- return result;
- }
- }
-
-
-
-
-
-
-
-
- public bool IsFile
- {
- get {
- return !IsDirectory && !HasDosAttributes(8);
- }
- }
-
-
-
-
-
- public bool IsCompressionMethodSupported()
- {
- return IsCompressionMethodSupported(CompressionMethod);
- }
-
- #region ICloneable Members
-
-
-
-
- public object Clone()
- {
- ZipEntry result = (ZipEntry)this.MemberwiseClone();
-
- if ( extra != null ) {
- result.extra = new byte[extra.Length];
- Array.Copy(extra, 0, result.extra, 0, extra.Length);
- }
- return result;
- }
-
- #endregion
-
-
-
-
- public override string ToString()
- {
- return name;
- }
-
-
-
-
-
-
- public static bool IsCompressionMethodSupported(CompressionMethod method)
- {
- return
- ( method == CompressionMethod.Deflated ) ||
- ( method == CompressionMethod.Stored );
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
- public static string CleanName(string name)
- {
- if (name == null) {
- return string.Empty;
- }
-
- if (Path.IsPathRooted(name)) {
-
-
- name = name.Substring(Path.GetPathRoot(name).Length);
- }
- name = name.Replace(@"\", "/");
-
- while ( (name.Length > 0) && (name[0] == '/')) {
- name = name.Remove(0, 1);
- }
- return name;
- }
- #region Instance Fields
- Known known;
- int externalFileAttributes = -1;
-
- ushort versionMadeBy;
-
-
- string name;
- ulong size;
- ulong compressedSize;
- ushort versionToExtract;
- uint crc;
- uint dosTime;
-
- CompressionMethod method = CompressionMethod.Deflated;
- byte[] extra;
- string comment;
-
- int flags;
- long zipFileIndex = -1;
- long offset;
-
- bool forceZip64_;
- byte cryptoCheckValue_;
- #if !NET_1_1 && !NETCF_2_0
- int _aesVer;
- int _aesEncryptionStrength;
- #endif
- #endregion
- }
- }
|