diff options
| -rw-r--r-- | src/StormLib.h | 1106 | ||||
| -rw-r--r-- | src/StormPort.h | 291 | 
2 files changed, 1397 insertions, 0 deletions
diff --git a/src/StormLib.h b/src/StormLib.h new file mode 100644 index 0000000..b6df481 --- /dev/null +++ b/src/StormLib.h @@ -0,0 +1,1106 @@ +/*****************************************************************************/ +/* StormLib.h                        Copyright (c) Ladislav Zezula 1999-2010 */ +/*---------------------------------------------------------------------------*/ +/* StormLib library v 7.02                                                   */ +/*                                                                           */ +/* Author : Ladislav Zezula                                                  */ +/* E-mail : ladik@zezula.net                                                 */ +/* WWW    : http://www.zezula.net                                            */ +/*---------------------------------------------------------------------------*/ +/*   Date    Ver   Who  Comment                                              */ +/* --------  ----  ---  -------                                              */ +/* xx.xx.99  1.00  Lad  Created                                              */ +/* 24.03.03  2.50  Lad  Version 2.50                                         */ +/* 02.04.03  3.00  Lad  Version 3.00 with compression                        */ +/* 11.04.03  3.01  Lad  Renamed to StormLib.h for compatibility with         */ +/*                      original headers for Storm.dll                       */ +/* 10.05.03  3.02  Lad  Added Pkware DCL compression                         */ +/* 26.05.03  4.00  Lad  Completed all compressions                           */ +/* 18.06.03  4.01  Lad  Added SFileSetFileLocale                             */ +/*                      Added SFileExtractFile                               */ +/* 26.07.03  4.02  Lad  Implemented nameless rename and delete               */ +/* 26.07.03  4.03  Lad  Added support for protected MPQs                     */ +/* 28.08.03  4.10  Lad  Fixed bugs that caused StormLib incorrectly work     */ +/*                      with Diablo I savegames and with files having full   */ +/*                      hash table                                           */ +/* 08.12.03  4.11  DCH  Fixed bug in reading file sector larger than 0x1000  */ +/*                      on certain files.                                    */ +/*                      Fixed bug in AddFile with MPQ_FILE_REPLACE_EXISTING  */ +/*                      (Thanx Daniel Chiamarello, dchiamarello@madvawes.com)*/ +/* 21.12.03  4.50  Lad  Completed port for Mac                               */ +/*                      Fixed bug in compacting (if fsize is mul of 0x1000)  */ +/*                      Fixed bug in SCompCompress                           */ +/* 27.05.04  4.51  Lad  Changed memory management from new/delete to our     */ +/*                      own macros                                           */ +/* 22.06.04  4.60  Lad  Optimized search. Support for multiple listfiles.    */ +/* 30.09.04  4.61  Lad  Fixed some bugs (Aaargh !!!)                         */ +/*                      Correctly works if HashTableSize > BlockTableSize    */ +/* 29.12.04  4.70  Lad  Fixed compatibility problem with MPQs from WoW       */ +/* 14.07.05  5.00  Lad  Added the BZLIB compression support                  */ +/*                      Added suport of files stored as single unit          */ +/* 17.04.06  5.01  Lad  Converted to MS Visual Studio 8.0                    */ +/*                      Fixed issue with protected Warcraft 3 protected maps */ +/* 15.05.06  5.02  Lad  Fixed issue with WoW 1.10+                           */ +/* 07.09.06  5.10  Lad  Fixed processing files longer than 2GB               */ +/* 22.11.06  6.00  Lad  Support for MPQ archives V2                          */ +/* 12.06.07  6.10  Lad  Support for (attributes) file                        */ +/* 10.09.07  6.12  Lad  Support for MPQs protected by corrupting hash table  */ +/* 03.12.07  6.13  Lad  Support for MPQs with hash tbl size > block tbl size */ +/* 07.04.08  6.20  Lad  Added SFileFlushArchive                              */ +/* 09.04.08        Lad  Removed FilePointer variable from MPQ handle         */ +/*                      structure, as it caused more problems than benefits  */ +/* 12.05.08  6.22  Lad  Support for w3xMaster map protector                  */ +/* 05.10.08  6.23  Lad  Support for protectors who set negative values in    */ +/*                      the table of file blocks                             */ +/* 26.05.09  6.24  Lad  Fixed search for multiple lang files with deleted    */ +/*                      entries                                              */ +/* 03.09.09  6.25  Lad  Fixed decompression bug in huffmann decompression    */ +/* 22.03.10  6.50  Lad  New compressions in Starcraft II (LZMA, sparse)      */ +/*                      Fixed compacting MPQs that contain single unit files */ +/* 26.04.10  7.00  Lad  Major rewrite                                        */ +/* 08.06.10  7.10  Lad  Support for partial MPQs                             */ +/* 08.07.10  7.11  Lad  Support for MPQs v 3.0                               */ +/* 20.08.10  7.20  Lad  Support for opening multiple MPQs in patch mode      */ +/* 20.09.10  8.00  Lad  MPQs v 4, HET and BET tables                         */ +/* 07.01.11  8.01  Lad  Write support for MPQs v 3 and 4                     */ +/* 15.09.11  8.04  Lad  Bug fixes, testing for Diablo III MPQs               */ +/* 26.04.12  8.10  Lad  Support for data map, added SFileGetArchiveBitmap    */ +/* 29.05.12  8.20  Lad  C-only interface                                     */ +/* 14.01.13  8.21  Lad  ADPCM and Huffmann (de)compression refactored        */ +/* 04.12.13  9.00  Lad  Unit tests, bug fixes                                */ +/* 27.08.14  9.10  Lad  Signing archives with weak digital signature         */ +/* 25.11.14  9.11  Lad  Fixed bug reading & creating HET table               */ +/* 18.09.15  9.20  Lad  Release 9.20                                         */ +/*****************************************************************************/ + +#ifndef __STORMLIB_H__ +#define __STORMLIB_H__ + +#ifdef _MSC_VER +#pragma warning(disable:4668)       // 'XXX' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'  +#pragma warning(disable:4820)       // 'XXX' : '2' bytes padding added after data member 'XXX::yyy' +#endif                                              + +#include "StormPort.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//----------------------------------------------------------------------------- +// Use the apropriate library +// +// The library type is encoded in the library name as the following +// StormLibXYZ.lib +//  +//  X - D for Debug version, R for Release version +//  Y - A for ANSI version, U for Unicode version +//  Z - S for static-linked CRT library, D for multithreaded DLL CRT library +// + +#if defined(_MSC_VER) && !defined(__STORMLIB_SELF__) +   +  #ifdef _DEBUG                                 // DEBUG VERSIONS +    #ifndef _UNICODE                             +      #ifdef _DLL                                +        #pragma comment(lib, "StormLibDAD.lib") // Debug Ansi CRT-DLL version +      #else         +        #pragma comment(lib, "StormLibDAS.lib") // Debug Ansi CRT-LIB version +      #endif +    #else +      #ifdef _DLL                                +        #pragma comment(lib, "StormLibDUD.lib") // Debug Unicode CRT-DLL version +      #else         +        #pragma comment(lib, "StormLibDUS.lib") // Debug Unicode CRT-LIB version +      #endif +    #endif +  #else                                         // RELEASE VERSIONS +    #ifndef _UNICODE                             +      #ifdef _DLL +        #pragma comment(lib, "StormLibRAD.lib") // Release Ansi CRT-DLL version +      #else         +        #pragma comment(lib, "StormLibRAS.lib") // Release Ansi CRT-LIB version +      #endif +    #else +      #ifdef _DLL +        #pragma comment(lib, "StormLibRUD.lib") // Release Unicode CRT-DLL version +      #else         +        #pragma comment(lib, "StormLibRUS.lib") // Release Unicode CRT-LIB version +      #endif +    #endif +  #endif + +#endif + +//----------------------------------------------------------------------------- +// Defines + +#define STORMLIB_VERSION                0x0914  // Current version of StormLib (9.20) +#define STORMLIB_VERSION_STRING         "9.20"  // String version of StormLib version + +#define ID_MPQ                      0x1A51504D  // MPQ archive header ID ('MPQ\x1A') +#define ID_MPQ_USERDATA             0x1B51504D  // MPQ userdata entry ('MPQ\x1B') +#define ID_MPK                      0x1A4B504D  // MPK archive header ID ('MPK\x1A') + +#define ERROR_AVI_FILE                   10000  // Not a MPQ file, but an AVI file. +#define ERROR_UNKNOWN_FILE_KEY           10001  // Returned by SFileReadFile when can't find file key +#define ERROR_CHECKSUM_ERROR             10002  // Returned by SFileReadFile when sector CRC doesn't match +#define ERROR_INTERNAL_FILE              10003  // The given operation is not allowed on internal file +#define ERROR_BASE_FILE_MISSING          10004  // The file is present as incremental patch file, but base file is missing +#define ERROR_MARKED_FOR_DELETE          10005  // The file was marked as "deleted" in the MPQ +#define ERROR_FILE_INCOMPLETE            10006  // The required file part is missing +#define ERROR_UNKNOWN_FILE_NAMES         10007  // A name of at least one file is unknown +#define ERROR_CANT_FIND_PATCH_PREFIX     10008  // StormLib was unable to find patch prefix for the patches + +// Values for SFileCreateArchive +#define HASH_TABLE_SIZE_MIN         0x00000004  // Verified: If there is 1 file, hash table size is 4 +#define HASH_TABLE_SIZE_DEFAULT     0x00001000  // Default hash table size for empty MPQs +#define HASH_TABLE_SIZE_MAX         0x00080000  // Maximum acceptable hash table size + +#define HASH_ENTRY_DELETED          0xFFFFFFFE  // Block index for deleted entry in the hash table +#define HASH_ENTRY_FREE             0xFFFFFFFF  // Block index for free entry in the hash table + +#define HET_ENTRY_DELETED                 0x80  // NameHash1 value for a deleted entry +#define HET_ENTRY_FREE                    0x00  // NameHash1 value for free entry + +#define HASH_STATE_SIZE                   0x60  // Size of LibTomCrypt's hash_state structure + +// Values for SFileOpenArchive +#define SFILE_OPEN_HARD_DISK_FILE            2  // Open the archive on HDD +#define SFILE_OPEN_CDROM_FILE                3  // Open the archive only if it is on CDROM + +// Values for SFileOpenFile +#define SFILE_OPEN_FROM_MPQ         0x00000000  // Open the file from the MPQ archive +#define SFILE_OPEN_CHECK_EXISTS     0xFFFFFFFC  // Only check whether the file exists +#define SFILE_OPEN_BASE_FILE        0xFFFFFFFD  // Reserved for StormLib internal use +#define SFILE_OPEN_ANY_LOCALE       0xFFFFFFFE  // Reserved for StormLib internal use +#define SFILE_OPEN_LOCAL_FILE       0xFFFFFFFF  // Open a local file + +// Flags for TMPQArchive::dwFlags +#define MPQ_FLAG_READ_ONLY          0x00000001  // If set, the MPQ has been open for read-only access +#define MPQ_FLAG_CHANGED            0x00000002  // If set, the MPQ tables have been changed +#define MPQ_FLAG_MALFORMED          0x00000004  // Malformed data structure detected (W3M map protectors) +#define MPQ_FLAG_HASH_TABLE_CUT     0x00000008  // The hash table goes beyond EOF +#define MPQ_FLAG_BLOCK_TABLE_CUT    0x00000010  // The hash table goes beyond EOF +#define MPQ_FLAG_CHECK_SECTOR_CRC   0x00000020  // Checking sector CRC when reading files +#define MPQ_FLAG_SAVING_TABLES      0x00000040  // If set, we are saving MPQ internal files and MPQ tables +#define MPQ_FLAG_PATCH              0x00000080  // If set, this MPQ is a patch archive +#define MPQ_FLAG_WAR3_MAP           0x00000100  // If set, this MPQ is a map for Warcraft III +#define MPQ_FLAG_LISTFILE_NONE      0x00000200  // Set when no (listfile) was found in InvalidateInternalFiles +#define MPQ_FLAG_LISTFILE_NEW       0x00000400  // Set when (listfile) invalidated by InvalidateInternalFiles +#define MPQ_FLAG_ATTRIBUTES_NONE    0x00000800  // Set when no (attributes) was found in InvalidateInternalFiles +#define MPQ_FLAG_ATTRIBUTES_NEW     0x00001000  // Set when (attributes) invalidated by InvalidateInternalFiles +#define MPQ_FLAG_SIGNATURE_NONE     0x00002000  // Set when no (signature) was found in InvalidateInternalFiles +#define MPQ_FLAG_SIGNATURE_NEW      0x00004000  // Set when (signature) invalidated by InvalidateInternalFiles + +// Values for TMPQArchive::dwSubType +#define MPQ_SUBTYPE_MPQ             0x00000000  // The file is a MPQ file (Blizzard games) +#define MPQ_SUBTYPE_SQP             0x00000001  // The file is a SQP file (War of the Immortals) +#define MPQ_SUBTYPE_MPK             0x00000002  // The file is a MPK file (Longwu Online) + +// Return value for SFileGetFileSize and SFileSetFilePointer +#define SFILE_INVALID_SIZE          0xFFFFFFFF +#define SFILE_INVALID_POS           0xFFFFFFFF +#define SFILE_INVALID_ATTRIBUTES    0xFFFFFFFF + +// Flags for SFileAddFile +#define MPQ_FILE_IMPLODE            0x00000100  // Implode method (By PKWARE Data Compression Library) +#define MPQ_FILE_COMPRESS           0x00000200  // Compress methods (By multiple methods) +#define MPQ_FILE_ENCRYPTED          0x00010000  // Indicates whether file is encrypted  +#define MPQ_FILE_FIX_KEY            0x00020000  // File decryption key has to be fixed +#define MPQ_FILE_PATCH_FILE         0x00100000  // The file is a patch file. Raw file data begin with TPatchInfo structure +#define MPQ_FILE_SINGLE_UNIT        0x01000000  // File is stored as a single unit, rather than split into sectors (Thx, Quantam) +#define MPQ_FILE_DELETE_MARKER      0x02000000  // File is a deletion marker. Used in MPQ patches, indicating that the file no longer exists. +#define MPQ_FILE_SECTOR_CRC         0x04000000  // File has checksums for each sector. +                                                // Ignored if file is not compressed or imploded. +#define MPQ_FILE_SIGNATURE          0x10000000  // Present on STANDARD.SNP\(signature). The only occurence ever observed +#define MPQ_FILE_EXISTS             0x80000000  // Set if file exists, reset when the file was deleted +#define MPQ_FILE_REPLACEEXISTING    0x80000000  // Replace when the file exist (SFileAddFile) + +#define MPQ_FILE_COMPRESS_MASK      0x0000FF00  // Mask for a file being compressed + +#define MPQ_FILE_VALID_FLAGS     (MPQ_FILE_IMPLODE       |  \ +                                  MPQ_FILE_COMPRESS      |  \ +                                  MPQ_FILE_ENCRYPTED     |  \ +                                  MPQ_FILE_FIX_KEY       |  \ +                                  MPQ_FILE_PATCH_FILE    |  \ +                                  MPQ_FILE_SINGLE_UNIT   |  \ +                                  MPQ_FILE_DELETE_MARKER |  \ +                                  MPQ_FILE_SECTOR_CRC    |  \ +                                  MPQ_FILE_SIGNATURE     |  \ +                                  MPQ_FILE_EXISTS) + +// We need to mask out the upper 4 bits of the block table index. +// This is because it gets shifted out when calculating block table offset +// BlockTableOffset = pHash->dwBlockIndex << 0x04 +// Malformed MPQ maps may contain block indexes like 0x40000001 or 0xF0000023 +#define BLOCK_INDEX_MASK          0x0FFFFFFF +#define MPQ_BLOCK_INDEX(pHash) (pHash->dwBlockIndex & BLOCK_INDEX_MASK) + +// Compression types for multiple compressions +#define MPQ_COMPRESSION_HUFFMANN          0x01  // Huffmann compression (used on WAVE files only) +#define MPQ_COMPRESSION_ZLIB              0x02  // ZLIB compression +#define MPQ_COMPRESSION_PKWARE            0x08  // PKWARE DCL compression +#define MPQ_COMPRESSION_BZIP2             0x10  // BZIP2 compression (added in Warcraft III) +#define MPQ_COMPRESSION_SPARSE            0x20  // Sparse compression (added in Starcraft 2) +#define MPQ_COMPRESSION_ADPCM_MONO        0x40  // IMA ADPCM compression (mono) +#define MPQ_COMPRESSION_ADPCM_STEREO      0x80  // IMA ADPCM compression (stereo) +#define MPQ_COMPRESSION_LZMA              0x12  // LZMA compression. Added in Starcraft 2. This value is NOT a combination of flags. +#define MPQ_COMPRESSION_NEXT_SAME   0xFFFFFFFF  // Same compression + +// Constants for SFileAddWave +#define MPQ_WAVE_QUALITY_HIGH                0  // Best quality, the worst compression +#define MPQ_WAVE_QUALITY_MEDIUM              1  // Medium quality, medium compression +#define MPQ_WAVE_QUALITY_LOW                 2  // Low quality, the best compression + +// Signatures for HET and BET table +#define HET_TABLE_SIGNATURE         0x1A544548  // 'HET\x1a' +#define BET_TABLE_SIGNATURE         0x1A544542  // 'BET\x1a' + +// Decryption keys for MPQ tables +#define MPQ_KEY_HASH_TABLE          0xC3AF3770  // Obtained by HashString("(hash table)", MPQ_HASH_FILE_KEY) +#define MPQ_KEY_BLOCK_TABLE         0xEC83B3A3  // Obtained by HashString("(block table)", MPQ_HASH_FILE_KEY) + +#define LISTFILE_NAME             "(listfile)"  // Name of internal listfile +#define SIGNATURE_NAME           "(signature)"  // Name of internal signature +#define ATTRIBUTES_NAME         "(attributes)"  // Name of internal attributes file +#define PATCH_METADATA_NAME "(patch_metadata)" + +#define MPQ_FORMAT_VERSION_1                 0  // Up to The Burning Crusade +#define MPQ_FORMAT_VERSION_2                 1  // The Burning Crusade and newer  +#define MPQ_FORMAT_VERSION_3                 2  // WoW Cataclysm Beta +#define MPQ_FORMAT_VERSION_4                 3  // WoW Cataclysm and newer + +// Flags for MPQ attributes +#define MPQ_ATTRIBUTE_CRC32         0x00000001  // The "(attributes)" contains CRC32 for each file +#define MPQ_ATTRIBUTE_FILETIME      0x00000002  // The "(attributes)" contains file time for each file +#define MPQ_ATTRIBUTE_MD5           0x00000004  // The "(attributes)" contains MD5 for each file +#define MPQ_ATTRIBUTE_PATCH_BIT     0x00000008  // The "(attributes)" contains a patch bit for each file +#define MPQ_ATTRIBUTE_ALL           0x0000000F  // Summary mask + +#define MPQ_ATTRIBUTES_V1                  100  // (attributes) format version 1.00 + +// Flags for SFileOpenArchive +#define BASE_PROVIDER_FILE          0x00000000  // Base data source is a file +#define BASE_PROVIDER_MAP           0x00000001  // Base data source is memory-mapped file +#define BASE_PROVIDER_HTTP          0x00000002  // Base data source is a file on web server +#define BASE_PROVIDER_MASK          0x0000000F  // Mask for base provider value + +#define STREAM_PROVIDER_FLAT        0x00000000  // Stream is linear with no offset mapping +#define STREAM_PROVIDER_PARTIAL     0x00000010  // Stream is partial file (.part) +#define STREAM_PROVIDER_MPQE        0x00000020  // Stream is an encrypted MPQ +#define STREAM_PROVIDER_BLOCK4      0x00000030  // 0x4000 per block, text MD5 after each block, max 0x2000 blocks per file +#define STREAM_PROVIDER_MASK        0x000000F0  // Mask for stream provider value + +#define STREAM_FLAG_READ_ONLY       0x00000100  // Stream is read only +#define STREAM_FLAG_WRITE_SHARE     0x00000200  // Allow write sharing when open for write +#define STREAM_FLAG_USE_BITMAP      0x00000400  // If the file has a file bitmap, load it and use it +#define STREAM_OPTIONS_MASK         0x0000FF00  // Mask for stream options + +#define STREAM_PROVIDERS_MASK       0x000000FF  // Mask to get stream providers +#define STREAM_FLAGS_MASK           0x0000FFFF  // Mask for all stream flags (providers+options) + +#define MPQ_OPEN_NO_LISTFILE        0x00010000  // Don't load the internal listfile +#define MPQ_OPEN_NO_ATTRIBUTES      0x00020000  // Don't open the attributes +#define MPQ_OPEN_NO_HEADER_SEARCH   0x00040000  // Don't search for the MPQ header past the begin of the file +#define MPQ_OPEN_FORCE_MPQ_V1       0x00080000  // Always open the archive as MPQ v 1.00, ignore the "wFormatVersion" variable in the header +#define MPQ_OPEN_CHECK_SECTOR_CRC   0x00100000  // On files with MPQ_FILE_SECTOR_CRC, the CRC will be checked when reading file +#define MPQ_OPEN_PATCH              0x00200000  // This archive is a patch MPQ. Used internally. +#define MPQ_OPEN_READ_ONLY          STREAM_FLAG_READ_ONLY + +// Flags for SFileCreateArchive +#define MPQ_CREATE_LISTFILE         0x00100000  // Also add the (listfile) file +#define MPQ_CREATE_ATTRIBUTES       0x00200000  // Also add the (attributes) file +#define MPQ_CREATE_SIGNATURE        0x00400000  // Also add the (signature) file +#define MPQ_CREATE_ARCHIVE_V1       0x00000000  // Creates archive of version 1 (size up to 4GB) +#define MPQ_CREATE_ARCHIVE_V2       0x01000000  // Creates archive of version 2 (larger than 4 GB) +#define MPQ_CREATE_ARCHIVE_V3       0x02000000  // Creates archive of version 3 +#define MPQ_CREATE_ARCHIVE_V4       0x03000000  // Creates archive of version 4 +#define MPQ_CREATE_ARCHIVE_VMASK    0x0F000000  // Mask for archive version + +#define FLAGS_TO_FORMAT_SHIFT               24  // (MPQ_CREATE_ARCHIVE_V4 >> FLAGS_TO_FORMAT_SHIFT) => MPQ_FORMAT_VERSION_4 + +// Flags for SFileVerifyFile +#define SFILE_VERIFY_SECTOR_CRC     0x00000001  // Verify sector checksum for the file, if available +#define SFILE_VERIFY_FILE_CRC       0x00000002  // Verify file CRC, if available +#define SFILE_VERIFY_FILE_MD5       0x00000004  // Verify file MD5, if available +#define SFILE_VERIFY_RAW_MD5        0x00000008  // Verify raw file MD5, if available +#define SFILE_VERIFY_ALL            0x0000000F  // Verify every checksum possible + +// Return values for SFileVerifyFile +#define VERIFY_OPEN_ERROR               0x0001  // Failed to open the file +#define VERIFY_READ_ERROR               0x0002  // Failed to read all data from the file +#define VERIFY_FILE_HAS_SECTOR_CRC      0x0004  // File has sector CRC +#define VERIFY_FILE_SECTOR_CRC_ERROR    0x0008  // Sector CRC check failed +#define VERIFY_FILE_HAS_CHECKSUM        0x0010  // File has CRC32 +#define VERIFY_FILE_CHECKSUM_ERROR      0x0020  // CRC32 check failed +#define VERIFY_FILE_HAS_MD5             0x0040  // File has data MD5 +#define VERIFY_FILE_MD5_ERROR           0x0080  // MD5 check failed +#define VERIFY_FILE_HAS_RAW_MD5         0x0100  // File has raw data MD5 +#define VERIFY_FILE_RAW_MD5_ERROR       0x0200  // Raw MD5 check failed +#define VERIFY_FILE_ERROR_MASK      (VERIFY_OPEN_ERROR | VERIFY_READ_ERROR | VERIFY_FILE_SECTOR_CRC_ERROR | VERIFY_FILE_CHECKSUM_ERROR | VERIFY_FILE_MD5_ERROR | VERIFY_FILE_RAW_MD5_ERROR) + +// Flags for SFileVerifyRawData (for MPQs version 4.0 or higher) +#define SFILE_VERIFY_MPQ_HEADER         0x0001  // Verify raw MPQ header +#define SFILE_VERIFY_HET_TABLE          0x0002  // Verify raw data of the HET table +#define SFILE_VERIFY_BET_TABLE          0x0003  // Verify raw data of the BET table +#define SFILE_VERIFY_HASH_TABLE         0x0004  // Verify raw data of the hash table +#define SFILE_VERIFY_BLOCK_TABLE        0x0005  // Verify raw data of the block table +#define SFILE_VERIFY_HIBLOCK_TABLE      0x0006  // Verify raw data of the hi-block table +#define SFILE_VERIFY_FILE               0x0007  // Verify raw data of a file + +// Signature types +#define SIGNATURE_TYPE_NONE             0x0000  // The archive has no signature in it +#define SIGNATURE_TYPE_WEAK             0x0001  // The archive has weak signature +#define SIGNATURE_TYPE_STRONG           0x0002  // The archive has strong signature + +// Return values for SFileVerifyArchive +#define ERROR_NO_SIGNATURE                   0  // There is no signature in the MPQ +#define ERROR_VERIFY_FAILED                  1  // There was an error during verifying signature (like no memory) +#define ERROR_WEAK_SIGNATURE_OK              2  // There is a weak signature and sign check passed +#define ERROR_WEAK_SIGNATURE_ERROR           3  // There is a weak signature but sign check failed +#define ERROR_STRONG_SIGNATURE_OK            4  // There is a strong signature and sign check passed +#define ERROR_STRONG_SIGNATURE_ERROR         5  // There is a strong signature but sign check failed +                                            +#ifndef MD5_DIGEST_SIZE +#define MD5_DIGEST_SIZE                   0x10 +#endif + +#ifndef SHA1_DIGEST_SIZE +#define SHA1_DIGEST_SIZE                  0x14  // 160 bits +#endif + +#ifndef LANG_NEUTRAL +#define LANG_NEUTRAL                      0x00  // Neutral locale +#endif + +// Pointer to hashing function +typedef DWORD (*HASH_STRING)(const char * szFileName, DWORD dwHashType); + +//----------------------------------------------------------------------------- +// File information classes for SFileGetFileInfo and SFileFreeFileInfo + +typedef enum _SFileInfoClass +{ +    // Info classes for archives +    SFileMpqFileName,                       // Name of the archive file (TCHAR []) +    SFileMpqStreamBitmap,                   // Array of bits, each bit means availability of one block (BYTE []) +    SFileMpqUserDataOffset,                 // Offset of the user data header (ULONGLONG) +    SFileMpqUserDataHeader,                 // Raw (unfixed) user data header (TMPQUserData) +    SFileMpqUserData,                       // MPQ USer data, without the header (BYTE []) +    SFileMpqHeaderOffset,                   // Offset of the MPQ header (ULONGLONG) +    SFileMpqHeaderSize,                     // Fixed size of the MPQ header +    SFileMpqHeader,                         // Raw (unfixed) archive header (TMPQHeader) +    SFileMpqHetTableOffset,                 // Offset of the HET table, relative to MPQ header (ULONGLONG) +    SFileMpqHetTableSize,                   // Compressed size of the HET table (ULONGLONG) +    SFileMpqHetHeader,                      // HET table header (TMPQHetHeader) +    SFileMpqHetTable,                       // HET table as pointer. Must be freed using SFileFreeFileInfo +    SFileMpqBetTableOffset,                 // Offset of the BET table, relative to MPQ header (ULONGLONG) +    SFileMpqBetTableSize,                   // Compressed size of the BET table (ULONGLONG) +    SFileMpqBetHeader,                      // BET table header, followed by the flags (TMPQBetHeader + DWORD[]) +    SFileMpqBetTable,                       // BET table as pointer. Must be freed using SFileFreeFileInfo +    SFileMpqHashTableOffset,                // Hash table offset, relative to MPQ header (ULONGLONG) +    SFileMpqHashTableSize64,                // Compressed size of the hash table (ULONGLONG) +    SFileMpqHashTableSize,                  // Size of the hash table, in entries (DWORD) +    SFileMpqHashTable,                      // Raw (unfixed) hash table (TMPQBlock []) +    SFileMpqBlockTableOffset,               // Block table offset, relative to MPQ header (ULONGLONG) +    SFileMpqBlockTableSize64,               // Compressed size of the block table (ULONGLONG) +    SFileMpqBlockTableSize,                 // Size of the block table, in entries (DWORD) +    SFileMpqBlockTable,                     // Raw (unfixed) block table (TMPQBlock []) +    SFileMpqHiBlockTableOffset,             // Hi-block table offset, relative to MPQ header (ULONGLONG) +    SFileMpqHiBlockTableSize64,             // Compressed size of the hi-block table (ULONGLONG) +    SFileMpqHiBlockTable,                   // The hi-block table (USHORT []) +    SFileMpqSignatures,                     // Signatures present in the MPQ (DWORD) +    SFileMpqStrongSignatureOffset,          // Byte offset of the strong signature, relative to begin of the file (ULONGLONG) +    SFileMpqStrongSignatureSize,            // Size of the strong signature (DWORD) +    SFileMpqStrongSignature,                // The strong signature (BYTE []) +    SFileMpqArchiveSize64,                  // Archive size from the header (ULONGLONG) +    SFileMpqArchiveSize,                    // Archive size from the header (DWORD) +    SFileMpqMaxFileCount,                   // Max number of files in the archive (DWORD) +    SFileMpqFileTableSize,                  // Number of entries in the file table (DWORD) +    SFileMpqSectorSize,                     // Sector size (DWORD) +    SFileMpqNumberOfFiles,                  // Number of files (DWORD) +    SFileMpqRawChunkSize,                   // Size of the raw data chunk for MD5 +    SFileMpqStreamFlags,                    // Stream flags (DWORD) +    SFileMpqFlags,                          // Nonzero if the MPQ is read only (DWORD) + +    // Info classes for files +    SFileInfoPatchChain,                    // Chain of patches where the file is (TCHAR []) +    SFileInfoFileEntry,                     // The file entry for the file (TFileEntry) +    SFileInfoHashEntry,                     // Hash table entry for the file (TMPQHash) +    SFileInfoHashIndex,                     // Index of the hash table entry (DWORD) +    SFileInfoNameHash1,                     // The first name hash in the hash table (DWORD) +    SFileInfoNameHash2,                     // The second name hash in the hash table (DWORD) +    SFileInfoNameHash3,                     // 64-bit file name hash for the HET/BET tables (ULONGLONG) +    SFileInfoLocale,                        // File locale (DWORD) +    SFileInfoFileIndex,                     // Block index (DWORD) +    SFileInfoByteOffset,                    // File position in the archive (ULONGLONG) +    SFileInfoFileTime,                      // File time (ULONGLONG) +    SFileInfoFileSize,                      // Size of the file (DWORD) +    SFileInfoCompressedSize,                // Compressed file size (DWORD) +    SFileInfoFlags,                         // File flags from (DWORD) +    SFileInfoEncryptionKey,                 // File encryption key +    SFileInfoEncryptionKeyRaw,              // Unfixed value of the file key +    SFileInfoCRC32,                         // CRC32 of the file +} SFileInfoClass; + +//----------------------------------------------------------------------------- +// Callback functions + +// Values for compact callback +#define CCB_CHECKING_FILES                  1   // Checking archive (dwParam1 = current, dwParam2 = total) +#define CCB_CHECKING_HASH_TABLE             2   // Checking hash table (dwParam1 = current, dwParam2 = total) +#define CCB_COPYING_NON_MPQ_DATA            3   // Copying non-MPQ data: No params used +#define CCB_COMPACTING_FILES                4   // Compacting archive (dwParam1 = current, dwParam2 = total) +#define CCB_CLOSING_ARCHIVE                 5   // Closing archive: No params used +                                       +typedef void (WINAPI * SFILE_DOWNLOAD_CALLBACK)(void * pvUserData, ULONGLONG ByteOffset, DWORD dwTotalBytes); +typedef void (WINAPI * SFILE_ADDFILE_CALLBACK)(void * pvUserData, DWORD dwBytesWritten, DWORD dwTotalBytes, bool bFinalCall); +typedef void (WINAPI * SFILE_COMPACT_CALLBACK)(void * pvUserData, DWORD dwWorkType, ULONGLONG BytesProcessed, ULONGLONG TotalBytes); + +typedef struct TFileStream TFileStream; + +//----------------------------------------------------------------------------- +// Structure for bit arrays used for HET and BET tables + +typedef struct _TBitArray +{ +    DWORD NumberOfBytes;                        // Total number of bytes in "Elements" +    DWORD NumberOfBits;                         // Total number of bits that are available +    BYTE Elements[1];                           // Array of elements (variable length) +} TBitArray; + +void GetBits(TBitArray * array, unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultSize); +void SetBits(TBitArray * array, unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultSize); + +//----------------------------------------------------------------------------- +// Structures related to MPQ format +// +// Note: All structures in this header file are supposed to remain private +// to StormLib. The structures may (and will) change over time, as the MPQ +// file format evolves. Programmers directly using these structures need to +// be aware of this. And the last, but not least, NEVER do any modifications +// to those structures directly, always use SFile* functions. +// + +#define MPQ_HEADER_SIZE_V1    0x20 +#define MPQ_HEADER_SIZE_V2    0x2C +#define MPQ_HEADER_SIZE_V3    0x44 +#define MPQ_HEADER_SIZE_V4    0xD0 +#define MPQ_HEADER_DWORDS     (MPQ_HEADER_SIZE_V4 / 0x04) + +typedef struct _TMPQUserData +{ +    // The ID_MPQ_USERDATA ('MPQ\x1B') signature +    DWORD dwID; + +    // Maximum size of the user data +    DWORD cbUserDataSize; + +    // Offset of the MPQ header, relative to the begin of this header +    DWORD dwHeaderOffs; + +    // Appears to be size of user data header (Starcraft II maps) +    DWORD cbUserDataHeader; +} TMPQUserData; + +// MPQ file header +// +// We have to make sure that the header is packed OK. +// Reason: A 64-bit integer at the beginning of 3.0 part, +// which is offset 0x2C +#pragma pack(push, 1) +typedef struct _TMPQHeader +{ +    // The ID_MPQ ('MPQ\x1A') signature +    DWORD dwID; + +    // Size of the archive header +    DWORD dwHeaderSize; + +    // 32-bit size of MPQ archive +    // This field is deprecated in the Burning Crusade MoPaQ format, and the size of the archive +    // is calculated as the size from the beginning of the archive to the end of the hash table, +    // block table, or hi-block table (whichever is largest). +    DWORD dwArchiveSize; + +    // 0 = Format 1 (up to The Burning Crusade) +    // 1 = Format 2 (The Burning Crusade and newer) +    // 2 = Format 3 (WoW - Cataclysm beta or newer) +    // 3 = Format 4 (WoW - Cataclysm beta or newer) +    USHORT wFormatVersion; + +    // Power of two exponent specifying the number of 512-byte disk sectors in each file sector +    // in the archive. The size of each file sector in the archive is 512 * 2 ^ wSectorSize. +    USHORT wSectorSize; + +    // Offset to the beginning of the hash table, relative to the beginning of the archive. +    DWORD dwHashTablePos; +     +    // Offset to the beginning of the block table, relative to the beginning of the archive. +    DWORD dwBlockTablePos; +     +    // Number of entries in the hash table. Must be a power of two, and must be less than 2^16 for +    // the original MoPaQ format, or less than 2^20 for the Burning Crusade format. +    DWORD dwHashTableSize; +     +    // Number of entries in the block table +    DWORD dwBlockTableSize; + +    //-- MPQ HEADER v 2 ------------------------------------------- + +    // Offset to the beginning of array of 16-bit high parts of file offsets. +    ULONGLONG HiBlockTablePos64; + +    // High 16 bits of the hash table offset for large archives. +    USHORT wHashTablePosHi; + +    // High 16 bits of the block table offset for large archives. +    USHORT wBlockTablePosHi; + +    //-- MPQ HEADER v 3 ------------------------------------------- + +    // 64-bit version of the archive size +    ULONGLONG ArchiveSize64; + +    // 64-bit position of the BET table +    ULONGLONG BetTablePos64; + +    // 64-bit position of the HET table +    ULONGLONG HetTablePos64; + +    //-- MPQ HEADER v 4 ------------------------------------------- + +    // Compressed size of the hash table +    ULONGLONG HashTableSize64; + +    // Compressed size of the block table +    ULONGLONG BlockTableSize64; + +    // Compressed size of the hi-block table +    ULONGLONG HiBlockTableSize64; + +    // Compressed size of the HET block +    ULONGLONG HetTableSize64; + +    // Compressed size of the BET block +    ULONGLONG BetTableSize64; + +    // Size of raw data chunk to calculate MD5. +    // MD5 of each data chunk follows the raw file data. +    DWORD dwRawChunkSize;                                  + +    // MD5 of MPQ tables +    unsigned char MD5_BlockTable[MD5_DIGEST_SIZE];      // MD5 of the block table before decryption +    unsigned char MD5_HashTable[MD5_DIGEST_SIZE];       // MD5 of the hash table before decryption +    unsigned char MD5_HiBlockTable[MD5_DIGEST_SIZE];    // MD5 of the hi-block table +    unsigned char MD5_BetTable[MD5_DIGEST_SIZE];        // MD5 of the BET table before decryption +    unsigned char MD5_HetTable[MD5_DIGEST_SIZE];        // MD5 of the HET table before decryption +    unsigned char MD5_MpqHeader[MD5_DIGEST_SIZE];       // MD5 of the MPQ header from signature to (including) MD5_HetTable +} TMPQHeader; +#pragma pack(pop) + +// Hash table entry. All files in the archive are searched by their hashes. +typedef struct _TMPQHash +{ +    // The hash of the file path, using method A. +    DWORD dwName1; +     +    // The hash of the file path, using method B. +    DWORD dwName2; + +#ifdef PLATFORM_LITTLE_ENDIAN + +    // The language of the file. This is a Windows LANGID data type, and uses the same values. +    // 0 indicates the default language (American English), or that the file is language-neutral. +    USHORT lcLocale; + +    // The platform the file is used for. 0 indicates the default platform. +    // No other values have been observed. +    BYTE   Platform; +    BYTE   Reserved; + +#else + +    BYTE   Platform; +    BYTE   Reserved; +    USHORT lcLocale; + +#endif + +    // If the hash table entry is valid, this is the index into the block table of the file. +    // Otherwise, one of the following two values: +    //  - FFFFFFFFh: Hash table entry is empty, and has always been empty. +    //               Terminates searches for a given file. +    //  - FFFFFFFEh: Hash table entry is empty, but was valid at some point (a deleted file). +    //               Does not terminate searches for a given file. +    DWORD dwBlockIndex; +} TMPQHash; + +// File description block contains informations about the file +typedef struct _TMPQBlock +{ +    // Offset of the beginning of the file, relative to the beginning of the archive. +    DWORD dwFilePos; +     +    // Compressed file size +    DWORD dwCSize; +     +    // Only valid if the block is a file; otherwise meaningless, and should be 0. +    // If the file is compressed, this is the size of the uncompressed file data. +    DWORD dwFSize;                       +     +    // Flags for the file. See MPQ_FILE_XXXX constants +    DWORD dwFlags;                       +} TMPQBlock; + +// Patch file information, preceding the sector offset table +typedef struct _TPatchInfo +{ +    DWORD dwLength;                             // Length of patch info header, in bytes +    DWORD dwFlags;                              // Flags. 0x80000000 = MD5 (?) +    DWORD dwDataSize;                           // Uncompressed size of the patch file +    BYTE  md5[0x10];                            // MD5 of the entire patch file after decompression + +    // Followed by the sector table (variable length) +} TPatchInfo; + +// This is the combined file entry for maintaining file list in the MPQ. +// This structure is combined from block table, hi-block table, +// (attributes) file and from (listfile). +typedef struct _TFileEntry +{ +    ULONGLONG FileNameHash;                     // Jenkins hash of the file name. Only used when the MPQ has BET table. +    ULONGLONG ByteOffset;                       // Position of the file content in the MPQ, relative to the MPQ header +    ULONGLONG FileTime;                         // FileTime from the (attributes) file. 0 if not present. +    DWORD     dwFileSize;                       // Decompressed size of the file +    DWORD     dwCmpSize;                        // Compressed size of the file (i.e., size of the file data in the MPQ) +    DWORD     dwFlags;                          // File flags (from block table) +    DWORD     dwCrc32;                          // CRC32 from (attributes) file. 0 if not present. +    BYTE      md5[MD5_DIGEST_SIZE];             // File MD5 from the (attributes) file. 0 if not present. +    char * szFileName;                          // File name. NULL if not known. +} TFileEntry; + +// Common header for HET and BET tables +typedef struct _TMPQExtHeader +{ +    DWORD dwSignature;                          // 'HET\x1A' or 'BET\x1A' +    DWORD dwVersion;                            // Version. Seems to be always 1 +    DWORD dwDataSize;                           // Size of the contained table + +    // Followed by the table header +    // Followed by the table data + +} TMPQExtHeader; + +// Structure for HET table header +typedef struct _TMPQHetHeader +{ +    TMPQExtHeader ExtHdr; + +    DWORD dwTableSize;                      // Size of the entire HET table, including HET_TABLE_HEADER (in bytes) +    DWORD dwEntryCount;                     // Number of occupied entries in the HET table +    DWORD dwTotalCount;                     // Total number of entries in the HET table +    DWORD dwNameHashBitSize;                // Size of the name hash entry (in bits) +    DWORD dwIndexSizeTotal;                 // Total size of file index (in bits) +    DWORD dwIndexSizeExtra;                 // Extra bits in the file index +    DWORD dwIndexSize;                      // Effective size of the file index (in bits) +    DWORD dwIndexTableSize;                 // Size of the block index subtable (in bytes) + +} TMPQHetHeader; + +// Structure for BET table header +typedef struct _TMPQBetHeader +{ +    TMPQExtHeader ExtHdr; + +    DWORD dwTableSize;                      // Size of the entire BET table, including the header (in bytes) +    DWORD dwEntryCount;                     // Number of entries in the BET table. Must match HET_TABLE_HEADER::dwEntryCount +    DWORD dwUnknown08; +    DWORD dwTableEntrySize;                 // Size of one table entry (in bits) +    DWORD dwBitIndex_FilePos;               // Bit index of the file position (within the entry record) +    DWORD dwBitIndex_FileSize;              // Bit index of the file size (within the entry record) +    DWORD dwBitIndex_CmpSize;               // Bit index of the compressed size (within the entry record) +    DWORD dwBitIndex_FlagIndex;             // Bit index of the flag index (within the entry record) +    DWORD dwBitIndex_Unknown;               // Bit index of the ??? (within the entry record) +    DWORD dwBitCount_FilePos;               // Bit size of file position (in the entry record) +    DWORD dwBitCount_FileSize;              // Bit size of file size (in the entry record) +    DWORD dwBitCount_CmpSize;               // Bit size of compressed file size (in the entry record) +    DWORD dwBitCount_FlagIndex;             // Bit size of flags index (in the entry record) +    DWORD dwBitCount_Unknown;               // Bit size of ??? (in the entry record) +    DWORD dwBitTotal_NameHash2;             // Total bit size of the NameHash2 +    DWORD dwBitExtra_NameHash2;             // Extra bits in the NameHash2 +    DWORD dwBitCount_NameHash2;             // Effective size of NameHash2 (in bits) +    DWORD dwNameHashArraySize;              // Size of NameHash2 table, in bytes +    DWORD dwFlagCount;                      // Number of flags in the following array + +} TMPQBetHeader; + +// Structure for parsed HET table +typedef struct _TMPQHetTable +{ +    TBitArray * pBetIndexes;                    // Bit array of FileIndex values +    LPBYTE     pNameHashes;                     // Array of NameHash1 values (NameHash1 = upper 8 bits of FileName hashe) +    ULONGLONG  AndMask64;                       // AND mask used for calculating file name hash +    ULONGLONG  OrMask64;                        // OR mask used for setting the highest bit of the file name hash + +    DWORD      dwEntryCount;                    // Number of occupied entries in the HET table +    DWORD      dwTotalCount;                    // Number of entries in both NameHash and FileIndex table +    DWORD      dwNameHashBitSize;               // Size of the name hash entry (in bits) +    DWORD      dwIndexSizeTotal;                // Total size of one entry in pBetIndexes (in bits) +    DWORD      dwIndexSizeExtra;                // Extra bits in the entry in pBetIndexes +    DWORD      dwIndexSize;                     // Effective size of one entry in pBetIndexes (in bits) +} TMPQHetTable; + +// Structure for parsed BET table +typedef struct _TMPQBetTable +{ +    TBitArray * pNameHashes;                    // Array of NameHash2 entries (lower 24 bits of FileName hash) +    TBitArray * pFileTable;                     // Bit-based file table +    LPDWORD pFileFlags;                         // Array of file flags + +    DWORD dwTableEntrySize;                     // Size of one table entry, in bits +    DWORD dwBitIndex_FilePos;                   // Bit index of the file position in the table entry +    DWORD dwBitIndex_FileSize;                  // Bit index of the file size in the table entry +    DWORD dwBitIndex_CmpSize;                   // Bit index of the compressed size in the table entry +    DWORD dwBitIndex_FlagIndex;                 // Bit index of the flag index in the table entry +    DWORD dwBitIndex_Unknown;                   // Bit index of ??? in the table entry +    DWORD dwBitCount_FilePos;                   // Size of file offset (in bits) within table entry +    DWORD dwBitCount_FileSize;                  // Size of file size (in bits) within table entry +    DWORD dwBitCount_CmpSize;                   // Size of compressed file size (in bits) within table entry +    DWORD dwBitCount_FlagIndex;                 // Size of flag index (in bits) within table entry +    DWORD dwBitCount_Unknown;                   // Size of ??? (in bits) within table entry +    DWORD dwBitTotal_NameHash2;                 // Total size of the NameHash2 +    DWORD dwBitExtra_NameHash2;                 // Extra bits in the NameHash2 +    DWORD dwBitCount_NameHash2;                 // Effective size of the NameHash2 +    DWORD dwEntryCount;                         // Number of entries +    DWORD dwFlagCount;                          // Number of file flags in pFileFlags +} TMPQBetTable; + +// Structure for patch prefix +typedef struct _TMPQNamePrefix +{ +    size_t nLength;                             // Length of this patch prefix. Can be 0 +    char szPatchPrefix[1];                      // Patch name prefix (variable length). If not empty, it always starts with backslash. +} TMPQNamePrefix; + +// Structure for name cache +typedef struct _TMPQNameCache +{ +    DWORD FirstNameOffset;                      // Offset of the first name in the name list (in bytes) +    DWORD FreeSpaceOffset;                      // Offset of the first free byte in the name cache (in bytes) +    DWORD TotalCacheSize;                       // Size, in bytes, of the cache. Includes wildcard +    DWORD SearchOffset;                         // Used by SListFileFindFirstFile + +    // Followed by search mask (ASCIIZ, '\0' if none) +    // Followed by name cache (ANSI multistring) + +} TMPQNameCache; + +// Archive handle structure +typedef struct _TMPQArchive +{ +    TFileStream  * pStream;                     // Open stream for the MPQ + +    ULONGLONG      UserDataPos;                 // Position of user data (relative to the begin of the file) +    ULONGLONG      MpqPos;                      // MPQ header offset (relative to the begin of the file) +    ULONGLONG      FileSize;                    // Size of the file at the moment of file open + +    struct _TMPQArchive * haPatch;              // Pointer to patch archive, if any +    struct _TMPQArchive * haBase;               // Pointer to base ("previous version") archive, if any +    TMPQNamePrefix * pPatchPrefix;              // Patch prefix to precede names of patch files + +    TMPQUserData * pUserData;                   // MPQ user data (NULL if not present in the file) +    TMPQHeader   * pHeader;                     // MPQ file header +    TMPQHash     * pHashTable;                  // Hash table +    TMPQHetTable * pHetTable;                   // HET table +    TFileEntry   * pFileTable;                  // File table +    HASH_STRING    pfnHashString;               // Hashing function that will convert the file name into hash +     +    TMPQUserData   UserData;                    // MPQ user data. Valid only when ID_MPQ_USERDATA has been found +    DWORD          HeaderData[MPQ_HEADER_DWORDS];  // Storage for MPQ header + +    DWORD          dwHETBlockSize; +    DWORD          dwBETBlockSize; +    DWORD          dwMaxFileCount;              // Maximum number of files in the MPQ. Also total size of the file table. +    DWORD          dwFileTableSize;             // Current size of the file table, e.g. index of the entry past the last occupied one +    DWORD          dwReservedFiles;             // Number of entries reserved for internal MPQ files (listfile, attributes) +    DWORD          dwSectorSize;                // Default size of one file sector +    DWORD          dwFileFlags1;                // Flags for (listfile) +    DWORD          dwFileFlags2;                // Flags for (attributes) +    DWORD          dwFileFlags3;                // Flags for (signature) +    DWORD          dwAttrFlags;                 // Flags for the (attributes) file, see MPQ_ATTRIBUTE_XXX +    DWORD          dwFlags;                     // See MPQ_FLAG_XXXXX +    DWORD          dwSubType;                   // See MPQ_SUBTYPE_XXX + +    SFILE_ADDFILE_CALLBACK pfnAddFileCB;        // Callback function for adding files +    void         * pvAddFileUserData;           // User data thats passed to the callback + +    SFILE_COMPACT_CALLBACK pfnCompactCB;        // Callback function for compacting the archive +    ULONGLONG      CompactBytesProcessed;       // Amount of bytes that have been processed during a particular compact call +    ULONGLONG      CompactTotalBytes;           // Total amount of bytes to be compacted +    void         * pvCompactUserData;           // User data thats passed to the callback +} TMPQArchive;                                       + +// File handle structure +typedef struct _TMPQFile +{ +    TFileStream  * pStream;                     // File stream. Only used on local files +    TMPQArchive  * ha;                          // Archive handle +    TMPQHash     * pHashEntry;                  // Pointer to hash table entry, if the file was open using hash table +    TFileEntry   * pFileEntry;                  // File entry for the file +    ULONGLONG      RawFilePos;                  // Offset in MPQ archive (relative to file begin) +    ULONGLONG      MpqFilePos;                  // Offset in MPQ archive (relative to MPQ header) +    DWORD          dwHashIndex;                 // Hash table index (0xFFFFFFFF if not used) +    DWORD          dwFileKey;                   // Decryption key +    DWORD          dwFilePos;                   // Current file position +    DWORD          dwMagic;                     // 'FILE' + +    struct _TMPQFile * hfPatch;                 // Pointer to opened patch file + +    TPatchInfo   * pPatchInfo;                  // Patch info block, preceding the sector table +    LPDWORD        SectorOffsets;               // Position of each file sector, relative to the begin of the file. Only for compressed files. +    LPDWORD        SectorChksums;               // Array of sector checksums (either ADLER32 or MD5) values for each file sector +    LPBYTE         pbFileData;                  // Data of the file (single unit files, patched files) +    DWORD          cbFileData;                  // Size of file data +    DWORD          dwCompression0;              // Compression that will be used on the first file sector +    DWORD          dwSectorCount;               // Number of sectors in the file +    DWORD          dwPatchedFileSize;           // Size of patched file. Used when saving patch file to the MPQ +    DWORD          dwDataSize;                  // Size of data in the file (on patch files, this differs from file size in block table entry) + +    LPBYTE         pbFileSector;                // Last loaded file sector. For single unit files, entire file content +    DWORD          dwSectorOffs;                // File position of currently loaded file sector +    DWORD          dwSectorSize;                // Size of the file sector. For single unit files, this is equal to the file size + +    unsigned char  hctx[HASH_STATE_SIZE];       // Hash state for MD5. Used when saving file to MPQ +    DWORD          dwCrc32;                     // CRC32 value, used when saving file to MPQ + +    int            nAddFileError;               // Result of the "Add File" operations + +    bool           bLoadedSectorCRCs;           // If true, we already tried to load sector CRCs +    bool           bCheckSectorCRCs;            // If true, then SFileReadFile will check sector CRCs when reading the file +    bool           bIsWriteHandle;              // If true, this handle has been created by SFileCreateFile +} TMPQFile; + +// Structure for SFileFindFirstFile and SFileFindNextFile +typedef struct _SFILE_FIND_DATA +{ +    char   cFileName[MAX_PATH];                 // Full name of the found file +    char * szPlainName;                         // Plain name of the found file +    DWORD  dwHashIndex;                         // Hash table index for the file (HAH_ENTRY_FREE if no hash table) +    DWORD  dwBlockIndex;                        // Block table index for the file +    DWORD  dwFileSize;                          // File size in bytes +    DWORD  dwFileFlags;                         // MPQ file flags +    DWORD  dwCompSize;                          // Compressed file size +    DWORD  dwFileTimeLo;                        // Low 32-bits of the file time (0 if not present) +    DWORD  dwFileTimeHi;                        // High 32-bits of the file time (0 if not present) +    LCID   lcLocale;                            // Locale version + +} SFILE_FIND_DATA, *PSFILE_FIND_DATA; + +typedef struct _SFILE_CREATE_MPQ +{ +    DWORD cbSize;                               // Size of this structure, in bytes +    DWORD dwMpqVersion;                         // Version of the MPQ to be created +    void *pvUserData;                           // Reserved, must be NULL +    DWORD cbUserData;                           // Reserved, must be 0 +    DWORD dwStreamFlags;                        // Stream flags for creating the MPQ +    DWORD dwFileFlags1;                         // File flags for (listfile). 0 = default +    DWORD dwFileFlags2;                         // File flags for (attributes). 0 = default +    DWORD dwFileFlags3;                         // File flags for (signature). 0 = default +    DWORD dwAttrFlags;                          // Flags for the (attributes) file. If 0, no attributes will be created +    DWORD dwSectorSize;                         // Sector size for compressed files +    DWORD dwRawChunkSize;                       // Size of raw data chunk +    DWORD dwMaxFileCount;                       // File limit for the MPQ + +} SFILE_CREATE_MPQ, *PSFILE_CREATE_MPQ; + +//----------------------------------------------------------------------------- +// Stream support - functions + +// Structure used by FileStream_GetBitmap +typedef struct _TStreamBitmap +{ +    ULONGLONG StreamSize;                       // Size of the stream, in bytes +    DWORD BitmapSize;                           // Size of the block map, in bytes +    DWORD BlockCount;                           // Number of blocks in the stream +    DWORD BlockSize;                            // Size of one block +    DWORD IsComplete;                           // Nonzero if the file is complete + +    // Followed by the BYTE array, each bit means availability of one block + +} TStreamBitmap; + +// UNICODE versions of the file access functions +TFileStream * FileStream_CreateFile(const TCHAR * szFileName, DWORD dwStreamFlags); +TFileStream * FileStream_OpenFile(const TCHAR * szFileName, DWORD dwStreamFlags); +const TCHAR * FileStream_GetFileName(TFileStream * pStream); +size_t FileStream_Prefix(const TCHAR * szFileName, DWORD * pdwProvider); + +bool FileStream_SetCallback(TFileStream * pStream, SFILE_DOWNLOAD_CALLBACK pfnCallback, void * pvUserData); + +bool FileStream_GetBitmap(TFileStream * pStream, void * pvBitmap, DWORD cbBitmap, LPDWORD pcbLengthNeeded); +bool FileStream_Read(TFileStream * pStream, ULONGLONG * pByteOffset, void * pvBuffer, DWORD dwBytesToRead); +bool FileStream_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite); +bool FileStream_SetSize(TFileStream * pStream, ULONGLONG NewFileSize); +bool FileStream_GetSize(TFileStream * pStream, ULONGLONG * pFileSize); +bool FileStream_GetPos(TFileStream * pStream, ULONGLONG * pByteOffset); +bool FileStream_GetTime(TFileStream * pStream, ULONGLONG * pFT); +bool FileStream_GetFlags(TFileStream * pStream, LPDWORD pdwStreamFlags); +bool FileStream_Replace(TFileStream * pStream, TFileStream * pNewStream); +void FileStream_Close(TFileStream * pStream); + +//----------------------------------------------------------------------------- +// Functions prototypes for Storm.dll + +// Typedefs for functions exported by Storm.dll +typedef LCID  (WINAPI * SFILESETLOCALE)(LCID); +typedef bool  (WINAPI * SFILEOPENARCHIVE)(const char *, DWORD, DWORD, HANDLE *); +typedef bool  (WINAPI * SFILECLOSEARCHIVE)(HANDLE); +typedef bool  (WINAPI * SFILEOPENFILEEX)(HANDLE, const char *, DWORD, HANDLE *); +typedef bool  (WINAPI * SFILECLOSEFILE)(HANDLE); +typedef DWORD (WINAPI * SFILEGETFILESIZE)(HANDLE, LPDWORD); +typedef DWORD (WINAPI * SFILESETFILEPOINTER)(HANDLE, LONG, LONG *, DWORD); +typedef bool  (WINAPI * SFILEREADFILE)(HANDLE, void *, DWORD, LPDWORD, LPOVERLAPPED); + +//----------------------------------------------------------------------------- +// Functions for manipulation with StormLib global flags + +LCID   WINAPI SFileGetLocale(); +LCID   WINAPI SFileSetLocale(LCID lcNewLocale); + +//----------------------------------------------------------------------------- +// Functions for archive manipulation + +bool   WINAPI SFileOpenArchive(const TCHAR * szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE * phMpq); +bool   WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwCreateFlags, DWORD dwMaxFileCount, HANDLE * phMpq); +bool   WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCreateInfo, HANDLE * phMpq); + +bool   WINAPI SFileSetDownloadCallback(HANDLE hMpq, SFILE_DOWNLOAD_CALLBACK DownloadCB, void * pvUserData); +bool   WINAPI SFileFlushArchive(HANDLE hMpq); +bool   WINAPI SFileCloseArchive(HANDLE hMpq); + +// Adds another listfile into MPQ. The currently added listfile(s) remain, +// so you can use this API to combining more listfiles. +// Note that this function is internally called by SFileFindFirstFile +int    WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile); + +// Archive compacting +bool   WINAPI SFileSetCompactCallback(HANDLE hMpq, SFILE_COMPACT_CALLBACK CompactCB, void * pvUserData); +bool   WINAPI SFileCompactArchive(HANDLE hMpq, const char * szListFile, bool bReserved); + +// Changing the maximum file count +DWORD  WINAPI SFileGetMaxFileCount(HANDLE hMpq); +bool   WINAPI SFileSetMaxFileCount(HANDLE hMpq, DWORD dwMaxFileCount); + +// Changing (attributes) file +DWORD  WINAPI SFileGetAttributes(HANDLE hMpq); +bool   WINAPI SFileSetAttributes(HANDLE hMpq, DWORD dwFlags); +bool   WINAPI SFileUpdateFileAttributes(HANDLE hMpq, const char * szFileName); + +//----------------------------------------------------------------------------- +// Functions for manipulation with patch archives + +bool   WINAPI SFileOpenPatchArchive(HANDLE hMpq, const TCHAR * szPatchMpqName, const char * szPatchPathPrefix, DWORD dwFlags); +bool   WINAPI SFileIsPatchedArchive(HANDLE hMpq); + +//----------------------------------------------------------------------------- +// Functions for file manipulation + +// Reading from MPQ file +bool   WINAPI SFileHasFile(HANDLE hMpq, const char * szFileName); +bool   WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope, HANDLE * phFile); +DWORD  WINAPI SFileGetFileSize(HANDLE hFile, LPDWORD pdwFileSizeHigh); +DWORD  WINAPI SFileSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * plFilePosHigh, DWORD dwMoveMethod); +bool   WINAPI SFileReadFile(HANDLE hFile, void * lpBuffer, DWORD dwToRead, LPDWORD pdwRead, LPOVERLAPPED lpOverlapped); +bool   WINAPI SFileCloseFile(HANDLE hFile); + +// Retrieving info about a file in the archive +bool   WINAPI SFileGetFileInfo(HANDLE hMpqOrFile, SFileInfoClass InfoClass, void * pvFileInfo, DWORD cbFileInfo, LPDWORD pcbLengthNeeded); +bool   WINAPI SFileGetFileName(HANDLE hFile, char * szFileName); +bool   WINAPI SFileFreeFileInfo(void * pvFileInfo, SFileInfoClass InfoClass); + +// High-level extract function +bool   WINAPI SFileExtractFile(HANDLE hMpq, const char * szToExtract, const TCHAR * szExtracted, DWORD dwSearchScope); + +//----------------------------------------------------------------------------- +// Functions for file and archive verification + +// Generates file CRC32 +bool   WINAPI SFileGetFileChecksums(HANDLE hMpq, const char * szFileName, LPDWORD pdwCrc32, char * pMD5); + +// Verifies file against its checksums stored in (attributes) attributes (depending on dwFlags). +// For dwFlags, use one or more of MPQ_ATTRIBUTE_MD5 +DWORD  WINAPI SFileVerifyFile(HANDLE hMpq, const char * szFileName, DWORD dwFlags); + +// Verifies raw data of the archive. Only works for MPQs version 4 or newer +int    WINAPI SFileVerifyRawData(HANDLE hMpq, DWORD dwWhatToVerify, const char * szFileName); + +// Verifies the signature, if present +bool   WINAPI SFileSignArchive(HANDLE hMpq, DWORD dwSignatureType); +DWORD  WINAPI SFileVerifyArchive(HANDLE hMpq); + +//----------------------------------------------------------------------------- +// Functions for file searching + +HANDLE WINAPI SFileFindFirstFile(HANDLE hMpq, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const char * szListFile); +bool   WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData); +bool   WINAPI SFileFindClose(HANDLE hFind); + +HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData); +bool   WINAPI SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData); +bool   WINAPI SListFileFindClose(HANDLE hFind); + +// Locale support +int    WINAPI SFileEnumLocales(HANDLE hMpq, const char * szFileName, LCID * plcLocales, LPDWORD pdwMaxLocales, DWORD dwSearchScope); + +//----------------------------------------------------------------------------- +// Support for adding files to the MPQ + +bool   WINAPI SFileCreateFile(HANDLE hMpq, const char * szArchivedName, ULONGLONG FileTime, DWORD dwFileSize, LCID lcLocale, DWORD dwFlags, HANDLE * phFile); +bool   WINAPI SFileWriteFile(HANDLE hFile, const void * pvData, DWORD dwSize, DWORD dwCompression); +bool   WINAPI SFileFinishFile(HANDLE hFile); + +bool   WINAPI SFileAddFileEx(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwCompression, DWORD dwCompressionNext); +bool   WINAPI SFileAddFile(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags);  +bool   WINAPI SFileAddWave(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwQuality);  +bool   WINAPI SFileRemoveFile(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope); +bool   WINAPI SFileRenameFile(HANDLE hMpq, const char * szOldFileName, const char * szNewFileName); +bool   WINAPI SFileSetFileLocale(HANDLE hFile, LCID lcNewLocale); +bool   WINAPI SFileSetDataCompression(DWORD DataCompression); + +bool   WINAPI SFileSetAddFileCallback(HANDLE hMpq, SFILE_ADDFILE_CALLBACK AddFileCB, void * pvUserData); + +//----------------------------------------------------------------------------- +// Compression and decompression + +int    WINAPI SCompImplode    (void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); +int    WINAPI SCompExplode    (void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); +int    WINAPI SCompCompress   (void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, unsigned uCompressionMask, int nCmpType, int nCmpLevel); +int    WINAPI SCompDecompress (void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); +int    WINAPI SCompDecompress2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); + +//----------------------------------------------------------------------------- +// Non-Windows support for SetLastError/GetLastError + +#ifndef PLATFORM_WINDOWS + +void  SetLastError(int err); +int   GetLastError(); + +#endif + +//----------------------------------------------------------------------------- +// Functions from Storm.dll. They use slightly different names for keeping +// possibility to use them together with StormLib (StormXXX instead of SFileXXX) + +#ifdef __LINK_STORM_DLL__ +  #define STORM_ALTERNATE_NAMES         // Force storm_dll.h to use alternate fnc names +  #include "..\storm_dll\storm_dll.h" +#endif // __LINK_STORM_DLL__ + +#ifdef __cplusplus +}   // extern "C" +#endif + +#endif  // __STORMLIB_H__ diff --git a/src/StormPort.h b/src/StormPort.h new file mode 100644 index 0000000..25134b9 --- /dev/null +++ b/src/StormPort.h @@ -0,0 +1,291 @@ +/*****************************************************************************/ +/* StormPort.h                           Copyright (c) Marko Friedemann 2001 */ +/*---------------------------------------------------------------------------*/ +/* Portability module for the StormLib library. Contains a wrapper symbols   */ +/* to make the compilation under Linux work                                  */ +/*                                                                           */ +/* Author: Marko Friedemann <marko.friedemann@bmx-chemnitz.de>               */ +/* Created at: Mon Jan 29 18:26:01 CEST 2001                                 */ +/* Computer: whiplash.flachland-chemnitz.de                                  */ +/* System: Linux 2.4.0 on i686                                               */ +/*                                                                           */ +/* Author: Sam Wilkins <swilkins1337@gmail.com>                              */ +/* System: Mac OS X and port to big endian processor                         */ +/*                                                                           */ +/*---------------------------------------------------------------------------*/ +/*   Date    Ver   Who  Comment                                              */ +/* --------  ----  ---  -------                                              */ +/* 29.01.01  1.00  Mar  Created                                              */ +/* 24.03.03  1.01  Lad  Some cosmetic changes                                */ +/* 12.11.03  1.02  Dan  Macintosh compatibility                              */ +/* 24.07.04  1.03  Sam  Mac OS X compatibility                               */ +/* 22.11.06  1.04  Sam  Mac OS X compatibility (for StormLib 6.0)            */ +/* 31.12.06  1.05  XPinguin  Full GNU/Linux compatibility		             */ +/* 17.10.12  1.05  Lad  Moved error codes so they don't overlap with errno.h */ +/*****************************************************************************/ + +#ifndef __STORMPORT_H__ +#define __STORMPORT_H__ + +#ifndef __cplusplus +  #define bool char +  #define true 1 +  #define false 0 +#endif + +//----------------------------------------------------------------------------- +// Defines for Windows + +#if !defined(PLATFORM_DEFINED) && defined(_WIN32) + +  // In MSVC 8.0, there are some functions declared as deprecated. +  #if _MSC_VER >= 1400 +  #define _CRT_SECURE_NO_DEPRECATE +  #define _CRT_NON_CONFORMING_SWPRINTFS +  #endif + +  #include <tchar.h> +  #include <assert.h> +  #include <ctype.h> +  #include <stdio.h> +  #include <windows.h> +  #include <wininet.h> +  #define PLATFORM_LITTLE_ENDIAN + +  #ifdef _WIN64 +    #define PLATFORM_64BIT +  #else +    #define PLATFORM_32BIT +  #endif + +  #define PLATFORM_WINDOWS +  #define PLATFORM_DEFINED                  // The platform is known now + +#endif + +//----------------------------------------------------------------------------- +// Defines for Mac + +#if !defined(PLATFORM_DEFINED) && defined(__APPLE__)  // Mac BSD API + +  // Macintosh +  #include <sys/types.h> +  #include <sys/stat.h> +  #include <sys/mman.h> +  #include <unistd.h> +  #include <fcntl.h> +  #include <stdlib.h> +  #include <errno.h> + +  // Support for PowerPC on Max OS X +  #if (__ppc__ == 1) || (__POWERPC__ == 1) || (_ARCH_PPC == 1) +    #include <stdint.h> +    #include <CoreFoundation/CFByteOrder.h> +  #endif  + +  #define    PKEXPORT +  #define    __SYS_ZLIB +  #define    __SYS_BZLIB + +  #ifndef __BIG_ENDIAN__ +    #define PLATFORM_LITTLE_ENDIAN +  #endif + +  #define PLATFORM_MAC +  #define PLATFORM_DEFINED                  // The platform is known now + +#endif + +//----------------------------------------------------------------------------- +// Assumption: we are not on Windows nor Macintosh, so this must be linux *grin* + +#if !defined(PLATFORM_DEFINED) + +  #include <sys/types.h> +  #include <sys/stat.h> +  #include <sys/mman.h> +  #include <fcntl.h> +  #include <unistd.h> +  #include <stdint.h> +  #include <stdlib.h> +  #include <stdio.h> +  #include <stdarg.h> +  #include <string.h> +  #include <ctype.h> +  #include <assert.h> +  #include <errno.h> + +  #define PLATFORM_LITTLE_ENDIAN +  #define PLATFORM_LINUX +  #define PLATFORM_DEFINED + +#endif + +//----------------------------------------------------------------------------- +// Definition of Windows-specific types for non-Windows platforms + +#ifndef PLATFORM_WINDOWS +  #if __LP64__ +    #define PLATFORM_64BIT +  #else +    #define PLATFORM_32BIT +  #endif + +  // Typedefs for ANSI C +  typedef unsigned char  BYTE; +  typedef unsigned short USHORT; +  typedef int            LONG; +  typedef unsigned int   DWORD; +  typedef unsigned long  DWORD_PTR; +  typedef long           LONG_PTR; +  typedef long           INT_PTR; +  typedef long long      LONGLONG; +  typedef unsigned long long ULONGLONG; +  typedef void         * HANDLE; +  typedef void         * LPOVERLAPPED; // Unsupported on Linux and Mac +  typedef char           TCHAR; +  typedef unsigned int   LCID; +  typedef LONG         * PLONG; +  typedef DWORD        * LPDWORD; +  typedef BYTE         * LPBYTE; + +  #ifdef PLATFORM_32BIT +    #define _LZMA_UINT32_IS_ULONG +  #endif + +  // Some Windows-specific defines +  #ifndef MAX_PATH +    #define MAX_PATH 1024 +  #endif + +  #define WINAPI  + +  #define FILE_BEGIN    SEEK_SET +  #define FILE_CURRENT  SEEK_CUR +  #define FILE_END      SEEK_END + +  #define _T(x)     x +  #define _tcslen   strlen +  #define _tcscpy   strcpy +  #define _tcscat   strcat +  #define _tcschr   strchr +  #define _tcsrchr  strrchr +  #define _tcsstr   strstr +  #define _tcsnicmp strncasecmp +  #define _tprintf  printf +  #define _stprintf sprintf +  #define _tremove  remove + +  #define _stricmp  strcasecmp +  #define _strnicmp strncasecmp +  #define _tcsicmp  strcasecmp +  #define _tcsnicmp strncasecmp + +#endif // !PLATFORM_WINDOWS + +// 64-bit calls are supplied by "normal" calls on Mac +#if defined(PLATFORM_MAC) +  #define stat64  stat +  #define fstat64 fstat +  #define lseek64 lseek +  #define ftruncate64 ftruncate +  #define off64_t off_t +  #define O_LARGEFILE 0 +#endif +                                                 +// Platform-specific error codes for UNIX-based platforms +#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) +  #define ERROR_SUCCESS                  0 +  #define ERROR_FILE_NOT_FOUND           ENOENT +  #define ERROR_ACCESS_DENIED            EPERM +  #define ERROR_INVALID_HANDLE           EBADF +  #define ERROR_NOT_ENOUGH_MEMORY        ENOMEM +  #define ERROR_NOT_SUPPORTED            ENOTSUP +  #define ERROR_INVALID_PARAMETER        EINVAL +  #define ERROR_DISK_FULL                ENOSPC +  #define ERROR_ALREADY_EXISTS           EEXIST +  #define ERROR_INSUFFICIENT_BUFFER      ENOBUFS +  #define ERROR_BAD_FORMAT               1000        // No such error code under Linux +  #define ERROR_NO_MORE_FILES            1001        // No such error code under Linux +  #define ERROR_HANDLE_EOF               1002        // No such error code under Linux +  #define ERROR_CAN_NOT_COMPLETE         1003        // No such error code under Linux +  #define ERROR_FILE_CORRUPT             1004        // No such error code under Linux +#endif + +//----------------------------------------------------------------------------- +// Swapping functions + +#ifdef PLATFORM_LITTLE_ENDIAN +    #define    BSWAP_INT16_UNSIGNED(a)          (a) +    #define    BSWAP_INT16_SIGNED(a)            (a) +    #define    BSWAP_INT32_UNSIGNED(a)          (a) +    #define    BSWAP_INT32_SIGNED(a)            (a) +    #define    BSWAP_INT64_SIGNED(a)            (a) +    #define    BSWAP_INT64_UNSIGNED(a)          (a) +    #define    BSWAP_ARRAY16_UNSIGNED(a,b)      {} +    #define    BSWAP_ARRAY32_UNSIGNED(a,b)      {} +    #define    BSWAP_ARRAY64_UNSIGNED(a,b)      {} +    #define    BSWAP_PART_HEADER(a)             {} +    #define    BSWAP_TMPQHEADER(a,b)            {} +    #define    BSWAP_TMPKHEADER(a)              {} +#else + +#ifdef __cplusplus +  extern "C" { +#endif +    int16_t  SwapInt16(uint16_t); +    uint16_t SwapUInt16(uint16_t); +    int32_t  SwapInt32(uint32_t); +    uint32_t SwapUInt32(uint32_t); +    int64_t  SwapInt64(uint64_t); +    uint64_t SwapUInt64(uint64_t); +    void ConvertUInt16Buffer(void * ptr, size_t length); +    void ConvertUInt32Buffer(void * ptr, size_t length); +    void ConvertUInt64Buffer(void * ptr, size_t length); +    void ConvertTMPQUserData(void *userData); +    void ConvertTMPQHeader(void *header, uint16_t wPart); +    void ConvertTMPKHeader(void *header); +#ifdef __cplusplus +  } +#endif +    #define    BSWAP_INT16_SIGNED(a)            SwapInt16((a)) +    #define    BSWAP_INT16_UNSIGNED(a)          SwapUInt16((a)) +    #define    BSWAP_INT32_SIGNED(a)            SwapInt32((a)) +    #define    BSWAP_INT32_UNSIGNED(a)          SwapUInt32((a)) +    #define    BSWAP_INT64_SIGNED(a)            SwapInt64((a)) +    #define    BSWAP_INT64_UNSIGNED(a)          SwapUInt64((a)) +    #define    BSWAP_ARRAY16_UNSIGNED(a,b)      ConvertUInt16Buffer((a),(b)) +    #define    BSWAP_ARRAY32_UNSIGNED(a,b)      ConvertUInt32Buffer((a),(b)) +    #define    BSWAP_ARRAY64_UNSIGNED(a,b)      ConvertUInt64Buffer((a),(b)) +    #define    BSWAP_TMPQHEADER(a,b)            ConvertTMPQHeader((a),(b)) +    #define    BSWAP_TMPKHEADER(a)              ConvertTMPKHeader((a)) +#endif + +//----------------------------------------------------------------------------- +// Macro for deprecated symbols + +/* +#ifdef _MSC_VER +  #if _MSC_FULL_VER >= 140050320 +    #define STORMLIB_DEPRECATED(_Text) __declspec(deprecated(_Text)) +  #else +    #define STORMLIB_DEPRECATED(_Text) __declspec(deprecated) +  #endif +#else +  #ifdef __GNUC__ +    #define STORMLIB_DEPRECATED(_Text) __attribute__((deprecated)) +  #else +    #define STORMLIB_DEPRECATED(_Text) __attribute__((deprecated(_Text))) +  #endif +#endif + +// When a flag is deprecated, use this macro +#ifndef _STORMLIB_NO_DEPRECATE +  #define STORMLIB_DEPRECATED_FLAG(type, oldflag, newflag)    \ +    const STORMLIB_DEPRECATED(#oldflag " is deprecated. Use " #newflag ". To supress this warning, define _STORMLIB_NO_DEPRECATE") static type oldflag = (type)newflag; +#else +#define STORMLIB_DEPRECATED_FLAG(type, oldflag, newflag) static type oldflag = (type)newflag; +#endif +*/ + +#endif // __STORMPORT_H__  | 
