PageRenderTime 72ms CodeModel.GetById 16ms app.highlight 48ms RepoModel.GetById 2ms app.codeStats 0ms

/StormLib/stormlib/StormLib.h

http://ghostcb.googlecode.com/
C++ Header | 644 lines | 329 code | 121 blank | 194 comment | 7 complexity | 1a8ce558f91fbddc79ae4cce0f5be95d MD5 | raw file
  1/*****************************************************************************/
  2/* StormLib.h                        Copyright (c) Ladislav Zezula 1999-2005 */
  3/*---------------------------------------------------------------------------*/
  4/* StormLib library v 5.00                                                   */
  5/*                                                                           */
  6/* Author : Ladislav Zezula                                                  */
  7/* E-mail : ladik@zezula.net                                                 */
  8/* WWW    : http://www.zezula.net                                            */
  9/*---------------------------------------------------------------------------*/
 10/*   Date    Ver   Who  Comment                                              */
 11/* --------  ----  ---  -------                                              */
 12/* xx.xx.99  1.00  Lad  Created                                              */
 13/* 24.03.03  2.50  Lad  Version 2.50                                         */
 14/* 02.04.03  3.00  Lad  Version 3.00 with compression                        */
 15/* 11.04.03  3.01  Lad  Renamed to StormLib.h for compatibility with         */
 16/*                      original headers for Storm.dll                       */
 17/* 10.05.03  3.02  Lad  Added Pkware DCL compression                         */
 18/* 26.05.03  4.00  Lad  Completed all compressions                           */
 19/* 18.06.03  4.01  Lad  Added SFileSetFileLocale                             */
 20/*                      Added SFileExtractFile                               */
 21/* 26.07.03  4.02  Lad  Implemented nameless rename and delete               */
 22/* 26.07.03  4.03  Lad  Added support for protected MPQs                     */
 23/* 28.08.03  4.10  Lad  Fixed bugs that caused StormLib incorrectly work     */
 24/*                      with Diablo I savegames and with files having full   */
 25/*                      hash table                                           */
 26/* 08.12.03  4.11  DCH  Fixed bug in reading file block larger than 0x1000   */
 27/*                      on certain files.                                    */
 28/*                      Fixed bug in AddFile with MPQ_FILE_REPLACE_EXISTING  */
 29/*                      (Thanx Daniel Chiamarello, dchiamarello@madvawes.com)*/
 30/* 21.12.03  4.50  Lad  Completed port for Mac                               */
 31/*                      Fixed bug in compacting (if fsize is mul of 0x1000)  */
 32/*                      Fixed bug in SCompCompress                           */
 33/* 27.05.04  4.51  Lad  Changed memory management from new/delete to our     */
 34/*                      own macros                                           */
 35/* 22.06.04  4.60  Lad  Optimized search. Support for multiple listfiles.    */
 36/* 30.09.04  4.61  Lad  Fixed some bugs (Aaargh !!!)                         */
 37/*                      Correctly works if HashTableSize > BlockTableSize    */
 38/* 29.12.04  4.70  Lad  Fixed compatibility problem with MPQs from WoW       */
 39/* 14.07.05  5.00  Lad  Added the BZLIB compression support                  */
 40/*                      Added suport of files stored as single unit          */
 41/* 17.04.06  5.01  Lad  Converted to MS Visual Studio 8.0                    */
 42/*                      Fixed issue with protected Warcraft 3 protected maps */
 43/* 15.05.06  5.02  Lad  Fixed issue with WoW 1.10+                           */
 44/* 07.09.06  5.10  Lad  Fixed processing files longer than 2GB               */
 45/* 22.11.06  6.00  Lad  Support for MPQ archives V2                          */
 46/* 12.06.07  6.10  Lad  Support for extended file attributes                 */
 47/* 10.09.07  6.12  Lad  Support for MPQs protected by corrupting hash table  */
 48/* 03.12.07  6.13  Lad  Support for MPQs with hash tbl size > block tbl size */
 49/* 07.04.08  6.20  Lad  Added SFileFlushArchive                              */
 50/* 09.04.08        Lad  Removed FilePointer variable from TMPQArchive, as    */
 51/*                      it caused more problems than benefits                */
 52/* 12.05.08  6.22  Lad  Support for w3xMaster map protector                  */
 53/* 05.10.08  6.23  Lad  Support for protectors who set negative values in    */
 54/*                      the table of file blocks                             */
 55/* 26.05.09  6.24  Lad  Fixed search for multiple lang files with deleted    */
 56/*                      entries                                              */
 57/* 03.09.09  6.25  Lad  Fixed decompression bug in huffmann decompression    */
 58/*****************************************************************************/
 59
 60#ifndef __STORMLIB_H_
 61#define __STORMLIB_H_
 62
 63#include "StormPort.h"
 64
 65//-----------------------------------------------------------------------------
 66// Use the apropriate library
 67//
 68// The library type is encoded in the library name as the following
 69// StormLibXYZ.lib
 70// 
 71//  X - D for Debug version, R for Release version
 72//  Y - A for ANSI version, U for Unicode version (Unicode version does not exist yet)
 73//  Z - S for static C library, D for multithreaded DLL C-library
 74//
 75
 76#if defined(_MSC_VER) && !defined (__STORMLIB_SELF__)
 77  #ifdef _DEBUG                                 // DEBUG VERSIONS
 78    #ifdef _DLL                               
 79      #pragma comment(lib, "StormLibDAD.lib")   // Debug Ansi Dynamic version
 80    #else        
 81      #pragma comment(lib, "StormLibDAS.lib")   // Debug Ansi Static version
 82    #endif
 83  #else                                         // RELEASE VERSIONS
 84    #ifdef _DLL
 85      #pragma comment(lib, "StormLibRAD.lib")   // Release Ansi Dynamic version
 86    #else        
 87      #pragma comment(lib, "StormLibRAS.lib")   // Release Ansi Static version
 88    #endif
 89  #endif
 90#endif
 91
 92//-----------------------------------------------------------------------------
 93// Defines
 94
 95#define ID_MPQ            0x1A51504D        // MPQ archive header ID ('MPQ\x1A')
 96#define ID_MPQ_SHUNT      0x1B51504D        // MPQ shunt entry ('MPQ\x1B')
 97
 98#define ERROR_AVI_FILE         10000        // No MPQ file, but AVI file.
 99
100// Values for SFileCreateArchiveEx
101#define HASH_TABLE_SIZE_MIN    0x00004
102#define HASH_TABLE_SIZE_MAX    0x40000
103
104#define HASH_ENTRY_DELETED       0xFFFFFFFE // Block index for deleted hash entry
105#define HASH_ENTRY_FREE          0xFFFFFFFF // Block index for free hash entry
106
107// Values for SFileOpenArchive
108#define SFILE_OPEN_HARD_DISK_FILE   2       // Open the archive on HDD
109#define SFILE_OPEN_CDROM_FILE       3       // Open the archive only if it is on CDROM
110
111// Values for SFileOpenFile
112#define SFILE_OPEN_FROM_MPQ         0       // Open the file from the MPQ archive
113#define SFILE_OPEN_BY_INDEX         1       // The 'szFileName' parameter is actually the file index
114#define SFILE_OPEN_LOCAL_FILE   (DWORD)-1   // Open the file from the MPQ archive
115
116// Flags for TMPQArchive::dwFlags
117#define MPQ_FLAG_CHANGED         0x00000001 // If set, the MPQ has been changed
118#define MPQ_FLAG_PROTECTED       0x00000002 // Set on protected MPQs (like W3M maps)
119
120// Flags for SFileAddFile
121// Note: MPQ_FILE_COMPRESS_PKWARE has been replaced by MPQ_FILE_IMPLODE
122// Note: MPQ_FILE_COMPRESS_MULTI has been replaced by MPQ_FILE_COMPRESS
123#define MPQ_FILE_IMPLODE         0x00000100 // Implode method (By PKWARE Data Compression Library)
124#define MPQ_FILE_COMPRESS        0x00000200 // Compress methods (My various methods)
125#define MPQ_FILE_COMPRESSED      0x0000FF00 // File is compressed
126#define MPQ_FILE_ENCRYPTED       0x00010000 // Indicates whether file is encrypted 
127#define MPQ_FILE_FIXSEED         0x00020000 // File decrypt seed has to be fixed
128#define MPQ_FILE_SINGLE_UNIT     0x01000000 // File is stored as a single unit, rather than split into sectors (Thx, Quantam)
129#define MPQ_FILE_DUMMY_FILE      0x02000000 // The file is only 1 byte long and its name is a hash
130#define MPQ_FILE_HAS_EXTRA       0x04000000 // The file has extra data appended after regular data.
131                                            // Must be with compressed files only
132#define MPQ_FILE_EXISTS          0x80000000 // Set if file exists, reset when the file was deleted
133#define MPQ_FILE_REPLACEEXISTING 0x80000000 // Replace when the file exist (SFileAddFile)
134
135#define MPQ_FILE_VALID_FLAGS     (MPQ_FILE_IMPLODE     |  \
136                                  MPQ_FILE_COMPRESS    |  \
137                                  MPQ_FILE_ENCRYPTED   |  \
138                                  MPQ_FILE_FIXSEED     |  \
139                                  MPQ_FILE_SINGLE_UNIT |  \
140                                  MPQ_FILE_DUMMY_FILE  |  \
141                                  MPQ_FILE_HAS_EXTRA   |  \
142                                  MPQ_FILE_EXISTS)
143
144// Compression types for multilpe compressions
145#define MPQ_COMPRESSION_HUFFMANN    0x01    // Huffmann compression (used on WAVE files only)
146#define MPQ_COMPRESSION_ZLIB        0x02    // ZLIB compression
147#define MPQ_COMPRESSION_PKWARE      0x08    // PKWARE DCL compression
148#define MPQ_COMPRESSION_BZIP2       0x10    // BZIP2 compression
149#define MPQ_COMPRESSION_WAVE_MONO   0x40    // 
150#define MPQ_COMPRESSION_WAVE_STEREO 0x80    // 
151
152
153// Constants for SFileAddWave
154#define MPQ_WAVE_QUALITY_HIGH        0      // Best quality, the worst compression
155#define MPQ_WAVE_QUALITY_MEDIUM      1      // Medium quality, medium compression
156#define MPQ_WAVE_QUALITY_LOW         2      // Low quality, the best compression
157
158// Constants for SFileGetFileInfo
159#define SFILE_INFO_ARCHIVE_SIZE      1      // MPQ size (value from header)
160#define SFILE_INFO_HASH_TABLE_SIZE   2      // Size of hash table, in entries
161#define SFILE_INFO_BLOCK_TABLE_SIZE  3      // Number of entries in the block table
162#define SFILE_INFO_BLOCK_SIZE        4      // Size of file block (in bytes)
163#define SFILE_INFO_HASH_TABLE        5      // Pointer to Hash table (TMPQHash *)
164#define SFILE_INFO_BLOCK_TABLE       6      // Pointer to Block Table (TMPQBlock *)
165#define SFILE_INFO_NUM_FILES         7      // Real number of files within archive
166//------
167#define SFILE_INFO_HASH_INDEX        8      // Hash index of file in MPQ
168#define SFILE_INFO_CODENAME1         9      // The first codename of the file
169#define SFILE_INFO_CODENAME2        10      // The second codename of the file
170#define SFILE_INFO_LOCALEID         11      // Locale ID of file in MPQ
171#define SFILE_INFO_BLOCKINDEX       12      // Index to Block Table
172#define SFILE_INFO_FILE_SIZE        13      // Original file size
173#define SFILE_INFO_COMPRESSED_SIZE  14      // Compressed file size
174#define SFILE_INFO_FLAGS            15      // File flags
175#define SFILE_INFO_POSITION         16      // File position within archive
176#define SFILE_INFO_SEED             17      // File decryption seed
177#define SFILE_INFO_SEED_UNFIXED     18      // Decryption seed not fixed to file pos and size
178
179// Values for compact callback
180#define CCB_CHECKING_FILES           1      // Checking archive (dwParam1 = current, dwParam2 = total)
181#define CCB_CHECKING_HASH_TABLE      2      // Checking hash table (dwParam1 = current, dwParam2 = total)
182#define CCB_COPYING_NON_MPQ_DATA     3      // Copying non-MPQ data: No params used
183#define CCB_COMPACTING_FILES         4      // Compacting archive (dwParam1 = current, dwParam2 = total)
184#define CCB_CLOSING_ARCHIVE          5      // Closing archive: No params used
185                                      
186#define LISTFILE_NAME     "(listfile)"      // Name of internal listfile
187#define SIGNATURE_NAME   "(signature)"      // Name of internal signature
188#define ATTRIBUTES_NAME "(attributes)"      // Name of internal attributes file
189
190#define STORMLIB_VERSION      (0x0619)      // Current version of StormLib
191
192#define MPQ_FORMAT_VERSION_1        0       // Up to The Burning Crusade
193#define MPQ_FORMAT_VERSION_2        1       // The Burning Crusade and newer 
194
195// Flags for SFileOpenArchiveEx
196#define MPQ_OPEN_NO_LISTFILE    0x00000001  // Don't add the internal listfile
197#define MPQ_OPEN_NO_ATTRIBUTES  0x00000002  // Don't open the attributes
198#define MPQ_OPEN_FORCE_MPQ_V1   0x00000004  // Always open the archive as MPQ v 1.00, ignore the "wFormatVersion" variable in the header
199
200// Flags for MPQ attributes
201#define MPQ_ATTRIBUTE_CRC32     0x00000001  // The "(attributes)" contain array of CRC32s
202#define MPQ_ATTRIBUTE_FILETIME  0x00000002  // The "(attributes)" contain array of FILETIMEs
203#define MPQ_ATTRIBUTE_MD5       0x00000004  // The "(attributes)" contain array of MD5s
204
205// Supports archives with size > 4 GB
206// Additional flags for SFileCreateArchiveEx
207#define MPQ_CREATE_ARCHIVE_V1   0x00000000  // Creates archive with size up to 4GB
208#define MPQ_CREATE_ARCHIVE_V2   0x00010000  // Creates archive larger than 4 GB
209#define MPQ_CREATE_ATTRIBUTES   0x00100000  // Also add the (attributes) file
210
211// Formats of (attributes) file
212#define MPQ_ATTRIBUTES_V1       100         // FOrmat version 1.00
213
214//-----------------------------------------------------------------------------
215// Structures
216
217#if (defined(WIN32) || defined(WIN64))
218#include <pshpack1.h>
219#else
220#pragma pack(push,1)
221#endif
222
223struct TMPQFile;
224
225struct TMPQShunt
226{
227    // The ID_MPQ_SHUNT ('MPQ\x1B') signature
228    DWORD dwID;
229
230    DWORD dwUnknown;
231
232    // Position of the MPQ header, relative to the begin of the shunt
233    DWORD dwHeaderPos;
234};
235
236
237// MPQ file header
238struct TMPQHeader
239{
240    // The ID_MPQ ('MPQ\x1A') signature
241    DWORD dwID;                         
242
243    // Size of the archive header
244    DWORD dwHeaderSize;                   
245
246    // Size of MPQ archive
247    // This field is deprecated in the Burning Crusade MoPaQ format, and the size of the archive
248    // is calculated as the size from the beginning of the archive to the end of the hash table,
249    // block table, or extended block table (whichever is largest).
250    DWORD dwArchiveSize;
251
252    // 0 = Original format
253    // 1 = Extended format (The Burning Crusade and newer)
254    USHORT wFormatVersion;
255
256    // Power of two exponent specifying the number of 512-byte disk sectors in each logical sector
257    // in the archive. The size of each logical sector in the archive is 512 * 2^SectorSizeShift.
258    // Bugs in the Storm library dictate that this should always be 3 (4096 byte sectors).
259    USHORT wBlockSize;
260
261    // Offset to the beginning of the hash table, relative to the beginning of the archive.
262    DWORD dwHashTablePos;
263    
264    // Offset to the beginning of the block table, relative to the beginning of the archive.
265    DWORD dwBlockTablePos;
266    
267    // Number of entries in the hash table. Must be a power of two, and must be less than 2^16 for
268    // the original MoPaQ format, or less than 2^20 for the Burning Crusade format.
269    DWORD dwHashTableSize;
270    
271    // Number of entries in the block table
272    DWORD dwBlockTableSize;
273};
274
275
276// Extended MPQ file header. Valid only if wFormatVersion is 1 or higher
277struct TMPQHeader2 : public TMPQHeader
278{
279    // Offset to the beginning of the extended block table, relative to the beginning of the archive.
280    LARGE_INTEGER ExtBlockTablePos;
281
282    // High 16 bits of the hash table offset for large archives.
283    USHORT wHashTablePosHigh;
284
285    // High 16 bits of the block table offset for large archives.
286    USHORT wBlockTablePosHigh;
287};
288
289
290// Hash entry. All files in the archive are searched by their hashes.
291struct TMPQHash
292{
293    // The hash of the file path, using method A.
294    DWORD dwName1;
295    
296    // The hash of the file path, using method B.
297    DWORD dwName2;
298
299#if PLATFORM_LITTLE_ENDIAN
300
301    // The language of the file. This is a Windows LANGID data type, and uses the same values.
302    // 0 indicates the default language (American English), or that the file is language-neutral.
303    USHORT lcLocale;
304
305    // The platform the file is used for. 0 indicates the default platform.
306    // No other values have been observed.
307    USHORT wPlatform;
308
309#else
310
311    USHORT wPlatform;
312    USHORT lcLocale;
313
314#endif
315
316    // If the hash table entry is valid, this is the index into the block table of the file.
317    // Otherwise, one of the following two values:
318    //  - FFFFFFFFh: Hash table entry is empty, and has always been empty.
319    //               Terminates searches for a given file.
320    //  - FFFFFFFEh: Hash table entry is empty, but was valid at some point (a deleted file).
321    //               Does not terminate searches for a given file.
322    DWORD dwBlockIndex;
323};
324
325
326// File description block contains informations about the file
327struct TMPQBlock
328{
329    // Offset of the beginning of the block, relative to the beginning of the archive.
330    DWORD dwFilePos;
331    
332    // Compressed file size
333    DWORD dwCSize;
334    
335    // Only valid if the block is a file; otherwise meaningless, and should be 0.
336    // If the file is compressed, this is the size of the uncompressed file data.
337    DWORD dwFSize;                      
338    
339    // Flags for the file. See MPQ_FILE_XXXX constants
340    DWORD dwFlags;                      
341};
342
343
344// The extended block table was added to support archives larger than 4 gigabytes (2^32 bytes).
345// The table contains the upper bits of the archive offsets for each block in the block table.
346// It is simply an array of int16s, which become bits 32-47 of the archive offsets for each block,
347// with bits 48-63 being zero. Individual blocks in the archive are still limited to 4 gigabytes
348// in size. This table is only present in Burning Crusade format archives that exceed 4 gigabytes size.
349struct TMPQBlockEx
350{
351    USHORT wFilePosHigh;
352};
353
354
355struct TFileNode
356{
357    DWORD dwRefCount;                   // Number of references
358                                        // There can be more files that have the same name.
359                                        // (e.g. multiple language files). We don't want to
360                                        // have an entry for each of them, so the entries will be referenced.
361                                        // When a number of node references reaches zero, 
362                                        // the node will be deleted
363
364    size_t nLength;                     // File name length
365    char  szFileName[1];                // File name, variable length
366};
367
368
369// CRC32 present in the (attributes) file
370struct TMPQCRC32
371{
372    DWORD dwValue;                      // Value of CRC32 for each block
373};
374
375
376// FILETIME present in the (attributes) file
377struct TMPQFileTime
378{
379    DWORD dwFileTimeLow;                // Low DWORD of the FILETIME
380    DWORD dwFileTimeHigh;               // High DWORD of the FILETIME
381};
382
383
384// MD5 presetn in the (attributes) file
385struct TMPQMD5
386{
387    BYTE Value[0x10];                   // 16 bytes of MD5
388};
389
390
391// Data from (attributes) file
392struct TMPQAttr
393{
394    DWORD dwVersion;                    // Version of the (attributes) file. Must be 100 (0x64)
395    DWORD dwFlags;                      // See MPQ_ATTRIBUTE_XXXX
396    TMPQCRC32    * pCrc32;              // Array of CRC32 (NULL if none)
397    TMPQFileTime * pFileTime;           // Array of FILETIME (NULL if not present)
398    TMPQMD5      * pMd5;                // Array of MD5 (NULL if none)
399};
400
401
402#if (defined(WIN32) || defined(WIN64))
403#include <poppack.h>
404#else
405#pragma pack(pop)
406#endif
407
408// Archive handle structure
409struct TMPQArchive
410{
411//  TMPQArchive * pNext;                // Next archive (used by Storm.dll only)
412//  TMPQArchive * pPrev;                // Previous archive (used by Storm.dll only)
413    char          szFileName[MAX_PATH]; // Opened archive file name
414    HANDLE        hFile;                // File handle
415    DWORD         dwPriority;           // Priority of the archive
416    LARGE_INTEGER ShuntPos;             // MPQShunt offset (only valid if a shunt is present)
417    LARGE_INTEGER MpqPos;               // File header offset (relative to the begin of the file)
418    LARGE_INTEGER HashTablePos;         // Hash table offset (relative to the begin of the file)
419    LARGE_INTEGER BlockTablePos;        // Block table offset (relative to the begin of the file)
420    LARGE_INTEGER ExtBlockTablePos;     // Ext. block table offset (relative to the begin of the file)
421    LARGE_INTEGER MpqSize;              // Size of MPQ archive
422
423    TMPQFile    * pLastFile;            // Recently read file
424    DWORD         dwBlockPos;           // Position of loaded block in the file
425    DWORD         dwBlockSize;          // Size of file block
426    BYTE        * pbBlockBuffer;        // Buffer (cache) for file block
427    DWORD         dwBuffPos;            // Position in block buffer
428    TMPQShunt   * pShunt;               // MPQ shunt (NULL if not present in the file)
429    TMPQHeader2 * pHeader;              // MPQ file header
430    TMPQHash    * pHashTable;           // Hash table
431    TMPQBlock   * pBlockTable;          // Block table
432    TMPQBlockEx * pExtBlockTable;       // Extended block table
433    
434    TMPQShunt     Shunt;                // MPQ shunt. Valid only when ID_MPQ_SHUNT has been found
435    TMPQHeader2   Header;               // MPQ header
436
437    TMPQAttr    * pAttributes;          // MPQ attributes from "(attributes)" file (NULL if none)
438    TFileNode  ** pListFile;            // File name array
439    DWORD         dwFlags;              // See MPQ_FLAG_XXXXX
440};
441
442
443// File handle structure
444struct TMPQFile
445{
446    HANDLE         hFile;               // File handle
447    TMPQArchive  * ha;                  // Archive handle
448    TMPQHash     * pHash;               // Hash table entry
449    TMPQBlockEx  * pBlockEx;            // Pointer to extended file block entry
450    TMPQBlock    * pBlock;              // File block pointer
451    DWORD          dwSeed1;             // Seed used for file decrypt
452    DWORD          dwFilePos;           // Current file position
453    LARGE_INTEGER  RawFilePos;          // Offset in MPQ archive (relative to file begin)
454    LARGE_INTEGER  MpqFilePos;          // Offset in MPQ archive (relative to MPQ header)
455
456    DWORD        * pdwBlockPos;         // Position of each file block (only for compressed files)
457    DWORD          nBlocks;             // Number of blocks in the file (incl. the last incomplete one)
458    BOOL           bBlockPosLoaded;     // TRUE if block positions loaded
459    BYTE         * pbFileBuffer;        // Decompressed file (for single unit files, size is the uncompressed file size)
460
461    TMPQCRC32    * pCrc32;              // Pointer to CRC32 (NULL if none)
462    TMPQFileTime * pFileTime;           // Pointer to file's FILETIME (NULL if none)
463    TMPQMD5      * pMd5;                // Pointer to file's MD5 (NULL if none)
464
465    DWORD          dwHashIndex;         // Index to Hash table
466    DWORD          dwBlockIndex;        // Index to Block table
467    char           szFileName[1];       // File name (variable length)
468};
469
470// Used by searching in MPQ archives
471struct TMPQSearch
472{
473    TMPQArchive * ha;                   // Handle to MPQ, where the search runs
474    DWORD  dwNextIndex;                 // Next hash index to be checked
475    DWORD  dwName1;                     // Lastly found Name1
476    DWORD  dwName2;                     // Lastly found Name2
477    char   szSearchMask[1];             // Search mask (variable length)
478};
479
480
481struct SFILE_FIND_DATA
482{
483    char   cFileName[MAX_PATH];         // Full name of the found file
484    char * szPlainName;                 // Pointer to file part
485    LCID   lcLocale;                    // Locale version
486    DWORD  dwFileSize;                  // File size in bytes
487    DWORD  dwFileFlags;                 // File flags (compressed or encrypted)
488    DWORD  dwBlockIndex;                // Block index for the file
489    DWORD  dwCompSize;                  // Compressed file size
490};
491
492//-----------------------------------------------------------------------------
493// Memory management
494//
495// We use our own macros for allocating/freeing memory. If you want
496// to redefine them, please keep the following rules
497//
498//  - The memory allocation must return NULL if not enough memory
499//    (i.e not to throw exception)
500//  - It is not necessary to fill the allocated block with zeros
501//  - Memory freeing function must not test the pointer to NULL.
502//
503
504
505__inline void * DebugMalloc(char * szFile, int nLine, int nSize)
506{
507    void * ptr = malloc(nSize + 100);
508    char * plain;
509
510    plain = strrchr(szFile, '\\');
511    if(plain == NULL)
512        plain = strrchr(szFile, '/');
513    if(plain == NULL)
514        plain = szFile;
515
516#if _MSC_VER > 1300
517    sprintf_s((char *)ptr, nSize+100, "%s(%u)", plain, nLine);
518#else
519    sprintf((char *)ptr, "%s(%u)", plain, nLine);
520#endif
521
522    return (char *)ptr + 100;
523}
524
525
526__inline void DebugFree(void * ptr)
527{
528    free((char *)ptr - 100);
529}
530
531
532#ifndef ALLOCMEM
533  #define ALLOCMEM(type, nitems)   (type *)malloc((nitems) * sizeof(type))
534  #define FREEMEM(ptr) free(ptr)
535#endif
536
537//#define ALLOCMEM(type, nitems)   (type *)DebugMalloc(__FILE__, __LINE__, (nitems) * sizeof(type))
538//#define FREEMEM(ptr) DebugFree(ptr)
539
540//-----------------------------------------------------------------------------
541// Functions in StormLib - compatible with Storm.dll
542
543// Typedefs for functions exported by Storm.dll
544typedef LCID  (WINAPI * SFILESETLOCALE)(LCID);
545typedef BOOL  (WINAPI * SFILEOPENARCHIVE)(const char *, DWORD, DWORD, HANDLE *);
546typedef BOOL  (WINAPI * SFILECLOSEARCHIVE)(HANDLE);
547typedef BOOL  (WINAPI * SFILEOPENFILEEX)(HANDLE, const char *, DWORD, HANDLE *);
548typedef BOOL  (WINAPI * SFILECLOSEFILE)(HANDLE);
549typedef DWORD (WINAPI * SFILEGETFILESIZE)(HANDLE, DWORD *);
550typedef DWORD (WINAPI * SFILESETFILEPOINTER)(HANDLE, LONG, LONG *, DWORD);
551typedef BOOL  (WINAPI * SFILEREADFILE)(HANDLE, VOID *, DWORD, DWORD *, LPOVERLAPPED);
552
553// Archive opening/closing
554LCID  WINAPI SFileSetLocale(LCID lcNewLocale);
555LCID  WINAPI SFileGetLocale();
556BOOL  WINAPI SFileOpenArchive(const char * szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE * phMpq);
557BOOL  WINAPI SFileFlushArchive(HANDLE hMpq);
558BOOL  WINAPI SFileCloseArchive(HANDLE hMpq);
559
560// File opening/closing
561BOOL  WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope, HANDLE * phFile);
562BOOL  WINAPI SFileCloseFile(HANDLE hFile);
563
564// File I/O
565DWORD WINAPI SFileGetFilePos(HANDLE hFile, DWORD * pdwFilePosHigh = NULL);
566DWORD WINAPI SFileGetFileSize(HANDLE hFile, DWORD * pdwFileSizeHigh = NULL);
567DWORD WINAPI SFileSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * pdwFilePosHigh, DWORD dwMethod);
568BOOL  WINAPI SFileReadFile(HANDLE hFile, VOID * lpBuffer, DWORD dwToRead, DWORD * pdwRead = NULL, LPOVERLAPPED lpOverlapped = NULL);
569
570// Adds another listfile into MPQ. The currently added listfile(s) remain,
571// so you can use this API to combining more listfiles.
572// Note that this function is internally called by SFileFindFirstFile
573int   WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile);
574
575//-----------------------------------------------------------------------------
576// Functions in StormLib - not implemented in Storm.dll
577
578// Archive creating and editing
579BOOL  WINAPI SFileCreateArchiveEx(const char * szMpqName, DWORD dwCreationDisposition, DWORD dwHashTableSize, HANDLE * phMpq);
580BOOL  WINAPI SFileAddFile(HANDLE hMpq, const char * szFileName, const char * szArchivedName, DWORD dwFlags); 
581BOOL  WINAPI SFileAddWave(HANDLE hMpq, const char * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwQuality); 
582BOOL  WINAPI SFileRemoveFile(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope = SFILE_OPEN_BY_INDEX);
583BOOL  WINAPI SFileRenameFile(HANDLE hMpq, const char * szOldFileName, const char * szNewFileName);
584BOOL  WINAPI SFileSetFileLocale(HANDLE hFile, LCID lcNewLocale);
585
586// Retrieving info about the file
587BOOL  WINAPI SFileHasFile(HANDLE hMpq, char * szFileName);
588BOOL  WINAPI SFileGetFileName(HANDLE hFile, char * szFileName);
589DWORD_PTR WINAPI SFileGetFileInfo(HANDLE hMpqOrFile, DWORD dwInfoType);
590
591// File search
592// Note that the SFileFindFirstFileEx has been removed. Use SListFileFindFirst/Next
593HANDLE WINAPI SFileFindFirstFile(HANDLE hMpq, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const char * szListFile);
594BOOL   WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData);
595BOOL   WINAPI SFileFindClose(HANDLE hFind);
596
597// Listfile search
598HANDLE SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData);
599BOOL   SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData);
600BOOL   SListFileFindClose(HANDLE hFind);
601
602// Archive compacting
603typedef void  (WINAPI * COMPACTCB)(void * lpUserData, DWORD dwWorkType, DWORD dwParam1, DWORD dwParam2);
604BOOL  WINAPI SFileSetCompactCallback(HANDLE hMpq, COMPACTCB CompactCB, void * lpData);
605BOOL  WINAPI SFileCompactArchive(HANDLE hMpq, const char * szListFile = NULL, BOOL bReserved = 0);
606
607// Locale support
608int   WINAPI SFileEnumLocales(HANDLE hMpq, const char * szFileName, LCID * plcLocales, DWORD * pdwMaxLocales, DWORD dwSearchScope);
609
610// (De)compression
611int WINAPI SCompCompress   (char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int uCompressions, int nCmpType, int nCmpLevel);
612int WINAPI SCompDecompress (char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength);
613
614// Sets the default data compression for files added to MPQ,
615// if MPQ_FILE_COMPRESS_MULTI has been specified in call to SFileAddFile
616// Use one of the MPQ_COMPRESSION_XXX values
617int WINAPI SCompSetDataCompression(int nDataCompression);
618
619// Verifies file against its extended attributes (depending on dwFlags).
620// For dwFlags, use one or more of MPQ_ATTRIBUTE_MD5
621BOOL  WINAPI SFileVerifyFile(HANDLE hMpq, const char * szFileName, DWORD dwFlags);
622
623// High-level extract function
624BOOL  WINAPI SFileExtractFile(HANDLE hMpq, const char * szToExtract, const char * szExtracted);
625
626//-----------------------------------------------------------------------------
627// Functions from Storm.dll. They use slightly different names for keeping
628// possibility to use them together with StormLib (StormXXX instead of SFileXXX)
629
630#ifdef __LINK_STORM_DLL__
631  #define STORM_ALTERNATE_NAMES         // Force Storm.h to use alternate fnc names
632  #include "StormDll.h"
633#endif // __LINK_STORM_DLL__
634
635//-----------------------------------------------------------------------------
636// GFX decode functions. See GfxDecode.cpp for details and description
637
638USHORT  WINAPI celGetFrameCount(BYTE * fileBuf);
639BYTE  * WINAPI celGetFrameData(BYTE *fileBuf, BYTE *palette, USHORT xsize, USHORT frame, USHORT *ysize, USHORT *maxX=NULL);
640USHORT  WINAPI cl2GetFrameCount(BYTE *fileBuf);
641BYTE ** WINAPI cl2GetDirData(BYTE *fileBuf, BYTE *palette, USHORT xsize, USHORT dir, USHORT *ysize);
642BYTE  * WINAPI pcxGetData(BYTE *filebuf, DWORD filesize, BYTE transcol, USHORT *xsize, USHORT *ysize);
643
644#endif  // __STORMLIB_H_