You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
389 lines
16 KiB
C++
389 lines
16 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
|
|
|
#ifndef CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPFILEFORMAT_H
|
|
#define CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPFILEFORMAT_H
|
|
#pragma once
|
|
|
|
#include <platform.h>
|
|
#include <ZipDir/ZipDir_Traits_Platform.h>
|
|
|
|
#if AZ_TRAIT_CRYCOMMONTOOLS_PACK_1
|
|
#pragma pack(push)
|
|
#pragma pack(1)
|
|
#define PACK_GCC
|
|
#else
|
|
#define PACK_GCC __PACKED
|
|
#endif
|
|
|
|
namespace ZipFile
|
|
{
|
|
typedef unsigned int ulong;
|
|
typedef unsigned short ushort;
|
|
|
|
// General-purpose bit field flags
|
|
enum
|
|
{
|
|
GPF_ENCRYPTED = 1 << 0, // If set, indicates that the file is encrypted.
|
|
GPF_DATA_DESCRIPTOR = 1 << 3, // if set, the CRC32 and sizes aren't set in the file header, but only in the data descriptor following compressed data
|
|
GPF_RESERVED_8_ENHANCED_DEFLATING = 1 << 4, // Reserved for use with method 8, for enhanced deflating.
|
|
GPF_COMPRESSED_PATCHED = 1 << 5, // the file is compressed patched data
|
|
};
|
|
|
|
// compression methods
|
|
enum
|
|
{
|
|
METHOD_STORE = 0, // The file is stored (no compression)
|
|
METHOD_SHRINK = 1, // The file is Shrunk
|
|
METHOD_REDUCE_1 = 2, // The file is Reduced with compression factor 1
|
|
METHOD_REDUCE_2 = 3, // The file is Reduced with compression factor 2
|
|
METHOD_REDUCE_3 = 4, // The file is Reduced with compression factor 3
|
|
METHOD_REDUCE_4 = 5, // The file is Reduced with compression factor 4
|
|
METHOD_IMPLODE = 6, // The file is Imploded
|
|
METHOD_TOKENIZE = 7, // Reserved for Tokenizing compression algorithm
|
|
METHOD_DEFLATE = 8, // The file is Deflated
|
|
METHOD_DEFLATE64 = 9, // Enhanced Deflating using Deflate64(tm)
|
|
METHOD_IMPLODE_PKWARE = 10, // PKWARE Date Compression Library Imploding
|
|
METHOD_DEFLATE_AND_ENCRYPT = 11 // Deflate + Custom encryption
|
|
};
|
|
|
|
// version numbers
|
|
enum
|
|
{
|
|
VERSION_DEFAULT = 10, // Default value
|
|
|
|
VERSION_TYPE_VOLUMELABEL = 11, // File is a volume label
|
|
VERSION_TYPE_FOLDER = 20, // File is a folder (directory)
|
|
VERSION_TYPE_PATCHDATASET = 27, // File is a patch data set
|
|
VERSION_TYPE_ZIP64 = 45, // File uses ZIP64 format extensions
|
|
|
|
VERSION_COMPRESSION_DEFLATE = 20, // File is compressed using Deflate compression
|
|
VERSION_COMPRESSION_DEFLATE64 = 21, // File is compressed using Deflate64(tm)
|
|
VERSION_COMPRESSION_DCLIMPLODE = 25, // File is compressed using PKWARE DCL Implode
|
|
VERSION_COMPRESSION_BZIP2 = 46, // File is compressed using BZIP2 compression*
|
|
VERSION_COMPRESSION_LZMA = 63, // File is compressed using LZMA
|
|
VERSION_COMPRESSION_PPMD = 63, // File is compressed using PPMd+
|
|
|
|
VERSION_ENCRYPTION_PKWARE = 20, // File is encrypted using traditional PKWARE encryption
|
|
VERSION_ENCRYPTION_DES = 50, // File is encrypted using DES
|
|
VERSION_ENCRYPTION_3DES = 50, // File is encrypted using 3DES
|
|
VERSION_ENCRYPTION_RC2 = 50, // File is encrypted using original RC2 encryption
|
|
VERSION_ENCRYPTION_RC4 = 50, // File is encrypted using RC4 encryption
|
|
VERSION_ENCRYPTION_AES = 51, // File is encrypted using AES encryption
|
|
VERSION_ENCRYPTION_RC2C = 51, // File is encrypted using corrected RC2 encryption**
|
|
VERSION_ENCRYPTION_RC4C = 52, // File is encrypted using corrected RC2-64 encryption**
|
|
VERSION_ENCRYPTION_NOOAEP = 61, // File is encrypted using non-OAEP key wrapping***
|
|
VERSION_ENCRYPTION_CDR = 62, // Central directory encryption
|
|
VERSION_ENCRYPTION_BLOWFISH = 63, // File is encrypted using Blowfish
|
|
VERSION_ENCRYPTION_TWOFISH = 63, // File is encrypted using Twofish
|
|
};
|
|
|
|
// creator numbers
|
|
enum
|
|
{
|
|
CREATOR_MSDOS = 0, // MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems)
|
|
CREATOR_AMIGA = 1, // Amiga
|
|
CREATOR_OpenVMS = 2, // OpenVMS
|
|
CREATOR_UNIX = 3, // UNIX
|
|
CREATOR_VM = 4, // VM/CMS
|
|
CREATOR_ATARI = 5, // Atari ST
|
|
CREATOR_OS2 = 6, // OS/2 H.P.F.S.
|
|
CREATOR_MACINTOSH = 7, // Macintosh
|
|
CREATOR_ZSYSTEM = 8, // Z-System
|
|
CREATOR_CPM = 9, // CP/M
|
|
CREATOR_WINDOWS = 10, // Windows NTFS
|
|
CREATOR_MVS = 11, // MVS (OS/390 - Z/OS)
|
|
CREATOR_VSE = 12, // VSE
|
|
CREATOR_ACORN = 13, // Acorn Risc
|
|
CREATOR_VFAT = 14, // VFAT
|
|
CREATOR_AMVS = 15, // alternate MVS
|
|
CREATOR_BEOS = 16, // BeOS
|
|
CREATOR_TANDEM = 17, // Tandem
|
|
CREATOR_OS400 = 18, // OS/400
|
|
CREATOR_OSX = 19, // OS X (Darwin)
|
|
|
|
CREATOR_UNUSED = 20, // 20 thru 255 - unused
|
|
};
|
|
|
|
enum
|
|
{
|
|
ZIP64_SEE_EXTENSION = -1 // If an archive is in ZIP64 format
|
|
// and a value in a field is 0xFFFFFFFF (or 0xFFFF), the size will be
|
|
// in the corresponding 8 byte (or 4 byte) ZIP64 extended information.
|
|
};
|
|
|
|
// end of Central Directory Record
|
|
// followed by the .zip file comment (variable size, can be empty, obtained from nCommentLength)
|
|
struct CDREnd
|
|
{
|
|
enum
|
|
{
|
|
SIGNATURE = 0x06054b50
|
|
};
|
|
ulong lSignature; // end of central dir signature 4 bytes (0x06054b50)
|
|
ushort nDisk; // number of this disk 2 bytes
|
|
ushort nCDRStartDisk; // number of the disk with the start of the central directory 2 bytes
|
|
ushort numEntriesOnDisk; // total number of entries in the central directory on this disk 2 bytes
|
|
ushort numEntriesTotal; // total number of entries in the central directory 2 bytes
|
|
ulong lCDRSize; // size of the central directory 4 bytes
|
|
ulong lCDROffset; // offset of start of central directory with respect to the starting disk number 4 bytes
|
|
ushort nCommentLength; // .ZIP file comment length 2 bytes
|
|
|
|
AUTO_STRUCT_INFO
|
|
|
|
// .ZIP file comment (variable size, can be empty) follows
|
|
} PACK_GCC;
|
|
|
|
// end of Central Directory Record
|
|
// followed by the zip64 extensible data sector (variable size, can be empty, obtained from nExtDataLength)
|
|
struct CDREnd_ZIP64
|
|
{
|
|
enum
|
|
{
|
|
SIGNATURE = 0x06064b50
|
|
};
|
|
ulong lSignature; // end of central dir signature 4 bytes (0x06064b50)
|
|
uint64 nExtDataLength; // The value stored into the "size of zip64 end of central directory record" should be the size of the remaining record and should not include the leading 12 bytes. 8 bytes
|
|
ushort nVersionMadeBy; // version made by 2 bytes
|
|
ushort nVersionNeeded; // version needed to extract 2 bytes
|
|
ulong nDisk; // number of this disk 4 bytes
|
|
ulong nCDRStartDisk; // number of the disk with the start of the central directory 4 bytes
|
|
uint64 numEntriesOnDisk; // total number of entries in the central directory on this disk 8 bytes
|
|
uint64 numEntriesTotal; // total number of entries in the central directory 8 bytes
|
|
uint64 lCDRSize; // size of the central directory 8 bytes
|
|
uint64 lCDROffset; // offset of start of central directory with respect to the starting disk number 8 bytes
|
|
|
|
AUTO_STRUCT_INFO
|
|
|
|
// zip64 extensible data sector (variable size, can be empty) follows
|
|
} PACK_GCC;
|
|
|
|
// end of Central Directory Locator
|
|
struct CDRLocator_ZIP64
|
|
{
|
|
enum
|
|
{
|
|
SIGNATURE = 0x07064b50
|
|
};
|
|
ulong lSignature; // end of central loc signature 4 bytes (0x07064b50)
|
|
ulong nCDR64StartDisk; // number of the disk with the start of the zip64 end of central directory 4 bytes
|
|
uint64 lCDR64EndOffset; // relative offset of the zip64 end of central directory record 8 bytes
|
|
ulong nDisks; // number of disks 4 bytes
|
|
|
|
AUTO_STRUCT_INFO
|
|
} PACK_GCC;
|
|
|
|
// This descriptor exists only if bit 3 of the general
|
|
// purpose bit flag is set (see below). It is byte aligned
|
|
// and immediately follows the last byte of compressed data.
|
|
// This descriptor is used only when it was not possible to
|
|
// seek in the output .ZIP file, e.g., when the output .ZIP file
|
|
// was standard output or a non seekable device. For Zip64 format
|
|
// archives, the compressed and uncompressed sizes are 8 bytes each.
|
|
struct DataDescriptor
|
|
{
|
|
ulong lCRC32; // crc-32 4 bytes
|
|
ulong lSizeCompressed; // compressed size 4 bytes
|
|
ulong lSizeUncompressed; // uncompressed size 4 bytes
|
|
|
|
bool operator == (const DataDescriptor& d) const
|
|
{
|
|
return lCRC32 == d.lCRC32 && lSizeCompressed == d.lSizeCompressed && lSizeUncompressed == d.lSizeUncompressed;
|
|
}
|
|
bool operator != (const DataDescriptor& d) const
|
|
{
|
|
return lCRC32 != d.lCRC32 || lSizeCompressed != d.lSizeCompressed || lSizeUncompressed != d.lSizeUncompressed;
|
|
}
|
|
|
|
bool IsZIP64([[maybe_unused]] const DataDescriptor& d) const
|
|
{
|
|
return lSizeCompressed == (ulong)ZIP64_SEE_EXTENSION || lSizeUncompressed == (ulong)ZIP64_SEE_EXTENSION;
|
|
}
|
|
|
|
AUTO_STRUCT_INFO
|
|
} PACK_GCC;
|
|
|
|
// When compressing files, compressed and uncompressed sizes
|
|
// should be stored in ZIP64 format (as 8 byte values) when a
|
|
// file's size exceeds 0xFFFFFFFF. However ZIP64 format may be
|
|
// used regardless of the size of a file. When extracting, if
|
|
// the zip64 extended information extra field is present for
|
|
// the file the compressed and uncompressed sizes will be 8
|
|
// byte values.
|
|
struct DataDescriptor_ZIP64
|
|
{
|
|
ulong lCRC32; // crc-32 4 bytes
|
|
uint64 lSizeCompressed; // compressed size 8 bytes
|
|
uint64 lSizeUncompressed; // uncompressed size 8 bytes
|
|
|
|
bool operator == (const DataDescriptor& d) const
|
|
{
|
|
return lCRC32 == d.lCRC32 && lSizeCompressed == d.lSizeCompressed && lSizeUncompressed == d.lSizeUncompressed;
|
|
}
|
|
bool operator != (const DataDescriptor& d) const
|
|
{
|
|
return lCRC32 != d.lCRC32 || lSizeCompressed != d.lSizeCompressed || lSizeUncompressed != d.lSizeUncompressed;
|
|
}
|
|
|
|
AUTO_STRUCT_INFO
|
|
} PACK_GCC;
|
|
|
|
// the File Header as it appears in the CDR
|
|
// followed by:
|
|
// file name (variable size)
|
|
// extra field (variable size)
|
|
// file comment (variable size)
|
|
struct CDRFileHeader
|
|
{
|
|
enum
|
|
{
|
|
SIGNATURE = 0x02014b50
|
|
};
|
|
ulong lSignature; // central file header signature 4 bytes (0x02014b50)
|
|
ushort nVersionMadeBy; // version made by 2 bytes
|
|
ushort nVersionNeeded; // version needed to extract 2 bytes
|
|
ushort nFlags; // general purpose bit flag 2 bytes
|
|
ushort nMethod; // compression method 2 bytes
|
|
ushort nLastModTime; // last mod file time 2 bytes
|
|
ushort nLastModDate; // last mod file date 2 bytes
|
|
DataDescriptor desc;
|
|
ushort nFileNameLength; // file name length 2 bytes
|
|
ushort nExtraFieldLength; // extra field length 2 bytes
|
|
ushort nFileCommentLength; // file comment length 2 bytes
|
|
ushort nDiskNumberStart; // disk number start 2 bytes
|
|
ushort nAttrInternal; // internal file attributes 2 bytes
|
|
ulong lAttrExternal; // external file attributes 4 bytes
|
|
|
|
// This is the offset from the start of the first disk on
|
|
// which this file appears, to where the local header should
|
|
// be found. If an archive is in zip64 format and the value
|
|
// in this field is 0xFFFFFFFF, the size will be in the
|
|
// corresponding 8 byte zip64 extended information extra field.
|
|
enum
|
|
{
|
|
ZIP64_LOCAL_HEADER_OFFSET = 0xFFFFFFFF
|
|
};
|
|
ulong lLocalHeaderOffset; // relative offset of local header 4 bytes
|
|
|
|
bool IsZIP64([[maybe_unused]] const CDRFileHeader& d) const
|
|
{
|
|
return desc.IsZIP64(desc) || nDiskNumberStart == (ushort)ZIP64_SEE_EXTENSION || lLocalHeaderOffset == (ulong)ZIP64_SEE_EXTENSION;
|
|
}
|
|
|
|
AUTO_STRUCT_INFO
|
|
} PACK_GCC;
|
|
|
|
|
|
// this is the local file header that appears before the compressed data
|
|
// followed by:
|
|
// file name (variable size)
|
|
// extra field (variable size)
|
|
struct LocalFileHeader
|
|
{
|
|
enum
|
|
{
|
|
SIGNATURE = 0x04034b50
|
|
};
|
|
ulong lSignature; // local file header signature 4 bytes (0x04034b50)
|
|
ushort nVersionNeeded; // version needed to extract 2 bytes
|
|
ushort nFlags; // general purpose bit flag 2 bytes
|
|
ushort nMethod; // compression method 2 bytes
|
|
ushort nLastModTime; // last mod file time 2 bytes
|
|
ushort nLastModDate; // last mod file date 2 bytes
|
|
DataDescriptor desc;
|
|
ushort nFileNameLength; // file name length 2 bytes
|
|
ushort nExtraFieldLength; // extra field length 2 bytes
|
|
|
|
bool IsZIP64([[maybe_unused]] const LocalFileHeader& d) const
|
|
{
|
|
return desc.IsZIP64(desc);
|
|
}
|
|
|
|
AUTO_STRUCT_INFO
|
|
} PACK_GCC;
|
|
|
|
// compression methods
|
|
enum EExtraHeaderID
|
|
{
|
|
EXTRA_ZIP64 = 0x0001, // ZIP64 extended information extra field
|
|
EXTRA_NTFS = 0x000a, // NTFS
|
|
EXTRA_UNIX = 0x000d, // UNIX
|
|
EXTRA_PATCH = 0x000f, // Patch Descriptor
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// header1+data1 + header2+data2 . . .
|
|
// Each header should consist of:
|
|
// Header ID - 2 bytes
|
|
// Data Size - 2 bytes
|
|
struct ExtraFieldHeader
|
|
{
|
|
ushort headerID;
|
|
ushort dataSize;
|
|
|
|
AUTO_STRUCT_INFO
|
|
} PACK_GCC;
|
|
|
|
struct ExtraNTFSHeader
|
|
{
|
|
ulong reserved; // 4 bytes.
|
|
ushort attrTag; // 2 bytes.
|
|
ushort attrSize; // 2 bytes.
|
|
|
|
AUTO_STRUCT_INFO
|
|
} PACK_GCC;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// The following is the layout of the zip64 extended
|
|
// information "extra" block. If one of the size or
|
|
// offset fields in the Local or Central directory
|
|
// record is too small to hold the required data,
|
|
// a Zip64 extended information record is created.
|
|
// The order of the fields in the zip64 extended
|
|
// information record is fixed, but the fields MUST
|
|
// only appear if the corresponding Local or Central
|
|
// directory record field is set to 0xFFFF or 0xFFFFFFFF.
|
|
//
|
|
// The extended information in the Local header MUST include
|
|
// BOTH original and compressed file size fields.
|
|
|
|
struct ExtraZIP64LocalFileHeader
|
|
{
|
|
// LocalFileHeader overrides
|
|
uint64 lSizeUncompressed; // uncompressed size 4->8 bytes
|
|
uint64 lSizeCompressed; // compressed size 4->8 bytes
|
|
|
|
AUTO_STRUCT_INFO
|
|
} PACK_GCC;
|
|
|
|
struct ExtraZIP64CDRFileHeader
|
|
{
|
|
// CDRFileHeader overrides
|
|
uint64 lSizeUncompressed; // uncompressed size 4->8 bytes
|
|
uint64 lSizeCompressed; // compressed size 4->8 bytes
|
|
|
|
uint64 lLocalHeaderOffset; // relative offset of local header 4->8 bytes
|
|
ulong nDiskNumberStart; // Number of the disk on which this file starts 2->4 bytes
|
|
|
|
AUTO_STRUCT_INFO
|
|
} PACK_GCC;
|
|
}
|
|
|
|
#undef PACK_GCC
|
|
|
|
#if AZ_TRAIT_CRYCOMMONTOOLS_PACK_1
|
|
#pragma pack(pop)
|
|
#endif
|
|
|
|
#endif // CRYINCLUDE_CRYCOMMONTOOLS_ZIPDIR_ZIPFILEFORMAT_H
|