Current News
Archived News
Search News
Discussion Forum


Old Forum
Install Programs More Downloads...
Troubleshooting
Source Code
Format Specs.
Misc. Information
Non-SF Stuff
Links




1 Attribute VB_Name = "SFmpqapi"\r
2 Option Explicit\r
3 \r
4 '  ShadowFlare MPQ API Library. (c) ShadowFlare Software 2002\r
5 \r
6 '  All functions below are actual functions that are part of this\r
7 '  library and do not need any additional dll files.  It does not\r
8 '  even require Storm to be able to decompress or compress files.\r
9 \r
10 '  This library emulates the interface of Lmpqapi and Storm MPQ\r
11 '  functions, so it may be used as a replacement for them in\r
12 '  MPQ extractors/archivers without even needing to recompile\r
13 '  the program that uses Lmpqapi or Storm.  It has a few features\r
14 '  not included in Lmpqapi and Storm, such as extra flags for some\r
15 '  functions, setting the locale ID of existing files, and adding\r
16 '  files without having to write them somewhere else first.  Also,\r
17 '  MPQ handles used by functions prefixed with "SFile" and "Mpq"\r
18 '  can be used interchangably; all functions use the same type\r
19 '  of MPQ handles.  You cannot, however, use handles from this\r
20 '  library with storm or lmpqapi or vice-versa.  Doing so will\r
21 '  most likely result in a crash.\r
22 \r
23 '  Revision History:\r
24 '  06/12/2002 1.07 (ShadowFlare)\r
25 '  - No longer requires Storm.dll to compress or decompress\r
26 '    Warcraft III files\r
27 '  - Added SFileListFiles for getting names and information\r
28 '    about all of the files in an archive\r
29 '  - Fixed a bug with renaming and deleting files\r
30 '  - Fixed a bug with adding wave compressed files with\r
31 '    low compression setting\r
32 '  - Added a check in MpqOpenArchiveForUpdate for proper\r
33 '    dwMaximumFilesInArchive values (should be a number that\r
34 '    is a power of 2).  If it is not a proper value, it will\r
35 '    be rounded up to the next higher power of 2\r
36 \r
37 '  05/09/2002 1.06 (ShadowFlare)\r
38 '  - Compresses files without Storm.dll!\r
39 '  - If Warcraft III is installed, this library will be able to\r
40 '    find Storm.dll on its own. (Storm.dll is needed to\r
41 '    decompress Warcraft III files)\r
42 '  - Fixed a bug where an embedded archive and the file that\r
43 '    contains it would be corrupted if the archive was modified\r
44 '  - Able to open all .w3m maps now\r
45 \r
46 '  29/06/2002 1.05 (ShadowFlare)\r
47 '  - Supports decompressing files from Warcraft III MPQ archives\r
48 '    if using Storm.dll from Warcraft III\r
49 '  - Added MpqAddFileToArchiveEx and MpqAddFileFromBufferEx for\r
50 '    using extra compression types\r
51 \r
52 '  29/05/2002 1.04 (ShadowFlare)\r
53 '  - Files can be compressed now!\r
54 '  - Fixed a bug in SFileReadFile when reading data not aligned\r
55 '    to the block size\r
56 '  - Optimized some of SFileReadFile's code.  It can read files\r
57 '    faster now\r
58 '  - SFile functions may now be used to access files not in mpq\r
59 '    archives as you can with the real storm functions\r
60 '  - MpqCompactArchive will no longer corrupt files with the\r
61 '    MODCRYPTKEY flag as long as the file is either compressed,\r
62 '    listed in "(listfile)", is "(listfile)", or is located in\r
63 '    the same place in the compacted archive; so it is safe\r
64 '    enough to use it on almost any archive\r
65 '  - Added MpqAddWaveFromBuffer\r
66 '  - Better handling of archives with no files\r
67 '  - Fixed compression with COMPRESS2 flag\r
68 \r
69 '  15/05/2002 1.03 (ShadowFlare)\r
70 '  - Supports adding files with the compression attribute (does\r
71 '    not actually compress files).  Now archives created with\r
72 '    this dll can have files added to them through lmpqapi\r
73 '    without causing staredit to crash\r
74 '  - SFileGetBasePath and SFileSetBasePath work more like their\r
75 '    Storm equivalents now\r
76 '  - Implemented MpqCompactArchive, but it is not finished yet.\r
77 '    In its current state, I would recommend against using it\r
78 '    on archives that contain files with the MODCRYPTKEY flag,\r
79 '    since it will corrupt any files with that flag\r
80 '  - Added SFMpqGetVersionString2 which may be used in Visual\r
81 '    Basic to get the version string\r
82 \r
83 '  07/05/2002 1.02 (ShadowFlare)\r
84 '  - SFileReadFile no longer passes the lpOverlapped parameter it\r
85 '    receives to ReadFile.  This is what was causing the function\r
86 '    to fail when used in Visual Basic\r
87 '  - Added support for more Storm MPQ functions\r
88 '  - GetLastError may now be used to get information about why a\r
89 '    function failed\r
90 \r
91 '  01/05/2002 1.01 (ShadowFlare)\r
92 '  - Added ordinals for Storm MPQ functions\r
93 '  - Fixed MPQ searching functionality of SFileOpenFileEx\r
94 '  - Added a check for whether a valid handle is given when\r
95 '    SFileCloseArchive is called\r
96 '  - Fixed functionality of SFileSetArchivePriority when multiple\r
97 '    files are open\r
98 '  - File renaming works for all filenames now\r
99 '  - SFileReadFile no longer reallocates the buffer for each block\r
100 '    that is decompressed.  This should make SFileReadFile at least\r
101 '    a little faster\r
102 \r
103 '  30/04/2002 1.00 (ShadowFlare)\r
104 '  - First version.\r
105 '  - Compression not yet supported\r
106 '  - Does not use SetLastError yet, so GetLastError will not return any\r
107 '    errors that have to do with this library\r
108 '  - MpqCompactArchive not implemented\r
109 \r
110 '  This library is freeware, you can do anything you want with it but with\r
111 '  one exception.  If you use it in your program, you must specify this fact\r
112 '  in Help|About box or in similar way.  You can obtain version string using\r
113 '  SFMpqGetVersionString call.\r
114 \r
115 '  THIS LIBRARY IS DISTRIBUTED "AS IS".  NO WARRANTY OF ANY KIND IS EXPRESSED\r
116 '  OR IMPLIED. YOU USE AT YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR\r
117 '  DATA LOSS, DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING\r
118 '  OR MISUSING THIS SOFTWARE.\r
119 \r
120 '  Any comments or suggestions are accepted at blakflare@hotmail.com (ShadowFlare)\r
121 \r
122 Type SFMPQVERSION\r
123     Major As Integer\r
124     Minor As Integer\r
125     Revision As Integer\r
126     Subrevision As Integer\r
127 End Type\r
128 \r
129 ' MpqInitialize does nothing.  It is only provided for\r
130 ' compatibility with MPQ archivers that use lmpqapi.\r
131 Declare Function MpqInitialize Lib "SFmpq.dll" () As Boolean\r
132 \r
133 Declare Function MpqGetVersionString Lib "SFmpq.dll" () As String\r
134 Declare Function MpqGetVersion Lib "SFmpq.dll" () As Single\r
135 \r
136 Declare Sub SFMpqDestroy Lib "SFmpq.dll" () ' This no longer needs to be called.  It is only provided for compatibility with older versions\r
137 \r
138 ' SFMpqGetVersionString2's return value is the required length of the buffer plus\r
139 ' the terminating null, so use SFMpqGetVersionString2(ByVal 0&, 0) to get the length.\r
140 Declare Function SFMpqGetVersionString Lib "SFmpq.dll" () As String\r
141 Declare Function SFMpqGetVersionString2 Lib "SFmpq.dll" (ByVal lpBuffer As String, ByVal dwBufferLength As Long) As Long\r
142 Declare Function SFMpqGetVersion Lib "SFmpq.dll" () As SFMPQVERSION\r
143 \r
144 ' General error codes\r
145 Public Const MPQ_ERROR_MPQ_INVALID As Long = &H85200065\r
146 Public Const MPQ_ERROR_FILE_NOT_FOUND As Long = &H85200066\r
147 Public Const MPQ_ERROR_DISK_FULL As Long = &H85200068 'Physical write file to MPQ failed. Not sure of exact meaning\r
148 Public Const MPQ_ERROR_HASH_TABLE_FULL As Long = &H85200069\r
149 Public Const MPQ_ERROR_ALREADY_EXISTS As Long = &H8520006A\r
150 Public Const MPQ_ERROR_BAD_OPEN_MODE As Long = &H8520006C 'When MOAU_READ_ONLY is used without MOAU_OPEN_EXISTING\r
151 \r
152 Public Const MPQ_ERROR_COMPACT_ERROR As Long = &H85300001\r
153 \r
154 ' MpqOpenArchiveForUpdate flags\r
155 Public Const MOAU_CREATE_NEW As Long = &H0\r
156 Public Const MOAU_CREATE_ALWAYS As Long = &H8 'Was wrongly named MOAU_CREATE_NEW\r
157 Public Const MOAU_OPEN_EXISTING As Long = &H4\r
158 Public Const MOAU_OPEN_ALWAYS As Long = &H20\r
159 Public Const MOAU_READ_ONLY As Long = &H10 'Must be used with MOAU_OPEN_EXISTING\r
160 Public Const MOAU_MAINTAIN_LISTFILE As Long = &H1\r
161 \r
162 ' MpqOpenArchiveForUpdateEx constants\r
163 Public Const DEFAULT_BLOCK_SIZE As Long = 3 ' 512 << number = block size\r
164 Public Const USE_DEFAULT_BLOCK_SIZE As Long = &HFFFF ' Use default block size that is defined internally\r
165 \r
166 ' MpqAddFileToArchive flags\r
167 Public Const MAFA_EXISTS As Long = &H80000000 'Will be added if not present\r
168 Public Const MAFA_UNKNOWN40000000 As Long = &H40000000\r
169 Public Const MAFA_MODCRYPTKEY As Long = &H20000\r
170 Public Const MAFA_ENCRYPT As Long = &H10000\r
171 Public Const MAFA_COMPRESS As Long = &H200\r
172 Public Const MAFA_COMPRESS2 As Long = &H100\r
173 Public Const MAFA_REPLACE_EXISTING As Long = &H1\r
174 \r
175 ' MpqAddFileToArchiveEx compression flags\r
176 Public Const MAFA_COMPRESS_STANDARD As Long = &H8 'Standard PKWare DCL compression\r
177 Public Const MAFA_COMPRESS_DEFLATE  As Long = &H2 'ZLib's deflate compression\r
178 Public Const MAFA_COMPRESS_BZIP2   As Long = &H10 'bzip2 compression\r
179 Public Const MAFA_COMPRESS_WAVE    As Long = &H81 'Stereo wave compression\r
180 Public Const MAFA_COMPRESS_WAVE2   As Long = &H41 'Mono wave compression\r
181 \r
182 ' Flags for individual compression types used for wave compression\r
183 Public Const MAFA_COMPRESS_WAVECOMP1 As Long = &H80 'Main compressor for stereo wave compression\r
184 Public Const MAFA_COMPRESS_WAVECOMP2 As Long = &H40 'Main compressor for mono wave compression\r
185 Public Const MAFA_COMPRESS_WAVECOMP3  As Long = &H1 'Secondary compressor for wave compression\r
186 \r
187 ' ZLib deflate compression level constants (used with MpqAddFileToArchiveEx and MpqAddFileFromBufferEx)\r
188 Public Const Z_NO_COMPRESSION         As Long = 0\r
189 Public Const Z_BEST_SPEED             As Long = 1\r
190 Public Const Z_BEST_COMPRESSION       As Long = 9\r
191 Public Const Z_DEFAULT_COMPRESSION  As Long = (-1)\r
192 \r
193 ' MpqAddWAVToArchive quality flags\r
194 Public Const MAWA_QUALITY_HIGH As Long = 1\r
195 Public Const MAWA_QUALITY_MEDIUM As Long = 0\r
196 Public Const MAWA_QUALITY_LOW As Long = 2\r
197 \r
198 ' SFileGetFileInfo flags\r
199 Public Const SFILE_INFO_BLOCK_SIZE As Long = &H1 'Block size in MPQ\r
200 Public Const SFILE_INFO_HASH_TABLE_SIZE As Long = &H2 'Hash table size in MPQ\r
201 Public Const SFILE_INFO_NUM_FILES As Long = &H3 'Number of files in MPQ\r
202 Public Const SFILE_INFO_TYPE As Long = &H4 'Is Long a file or an MPQ?\r
203 Public Const SFILE_INFO_SIZE As Long = &H5 'Size of MPQ or uncompressed file\r
204 Public Const SFILE_INFO_COMPRESSED_SIZE As Long = &H6 'Size of compressed file\r
205 Public Const SFILE_INFO_FLAGS As Long = &H7 'File flags (compressed, etc.), file attributes if a file not in an archive\r
206 Public Const SFILE_INFO_PARENT As Long = &H8 'Handle of MPQ that file is in\r
207 Public Const SFILE_INFO_POSITION As Long = &H9 'Position of file pointer in files\r
208 Public Const SFILE_INFO_LOCALEID As Long = &HA 'Locale ID of file in MPQ\r
209 Public Const SFILE_INFO_PRIORITY As Long = &HB 'Priority of open MPQ\r
210 Public Const SFILE_INFO_HASH_INDEX As Long = &HC 'Hash index of file in MPQ\r
211 \r
212 ' SFileListFiles flags\r
213 Public Const SFILE_LIST_MEMORY_LIST  As Long = &H1 ' Specifies that lpFilelists is a file list from memory, rather than being a list of file lists\r
214 Public Const SFILE_LIST_ONLY_KNOWN   As Long = &H2 ' Only list files that the function finds a name for\r
215 Public Const SFILE_LIST_ONLY_UNKNOWN As Long = &H4 ' Only list files that the function does not find a name for\r
216 \r
217 Public Const SFILE_TYPE_MPQ As Long = &H1\r
218 Public Const SFILE_TYPE_FILE As Long = &H2\r
219 \r
220 Public Const INVALID_HANDLE_VALUE As Long = -1\r
221 \r
222 Public Const FILE_BEGIN   As Long = 0\r
223 Public Const FILE_CURRENT As Long = 1\r
224 Public Const FILE_END     As Long = 2\r
225 \r
226 Public Const SFILE_OPEN_HARD_DISK_FILE As Long = &H0 'Open archive without regard to the drive type it resides on\r
227 Public Const SFILE_OPEN_CD_ROM_FILE As Long = &H1 'Open the archive only if it is on a CD-ROM\r
228 Public Const SFILE_OPEN_ALLOW_WRITE As Long = &H8000 'Open file with write access\r
229 \r
230 Public Const SFILE_SEARCH_CURRENT_ONLY As Long = &H0 'Used with SFileOpenFileEx; only the archive with the handle specified will be searched for the file\r
231 Public Const SFILE_SEARCH_ALL_OPEN As Long = &H1 'SFileOpenFileEx will look through all open archives for the file\r
232 \r
233 Type FILELISTENTRY\r
234     dwFileExists As Long ' Nonzero if this entry is used\r
235     lcLocale As Long ' Locale ID of file\r
236     dwCompressedSize As Long ' Compressed size of file\r
237     dwFullSize As Long ' Uncompressed size of file\r
238     dwFlags As Long ' Flags for file\r
239     szFileName(259) As Byte\r
240 End Type\r
241 \r
242 ' Storm functions implemented by this library\r
243 Declare Function SFileOpenArchive Lib "SFmpq.dll" (ByVal lpFileName As String, ByVal dwPriority As Long, ByVal dwFlags As Long, ByRef hMPQ As Long) As Boolean\r
244 Declare Function SFileCloseArchive Lib "SFmpq.dll" (ByVal hMPQ As Long) As Boolean\r
245 Declare Function SFileGetArchiveName Lib "SFmpq.dll" (ByVal hMPQ As Long, ByVal lpBuffer As String, ByVal dwBufferLength As Long) As Boolean\r
246 Declare Function SFileOpenFile Lib "SFmpq.dll" (ByVal lpFileName As String, ByRef hFile As Long) As Boolean\r
247 Declare Function SFileOpenFileEx Lib "SFmpq.dll" (ByVal hMPQ As Long, ByVal lpFileName As String, ByVal dwSearchScope As Long, ByRef hFile As Long) As Boolean\r
248 Declare Function SFileCloseFile Lib "SFmpq.dll" (ByVal hFile As Long) As Boolean\r
249 Declare Function SFileGetFileSize Lib "SFmpq.dll" (ByVal hFile As Long, lpFileSizeHigh As Long) As Long\r
250 Declare Function SFileGetFileArchive Lib "SFmpq.dll" (ByVal hFile As Long, ByRef hMPQ As Long) As Boolean\r
251 Declare Function SFileGetFileName Lib "SFmpq.dll" (ByVal hMPQ As Long, ByVal lpBuffer As String, ByVal dwBufferLength As Long) As Boolean\r
252 Declare Function SFileSetFilePointer Lib "SFmpq.dll" (ByVal hFile As Long, ByVal lDistanceToMove As Long, lplDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long\r
253 Declare Function SFileReadFile Lib "SFmpq.dll" (ByVal hFile As Long, ByRef lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByRef lpOverlapped As Any) As Boolean\r
254 Declare Function SFileSetLocale Lib "SFmpq.dll" (ByVal nNewLocale As Long) As Long\r
255 Declare Function SFileGetBasePath Lib "SFmpq.dll" (ByVal lpBuffer As String, ByVal dwBufferLength As Long) As Boolean\r
256 Declare Function SFileSetBasePath Lib "SFmpq.dll" (ByVal lpNewBasePath As String) As Boolean\r
257 \r
258 ' Extra storm-related functions\r
259 Declare Function SFileGetFileInfo Lib "SFmpq.dll" (ByVal hFile As Long, ByVal dwInfoType As Long) As Long\r
260 Declare Function SFileSetArchivePriority Lib "SFmpq.dll" (ByVal hMPQ As Long, ByVal dwPriority As Long) As Boolean\r
261 Declare Function SFileFindMpqHeader Lib "SFmpq.dll" (ByVal hFile As Long) As Long\r
262 Declare Function SFileListFiles Lib "SFmpq.dll" (ByVal hMPQ As Long, ByVal lpFileLists As String, ByRef lpListBuffer As FILELISTENTRY, ByVal dwFlags As Long) As Boolean\r
263 \r
264 ' Archive editing functions implemented by this library\r
265 Declare Function MpqOpenArchiveForUpdate Lib "SFmpq.dll" (ByVal lpFileName As String, ByVal dwFlags As Long, ByVal dwMaximumFilesInArchive As Long) As Long\r
266 Declare Function MpqCloseUpdatedArchive Lib "SFmpq.dll" (ByVal hMPQ As Long, ByVal dwUnknown2 As Long) As Long\r
267 Declare Function MpqAddFileToArchive Lib "SFmpq.dll" (ByVal hMPQ As Long, ByVal lpSourceFileName As String, ByVal lpDestFileName As String, ByVal dwFlags As Long) As Boolean\r
268 Declare Function MpqAddWaveToArchive Lib "SFmpq.dll" (ByVal hMPQ As Long, ByVal lpSourceFileName As String, ByVal lpDestFileName As String, ByVal dwFlags As Long, ByVal dwQuality As Long) As Boolean\r
269 Declare Function MpqRenameFile Lib "SFmpq.dll" (ByVal hMPQ As Long, ByVal lpcOldFileName As String, ByVal lpcNewFileName As String) As Boolean\r
270 Declare Function MpqDeleteFile Lib "SFmpq.dll" (ByVal hMPQ As Long, ByVal lpFileName As String) As Boolean\r
271 Declare Function MpqCompactArchive Lib "SFmpq.dll" (ByVal hMPQ As Long) As Boolean\r
272 \r
273 ' Extra archive editing functions\r
274 Declare Function MpqOpenArchiveForUpdateEx Lib "SFmpq.dll" (ByVal lpFileName As String, ByVal dwFlags As Long, ByVal dwMaximumFilesInArchive As Long, ByVal dwBlockSize As Long) As Long\r
275 Declare Function MpqAddFileToArchiveEx Lib "SFmpq.dll" (ByVal hMPQ As Long, ByVal lpSourceFileName As String, ByVal lpDestFileName As String, ByVal dwFlags As Long, ByVal dwCompressionType As Long, ByVal dwCompressLevel As Long) As Boolean\r
276 Declare Function MpqAddFileFromBufferEx Lib "SFmpq.dll" (ByVal hMPQ As Long, ByRef lpBuffer As Any, ByVal dwLength As Long, ByVal lpFileName As String, ByVal dwFlags As Long, ByVal dwCompressionType As Long, ByVal dwCompressLevel As Long) As Boolean\r
277 Declare Function MpqAddFileFromBuffer Lib "SFmpq.dll" (ByVal hMPQ As Long, ByRef lpBuffer As Any, ByVal dwLength As Long, ByVal lpFileName As String, ByVal dwFlags As Long) As Boolean\r
278 Declare Function MpqAddWaveFromBuffer Lib "SFmpq.dll" (ByVal hMPQ As Long, ByRef lpBuffer As Any, ByVal dwLength As Long, ByVal lpFileName As String, ByVal dwFlags As Long, ByVal dwQuality As Long) As Boolean\r
279 Declare Function MpqSetFileLocale Lib "SFmpq.dll" (ByVal hMPQ As Long, ByVal lpFileName As String, ByVal nOldLocale As Long, ByVal nNewLocale As Long) As Boolean\r
280 \r
281 ' These functions do nothing.  They are only provided for\r
282 ' compatibility with MPQ extractors that use storm.\r
283 Declare Function SFileDestroy Lib "SFmpq.dll" () As Boolean\r
284 Declare Sub StormDestroy Lib "SFmpq.dll" ()\r
285 \r
286 ' Returns 0 if the dll version is equal to the version your program was compiled\r
287 ' with, 1 if the dll is newer, -1 if the dll is older.\r
288 Function SFMpqCompareVersion() As Long\r
289     Dim ExeVersion As SFMPQVERSION, DllVersion As SFMPQVERSION\r
290     With ExeVersion\r
291         .Major = 1\r
292         .Minor = 0\r
293         .Revision = 7\r
294         .Subrevision = 4\r
295     End With\r
296     DllVersion = SFMpqGetVersion()\r
297     If DllVersion.Major > ExeVersion.Major Then\r
298         SFMpqCompareVersion = 1\r
299         Exit Function\r
300     ElseIf DllVersion.Major < ExeVersion.Major Then\r
301         SFMpqCompareVersion = -1\r
302         Exit Function\r
303     End If\r
304     If DllVersion.Minor > ExeVersion.Minor Then\r
305         SFMpqCompareVersion = 1\r
306         Exit Function\r
307     ElseIf DllVersion.Minor < ExeVersion.Minor Then\r
308         SFMpqCompareVersion = -1\r
309         Exit Function\r
310     End If\r
311     If DllVersion.Revision > ExeVersion.Revision Then\r
312         SFMpqCompareVersion = 1\r
313         Exit Function\r
314     ElseIf DllVersion.Revision < ExeVersion.Revision Then\r
315         SFMpqCompareVersion = -1\r
316         Exit Function\r
317     End If\r
318     If DllVersion.Subrevision > ExeVersion.Subrevision Then\r
319         SFMpqCompareVersion = 1\r
320         Exit Function\r
321     ElseIf DllVersion.Subrevision < ExeVersion.Subrevision Then\r
322         SFMpqCompareVersion = -1\r
323         Exit Function\r
324     End If\r
325     SFMpqCompareVersion = 0\r
326 End Function\r
327 \r