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