diff --git a/OpenSource/StormLib/StormLib.xcodeproj/project.pbxproj b/OpenSource/StormLib/StormLib.xcodeproj/project.pbxproj
new file mode 100644
index 000000000..cc77a682d
--- /dev/null
+++ b/OpenSource/StormLib/StormLib.xcodeproj/project.pbxproj
@@ -0,0 +1,2104 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		221F6A741168529C0026C852 /* LzmaDec.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6A721168529C0026C852 /* LzmaDec.h */; };
+		221F6A751168529C0026C852 /* LzmaEnc.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6A731168529C0026C852 /* LzmaEnc.h */; };
+		221F6A761168529C0026C852 /* LzmaDec.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6A721168529C0026C852 /* LzmaDec.h */; };
+		221F6A771168529C0026C852 /* LzmaEnc.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6A731168529C0026C852 /* LzmaEnc.h */; };
+		221F6A7B116852AA0026C852 /* LzmaEnc.c in Sources */ = {isa = PBXBuildFile; fileRef = 221F6A7A116852AA0026C852 /* LzmaEnc.c */; };
+		221F6A7C116852AA0026C852 /* LzmaEnc.c in Sources */ = {isa = PBXBuildFile; fileRef = 221F6A7A116852AA0026C852 /* LzmaEnc.c */; };
+		221F6A7E116852B20026C852 /* LzmaDec.c in Sources */ = {isa = PBXBuildFile; fileRef = 221F6A7D116852B20026C852 /* LzmaDec.c */; };
+		221F6A7F116852B20026C852 /* LzmaDec.c in Sources */ = {isa = PBXBuildFile; fileRef = 221F6A7D116852B20026C852 /* LzmaDec.c */; };
+		221F6AB51168545B0026C852 /* LzFind.c in Sources */ = {isa = PBXBuildFile; fileRef = 221F6AB31168545B0026C852 /* LzFind.c */; };
+		221F6AB61168545B0026C852 /* LzFind.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6AB41168545B0026C852 /* LzFind.h */; };
+		221F6AB71168545B0026C852 /* LzFind.c in Sources */ = {isa = PBXBuildFile; fileRef = 221F6AB31168545B0026C852 /* LzFind.c */; };
+		221F6AB81168545B0026C852 /* LzFind.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6AB41168545B0026C852 /* LzFind.h */; };
+		221F6ABA116854730026C852 /* LzHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6AB9116854730026C852 /* LzHash.h */; };
+		221F6ABB116854730026C852 /* LzHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6AB9116854730026C852 /* LzHash.h */; };
+		221F6ABD116854870026C852 /* Types.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6ABC116854870026C852 /* Types.h */; };
+		221F6ABE116854870026C852 /* Types.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6ABC116854870026C852 /* Types.h */; };
+		2254917B11948CE70044424D /* crypt_ltc_mp_descriptor.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184811933FCF0083AC69 /* crypt_ltc_mp_descriptor.c */; settings = {COMPILER_FLAGS = "-fno-common"; }; };
+		225530DB1056BC7900FA646A /* huff.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED009D0D03542A00AB0B4E /* huff.h */; };
+		225530DE1056BC7900FA646A /* pklib.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED00A80D03542A00AB0B4E /* pklib.h */; };
+		225530DF1056BC7900FA646A /* StormCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED00AB0D03542A00AB0B4E /* StormCommon.h */; };
+		225530E01056BC7900FA646A /* StormLib.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED00B60D03542A00AB0B4E /* StormLib.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		225530E11056BC7900FA646A /* StormPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED00B70D03542A00AB0B4E /* StormPort.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		225530E31056BC8700FA646A /* huff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED009C0D03542A00AB0B4E /* huff.cpp */; };
+		225530E61056BC8700FA646A /* explode.c in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00A60D03542A00AB0B4E /* explode.c */; };
+		225530E71056BC8700FA646A /* implode.c in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00A70D03542A00AB0B4E /* implode.c */; };
+		225530E81056BC8700FA646A /* SFileAttributes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00A90D03542A00AB0B4E /* SFileAttributes.cpp */; };
+		225530E91056BC8700FA646A /* SBaseCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AA0D03542A00AB0B4E /* SBaseCommon.cpp */; };
+		225530EA1056BC8700FA646A /* SCompression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AC0D03542A00AB0B4E /* SCompression.cpp */; };
+		225530EB1056BC8700FA646A /* SFileCompactArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AD0D03542A00AB0B4E /* SFileCompactArchive.cpp */; };
+		225530EC1056BC8700FA646A /* SFileCreateArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AE0D03542A00AB0B4E /* SFileCreateArchive.cpp */; };
+		225530ED1056BC8700FA646A /* SFileExtractFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AF0D03542A00AB0B4E /* SFileExtractFile.cpp */; };
+		225530EE1056BC8700FA646A /* SFileFindFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B00D03542A00AB0B4E /* SFileFindFile.cpp */; };
+		225530EF1056BC8700FA646A /* SFileOpenArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B10D03542A00AB0B4E /* SFileOpenArchive.cpp */; };
+		225530F01056BC8700FA646A /* SFileOpenFileEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B20D03542A00AB0B4E /* SFileOpenFileEx.cpp */; };
+		225530F11056BC8700FA646A /* SFileReadFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B30D03542A00AB0B4E /* SFileReadFile.cpp */; };
+		225530F21056BC8700FA646A /* SFileListFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B40D03542A00AB0B4E /* SFileListFile.cpp */; };
+		225C734D1257CCC70009E8DA /* lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = 225C734B1257CCC70009E8DA /* lookup.h */; };
+		225C734F1257CCC70009E8DA /* lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = 225C734B1257CCC70009E8DA /* lookup.h */; };
+		225C73501257CCC70009E8DA /* lookup3.c in Sources */ = {isa = PBXBuildFile; fileRef = 225C734C1257CCC70009E8DA /* lookup3.c */; };
+		225C73541257CD0C0009E8DA /* SBaseFileTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 225C73531257CD0C0009E8DA /* SBaseFileTable.cpp */; };
+		225C73551257CD0C0009E8DA /* SBaseFileTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 225C73531257CD0C0009E8DA /* SBaseFileTable.cpp */; };
+		225C735A1257CD1F0009E8DA /* lookup3.c in Sources */ = {isa = PBXBuildFile; fileRef = 225C734C1257CCC70009E8DA /* lookup3.c */; };
+		225FAC9C0E53BAA100DA2CAE /* huff.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED009D0D03542A00AB0B4E /* huff.h */; };
+		225FAC9F0E53BAA100DA2CAE /* pklib.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED00A80D03542A00AB0B4E /* pklib.h */; };
+		225FACA00E53BAA100DA2CAE /* StormCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED00AB0D03542A00AB0B4E /* StormCommon.h */; };
+		225FACA10E53BAA100DA2CAE /* StormLib.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED00B60D03542A00AB0B4E /* StormLib.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		225FACA20E53BAA100DA2CAE /* StormPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED00B70D03542A00AB0B4E /* StormPort.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		225FACA50E53BAB400DA2CAE /* huff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED009C0D03542A00AB0B4E /* huff.cpp */; };
+		225FACA90E53BAB400DA2CAE /* explode.c in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00A60D03542A00AB0B4E /* explode.c */; };
+		225FACAA0E53BAB400DA2CAE /* implode.c in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00A70D03542A00AB0B4E /* implode.c */; };
+		225FACAB0E53BAB400DA2CAE /* SFileAttributes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00A90D03542A00AB0B4E /* SFileAttributes.cpp */; };
+		225FACAC0E53BAB400DA2CAE /* SBaseCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AA0D03542A00AB0B4E /* SBaseCommon.cpp */; };
+		225FACAD0E53BAB400DA2CAE /* SCompression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AC0D03542A00AB0B4E /* SCompression.cpp */; };
+		225FACAE0E53BAB400DA2CAE /* SFileCompactArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AD0D03542A00AB0B4E /* SFileCompactArchive.cpp */; };
+		225FACAF0E53BAB400DA2CAE /* SFileCreateArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AE0D03542A00AB0B4E /* SFileCreateArchive.cpp */; };
+		225FACB00E53BAB400DA2CAE /* SFileExtractFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AF0D03542A00AB0B4E /* SFileExtractFile.cpp */; };
+		225FACB10E53BAB400DA2CAE /* SFileFindFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B00D03542A00AB0B4E /* SFileFindFile.cpp */; };
+		225FACB20E53BAB400DA2CAE /* SFileOpenArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B10D03542A00AB0B4E /* SFileOpenArchive.cpp */; };
+		225FACB30E53BAB400DA2CAE /* SFileOpenFileEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B20D03542A00AB0B4E /* SFileOpenFileEx.cpp */; };
+		225FACB40E53BAB400DA2CAE /* SFileReadFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B30D03542A00AB0B4E /* SFileReadFile.cpp */; };
+		225FACB50E53BAB400DA2CAE /* SFileListFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B40D03542A00AB0B4E /* SFileListFile.cpp */; };
+		225FADD40E53C06600DA2CAE /* libbz2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 32D20A8A0CF3902D00230E7A /* libbz2.dylib */; settings = {ATTRIBUTES = (Required, ); }; };
+		225FADD50E53C06600DA2CAE /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 32D20A8B0CF3902D00230E7A /* libz.dylib */; settings = {ATTRIBUTES = (Required, ); }; };
+		226C7CA71857DE9400AB689C /* SBaseDumpData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 226C7CA61857DE9400AB689C /* SBaseDumpData.cpp */; };
+		226C7CA81857DE9400AB689C /* SBaseDumpData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 226C7CA61857DE9400AB689C /* SBaseDumpData.cpp */; };
+		226C7CAA1857DEAC00AB689C /* SBaseSubTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 226C7CA91857DEAC00AB689C /* SBaseSubTypes.cpp */; };
+		226C7CAB1857DEAC00AB689C /* SBaseSubTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 226C7CA91857DEAC00AB689C /* SBaseSubTypes.cpp */; };
+		226C7CAD1857DEEB00AB689C /* SFileGetFileInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 226C7CAC1857DEEB00AB689C /* SFileGetFileInfo.cpp */; };
+		226C7CAE1857DEEB00AB689C /* SFileGetFileInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 226C7CAC1857DEEB00AB689C /* SFileGetFileInfo.cpp */; };
+		228B538411BF7D0D001A58DA /* FileStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 228B538311BF7D0D001A58DA /* FileStream.cpp */; };
+		228B538511BF7D0D001A58DA /* FileStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 228B538311BF7D0D001A58DA /* FileStream.cpp */; };
+		22954AD211D463AB0064B264 /* Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2295488911D45A820064B264 /* Test.cpp */; };
+		22954AD311D463B50064B264 /* libStormLib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 225530D41056BAC800FA646A /* libStormLib.a */; };
+		22954AD611D463BE0064B264 /* libbz2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 32D20A8A0CF3902D00230E7A /* libbz2.dylib */; };
+		22954AD711D463BE0064B264 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 32D20A8B0CF3902D00230E7A /* libz.dylib */; };
+		2299D9D71167EFA8005C19BF /* adpcm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2299D9D51167EFA8005C19BF /* adpcm.cpp */; };
+		2299D9D81167EFA8005C19BF /* adpcm.h in Headers */ = {isa = PBXBuildFile; fileRef = 2299D9D61167EFA8005C19BF /* adpcm.h */; };
+		2299D9D91167EFA8005C19BF /* adpcm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2299D9D51167EFA8005C19BF /* adpcm.cpp */; };
+		2299D9DA1167EFA8005C19BF /* adpcm.h in Headers */ = {isa = PBXBuildFile; fileRef = 2299D9D61167EFA8005C19BF /* adpcm.h */; };
+		2299D9DE1167EFC6005C19BF /* sparse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2299D9DC1167EFC6005C19BF /* sparse.cpp */; };
+		2299D9DF1167EFC6005C19BF /* sparse.h in Headers */ = {isa = PBXBuildFile; fileRef = 2299D9DD1167EFC6005C19BF /* sparse.h */; };
+		2299D9E01167EFC6005C19BF /* sparse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2299D9DC1167EFC6005C19BF /* sparse.cpp */; };
+		2299D9E11167EFC6005C19BF /* sparse.h in Headers */ = {isa = PBXBuildFile; fileRef = 2299D9DD1167EFC6005C19BF /* sparse.h */; };
+		2299DA4E1167FD16005C19BF /* SFileAddFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2299DA4D1167FD16005C19BF /* SFileAddFile.cpp */; };
+		2299DA4F1167FD16005C19BF /* SFileAddFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2299DA4D1167FD16005C19BF /* SFileAddFile.cpp */; };
+		22AEA122123125D800359B16 /* SFilePatchArchives.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 22AEA121123125D800359B16 /* SFilePatchArchives.cpp */; };
+		22AEA123123125D800359B16 /* SFilePatchArchives.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 22AEA121123125D800359B16 /* SFilePatchArchives.cpp */; };
+		22C9187D11933FCF0083AC69 /* hash_memory.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9182B11933FCF0083AC69 /* hash_memory.c */; };
+		22C9187E11933FCF0083AC69 /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9182C11933FCF0083AC69 /* md5.c */; };
+		22C9187F11933FCF0083AC69 /* sha1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9182D11933FCF0083AC69 /* sha1.c */; };
+		22C9188011933FCF0083AC69 /* tomcrypt.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9182F11933FCF0083AC69 /* tomcrypt.h */; };
+		22C9188111933FCF0083AC69 /* tomcrypt_argchk.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183011933FCF0083AC69 /* tomcrypt_argchk.h */; };
+		22C9188211933FCF0083AC69 /* tomcrypt_cfg.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183111933FCF0083AC69 /* tomcrypt_cfg.h */; };
+		22C9188311933FCF0083AC69 /* tomcrypt_cipher.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183211933FCF0083AC69 /* tomcrypt_cipher.h */; };
+		22C9188411933FCF0083AC69 /* tomcrypt_custom.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183311933FCF0083AC69 /* tomcrypt_custom.h */; };
+		22C9188511933FCF0083AC69 /* tomcrypt_hash.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183411933FCF0083AC69 /* tomcrypt_hash.h */; };
+		22C9188611933FCF0083AC69 /* tomcrypt_mac.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183511933FCF0083AC69 /* tomcrypt_mac.h */; };
+		22C9188711933FCF0083AC69 /* tomcrypt_macros.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183611933FCF0083AC69 /* tomcrypt_macros.h */; };
+		22C9188811933FCF0083AC69 /* tomcrypt_math.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183711933FCF0083AC69 /* tomcrypt_math.h */; };
+		22C9188911933FCF0083AC69 /* tomcrypt_misc.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183811933FCF0083AC69 /* tomcrypt_misc.h */; };
+		22C9188A11933FCF0083AC69 /* tomcrypt_pk.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183911933FCF0083AC69 /* tomcrypt_pk.h */; };
+		22C9188B11933FCF0083AC69 /* tomcrypt_pkcs.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183A11933FCF0083AC69 /* tomcrypt_pkcs.h */; };
+		22C9188C11933FCF0083AC69 /* tomcrypt_prng.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183B11933FCF0083AC69 /* tomcrypt_prng.h */; };
+		22C9188D11933FCF0083AC69 /* ltm_desc.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9183D11933FCF0083AC69 /* ltm_desc.c */; };
+		22C9188E11933FCF0083AC69 /* multi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9183E11933FCF0083AC69 /* multi.c */; };
+		22C9188F11933FCF0083AC69 /* rand_prime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9183F11933FCF0083AC69 /* rand_prime.c */; };
+		22C9189011933FCF0083AC69 /* base64_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184111933FCF0083AC69 /* base64_decode.c */; };
+		22C9189111933FCF0083AC69 /* crypt_argchk.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184211933FCF0083AC69 /* crypt_argchk.c */; };
+		22C9189211933FCF0083AC69 /* crypt_find_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184311933FCF0083AC69 /* crypt_find_hash.c */; };
+		22C9189311933FCF0083AC69 /* crypt_find_prng.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184411933FCF0083AC69 /* crypt_find_prng.c */; };
+		22C9189411933FCF0083AC69 /* crypt_hash_descriptor.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184511933FCF0083AC69 /* crypt_hash_descriptor.c */; };
+		22C9189511933FCF0083AC69 /* crypt_hash_is_valid.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184611933FCF0083AC69 /* crypt_hash_is_valid.c */; };
+		22C9189611933FCF0083AC69 /* crypt_libc.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184711933FCF0083AC69 /* crypt_libc.c */; };
+		22C9189811933FCF0083AC69 /* crypt_prng_descriptor.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184911933FCF0083AC69 /* crypt_prng_descriptor.c */; };
+		22C9189911933FCF0083AC69 /* crypt_prng_is_valid.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184A11933FCF0083AC69 /* crypt_prng_is_valid.c */; };
+		22C9189A11933FCF0083AC69 /* crypt_register_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184B11933FCF0083AC69 /* crypt_register_hash.c */; };
+		22C9189B11933FCF0083AC69 /* crypt_register_prng.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184C11933FCF0083AC69 /* crypt_register_prng.c */; };
+		22C9189C11933FCF0083AC69 /* zeromem.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184D11933FCF0083AC69 /* zeromem.c */; };
+		22C9189D11933FCF0083AC69 /* der_decode_bit_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185011933FCF0083AC69 /* der_decode_bit_string.c */; };
+		22C9189E11933FCF0083AC69 /* der_decode_boolean.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185111933FCF0083AC69 /* der_decode_boolean.c */; };
+		22C9189F11933FCF0083AC69 /* der_decode_choice.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185211933FCF0083AC69 /* der_decode_choice.c */; };
+		22C918A011933FCF0083AC69 /* der_decode_ia5_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185311933FCF0083AC69 /* der_decode_ia5_string.c */; };
+		22C918A111933FCF0083AC69 /* der_decode_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185411933FCF0083AC69 /* der_decode_integer.c */; };
+		22C918A211933FCF0083AC69 /* der_decode_object_identifier.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185511933FCF0083AC69 /* der_decode_object_identifier.c */; };
+		22C918A311933FCF0083AC69 /* der_decode_octet_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185611933FCF0083AC69 /* der_decode_octet_string.c */; };
+		22C918A411933FCF0083AC69 /* der_decode_printable_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185711933FCF0083AC69 /* der_decode_printable_string.c */; };
+		22C918A511933FCF0083AC69 /* der_decode_sequence_ex.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185811933FCF0083AC69 /* der_decode_sequence_ex.c */; };
+		22C918A611933FCF0083AC69 /* der_decode_sequence_flexi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185911933FCF0083AC69 /* der_decode_sequence_flexi.c */; };
+		22C918A711933FCF0083AC69 /* der_decode_sequence_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185A11933FCF0083AC69 /* der_decode_sequence_multi.c */; };
+		22C918A811933FCF0083AC69 /* der_decode_short_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185B11933FCF0083AC69 /* der_decode_short_integer.c */; };
+		22C918A911933FCF0083AC69 /* der_decode_utctime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185C11933FCF0083AC69 /* der_decode_utctime.c */; };
+		22C918AA11933FCF0083AC69 /* der_decode_utf8_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185D11933FCF0083AC69 /* der_decode_utf8_string.c */; };
+		22C918AB11933FCF0083AC69 /* der_length_bit_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185E11933FCF0083AC69 /* der_length_bit_string.c */; };
+		22C918AC11933FCF0083AC69 /* der_length_boolean.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185F11933FCF0083AC69 /* der_length_boolean.c */; };
+		22C918AD11933FCF0083AC69 /* der_length_ia5_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186011933FCF0083AC69 /* der_length_ia5_string.c */; };
+		22C918AE11933FCF0083AC69 /* der_length_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186111933FCF0083AC69 /* der_length_integer.c */; };
+		22C918AF11933FCF0083AC69 /* der_length_object_identifier.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186211933FCF0083AC69 /* der_length_object_identifier.c */; };
+		22C918B011933FCF0083AC69 /* der_length_octet_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186311933FCF0083AC69 /* der_length_octet_string.c */; };
+		22C918B111933FCF0083AC69 /* der_length_printable_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186411933FCF0083AC69 /* der_length_printable_string.c */; };
+		22C918B211933FCF0083AC69 /* der_length_sequence.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186511933FCF0083AC69 /* der_length_sequence.c */; };
+		22C918B311933FCF0083AC69 /* der_length_short_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186611933FCF0083AC69 /* der_length_short_integer.c */; };
+		22C918B411933FCF0083AC69 /* der_length_utctime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186711933FCF0083AC69 /* der_length_utctime.c */; };
+		22C918B511933FCF0083AC69 /* der_length_utf8_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186811933FCF0083AC69 /* der_length_utf8_string.c */; };
+		22C918B611933FCF0083AC69 /* der_sequence_free.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186911933FCF0083AC69 /* der_sequence_free.c */; };
+		22C918B711933FCF0083AC69 /* ltc_ecc_map.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186B11933FCF0083AC69 /* ltc_ecc_map.c */; };
+		22C918B811933FCF0083AC69 /* ltc_ecc_mul2add.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186C11933FCF0083AC69 /* ltc_ecc_mul2add.c */; };
+		22C918B911933FCF0083AC69 /* ltc_ecc_mulmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186D11933FCF0083AC69 /* ltc_ecc_mulmod.c */; };
+		22C918BA11933FCF0083AC69 /* ltc_ecc_points.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186E11933FCF0083AC69 /* ltc_ecc_points.c */; };
+		22C918BB11933FCF0083AC69 /* ltc_ecc_projective_add_point.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186F11933FCF0083AC69 /* ltc_ecc_projective_add_point.c */; };
+		22C918BC11933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187011933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c */; };
+		22C918BD11933FCF0083AC69 /* pkcs_1_mgf1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187211933FCF0083AC69 /* pkcs_1_mgf1.c */; };
+		22C918BE11933FCF0083AC69 /* pkcs_1_oaep_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187311933FCF0083AC69 /* pkcs_1_oaep_decode.c */; };
+		22C918BF11933FCF0083AC69 /* pkcs_1_pss_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187411933FCF0083AC69 /* pkcs_1_pss_decode.c */; };
+		22C918C011933FCF0083AC69 /* pkcs_1_v1_5_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187511933FCF0083AC69 /* pkcs_1_v1_5_decode.c */; };
+		22C918C111933FCF0083AC69 /* rsa_exptmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187711933FCF0083AC69 /* rsa_exptmod.c */; };
+		22C918C211933FCF0083AC69 /* rsa_free.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187811933FCF0083AC69 /* rsa_free.c */; };
+		22C918C311933FCF0083AC69 /* rsa_import.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187911933FCF0083AC69 /* rsa_import.c */; };
+		22C918C411933FCF0083AC69 /* rsa_make_key.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187A11933FCF0083AC69 /* rsa_make_key.c */; };
+		22C918C511933FCF0083AC69 /* rsa_verify_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187B11933FCF0083AC69 /* rsa_verify_hash.c */; };
+		22C918C611933FCF0083AC69 /* rsa_verify_simple.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187C11933FCF0083AC69 /* rsa_verify_simple.c */; };
+		22C918C711933FCF0083AC69 /* hash_memory.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9182B11933FCF0083AC69 /* hash_memory.c */; };
+		22C918C811933FCF0083AC69 /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9182C11933FCF0083AC69 /* md5.c */; };
+		22C918C911933FCF0083AC69 /* sha1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9182D11933FCF0083AC69 /* sha1.c */; };
+		22C918CA11933FCF0083AC69 /* tomcrypt.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9182F11933FCF0083AC69 /* tomcrypt.h */; };
+		22C918CB11933FCF0083AC69 /* tomcrypt_argchk.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183011933FCF0083AC69 /* tomcrypt_argchk.h */; };
+		22C918CC11933FCF0083AC69 /* tomcrypt_cfg.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183111933FCF0083AC69 /* tomcrypt_cfg.h */; };
+		22C918CD11933FCF0083AC69 /* tomcrypt_cipher.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183211933FCF0083AC69 /* tomcrypt_cipher.h */; };
+		22C918CE11933FCF0083AC69 /* tomcrypt_custom.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183311933FCF0083AC69 /* tomcrypt_custom.h */; };
+		22C918CF11933FCF0083AC69 /* tomcrypt_hash.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183411933FCF0083AC69 /* tomcrypt_hash.h */; };
+		22C918D011933FCF0083AC69 /* tomcrypt_mac.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183511933FCF0083AC69 /* tomcrypt_mac.h */; };
+		22C918D111933FCF0083AC69 /* tomcrypt_macros.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183611933FCF0083AC69 /* tomcrypt_macros.h */; };
+		22C918D211933FCF0083AC69 /* tomcrypt_math.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183711933FCF0083AC69 /* tomcrypt_math.h */; };
+		22C918D311933FCF0083AC69 /* tomcrypt_misc.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183811933FCF0083AC69 /* tomcrypt_misc.h */; };
+		22C918D411933FCF0083AC69 /* tomcrypt_pk.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183911933FCF0083AC69 /* tomcrypt_pk.h */; };
+		22C918D511933FCF0083AC69 /* tomcrypt_pkcs.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183A11933FCF0083AC69 /* tomcrypt_pkcs.h */; };
+		22C918D611933FCF0083AC69 /* tomcrypt_prng.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183B11933FCF0083AC69 /* tomcrypt_prng.h */; };
+		22C918D711933FCF0083AC69 /* ltm_desc.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9183D11933FCF0083AC69 /* ltm_desc.c */; };
+		22C918D811933FCF0083AC69 /* multi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9183E11933FCF0083AC69 /* multi.c */; };
+		22C918D911933FCF0083AC69 /* rand_prime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9183F11933FCF0083AC69 /* rand_prime.c */; };
+		22C918DA11933FCF0083AC69 /* base64_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184111933FCF0083AC69 /* base64_decode.c */; };
+		22C918DB11933FCF0083AC69 /* crypt_argchk.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184211933FCF0083AC69 /* crypt_argchk.c */; };
+		22C918DC11933FCF0083AC69 /* crypt_find_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184311933FCF0083AC69 /* crypt_find_hash.c */; };
+		22C918DD11933FCF0083AC69 /* crypt_find_prng.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184411933FCF0083AC69 /* crypt_find_prng.c */; };
+		22C918DE11933FCF0083AC69 /* crypt_hash_descriptor.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184511933FCF0083AC69 /* crypt_hash_descriptor.c */; };
+		22C918DF11933FCF0083AC69 /* crypt_hash_is_valid.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184611933FCF0083AC69 /* crypt_hash_is_valid.c */; };
+		22C918E011933FCF0083AC69 /* crypt_libc.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184711933FCF0083AC69 /* crypt_libc.c */; };
+		22C918E111933FCF0083AC69 /* crypt_ltc_mp_descriptor.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184811933FCF0083AC69 /* crypt_ltc_mp_descriptor.c */; };
+		22C918E211933FCF0083AC69 /* crypt_prng_descriptor.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184911933FCF0083AC69 /* crypt_prng_descriptor.c */; };
+		22C918E311933FCF0083AC69 /* crypt_prng_is_valid.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184A11933FCF0083AC69 /* crypt_prng_is_valid.c */; };
+		22C918E411933FCF0083AC69 /* crypt_register_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184B11933FCF0083AC69 /* crypt_register_hash.c */; };
+		22C918E511933FCF0083AC69 /* crypt_register_prng.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184C11933FCF0083AC69 /* crypt_register_prng.c */; };
+		22C918E611933FCF0083AC69 /* zeromem.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184D11933FCF0083AC69 /* zeromem.c */; };
+		22C918E711933FCF0083AC69 /* der_decode_bit_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185011933FCF0083AC69 /* der_decode_bit_string.c */; };
+		22C918E811933FCF0083AC69 /* der_decode_boolean.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185111933FCF0083AC69 /* der_decode_boolean.c */; };
+		22C918E911933FCF0083AC69 /* der_decode_choice.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185211933FCF0083AC69 /* der_decode_choice.c */; };
+		22C918EA11933FCF0083AC69 /* der_decode_ia5_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185311933FCF0083AC69 /* der_decode_ia5_string.c */; };
+		22C918EB11933FCF0083AC69 /* der_decode_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185411933FCF0083AC69 /* der_decode_integer.c */; };
+		22C918EC11933FCF0083AC69 /* der_decode_object_identifier.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185511933FCF0083AC69 /* der_decode_object_identifier.c */; };
+		22C918ED11933FCF0083AC69 /* der_decode_octet_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185611933FCF0083AC69 /* der_decode_octet_string.c */; };
+		22C918EE11933FCF0083AC69 /* der_decode_printable_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185711933FCF0083AC69 /* der_decode_printable_string.c */; };
+		22C918EF11933FCF0083AC69 /* der_decode_sequence_ex.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185811933FCF0083AC69 /* der_decode_sequence_ex.c */; };
+		22C918F011933FCF0083AC69 /* der_decode_sequence_flexi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185911933FCF0083AC69 /* der_decode_sequence_flexi.c */; };
+		22C918F111933FCF0083AC69 /* der_decode_sequence_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185A11933FCF0083AC69 /* der_decode_sequence_multi.c */; };
+		22C918F211933FCF0083AC69 /* der_decode_short_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185B11933FCF0083AC69 /* der_decode_short_integer.c */; };
+		22C918F311933FCF0083AC69 /* der_decode_utctime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185C11933FCF0083AC69 /* der_decode_utctime.c */; };
+		22C918F411933FCF0083AC69 /* der_decode_utf8_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185D11933FCF0083AC69 /* der_decode_utf8_string.c */; };
+		22C918F511933FCF0083AC69 /* der_length_bit_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185E11933FCF0083AC69 /* der_length_bit_string.c */; };
+		22C918F611933FCF0083AC69 /* der_length_boolean.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185F11933FCF0083AC69 /* der_length_boolean.c */; };
+		22C918F711933FCF0083AC69 /* der_length_ia5_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186011933FCF0083AC69 /* der_length_ia5_string.c */; };
+		22C918F811933FCF0083AC69 /* der_length_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186111933FCF0083AC69 /* der_length_integer.c */; };
+		22C918F911933FCF0083AC69 /* der_length_object_identifier.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186211933FCF0083AC69 /* der_length_object_identifier.c */; };
+		22C918FA11933FCF0083AC69 /* der_length_octet_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186311933FCF0083AC69 /* der_length_octet_string.c */; };
+		22C918FB11933FCF0083AC69 /* der_length_printable_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186411933FCF0083AC69 /* der_length_printable_string.c */; };
+		22C918FC11933FCF0083AC69 /* der_length_sequence.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186511933FCF0083AC69 /* der_length_sequence.c */; };
+		22C918FD11933FCF0083AC69 /* der_length_short_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186611933FCF0083AC69 /* der_length_short_integer.c */; };
+		22C918FE11933FCF0083AC69 /* der_length_utctime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186711933FCF0083AC69 /* der_length_utctime.c */; };
+		22C918FF11933FCF0083AC69 /* der_length_utf8_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186811933FCF0083AC69 /* der_length_utf8_string.c */; };
+		22C9190011933FCF0083AC69 /* der_sequence_free.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186911933FCF0083AC69 /* der_sequence_free.c */; };
+		22C9190111933FCF0083AC69 /* ltc_ecc_map.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186B11933FCF0083AC69 /* ltc_ecc_map.c */; };
+		22C9190211933FCF0083AC69 /* ltc_ecc_mul2add.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186C11933FCF0083AC69 /* ltc_ecc_mul2add.c */; };
+		22C9190311933FCF0083AC69 /* ltc_ecc_mulmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186D11933FCF0083AC69 /* ltc_ecc_mulmod.c */; };
+		22C9190411933FCF0083AC69 /* ltc_ecc_points.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186E11933FCF0083AC69 /* ltc_ecc_points.c */; };
+		22C9190511933FCF0083AC69 /* ltc_ecc_projective_add_point.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186F11933FCF0083AC69 /* ltc_ecc_projective_add_point.c */; };
+		22C9190611933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187011933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c */; };
+		22C9190711933FCF0083AC69 /* pkcs_1_mgf1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187211933FCF0083AC69 /* pkcs_1_mgf1.c */; };
+		22C9190811933FCF0083AC69 /* pkcs_1_oaep_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187311933FCF0083AC69 /* pkcs_1_oaep_decode.c */; };
+		22C9190911933FCF0083AC69 /* pkcs_1_pss_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187411933FCF0083AC69 /* pkcs_1_pss_decode.c */; };
+		22C9190A11933FCF0083AC69 /* pkcs_1_v1_5_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187511933FCF0083AC69 /* pkcs_1_v1_5_decode.c */; };
+		22C9190B11933FCF0083AC69 /* rsa_exptmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187711933FCF0083AC69 /* rsa_exptmod.c */; };
+		22C9190C11933FCF0083AC69 /* rsa_free.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187811933FCF0083AC69 /* rsa_free.c */; };
+		22C9190D11933FCF0083AC69 /* rsa_import.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187911933FCF0083AC69 /* rsa_import.c */; };
+		22C9190E11933FCF0083AC69 /* rsa_make_key.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187A11933FCF0083AC69 /* rsa_make_key.c */; };
+		22C9190F11933FCF0083AC69 /* rsa_verify_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187B11933FCF0083AC69 /* rsa_verify_hash.c */; };
+		22C9191011933FCF0083AC69 /* rsa_verify_simple.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187C11933FCF0083AC69 /* rsa_verify_simple.c */; };
+		22C9198A1193400A0083AC69 /* bn_fast_mp_invmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919111193400A0083AC69 /* bn_fast_mp_invmod.c */; };
+		22C9198B1193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919121193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c */; };
+		22C9198C1193400A0083AC69 /* bn_fast_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919131193400A0083AC69 /* bn_fast_s_mp_mul_digs.c */; };
+		22C9198D1193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919141193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c */; };
+		22C9198E1193400A0083AC69 /* bn_fast_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919151193400A0083AC69 /* bn_fast_s_mp_sqr.c */; };
+		22C9198F1193400A0083AC69 /* bn_mp_2expt.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919161193400A0083AC69 /* bn_mp_2expt.c */; };
+		22C919901193400A0083AC69 /* bn_mp_abs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919171193400A0083AC69 /* bn_mp_abs.c */; };
+		22C919911193400A0083AC69 /* bn_mp_add_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919181193400A0083AC69 /* bn_mp_add_d.c */; };
+		22C919921193400A0083AC69 /* bn_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919191193400A0083AC69 /* bn_mp_add.c */; };
+		22C919931193400A0083AC69 /* bn_mp_addmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191A1193400A0083AC69 /* bn_mp_addmod.c */; };
+		22C919941193400A0083AC69 /* bn_mp_and.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191B1193400A0083AC69 /* bn_mp_and.c */; };
+		22C919951193400A0083AC69 /* bn_mp_clamp.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191C1193400A0083AC69 /* bn_mp_clamp.c */; };
+		22C919961193400A0083AC69 /* bn_mp_clear_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191D1193400A0083AC69 /* bn_mp_clear_multi.c */; };
+		22C919971193400A0083AC69 /* bn_mp_clear.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191E1193400A0083AC69 /* bn_mp_clear.c */; };
+		22C919981193400A0083AC69 /* bn_mp_cmp_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191F1193400A0083AC69 /* bn_mp_cmp_d.c */; };
+		22C919991193400A0083AC69 /* bn_mp_cmp_mag.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919201193400A0083AC69 /* bn_mp_cmp_mag.c */; };
+		22C9199A1193400A0083AC69 /* bn_mp_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919211193400A0083AC69 /* bn_mp_cmp.c */; };
+		22C9199B1193400A0083AC69 /* bn_mp_cnt_lsb.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919221193400A0083AC69 /* bn_mp_cnt_lsb.c */; };
+		22C9199C1193400A0083AC69 /* bn_mp_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919231193400A0083AC69 /* bn_mp_copy.c */; };
+		22C9199D1193400A0083AC69 /* bn_mp_count_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919241193400A0083AC69 /* bn_mp_count_bits.c */; };
+		22C9199E1193400A0083AC69 /* bn_mp_div_2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919251193400A0083AC69 /* bn_mp_div_2.c */; };
+		22C9199F1193400A0083AC69 /* bn_mp_div_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919261193400A0083AC69 /* bn_mp_div_2d.c */; };
+		22C919A01193400A0083AC69 /* bn_mp_div_3.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919271193400A0083AC69 /* bn_mp_div_3.c */; };
+		22C919A11193400A0083AC69 /* bn_mp_div_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919281193400A0083AC69 /* bn_mp_div_d.c */; };
+		22C919A21193400A0083AC69 /* bn_mp_div.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919291193400A0083AC69 /* bn_mp_div.c */; };
+		22C919A31193400A0083AC69 /* bn_mp_dr_is_modulus.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192A1193400A0083AC69 /* bn_mp_dr_is_modulus.c */; };
+		22C919A41193400A0083AC69 /* bn_mp_dr_reduce.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192B1193400A0083AC69 /* bn_mp_dr_reduce.c */; };
+		22C919A51193400A0083AC69 /* bn_mp_dr_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192C1193400A0083AC69 /* bn_mp_dr_setup.c */; };
+		22C919A61193400A0083AC69 /* bn_mp_exch.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192D1193400A0083AC69 /* bn_mp_exch.c */; };
+		22C919A71193400A0083AC69 /* bn_mp_expt_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192E1193400A0083AC69 /* bn_mp_expt_d.c */; };
+		22C919A81193400A0083AC69 /* bn_mp_exptmod_fast.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192F1193400A0083AC69 /* bn_mp_exptmod_fast.c */; };
+		22C919A91193400A0083AC69 /* bn_mp_exptmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919301193400A0083AC69 /* bn_mp_exptmod.c */; };
+		22C919AA1193400A0083AC69 /* bn_mp_exteuclid.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919311193400A0083AC69 /* bn_mp_exteuclid.c */; };
+		22C919AB1193400A0083AC69 /* bn_mp_fread.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919321193400A0083AC69 /* bn_mp_fread.c */; };
+		22C919AC1193400A0083AC69 /* bn_mp_fwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919331193400A0083AC69 /* bn_mp_fwrite.c */; };
+		22C919AD1193400A0083AC69 /* bn_mp_gcd.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919341193400A0083AC69 /* bn_mp_gcd.c */; };
+		22C919AE1193400A0083AC69 /* bn_mp_get_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919351193400A0083AC69 /* bn_mp_get_int.c */; };
+		22C919AF1193400A0083AC69 /* bn_mp_grow.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919361193400A0083AC69 /* bn_mp_grow.c */; };
+		22C919B01193400A0083AC69 /* bn_mp_init_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919371193400A0083AC69 /* bn_mp_init_copy.c */; };
+		22C919B11193400A0083AC69 /* bn_mp_init_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919381193400A0083AC69 /* bn_mp_init_multi.c */; };
+		22C919B21193400A0083AC69 /* bn_mp_init_set_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919391193400A0083AC69 /* bn_mp_init_set_int.c */; };
+		22C919B31193400A0083AC69 /* bn_mp_init_set.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193A1193400A0083AC69 /* bn_mp_init_set.c */; };
+		22C919B41193400A0083AC69 /* bn_mp_init_size.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193B1193400A0083AC69 /* bn_mp_init_size.c */; };
+		22C919B51193400A0083AC69 /* bn_mp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193C1193400A0083AC69 /* bn_mp_init.c */; };
+		22C919B61193400A0083AC69 /* bn_mp_invmod_slow.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193D1193400A0083AC69 /* bn_mp_invmod_slow.c */; };
+		22C919B71193400A0083AC69 /* bn_mp_invmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193E1193400A0083AC69 /* bn_mp_invmod.c */; };
+		22C919B81193400A0083AC69 /* bn_mp_is_square.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193F1193400A0083AC69 /* bn_mp_is_square.c */; };
+		22C919B91193400A0083AC69 /* bn_mp_jacobi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919401193400A0083AC69 /* bn_mp_jacobi.c */; };
+		22C919BA1193400A0083AC69 /* bn_mp_karatsuba_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919411193400A0083AC69 /* bn_mp_karatsuba_mul.c */; };
+		22C919BB1193400A0083AC69 /* bn_mp_karatsuba_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919421193400A0083AC69 /* bn_mp_karatsuba_sqr.c */; };
+		22C919BC1193400A0083AC69 /* bn_mp_lcm.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919431193400A0083AC69 /* bn_mp_lcm.c */; };
+		22C919BD1193400A0083AC69 /* bn_mp_lshd.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919441193400A0083AC69 /* bn_mp_lshd.c */; };
+		22C919BE1193400A0083AC69 /* bn_mp_mod_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919451193400A0083AC69 /* bn_mp_mod_2d.c */; };
+		22C919BF1193400A0083AC69 /* bn_mp_mod_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919461193400A0083AC69 /* bn_mp_mod_d.c */; };
+		22C919C01193400A0083AC69 /* bn_mp_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919471193400A0083AC69 /* bn_mp_mod.c */; };
+		22C919C11193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919481193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c */; };
+		22C919C21193400A0083AC69 /* bn_mp_montgomery_reduce.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919491193400A0083AC69 /* bn_mp_montgomery_reduce.c */; };
+		22C919C31193400A0083AC69 /* bn_mp_montgomery_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194A1193400A0083AC69 /* bn_mp_montgomery_setup.c */; };
+		22C919C41193400A0083AC69 /* bn_mp_mul_2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194B1193400A0083AC69 /* bn_mp_mul_2.c */; };
+		22C919C51193400A0083AC69 /* bn_mp_mul_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194C1193400A0083AC69 /* bn_mp_mul_2d.c */; };
+		22C919C61193400A0083AC69 /* bn_mp_mul_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194D1193400A0083AC69 /* bn_mp_mul_d.c */; };
+		22C919C71193400A0083AC69 /* bn_mp_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194E1193400A0083AC69 /* bn_mp_mul.c */; };
+		22C919C81193400A0083AC69 /* bn_mp_mulmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194F1193400A0083AC69 /* bn_mp_mulmod.c */; };
+		22C919C91193400A0083AC69 /* bn_mp_n_root.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919501193400A0083AC69 /* bn_mp_n_root.c */; };
+		22C919CA1193400A0083AC69 /* bn_mp_neg.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919511193400A0083AC69 /* bn_mp_neg.c */; };
+		22C919CB1193400A0083AC69 /* bn_mp_or.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919521193400A0083AC69 /* bn_mp_or.c */; };
+		22C919CC1193400A0083AC69 /* bn_mp_prime_fermat.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919531193400A0083AC69 /* bn_mp_prime_fermat.c */; };
+		22C919CD1193400A0083AC69 /* bn_mp_prime_is_divisible.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919541193400A0083AC69 /* bn_mp_prime_is_divisible.c */; };
+		22C919CE1193400A0083AC69 /* bn_mp_prime_is_prime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919551193400A0083AC69 /* bn_mp_prime_is_prime.c */; };
+		22C919CF1193400A0083AC69 /* bn_mp_prime_miller_rabin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919561193400A0083AC69 /* bn_mp_prime_miller_rabin.c */; };
+		22C919D01193400A0083AC69 /* bn_mp_prime_next_prime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919571193400A0083AC69 /* bn_mp_prime_next_prime.c */; };
+		22C919D11193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919581193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c */; };
+		22C919D21193400A0083AC69 /* bn_mp_prime_random_ex.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919591193400A0083AC69 /* bn_mp_prime_random_ex.c */; };
+		22C919D31193400A0083AC69 /* bn_mp_radix_size.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195A1193400A0083AC69 /* bn_mp_radix_size.c */; };
+		22C919D41193400A0083AC69 /* bn_mp_radix_smap.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195B1193400A0083AC69 /* bn_mp_radix_smap.c */; };
+		22C919D51193400A0083AC69 /* bn_mp_rand.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195C1193400A0083AC69 /* bn_mp_rand.c */; };
+		22C919D61193400A0083AC69 /* bn_mp_read_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195D1193400A0083AC69 /* bn_mp_read_radix.c */; };
+		22C919D71193400A0083AC69 /* bn_mp_read_signed_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195E1193400A0083AC69 /* bn_mp_read_signed_bin.c */; };
+		22C919D81193400A0083AC69 /* bn_mp_read_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195F1193400A0083AC69 /* bn_mp_read_unsigned_bin.c */; };
+		22C919D91193400A0083AC69 /* bn_mp_reduce_2k_l.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919601193400A0083AC69 /* bn_mp_reduce_2k_l.c */; };
+		22C919DA1193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919611193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c */; };
+		22C919DB1193400A0083AC69 /* bn_mp_reduce_2k_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919621193400A0083AC69 /* bn_mp_reduce_2k_setup.c */; };
+		22C919DC1193400A0083AC69 /* bn_mp_reduce_2k.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919631193400A0083AC69 /* bn_mp_reduce_2k.c */; };
+		22C919DD1193400A0083AC69 /* bn_mp_reduce_is_2k_l.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919641193400A0083AC69 /* bn_mp_reduce_is_2k_l.c */; };
+		22C919DE1193400A0083AC69 /* bn_mp_reduce_is_2k.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919651193400A0083AC69 /* bn_mp_reduce_is_2k.c */; };
+		22C919DF1193400A0083AC69 /* bn_mp_reduce_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919661193400A0083AC69 /* bn_mp_reduce_setup.c */; };
+		22C919E01193400A0083AC69 /* bn_mp_reduce.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919671193400A0083AC69 /* bn_mp_reduce.c */; };
+		22C919E11193400A0083AC69 /* bn_mp_rshd.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919681193400A0083AC69 /* bn_mp_rshd.c */; };
+		22C919E21193400A0083AC69 /* bn_mp_set_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919691193400A0083AC69 /* bn_mp_set_int.c */; };
+		22C919E31193400A0083AC69 /* bn_mp_set.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196A1193400A0083AC69 /* bn_mp_set.c */; };
+		22C919E41193400A0083AC69 /* bn_mp_shrink.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196B1193400A0083AC69 /* bn_mp_shrink.c */; };
+		22C919E51193400A0083AC69 /* bn_mp_signed_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196C1193400A0083AC69 /* bn_mp_signed_bin_size.c */; };
+		22C919E61193400A0083AC69 /* bn_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196D1193400A0083AC69 /* bn_mp_sqr.c */; };
+		22C919E71193400A0083AC69 /* bn_mp_sqrmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196E1193400A0083AC69 /* bn_mp_sqrmod.c */; };
+		22C919E81193400A0083AC69 /* bn_mp_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196F1193400A0083AC69 /* bn_mp_sqrt.c */; };
+		22C919E91193400A0083AC69 /* bn_mp_sub_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919701193400A0083AC69 /* bn_mp_sub_d.c */; };
+		22C919EA1193400A0083AC69 /* bn_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919711193400A0083AC69 /* bn_mp_sub.c */; };
+		22C919EB1193400A0083AC69 /* bn_mp_submod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919721193400A0083AC69 /* bn_mp_submod.c */; };
+		22C919EC1193400A0083AC69 /* bn_mp_to_signed_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919731193400A0083AC69 /* bn_mp_to_signed_bin_n.c */; };
+		22C919ED1193400A0083AC69 /* bn_mp_to_signed_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919741193400A0083AC69 /* bn_mp_to_signed_bin.c */; };
+		22C919EE1193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919751193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c */; };
+		22C919EF1193400A0083AC69 /* bn_mp_to_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919761193400A0083AC69 /* bn_mp_to_unsigned_bin.c */; };
+		22C919F01193400A0083AC69 /* bn_mp_toom_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919771193400A0083AC69 /* bn_mp_toom_mul.c */; };
+		22C919F11193400A0083AC69 /* bn_mp_toom_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919781193400A0083AC69 /* bn_mp_toom_sqr.c */; };
+		22C919F21193400A0083AC69 /* bn_mp_toradix_n.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919791193400A0083AC69 /* bn_mp_toradix_n.c */; };
+		22C919F31193400A0083AC69 /* bn_mp_toradix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197A1193400A0083AC69 /* bn_mp_toradix.c */; };
+		22C919F41193400A0083AC69 /* bn_mp_unsigned_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197B1193400A0083AC69 /* bn_mp_unsigned_bin_size.c */; };
+		22C919F51193400A0083AC69 /* bn_mp_xor.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197C1193400A0083AC69 /* bn_mp_xor.c */; };
+		22C919F61193400A0083AC69 /* bn_mp_zero.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197D1193400A0083AC69 /* bn_mp_zero.c */; };
+		22C919F71193400A0083AC69 /* bn_prime_tab.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197E1193400A0083AC69 /* bn_prime_tab.c */; };
+		22C919F81193400A0083AC69 /* bn_reverse.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197F1193400A0083AC69 /* bn_reverse.c */; };
+		22C919F91193400A0083AC69 /* bn_s_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919801193400A0083AC69 /* bn_s_mp_add.c */; };
+		22C919FA1193400A0083AC69 /* bn_s_mp_exptmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919811193400A0083AC69 /* bn_s_mp_exptmod.c */; };
+		22C919FB1193400A0083AC69 /* bn_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919821193400A0083AC69 /* bn_s_mp_mul_digs.c */; };
+		22C919FC1193400A0083AC69 /* bn_s_mp_mul_high_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919831193400A0083AC69 /* bn_s_mp_mul_high_digs.c */; };
+		22C919FD1193400A0083AC69 /* bn_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919841193400A0083AC69 /* bn_s_mp_sqr.c */; };
+		22C919FE1193400A0083AC69 /* bn_s_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919851193400A0083AC69 /* bn_s_mp_sub.c */; };
+		22C919FF1193400A0083AC69 /* bncore.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919861193400A0083AC69 /* bncore.c */; };
+		22C91A001193400A0083AC69 /* tommath_class.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C919871193400A0083AC69 /* tommath_class.h */; };
+		22C91A011193400A0083AC69 /* tommath_superclass.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C919881193400A0083AC69 /* tommath_superclass.h */; };
+		22C91A021193400A0083AC69 /* tommath.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C919891193400A0083AC69 /* tommath.h */; };
+		22C91A031193400A0083AC69 /* bn_fast_mp_invmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919111193400A0083AC69 /* bn_fast_mp_invmod.c */; };
+		22C91A041193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919121193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c */; };
+		22C91A051193400A0083AC69 /* bn_fast_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919131193400A0083AC69 /* bn_fast_s_mp_mul_digs.c */; };
+		22C91A061193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919141193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c */; };
+		22C91A071193400A0083AC69 /* bn_fast_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919151193400A0083AC69 /* bn_fast_s_mp_sqr.c */; };
+		22C91A081193400A0083AC69 /* bn_mp_2expt.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919161193400A0083AC69 /* bn_mp_2expt.c */; };
+		22C91A091193400A0083AC69 /* bn_mp_abs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919171193400A0083AC69 /* bn_mp_abs.c */; };
+		22C91A0A1193400A0083AC69 /* bn_mp_add_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919181193400A0083AC69 /* bn_mp_add_d.c */; };
+		22C91A0B1193400A0083AC69 /* bn_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919191193400A0083AC69 /* bn_mp_add.c */; };
+		22C91A0C1193400A0083AC69 /* bn_mp_addmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191A1193400A0083AC69 /* bn_mp_addmod.c */; };
+		22C91A0D1193400A0083AC69 /* bn_mp_and.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191B1193400A0083AC69 /* bn_mp_and.c */; };
+		22C91A0E1193400A0083AC69 /* bn_mp_clamp.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191C1193400A0083AC69 /* bn_mp_clamp.c */; };
+		22C91A0F1193400A0083AC69 /* bn_mp_clear_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191D1193400A0083AC69 /* bn_mp_clear_multi.c */; };
+		22C91A101193400A0083AC69 /* bn_mp_clear.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191E1193400A0083AC69 /* bn_mp_clear.c */; };
+		22C91A111193400A0083AC69 /* bn_mp_cmp_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191F1193400A0083AC69 /* bn_mp_cmp_d.c */; };
+		22C91A121193400A0083AC69 /* bn_mp_cmp_mag.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919201193400A0083AC69 /* bn_mp_cmp_mag.c */; };
+		22C91A131193400A0083AC69 /* bn_mp_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919211193400A0083AC69 /* bn_mp_cmp.c */; };
+		22C91A141193400A0083AC69 /* bn_mp_cnt_lsb.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919221193400A0083AC69 /* bn_mp_cnt_lsb.c */; };
+		22C91A151193400A0083AC69 /* bn_mp_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919231193400A0083AC69 /* bn_mp_copy.c */; };
+		22C91A161193400A0083AC69 /* bn_mp_count_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919241193400A0083AC69 /* bn_mp_count_bits.c */; };
+		22C91A171193400A0083AC69 /* bn_mp_div_2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919251193400A0083AC69 /* bn_mp_div_2.c */; };
+		22C91A181193400A0083AC69 /* bn_mp_div_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919261193400A0083AC69 /* bn_mp_div_2d.c */; };
+		22C91A191193400A0083AC69 /* bn_mp_div_3.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919271193400A0083AC69 /* bn_mp_div_3.c */; };
+		22C91A1A1193400A0083AC69 /* bn_mp_div_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919281193400A0083AC69 /* bn_mp_div_d.c */; };
+		22C91A1B1193400A0083AC69 /* bn_mp_div.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919291193400A0083AC69 /* bn_mp_div.c */; };
+		22C91A1C1193400A0083AC69 /* bn_mp_dr_is_modulus.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192A1193400A0083AC69 /* bn_mp_dr_is_modulus.c */; };
+		22C91A1D1193400A0083AC69 /* bn_mp_dr_reduce.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192B1193400A0083AC69 /* bn_mp_dr_reduce.c */; };
+		22C91A1E1193400A0083AC69 /* bn_mp_dr_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192C1193400A0083AC69 /* bn_mp_dr_setup.c */; };
+		22C91A1F1193400A0083AC69 /* bn_mp_exch.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192D1193400A0083AC69 /* bn_mp_exch.c */; };
+		22C91A201193400A0083AC69 /* bn_mp_expt_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192E1193400A0083AC69 /* bn_mp_expt_d.c */; };
+		22C91A211193400A0083AC69 /* bn_mp_exptmod_fast.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192F1193400A0083AC69 /* bn_mp_exptmod_fast.c */; };
+		22C91A221193400A0083AC69 /* bn_mp_exptmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919301193400A0083AC69 /* bn_mp_exptmod.c */; };
+		22C91A231193400A0083AC69 /* bn_mp_exteuclid.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919311193400A0083AC69 /* bn_mp_exteuclid.c */; };
+		22C91A241193400A0083AC69 /* bn_mp_fread.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919321193400A0083AC69 /* bn_mp_fread.c */; };
+		22C91A251193400A0083AC69 /* bn_mp_fwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919331193400A0083AC69 /* bn_mp_fwrite.c */; };
+		22C91A261193400A0083AC69 /* bn_mp_gcd.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919341193400A0083AC69 /* bn_mp_gcd.c */; };
+		22C91A271193400A0083AC69 /* bn_mp_get_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919351193400A0083AC69 /* bn_mp_get_int.c */; };
+		22C91A281193400A0083AC69 /* bn_mp_grow.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919361193400A0083AC69 /* bn_mp_grow.c */; };
+		22C91A291193400A0083AC69 /* bn_mp_init_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919371193400A0083AC69 /* bn_mp_init_copy.c */; };
+		22C91A2A1193400A0083AC69 /* bn_mp_init_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919381193400A0083AC69 /* bn_mp_init_multi.c */; };
+		22C91A2B1193400A0083AC69 /* bn_mp_init_set_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919391193400A0083AC69 /* bn_mp_init_set_int.c */; };
+		22C91A2C1193400A0083AC69 /* bn_mp_init_set.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193A1193400A0083AC69 /* bn_mp_init_set.c */; };
+		22C91A2D1193400A0083AC69 /* bn_mp_init_size.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193B1193400A0083AC69 /* bn_mp_init_size.c */; };
+		22C91A2E1193400A0083AC69 /* bn_mp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193C1193400A0083AC69 /* bn_mp_init.c */; };
+		22C91A2F1193400A0083AC69 /* bn_mp_invmod_slow.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193D1193400A0083AC69 /* bn_mp_invmod_slow.c */; };
+		22C91A301193400A0083AC69 /* bn_mp_invmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193E1193400A0083AC69 /* bn_mp_invmod.c */; };
+		22C91A311193400A0083AC69 /* bn_mp_is_square.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193F1193400A0083AC69 /* bn_mp_is_square.c */; };
+		22C91A321193400A0083AC69 /* bn_mp_jacobi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919401193400A0083AC69 /* bn_mp_jacobi.c */; };
+		22C91A331193400A0083AC69 /* bn_mp_karatsuba_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919411193400A0083AC69 /* bn_mp_karatsuba_mul.c */; };
+		22C91A341193400A0083AC69 /* bn_mp_karatsuba_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919421193400A0083AC69 /* bn_mp_karatsuba_sqr.c */; };
+		22C91A351193400A0083AC69 /* bn_mp_lcm.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919431193400A0083AC69 /* bn_mp_lcm.c */; };
+		22C91A361193400A0083AC69 /* bn_mp_lshd.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919441193400A0083AC69 /* bn_mp_lshd.c */; };
+		22C91A371193400A0083AC69 /* bn_mp_mod_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919451193400A0083AC69 /* bn_mp_mod_2d.c */; };
+		22C91A381193400A0083AC69 /* bn_mp_mod_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919461193400A0083AC69 /* bn_mp_mod_d.c */; };
+		22C91A391193400A0083AC69 /* bn_mp_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919471193400A0083AC69 /* bn_mp_mod.c */; };
+		22C91A3A1193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919481193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c */; };
+		22C91A3B1193400A0083AC69 /* bn_mp_montgomery_reduce.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919491193400A0083AC69 /* bn_mp_montgomery_reduce.c */; };
+		22C91A3C1193400A0083AC69 /* bn_mp_montgomery_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194A1193400A0083AC69 /* bn_mp_montgomery_setup.c */; };
+		22C91A3D1193400A0083AC69 /* bn_mp_mul_2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194B1193400A0083AC69 /* bn_mp_mul_2.c */; };
+		22C91A3E1193400A0083AC69 /* bn_mp_mul_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194C1193400A0083AC69 /* bn_mp_mul_2d.c */; };
+		22C91A3F1193400A0083AC69 /* bn_mp_mul_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194D1193400A0083AC69 /* bn_mp_mul_d.c */; };
+		22C91A401193400A0083AC69 /* bn_mp_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194E1193400A0083AC69 /* bn_mp_mul.c */; };
+		22C91A411193400A0083AC69 /* bn_mp_mulmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194F1193400A0083AC69 /* bn_mp_mulmod.c */; };
+		22C91A421193400A0083AC69 /* bn_mp_n_root.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919501193400A0083AC69 /* bn_mp_n_root.c */; };
+		22C91A431193400A0083AC69 /* bn_mp_neg.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919511193400A0083AC69 /* bn_mp_neg.c */; };
+		22C91A441193400A0083AC69 /* bn_mp_or.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919521193400A0083AC69 /* bn_mp_or.c */; };
+		22C91A451193400A0083AC69 /* bn_mp_prime_fermat.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919531193400A0083AC69 /* bn_mp_prime_fermat.c */; };
+		22C91A461193400A0083AC69 /* bn_mp_prime_is_divisible.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919541193400A0083AC69 /* bn_mp_prime_is_divisible.c */; };
+		22C91A471193400A0083AC69 /* bn_mp_prime_is_prime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919551193400A0083AC69 /* bn_mp_prime_is_prime.c */; };
+		22C91A481193400A0083AC69 /* bn_mp_prime_miller_rabin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919561193400A0083AC69 /* bn_mp_prime_miller_rabin.c */; };
+		22C91A491193400A0083AC69 /* bn_mp_prime_next_prime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919571193400A0083AC69 /* bn_mp_prime_next_prime.c */; };
+		22C91A4A1193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919581193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c */; };
+		22C91A4B1193400A0083AC69 /* bn_mp_prime_random_ex.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919591193400A0083AC69 /* bn_mp_prime_random_ex.c */; };
+		22C91A4C1193400A0083AC69 /* bn_mp_radix_size.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195A1193400A0083AC69 /* bn_mp_radix_size.c */; };
+		22C91A4D1193400A0083AC69 /* bn_mp_radix_smap.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195B1193400A0083AC69 /* bn_mp_radix_smap.c */; };
+		22C91A4E1193400A0083AC69 /* bn_mp_rand.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195C1193400A0083AC69 /* bn_mp_rand.c */; };
+		22C91A4F1193400A0083AC69 /* bn_mp_read_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195D1193400A0083AC69 /* bn_mp_read_radix.c */; };
+		22C91A501193400A0083AC69 /* bn_mp_read_signed_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195E1193400A0083AC69 /* bn_mp_read_signed_bin.c */; };
+		22C91A511193400A0083AC69 /* bn_mp_read_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195F1193400A0083AC69 /* bn_mp_read_unsigned_bin.c */; };
+		22C91A521193400A0083AC69 /* bn_mp_reduce_2k_l.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919601193400A0083AC69 /* bn_mp_reduce_2k_l.c */; };
+		22C91A531193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919611193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c */; };
+		22C91A541193400A0083AC69 /* bn_mp_reduce_2k_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919621193400A0083AC69 /* bn_mp_reduce_2k_setup.c */; };
+		22C91A551193400A0083AC69 /* bn_mp_reduce_2k.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919631193400A0083AC69 /* bn_mp_reduce_2k.c */; };
+		22C91A561193400A0083AC69 /* bn_mp_reduce_is_2k_l.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919641193400A0083AC69 /* bn_mp_reduce_is_2k_l.c */; };
+		22C91A571193400A0083AC69 /* bn_mp_reduce_is_2k.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919651193400A0083AC69 /* bn_mp_reduce_is_2k.c */; };
+		22C91A581193400A0083AC69 /* bn_mp_reduce_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919661193400A0083AC69 /* bn_mp_reduce_setup.c */; };
+		22C91A591193400A0083AC69 /* bn_mp_reduce.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919671193400A0083AC69 /* bn_mp_reduce.c */; };
+		22C91A5A1193400A0083AC69 /* bn_mp_rshd.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919681193400A0083AC69 /* bn_mp_rshd.c */; };
+		22C91A5B1193400A0083AC69 /* bn_mp_set_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919691193400A0083AC69 /* bn_mp_set_int.c */; };
+		22C91A5C1193400A0083AC69 /* bn_mp_set.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196A1193400A0083AC69 /* bn_mp_set.c */; };
+		22C91A5D1193400A0083AC69 /* bn_mp_shrink.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196B1193400A0083AC69 /* bn_mp_shrink.c */; };
+		22C91A5E1193400A0083AC69 /* bn_mp_signed_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196C1193400A0083AC69 /* bn_mp_signed_bin_size.c */; };
+		22C91A5F1193400A0083AC69 /* bn_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196D1193400A0083AC69 /* bn_mp_sqr.c */; };
+		22C91A601193400A0083AC69 /* bn_mp_sqrmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196E1193400A0083AC69 /* bn_mp_sqrmod.c */; };
+		22C91A611193400A0083AC69 /* bn_mp_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196F1193400A0083AC69 /* bn_mp_sqrt.c */; };
+		22C91A621193400A0083AC69 /* bn_mp_sub_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919701193400A0083AC69 /* bn_mp_sub_d.c */; };
+		22C91A631193400A0083AC69 /* bn_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919711193400A0083AC69 /* bn_mp_sub.c */; };
+		22C91A641193400A0083AC69 /* bn_mp_submod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919721193400A0083AC69 /* bn_mp_submod.c */; };
+		22C91A651193400A0083AC69 /* bn_mp_to_signed_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919731193400A0083AC69 /* bn_mp_to_signed_bin_n.c */; };
+		22C91A661193400A0083AC69 /* bn_mp_to_signed_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919741193400A0083AC69 /* bn_mp_to_signed_bin.c */; };
+		22C91A671193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919751193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c */; };
+		22C91A681193400A0083AC69 /* bn_mp_to_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919761193400A0083AC69 /* bn_mp_to_unsigned_bin.c */; };
+		22C91A691193400A0083AC69 /* bn_mp_toom_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919771193400A0083AC69 /* bn_mp_toom_mul.c */; };
+		22C91A6A1193400A0083AC69 /* bn_mp_toom_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919781193400A0083AC69 /* bn_mp_toom_sqr.c */; };
+		22C91A6B1193400A0083AC69 /* bn_mp_toradix_n.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919791193400A0083AC69 /* bn_mp_toradix_n.c */; };
+		22C91A6C1193400A0083AC69 /* bn_mp_toradix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197A1193400A0083AC69 /* bn_mp_toradix.c */; };
+		22C91A6D1193400A0083AC69 /* bn_mp_unsigned_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197B1193400A0083AC69 /* bn_mp_unsigned_bin_size.c */; };
+		22C91A6E1193400A0083AC69 /* bn_mp_xor.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197C1193400A0083AC69 /* bn_mp_xor.c */; };
+		22C91A6F1193400A0083AC69 /* bn_mp_zero.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197D1193400A0083AC69 /* bn_mp_zero.c */; };
+		22C91A701193400A0083AC69 /* bn_prime_tab.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197E1193400A0083AC69 /* bn_prime_tab.c */; };
+		22C91A711193400A0083AC69 /* bn_reverse.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197F1193400A0083AC69 /* bn_reverse.c */; };
+		22C91A721193400A0083AC69 /* bn_s_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919801193400A0083AC69 /* bn_s_mp_add.c */; };
+		22C91A731193400A0083AC69 /* bn_s_mp_exptmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919811193400A0083AC69 /* bn_s_mp_exptmod.c */; };
+		22C91A741193400A0083AC69 /* bn_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919821193400A0083AC69 /* bn_s_mp_mul_digs.c */; };
+		22C91A751193400A0083AC69 /* bn_s_mp_mul_high_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919831193400A0083AC69 /* bn_s_mp_mul_high_digs.c */; };
+		22C91A761193400A0083AC69 /* bn_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919841193400A0083AC69 /* bn_s_mp_sqr.c */; };
+		22C91A771193400A0083AC69 /* bn_s_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919851193400A0083AC69 /* bn_s_mp_sub.c */; };
+		22C91A781193400A0083AC69 /* bncore.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919861193400A0083AC69 /* bncore.c */; };
+		22C91A791193400A0083AC69 /* tommath_class.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C919871193400A0083AC69 /* tommath_class.h */; };
+		22C91A7A1193400A0083AC69 /* tommath_superclass.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C919881193400A0083AC69 /* tommath_superclass.h */; };
+		22C91A7B1193400A0083AC69 /* tommath.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C919891193400A0083AC69 /* tommath.h */; };
+		22EC6044154B28A000679228 /* FileStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 22EC6043154B28A000679228 /* FileStream.h */; };
+		22EC6045154B28A000679228 /* FileStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 22EC6043154B28A000679228 /* FileStream.h */; };
+		22F5A9C51193DFBA00F8B121 /* SFileVerify.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 22F5A9C41193DFBA00F8B121 /* SFileVerify.cpp */; };
+		22F5A9C61193DFBA00F8B121 /* SFileVerify.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 22F5A9C41193DFBA00F8B121 /* SFileVerify.cpp */; };
+		E60816D61B707A9000B283F7 /* rsa_sign_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816D51B707A9000B283F7 /* rsa_sign_hash.c */; };
+		E60816D71B707A9B00B283F7 /* rsa_sign_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816D51B707A9000B283F7 /* rsa_sign_hash.c */; };
+		E60816D91B707B1800B283F7 /* pkcs_1_pss_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816D81B707B1800B283F7 /* pkcs_1_pss_encode.c */; };
+		E60816DA1B707B1800B283F7 /* pkcs_1_pss_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816D81B707B1800B283F7 /* pkcs_1_pss_encode.c */; };
+		E60816DC1B707B2700B283F7 /* pkcs_1_v1_5_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816DB1B707B2700B283F7 /* pkcs_1_v1_5_encode.c */; };
+		E60816DD1B707B2700B283F7 /* pkcs_1_v1_5_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816DB1B707B2700B283F7 /* pkcs_1_v1_5_encode.c */; };
+		E60816DF1B707B5700B283F7 /* der_encode_sequence_ex.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816DE1B707B5700B283F7 /* der_encode_sequence_ex.c */; };
+		E60816E01B707B5700B283F7 /* der_encode_sequence_ex.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816DE1B707B5700B283F7 /* der_encode_sequence_ex.c */; };
+		E60816EE1B707B7200B283F7 /* der_encode_bit_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E11B707B7200B283F7 /* der_encode_bit_string.c */; };
+		E60816EF1B707B7200B283F7 /* der_encode_bit_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E11B707B7200B283F7 /* der_encode_bit_string.c */; };
+		E60816F01B707B7200B283F7 /* der_encode_boolean.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E21B707B7200B283F7 /* der_encode_boolean.c */; };
+		E60816F11B707B7200B283F7 /* der_encode_boolean.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E21B707B7200B283F7 /* der_encode_boolean.c */; };
+		E60816F21B707B7200B283F7 /* der_encode_ia5_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E31B707B7200B283F7 /* der_encode_ia5_string.c */; };
+		E60816F31B707B7200B283F7 /* der_encode_ia5_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E31B707B7200B283F7 /* der_encode_ia5_string.c */; };
+		E60816F41B707B7200B283F7 /* der_encode_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E41B707B7200B283F7 /* der_encode_integer.c */; };
+		E60816F51B707B7200B283F7 /* der_encode_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E41B707B7200B283F7 /* der_encode_integer.c */; };
+		E60816F61B707B7200B283F7 /* der_encode_object_identifier.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E51B707B7200B283F7 /* der_encode_object_identifier.c */; };
+		E60816F71B707B7200B283F7 /* der_encode_object_identifier.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E51B707B7200B283F7 /* der_encode_object_identifier.c */; };
+		E60816F81B707B7200B283F7 /* der_encode_octet_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E61B707B7200B283F7 /* der_encode_octet_string.c */; };
+		E60816F91B707B7200B283F7 /* der_encode_octet_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E61B707B7200B283F7 /* der_encode_octet_string.c */; };
+		E60816FA1B707B7200B283F7 /* der_encode_printable_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E71B707B7200B283F7 /* der_encode_printable_string.c */; };
+		E60816FB1B707B7200B283F7 /* der_encode_printable_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E71B707B7200B283F7 /* der_encode_printable_string.c */; };
+		E60816FC1B707B7200B283F7 /* der_encode_sequence_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E81B707B7200B283F7 /* der_encode_sequence_multi.c */; };
+		E60816FD1B707B7200B283F7 /* der_encode_sequence_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E81B707B7200B283F7 /* der_encode_sequence_multi.c */; };
+		E60816FE1B707B7200B283F7 /* der_encode_set.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E91B707B7200B283F7 /* der_encode_set.c */; };
+		E60816FF1B707B7200B283F7 /* der_encode_set.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E91B707B7200B283F7 /* der_encode_set.c */; };
+		E60817001B707B7200B283F7 /* der_encode_setof.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816EA1B707B7200B283F7 /* der_encode_setof.c */; };
+		E60817011B707B7200B283F7 /* der_encode_setof.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816EA1B707B7200B283F7 /* der_encode_setof.c */; };
+		E60817021B707B7200B283F7 /* der_encode_short_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816EB1B707B7200B283F7 /* der_encode_short_integer.c */; };
+		E60817031B707B7200B283F7 /* der_encode_short_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816EB1B707B7200B283F7 /* der_encode_short_integer.c */; };
+		E60817041B707B7200B283F7 /* der_encode_utctime.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816EC1B707B7200B283F7 /* der_encode_utctime.c */; };
+		E60817051B707B7200B283F7 /* der_encode_utctime.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816EC1B707B7200B283F7 /* der_encode_utctime.c */; };
+		E60817061B707B7200B283F7 /* der_encode_utf8_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816ED1B707B7200B283F7 /* der_encode_utf8_string.c */; };
+		E60817071B707B7200B283F7 /* der_encode_utf8_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816ED1B707B7200B283F7 /* der_encode_utf8_string.c */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		2229F62E11D4653600118914 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 225530D31056BAC800FA646A;
+			remoteInfo = StormLib;
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+		221F6A721168529C0026C852 /* LzmaDec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LzmaDec.h; path = C/LzmaDec.h; sourceTree = "<group>"; };
+		221F6A731168529C0026C852 /* LzmaEnc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LzmaEnc.h; path = C/LzmaEnc.h; sourceTree = "<group>"; };
+		221F6A7A116852AA0026C852 /* LzmaEnc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = LzmaEnc.c; path = C/LzmaEnc.c; sourceTree = "<group>"; };
+		221F6A7D116852B20026C852 /* LzmaDec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = LzmaDec.c; path = C/LzmaDec.c; sourceTree = "<group>"; };
+		221F6AB31168545B0026C852 /* LzFind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = LzFind.c; path = C/LzFind.c; sourceTree = "<group>"; };
+		221F6AB41168545B0026C852 /* LzFind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LzFind.h; path = C/LzFind.h; sourceTree = "<group>"; };
+		221F6AB9116854730026C852 /* LzHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LzHash.h; path = C/LzHash.h; sourceTree = "<group>"; };
+		221F6ABC116854870026C852 /* Types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Types.h; path = C/Types.h; sourceTree = "<group>"; };
+		2253A19F10568A83001909F9 /* StormLib.exp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.exports; name = StormLib.exp; path = stormlib_dll/StormLib.exp; sourceTree = "<group>"; };
+		225530D41056BAC800FA646A /* libStormLib.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libStormLib.a; sourceTree = BUILT_PRODUCTS_DIR; };
+		225C734B1257CCC70009E8DA /* lookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lookup.h; sourceTree = "<group>"; };
+		225C734C1257CCC70009E8DA /* lookup3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lookup3.c; sourceTree = "<group>"; };
+		225C73531257CD0C0009E8DA /* SBaseFileTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBaseFileTable.cpp; path = src/SBaseFileTable.cpp; sourceTree = "<group>"; };
+		225FAC940E53B7F800DA2CAE /* StormLib.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = StormLib.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		225FAC950E53B7F800DA2CAE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		226C7CA61857DE9400AB689C /* SBaseDumpData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBaseDumpData.cpp; path = src/SBaseDumpData.cpp; sourceTree = "<group>"; };
+		226C7CA91857DEAC00AB689C /* SBaseSubTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBaseSubTypes.cpp; path = src/SBaseSubTypes.cpp; sourceTree = "<group>"; };
+		226C7CAC1857DEEB00AB689C /* SFileGetFileInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileGetFileInfo.cpp; path = src/SFileGetFileInfo.cpp; sourceTree = "<group>"; };
+		228B538311BF7D0D001A58DA /* FileStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FileStream.cpp; path = src/FileStream.cpp; sourceTree = "<group>"; };
+		2295488911D45A820064B264 /* Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Test.cpp; path = test/Test.cpp; sourceTree = "<group>"; };
+		22954ACE11D463A30064B264 /* StormLib_Test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = StormLib_Test; sourceTree = BUILT_PRODUCTS_DIR; };
+		2299D9D51167EFA8005C19BF /* adpcm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = adpcm.cpp; sourceTree = "<group>"; };
+		2299D9D61167EFA8005C19BF /* adpcm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = adpcm.h; sourceTree = "<group>"; };
+		2299D9DC1167EFC6005C19BF /* sparse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sparse.cpp; sourceTree = "<group>"; };
+		2299D9DD1167EFC6005C19BF /* sparse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sparse.h; sourceTree = "<group>"; };
+		2299DA4D1167FD16005C19BF /* SFileAddFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileAddFile.cpp; path = src/SFileAddFile.cpp; sourceTree = "<group>"; };
+		22AEA121123125D800359B16 /* SFilePatchArchives.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFilePatchArchives.cpp; path = src/SFilePatchArchives.cpp; sourceTree = "<group>"; };
+		22C9182B11933FCF0083AC69 /* hash_memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hash_memory.c; sourceTree = "<group>"; };
+		22C9182C11933FCF0083AC69 /* md5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = md5.c; sourceTree = "<group>"; };
+		22C9182D11933FCF0083AC69 /* sha1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sha1.c; sourceTree = "<group>"; };
+		22C9182F11933FCF0083AC69 /* tomcrypt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt.h; sourceTree = "<group>"; };
+		22C9183011933FCF0083AC69 /* tomcrypt_argchk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_argchk.h; sourceTree = "<group>"; };
+		22C9183111933FCF0083AC69 /* tomcrypt_cfg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_cfg.h; sourceTree = "<group>"; };
+		22C9183211933FCF0083AC69 /* tomcrypt_cipher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_cipher.h; sourceTree = "<group>"; };
+		22C9183311933FCF0083AC69 /* tomcrypt_custom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_custom.h; sourceTree = "<group>"; };
+		22C9183411933FCF0083AC69 /* tomcrypt_hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_hash.h; sourceTree = "<group>"; };
+		22C9183511933FCF0083AC69 /* tomcrypt_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_mac.h; sourceTree = "<group>"; };
+		22C9183611933FCF0083AC69 /* tomcrypt_macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_macros.h; sourceTree = "<group>"; };
+		22C9183711933FCF0083AC69 /* tomcrypt_math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_math.h; sourceTree = "<group>"; };
+		22C9183811933FCF0083AC69 /* tomcrypt_misc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_misc.h; sourceTree = "<group>"; };
+		22C9183911933FCF0083AC69 /* tomcrypt_pk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_pk.h; sourceTree = "<group>"; };
+		22C9183A11933FCF0083AC69 /* tomcrypt_pkcs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_pkcs.h; sourceTree = "<group>"; };
+		22C9183B11933FCF0083AC69 /* tomcrypt_prng.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_prng.h; sourceTree = "<group>"; };
+		22C9183D11933FCF0083AC69 /* ltm_desc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltm_desc.c; sourceTree = "<group>"; };
+		22C9183E11933FCF0083AC69 /* multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = multi.c; sourceTree = "<group>"; };
+		22C9183F11933FCF0083AC69 /* rand_prime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rand_prime.c; sourceTree = "<group>"; };
+		22C9184111933FCF0083AC69 /* base64_decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = base64_decode.c; sourceTree = "<group>"; };
+		22C9184211933FCF0083AC69 /* crypt_argchk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_argchk.c; sourceTree = "<group>"; };
+		22C9184311933FCF0083AC69 /* crypt_find_hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_find_hash.c; sourceTree = "<group>"; };
+		22C9184411933FCF0083AC69 /* crypt_find_prng.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_find_prng.c; sourceTree = "<group>"; };
+		22C9184511933FCF0083AC69 /* crypt_hash_descriptor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_hash_descriptor.c; sourceTree = "<group>"; };
+		22C9184611933FCF0083AC69 /* crypt_hash_is_valid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_hash_is_valid.c; sourceTree = "<group>"; };
+		22C9184711933FCF0083AC69 /* crypt_libc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_libc.c; sourceTree = "<group>"; };
+		22C9184811933FCF0083AC69 /* crypt_ltc_mp_descriptor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_ltc_mp_descriptor.c; sourceTree = "<group>"; };
+		22C9184911933FCF0083AC69 /* crypt_prng_descriptor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_prng_descriptor.c; sourceTree = "<group>"; };
+		22C9184A11933FCF0083AC69 /* crypt_prng_is_valid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_prng_is_valid.c; sourceTree = "<group>"; };
+		22C9184B11933FCF0083AC69 /* crypt_register_hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_register_hash.c; sourceTree = "<group>"; };
+		22C9184C11933FCF0083AC69 /* crypt_register_prng.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_register_prng.c; sourceTree = "<group>"; };
+		22C9184D11933FCF0083AC69 /* zeromem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = zeromem.c; sourceTree = "<group>"; };
+		22C9185011933FCF0083AC69 /* der_decode_bit_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_bit_string.c; sourceTree = "<group>"; };
+		22C9185111933FCF0083AC69 /* der_decode_boolean.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_boolean.c; sourceTree = "<group>"; };
+		22C9185211933FCF0083AC69 /* der_decode_choice.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_choice.c; sourceTree = "<group>"; };
+		22C9185311933FCF0083AC69 /* der_decode_ia5_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_ia5_string.c; sourceTree = "<group>"; };
+		22C9185411933FCF0083AC69 /* der_decode_integer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_integer.c; sourceTree = "<group>"; };
+		22C9185511933FCF0083AC69 /* der_decode_object_identifier.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_object_identifier.c; sourceTree = "<group>"; };
+		22C9185611933FCF0083AC69 /* der_decode_octet_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_octet_string.c; sourceTree = "<group>"; };
+		22C9185711933FCF0083AC69 /* der_decode_printable_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_printable_string.c; sourceTree = "<group>"; };
+		22C9185811933FCF0083AC69 /* der_decode_sequence_ex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_sequence_ex.c; sourceTree = "<group>"; };
+		22C9185911933FCF0083AC69 /* der_decode_sequence_flexi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_sequence_flexi.c; sourceTree = "<group>"; };
+		22C9185A11933FCF0083AC69 /* der_decode_sequence_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_sequence_multi.c; sourceTree = "<group>"; };
+		22C9185B11933FCF0083AC69 /* der_decode_short_integer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_short_integer.c; sourceTree = "<group>"; };
+		22C9185C11933FCF0083AC69 /* der_decode_utctime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_utctime.c; sourceTree = "<group>"; };
+		22C9185D11933FCF0083AC69 /* der_decode_utf8_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_utf8_string.c; sourceTree = "<group>"; };
+		22C9185E11933FCF0083AC69 /* der_length_bit_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_bit_string.c; sourceTree = "<group>"; };
+		22C9185F11933FCF0083AC69 /* der_length_boolean.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_boolean.c; sourceTree = "<group>"; };
+		22C9186011933FCF0083AC69 /* der_length_ia5_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_ia5_string.c; sourceTree = "<group>"; };
+		22C9186111933FCF0083AC69 /* der_length_integer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_integer.c; sourceTree = "<group>"; };
+		22C9186211933FCF0083AC69 /* der_length_object_identifier.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_object_identifier.c; sourceTree = "<group>"; };
+		22C9186311933FCF0083AC69 /* der_length_octet_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_octet_string.c; sourceTree = "<group>"; };
+		22C9186411933FCF0083AC69 /* der_length_printable_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_printable_string.c; sourceTree = "<group>"; };
+		22C9186511933FCF0083AC69 /* der_length_sequence.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_sequence.c; sourceTree = "<group>"; };
+		22C9186611933FCF0083AC69 /* der_length_short_integer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_short_integer.c; sourceTree = "<group>"; };
+		22C9186711933FCF0083AC69 /* der_length_utctime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_utctime.c; sourceTree = "<group>"; };
+		22C9186811933FCF0083AC69 /* der_length_utf8_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_utf8_string.c; sourceTree = "<group>"; };
+		22C9186911933FCF0083AC69 /* der_sequence_free.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_sequence_free.c; sourceTree = "<group>"; };
+		22C9186B11933FCF0083AC69 /* ltc_ecc_map.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_map.c; sourceTree = "<group>"; };
+		22C9186C11933FCF0083AC69 /* ltc_ecc_mul2add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_mul2add.c; sourceTree = "<group>"; };
+		22C9186D11933FCF0083AC69 /* ltc_ecc_mulmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_mulmod.c; sourceTree = "<group>"; };
+		22C9186E11933FCF0083AC69 /* ltc_ecc_points.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_points.c; sourceTree = "<group>"; };
+		22C9186F11933FCF0083AC69 /* ltc_ecc_projective_add_point.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_projective_add_point.c; sourceTree = "<group>"; };
+		22C9187011933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_projective_dbl_point.c; sourceTree = "<group>"; };
+		22C9187211933FCF0083AC69 /* pkcs_1_mgf1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs_1_mgf1.c; sourceTree = "<group>"; };
+		22C9187311933FCF0083AC69 /* pkcs_1_oaep_decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs_1_oaep_decode.c; sourceTree = "<group>"; };
+		22C9187411933FCF0083AC69 /* pkcs_1_pss_decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs_1_pss_decode.c; sourceTree = "<group>"; };
+		22C9187511933FCF0083AC69 /* pkcs_1_v1_5_decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs_1_v1_5_decode.c; sourceTree = "<group>"; };
+		22C9187711933FCF0083AC69 /* rsa_exptmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_exptmod.c; sourceTree = "<group>"; };
+		22C9187811933FCF0083AC69 /* rsa_free.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_free.c; sourceTree = "<group>"; };
+		22C9187911933FCF0083AC69 /* rsa_import.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_import.c; sourceTree = "<group>"; };
+		22C9187A11933FCF0083AC69 /* rsa_make_key.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_make_key.c; sourceTree = "<group>"; };
+		22C9187B11933FCF0083AC69 /* rsa_verify_hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_verify_hash.c; sourceTree = "<group>"; };
+		22C9187C11933FCF0083AC69 /* rsa_verify_simple.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_verify_simple.c; sourceTree = "<group>"; };
+		22C919111193400A0083AC69 /* bn_fast_mp_invmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_mp_invmod.c; sourceTree = "<group>"; };
+		22C919121193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_mp_montgomery_reduce.c; sourceTree = "<group>"; };
+		22C919131193400A0083AC69 /* bn_fast_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_mul_digs.c; sourceTree = "<group>"; };
+		22C919141193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_mul_high_digs.c; sourceTree = "<group>"; };
+		22C919151193400A0083AC69 /* bn_fast_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_sqr.c; sourceTree = "<group>"; };
+		22C919161193400A0083AC69 /* bn_mp_2expt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_2expt.c; sourceTree = "<group>"; };
+		22C919171193400A0083AC69 /* bn_mp_abs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_abs.c; sourceTree = "<group>"; };
+		22C919181193400A0083AC69 /* bn_mp_add_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add_d.c; sourceTree = "<group>"; };
+		22C919191193400A0083AC69 /* bn_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add.c; sourceTree = "<group>"; };
+		22C9191A1193400A0083AC69 /* bn_mp_addmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_addmod.c; sourceTree = "<group>"; };
+		22C9191B1193400A0083AC69 /* bn_mp_and.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_and.c; sourceTree = "<group>"; };
+		22C9191C1193400A0083AC69 /* bn_mp_clamp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clamp.c; sourceTree = "<group>"; };
+		22C9191D1193400A0083AC69 /* bn_mp_clear_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear_multi.c; sourceTree = "<group>"; };
+		22C9191E1193400A0083AC69 /* bn_mp_clear.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear.c; sourceTree = "<group>"; };
+		22C9191F1193400A0083AC69 /* bn_mp_cmp_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_d.c; sourceTree = "<group>"; };
+		22C919201193400A0083AC69 /* bn_mp_cmp_mag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_mag.c; sourceTree = "<group>"; };
+		22C919211193400A0083AC69 /* bn_mp_cmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp.c; sourceTree = "<group>"; };
+		22C919221193400A0083AC69 /* bn_mp_cnt_lsb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cnt_lsb.c; sourceTree = "<group>"; };
+		22C919231193400A0083AC69 /* bn_mp_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_copy.c; sourceTree = "<group>"; };
+		22C919241193400A0083AC69 /* bn_mp_count_bits.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_count_bits.c; sourceTree = "<group>"; };
+		22C919251193400A0083AC69 /* bn_mp_div_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2.c; sourceTree = "<group>"; };
+		22C919261193400A0083AC69 /* bn_mp_div_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2d.c; sourceTree = "<group>"; };
+		22C919271193400A0083AC69 /* bn_mp_div_3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_3.c; sourceTree = "<group>"; };
+		22C919281193400A0083AC69 /* bn_mp_div_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_d.c; sourceTree = "<group>"; };
+		22C919291193400A0083AC69 /* bn_mp_div.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div.c; sourceTree = "<group>"; };
+		22C9192A1193400A0083AC69 /* bn_mp_dr_is_modulus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_dr_is_modulus.c; sourceTree = "<group>"; };
+		22C9192B1193400A0083AC69 /* bn_mp_dr_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_dr_reduce.c; sourceTree = "<group>"; };
+		22C9192C1193400A0083AC69 /* bn_mp_dr_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_dr_setup.c; sourceTree = "<group>"; };
+		22C9192D1193400A0083AC69 /* bn_mp_exch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exch.c; sourceTree = "<group>"; };
+		22C9192E1193400A0083AC69 /* bn_mp_expt_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_expt_d.c; sourceTree = "<group>"; };
+		22C9192F1193400A0083AC69 /* bn_mp_exptmod_fast.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exptmod_fast.c; sourceTree = "<group>"; };
+		22C919301193400A0083AC69 /* bn_mp_exptmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exptmod.c; sourceTree = "<group>"; };
+		22C919311193400A0083AC69 /* bn_mp_exteuclid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exteuclid.c; sourceTree = "<group>"; };
+		22C919321193400A0083AC69 /* bn_mp_fread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_fread.c; sourceTree = "<group>"; };
+		22C919331193400A0083AC69 /* bn_mp_fwrite.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_fwrite.c; sourceTree = "<group>"; };
+		22C919341193400A0083AC69 /* bn_mp_gcd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_gcd.c; sourceTree = "<group>"; };
+		22C919351193400A0083AC69 /* bn_mp_get_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_get_int.c; sourceTree = "<group>"; };
+		22C919361193400A0083AC69 /* bn_mp_grow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_grow.c; sourceTree = "<group>"; };
+		22C919371193400A0083AC69 /* bn_mp_init_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_copy.c; sourceTree = "<group>"; };
+		22C919381193400A0083AC69 /* bn_mp_init_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_multi.c; sourceTree = "<group>"; };
+		22C919391193400A0083AC69 /* bn_mp_init_set_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_set_int.c; sourceTree = "<group>"; };
+		22C9193A1193400A0083AC69 /* bn_mp_init_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_set.c; sourceTree = "<group>"; };
+		22C9193B1193400A0083AC69 /* bn_mp_init_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_size.c; sourceTree = "<group>"; };
+		22C9193C1193400A0083AC69 /* bn_mp_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init.c; sourceTree = "<group>"; };
+		22C9193D1193400A0083AC69 /* bn_mp_invmod_slow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_invmod_slow.c; sourceTree = "<group>"; };
+		22C9193E1193400A0083AC69 /* bn_mp_invmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_invmod.c; sourceTree = "<group>"; };
+		22C9193F1193400A0083AC69 /* bn_mp_is_square.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_is_square.c; sourceTree = "<group>"; };
+		22C919401193400A0083AC69 /* bn_mp_jacobi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_jacobi.c; sourceTree = "<group>"; };
+		22C919411193400A0083AC69 /* bn_mp_karatsuba_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_mul.c; sourceTree = "<group>"; };
+		22C919421193400A0083AC69 /* bn_mp_karatsuba_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_sqr.c; sourceTree = "<group>"; };
+		22C919431193400A0083AC69 /* bn_mp_lcm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_lcm.c; sourceTree = "<group>"; };
+		22C919441193400A0083AC69 /* bn_mp_lshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_lshd.c; sourceTree = "<group>"; };
+		22C919451193400A0083AC69 /* bn_mp_mod_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod_2d.c; sourceTree = "<group>"; };
+		22C919461193400A0083AC69 /* bn_mp_mod_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod_d.c; sourceTree = "<group>"; };
+		22C919471193400A0083AC69 /* bn_mp_mod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod.c; sourceTree = "<group>"; };
+		22C919481193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_montgomery_calc_normalization.c; sourceTree = "<group>"; };
+		22C919491193400A0083AC69 /* bn_mp_montgomery_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_montgomery_reduce.c; sourceTree = "<group>"; };
+		22C9194A1193400A0083AC69 /* bn_mp_montgomery_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_montgomery_setup.c; sourceTree = "<group>"; };
+		22C9194B1193400A0083AC69 /* bn_mp_mul_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2.c; sourceTree = "<group>"; };
+		22C9194C1193400A0083AC69 /* bn_mp_mul_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2d.c; sourceTree = "<group>"; };
+		22C9194D1193400A0083AC69 /* bn_mp_mul_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_d.c; sourceTree = "<group>"; };
+		22C9194E1193400A0083AC69 /* bn_mp_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul.c; sourceTree = "<group>"; };
+		22C9194F1193400A0083AC69 /* bn_mp_mulmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mulmod.c; sourceTree = "<group>"; };
+		22C919501193400A0083AC69 /* bn_mp_n_root.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_n_root.c; sourceTree = "<group>"; };
+		22C919511193400A0083AC69 /* bn_mp_neg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_neg.c; sourceTree = "<group>"; };
+		22C919521193400A0083AC69 /* bn_mp_or.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_or.c; sourceTree = "<group>"; };
+		22C919531193400A0083AC69 /* bn_mp_prime_fermat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_fermat.c; sourceTree = "<group>"; };
+		22C919541193400A0083AC69 /* bn_mp_prime_is_divisible.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_is_divisible.c; sourceTree = "<group>"; };
+		22C919551193400A0083AC69 /* bn_mp_prime_is_prime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_is_prime.c; sourceTree = "<group>"; };
+		22C919561193400A0083AC69 /* bn_mp_prime_miller_rabin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_miller_rabin.c; sourceTree = "<group>"; };
+		22C919571193400A0083AC69 /* bn_mp_prime_next_prime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_next_prime.c; sourceTree = "<group>"; };
+		22C919581193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_rabin_miller_trials.c; sourceTree = "<group>"; };
+		22C919591193400A0083AC69 /* bn_mp_prime_random_ex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_random_ex.c; sourceTree = "<group>"; };
+		22C9195A1193400A0083AC69 /* bn_mp_radix_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_size.c; sourceTree = "<group>"; };
+		22C9195B1193400A0083AC69 /* bn_mp_radix_smap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_smap.c; sourceTree = "<group>"; };
+		22C9195C1193400A0083AC69 /* bn_mp_rand.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_rand.c; sourceTree = "<group>"; };
+		22C9195D1193400A0083AC69 /* bn_mp_read_radix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_radix.c; sourceTree = "<group>"; };
+		22C9195E1193400A0083AC69 /* bn_mp_read_signed_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_signed_bin.c; sourceTree = "<group>"; };
+		22C9195F1193400A0083AC69 /* bn_mp_read_unsigned_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_unsigned_bin.c; sourceTree = "<group>"; };
+		22C919601193400A0083AC69 /* bn_mp_reduce_2k_l.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k_l.c; sourceTree = "<group>"; };
+		22C919611193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k_setup_l.c; sourceTree = "<group>"; };
+		22C919621193400A0083AC69 /* bn_mp_reduce_2k_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k_setup.c; sourceTree = "<group>"; };
+		22C919631193400A0083AC69 /* bn_mp_reduce_2k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k.c; sourceTree = "<group>"; };
+		22C919641193400A0083AC69 /* bn_mp_reduce_is_2k_l.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_is_2k_l.c; sourceTree = "<group>"; };
+		22C919651193400A0083AC69 /* bn_mp_reduce_is_2k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_is_2k.c; sourceTree = "<group>"; };
+		22C919661193400A0083AC69 /* bn_mp_reduce_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_setup.c; sourceTree = "<group>"; };
+		22C919671193400A0083AC69 /* bn_mp_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce.c; sourceTree = "<group>"; };
+		22C919681193400A0083AC69 /* bn_mp_rshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_rshd.c; sourceTree = "<group>"; };
+		22C919691193400A0083AC69 /* bn_mp_set_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_set_int.c; sourceTree = "<group>"; };
+		22C9196A1193400A0083AC69 /* bn_mp_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_set.c; sourceTree = "<group>"; };
+		22C9196B1193400A0083AC69 /* bn_mp_shrink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_shrink.c; sourceTree = "<group>"; };
+		22C9196C1193400A0083AC69 /* bn_mp_signed_bin_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_signed_bin_size.c; sourceTree = "<group>"; };
+		22C9196D1193400A0083AC69 /* bn_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqr.c; sourceTree = "<group>"; };
+		22C9196E1193400A0083AC69 /* bn_mp_sqrmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqrmod.c; sourceTree = "<group>"; };
+		22C9196F1193400A0083AC69 /* bn_mp_sqrt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqrt.c; sourceTree = "<group>"; };
+		22C919701193400A0083AC69 /* bn_mp_sub_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub_d.c; sourceTree = "<group>"; };
+		22C919711193400A0083AC69 /* bn_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub.c; sourceTree = "<group>"; };
+		22C919721193400A0083AC69 /* bn_mp_submod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_submod.c; sourceTree = "<group>"; };
+		22C919731193400A0083AC69 /* bn_mp_to_signed_bin_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_signed_bin_n.c; sourceTree = "<group>"; };
+		22C919741193400A0083AC69 /* bn_mp_to_signed_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_signed_bin.c; sourceTree = "<group>"; };
+		22C919751193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin_n.c; sourceTree = "<group>"; };
+		22C919761193400A0083AC69 /* bn_mp_to_unsigned_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin.c; sourceTree = "<group>"; };
+		22C919771193400A0083AC69 /* bn_mp_toom_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_mul.c; sourceTree = "<group>"; };
+		22C919781193400A0083AC69 /* bn_mp_toom_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_sqr.c; sourceTree = "<group>"; };
+		22C919791193400A0083AC69 /* bn_mp_toradix_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toradix_n.c; sourceTree = "<group>"; };
+		22C9197A1193400A0083AC69 /* bn_mp_toradix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toradix.c; sourceTree = "<group>"; };
+		22C9197B1193400A0083AC69 /* bn_mp_unsigned_bin_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_unsigned_bin_size.c; sourceTree = "<group>"; };
+		22C9197C1193400A0083AC69 /* bn_mp_xor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_xor.c; sourceTree = "<group>"; };
+		22C9197D1193400A0083AC69 /* bn_mp_zero.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_zero.c; sourceTree = "<group>"; };
+		22C9197E1193400A0083AC69 /* bn_prime_tab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_prime_tab.c; sourceTree = "<group>"; };
+		22C9197F1193400A0083AC69 /* bn_reverse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_reverse.c; sourceTree = "<group>"; };
+		22C919801193400A0083AC69 /* bn_s_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_add.c; sourceTree = "<group>"; };
+		22C919811193400A0083AC69 /* bn_s_mp_exptmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_exptmod.c; sourceTree = "<group>"; };
+		22C919821193400A0083AC69 /* bn_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_mul_digs.c; sourceTree = "<group>"; };
+		22C919831193400A0083AC69 /* bn_s_mp_mul_high_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_mul_high_digs.c; sourceTree = "<group>"; };
+		22C919841193400A0083AC69 /* bn_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sqr.c; sourceTree = "<group>"; };
+		22C919851193400A0083AC69 /* bn_s_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sub.c; sourceTree = "<group>"; };
+		22C919861193400A0083AC69 /* bncore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bncore.c; sourceTree = "<group>"; };
+		22C919871193400A0083AC69 /* tommath_class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_class.h; sourceTree = "<group>"; };
+		22C919881193400A0083AC69 /* tommath_superclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_superclass.h; sourceTree = "<group>"; };
+		22C919891193400A0083AC69 /* tommath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath.h; sourceTree = "<group>"; };
+		22EC6043154B28A000679228 /* FileStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FileStream.h; path = src/FileStream.h; sourceTree = "<group>"; };
+		22F5A9C41193DFBA00F8B121 /* SFileVerify.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileVerify.cpp; path = src/SFileVerify.cpp; sourceTree = "<group>"; };
+		32D20A8A0CF3902D00230E7A /* libbz2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbz2.dylib; path = /usr/lib/libbz2.dylib; sourceTree = "<absolute>"; };
+		32D20A8B0CF3902D00230E7A /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
+		32ED009C0D03542A00AB0B4E /* huff.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = huff.cpp; sourceTree = "<group>"; };
+		32ED009D0D03542A00AB0B4E /* huff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = huff.h; sourceTree = "<group>"; };
+		32ED00A60D03542A00AB0B4E /* explode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = explode.c; sourceTree = "<group>"; };
+		32ED00A70D03542A00AB0B4E /* implode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = implode.c; sourceTree = "<group>"; };
+		32ED00A80D03542A00AB0B4E /* pklib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pklib.h; sourceTree = "<group>"; };
+		32ED00A90D03542A00AB0B4E /* SFileAttributes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileAttributes.cpp; path = src/SFileAttributes.cpp; sourceTree = "<group>"; };
+		32ED00AA0D03542A00AB0B4E /* SBaseCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBaseCommon.cpp; path = src/SBaseCommon.cpp; sourceTree = "<group>"; };
+		32ED00AB0D03542A00AB0B4E /* StormCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StormCommon.h; path = src/StormCommon.h; sourceTree = "<group>"; };
+		32ED00AC0D03542A00AB0B4E /* SCompression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SCompression.cpp; path = src/SCompression.cpp; sourceTree = "<group>"; };
+		32ED00AD0D03542A00AB0B4E /* SFileCompactArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileCompactArchive.cpp; path = src/SFileCompactArchive.cpp; sourceTree = "<group>"; };
+		32ED00AE0D03542A00AB0B4E /* SFileCreateArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileCreateArchive.cpp; path = src/SFileCreateArchive.cpp; sourceTree = "<group>"; };
+		32ED00AF0D03542A00AB0B4E /* SFileExtractFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileExtractFile.cpp; path = src/SFileExtractFile.cpp; sourceTree = "<group>"; };
+		32ED00B00D03542A00AB0B4E /* SFileFindFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileFindFile.cpp; path = src/SFileFindFile.cpp; sourceTree = "<group>"; };
+		32ED00B10D03542A00AB0B4E /* SFileOpenArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileOpenArchive.cpp; path = src/SFileOpenArchive.cpp; sourceTree = "<group>"; };
+		32ED00B20D03542A00AB0B4E /* SFileOpenFileEx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileOpenFileEx.cpp; path = src/SFileOpenFileEx.cpp; sourceTree = "<group>"; };
+		32ED00B30D03542A00AB0B4E /* SFileReadFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileReadFile.cpp; path = src/SFileReadFile.cpp; sourceTree = "<group>"; };
+		32ED00B40D03542A00AB0B4E /* SFileListFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileListFile.cpp; path = src/SFileListFile.cpp; sourceTree = "<group>"; };
+		32ED00B60D03542A00AB0B4E /* StormLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StormLib.h; path = src/StormLib.h; sourceTree = "<group>"; };
+		32ED00B70D03542A00AB0B4E /* StormPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StormPort.h; path = src/StormPort.h; sourceTree = "<group>"; };
+		E60816D51B707A9000B283F7 /* rsa_sign_hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_sign_hash.c; sourceTree = "<group>"; };
+		E60816D81B707B1800B283F7 /* pkcs_1_pss_encode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs_1_pss_encode.c; sourceTree = "<group>"; };
+		E60816DB1B707B2700B283F7 /* pkcs_1_v1_5_encode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs_1_v1_5_encode.c; sourceTree = "<group>"; };
+		E60816DE1B707B5700B283F7 /* der_encode_sequence_ex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_sequence_ex.c; sourceTree = "<group>"; };
+		E60816E11B707B7200B283F7 /* der_encode_bit_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_bit_string.c; sourceTree = "<group>"; };
+		E60816E21B707B7200B283F7 /* der_encode_boolean.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_boolean.c; sourceTree = "<group>"; };
+		E60816E31B707B7200B283F7 /* der_encode_ia5_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_ia5_string.c; sourceTree = "<group>"; };
+		E60816E41B707B7200B283F7 /* der_encode_integer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_integer.c; sourceTree = "<group>"; };
+		E60816E51B707B7200B283F7 /* der_encode_object_identifier.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_object_identifier.c; sourceTree = "<group>"; };
+		E60816E61B707B7200B283F7 /* der_encode_octet_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_octet_string.c; sourceTree = "<group>"; };
+		E60816E71B707B7200B283F7 /* der_encode_printable_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_printable_string.c; sourceTree = "<group>"; };
+		E60816E81B707B7200B283F7 /* der_encode_sequence_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_sequence_multi.c; sourceTree = "<group>"; };
+		E60816E91B707B7200B283F7 /* der_encode_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_set.c; sourceTree = "<group>"; };
+		E60816EA1B707B7200B283F7 /* der_encode_setof.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_setof.c; sourceTree = "<group>"; };
+		E60816EB1B707B7200B283F7 /* der_encode_short_integer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_short_integer.c; sourceTree = "<group>"; };
+		E60816EC1B707B7200B283F7 /* der_encode_utctime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_utctime.c; sourceTree = "<group>"; };
+		E60816ED1B707B7200B283F7 /* der_encode_utf8_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_utf8_string.c; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		225530D21056BAC800FA646A /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		225FAC920E53B7F800DA2CAE /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				225FADD40E53C06600DA2CAE /* libbz2.dylib in Frameworks */,
+				225FADD50E53C06600DA2CAE /* libz.dylib in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		22954ACC11D463A30064B264 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				22954AD611D463BE0064B264 /* libbz2.dylib in Frameworks */,
+				22954AD711D463BE0064B264 /* libz.dylib in Frameworks */,
+				22954AD311D463B50064B264 /* libStormLib.a in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		034768DDFF38A45A11DB9C8B /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				225FAC940E53B7F800DA2CAE /* StormLib.framework */,
+				225530D41056BAC800FA646A /* libStormLib.a */,
+				22954ACE11D463A30064B264 /* StormLib_Test */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		0867D691FE84028FC02AAC07 /* stormlib */ = {
+			isa = PBXGroup;
+			children = (
+				32DBEE830D00E58F00DB1E81 /* Source */,
+				2295488711D45A520064B264 /* Test */,
+				0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */,
+				22B54B321054B287001D6436 /* Resources */,
+				034768DDFF38A45A11DB9C8B /* Products */,
+				2253A19F10568A83001909F9 /* StormLib.exp */,
+			);
+			name = stormlib;
+			sourceTree = "<group>";
+		};
+		0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = {
+			isa = PBXGroup;
+			children = (
+				32D20A8A0CF3902D00230E7A /* libbz2.dylib */,
+				32D20A8B0CF3902D00230E7A /* libz.dylib */,
+			);
+			name = "External Frameworks and Libraries";
+			sourceTree = "<group>";
+		};
+		221F652D116851D70026C852 /* lzma */ = {
+			isa = PBXGroup;
+			children = (
+				221F6AB31168545B0026C852 /* LzFind.c */,
+				221F6AB41168545B0026C852 /* LzFind.h */,
+				221F6AB9116854730026C852 /* LzHash.h */,
+				221F6A7D116852B20026C852 /* LzmaDec.c */,
+				221F6A721168529C0026C852 /* LzmaDec.h */,
+				221F6A7A116852AA0026C852 /* LzmaEnc.c */,
+				221F6A731168529C0026C852 /* LzmaEnc.h */,
+				221F6ABC116854870026C852 /* Types.h */,
+			);
+			name = lzma;
+			path = src/lzma;
+			sourceTree = "<group>";
+		};
+		225C734A1257CCC70009E8DA /* jenkins */ = {
+			isa = PBXGroup;
+			children = (
+				225C734B1257CCC70009E8DA /* lookup.h */,
+				225C734C1257CCC70009E8DA /* lookup3.c */,
+			);
+			name = jenkins;
+			path = src/jenkins;
+			sourceTree = "<group>";
+		};
+		2295488711D45A520064B264 /* Test */ = {
+			isa = PBXGroup;
+			children = (
+				2295488911D45A820064B264 /* Test.cpp */,
+			);
+			name = Test;
+			sourceTree = "<group>";
+		};
+		2299D9D41167EFA8005C19BF /* adpcm */ = {
+			isa = PBXGroup;
+			children = (
+				2299D9D51167EFA8005C19BF /* adpcm.cpp */,
+				2299D9D61167EFA8005C19BF /* adpcm.h */,
+			);
+			name = adpcm;
+			path = src/adpcm;
+			sourceTree = "<group>";
+		};
+		2299D9DB1167EFC6005C19BF /* sparse */ = {
+			isa = PBXGroup;
+			children = (
+				2299D9DC1167EFC6005C19BF /* sparse.cpp */,
+				2299D9DD1167EFC6005C19BF /* sparse.h */,
+			);
+			name = sparse;
+			path = src/sparse;
+			sourceTree = "<group>";
+		};
+		22B54B321054B287001D6436 /* Resources */ = {
+			isa = PBXGroup;
+			children = (
+				225FAC950E53B7F800DA2CAE /* Info.plist */,
+			);
+			name = Resources;
+			sourceTree = "<group>";
+		};
+		22C9181D11933E3A0083AC69 /* libtomcrypt */ = {
+			isa = PBXGroup;
+			children = (
+				22C9182A11933FCF0083AC69 /* hashes */,
+				22C9182E11933FCF0083AC69 /* headers */,
+				22C9183C11933FCF0083AC69 /* math */,
+				22C9184011933FCF0083AC69 /* misc */,
+				22C9184E11933FCF0083AC69 /* pk */,
+			);
+			name = libtomcrypt;
+			path = src/libtomcrypt;
+			sourceTree = "<group>";
+		};
+		22C9181E11933E470083AC69 /* libtommath */ = {
+			isa = PBXGroup;
+			children = (
+				22C919111193400A0083AC69 /* bn_fast_mp_invmod.c */,
+				22C919121193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c */,
+				22C919131193400A0083AC69 /* bn_fast_s_mp_mul_digs.c */,
+				22C919141193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c */,
+				22C919151193400A0083AC69 /* bn_fast_s_mp_sqr.c */,
+				22C919161193400A0083AC69 /* bn_mp_2expt.c */,
+				22C919171193400A0083AC69 /* bn_mp_abs.c */,
+				22C919181193400A0083AC69 /* bn_mp_add_d.c */,
+				22C919191193400A0083AC69 /* bn_mp_add.c */,
+				22C9191A1193400A0083AC69 /* bn_mp_addmod.c */,
+				22C9191B1193400A0083AC69 /* bn_mp_and.c */,
+				22C9191C1193400A0083AC69 /* bn_mp_clamp.c */,
+				22C9191D1193400A0083AC69 /* bn_mp_clear_multi.c */,
+				22C9191E1193400A0083AC69 /* bn_mp_clear.c */,
+				22C9191F1193400A0083AC69 /* bn_mp_cmp_d.c */,
+				22C919201193400A0083AC69 /* bn_mp_cmp_mag.c */,
+				22C919211193400A0083AC69 /* bn_mp_cmp.c */,
+				22C919221193400A0083AC69 /* bn_mp_cnt_lsb.c */,
+				22C919231193400A0083AC69 /* bn_mp_copy.c */,
+				22C919241193400A0083AC69 /* bn_mp_count_bits.c */,
+				22C919251193400A0083AC69 /* bn_mp_div_2.c */,
+				22C919261193400A0083AC69 /* bn_mp_div_2d.c */,
+				22C919271193400A0083AC69 /* bn_mp_div_3.c */,
+				22C919281193400A0083AC69 /* bn_mp_div_d.c */,
+				22C919291193400A0083AC69 /* bn_mp_div.c */,
+				22C9192A1193400A0083AC69 /* bn_mp_dr_is_modulus.c */,
+				22C9192B1193400A0083AC69 /* bn_mp_dr_reduce.c */,
+				22C9192C1193400A0083AC69 /* bn_mp_dr_setup.c */,
+				22C9192D1193400A0083AC69 /* bn_mp_exch.c */,
+				22C9192E1193400A0083AC69 /* bn_mp_expt_d.c */,
+				22C9192F1193400A0083AC69 /* bn_mp_exptmod_fast.c */,
+				22C919301193400A0083AC69 /* bn_mp_exptmod.c */,
+				22C919311193400A0083AC69 /* bn_mp_exteuclid.c */,
+				22C919321193400A0083AC69 /* bn_mp_fread.c */,
+				22C919331193400A0083AC69 /* bn_mp_fwrite.c */,
+				22C919341193400A0083AC69 /* bn_mp_gcd.c */,
+				22C919351193400A0083AC69 /* bn_mp_get_int.c */,
+				22C919361193400A0083AC69 /* bn_mp_grow.c */,
+				22C919371193400A0083AC69 /* bn_mp_init_copy.c */,
+				22C919381193400A0083AC69 /* bn_mp_init_multi.c */,
+				22C919391193400A0083AC69 /* bn_mp_init_set_int.c */,
+				22C9193A1193400A0083AC69 /* bn_mp_init_set.c */,
+				22C9193B1193400A0083AC69 /* bn_mp_init_size.c */,
+				22C9193C1193400A0083AC69 /* bn_mp_init.c */,
+				22C9193D1193400A0083AC69 /* bn_mp_invmod_slow.c */,
+				22C9193E1193400A0083AC69 /* bn_mp_invmod.c */,
+				22C9193F1193400A0083AC69 /* bn_mp_is_square.c */,
+				22C919401193400A0083AC69 /* bn_mp_jacobi.c */,
+				22C919411193400A0083AC69 /* bn_mp_karatsuba_mul.c */,
+				22C919421193400A0083AC69 /* bn_mp_karatsuba_sqr.c */,
+				22C919431193400A0083AC69 /* bn_mp_lcm.c */,
+				22C919441193400A0083AC69 /* bn_mp_lshd.c */,
+				22C919451193400A0083AC69 /* bn_mp_mod_2d.c */,
+				22C919461193400A0083AC69 /* bn_mp_mod_d.c */,
+				22C919471193400A0083AC69 /* bn_mp_mod.c */,
+				22C919481193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c */,
+				22C919491193400A0083AC69 /* bn_mp_montgomery_reduce.c */,
+				22C9194A1193400A0083AC69 /* bn_mp_montgomery_setup.c */,
+				22C9194B1193400A0083AC69 /* bn_mp_mul_2.c */,
+				22C9194C1193400A0083AC69 /* bn_mp_mul_2d.c */,
+				22C9194D1193400A0083AC69 /* bn_mp_mul_d.c */,
+				22C9194E1193400A0083AC69 /* bn_mp_mul.c */,
+				22C9194F1193400A0083AC69 /* bn_mp_mulmod.c */,
+				22C919501193400A0083AC69 /* bn_mp_n_root.c */,
+				22C919511193400A0083AC69 /* bn_mp_neg.c */,
+				22C919521193400A0083AC69 /* bn_mp_or.c */,
+				22C919531193400A0083AC69 /* bn_mp_prime_fermat.c */,
+				22C919541193400A0083AC69 /* bn_mp_prime_is_divisible.c */,
+				22C919551193400A0083AC69 /* bn_mp_prime_is_prime.c */,
+				22C919561193400A0083AC69 /* bn_mp_prime_miller_rabin.c */,
+				22C919571193400A0083AC69 /* bn_mp_prime_next_prime.c */,
+				22C919581193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c */,
+				22C919591193400A0083AC69 /* bn_mp_prime_random_ex.c */,
+				22C9195A1193400A0083AC69 /* bn_mp_radix_size.c */,
+				22C9195B1193400A0083AC69 /* bn_mp_radix_smap.c */,
+				22C9195C1193400A0083AC69 /* bn_mp_rand.c */,
+				22C9195D1193400A0083AC69 /* bn_mp_read_radix.c */,
+				22C9195E1193400A0083AC69 /* bn_mp_read_signed_bin.c */,
+				22C9195F1193400A0083AC69 /* bn_mp_read_unsigned_bin.c */,
+				22C919601193400A0083AC69 /* bn_mp_reduce_2k_l.c */,
+				22C919611193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c */,
+				22C919621193400A0083AC69 /* bn_mp_reduce_2k_setup.c */,
+				22C919631193400A0083AC69 /* bn_mp_reduce_2k.c */,
+				22C919641193400A0083AC69 /* bn_mp_reduce_is_2k_l.c */,
+				22C919651193400A0083AC69 /* bn_mp_reduce_is_2k.c */,
+				22C919661193400A0083AC69 /* bn_mp_reduce_setup.c */,
+				22C919671193400A0083AC69 /* bn_mp_reduce.c */,
+				22C919681193400A0083AC69 /* bn_mp_rshd.c */,
+				22C919691193400A0083AC69 /* bn_mp_set_int.c */,
+				22C9196A1193400A0083AC69 /* bn_mp_set.c */,
+				22C9196B1193400A0083AC69 /* bn_mp_shrink.c */,
+				22C9196C1193400A0083AC69 /* bn_mp_signed_bin_size.c */,
+				22C9196D1193400A0083AC69 /* bn_mp_sqr.c */,
+				22C9196E1193400A0083AC69 /* bn_mp_sqrmod.c */,
+				22C9196F1193400A0083AC69 /* bn_mp_sqrt.c */,
+				22C919701193400A0083AC69 /* bn_mp_sub_d.c */,
+				22C919711193400A0083AC69 /* bn_mp_sub.c */,
+				22C919721193400A0083AC69 /* bn_mp_submod.c */,
+				22C919731193400A0083AC69 /* bn_mp_to_signed_bin_n.c */,
+				22C919741193400A0083AC69 /* bn_mp_to_signed_bin.c */,
+				22C919751193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c */,
+				22C919761193400A0083AC69 /* bn_mp_to_unsigned_bin.c */,
+				22C919771193400A0083AC69 /* bn_mp_toom_mul.c */,
+				22C919781193400A0083AC69 /* bn_mp_toom_sqr.c */,
+				22C919791193400A0083AC69 /* bn_mp_toradix_n.c */,
+				22C9197A1193400A0083AC69 /* bn_mp_toradix.c */,
+				22C9197B1193400A0083AC69 /* bn_mp_unsigned_bin_size.c */,
+				22C9197C1193400A0083AC69 /* bn_mp_xor.c */,
+				22C9197D1193400A0083AC69 /* bn_mp_zero.c */,
+				22C9197E1193400A0083AC69 /* bn_prime_tab.c */,
+				22C9197F1193400A0083AC69 /* bn_reverse.c */,
+				22C919801193400A0083AC69 /* bn_s_mp_add.c */,
+				22C919811193400A0083AC69 /* bn_s_mp_exptmod.c */,
+				22C919821193400A0083AC69 /* bn_s_mp_mul_digs.c */,
+				22C919831193400A0083AC69 /* bn_s_mp_mul_high_digs.c */,
+				22C919841193400A0083AC69 /* bn_s_mp_sqr.c */,
+				22C919851193400A0083AC69 /* bn_s_mp_sub.c */,
+				22C919861193400A0083AC69 /* bncore.c */,
+				22C919871193400A0083AC69 /* tommath_class.h */,
+				22C919881193400A0083AC69 /* tommath_superclass.h */,
+				22C919891193400A0083AC69 /* tommath.h */,
+			);
+			name = libtommath;
+			path = src/libtommath;
+			sourceTree = "<group>";
+		};
+		22C9182A11933FCF0083AC69 /* hashes */ = {
+			isa = PBXGroup;
+			children = (
+				22C9182B11933FCF0083AC69 /* hash_memory.c */,
+				22C9182C11933FCF0083AC69 /* md5.c */,
+				22C9182D11933FCF0083AC69 /* sha1.c */,
+			);
+			name = hashes;
+			path = src/hashes;
+			sourceTree = "<group>";
+		};
+		22C9182E11933FCF0083AC69 /* headers */ = {
+			isa = PBXGroup;
+			children = (
+				22C9182F11933FCF0083AC69 /* tomcrypt.h */,
+				22C9183011933FCF0083AC69 /* tomcrypt_argchk.h */,
+				22C9183111933FCF0083AC69 /* tomcrypt_cfg.h */,
+				22C9183211933FCF0083AC69 /* tomcrypt_cipher.h */,
+				22C9183311933FCF0083AC69 /* tomcrypt_custom.h */,
+				22C9183411933FCF0083AC69 /* tomcrypt_hash.h */,
+				22C9183511933FCF0083AC69 /* tomcrypt_mac.h */,
+				22C9183611933FCF0083AC69 /* tomcrypt_macros.h */,
+				22C9183711933FCF0083AC69 /* tomcrypt_math.h */,
+				22C9183811933FCF0083AC69 /* tomcrypt_misc.h */,
+				22C9183911933FCF0083AC69 /* tomcrypt_pk.h */,
+				22C9183A11933FCF0083AC69 /* tomcrypt_pkcs.h */,
+				22C9183B11933FCF0083AC69 /* tomcrypt_prng.h */,
+			);
+			name = headers;
+			path = src/headers;
+			sourceTree = "<group>";
+		};
+		22C9183C11933FCF0083AC69 /* math */ = {
+			isa = PBXGroup;
+			children = (
+				22C9183D11933FCF0083AC69 /* ltm_desc.c */,
+				22C9183E11933FCF0083AC69 /* multi.c */,
+				22C9183F11933FCF0083AC69 /* rand_prime.c */,
+			);
+			name = math;
+			path = src/math;
+			sourceTree = "<group>";
+		};
+		22C9184011933FCF0083AC69 /* misc */ = {
+			isa = PBXGroup;
+			children = (
+				22C9184111933FCF0083AC69 /* base64_decode.c */,
+				22C9184211933FCF0083AC69 /* crypt_argchk.c */,
+				22C9184311933FCF0083AC69 /* crypt_find_hash.c */,
+				22C9184411933FCF0083AC69 /* crypt_find_prng.c */,
+				22C9184511933FCF0083AC69 /* crypt_hash_descriptor.c */,
+				22C9184611933FCF0083AC69 /* crypt_hash_is_valid.c */,
+				22C9184711933FCF0083AC69 /* crypt_libc.c */,
+				22C9184811933FCF0083AC69 /* crypt_ltc_mp_descriptor.c */,
+				22C9184911933FCF0083AC69 /* crypt_prng_descriptor.c */,
+				22C9184A11933FCF0083AC69 /* crypt_prng_is_valid.c */,
+				22C9184B11933FCF0083AC69 /* crypt_register_hash.c */,
+				22C9184C11933FCF0083AC69 /* crypt_register_prng.c */,
+				22C9184D11933FCF0083AC69 /* zeromem.c */,
+			);
+			name = misc;
+			path = src/misc;
+			sourceTree = "<group>";
+		};
+		22C9184E11933FCF0083AC69 /* pk */ = {
+			isa = PBXGroup;
+			children = (
+				22C9184F11933FCF0083AC69 /* asn1 */,
+				22C9186A11933FCF0083AC69 /* ecc */,
+				22C9187111933FCF0083AC69 /* pkcs1 */,
+				22C9187611933FCF0083AC69 /* rsa */,
+			);
+			name = pk;
+			path = src/pk;
+			sourceTree = "<group>";
+		};
+		22C9184F11933FCF0083AC69 /* asn1 */ = {
+			isa = PBXGroup;
+			children = (
+				E60816E11B707B7200B283F7 /* der_encode_bit_string.c */,
+				E60816E21B707B7200B283F7 /* der_encode_boolean.c */,
+				E60816E31B707B7200B283F7 /* der_encode_ia5_string.c */,
+				E60816E41B707B7200B283F7 /* der_encode_integer.c */,
+				E60816E51B707B7200B283F7 /* der_encode_object_identifier.c */,
+				E60816E61B707B7200B283F7 /* der_encode_octet_string.c */,
+				E60816E71B707B7200B283F7 /* der_encode_printable_string.c */,
+				E60816E81B707B7200B283F7 /* der_encode_sequence_multi.c */,
+				E60816E91B707B7200B283F7 /* der_encode_set.c */,
+				E60816EA1B707B7200B283F7 /* der_encode_setof.c */,
+				E60816EB1B707B7200B283F7 /* der_encode_short_integer.c */,
+				E60816EC1B707B7200B283F7 /* der_encode_utctime.c */,
+				E60816ED1B707B7200B283F7 /* der_encode_utf8_string.c */,
+				E60816DE1B707B5700B283F7 /* der_encode_sequence_ex.c */,
+				22C9185011933FCF0083AC69 /* der_decode_bit_string.c */,
+				22C9185111933FCF0083AC69 /* der_decode_boolean.c */,
+				22C9185211933FCF0083AC69 /* der_decode_choice.c */,
+				22C9185311933FCF0083AC69 /* der_decode_ia5_string.c */,
+				22C9185411933FCF0083AC69 /* der_decode_integer.c */,
+				22C9185511933FCF0083AC69 /* der_decode_object_identifier.c */,
+				22C9185611933FCF0083AC69 /* der_decode_octet_string.c */,
+				22C9185711933FCF0083AC69 /* der_decode_printable_string.c */,
+				22C9185811933FCF0083AC69 /* der_decode_sequence_ex.c */,
+				22C9185911933FCF0083AC69 /* der_decode_sequence_flexi.c */,
+				22C9185A11933FCF0083AC69 /* der_decode_sequence_multi.c */,
+				22C9185B11933FCF0083AC69 /* der_decode_short_integer.c */,
+				22C9185C11933FCF0083AC69 /* der_decode_utctime.c */,
+				22C9185D11933FCF0083AC69 /* der_decode_utf8_string.c */,
+				22C9185E11933FCF0083AC69 /* der_length_bit_string.c */,
+				22C9185F11933FCF0083AC69 /* der_length_boolean.c */,
+				22C9186011933FCF0083AC69 /* der_length_ia5_string.c */,
+				22C9186111933FCF0083AC69 /* der_length_integer.c */,
+				22C9186211933FCF0083AC69 /* der_length_object_identifier.c */,
+				22C9186311933FCF0083AC69 /* der_length_octet_string.c */,
+				22C9186411933FCF0083AC69 /* der_length_printable_string.c */,
+				22C9186511933FCF0083AC69 /* der_length_sequence.c */,
+				22C9186611933FCF0083AC69 /* der_length_short_integer.c */,
+				22C9186711933FCF0083AC69 /* der_length_utctime.c */,
+				22C9186811933FCF0083AC69 /* der_length_utf8_string.c */,
+				22C9186911933FCF0083AC69 /* der_sequence_free.c */,
+			);
+			path = asn1;
+			sourceTree = "<group>";
+		};
+		22C9186A11933FCF0083AC69 /* ecc */ = {
+			isa = PBXGroup;
+			children = (
+				22C9186B11933FCF0083AC69 /* ltc_ecc_map.c */,
+				22C9186C11933FCF0083AC69 /* ltc_ecc_mul2add.c */,
+				22C9186D11933FCF0083AC69 /* ltc_ecc_mulmod.c */,
+				22C9186E11933FCF0083AC69 /* ltc_ecc_points.c */,
+				22C9186F11933FCF0083AC69 /* ltc_ecc_projective_add_point.c */,
+				22C9187011933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c */,
+			);
+			path = ecc;
+			sourceTree = "<group>";
+		};
+		22C9187111933FCF0083AC69 /* pkcs1 */ = {
+			isa = PBXGroup;
+			children = (
+				E60816DB1B707B2700B283F7 /* pkcs_1_v1_5_encode.c */,
+				E60816D81B707B1800B283F7 /* pkcs_1_pss_encode.c */,
+				22C9187211933FCF0083AC69 /* pkcs_1_mgf1.c */,
+				22C9187311933FCF0083AC69 /* pkcs_1_oaep_decode.c */,
+				22C9187411933FCF0083AC69 /* pkcs_1_pss_decode.c */,
+				22C9187511933FCF0083AC69 /* pkcs_1_v1_5_decode.c */,
+			);
+			path = pkcs1;
+			sourceTree = "<group>";
+		};
+		22C9187611933FCF0083AC69 /* rsa */ = {
+			isa = PBXGroup;
+			children = (
+				E60816D51B707A9000B283F7 /* rsa_sign_hash.c */,
+				22C9187711933FCF0083AC69 /* rsa_exptmod.c */,
+				22C9187811933FCF0083AC69 /* rsa_free.c */,
+				22C9187911933FCF0083AC69 /* rsa_import.c */,
+				22C9187A11933FCF0083AC69 /* rsa_make_key.c */,
+				22C9187B11933FCF0083AC69 /* rsa_verify_hash.c */,
+				22C9187C11933FCF0083AC69 /* rsa_verify_simple.c */,
+			);
+			path = rsa;
+			sourceTree = "<group>";
+		};
+		32DBEE830D00E58F00DB1E81 /* Source */ = {
+			isa = PBXGroup;
+			children = (
+				2299D9D41167EFA8005C19BF /* adpcm */,
+				32ED009B0D03542A00AB0B4E /* huffman */,
+				225C734A1257CCC70009E8DA /* jenkins */,
+				22C9181D11933E3A0083AC69 /* libtomcrypt */,
+				22C9181E11933E470083AC69 /* libtommath */,
+				221F652D116851D70026C852 /* lzma */,
+				32ED00A40D03542A00AB0B4E /* pklib */,
+				2299D9DB1167EFC6005C19BF /* sparse */,
+				228B538311BF7D0D001A58DA /* FileStream.cpp */,
+				22EC6043154B28A000679228 /* FileStream.h */,
+				32ED00AA0D03542A00AB0B4E /* SBaseCommon.cpp */,
+				226C7CA61857DE9400AB689C /* SBaseDumpData.cpp */,
+				225C73531257CD0C0009E8DA /* SBaseFileTable.cpp */,
+				226C7CA91857DEAC00AB689C /* SBaseSubTypes.cpp */,
+				32ED00AC0D03542A00AB0B4E /* SCompression.cpp */,
+				2299DA4D1167FD16005C19BF /* SFileAddFile.cpp */,
+				32ED00A90D03542A00AB0B4E /* SFileAttributes.cpp */,
+				32ED00AD0D03542A00AB0B4E /* SFileCompactArchive.cpp */,
+				32ED00AE0D03542A00AB0B4E /* SFileCreateArchive.cpp */,
+				32ED00AF0D03542A00AB0B4E /* SFileExtractFile.cpp */,
+				32ED00B00D03542A00AB0B4E /* SFileFindFile.cpp */,
+				226C7CAC1857DEEB00AB689C /* SFileGetFileInfo.cpp */,
+				32ED00B40D03542A00AB0B4E /* SFileListFile.cpp */,
+				32ED00B10D03542A00AB0B4E /* SFileOpenArchive.cpp */,
+				32ED00B20D03542A00AB0B4E /* SFileOpenFileEx.cpp */,
+				22AEA121123125D800359B16 /* SFilePatchArchives.cpp */,
+				32ED00B30D03542A00AB0B4E /* SFileReadFile.cpp */,
+				22F5A9C41193DFBA00F8B121 /* SFileVerify.cpp */,
+				32ED00AB0D03542A00AB0B4E /* StormCommon.h */,
+				32ED00B60D03542A00AB0B4E /* StormLib.h */,
+				32ED00B70D03542A00AB0B4E /* StormPort.h */,
+			);
+			name = Source;
+			sourceTree = "<group>";
+		};
+		32ED009B0D03542A00AB0B4E /* huffman */ = {
+			isa = PBXGroup;
+			children = (
+				32ED009C0D03542A00AB0B4E /* huff.cpp */,
+				32ED009D0D03542A00AB0B4E /* huff.h */,
+			);
+			name = huffman;
+			path = src/huffman;
+			sourceTree = "<group>";
+		};
+		32ED00A40D03542A00AB0B4E /* pklib */ = {
+			isa = PBXGroup;
+			children = (
+				32ED00A60D03542A00AB0B4E /* explode.c */,
+				32ED00A70D03542A00AB0B4E /* implode.c */,
+				32ED00A80D03542A00AB0B4E /* pklib.h */,
+			);
+			name = pklib;
+			path = src/pklib;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+		225530D01056BAC800FA646A /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				225530DB1056BC7900FA646A /* huff.h in Headers */,
+				225530DE1056BC7900FA646A /* pklib.h in Headers */,
+				225530DF1056BC7900FA646A /* StormCommon.h in Headers */,
+				225530E01056BC7900FA646A /* StormLib.h in Headers */,
+				225530E11056BC7900FA646A /* StormPort.h in Headers */,
+				2299D9DA1167EFA8005C19BF /* adpcm.h in Headers */,
+				2299D9E11167EFC6005C19BF /* sparse.h in Headers */,
+				221F6A761168529C0026C852 /* LzmaDec.h in Headers */,
+				221F6A771168529C0026C852 /* LzmaEnc.h in Headers */,
+				221F6AB81168545B0026C852 /* LzFind.h in Headers */,
+				221F6ABB116854730026C852 /* LzHash.h in Headers */,
+				221F6ABE116854870026C852 /* Types.h in Headers */,
+				22C9188011933FCF0083AC69 /* tomcrypt.h in Headers */,
+				22C9188111933FCF0083AC69 /* tomcrypt_argchk.h in Headers */,
+				22C9188211933FCF0083AC69 /* tomcrypt_cfg.h in Headers */,
+				22C9188311933FCF0083AC69 /* tomcrypt_cipher.h in Headers */,
+				22C9188411933FCF0083AC69 /* tomcrypt_custom.h in Headers */,
+				22C9188511933FCF0083AC69 /* tomcrypt_hash.h in Headers */,
+				22C9188611933FCF0083AC69 /* tomcrypt_mac.h in Headers */,
+				22C9188711933FCF0083AC69 /* tomcrypt_macros.h in Headers */,
+				22C9188811933FCF0083AC69 /* tomcrypt_math.h in Headers */,
+				22C9188911933FCF0083AC69 /* tomcrypt_misc.h in Headers */,
+				22C9188A11933FCF0083AC69 /* tomcrypt_pk.h in Headers */,
+				22C9188B11933FCF0083AC69 /* tomcrypt_pkcs.h in Headers */,
+				22C9188C11933FCF0083AC69 /* tomcrypt_prng.h in Headers */,
+				22C91A001193400A0083AC69 /* tommath_class.h in Headers */,
+				22C91A011193400A0083AC69 /* tommath_superclass.h in Headers */,
+				22C91A021193400A0083AC69 /* tommath.h in Headers */,
+				225C734F1257CCC70009E8DA /* lookup.h in Headers */,
+				22EC6044154B28A000679228 /* FileStream.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		225FAC8F0E53B7F800DA2CAE /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				225FAC9C0E53BAA100DA2CAE /* huff.h in Headers */,
+				225FAC9F0E53BAA100DA2CAE /* pklib.h in Headers */,
+				225FACA00E53BAA100DA2CAE /* StormCommon.h in Headers */,
+				225FACA10E53BAA100DA2CAE /* StormLib.h in Headers */,
+				225FACA20E53BAA100DA2CAE /* StormPort.h in Headers */,
+				2299D9D81167EFA8005C19BF /* adpcm.h in Headers */,
+				2299D9DF1167EFC6005C19BF /* sparse.h in Headers */,
+				221F6A741168529C0026C852 /* LzmaDec.h in Headers */,
+				221F6A751168529C0026C852 /* LzmaEnc.h in Headers */,
+				221F6AB61168545B0026C852 /* LzFind.h in Headers */,
+				221F6ABA116854730026C852 /* LzHash.h in Headers */,
+				221F6ABD116854870026C852 /* Types.h in Headers */,
+				22C918CA11933FCF0083AC69 /* tomcrypt.h in Headers */,
+				22C918CB11933FCF0083AC69 /* tomcrypt_argchk.h in Headers */,
+				22C918CC11933FCF0083AC69 /* tomcrypt_cfg.h in Headers */,
+				22C918CD11933FCF0083AC69 /* tomcrypt_cipher.h in Headers */,
+				22C918CE11933FCF0083AC69 /* tomcrypt_custom.h in Headers */,
+				22C918CF11933FCF0083AC69 /* tomcrypt_hash.h in Headers */,
+				22C918D011933FCF0083AC69 /* tomcrypt_mac.h in Headers */,
+				22C918D111933FCF0083AC69 /* tomcrypt_macros.h in Headers */,
+				22C918D211933FCF0083AC69 /* tomcrypt_math.h in Headers */,
+				22C918D311933FCF0083AC69 /* tomcrypt_misc.h in Headers */,
+				22C918D411933FCF0083AC69 /* tomcrypt_pk.h in Headers */,
+				22C918D511933FCF0083AC69 /* tomcrypt_pkcs.h in Headers */,
+				22C918D611933FCF0083AC69 /* tomcrypt_prng.h in Headers */,
+				22C91A791193400A0083AC69 /* tommath_class.h in Headers */,
+				22C91A7A1193400A0083AC69 /* tommath_superclass.h in Headers */,
+				22C91A7B1193400A0083AC69 /* tommath.h in Headers */,
+				225C734D1257CCC70009E8DA /* lookup.h in Headers */,
+				22EC6045154B28A000679228 /* FileStream.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+		225530D31056BAC800FA646A /* StormLib */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 225530D71056BB1600FA646A /* Build configuration list for PBXNativeTarget "StormLib" */;
+			buildPhases = (
+				225530D01056BAC800FA646A /* Headers */,
+				225530D11056BAC800FA646A /* Sources */,
+				225530D21056BAC800FA646A /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = StormLib;
+			productName = StormLib;
+			productReference = 225530D41056BAC800FA646A /* libStormLib.a */;
+			productType = "com.apple.product-type.library.static";
+		};
+		225FAC930E53B7F800DA2CAE /* StormLibFramework */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 225FAC980E53B7F900DA2CAE /* Build configuration list for PBXNativeTarget "StormLibFramework" */;
+			buildPhases = (
+				225FAC8F0E53B7F800DA2CAE /* Headers */,
+				225FAC900E53B7F800DA2CAE /* Resources */,
+				225FAC910E53B7F800DA2CAE /* Sources */,
+				225FAC920E53B7F800DA2CAE /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = StormLibFramework;
+			productName = StormLib;
+			productReference = 225FAC940E53B7F800DA2CAE /* StormLib.framework */;
+			productType = "com.apple.product-type.framework";
+		};
+		22954ACD11D463A30064B264 /* StormLib_Test */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 22954AD911D463E00064B264 /* Build configuration list for PBXNativeTarget "StormLib_Test" */;
+			buildPhases = (
+				22954ACB11D463A30064B264 /* Sources */,
+				22954ACC11D463A30064B264 /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				2229F62F11D4653600118914 /* PBXTargetDependency */,
+			);
+			name = StormLib_Test;
+			productName = StormLib_Test;
+			productReference = 22954ACE11D463A30064B264 /* StormLib_Test */;
+			productType = "com.apple.product-type.tool";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		0867D690FE84028FC02AAC07 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 0500;
+			};
+			buildConfigurationList = 1DEB916408733D950010E9CD /* Build configuration list for PBXProject "StormLib" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = English;
+			hasScannedForEncodings = 1;
+			knownRegions = (
+				en,
+			);
+			mainGroup = 0867D691FE84028FC02AAC07 /* stormlib */;
+			productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				225530D31056BAC800FA646A /* StormLib */,
+				225FAC930E53B7F800DA2CAE /* StormLibFramework */,
+				22954ACD11D463A30064B264 /* StormLib_Test */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		225FAC900E53B7F800DA2CAE /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		225530D11056BAC800FA646A /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				225530E31056BC8700FA646A /* huff.cpp in Sources */,
+				225530E61056BC8700FA646A /* explode.c in Sources */,
+				226C7CA71857DE9400AB689C /* SBaseDumpData.cpp in Sources */,
+				225530E71056BC8700FA646A /* implode.c in Sources */,
+				225530E81056BC8700FA646A /* SFileAttributes.cpp in Sources */,
+				226C7CAA1857DEAC00AB689C /* SBaseSubTypes.cpp in Sources */,
+				225530E91056BC8700FA646A /* SBaseCommon.cpp in Sources */,
+				225530EA1056BC8700FA646A /* SCompression.cpp in Sources */,
+				225530EB1056BC8700FA646A /* SFileCompactArchive.cpp in Sources */,
+				225530EC1056BC8700FA646A /* SFileCreateArchive.cpp in Sources */,
+				225530ED1056BC8700FA646A /* SFileExtractFile.cpp in Sources */,
+				E60816F81B707B7200B283F7 /* der_encode_octet_string.c in Sources */,
+				225530EE1056BC8700FA646A /* SFileFindFile.cpp in Sources */,
+				225530EF1056BC8700FA646A /* SFileOpenArchive.cpp in Sources */,
+				226C7CAD1857DEEB00AB689C /* SFileGetFileInfo.cpp in Sources */,
+				225530F01056BC8700FA646A /* SFileOpenFileEx.cpp in Sources */,
+				225530F11056BC8700FA646A /* SFileReadFile.cpp in Sources */,
+				225530F21056BC8700FA646A /* SFileListFile.cpp in Sources */,
+				2299D9D91167EFA8005C19BF /* adpcm.cpp in Sources */,
+				2299D9E01167EFC6005C19BF /* sparse.cpp in Sources */,
+				2299DA4F1167FD16005C19BF /* SFileAddFile.cpp in Sources */,
+				221F6A7C116852AA0026C852 /* LzmaEnc.c in Sources */,
+				221F6A7F116852B20026C852 /* LzmaDec.c in Sources */,
+				221F6AB71168545B0026C852 /* LzFind.c in Sources */,
+				22C9187D11933FCF0083AC69 /* hash_memory.c in Sources */,
+				22C9187E11933FCF0083AC69 /* md5.c in Sources */,
+				22C9187F11933FCF0083AC69 /* sha1.c in Sources */,
+				22C9188D11933FCF0083AC69 /* ltm_desc.c in Sources */,
+				22C9188E11933FCF0083AC69 /* multi.c in Sources */,
+				22C9188F11933FCF0083AC69 /* rand_prime.c in Sources */,
+				22C9189011933FCF0083AC69 /* base64_decode.c in Sources */,
+				22C9189111933FCF0083AC69 /* crypt_argchk.c in Sources */,
+				22C9189211933FCF0083AC69 /* crypt_find_hash.c in Sources */,
+				22C9189311933FCF0083AC69 /* crypt_find_prng.c in Sources */,
+				22C9189411933FCF0083AC69 /* crypt_hash_descriptor.c in Sources */,
+				22C9189511933FCF0083AC69 /* crypt_hash_is_valid.c in Sources */,
+				22C9189611933FCF0083AC69 /* crypt_libc.c in Sources */,
+				2254917B11948CE70044424D /* crypt_ltc_mp_descriptor.c in Sources */,
+				22C9189811933FCF0083AC69 /* crypt_prng_descriptor.c in Sources */,
+				22C9189911933FCF0083AC69 /* crypt_prng_is_valid.c in Sources */,
+				22C9189A11933FCF0083AC69 /* crypt_register_hash.c in Sources */,
+				22C9189B11933FCF0083AC69 /* crypt_register_prng.c in Sources */,
+				22C9189C11933FCF0083AC69 /* zeromem.c in Sources */,
+				22C9189D11933FCF0083AC69 /* der_decode_bit_string.c in Sources */,
+				22C9189E11933FCF0083AC69 /* der_decode_boolean.c in Sources */,
+				22C9189F11933FCF0083AC69 /* der_decode_choice.c in Sources */,
+				22C918A011933FCF0083AC69 /* der_decode_ia5_string.c in Sources */,
+				22C918A111933FCF0083AC69 /* der_decode_integer.c in Sources */,
+				22C918A211933FCF0083AC69 /* der_decode_object_identifier.c in Sources */,
+				22C918A311933FCF0083AC69 /* der_decode_octet_string.c in Sources */,
+				22C918A411933FCF0083AC69 /* der_decode_printable_string.c in Sources */,
+				22C918A511933FCF0083AC69 /* der_decode_sequence_ex.c in Sources */,
+				22C918A611933FCF0083AC69 /* der_decode_sequence_flexi.c in Sources */,
+				22C918A711933FCF0083AC69 /* der_decode_sequence_multi.c in Sources */,
+				22C918A811933FCF0083AC69 /* der_decode_short_integer.c in Sources */,
+				22C918A911933FCF0083AC69 /* der_decode_utctime.c in Sources */,
+				22C918AA11933FCF0083AC69 /* der_decode_utf8_string.c in Sources */,
+				E60816F01B707B7200B283F7 /* der_encode_boolean.c in Sources */,
+				22C918AB11933FCF0083AC69 /* der_length_bit_string.c in Sources */,
+				22C918AC11933FCF0083AC69 /* der_length_boolean.c in Sources */,
+				22C918AD11933FCF0083AC69 /* der_length_ia5_string.c in Sources */,
+				22C918AE11933FCF0083AC69 /* der_length_integer.c in Sources */,
+				22C918AF11933FCF0083AC69 /* der_length_object_identifier.c in Sources */,
+				22C918B011933FCF0083AC69 /* der_length_octet_string.c in Sources */,
+				22C918B111933FCF0083AC69 /* der_length_printable_string.c in Sources */,
+				22C918B211933FCF0083AC69 /* der_length_sequence.c in Sources */,
+				22C918B311933FCF0083AC69 /* der_length_short_integer.c in Sources */,
+				22C918B411933FCF0083AC69 /* der_length_utctime.c in Sources */,
+				22C918B511933FCF0083AC69 /* der_length_utf8_string.c in Sources */,
+				22C918B611933FCF0083AC69 /* der_sequence_free.c in Sources */,
+				22C918B711933FCF0083AC69 /* ltc_ecc_map.c in Sources */,
+				22C918B811933FCF0083AC69 /* ltc_ecc_mul2add.c in Sources */,
+				22C918B911933FCF0083AC69 /* ltc_ecc_mulmod.c in Sources */,
+				22C918BA11933FCF0083AC69 /* ltc_ecc_points.c in Sources */,
+				22C918BB11933FCF0083AC69 /* ltc_ecc_projective_add_point.c in Sources */,
+				22C918BC11933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c in Sources */,
+				22C918BD11933FCF0083AC69 /* pkcs_1_mgf1.c in Sources */,
+				22C918BE11933FCF0083AC69 /* pkcs_1_oaep_decode.c in Sources */,
+				22C918BF11933FCF0083AC69 /* pkcs_1_pss_decode.c in Sources */,
+				22C918C011933FCF0083AC69 /* pkcs_1_v1_5_decode.c in Sources */,
+				22C918C111933FCF0083AC69 /* rsa_exptmod.c in Sources */,
+				22C918C211933FCF0083AC69 /* rsa_free.c in Sources */,
+				22C918C311933FCF0083AC69 /* rsa_import.c in Sources */,
+				22C918C411933FCF0083AC69 /* rsa_make_key.c in Sources */,
+				22C918C511933FCF0083AC69 /* rsa_verify_hash.c in Sources */,
+				22C918C611933FCF0083AC69 /* rsa_verify_simple.c in Sources */,
+				22C9198A1193400A0083AC69 /* bn_fast_mp_invmod.c in Sources */,
+				22C9198B1193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c in Sources */,
+				E60816F61B707B7200B283F7 /* der_encode_object_identifier.c in Sources */,
+				22C9198C1193400A0083AC69 /* bn_fast_s_mp_mul_digs.c in Sources */,
+				E60816FA1B707B7200B283F7 /* der_encode_printable_string.c in Sources */,
+				22C9198D1193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c in Sources */,
+				22C9198E1193400A0083AC69 /* bn_fast_s_mp_sqr.c in Sources */,
+				22C9198F1193400A0083AC69 /* bn_mp_2expt.c in Sources */,
+				22C919901193400A0083AC69 /* bn_mp_abs.c in Sources */,
+				22C919911193400A0083AC69 /* bn_mp_add_d.c in Sources */,
+				22C919921193400A0083AC69 /* bn_mp_add.c in Sources */,
+				22C919931193400A0083AC69 /* bn_mp_addmod.c in Sources */,
+				22C919941193400A0083AC69 /* bn_mp_and.c in Sources */,
+				22C919951193400A0083AC69 /* bn_mp_clamp.c in Sources */,
+				22C919961193400A0083AC69 /* bn_mp_clear_multi.c in Sources */,
+				22C919971193400A0083AC69 /* bn_mp_clear.c in Sources */,
+				22C919981193400A0083AC69 /* bn_mp_cmp_d.c in Sources */,
+				22C919991193400A0083AC69 /* bn_mp_cmp_mag.c in Sources */,
+				22C9199A1193400A0083AC69 /* bn_mp_cmp.c in Sources */,
+				22C9199B1193400A0083AC69 /* bn_mp_cnt_lsb.c in Sources */,
+				22C9199C1193400A0083AC69 /* bn_mp_copy.c in Sources */,
+				22C9199D1193400A0083AC69 /* bn_mp_count_bits.c in Sources */,
+				E60816F41B707B7200B283F7 /* der_encode_integer.c in Sources */,
+				E60817061B707B7200B283F7 /* der_encode_utf8_string.c in Sources */,
+				22C9199E1193400A0083AC69 /* bn_mp_div_2.c in Sources */,
+				22C9199F1193400A0083AC69 /* bn_mp_div_2d.c in Sources */,
+				22C919A01193400A0083AC69 /* bn_mp_div_3.c in Sources */,
+				22C919A11193400A0083AC69 /* bn_mp_div_d.c in Sources */,
+				22C919A21193400A0083AC69 /* bn_mp_div.c in Sources */,
+				22C919A31193400A0083AC69 /* bn_mp_dr_is_modulus.c in Sources */,
+				22C919A41193400A0083AC69 /* bn_mp_dr_reduce.c in Sources */,
+				22C919A51193400A0083AC69 /* bn_mp_dr_setup.c in Sources */,
+				22C919A61193400A0083AC69 /* bn_mp_exch.c in Sources */,
+				22C919A71193400A0083AC69 /* bn_mp_expt_d.c in Sources */,
+				22C919A81193400A0083AC69 /* bn_mp_exptmod_fast.c in Sources */,
+				22C919A91193400A0083AC69 /* bn_mp_exptmod.c in Sources */,
+				22C919AA1193400A0083AC69 /* bn_mp_exteuclid.c in Sources */,
+				22C919AB1193400A0083AC69 /* bn_mp_fread.c in Sources */,
+				22C919AC1193400A0083AC69 /* bn_mp_fwrite.c in Sources */,
+				22C919AD1193400A0083AC69 /* bn_mp_gcd.c in Sources */,
+				22C919AE1193400A0083AC69 /* bn_mp_get_int.c in Sources */,
+				22C919AF1193400A0083AC69 /* bn_mp_grow.c in Sources */,
+				22C919B01193400A0083AC69 /* bn_mp_init_copy.c in Sources */,
+				22C919B11193400A0083AC69 /* bn_mp_init_multi.c in Sources */,
+				22C919B21193400A0083AC69 /* bn_mp_init_set_int.c in Sources */,
+				22C919B31193400A0083AC69 /* bn_mp_init_set.c in Sources */,
+				22C919B41193400A0083AC69 /* bn_mp_init_size.c in Sources */,
+				22C919B51193400A0083AC69 /* bn_mp_init.c in Sources */,
+				E60816D91B707B1800B283F7 /* pkcs_1_pss_encode.c in Sources */,
+				22C919B61193400A0083AC69 /* bn_mp_invmod_slow.c in Sources */,
+				22C919B71193400A0083AC69 /* bn_mp_invmod.c in Sources */,
+				22C919B81193400A0083AC69 /* bn_mp_is_square.c in Sources */,
+				22C919B91193400A0083AC69 /* bn_mp_jacobi.c in Sources */,
+				22C919BA1193400A0083AC69 /* bn_mp_karatsuba_mul.c in Sources */,
+				22C919BB1193400A0083AC69 /* bn_mp_karatsuba_sqr.c in Sources */,
+				22C919BC1193400A0083AC69 /* bn_mp_lcm.c in Sources */,
+				22C919BD1193400A0083AC69 /* bn_mp_lshd.c in Sources */,
+				22C919BE1193400A0083AC69 /* bn_mp_mod_2d.c in Sources */,
+				22C919BF1193400A0083AC69 /* bn_mp_mod_d.c in Sources */,
+				22C919C01193400A0083AC69 /* bn_mp_mod.c in Sources */,
+				22C919C11193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c in Sources */,
+				22C919C21193400A0083AC69 /* bn_mp_montgomery_reduce.c in Sources */,
+				E60817021B707B7200B283F7 /* der_encode_short_integer.c in Sources */,
+				22C919C31193400A0083AC69 /* bn_mp_montgomery_setup.c in Sources */,
+				E60816DC1B707B2700B283F7 /* pkcs_1_v1_5_encode.c in Sources */,
+				22C919C41193400A0083AC69 /* bn_mp_mul_2.c in Sources */,
+				E60816FC1B707B7200B283F7 /* der_encode_sequence_multi.c in Sources */,
+				22C919C51193400A0083AC69 /* bn_mp_mul_2d.c in Sources */,
+				22C919C61193400A0083AC69 /* bn_mp_mul_d.c in Sources */,
+				22C919C71193400A0083AC69 /* bn_mp_mul.c in Sources */,
+				E60816EE1B707B7200B283F7 /* der_encode_bit_string.c in Sources */,
+				22C919C81193400A0083AC69 /* bn_mp_mulmod.c in Sources */,
+				22C919C91193400A0083AC69 /* bn_mp_n_root.c in Sources */,
+				22C919CA1193400A0083AC69 /* bn_mp_neg.c in Sources */,
+				22C919CB1193400A0083AC69 /* bn_mp_or.c in Sources */,
+				22C919CC1193400A0083AC69 /* bn_mp_prime_fermat.c in Sources */,
+				22C919CD1193400A0083AC69 /* bn_mp_prime_is_divisible.c in Sources */,
+				22C919CE1193400A0083AC69 /* bn_mp_prime_is_prime.c in Sources */,
+				E60816D61B707A9000B283F7 /* rsa_sign_hash.c in Sources */,
+				22C919CF1193400A0083AC69 /* bn_mp_prime_miller_rabin.c in Sources */,
+				22C919D01193400A0083AC69 /* bn_mp_prime_next_prime.c in Sources */,
+				22C919D11193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c in Sources */,
+				22C919D21193400A0083AC69 /* bn_mp_prime_random_ex.c in Sources */,
+				22C919D31193400A0083AC69 /* bn_mp_radix_size.c in Sources */,
+				22C919D41193400A0083AC69 /* bn_mp_radix_smap.c in Sources */,
+				22C919D51193400A0083AC69 /* bn_mp_rand.c in Sources */,
+				22C919D61193400A0083AC69 /* bn_mp_read_radix.c in Sources */,
+				22C919D71193400A0083AC69 /* bn_mp_read_signed_bin.c in Sources */,
+				22C919D81193400A0083AC69 /* bn_mp_read_unsigned_bin.c in Sources */,
+				22C919D91193400A0083AC69 /* bn_mp_reduce_2k_l.c in Sources */,
+				22C919DA1193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c in Sources */,
+				22C919DB1193400A0083AC69 /* bn_mp_reduce_2k_setup.c in Sources */,
+				E60816FE1B707B7200B283F7 /* der_encode_set.c in Sources */,
+				E60817001B707B7200B283F7 /* der_encode_setof.c in Sources */,
+				22C919DC1193400A0083AC69 /* bn_mp_reduce_2k.c in Sources */,
+				22C919DD1193400A0083AC69 /* bn_mp_reduce_is_2k_l.c in Sources */,
+				E60817041B707B7200B283F7 /* der_encode_utctime.c in Sources */,
+				22C919DE1193400A0083AC69 /* bn_mp_reduce_is_2k.c in Sources */,
+				22C919DF1193400A0083AC69 /* bn_mp_reduce_setup.c in Sources */,
+				22C919E01193400A0083AC69 /* bn_mp_reduce.c in Sources */,
+				22C919E11193400A0083AC69 /* bn_mp_rshd.c in Sources */,
+				22C919E21193400A0083AC69 /* bn_mp_set_int.c in Sources */,
+				22C919E31193400A0083AC69 /* bn_mp_set.c in Sources */,
+				22C919E41193400A0083AC69 /* bn_mp_shrink.c in Sources */,
+				22C919E51193400A0083AC69 /* bn_mp_signed_bin_size.c in Sources */,
+				22C919E61193400A0083AC69 /* bn_mp_sqr.c in Sources */,
+				22C919E71193400A0083AC69 /* bn_mp_sqrmod.c in Sources */,
+				22C919E81193400A0083AC69 /* bn_mp_sqrt.c in Sources */,
+				22C919E91193400A0083AC69 /* bn_mp_sub_d.c in Sources */,
+				22C919EA1193400A0083AC69 /* bn_mp_sub.c in Sources */,
+				22C919EB1193400A0083AC69 /* bn_mp_submod.c in Sources */,
+				22C919EC1193400A0083AC69 /* bn_mp_to_signed_bin_n.c in Sources */,
+				22C919ED1193400A0083AC69 /* bn_mp_to_signed_bin.c in Sources */,
+				22C919EE1193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c in Sources */,
+				22C919EF1193400A0083AC69 /* bn_mp_to_unsigned_bin.c in Sources */,
+				22C919F01193400A0083AC69 /* bn_mp_toom_mul.c in Sources */,
+				22C919F11193400A0083AC69 /* bn_mp_toom_sqr.c in Sources */,
+				22C919F21193400A0083AC69 /* bn_mp_toradix_n.c in Sources */,
+				22C919F31193400A0083AC69 /* bn_mp_toradix.c in Sources */,
+				22C919F41193400A0083AC69 /* bn_mp_unsigned_bin_size.c in Sources */,
+				E60816F21B707B7200B283F7 /* der_encode_ia5_string.c in Sources */,
+				E60816DF1B707B5700B283F7 /* der_encode_sequence_ex.c in Sources */,
+				22C919F51193400A0083AC69 /* bn_mp_xor.c in Sources */,
+				22C919F61193400A0083AC69 /* bn_mp_zero.c in Sources */,
+				22C919F71193400A0083AC69 /* bn_prime_tab.c in Sources */,
+				22C919F81193400A0083AC69 /* bn_reverse.c in Sources */,
+				22C919F91193400A0083AC69 /* bn_s_mp_add.c in Sources */,
+				22C919FA1193400A0083AC69 /* bn_s_mp_exptmod.c in Sources */,
+				22C919FB1193400A0083AC69 /* bn_s_mp_mul_digs.c in Sources */,
+				22C919FC1193400A0083AC69 /* bn_s_mp_mul_high_digs.c in Sources */,
+				22C919FD1193400A0083AC69 /* bn_s_mp_sqr.c in Sources */,
+				22C919FE1193400A0083AC69 /* bn_s_mp_sub.c in Sources */,
+				22C919FF1193400A0083AC69 /* bncore.c in Sources */,
+				22F5A9C51193DFBA00F8B121 /* SFileVerify.cpp in Sources */,
+				228B538511BF7D0D001A58DA /* FileStream.cpp in Sources */,
+				22AEA123123125D800359B16 /* SFilePatchArchives.cpp in Sources */,
+				225C73501257CCC70009E8DA /* lookup3.c in Sources */,
+				225C73551257CD0C0009E8DA /* SBaseFileTable.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		225FAC910E53B7F800DA2CAE /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				225FACA50E53BAB400DA2CAE /* huff.cpp in Sources */,
+				225FACA90E53BAB400DA2CAE /* explode.c in Sources */,
+				226C7CA81857DE9400AB689C /* SBaseDumpData.cpp in Sources */,
+				225FACAA0E53BAB400DA2CAE /* implode.c in Sources */,
+				225FACAB0E53BAB400DA2CAE /* SFileAttributes.cpp in Sources */,
+				226C7CAB1857DEAC00AB689C /* SBaseSubTypes.cpp in Sources */,
+				225FACAC0E53BAB400DA2CAE /* SBaseCommon.cpp in Sources */,
+				225FACAD0E53BAB400DA2CAE /* SCompression.cpp in Sources */,
+				225FACAE0E53BAB400DA2CAE /* SFileCompactArchive.cpp in Sources */,
+				225FACAF0E53BAB400DA2CAE /* SFileCreateArchive.cpp in Sources */,
+				225FACB00E53BAB400DA2CAE /* SFileExtractFile.cpp in Sources */,
+				E60816F91B707B7200B283F7 /* der_encode_octet_string.c in Sources */,
+				225FACB10E53BAB400DA2CAE /* SFileFindFile.cpp in Sources */,
+				225FACB20E53BAB400DA2CAE /* SFileOpenArchive.cpp in Sources */,
+				226C7CAE1857DEEB00AB689C /* SFileGetFileInfo.cpp in Sources */,
+				225FACB30E53BAB400DA2CAE /* SFileOpenFileEx.cpp in Sources */,
+				225FACB40E53BAB400DA2CAE /* SFileReadFile.cpp in Sources */,
+				225FACB50E53BAB400DA2CAE /* SFileListFile.cpp in Sources */,
+				2299D9D71167EFA8005C19BF /* adpcm.cpp in Sources */,
+				2299D9DE1167EFC6005C19BF /* sparse.cpp in Sources */,
+				2299DA4E1167FD16005C19BF /* SFileAddFile.cpp in Sources */,
+				221F6A7B116852AA0026C852 /* LzmaEnc.c in Sources */,
+				221F6A7E116852B20026C852 /* LzmaDec.c in Sources */,
+				221F6AB51168545B0026C852 /* LzFind.c in Sources */,
+				22C918C711933FCF0083AC69 /* hash_memory.c in Sources */,
+				22C918C811933FCF0083AC69 /* md5.c in Sources */,
+				22C918C911933FCF0083AC69 /* sha1.c in Sources */,
+				22C918D711933FCF0083AC69 /* ltm_desc.c in Sources */,
+				22C918D811933FCF0083AC69 /* multi.c in Sources */,
+				22C918D911933FCF0083AC69 /* rand_prime.c in Sources */,
+				22C918DA11933FCF0083AC69 /* base64_decode.c in Sources */,
+				22C918DB11933FCF0083AC69 /* crypt_argchk.c in Sources */,
+				22C918DC11933FCF0083AC69 /* crypt_find_hash.c in Sources */,
+				22C918DD11933FCF0083AC69 /* crypt_find_prng.c in Sources */,
+				22C918DE11933FCF0083AC69 /* crypt_hash_descriptor.c in Sources */,
+				22C918DF11933FCF0083AC69 /* crypt_hash_is_valid.c in Sources */,
+				22C918E011933FCF0083AC69 /* crypt_libc.c in Sources */,
+				22C918E111933FCF0083AC69 /* crypt_ltc_mp_descriptor.c in Sources */,
+				22C918E211933FCF0083AC69 /* crypt_prng_descriptor.c in Sources */,
+				22C918E311933FCF0083AC69 /* crypt_prng_is_valid.c in Sources */,
+				22C918E411933FCF0083AC69 /* crypt_register_hash.c in Sources */,
+				22C918E511933FCF0083AC69 /* crypt_register_prng.c in Sources */,
+				22C918E611933FCF0083AC69 /* zeromem.c in Sources */,
+				22C918E711933FCF0083AC69 /* der_decode_bit_string.c in Sources */,
+				22C918E811933FCF0083AC69 /* der_decode_boolean.c in Sources */,
+				22C918E911933FCF0083AC69 /* der_decode_choice.c in Sources */,
+				22C918EA11933FCF0083AC69 /* der_decode_ia5_string.c in Sources */,
+				22C918EB11933FCF0083AC69 /* der_decode_integer.c in Sources */,
+				22C918EC11933FCF0083AC69 /* der_decode_object_identifier.c in Sources */,
+				22C918ED11933FCF0083AC69 /* der_decode_octet_string.c in Sources */,
+				22C918EE11933FCF0083AC69 /* der_decode_printable_string.c in Sources */,
+				22C918EF11933FCF0083AC69 /* der_decode_sequence_ex.c in Sources */,
+				22C918F011933FCF0083AC69 /* der_decode_sequence_flexi.c in Sources */,
+				22C918F111933FCF0083AC69 /* der_decode_sequence_multi.c in Sources */,
+				22C918F211933FCF0083AC69 /* der_decode_short_integer.c in Sources */,
+				22C918F311933FCF0083AC69 /* der_decode_utctime.c in Sources */,
+				22C918F411933FCF0083AC69 /* der_decode_utf8_string.c in Sources */,
+				E60816F11B707B7200B283F7 /* der_encode_boolean.c in Sources */,
+				22C918F511933FCF0083AC69 /* der_length_bit_string.c in Sources */,
+				22C918F611933FCF0083AC69 /* der_length_boolean.c in Sources */,
+				22C918F711933FCF0083AC69 /* der_length_ia5_string.c in Sources */,
+				22C918F811933FCF0083AC69 /* der_length_integer.c in Sources */,
+				22C918F911933FCF0083AC69 /* der_length_object_identifier.c in Sources */,
+				22C918FA11933FCF0083AC69 /* der_length_octet_string.c in Sources */,
+				22C918FB11933FCF0083AC69 /* der_length_printable_string.c in Sources */,
+				22C918FC11933FCF0083AC69 /* der_length_sequence.c in Sources */,
+				22C918FD11933FCF0083AC69 /* der_length_short_integer.c in Sources */,
+				22C918FE11933FCF0083AC69 /* der_length_utctime.c in Sources */,
+				22C918FF11933FCF0083AC69 /* der_length_utf8_string.c in Sources */,
+				22C9190011933FCF0083AC69 /* der_sequence_free.c in Sources */,
+				22C9190111933FCF0083AC69 /* ltc_ecc_map.c in Sources */,
+				22C9190211933FCF0083AC69 /* ltc_ecc_mul2add.c in Sources */,
+				22C9190311933FCF0083AC69 /* ltc_ecc_mulmod.c in Sources */,
+				22C9190411933FCF0083AC69 /* ltc_ecc_points.c in Sources */,
+				22C9190511933FCF0083AC69 /* ltc_ecc_projective_add_point.c in Sources */,
+				22C9190611933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c in Sources */,
+				22C9190711933FCF0083AC69 /* pkcs_1_mgf1.c in Sources */,
+				22C9190811933FCF0083AC69 /* pkcs_1_oaep_decode.c in Sources */,
+				22C9190911933FCF0083AC69 /* pkcs_1_pss_decode.c in Sources */,
+				22C9190A11933FCF0083AC69 /* pkcs_1_v1_5_decode.c in Sources */,
+				22C9190B11933FCF0083AC69 /* rsa_exptmod.c in Sources */,
+				22C9190C11933FCF0083AC69 /* rsa_free.c in Sources */,
+				22C9190D11933FCF0083AC69 /* rsa_import.c in Sources */,
+				22C9190E11933FCF0083AC69 /* rsa_make_key.c in Sources */,
+				22C9190F11933FCF0083AC69 /* rsa_verify_hash.c in Sources */,
+				22C9191011933FCF0083AC69 /* rsa_verify_simple.c in Sources */,
+				22C91A031193400A0083AC69 /* bn_fast_mp_invmod.c in Sources */,
+				22C91A041193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c in Sources */,
+				E60816F71B707B7200B283F7 /* der_encode_object_identifier.c in Sources */,
+				22C91A051193400A0083AC69 /* bn_fast_s_mp_mul_digs.c in Sources */,
+				E60816FB1B707B7200B283F7 /* der_encode_printable_string.c in Sources */,
+				22C91A061193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c in Sources */,
+				22C91A071193400A0083AC69 /* bn_fast_s_mp_sqr.c in Sources */,
+				22C91A081193400A0083AC69 /* bn_mp_2expt.c in Sources */,
+				22C91A091193400A0083AC69 /* bn_mp_abs.c in Sources */,
+				22C91A0A1193400A0083AC69 /* bn_mp_add_d.c in Sources */,
+				22C91A0B1193400A0083AC69 /* bn_mp_add.c in Sources */,
+				22C91A0C1193400A0083AC69 /* bn_mp_addmod.c in Sources */,
+				22C91A0D1193400A0083AC69 /* bn_mp_and.c in Sources */,
+				22C91A0E1193400A0083AC69 /* bn_mp_clamp.c in Sources */,
+				22C91A0F1193400A0083AC69 /* bn_mp_clear_multi.c in Sources */,
+				22C91A101193400A0083AC69 /* bn_mp_clear.c in Sources */,
+				22C91A111193400A0083AC69 /* bn_mp_cmp_d.c in Sources */,
+				22C91A121193400A0083AC69 /* bn_mp_cmp_mag.c in Sources */,
+				22C91A131193400A0083AC69 /* bn_mp_cmp.c in Sources */,
+				22C91A141193400A0083AC69 /* bn_mp_cnt_lsb.c in Sources */,
+				22C91A151193400A0083AC69 /* bn_mp_copy.c in Sources */,
+				22C91A161193400A0083AC69 /* bn_mp_count_bits.c in Sources */,
+				E60816F51B707B7200B283F7 /* der_encode_integer.c in Sources */,
+				E60817071B707B7200B283F7 /* der_encode_utf8_string.c in Sources */,
+				22C91A171193400A0083AC69 /* bn_mp_div_2.c in Sources */,
+				22C91A181193400A0083AC69 /* bn_mp_div_2d.c in Sources */,
+				22C91A191193400A0083AC69 /* bn_mp_div_3.c in Sources */,
+				22C91A1A1193400A0083AC69 /* bn_mp_div_d.c in Sources */,
+				22C91A1B1193400A0083AC69 /* bn_mp_div.c in Sources */,
+				22C91A1C1193400A0083AC69 /* bn_mp_dr_is_modulus.c in Sources */,
+				22C91A1D1193400A0083AC69 /* bn_mp_dr_reduce.c in Sources */,
+				22C91A1E1193400A0083AC69 /* bn_mp_dr_setup.c in Sources */,
+				22C91A1F1193400A0083AC69 /* bn_mp_exch.c in Sources */,
+				22C91A201193400A0083AC69 /* bn_mp_expt_d.c in Sources */,
+				22C91A211193400A0083AC69 /* bn_mp_exptmod_fast.c in Sources */,
+				22C91A221193400A0083AC69 /* bn_mp_exptmod.c in Sources */,
+				22C91A231193400A0083AC69 /* bn_mp_exteuclid.c in Sources */,
+				22C91A241193400A0083AC69 /* bn_mp_fread.c in Sources */,
+				22C91A251193400A0083AC69 /* bn_mp_fwrite.c in Sources */,
+				22C91A261193400A0083AC69 /* bn_mp_gcd.c in Sources */,
+				22C91A271193400A0083AC69 /* bn_mp_get_int.c in Sources */,
+				22C91A281193400A0083AC69 /* bn_mp_grow.c in Sources */,
+				22C91A291193400A0083AC69 /* bn_mp_init_copy.c in Sources */,
+				22C91A2A1193400A0083AC69 /* bn_mp_init_multi.c in Sources */,
+				22C91A2B1193400A0083AC69 /* bn_mp_init_set_int.c in Sources */,
+				22C91A2C1193400A0083AC69 /* bn_mp_init_set.c in Sources */,
+				22C91A2D1193400A0083AC69 /* bn_mp_init_size.c in Sources */,
+				22C91A2E1193400A0083AC69 /* bn_mp_init.c in Sources */,
+				E60816DA1B707B1800B283F7 /* pkcs_1_pss_encode.c in Sources */,
+				22C91A2F1193400A0083AC69 /* bn_mp_invmod_slow.c in Sources */,
+				22C91A301193400A0083AC69 /* bn_mp_invmod.c in Sources */,
+				22C91A311193400A0083AC69 /* bn_mp_is_square.c in Sources */,
+				22C91A321193400A0083AC69 /* bn_mp_jacobi.c in Sources */,
+				22C91A331193400A0083AC69 /* bn_mp_karatsuba_mul.c in Sources */,
+				22C91A341193400A0083AC69 /* bn_mp_karatsuba_sqr.c in Sources */,
+				22C91A351193400A0083AC69 /* bn_mp_lcm.c in Sources */,
+				22C91A361193400A0083AC69 /* bn_mp_lshd.c in Sources */,
+				22C91A371193400A0083AC69 /* bn_mp_mod_2d.c in Sources */,
+				22C91A381193400A0083AC69 /* bn_mp_mod_d.c in Sources */,
+				22C91A391193400A0083AC69 /* bn_mp_mod.c in Sources */,
+				22C91A3A1193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c in Sources */,
+				22C91A3B1193400A0083AC69 /* bn_mp_montgomery_reduce.c in Sources */,
+				E60817031B707B7200B283F7 /* der_encode_short_integer.c in Sources */,
+				22C91A3C1193400A0083AC69 /* bn_mp_montgomery_setup.c in Sources */,
+				E60816DD1B707B2700B283F7 /* pkcs_1_v1_5_encode.c in Sources */,
+				22C91A3D1193400A0083AC69 /* bn_mp_mul_2.c in Sources */,
+				E60816FD1B707B7200B283F7 /* der_encode_sequence_multi.c in Sources */,
+				22C91A3E1193400A0083AC69 /* bn_mp_mul_2d.c in Sources */,
+				22C91A3F1193400A0083AC69 /* bn_mp_mul_d.c in Sources */,
+				22C91A401193400A0083AC69 /* bn_mp_mul.c in Sources */,
+				E60816EF1B707B7200B283F7 /* der_encode_bit_string.c in Sources */,
+				22C91A411193400A0083AC69 /* bn_mp_mulmod.c in Sources */,
+				22C91A421193400A0083AC69 /* bn_mp_n_root.c in Sources */,
+				22C91A431193400A0083AC69 /* bn_mp_neg.c in Sources */,
+				22C91A441193400A0083AC69 /* bn_mp_or.c in Sources */,
+				22C91A451193400A0083AC69 /* bn_mp_prime_fermat.c in Sources */,
+				22C91A461193400A0083AC69 /* bn_mp_prime_is_divisible.c in Sources */,
+				22C91A471193400A0083AC69 /* bn_mp_prime_is_prime.c in Sources */,
+				E60816D71B707A9B00B283F7 /* rsa_sign_hash.c in Sources */,
+				22C91A481193400A0083AC69 /* bn_mp_prime_miller_rabin.c in Sources */,
+				22C91A491193400A0083AC69 /* bn_mp_prime_next_prime.c in Sources */,
+				22C91A4A1193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c in Sources */,
+				22C91A4B1193400A0083AC69 /* bn_mp_prime_random_ex.c in Sources */,
+				22C91A4C1193400A0083AC69 /* bn_mp_radix_size.c in Sources */,
+				22C91A4D1193400A0083AC69 /* bn_mp_radix_smap.c in Sources */,
+				22C91A4E1193400A0083AC69 /* bn_mp_rand.c in Sources */,
+				22C91A4F1193400A0083AC69 /* bn_mp_read_radix.c in Sources */,
+				22C91A501193400A0083AC69 /* bn_mp_read_signed_bin.c in Sources */,
+				22C91A511193400A0083AC69 /* bn_mp_read_unsigned_bin.c in Sources */,
+				22C91A521193400A0083AC69 /* bn_mp_reduce_2k_l.c in Sources */,
+				22C91A531193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c in Sources */,
+				22C91A541193400A0083AC69 /* bn_mp_reduce_2k_setup.c in Sources */,
+				E60816FF1B707B7200B283F7 /* der_encode_set.c in Sources */,
+				E60817011B707B7200B283F7 /* der_encode_setof.c in Sources */,
+				22C91A551193400A0083AC69 /* bn_mp_reduce_2k.c in Sources */,
+				22C91A561193400A0083AC69 /* bn_mp_reduce_is_2k_l.c in Sources */,
+				E60817051B707B7200B283F7 /* der_encode_utctime.c in Sources */,
+				22C91A571193400A0083AC69 /* bn_mp_reduce_is_2k.c in Sources */,
+				22C91A581193400A0083AC69 /* bn_mp_reduce_setup.c in Sources */,
+				22C91A591193400A0083AC69 /* bn_mp_reduce.c in Sources */,
+				22C91A5A1193400A0083AC69 /* bn_mp_rshd.c in Sources */,
+				22C91A5B1193400A0083AC69 /* bn_mp_set_int.c in Sources */,
+				22C91A5C1193400A0083AC69 /* bn_mp_set.c in Sources */,
+				22C91A5D1193400A0083AC69 /* bn_mp_shrink.c in Sources */,
+				22C91A5E1193400A0083AC69 /* bn_mp_signed_bin_size.c in Sources */,
+				22C91A5F1193400A0083AC69 /* bn_mp_sqr.c in Sources */,
+				22C91A601193400A0083AC69 /* bn_mp_sqrmod.c in Sources */,
+				22C91A611193400A0083AC69 /* bn_mp_sqrt.c in Sources */,
+				22C91A621193400A0083AC69 /* bn_mp_sub_d.c in Sources */,
+				22C91A631193400A0083AC69 /* bn_mp_sub.c in Sources */,
+				22C91A641193400A0083AC69 /* bn_mp_submod.c in Sources */,
+				22C91A651193400A0083AC69 /* bn_mp_to_signed_bin_n.c in Sources */,
+				22C91A661193400A0083AC69 /* bn_mp_to_signed_bin.c in Sources */,
+				22C91A671193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c in Sources */,
+				22C91A681193400A0083AC69 /* bn_mp_to_unsigned_bin.c in Sources */,
+				22C91A691193400A0083AC69 /* bn_mp_toom_mul.c in Sources */,
+				22C91A6A1193400A0083AC69 /* bn_mp_toom_sqr.c in Sources */,
+				22C91A6B1193400A0083AC69 /* bn_mp_toradix_n.c in Sources */,
+				22C91A6C1193400A0083AC69 /* bn_mp_toradix.c in Sources */,
+				22C91A6D1193400A0083AC69 /* bn_mp_unsigned_bin_size.c in Sources */,
+				E60816F31B707B7200B283F7 /* der_encode_ia5_string.c in Sources */,
+				E60816E01B707B5700B283F7 /* der_encode_sequence_ex.c in Sources */,
+				22C91A6E1193400A0083AC69 /* bn_mp_xor.c in Sources */,
+				22C91A6F1193400A0083AC69 /* bn_mp_zero.c in Sources */,
+				22C91A701193400A0083AC69 /* bn_prime_tab.c in Sources */,
+				22C91A711193400A0083AC69 /* bn_reverse.c in Sources */,
+				22C91A721193400A0083AC69 /* bn_s_mp_add.c in Sources */,
+				22C91A731193400A0083AC69 /* bn_s_mp_exptmod.c in Sources */,
+				22C91A741193400A0083AC69 /* bn_s_mp_mul_digs.c in Sources */,
+				22C91A751193400A0083AC69 /* bn_s_mp_mul_high_digs.c in Sources */,
+				22C91A761193400A0083AC69 /* bn_s_mp_sqr.c in Sources */,
+				22C91A771193400A0083AC69 /* bn_s_mp_sub.c in Sources */,
+				22C91A781193400A0083AC69 /* bncore.c in Sources */,
+				22F5A9C61193DFBA00F8B121 /* SFileVerify.cpp in Sources */,
+				228B538411BF7D0D001A58DA /* FileStream.cpp in Sources */,
+				22AEA122123125D800359B16 /* SFilePatchArchives.cpp in Sources */,
+				225C73541257CD0C0009E8DA /* SBaseFileTable.cpp in Sources */,
+				225C735A1257CD1F0009E8DA /* lookup3.c in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		22954ACB11D463A30064B264 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				22954AD211D463AB0064B264 /* Test.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		2229F62F11D4653600118914 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 225530D31056BAC800FA646A /* StormLib */;
+			targetProxy = 2229F62E11D4653600118914 /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+		1DEB916508733D950010E9CD /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				GCC_C_LANGUAGE_STANDARD = c89;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					_7ZIP_ST,
+					_DEBUG,
+				);
+				GCC_VERSION = "";
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = macosx;
+				STRIP_INSTALLED_PRODUCT = NO;
+			};
+			name = Debug;
+		};
+		1DEB916608733D950010E9CD /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				COPY_PHASE_STRIP = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				GCC_C_LANGUAGE_STANDARD = c89;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = _7ZIP_ST;
+				GCC_VERSION = "";
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				SDKROOT = macosx;
+				STRIP_INSTALLED_PRODUCT = YES;
+			};
+			name = Release;
+		};
+		225530D51056BAC900FA646A /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_VERSION = "";
+				INSTALL_PATH = /usr/local/lib;
+				PRODUCT_NAME = StormLib;
+			};
+			name = Debug;
+		};
+		225530D61056BAC900FA646A /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+				GCC_VERSION = "";
+				INSTALL_PATH = /usr/local/lib;
+				PRODUCT_NAME = StormLib;
+			};
+			name = Release;
+		};
+		225FAC960E53B7F900DA2CAE /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COMBINE_HIDPI_IMAGES = YES;
+				EXPORTED_SYMBOLS_FILE = "$(PROJECT_DIR)/stormlib_dll/StormLib.exp";
+				FRAMEWORK_VERSION = A;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				PRODUCT_NAME = StormLib;
+			};
+			name = Debug;
+		};
+		225FAC970E53B7F900DA2CAE /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COMBINE_HIDPI_IMAGES = YES;
+				EXPORTED_SYMBOLS_FILE = "$(PROJECT_DIR)/stormlib_dll/StormLib.exp";
+				FRAMEWORK_VERSION = A;
+				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				PRODUCT_NAME = StormLib;
+			};
+			name = Release;
+		};
+		22954AD011D463A40064B264 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				COPY_PHASE_STRIP = NO;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					_7ZIP_ST,
+					_DEBUG,
+					__STORMLIB_TEST__,
+				);
+				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				INSTALL_PATH = /usr/local/bin;
+				PRODUCT_NAME = StormLib_Test;
+			};
+			name = Debug;
+		};
+		22954AD111D463A40064B264 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				COPY_PHASE_STRIP = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				INSTALL_PATH = /usr/local/bin;
+				PRODUCT_NAME = StormLib_Test;
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		1DEB916408733D950010E9CD /* Build configuration list for PBXProject "StormLib" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				1DEB916508733D950010E9CD /* Debug */,
+				1DEB916608733D950010E9CD /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Debug;
+		};
+		225530D71056BB1600FA646A /* Build configuration list for PBXNativeTarget "StormLib" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				225530D51056BAC900FA646A /* Debug */,
+				225530D61056BAC900FA646A /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Debug;
+		};
+		225FAC980E53B7F900DA2CAE /* Build configuration list for PBXNativeTarget "StormLibFramework" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				225FAC960E53B7F900DA2CAE /* Debug */,
+				225FAC970E53B7F900DA2CAE /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Debug;
+		};
+		22954AD911D463E00064B264 /* Build configuration list for PBXNativeTarget "StormLib_Test" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				22954AD011D463A40064B264 /* Debug */,
+				22954AD111D463A40064B264 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Debug;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
+}
diff --git a/OpenSource/StormLib/StormLib_dll.vcxproj b/OpenSource/StormLib/StormLib_dll.vcxproj
index 856334d39..bf2a23e4d 100644
--- a/OpenSource/StormLib/StormLib_dll.vcxproj
+++ b/OpenSource/StormLib/StormLib_dll.vcxproj
@@ -100,7 +100,7 @@
     </ClCompile>
     <Link>
       <OutputFile>$(ProjectDir)/bin/$(Platform)/$(Configuration)/StormLib$(TargetExt)</OutputFile>
-      <ModuleDefinitionFile>.\StormLib_dll\StormLib.def</ModuleDefinitionFile>
+      <ModuleDefinitionFile>.\src\DllMain.def</ModuleDefinitionFile>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <RandomizedBaseAddress>false</RandomizedBaseAddress>
@@ -123,7 +123,7 @@
     </ClCompile>
     <Link>
       <OutputFile>$(OutDir)StormLib.dll</OutputFile>
-      <ModuleDefinitionFile>.\StormLib_dll\StormLib.def</ModuleDefinitionFile>
+      <ModuleDefinitionFile>.\src\DllMain.def</ModuleDefinitionFile>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <RandomizedBaseAddress>false</RandomizedBaseAddress>
@@ -141,7 +141,7 @@
     </ClCompile>
     <Link>
       <OutputFile>$(ProjectDir)/bin/$(Platform)/$(Configuration)/StormLib$(TargetExt)</OutputFile>
-      <ModuleDefinitionFile>.\StormLib_dll\StormLib.def</ModuleDefinitionFile>
+      <ModuleDefinitionFile>.\src\DllMain.def</ModuleDefinitionFile>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <OptimizeReferences>true</OptimizeReferences>
@@ -164,7 +164,7 @@
     </ClCompile>
     <Link>
       <OutputFile>$(OutDir)StormLib.dll</OutputFile>
-      <ModuleDefinitionFile>.\StormLib_dll\StormLib.def</ModuleDefinitionFile>
+      <ModuleDefinitionFile>.\src\DllMain.def</ModuleDefinitionFile>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <SubSystem>Windows</SubSystem>
       <OptimizeReferences>true</OptimizeReferences>
@@ -190,6 +190,7 @@
     <ClInclude Include="src\jenkins\lookup.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="src\DllMain.c" />
     <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_bit_string.c" />
     <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_boolean.c" />
     <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_ia5_string.c" />
@@ -208,12 +209,6 @@
     <ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_encode.c" />
     <ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_sign_hash.c" />
     <ClCompile Include="src\SBaseSubTypes.cpp" />
-    <ClCompile Include="stormlib_dll\DllMain.c">
-      <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
-      <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
-      <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
-      <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level4</WarningLevel>
-    </ClCompile>
     <ClCompile Include="src\FileStream.cpp">
       <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
       <WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level4</WarningLevel>
diff --git a/OpenSource/StormLib/StormLib_dll.vcxproj.filters b/OpenSource/StormLib/StormLib_dll.vcxproj.filters
index 90c622f0c..acb3a29b6 100644
--- a/OpenSource/StormLib/StormLib_dll.vcxproj.filters
+++ b/OpenSource/StormLib/StormLib_dll.vcxproj.filters
@@ -1,838 +1,836 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Doc Files">
-      <UniqueIdentifier>{85359376-4146-45ff-a6ce-225b3f103198}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{02d49f0b-fc11-4b84-8ca2-0d0df0bc524e}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{c6293ab1-ea8a-42fb-ae3e-85524ad2e68d}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\adpcm">
-      <UniqueIdentifier>{fd9d5cac-d0b6-4204-9160-706a03ec0c69}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\bzip2">
-      <UniqueIdentifier>{7333e6fb-8b95-40b6-bc5e-bdfa7f15b93a}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\huffman">
-      <UniqueIdentifier>{0e473b19-e86f-4180-82b4-3c427117b6c7}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\libtomcrypt">
-      <UniqueIdentifier>{cca0e168-e531-4d83-8a8e-478c2ba39323}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\libtomcrypt\hashes">
-      <UniqueIdentifier>{8b8ae872-b929-4758-ac0d-ccb28436ebb8}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\libtomcrypt\math">
-      <UniqueIdentifier>{c5829ed3-f34a-4cc5-b01d-b4d44ef6a07c}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\libtomcrypt\misc">
-      <UniqueIdentifier>{d10b97e0-dd06-440b-aa78-d7739e762511}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\libtomcrypt\pk">
-      <UniqueIdentifier>{bc743c98-8a6a-4eb4-bb65-2407720090ae}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\libtomcrypt\pk\asn1">
-      <UniqueIdentifier>{f155fafa-653d-4638-a0a4-dc46e5581713}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\libtomcrypt\pk\ecc">
-      <UniqueIdentifier>{7478ca26-875e-4ebf-99d5-7957270bc95f}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\libtomcrypt\pk\pkcs1">
-      <UniqueIdentifier>{4169e85a-6a42-47f5-a69a-34de5a13ca30}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\libtomcrypt\pk\rsa">
-      <UniqueIdentifier>{df7f82be-b039-4b9b-bb1f-a48b2724957a}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\libtommath">
-      <UniqueIdentifier>{3861070d-c4b6-45a8-8a8e-ec7ce7e12d48}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\lzma">
-      <UniqueIdentifier>{b25aeeef-06f4-4b47-a892-42df4354591b}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\pklib">
-      <UniqueIdentifier>{77645fb6-77f6-4623-a67a-bc844d414aa9}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\sparse">
-      <UniqueIdentifier>{e10bf121-3ed4-478c-a0d5-3eb83d0a98c7}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\zlib">
-      <UniqueIdentifier>{abbf0b9a-8227-4cb1-b5f7-76306334c483}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\jenkins">
-      <UniqueIdentifier>{66f88b55-bc43-4c10-838c-b6f27dfc7f4a}</UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <Text Include="doc\History.txt">
-      <Filter>Doc Files</Filter>
-    </Text>
-    <Text Include="doc\The MoPaQ File Format 0.9.txt">
-      <Filter>Doc Files</Filter>
-    </Text>
-    <Text Include="doc\The MoPaQ File Format 1.0.txt">
-      <Filter>Doc Files</Filter>
-    </Text>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="src\StormCommon.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="src\StormLib.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="src\StormPort.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="src\adpcm\adpcm.h">
-      <Filter>Source Files\adpcm</Filter>
-    </ClInclude>
-    <ClInclude Include="src\huffman\huff.h">
-      <Filter>Source Files\huffman</Filter>
-    </ClInclude>
-    <ClInclude Include="src\pklib\pklib.h">
-      <Filter>Source Files\pklib</Filter>
-    </ClInclude>
-    <ClInclude Include="src\sparse\sparse.h">
-      <Filter>Source Files\sparse</Filter>
-    </ClInclude>
-    <ClInclude Include="src\jenkins\lookup.h">
-      <Filter>Source Files\jenkins</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="stormlib_dll\DllMain.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\FileStream.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\SBaseCommon.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\SBaseFileTable.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\SCompression.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\SFileAddFile.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\SFileAttributes.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\SFileCompactArchive.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\SFileCreateArchive.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\SFileExtractFile.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\SFileFindFile.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\SFileGetFileInfo.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\SFileListFile.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\SFileOpenArchive.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\SFileOpenFileEx.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\SFilePatchArchives.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\SFileReadFile.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\SFileVerify.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\adpcm\adpcm.cpp">
-      <Filter>Source Files\adpcm</Filter>
-    </ClCompile>
-    <ClCompile Include="src\bzip2\blocksort.c">
-      <Filter>Source Files\bzip2</Filter>
-    </ClCompile>
-    <ClCompile Include="src\bzip2\bzlib.c">
-      <Filter>Source Files\bzip2</Filter>
-    </ClCompile>
-    <ClCompile Include="src\bzip2\compress.c">
-      <Filter>Source Files\bzip2</Filter>
-    </ClCompile>
-    <ClCompile Include="src\bzip2\crctable.c">
-      <Filter>Source Files\bzip2</Filter>
-    </ClCompile>
-    <ClCompile Include="src\bzip2\decompress.c">
-      <Filter>Source Files\bzip2</Filter>
-    </ClCompile>
-    <ClCompile Include="src\bzip2\huffman.c">
-      <Filter>Source Files\bzip2</Filter>
-    </ClCompile>
-    <ClCompile Include="src\bzip2\randtable.c">
-      <Filter>Source Files\bzip2</Filter>
-    </ClCompile>
-    <ClCompile Include="src\huffman\huff.cpp">
-      <Filter>Source Files\huffman</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\hashes\hash_memory.c">
-      <Filter>Source Files\libtomcrypt\hashes</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\hashes\md5.c">
-      <Filter>Source Files\libtomcrypt\hashes</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\hashes\sha1.c">
-      <Filter>Source Files\libtomcrypt\hashes</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\math\ltm_desc.c">
-      <Filter>Source Files\libtomcrypt\math</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\math\multi.c">
-      <Filter>Source Files\libtomcrypt\math</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\math\rand_prime.c">
-      <Filter>Source Files\libtomcrypt\math</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\misc\base64_decode.c">
-      <Filter>Source Files\libtomcrypt\misc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\misc\crypt_argchk.c">
-      <Filter>Source Files\libtomcrypt\misc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\misc\crypt_find_hash.c">
-      <Filter>Source Files\libtomcrypt\misc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\misc\crypt_find_prng.c">
-      <Filter>Source Files\libtomcrypt\misc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\misc\crypt_hash_descriptor.c">
-      <Filter>Source Files\libtomcrypt\misc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\misc\crypt_hash_is_valid.c">
-      <Filter>Source Files\libtomcrypt\misc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\misc\crypt_libc.c">
-      <Filter>Source Files\libtomcrypt\misc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\misc\crypt_ltc_mp_descriptor.c">
-      <Filter>Source Files\libtomcrypt\misc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\misc\crypt_prng_descriptor.c">
-      <Filter>Source Files\libtomcrypt\misc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\misc\crypt_prng_is_valid.c">
-      <Filter>Source Files\libtomcrypt\misc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\misc\crypt_register_hash.c">
-      <Filter>Source Files\libtomcrypt\misc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\misc\crypt_register_prng.c">
-      <Filter>Source Files\libtomcrypt\misc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\misc\zeromem.c">
-      <Filter>Source Files\libtomcrypt\misc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_bit_string.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_boolean.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_choice.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_ia5_string.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_integer.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_object_identifier.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_octet_string.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_printable_string.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_ex.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_flexi.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_multi.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_short_integer.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_utctime.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_utf8_string.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_bit_string.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_boolean.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_ia5_string.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_integer.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_object_identifier.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_octet_string.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_printable_string.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_sequence.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_short_integer.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_utctime.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_utf8_string.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_sequence_free.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_map.c">
-      <Filter>Source Files\libtomcrypt\pk\ecc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_mul2add.c">
-      <Filter>Source Files\libtomcrypt\pk\ecc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_mulmod.c">
-      <Filter>Source Files\libtomcrypt\pk\ecc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_points.c">
-      <Filter>Source Files\libtomcrypt\pk\ecc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_add_point.c">
-      <Filter>Source Files\libtomcrypt\pk\ecc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_dbl_point.c">
-      <Filter>Source Files\libtomcrypt\pk\ecc</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_mgf1.c">
-      <Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_oaep_decode.c">
-      <Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_decode.c">
-      <Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_decode.c">
-      <Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_exptmod.c">
-      <Filter>Source Files\libtomcrypt\pk\rsa</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_free.c">
-      <Filter>Source Files\libtomcrypt\pk\rsa</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_import.c">
-      <Filter>Source Files\libtomcrypt\pk\rsa</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_make_key.c">
-      <Filter>Source Files\libtomcrypt\pk\rsa</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_verify_hash.c">
-      <Filter>Source Files\libtomcrypt\pk\rsa</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_verify_simple.c">
-      <Filter>Source Files\libtomcrypt\pk\rsa</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_fast_mp_invmod.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_fast_mp_montgomery_reduce.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_fast_s_mp_mul_digs.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_fast_s_mp_mul_high_digs.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_fast_s_mp_sqr.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_2expt.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_abs.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_add.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_add_d.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_addmod.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_and.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_clamp.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_clear.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_clear_multi.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_cmp.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_cmp_d.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_cmp_mag.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_cnt_lsb.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_copy.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_count_bits.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_div.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_div_2.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_div_2d.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_div_3.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_div_d.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_dr_is_modulus.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_dr_reduce.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_dr_setup.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_exch.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_expt_d.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_exptmod.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_exptmod_fast.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_exteuclid.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_fread.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_fwrite.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_gcd.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_get_int.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_grow.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_init.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_init_copy.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_init_multi.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_init_set.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_init_set_int.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_init_size.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_invmod.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_invmod_slow.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_is_square.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_jacobi.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_karatsuba_mul.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_karatsuba_sqr.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_lcm.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_lshd.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_mod.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_mod_2d.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_mod_d.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_montgomery_calc_normalization.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_montgomery_reduce.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_montgomery_setup.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_mul.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_mul_2.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_mul_2d.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_mul_d.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_mulmod.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_n_root.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_neg.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_or.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_prime_fermat.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_prime_is_divisible.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_prime_is_prime.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_prime_miller_rabin.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_prime_next_prime.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_prime_rabin_miller_trials.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_prime_random_ex.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_radix_size.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_radix_smap.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_rand.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_read_radix.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_read_signed_bin.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_read_unsigned_bin.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_reduce.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_reduce_2k.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_reduce_2k_l.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_reduce_2k_setup.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_reduce_2k_setup_l.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_reduce_is_2k.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_reduce_is_2k_l.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_reduce_setup.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_rshd.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_set.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_set_int.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_shrink.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_signed_bin_size.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_sqr.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_sqrmod.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_sqrt.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_sub.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_sub_d.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_submod.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_to_signed_bin.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_to_signed_bin_n.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_to_unsigned_bin.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_to_unsigned_bin_n.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_toom_mul.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_toom_sqr.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_toradix.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_toradix_n.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_unsigned_bin_size.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_xor.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_mp_zero.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_prime_tab.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_reverse.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_s_mp_add.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_s_mp_exptmod.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_s_mp_mul_digs.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_s_mp_mul_high_digs.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_s_mp_sqr.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bn_s_mp_sub.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtommath\bncore.c">
-      <Filter>Source Files\libtommath</Filter>
-    </ClCompile>
-    <ClCompile Include="src\lzma\C\LzFind.c">
-      <Filter>Source Files\lzma</Filter>
-    </ClCompile>
-    <ClCompile Include="src\lzma\C\LzFindMt.c">
-      <Filter>Source Files\lzma</Filter>
-    </ClCompile>
-    <ClCompile Include="src\lzma\C\LzmaDec.c">
-      <Filter>Source Files\lzma</Filter>
-    </ClCompile>
-    <ClCompile Include="src\lzma\C\LzmaEnc.c">
-      <Filter>Source Files\lzma</Filter>
-    </ClCompile>
-    <ClCompile Include="src\lzma\C\Threads.c">
-      <Filter>Source Files\lzma</Filter>
-    </ClCompile>
-    <ClCompile Include="src\pklib\explode.c">
-      <Filter>Source Files\pklib</Filter>
-    </ClCompile>
-    <ClCompile Include="src\pklib\implode.c">
-      <Filter>Source Files\pklib</Filter>
-    </ClCompile>
-    <ClCompile Include="src\sparse\sparse.cpp">
-      <Filter>Source Files\sparse</Filter>
-    </ClCompile>
-    <ClCompile Include="src\zlib\adler32.c">
-      <Filter>Source Files\zlib</Filter>
-    </ClCompile>
-    <ClCompile Include="src\zlib\crc32.c">
-      <Filter>Source Files\zlib</Filter>
-    </ClCompile>
-    <ClCompile Include="src\zlib\deflate.c">
-      <Filter>Source Files\zlib</Filter>
-    </ClCompile>
-    <ClCompile Include="src\zlib\inffast.c">
-      <Filter>Source Files\zlib</Filter>
-    </ClCompile>
-    <ClCompile Include="src\zlib\inflate.c">
-      <Filter>Source Files\zlib</Filter>
-    </ClCompile>
-    <ClCompile Include="src\zlib\inftrees.c">
-      <Filter>Source Files\zlib</Filter>
-    </ClCompile>
-    <ClCompile Include="src\zlib\trees.c">
-      <Filter>Source Files\zlib</Filter>
-    </ClCompile>
-    <ClCompile Include="src\zlib\zutil.c">
-      <Filter>Source Files\zlib</Filter>
-    </ClCompile>
-    <ClCompile Include="src\jenkins\lookup3.c">
-      <Filter>Source Files\jenkins</Filter>
-    </ClCompile>
-    <ClCompile Include="src\zlib\compress_zlib.c">
-      <Filter>Source Files\zlib</Filter>
-    </ClCompile>
-    <ClCompile Include="src\SBaseSubTypes.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_sign_hash.c">
-      <Filter>Source Files\libtomcrypt\pk\rsa</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_encode.c">
-      <Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_encode.c">
-      <Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_bit_string.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_boolean.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_ia5_string.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_integer.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_object_identifier.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_octet_string.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_printable_string.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_sequence_ex.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_sequence_multi.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_set.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_setof.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_short_integer.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_utctime.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_utf8_string.c">
-      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="stormlib_dll\StormLib.def">
-      <Filter>Source Files</Filter>
-    </None>
-  </ItemGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Doc Files">
+      <UniqueIdentifier>{85359376-4146-45ff-a6ce-225b3f103198}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{02d49f0b-fc11-4b84-8ca2-0d0df0bc524e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{c6293ab1-ea8a-42fb-ae3e-85524ad2e68d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\adpcm">
+      <UniqueIdentifier>{fd9d5cac-d0b6-4204-9160-706a03ec0c69}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\bzip2">
+      <UniqueIdentifier>{7333e6fb-8b95-40b6-bc5e-bdfa7f15b93a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\huffman">
+      <UniqueIdentifier>{0e473b19-e86f-4180-82b4-3c427117b6c7}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\libtomcrypt">
+      <UniqueIdentifier>{cca0e168-e531-4d83-8a8e-478c2ba39323}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\libtomcrypt\hashes">
+      <UniqueIdentifier>{8b8ae872-b929-4758-ac0d-ccb28436ebb8}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\libtomcrypt\math">
+      <UniqueIdentifier>{c5829ed3-f34a-4cc5-b01d-b4d44ef6a07c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\libtomcrypt\misc">
+      <UniqueIdentifier>{d10b97e0-dd06-440b-aa78-d7739e762511}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\libtomcrypt\pk">
+      <UniqueIdentifier>{bc743c98-8a6a-4eb4-bb65-2407720090ae}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\libtomcrypt\pk\asn1">
+      <UniqueIdentifier>{f155fafa-653d-4638-a0a4-dc46e5581713}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\libtomcrypt\pk\ecc">
+      <UniqueIdentifier>{7478ca26-875e-4ebf-99d5-7957270bc95f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\libtomcrypt\pk\pkcs1">
+      <UniqueIdentifier>{4169e85a-6a42-47f5-a69a-34de5a13ca30}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\libtomcrypt\pk\rsa">
+      <UniqueIdentifier>{df7f82be-b039-4b9b-bb1f-a48b2724957a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\libtommath">
+      <UniqueIdentifier>{3861070d-c4b6-45a8-8a8e-ec7ce7e12d48}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\lzma">
+      <UniqueIdentifier>{b25aeeef-06f4-4b47-a892-42df4354591b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\pklib">
+      <UniqueIdentifier>{77645fb6-77f6-4623-a67a-bc844d414aa9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\sparse">
+      <UniqueIdentifier>{e10bf121-3ed4-478c-a0d5-3eb83d0a98c7}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\zlib">
+      <UniqueIdentifier>{abbf0b9a-8227-4cb1-b5f7-76306334c483}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\jenkins">
+      <UniqueIdentifier>{66f88b55-bc43-4c10-838c-b6f27dfc7f4a}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="doc\History.txt">
+      <Filter>Doc Files</Filter>
+    </Text>
+    <Text Include="doc\The MoPaQ File Format 0.9.txt">
+      <Filter>Doc Files</Filter>
+    </Text>
+    <Text Include="doc\The MoPaQ File Format 1.0.txt">
+      <Filter>Doc Files</Filter>
+    </Text>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="src\StormCommon.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="src\StormLib.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="src\StormPort.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="src\adpcm\adpcm.h">
+      <Filter>Source Files\adpcm</Filter>
+    </ClInclude>
+    <ClInclude Include="src\huffman\huff.h">
+      <Filter>Source Files\huffman</Filter>
+    </ClInclude>
+    <ClInclude Include="src\pklib\pklib.h">
+      <Filter>Source Files\pklib</Filter>
+    </ClInclude>
+    <ClInclude Include="src\sparse\sparse.h">
+      <Filter>Source Files\sparse</Filter>
+    </ClInclude>
+    <ClInclude Include="src\jenkins\lookup.h">
+      <Filter>Source Files\jenkins</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\FileStream.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SBaseCommon.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SBaseFileTable.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SCompression.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SFileAddFile.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SFileAttributes.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SFileCompactArchive.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SFileCreateArchive.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SFileExtractFile.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SFileFindFile.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SFileGetFileInfo.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SFileListFile.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SFileOpenArchive.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SFileOpenFileEx.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SFilePatchArchives.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SFileReadFile.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SFileVerify.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\adpcm\adpcm.cpp">
+      <Filter>Source Files\adpcm</Filter>
+    </ClCompile>
+    <ClCompile Include="src\bzip2\blocksort.c">
+      <Filter>Source Files\bzip2</Filter>
+    </ClCompile>
+    <ClCompile Include="src\bzip2\bzlib.c">
+      <Filter>Source Files\bzip2</Filter>
+    </ClCompile>
+    <ClCompile Include="src\bzip2\compress.c">
+      <Filter>Source Files\bzip2</Filter>
+    </ClCompile>
+    <ClCompile Include="src\bzip2\crctable.c">
+      <Filter>Source Files\bzip2</Filter>
+    </ClCompile>
+    <ClCompile Include="src\bzip2\decompress.c">
+      <Filter>Source Files\bzip2</Filter>
+    </ClCompile>
+    <ClCompile Include="src\bzip2\huffman.c">
+      <Filter>Source Files\bzip2</Filter>
+    </ClCompile>
+    <ClCompile Include="src\bzip2\randtable.c">
+      <Filter>Source Files\bzip2</Filter>
+    </ClCompile>
+    <ClCompile Include="src\huffman\huff.cpp">
+      <Filter>Source Files\huffman</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\hashes\hash_memory.c">
+      <Filter>Source Files\libtomcrypt\hashes</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\hashes\md5.c">
+      <Filter>Source Files\libtomcrypt\hashes</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\hashes\sha1.c">
+      <Filter>Source Files\libtomcrypt\hashes</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\math\ltm_desc.c">
+      <Filter>Source Files\libtomcrypt\math</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\math\multi.c">
+      <Filter>Source Files\libtomcrypt\math</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\math\rand_prime.c">
+      <Filter>Source Files\libtomcrypt\math</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\misc\base64_decode.c">
+      <Filter>Source Files\libtomcrypt\misc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\misc\crypt_argchk.c">
+      <Filter>Source Files\libtomcrypt\misc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\misc\crypt_find_hash.c">
+      <Filter>Source Files\libtomcrypt\misc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\misc\crypt_find_prng.c">
+      <Filter>Source Files\libtomcrypt\misc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\misc\crypt_hash_descriptor.c">
+      <Filter>Source Files\libtomcrypt\misc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\misc\crypt_hash_is_valid.c">
+      <Filter>Source Files\libtomcrypt\misc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\misc\crypt_libc.c">
+      <Filter>Source Files\libtomcrypt\misc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\misc\crypt_ltc_mp_descriptor.c">
+      <Filter>Source Files\libtomcrypt\misc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\misc\crypt_prng_descriptor.c">
+      <Filter>Source Files\libtomcrypt\misc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\misc\crypt_prng_is_valid.c">
+      <Filter>Source Files\libtomcrypt\misc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\misc\crypt_register_hash.c">
+      <Filter>Source Files\libtomcrypt\misc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\misc\crypt_register_prng.c">
+      <Filter>Source Files\libtomcrypt\misc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\misc\zeromem.c">
+      <Filter>Source Files\libtomcrypt\misc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_bit_string.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_boolean.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_choice.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_ia5_string.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_integer.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_object_identifier.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_octet_string.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_printable_string.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_ex.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_flexi.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_sequence_multi.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_short_integer.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_utctime.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_decode_utf8_string.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_bit_string.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_boolean.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_ia5_string.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_integer.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_object_identifier.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_octet_string.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_printable_string.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_sequence.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_short_integer.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_utctime.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_length_utf8_string.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_sequence_free.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_map.c">
+      <Filter>Source Files\libtomcrypt\pk\ecc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_mul2add.c">
+      <Filter>Source Files\libtomcrypt\pk\ecc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_mulmod.c">
+      <Filter>Source Files\libtomcrypt\pk\ecc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_points.c">
+      <Filter>Source Files\libtomcrypt\pk\ecc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_add_point.c">
+      <Filter>Source Files\libtomcrypt\pk\ecc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_dbl_point.c">
+      <Filter>Source Files\libtomcrypt\pk\ecc</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_mgf1.c">
+      <Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_oaep_decode.c">
+      <Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_decode.c">
+      <Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_decode.c">
+      <Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_exptmod.c">
+      <Filter>Source Files\libtomcrypt\pk\rsa</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_free.c">
+      <Filter>Source Files\libtomcrypt\pk\rsa</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_import.c">
+      <Filter>Source Files\libtomcrypt\pk\rsa</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_make_key.c">
+      <Filter>Source Files\libtomcrypt\pk\rsa</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_verify_hash.c">
+      <Filter>Source Files\libtomcrypt\pk\rsa</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_verify_simple.c">
+      <Filter>Source Files\libtomcrypt\pk\rsa</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_fast_mp_invmod.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_fast_mp_montgomery_reduce.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_fast_s_mp_mul_digs.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_fast_s_mp_mul_high_digs.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_fast_s_mp_sqr.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_2expt.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_abs.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_add.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_add_d.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_addmod.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_and.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_clamp.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_clear.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_clear_multi.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_cmp.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_cmp_d.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_cmp_mag.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_cnt_lsb.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_copy.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_count_bits.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_div.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_div_2.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_div_2d.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_div_3.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_div_d.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_dr_is_modulus.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_dr_reduce.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_dr_setup.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_exch.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_expt_d.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_exptmod.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_exptmod_fast.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_exteuclid.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_fread.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_fwrite.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_gcd.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_get_int.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_grow.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_init.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_init_copy.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_init_multi.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_init_set.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_init_set_int.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_init_size.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_invmod.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_invmod_slow.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_is_square.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_jacobi.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_karatsuba_mul.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_karatsuba_sqr.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_lcm.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_lshd.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_mod.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_mod_2d.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_mod_d.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_montgomery_calc_normalization.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_montgomery_reduce.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_montgomery_setup.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_mul.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_mul_2.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_mul_2d.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_mul_d.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_mulmod.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_n_root.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_neg.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_or.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_prime_fermat.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_prime_is_divisible.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_prime_is_prime.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_prime_miller_rabin.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_prime_next_prime.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_prime_rabin_miller_trials.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_prime_random_ex.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_radix_size.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_radix_smap.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_rand.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_read_radix.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_read_signed_bin.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_read_unsigned_bin.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_reduce.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_reduce_2k.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_reduce_2k_l.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_reduce_2k_setup.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_reduce_2k_setup_l.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_reduce_is_2k.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_reduce_is_2k_l.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_reduce_setup.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_rshd.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_set.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_set_int.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_shrink.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_signed_bin_size.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_sqr.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_sqrmod.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_sqrt.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_sub.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_sub_d.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_submod.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_to_signed_bin.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_to_signed_bin_n.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_to_unsigned_bin.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_to_unsigned_bin_n.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_toom_mul.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_toom_sqr.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_toradix.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_toradix_n.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_unsigned_bin_size.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_xor.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_mp_zero.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_prime_tab.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_reverse.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_s_mp_add.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_s_mp_exptmod.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_s_mp_mul_digs.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_s_mp_mul_high_digs.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_s_mp_sqr.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bn_s_mp_sub.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtommath\bncore.c">
+      <Filter>Source Files\libtommath</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lzma\C\LzFind.c">
+      <Filter>Source Files\lzma</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lzma\C\LzFindMt.c">
+      <Filter>Source Files\lzma</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lzma\C\LzmaDec.c">
+      <Filter>Source Files\lzma</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lzma\C\LzmaEnc.c">
+      <Filter>Source Files\lzma</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lzma\C\Threads.c">
+      <Filter>Source Files\lzma</Filter>
+    </ClCompile>
+    <ClCompile Include="src\pklib\explode.c">
+      <Filter>Source Files\pklib</Filter>
+    </ClCompile>
+    <ClCompile Include="src\pklib\implode.c">
+      <Filter>Source Files\pklib</Filter>
+    </ClCompile>
+    <ClCompile Include="src\sparse\sparse.cpp">
+      <Filter>Source Files\sparse</Filter>
+    </ClCompile>
+    <ClCompile Include="src\zlib\adler32.c">
+      <Filter>Source Files\zlib</Filter>
+    </ClCompile>
+    <ClCompile Include="src\zlib\crc32.c">
+      <Filter>Source Files\zlib</Filter>
+    </ClCompile>
+    <ClCompile Include="src\zlib\deflate.c">
+      <Filter>Source Files\zlib</Filter>
+    </ClCompile>
+    <ClCompile Include="src\zlib\inffast.c">
+      <Filter>Source Files\zlib</Filter>
+    </ClCompile>
+    <ClCompile Include="src\zlib\inflate.c">
+      <Filter>Source Files\zlib</Filter>
+    </ClCompile>
+    <ClCompile Include="src\zlib\inftrees.c">
+      <Filter>Source Files\zlib</Filter>
+    </ClCompile>
+    <ClCompile Include="src\zlib\trees.c">
+      <Filter>Source Files\zlib</Filter>
+    </ClCompile>
+    <ClCompile Include="src\zlib\zutil.c">
+      <Filter>Source Files\zlib</Filter>
+    </ClCompile>
+    <ClCompile Include="src\jenkins\lookup3.c">
+      <Filter>Source Files\jenkins</Filter>
+    </ClCompile>
+    <ClCompile Include="src\zlib\compress_zlib.c">
+      <Filter>Source Files\zlib</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SBaseSubTypes.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\rsa\rsa_sign_hash.c">
+      <Filter>Source Files\libtomcrypt\pk\rsa</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_encode.c">
+      <Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_encode.c">
+      <Filter>Source Files\libtomcrypt\pk\pkcs1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_bit_string.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_boolean.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_ia5_string.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_integer.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_object_identifier.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_octet_string.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_printable_string.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_sequence_ex.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_sequence_multi.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_set.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_setof.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_short_integer.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_utctime.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\libtomcrypt\src\pk\asn1\der_encode_utf8_string.c">
+      <Filter>Source Files\libtomcrypt\pk\asn1</Filter>
+    </ClCompile>
+    <ClCompile Include="src\DllMain.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="stormlib_dll\StormLib.def">
+      <Filter>Source Files</Filter>
+    </None>
+  </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/OpenSource/StormLib/stormlib_dll/DllMain.c b/OpenSource/StormLib/src/DllMain.c
similarity index 100%
rename from OpenSource/StormLib/stormlib_dll/DllMain.c
rename to OpenSource/StormLib/src/DllMain.c
diff --git a/OpenSource/StormLib/stormlib_dll/StormLib.def b/OpenSource/StormLib/src/DllMain.def
similarity index 91%
rename from OpenSource/StormLib/stormlib_dll/StormLib.def
rename to OpenSource/StormLib/src/DllMain.def
index 5155d340d..bce2877a3 100644
--- a/OpenSource/StormLib/stormlib_dll/StormLib.def
+++ b/OpenSource/StormLib/src/DllMain.def
@@ -13,7 +13,7 @@ EXPORTS
 
     SFileOpenArchive
     SFileCreateArchive
-	SFileCreateArchive2
+    SFileCreateArchive2
     SFileFlushArchive
     SFileCloseArchive
 
@@ -21,23 +21,23 @@ EXPORTS
 
     SFileSetCompactCallback
     SFileCompactArchive
-    
+
     SFileGetMaxFileCount
-    SFileSetMaxFileCount    
-    
+    SFileSetMaxFileCount
+
     SFileGetAttributes
     SFileSetAttributes
     SFileUpdateFileAttributes
 
     SFileOpenPatchArchive
     SFileIsPatchedArchive
-    
+
     SFileOpenFileEx
     SFileGetFileSize
     SFileSetFilePointer
     SFileReadFile
     SFileCloseFile
-    
+
     SFileHasFile
     SFileGetFileName
     SFileGetFileInfo
@@ -57,7 +57,7 @@ EXPORTS
     SListFileFindClose
 
     SFileEnumLocales
-    
+
     SFileCreateFile
     SFileWriteFile
     SFileFinishFile
@@ -72,8 +72,8 @@ EXPORTS
 
     SCompImplode
     SCompExplode
-    SCompCompress   
-    SCompDecompress 
+    SCompCompress
+    SCompDecompress
 
     GetLastError=Kernel32.GetLastError
     SetLastError=Kernel32.SetLastError
diff --git a/OpenSource/StormLib/src/DllMain.rc b/OpenSource/StormLib/src/DllMain.rc
new file mode 100644
index 000000000..27f43e252
--- /dev/null
+++ b/OpenSource/StormLib/src/DllMain.rc
@@ -0,0 +1,114 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+#pragma code_page(1250)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 9,22,0,3
+ PRODUCTVERSION 9,22,0,3
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x0L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040504b0"
+        BEGIN
+            VALUE "Comments", "http://www.zezula.net/mpq.html"
+            VALUE "FileDescription", "StormLib library for reading Blizzard MPQ archives"
+            VALUE "FileVersion", "9, 22, 0, 3\0"
+            VALUE "InternalName", "StormLib"
+            VALUE "LegalCopyright", "Copyright (c) 2014 - 2020 Ladislav Zezula"
+            VALUE "OriginalFilename", "StormLib.dll"
+            VALUE "ProductName", "StormLib"
+            VALUE "ProductVersion", "9, 22, 0, 3\0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x405, 1200
+    END
+END
+
+#endif    // Neutral resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Czech resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY)
+#ifdef _WIN32
+LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
+#pragma code_page(1250)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+2 TEXTINCLUDE
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+1 TEXTINCLUDE
+BEGIN
+    "resource.h\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+#endif    // Czech resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
diff --git a/OpenSource/StormLib/src/FileStream.cpp b/OpenSource/StormLib/src/FileStream.cpp
index 74635c389..a9679a13c 100644
--- a/OpenSource/StormLib/src/FileStream.cpp
+++ b/OpenSource/StormLib/src/FileStream.cpp
@@ -33,7 +33,7 @@
 //-----------------------------------------------------------------------------
 // Local functions - platform-specific functions
 
-#ifndef PLATFORM_WINDOWS
+#ifndef STORMLIB_WINDOWS
 static DWORD nLastError = ERROR_SUCCESS;
 
 DWORD GetLastError()
@@ -41,9 +41,9 @@ DWORD GetLastError()
     return nLastError;
 }
 
-void SetLastError(DWORD nError)
+void SetLastError(DWORD dwErrCode)
 {
-    nLastError = nError;
+    nLastError = dwErrCode;
 }
 #endif
 
@@ -53,13 +53,29 @@ static DWORD StringToInt(const char * szString)
 
     while('0' <= szString[0] && szString[0] <= '9')
     {
-        dwValue = (dwValue * 10) + (szString[0] - '9');
+        dwValue = (dwValue * 10) + (szString[0] - '0');
         szString++;
     }
 
     return dwValue;
 }
 
+static void CreateNameWithSuffix(LPTSTR szBuffer, size_t cchMaxChars, LPCTSTR szName, unsigned int nValue)
+{
+    LPTSTR szBufferEnd = szBuffer + cchMaxChars - 1;
+
+    // Copy the name
+    while(szBuffer < szBufferEnd && szName[0] != 0)
+        *szBuffer++ = *szName++;
+
+    // Append "."
+    if(szBuffer < szBufferEnd)
+        *szBuffer++ = '.';
+
+    // Append the number
+    IntToString(szBuffer, szBufferEnd - szBuffer + 1, nValue);
+}
+
 //-----------------------------------------------------------------------------
 // Dummy init function
 
@@ -73,7 +89,7 @@ static void BaseNone_Init(TFileStream *)
 
 static bool BaseFile_Create(TFileStream * pStream)
 {
-#ifdef PLATFORM_WINDOWS
+#ifdef STORMLIB_WINDOWS
     {
         DWORD dwWriteShare = (pStream->dwFlags & STREAM_FLAG_WRITE_SHARE) ? FILE_SHARE_WRITE : 0;
 
@@ -89,17 +105,17 @@ static bool BaseFile_Create(TFileStream * pStream)
     }
 #endif
 
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+#if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX) || defined(STORMLIB_HAIKU)
     {
         intptr_t handle;
-        
+
         handle = open(pStream->szFileName, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
         if(handle == -1)
         {
             nLastError = errno;
             return false;
         }
-        
+
         pStream->Base.File.hFile = (HANDLE)handle;
     }
 #endif
@@ -112,7 +128,7 @@ static bool BaseFile_Create(TFileStream * pStream)
 
 static bool BaseFile_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD dwStreamFlags)
 {
-#ifdef PLATFORM_WINDOWS
+#ifdef STORMLIB_WINDOWS
     {
         ULARGE_INTEGER FileSize;
         DWORD dwWriteAccess = (dwStreamFlags & STREAM_FLAG_READ_ONLY) ? 0 : FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES;
@@ -138,7 +154,7 @@ static bool BaseFile_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD
     }
 #endif
 
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+#if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX) || defined(STORMLIB_HAIKU)
     {
         struct stat64 fileinfo;
         int oflag = (dwStreamFlags & STREAM_FLAG_READ_ONLY) ? O_RDONLY : O_RDWR;
@@ -183,7 +199,7 @@ static bool BaseFile_Read(
     ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos;
     DWORD dwBytesRead = 0;                  // Must be set by platform-specific code
 
-#ifdef PLATFORM_WINDOWS
+#ifdef STORMLIB_WINDOWS
     {
         // Note: StormLib no longer supports Windows 9x.
         // Thus, we can use the OVERLAPPED structure to specify
@@ -207,7 +223,7 @@ static bool BaseFile_Read(
     }
 #endif
 
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+#if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX) || defined(STORMLIB_HAIKU)
     {
         ssize_t bytes_read;
 
@@ -228,7 +244,7 @@ static bool BaseFile_Read(
                 nLastError = errno;
                 return false;
             }
-            
+
             dwBytesRead = (DWORD)(size_t)bytes_read;
         }
     }
@@ -254,7 +270,7 @@ static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const
     ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos;
     DWORD dwBytesWritten = 0;               // Must be set by platform-specific code
 
-#ifdef PLATFORM_WINDOWS
+#ifdef STORMLIB_WINDOWS
     {
         // Note: StormLib no longer supports Windows 9x.
         // Thus, we can use the OVERLAPPED structure to specify
@@ -278,7 +294,7 @@ static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const
     }
 #endif
 
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+#if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX) || defined(STORMLIB_HAIKU)
     {
         ssize_t bytes_written;
 
@@ -297,7 +313,7 @@ static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const
             nLastError = errno;
             return false;
         }
-        
+
         dwBytesWritten = (DWORD)(size_t)bytes_written;
     }
 #endif
@@ -320,7 +336,7 @@ static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const
  */
 static bool BaseFile_Resize(TFileStream * pStream, ULONGLONG NewFileSize)
 {
-#ifdef PLATFORM_WINDOWS
+#ifdef STORMLIB_WINDOWS
     {
         LONG FileSizeHi = (LONG)(NewFileSize >> 32);
         LONG FileSizeLo;
@@ -344,15 +360,15 @@ static bool BaseFile_Resize(TFileStream * pStream, ULONGLONG NewFileSize)
         return bResult;
     }
 #endif
-    
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+
+#if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX) || defined(STORMLIB_HAIKU)
     {
         if(ftruncate64((intptr_t)pStream->Base.File.hFile, (off64_t)NewFileSize) == -1)
         {
             nLastError = errno;
             return false;
         }
-        
+
         pStream->Base.File.FileSize = NewFileSize;
         return true;
     }
@@ -380,7 +396,7 @@ static bool BaseFile_GetPos(TFileStream * pStream, ULONGLONG * pByteOffset)
 // Renames the file pointed by pStream so that it contains data from pNewStream
 static bool BaseFile_Replace(TFileStream * pStream, TFileStream * pNewStream)
 {
-#ifdef PLATFORM_WINDOWS
+#ifdef STORMLIB_WINDOWS
     // Delete the original stream file. Don't check the result value,
     // because if the file doesn't exist, it would fail
     DeleteFile(pStream->szFileName);
@@ -389,14 +405,14 @@ static bool BaseFile_Replace(TFileStream * pStream, TFileStream * pNewStream)
     return (bool)MoveFile(pNewStream->szFileName, pStream->szFileName);
 #endif
 
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+#if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX) || defined(STORMLIB_HAIKU)
     // "rename" on Linux also works if the target file exists
     if(rename(pNewStream->szFileName, pStream->szFileName) == -1)
     {
         nLastError = errno;
         return false;
     }
-    
+
     return true;
 #endif
 }
@@ -405,11 +421,11 @@ static void BaseFile_Close(TFileStream * pStream)
 {
     if(pStream->Base.File.hFile != INVALID_HANDLE_VALUE)
     {
-#ifdef PLATFORM_WINDOWS
+#ifdef STORMLIB_WINDOWS
         CloseHandle(pStream->Base.File.hFile);
 #endif
 
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+#if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX) || defined(STORMLIB_HAIKU)
         close((intptr_t)pStream->Base.File.hFile);
 #endif
     }
@@ -434,61 +450,121 @@ static void BaseFile_Init(TFileStream * pStream)
 //-----------------------------------------------------------------------------
 // Local functions - base memory-mapped file support
 
-static bool BaseMap_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD dwStreamFlags)
+#ifdef STORMLIB_WINDOWS
+
+typedef struct _SECTION_BASIC_INFORMATION
 {
-#ifdef PLATFORM_WINDOWS
+    PVOID BaseAddress;
+    ULONG Attributes;
+    LARGE_INTEGER Size;
+} SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION;
 
-    ULARGE_INTEGER FileSize;
-    HANDLE hFile;
-    HANDLE hMap;
+typedef ULONG (WINAPI * NTQUERYSECTION)(
+    IN  HANDLE SectionHandle,
+    IN  ULONG SectionInformationClass,
+    OUT PVOID SectionInformation,
+    IN  SIZE_T Length,
+    OUT PSIZE_T ResultLength);
+
+static bool RetrieveFileMappingSize(HANDLE hSection, ULARGE_INTEGER & RefFileSize)
+{
+    SECTION_BASIC_INFORMATION BasicInfo = {0};
+    NTQUERYSECTION PfnQuerySection;
+    HMODULE hNtdll;
+    SIZE_T ReturnLength = 0;
+
+    if((hNtdll = GetModuleHandle(_T("ntdll.dll"))) != NULL)
+    {
+        PfnQuerySection = (NTQUERYSECTION)GetProcAddress(hNtdll, "NtQuerySection");
+        if(PfnQuerySection != NULL)
+        {
+            if(PfnQuerySection(hSection, 0, &BasicInfo, sizeof(SECTION_BASIC_INFORMATION), &ReturnLength) == 0)
+            {
+                RefFileSize.HighPart = BasicInfo.Size.HighPart;
+                RefFileSize.LowPart = BasicInfo.Size.LowPart;
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+#endif
+
+static bool BaseMap_Open(TFileStream * pStream, LPCTSTR szFileName, DWORD dwStreamFlags)
+{
+#ifdef STORMLIB_WINDOWS
+
+    ULARGE_INTEGER FileSize = {0};
+    HANDLE hFile = INVALID_HANDLE_VALUE;
+    HANDLE hMap = NULL;
     bool bResult = false;
 
     // Keep compiler happy
     dwStreamFlags = dwStreamFlags;
 
-    // Open the file for read access
-    hFile = CreateFile(szFileName, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
-    if(hFile != INVALID_HANDLE_VALUE)
+    // 1) Try to treat "szFileName" as a section name
+    hMap = OpenFileMapping(SECTION_QUERY | FILE_MAP_READ, FALSE, szFileName);
+    if(hMap != NULL)
+    {
+        // Try to retrieve the size of the mapping
+        if(!RetrieveFileMappingSize(hMap, FileSize))
+        {
+            CloseHandle(hMap);
+            hMap = NULL;
+        }
+    }
+
+    // 2) Treat the name as file name
+    else
     {
-        // Retrieve file size. Don't allow mapping file of a zero size.
-        FileSize.LowPart = GetFileSize(hFile, &FileSize.HighPart);
-        if(FileSize.QuadPart != 0)
+        hFile = CreateFile(szFileName, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+        if(hFile != INVALID_HANDLE_VALUE)
         {
-            // Now create mapping object
-            hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
-            if(hMap != NULL)
+            // Retrieve file size. Don't allow mapping file of a zero size.
+            FileSize.LowPart = GetFileSize(hFile, &FileSize.HighPart);
+            if(FileSize.QuadPart != 0)
             {
-                // Map the entire view into memory
-                // Note that this operation will fail if the file can't fit
-                // into usermode address space
-                pStream->Base.Map.pbFile = (LPBYTE)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
-                if(pStream->Base.Map.pbFile != NULL)
-                {
-                    // Retrieve file time
-                    GetFileTime(hFile, NULL, NULL, (LPFILETIME)&pStream->Base.Map.FileTime);
+                // Now create file mapping over the file
+                hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+            }
+        }
+    }
 
-                    // Retrieve file size and position
-                    pStream->Base.Map.FileSize = FileSize.QuadPart;
-                    pStream->Base.Map.FilePos = 0;
-                    bResult = true;
-                }
+    // Did it succeed?
+    if(hMap != NULL)
+    {
+        // Map the entire view into memory
+        // Note that this operation will fail if the file can't fit
+        // into usermode address space
+        pStream->Base.Map.pbFile = (LPBYTE)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
+        if(pStream->Base.Map.pbFile != NULL)
+        {
+            // Retrieve file time. If it's named section, put 0
+            if(hFile != INVALID_HANDLE_VALUE)
+                GetFileTime(hFile, NULL, NULL, (LPFILETIME)&pStream->Base.Map.FileTime);
 
-                // Close the map handle
-                CloseHandle(hMap);
-            }
+            // Retrieve file size and position
+            pStream->Base.Map.FileSize = FileSize.QuadPart;
+            pStream->Base.Map.FilePos = 0;
+            bResult = true;
         }
 
-        // Close the file handle
-        CloseHandle(hFile);
+        // Close the map handle
+        CloseHandle(hMap);
     }
 
+    // Close the file handle
+    if(hFile != INVALID_HANDLE_VALUE)
+        CloseHandle(hFile);
+
     // If the file is not there and is not available for random access,
     // report error
     if(bResult == false)
         return false;
 #endif
 
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+#if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX) || defined(STORMLIB_HAIKU)
     struct stat64 fileinfo;
     intptr_t handle;
     bool bResult = false;
@@ -552,12 +628,12 @@ static bool BaseMap_Read(
 
 static void BaseMap_Close(TFileStream * pStream)
 {
-#ifdef PLATFORM_WINDOWS
+#ifdef STORMLIB_WINDOWS
     if(pStream->Base.Map.pbFile != NULL)
         UnmapViewOfFile(pStream->Base.Map.pbFile);
 #endif
 
-#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+#if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX) || defined(STORMLIB_HAIKU)
     if(pStream->Base.Map.pbFile != NULL)
         munmap(pStream->Base.Map.pbFile, (size_t )pStream->Base.Map.FileSize);
 #endif
@@ -607,7 +683,7 @@ static const TCHAR * BaseHttp_ExtractServerName(const TCHAR * szFileName, TCHAR
 
 static bool BaseHttp_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD dwStreamFlags)
 {
-#ifdef PLATFORM_WINDOWS
+#ifdef STORMLIB_WINDOWS
 
     HINTERNET hRequest;
     DWORD dwTemp = 0;
@@ -652,6 +728,19 @@ static bool BaseHttp_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD
                     DWORD dwFileSize = 0;
                     DWORD dwDataSize;
                     DWORD dwIndex = 0;
+                    TCHAR StatusCode[0x08];
+
+                    // Check if the file succeeded to open
+                    dwDataSize = sizeof(StatusCode);
+                    if(HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE, StatusCode, &dwDataSize, &dwIndex))
+                    {
+                        if(_tcscmp(StatusCode, _T("200")))
+                        {
+                            InternetCloseHandle(hRequest);
+                            SetLastError(ERROR_FILE_NOT_FOUND);
+                            return false;
+                        }
+                    }
 
                     // Check if the MPQ has Last Modified field
                     dwDataSize = sizeof(ULONGLONG);
@@ -706,7 +795,7 @@ static bool BaseHttp_Read(
     void * pvBuffer,                        // Pointer to data to be read
     DWORD dwBytesToRead)                    // Number of bytes to read from the file
 {
-#ifdef PLATFORM_WINDOWS
+#ifdef STORMLIB_WINDOWS
     ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.Http.FilePos;
     DWORD dwTotalBytesRead = 0;
 
@@ -727,8 +816,8 @@ static bool BaseHttp_Read(
         {
             // Add range request to the HTTP headers
             // http://www.clevercomponents.com/articles/article015/resuming.asp
-            _stprintf(szRangeRequest, _T("Range: bytes=%u-%u"), (unsigned int)dwStartOffset, (unsigned int)dwEndOffset);
-            HttpAddRequestHeaders(hRequest, szRangeRequest, 0xFFFFFFFF, HTTP_ADDREQ_FLAG_ADD_IF_NEW); 
+            wsprintf(szRangeRequest, _T("Range: bytes=%u-%u"), (unsigned int)dwStartOffset, (unsigned int)dwEndOffset);
+            HttpAddRequestHeaders(hRequest, szRangeRequest, 0xFFFFFFFF, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
 
             // Send the request to the server
             if(HttpSendRequest(hRequest, NULL, 0, NULL, 0))
@@ -779,7 +868,7 @@ static bool BaseHttp_Read(
 
 static void BaseHttp_Close(TFileStream * pStream)
 {
-#ifdef PLATFORM_WINDOWS
+#ifdef STORMLIB_WINDOWS
     if(pStream->Base.Http.hConnect != NULL)
         InternetCloseHandle(pStream->Base.Http.hConnect);
     pStream->Base.Http.hConnect = NULL;
@@ -981,7 +1070,7 @@ static void BlockStream_Close(TBlockStream * pStream)
 static STREAM_INIT StreamBaseInit[4] =
 {
     BaseFile_Init,
-    BaseMap_Init, 
+    BaseMap_Init,
     BaseHttp_Init,
     BaseNone_Init
 };
@@ -1020,7 +1109,7 @@ static TFileStream * AllocateFileStream(
             SetLastError(ERROR_INVALID_PARAMETER);
             return NULL;
         }
-        
+
         // Open the master file
         pMaster = FileStream_OpenFile(szNextFile + 1, STREAM_FLAG_READ_ONLY);
     }
@@ -1078,7 +1167,7 @@ static DWORD FlatStream_CheckFile(TBlockStream * pStream)
 static bool FlatStream_LoadBitmap(TBlockStream * pStream)
 {
     FILE_BITMAP_FOOTER Footer;
-    ULONGLONG ByteOffset; 
+    ULONGLONG ByteOffset;
     LPBYTE FileBitmap;
     DWORD BlockCount;
     DWORD BitmapSize;
@@ -1186,7 +1275,7 @@ static bool FlatStream_BlockCheck(
     // Sanity checks
     assert((BlockOffset & (pStream->BlockSize - 1)) == 0);
     assert(FileBitmap != NULL);
-    
+
     // Calculate the index of the block
     BlockIndex = (DWORD)(BlockOffset / pStream->BlockSize);
     BitMask = (BYTE)(1 << (BlockIndex & 0x07));
@@ -1247,7 +1336,7 @@ static void FlatStream_Close(TBlockStream * pStream)
     {
         // Write the file bitmap
         pStream->BaseWrite(pStream, &pStream->StreamSize, pStream->FileBitmap, pStream->BitmapSize);
-        
+
         // Prepare and write the file footer
         Footer.Signature   = ID_FILE_BITMAP_FOOTER;
         Footer.Version     = 3;
@@ -1342,7 +1431,7 @@ static bool FlatStream_CreateMirror(TBlockStream * pStream)
 
 static TFileStream * FlatStream_Open(const TCHAR * szFileName, DWORD dwStreamFlags)
 {
-    TBlockStream * pStream;    
+    TBlockStream * pStream;
     ULONGLONG ByteOffset = 0;
 
     // Create new empty stream
@@ -1566,7 +1655,7 @@ static bool PartStream_BlockCheck(
     // Sanity checks
     assert((BlockOffset & (pStream->BlockSize - 1)) == 0);
     assert(pStream->FileBitmap != NULL);
-    
+
     // Calculate the block map entry
     FileBitmap = (PPART_FILE_MAP_ENTRY)pStream->FileBitmap + (BlockOffset / pStream->BlockSize);
 
@@ -1662,10 +1751,10 @@ static void PartStream_Close(TBlockStream * pStream)
         PartHeader.FileSizeHi     = (DWORD)(pStream->StreamSize >> 0x20);
         PartHeader.FileSizeLo     = (DWORD)(pStream->StreamSize & 0xFFFFFFFF);
         PartHeader.BlockSize      = pStream->BlockSize;
-        
+
         // Make sure that the header is properly BSWAPed
         BSWAP_ARRAY32_UNSIGNED(&PartHeader, sizeof(PART_FILE_HEADER));
-        sprintf(PartHeader.GameBuildNumber, "%u", (unsigned int)pStream->BuildNumber);
+        IntToString(PartHeader.GameBuildNumber, _countof(PartHeader.GameBuildNumber), pStream->BuildNumber);
 
         // Write the part header
         pStream->BaseWrite(pStream, &ByteOffset, &PartHeader, sizeof(PART_FILE_HEADER));
@@ -1827,7 +1916,7 @@ static const char * AuthCodeArray[] =
     "S48B6CDTN5XEQAKQDJNDLJBJ73FDFM3U",         // SC2 Heart of the Swarm-all : "expand 32-byte kQAKQ0000FM3UN5XE000073FD6CDT0000LJBJS48B0000DJND"
 
     // Diablo III: Agent.exe (1.0.0.954)
-    // Address of decryption routine: 00502b00                             
+    // Address of decryption routine: 00502b00
     // Pointer to decryptor object: ECX
     // Pointer to key: ECX+0x5C
     // Authentication code URL: http://dist.blizzard.com/mediakey/d3-authenticationcode-enGB.txt
@@ -1933,7 +2022,7 @@ static void DecryptFileChunk(
         KeyShuffled[0x04] = KeyMirror[0x0D];
         KeyShuffled[0x01] = KeyMirror[0x0E];
         KeyShuffled[0x00] = KeyMirror[0x0F];
-        
+
         // Shuffle the key - part 2
         for(DWORD i = 0; i < RoundCount; i += 2)
         {
@@ -2024,7 +2113,7 @@ static bool MpqeStream_DetectFileKey(TEncryptedStream * pStream)
             // Prepare they decryption key from game serial number
             CreateKeyFromAuthCode(pStream->Key, AuthCodeArray[i]);
 
-            // Try to decrypt with the given key 
+            // Try to decrypt with the given key
             memcpy(FileHeader, EncryptedHeader, MPQE_CHUNK_SIZE);
             DecryptFileChunk((LPDWORD)FileHeader, pStream->Key, ByteOffset, MPQE_CHUNK_SIZE);
 
@@ -2250,7 +2339,7 @@ static TFileStream * Block4Stream_Open(const TCHAR * szFileName, DWORD dwStreamF
         for(int nSuffix = 0; nSuffix < 30; nSuffix++)
         {
             // Open the n-th file
-            _stprintf(szNameBuff, _T("%s.%u"), pStream->szFileName, nSuffix);
+            CreateNameWithSuffix(szNameBuff, nNameLength + 4, pStream->szFileName, nSuffix);
             if(!pStream->BaseOpen(pStream, szNameBuff, dwBaseFlags))
                 break;
 
@@ -2279,8 +2368,8 @@ static TFileStream * Block4Stream_Open(const TCHAR * szFileName, DWORD dwStreamF
             assert(FileSize <= BLOCK4_MAX_FSIZE);
             RemainderBlock = FileSize % (BLOCK4_BLOCK_SIZE + BLOCK4_HASH_SIZE);
             BlockCount = FileSize / (BLOCK4_BLOCK_SIZE + BLOCK4_HASH_SIZE);
-            
-            // Increment the stream size and number of blocks            
+
+            // Increment the stream size and number of blocks
             pStream->StreamSize += (BlockCount * BLOCK4_BLOCK_SIZE);
             pStream->BlockCount += (DWORD)BlockCount;
 
@@ -2497,7 +2586,7 @@ size_t FileStream_Prefix(const TCHAR * szFileName, DWORD * pdwProvider)
             dwProvider |= BASE_PROVIDER_MAP;
             nPrefixLength2 = 4;
         }
-        
+
         else if(!_tcsnicmp(szFileName+nPrefixLength1, _T("http:"), 5))
         {
             dwProvider |= BASE_PROVIDER_HTTP;
@@ -2705,7 +2794,7 @@ bool FileStream_GetSize(TFileStream * pStream, ULONGLONG * pFileSize)
  * \a NewFileSize File size to set
  */
 bool FileStream_SetSize(TFileStream * pStream, ULONGLONG NewFileSize)
-{                                 
+{
     if(pStream->dwFlags & STREAM_FLAG_READ_ONLY)
     {
         SetLastError(ERROR_ACCESS_DENIED);
@@ -2814,10 +2903,10 @@ void FileStream_Close(TFileStream * pStream)
             FileStream_Close(pStream->pMaster);
         pStream->pMaster = NULL;
 
-        // Close the stream provider ...
+        // Close the stream provider
         if(pStream->StreamClose != NULL)
             pStream->StreamClose(pStream);
-        
+
         // ... or close base stream, if any
         else if(pStream->BaseClose != NULL)
             pStream->BaseClose(pStream);
diff --git a/OpenSource/StormLib/src/FileStream.h b/OpenSource/StormLib/src/FileStream.h
index 44beeed91..2bc118b28 100644
--- a/OpenSource/StormLib/src/FileStream.h
+++ b/OpenSource/StormLib/src/FileStream.h
@@ -202,7 +202,7 @@ struct TBlockStream : public TFileStream
     DWORD BlockCount;                       // Number of data blocks in the file
     DWORD IsComplete;                       // If nonzero, no blocks are missing
     DWORD IsModified;                       // nonzero if the bitmap has been modified
-};        
+};
 
 //-----------------------------------------------------------------------------
 // Structure for encrypted stream
diff --git a/OpenSource/StormLib/src/SBaseCommon.cpp b/OpenSource/StormLib/src/SBaseCommon.cpp
index 782e154a3..b083f89d5 100644
--- a/OpenSource/StormLib/src/SBaseCommon.cpp
+++ b/OpenSource/StormLib/src/SBaseCommon.cpp
@@ -20,7 +20,10 @@ char StormLibCopyright[] = "StormLib v " STORMLIB_VERSION_STRING " Copyright Lad
 //-----------------------------------------------------------------------------
 // Local variables
 
-LCID    lcFileLocale = LANG_NEUTRAL;            // File locale
+DWORD g_dwMpqSignature = ID_MPQ;                // Marker for MPQ header
+DWORD g_dwHashTableKey = MPQ_KEY_HASH_TABLE;    // Key for hash table
+DWORD g_dwBlockTableKey = MPQ_KEY_BLOCK_TABLE;  // Key for block table
+LCID  g_lcFileLocale = LANG_NEUTRAL;            // File locale
 USHORT  wPlatform = 0;                          // File platform
 
 //-----------------------------------------------------------------------------
@@ -28,66 +31,66 @@ USHORT  wPlatform = 0;                          // File platform
 
 // Converts ASCII characters to lowercase
 // Converts slash (0x2F) to backslash (0x5C)
-unsigned char AsciiToLowerTable[256] = 
+unsigned char AsciiToLowerTable[256] =
 {
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 
-    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 
-    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x5C, 
-    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 
-    0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 
-    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 
-    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 
-    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 
-    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 
-    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 
-    0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 
-    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 
-    0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 
-    0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x5C,
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+    0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
+    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
+    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+    0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+    0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+    0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
     0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
 };
 
 // Converts ASCII characters to uppercase
 // Converts slash (0x2F) to backslash (0x5C)
-unsigned char AsciiToUpperTable[256] = 
+unsigned char AsciiToUpperTable[256] =
 {
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 
-    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 
-    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x5C, 
-    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 
-    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 
-    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 
-    0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 
-    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 
-    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 
-    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 
-    0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 
-    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 
-    0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 
-    0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x5C,
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+    0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
+    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
+    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+    0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+    0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+    0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
     0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
 };
 
 // Converts ASCII characters to uppercase
 // Does NOT convert slash (0x2F) to backslash (0x5C)
-unsigned char AsciiToUpperTable_Slash[256] = 
+unsigned char AsciiToUpperTable_Slash[256] =
 {
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 
-    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 
-    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 
-    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 
-    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 
-    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 
-    0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 
-    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 
-    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 
-    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 
-    0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 
-    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 
-    0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 
-    0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+    0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
+    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
+    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+    0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+    0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+    0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
     0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
 };
@@ -95,18 +98,22 @@ unsigned char AsciiToUpperTable_Slash[256] =
 //-----------------------------------------------------------------------------
 // Safe string functions (for ANSI builds)
 
-void StringCopy(char * szTarget, size_t cchTarget, const char * szSource)
+char * StringCopy(char * szTarget, size_t cchTarget, const char * szSource)
 {
+    size_t cchSource = 0;
+
     if(cchTarget > 0)
     {
-        size_t cchSource = strlen(szSource);
+        cchSource = strlen(szSource);
 
         if(cchSource >= cchTarget)
             cchSource = cchTarget - 1;
-        
+
         memcpy(szTarget, szSource, cchSource);
         szTarget[cchSource] = 0;
     }
+
+    return szTarget + cchSource;
 }
 
 void StringCat(char * szTarget, size_t cchTargetMax, const char * szSource)
@@ -121,6 +128,26 @@ void StringCat(char * szTarget, size_t cchTargetMax, const char * szSource)
     }
 }
 
+void StringCreatePseudoFileName(char * szBuffer, size_t cchMaxChars, unsigned int nIndex, const char * szExtension)
+{
+    char * szBufferEnd = szBuffer + cchMaxChars;
+
+    // "File"
+    szBuffer = StringCopy(szBuffer, (szBufferEnd - szBuffer), "File");
+
+    // Number
+    szBuffer = IntToString(szBuffer, szBufferEnd - szBuffer + 1, nIndex, 8);
+
+    // Dot
+    if(szBuffer < szBufferEnd)
+        *szBuffer++ = '.';
+
+    // Extension
+    while(szExtension[0] == '.')
+        szExtension++;
+    StringCopy(szBuffer, (szBufferEnd - szBuffer), szExtension);
+}
+
 //-----------------------------------------------------------------------------
 // Utility functions (UNICODE) only exist in the ANSI version of the library
 // In ANSI builds, TCHAR = char, so we don't need these functions implemented
@@ -134,7 +161,7 @@ void StringCopy(TCHAR * szTarget, size_t cchTarget, const char * szSource)
 
         if(cchSource >= cchTarget)
             cchSource = cchTarget - 1;
-        
+
         mbstowcs(szTarget, szSource, cchSource);
         szTarget[cchSource] = 0;
     }
@@ -148,7 +175,7 @@ void StringCopy(char * szTarget, size_t cchTarget, const TCHAR * szSource)
 
         if(cchSource >= cchTarget)
             cchSource = cchTarget - 1;
-        
+
         wcstombs(szTarget, szSource, cchSource);
         szTarget[cchSource] = 0;
     }
@@ -162,7 +189,7 @@ void StringCopy(TCHAR * szTarget, size_t cchTarget, const TCHAR * szSource)
 
         if(cchSource >= cchTarget)
             cchSource = cchTarget - 1;
-        
+
         memcpy(szTarget, szSource, cchSource * sizeof(TCHAR));
         szTarget[cchSource] = 0;
     }
@@ -222,7 +249,7 @@ void InitializeMpqCryptography()
         register_hash(&sha1_desc);
 
         // Use LibTomMath as support math library for LibTomCrypt
-        ltc_mp = ltm_desc;    
+        ltc_mp = ltm_desc;
 
         // Don't do that again
         bMpqCryptographyInitialized = true;
@@ -231,7 +258,7 @@ void InitializeMpqCryptography()
 
 //
 // Note: Implementation of this function in WorldEdit.exe and storm.dll
-// incorrectly treats the character as signed, which leads to the 
+// incorrectly treats the character as signed, which leads to the
 // a buffer underflow if the character in the file name >= 0x80:
 // The following steps happen when *pbKey == 0xBF and dwHashType == 0x0000
 // (calculating hash index)
@@ -244,7 +271,7 @@ void InitializeMpqCryptography()
 // As result, MPQs containing files with non-ANSI characters will not work between
 // various game versions and localizations. Even WorldEdit, after importing a file
 // with Korean characters in the name, cannot open the file back.
-// 
+//
 DWORD HashString(const char * szFileName, DWORD dwHashType)
 {
     LPBYTE pbKey   = (BYTE *)szFileName;
@@ -424,7 +451,7 @@ void DecryptMpqBlock(void * pvDataBlock, DWORD dwLength, DWORD dwKey1)
     {
         // Modify the second key
         dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)];
-        
+
         DataBlock[i] = DataBlock[i] ^ (dwKey1 + dwKey2);
         dwValue32 = DataBlock[i];
 
@@ -605,8 +632,8 @@ DWORD DecryptFileKey(
 TMPQArchive * IsValidMpqHandle(HANDLE hMpq)
 {
     TMPQArchive * ha = (TMPQArchive *)hMpq;
-    
-    return (ha != NULL && ha->pHeader != NULL && ha->pHeader->dwID == ID_MPQ) ? ha : NULL;
+
+    return (ha != NULL && ha->pHeader != NULL && ha->pHeader->dwID == g_dwMpqSignature) ? ha : NULL;
 }
 
 TMPQFile * IsValidFileHandle(HANDLE hFile)
@@ -855,7 +882,7 @@ TMPQFile * CreateWritableHandle(TMPQArchive * ha, DWORD dwFileSize)
     {
         TempPos  = FreeMpqSpace +
                    dwFileSize +
-                  (ha->pHeader->dwHashTableSize * sizeof(TMPQHash)) + 
+                  (ha->pHeader->dwHashTableSize * sizeof(TMPQHash)) +
                   (ha->dwFileTableSize * sizeof(TMPQBlock));
         if((TempPos >> 32) != 0)
         {
@@ -883,6 +910,7 @@ TMPQFile * CreateWritableHandle(TMPQArchive * ha, DWORD dwFileSize)
 void * LoadMpqTable(
     TMPQArchive * ha,
     ULONGLONG ByteOffset,
+    LPBYTE pbTableHash,
     DWORD dwCompressedSize,
     DWORD dwTableSize,
     DWORD dwKey,
@@ -921,6 +949,7 @@ void * LoadMpqTable(
         // On archives v 1.0, hash table and block table can go beyond EOF.
         // Storm.dll reads as much as possible, then fills the missing part with zeros.
         // Abused by Spazzler map protector which sets hash table size to 0x00100000
+        // Abused by NP_Protect in MPQs v4 as well
         if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
         {
             // Cut the table size
@@ -930,15 +959,28 @@ void * LoadMpqTable(
                 // Fill the extra data with zeros
                 dwBytesToRead = (DWORD)(FileSize - ByteOffset);
                 memset(pbMpqTable + dwBytesToRead, 0, (dwTableSize - dwBytesToRead));
-                
+
                 // Give the caller information that the table was cut
                 if(pbTableIsCut != NULL)
                     pbTableIsCut[0] = true;
             }
         }
 
-        // If everything succeeded, read the raw table form the MPQ
+        // If everything succeeded, read the raw table from the MPQ
         if(FileStream_Read(ha->pStream, &ByteOffset, pbToRead, dwBytesToRead))
+        {
+            // Verify the MD5 of the table, if present
+            if(!VerifyDataBlockHash(pbToRead, dwBytesToRead, pbTableHash))
+            {
+                nError = ERROR_FILE_CORRUPT;
+            }
+        }
+        else
+        {
+            nError = GetLastError();
+        }
+
+        if(nError == ERROR_SUCCESS)
         {
             // First of all, decrypt the table
             if(dwKey != 0)
@@ -961,10 +1003,6 @@ void * LoadMpqTable(
             // Make sure that the table is properly byte-swapped
             BSWAP_ARRAY32_UNSIGNED(pbMpqTable, dwTableSize);
         }
-        else
-        {
-            nError = GetLastError();
-        }
 
         // If read failed, free the table and return
         if(nError != ERROR_SUCCESS)
@@ -1120,7 +1158,7 @@ int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile)
 
     // Calculate the number of file sectors
     dwSectorOffsLen = (hf->dwSectorCount + 1) * sizeof(DWORD);
-    
+
     // If MPQ_FILE_SECTOR_CRC flag is set, there will either be extra DWORD
     // or an array of MD5's. Either way, we read at least 4 bytes more
     // in order to save additional read from the file.
@@ -1226,7 +1264,7 @@ int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile)
             //
             // These extra values are, however, include in the dwCmpSize in the file
             // table. We cannot ignore them, because compacting archive would fail
-            // 
+            //
 
             if(hf->SectorOffsets[0] > dwSectorOffsLen)
             {
@@ -1273,7 +1311,7 @@ int AllocateSectorChecksums(TMPQFile * hf, bool bLoadFromFile)
     // Caller must ensure that we are only called when we have sector checksums
     assert(pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC);
 
-    // 
+    //
     // Older MPQs store an array of CRC32's after
     // the raw file data in the MPQ.
     //
@@ -1313,10 +1351,10 @@ int AllocateSectorChecksums(TMPQFile * hf, bool bLoadFromFile)
             // Calculate offset of the CRC table
             dwCrcSize = hf->dwSectorCount * sizeof(DWORD);
             dwCrcOffset = hf->SectorOffsets[hf->dwSectorCount];
-            RawFilePos = CalculateRawSectorOffset(hf, dwCrcOffset); 
+            RawFilePos = CalculateRawSectorOffset(hf, dwCrcOffset);
 
             // Now read the table from the MPQ
-            hf->SectorChksums = (DWORD *)LoadMpqTable(ha, RawFilePos, dwCompressedSize, dwCrcSize, 0, NULL);
+            hf->SectorChksums = (DWORD *)LoadMpqTable(ha, RawFilePos, NULL, dwCompressedSize, dwCrcSize, 0, NULL);
             if(hf->SectorChksums == NULL)
                 return ERROR_NOT_ENOUGH_MEMORY;
         }
@@ -1369,14 +1407,13 @@ int WriteSectorOffsets(TMPQFile * hf)
     // Write sector offsets to the archive
     if(!FileStream_Write(ha->pStream, &RawFilePos, hf->SectorOffsets, dwSectorOffsLen))
         return GetLastError();
-    
+
     // Not necessary, as the sector checksums
     // are going to be freed when this is done.
 //  BSWAP_ARRAY32_UNSIGNED(hf->SectorOffsets, dwSectorOffsLen);
     return ERROR_SUCCESS;
 }
 
-
 int WriteSectorChecksums(TMPQFile * hf)
 {
     TMPQArchive * ha = hf->ha;
@@ -1428,7 +1465,7 @@ int WriteSectorChecksums(TMPQFile * hf)
     // are going to be freed when this is done.
 //  BSWAP_ARRAY32_UNSIGNED(hf->SectorChksums, dwCrcSize);
 
-    // Store the sector CRCs 
+    // Store the sector CRCs
     hf->SectorOffsets[hf->dwSectorCount + 1] = hf->SectorOffsets[hf->dwSectorCount] + dwCompressedSize;
     pFileEntry->dwCmpSize += dwCompressedSize;
     STORM_FREE(pbCompressed);
@@ -1668,7 +1705,7 @@ bool IsValidMD5(LPBYTE pbMd5)
 {
     LPDWORD Md5 = (LPDWORD)pbMd5;
 
-    return (Md5[0] | Md5[1] | Md5[2] | Md5[3]) ? true : false;
+    return ((Md5 != NULL) && (Md5[0] | Md5[1] | Md5[2] | Md5[3])) ? true : false;
 }
 
 bool IsValidSignature(LPBYTE pbSignature)
@@ -1687,18 +1724,21 @@ bool VerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_
 {
     hash_state md5_state;
     BYTE md5_digest[MD5_DIGEST_SIZE];
+    bool bResult = true;
 
     // Don't verify the block if the MD5 is not valid.
-    if(!IsValidMD5(expected_md5))
-        return true;
+    if(IsValidMD5(expected_md5))
+    {
+        // Calculate the MD5 of the data block
+        md5_init(&md5_state);
+        md5_process(&md5_state, (unsigned char *)pvDataBlock, cbDataBlock);
+        md5_done(&md5_state, md5_digest);
 
-    // Calculate the MD5 of the data block
-    md5_init(&md5_state);
-    md5_process(&md5_state, (unsigned char *)pvDataBlock, cbDataBlock);
-    md5_done(&md5_state, md5_digest);
+        // Does the MD5's match?
+        bResult = (memcmp(md5_digest, expected_md5, MD5_DIGEST_SIZE) == 0);
+    }
 
-    // Does the MD5's match?
-    return (memcmp(md5_digest, expected_md5, MD5_DIGEST_SIZE) == 0);
+    return bResult;
 }
 
 void CalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_hash)
@@ -1714,7 +1754,7 @@ void CalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_ha
 //-----------------------------------------------------------------------------
 // Swapping functions
 
-#ifndef PLATFORM_LITTLE_ENDIAN
+#ifndef STORMLIB_LITTLE_ENDIAN
 
 //
 // Note that those functions are implemented for Mac operating system,
@@ -1839,4 +1879,4 @@ void ConvertTMPQHeader(void *header, uint16_t version)
     }
 }
 
-#endif  // PLATFORM_LITTLE_ENDIAN
+#endif  // STORMLIB_LITTLE_ENDIAN
diff --git a/OpenSource/StormLib/src/SBaseDumpData.cpp b/OpenSource/StormLib/src/SBaseDumpData.cpp
index 334561b85..b08796a4a 100644
--- a/OpenSource/StormLib/src/SBaseDumpData.cpp
+++ b/OpenSource/StormLib/src/SBaseDumpData.cpp
@@ -69,14 +69,14 @@ void DumpHetAndBetTable(TMPQHetTable * pHetTable, TMPQBetTable * pBetTable)
         return;
 
     printf("== HET Header =================================\n");
-    printf("ULONGLONG  AndMask64         = %016llX\n",  pHetTable->AndMask64);       
-    printf("ULONGLONG  OrMask64          = %016llX\n",  pHetTable->OrMask64);        
+    printf("ULONGLONG  AndMask64         = %016llX\n",  pHetTable->AndMask64);
+    printf("ULONGLONG  OrMask64          = %016llX\n",  pHetTable->OrMask64);
     printf("DWORD      dwEntryCount      = %08X\n",     pHetTable->dwEntryCount);
     printf("DWORD      dwTotalCount      = %08X\n",     pHetTable->dwTotalCount);
     printf("DWORD      dwNameHashBitSize = %08X\n",     pHetTable->dwNameHashBitSize);
     printf("DWORD      dwIndexSizeTotal  = %08X\n",     pHetTable->dwIndexSizeTotal);
     printf("DWORD      dwIndexSizeExtra  = %08X\n",     pHetTable->dwIndexSizeExtra);
-    printf("DWORD      dwIndexSize       = %08X\n",     pHetTable->dwIndexSize);     
+    printf("DWORD      dwIndexSize       = %08X\n",     pHetTable->dwIndexSize);
     printf("-----------------------------------------------\n\n");
 
     printf("== BET Header =================================\n");
@@ -89,7 +89,7 @@ void DumpHetAndBetTable(TMPQHetTable * pHetTable, TMPQBetTable * pBetTable)
     printf("DWORD dwBitCount_FilePos     = %08X\n",     pBetTable->dwBitCount_FilePos);
     printf("DWORD dwBitCount_FileSize    = %08X\n",     pBetTable->dwBitCount_FileSize);
     printf("DWORD dwBitCount_CmpSize     = %08X\n",     pBetTable->dwBitCount_CmpSize);
-    printf("DWORD dwBitCount_FlagIndex   = %08X\n",     pBetTable->dwBitCount_FlagIndex);   
+    printf("DWORD dwBitCount_FlagIndex   = %08X\n",     pBetTable->dwBitCount_FlagIndex);
     printf("DWORD dwBitCount_Unknown     = %08X\n",     pBetTable->dwBitCount_Unknown);
     printf("DWORD dwBitTotal_NameHash2   = %08X\n",     pBetTable->dwBitTotal_NameHash2);
     printf("DWORD dwBitExtra_NameHash2   = %08X\n",     pBetTable->dwBitExtra_NameHash2);
@@ -111,39 +111,33 @@ void DumpHetAndBetTable(TMPQHetTable * pHetTable, TMPQBetTable * pBetTable)
         DWORD dwFlags = 0;
         DWORD dwBetIndex = 0;
 
-        GetBits(pHetTable->pBetIndexes, i * pHetTable->dwIndexSizeTotal,
-                                        pHetTable->dwIndexSize,
-                                       &dwBetIndex,
-                                        4);
-        
+        GetMPQBits(pHetTable->pBetIndexes, i * pHetTable->dwIndexSizeTotal,
+                                           pHetTable->dwIndexSize,
+                                          &dwBetIndex, 4);
+
         if(dwBetIndex < pHetTable->dwTotalCount)
         {
             DWORD dwEntryIndex = pBetTable->dwTableEntrySize * dwBetIndex;
 
-            GetBits(pBetTable->pNameHashes, dwBetIndex * pBetTable->dwBitTotal_NameHash2,
-                                            pBetTable->dwBitCount_NameHash2,
-                                           &BetHash,
-                                            8);
-
-            GetBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FilePos,
-                                           pBetTable->dwBitCount_FilePos,
-                                          &ByteOffset,
-                                           8);
-
-            GetBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FileSize,
-                                           pBetTable->dwBitCount_FileSize,
-                                          &dwFileSize,
-                                           4);
-
-            GetBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_CmpSize,
-                                           pBetTable->dwBitCount_CmpSize,
-                                          &dwCmpSize,
-                                           4);
-
-            GetBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FlagIndex,
-                                           pBetTable->dwBitCount_FlagIndex,
-                                          &dwFlagIndex,
-                                           4);
+            GetMPQBits(pBetTable->pNameHashes, dwBetIndex * pBetTable->dwBitTotal_NameHash2,
+                                               pBetTable->dwBitCount_NameHash2,
+                                              &BetHash, 8);
+
+            GetMPQBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FilePos,
+                                              pBetTable->dwBitCount_FilePos,
+                                             &ByteOffset, 8);
+
+            GetMPQBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FileSize,
+                                              pBetTable->dwBitCount_FileSize,
+                                             &dwFileSize, 4);
+
+            GetMPQBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_CmpSize,
+                                              pBetTable->dwBitCount_CmpSize,
+                                             &dwCmpSize, 4);
+
+            GetMPQBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FlagIndex,
+                                              pBetTable->dwBitCount_FlagIndex,
+                                             &dwFlagIndex, 4);
 
             dwFlags = pBetTable->pFileFlags[dwFlagIndex];
         }
diff --git a/OpenSource/StormLib/src/SBaseFileTable.cpp b/OpenSource/StormLib/src/SBaseFileTable.cpp
index d3797d9c8..8570563d4 100644
--- a/OpenSource/StormLib/src/SBaseFileTable.cpp
+++ b/OpenSource/StormLib/src/SBaseFileTable.cpp
@@ -52,24 +52,38 @@ static DWORD GetNecessaryBitCount(ULONGLONG MaxValue)
         MaxValue >>= 1;
         dwBitCount++;
     }
-    
+
     return dwBitCount;
 }
 
 //-----------------------------------------------------------------------------
-// Support functions for BIT_ARRAY
+// Implementation of the TMPQBits struct
+
+struct TMPQBits
+{
+    static TMPQBits * Create(DWORD NumberOfBits, BYTE FillValue);
+
+    void GetBits(unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultSize);
+    void SetBits(unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultSize);
+
+    static const USHORT SetBitsMask[];          // Bit mask for each number of bits (0-8)
 
-static USHORT SetBitsMask[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
+    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)
+};
 
-static TBitArray * CreateBitArray(
+const USHORT TMPQBits::SetBitsMask[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
+
+TMPQBits * TMPQBits::Create(
     DWORD NumberOfBits,
     BYTE FillValue)
 {
-    TBitArray * pBitArray;
-    size_t nSize = sizeof(TBitArray) + (NumberOfBits + 7) / 8;
+    TMPQBits * pBitArray;
+    size_t nSize = sizeof(TMPQBits) + (NumberOfBits + 7) / 8;
 
     // Allocate the bit array
-    pBitArray = (TBitArray *)STORM_ALLOC(BYTE, nSize);
+    pBitArray = (TMPQBits *)STORM_ALLOC(BYTE, nSize);
     if(pBitArray != NULL)
     {
         memset(pBitArray, FillValue, nSize);
@@ -80,8 +94,7 @@ static TBitArray * CreateBitArray(
     return pBitArray;
 }
 
-void GetBits(
-    TBitArray * pArray,
+void TMPQBits::GetBits(
     unsigned int nBitPosition,
     unsigned int nBitLength,
     void * pvBuffer,
@@ -103,10 +116,10 @@ void GetBits(
         assert(pbBuffer[i] == 0);
 #endif
 
-#ifndef PLATFORM_LITTLE_ENDIAN
+#ifndef STORMLIB_LITTLE_ENDIAN
     // Adjust the buffer pointer for big endian platforms
     pbBuffer += (nResultByteSize - 1);
-#endif    
+#endif
 
     // Copy whole bytes, if any
     while(nByteLength > 0)
@@ -114,14 +127,14 @@ void GetBits(
         // Is the current position in the Elements byte-aligned?
         if(nBitOffset != 0)
         {
-            BitBuffer = (unsigned char)((pArray->Elements[nBytePosition0] >> nBitOffset) | (pArray->Elements[nBytePosition1] << (0x08 - nBitOffset)));
+            BitBuffer = (unsigned char)((Elements[nBytePosition0] >> nBitOffset) | (Elements[nBytePosition1] << (0x08 - nBitOffset)));
         }
         else
         {
-            BitBuffer = pArray->Elements[nBytePosition0];
+            BitBuffer = Elements[nBytePosition0];
         }
 
-#ifdef PLATFORM_LITTLE_ENDIAN
+#ifdef STORMLIB_LITTLE_ENDIAN
         *pbBuffer++ = BitBuffer;
 #else
         *pbBuffer-- = BitBuffer;
@@ -137,17 +150,16 @@ void GetBits(
     nBitLength = (nBitLength & 0x07);
     if(nBitLength != 0)
     {
-        *pbBuffer = (unsigned char)(pArray->Elements[nBytePosition0] >> nBitOffset);
+        *pbBuffer = (unsigned char)(Elements[nBytePosition0] >> nBitOffset);
 
         if(nBitLength > (8 - nBitOffset))
-            *pbBuffer = (unsigned char)((pArray->Elements[nBytePosition1] << (8 - nBitOffset)) | (pArray->Elements[nBytePosition0] >> nBitOffset));
+            *pbBuffer = (unsigned char)((Elements[nBytePosition1] << (8 - nBitOffset)) | (Elements[nBytePosition0] >> nBitOffset));
 
         *pbBuffer &= (0x01 << nBitLength) - 1;
     }
 }
 
-void SetBits(
-    TBitArray * pArray,
+void TMPQBits::SetBits(
     unsigned int nBitPosition,
     unsigned int nBitLength,
     void * pvBuffer,
@@ -163,16 +175,16 @@ void SetBits(
     // Keep compiler happy for platforms where nResultByteSize is not used
     nResultByteSize = nResultByteSize;
 
-#ifndef PLATFORM_LITTLE_ENDIAN
+#ifndef STORMLIB_LITTLE_ENDIAN
     // Adjust the buffer pointer for big endian platforms
     pbBuffer += (nResultByteSize - 1);
-#endif    
+#endif
 
     // Copy whole bytes, if any
     while(nBitLength > 8)
     {
         // Reload the bit buffer
-#ifdef PLATFORM_LITTLE_ENDIAN
+#ifdef STORMLIB_LITTLE_ENDIAN
         OneByte = *pbBuffer++;
 #else
         OneByte = *pbBuffer--;
@@ -182,7 +194,7 @@ void SetBits(
         AndMask = (AndMask >> 0x08) | (0x00FF << nBitOffset);
 
         // Update the byte in the array
-        pArray->Elements[nBytePosition] = (BYTE)((pArray->Elements[nBytePosition] & ~AndMask) | BitBuffer);
+        Elements[nBytePosition] = (BYTE)((Elements[nBytePosition] & ~AndMask) | BitBuffer);
 
         // Move byte positions and lengths
         nBytePosition++;
@@ -199,7 +211,7 @@ void SetBits(
         AndMask = (AndMask >> 0x08) | (SetBitsMask[nBitLength] << nBitOffset);
 
         // Update the byte in the array
-        pArray->Elements[nBytePosition] = (BYTE)((pArray->Elements[nBytePosition] & ~AndMask) | BitBuffer);
+        Elements[nBytePosition] = (BYTE)((Elements[nBytePosition] & ~AndMask) | BitBuffer);
 
         // Update the next byte, if needed
         if(AndMask & 0xFF00)
@@ -208,14 +220,56 @@ void SetBits(
             BitBuffer >>= 0x08;
             AndMask >>= 0x08;
 
-            pArray->Elements[nBytePosition] = (BYTE)((pArray->Elements[nBytePosition] & ~AndMask) | BitBuffer);
+            Elements[nBytePosition] = (BYTE)((Elements[nBytePosition] & ~AndMask) | BitBuffer);
         }
     }
 }
 
+void GetMPQBits(TMPQBits * pBits, unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultByteSize)
+{
+    pBits->GetBits(nBitPosition, nBitLength, pvBuffer, nResultByteSize);
+}
+
 //-----------------------------------------------------------------------------
 // Support for MPQ header
 
+static bool VerifyTablePosition64(
+    ULONGLONG MpqOffset,                // Position of the MPQ header
+    ULONGLONG TableOffset,              // Position of the MPQ table, relative to MPQ header
+    ULONGLONG TableSize,                // Size of the MPQ table, in bytes
+    ULONGLONG FileSize)                 // Size of the entire file, in bytes
+{
+    if(TableOffset != 0)
+    {
+        // Verify overflows
+        if((MpqOffset + TableOffset) < MpqOffset)
+            return false;
+        if((MpqOffset + TableOffset + TableSize) < MpqOffset)
+            return false;
+
+        // Verify sizes
+        if(TableOffset >= FileSize || TableSize >= FileSize)
+            return false;
+        if((MpqOffset + TableOffset) >= FileSize)
+            return false;
+        if((MpqOffset + TableOffset + TableSize) >= FileSize)
+            return false;
+    }
+    return true;
+}
+
+static bool VerifyTableTandemPositions(
+    ULONGLONG MpqOffset,                // Position of the MPQ header
+    ULONGLONG TableOffset1,             // 1st table: Position, relative to MPQ header
+    ULONGLONG TableSize1,               // 1st table: Size in bytes
+    ULONGLONG TableOffset2,             // 2nd table: Position, relative to MPQ header
+    ULONGLONG TableSize2,               // 2nd table: Size in bytes
+    ULONGLONG FileSize)                 // Size of the entire file, in bytes
+{
+    return VerifyTablePosition64(MpqOffset, TableOffset1, TableSize1, FileSize) &&
+           VerifyTablePosition64(MpqOffset, TableOffset2, TableSize2, FileSize);
+}
+
 static ULONGLONG DetermineArchiveSize_V1(
     TMPQArchive * ha,
     TMPQHeader * pHeader,
@@ -288,6 +342,45 @@ static ULONGLONG DetermineArchiveSize_V2(
     return (EndOfMpq - MpqOffset);
 }
 
+static ULONGLONG DetermineArchiveSize_V4(
+    TMPQHeader * pHeader,
+    ULONGLONG /* MpqOffset */,
+    ULONGLONG /* FileSize */)
+{
+    ULONGLONG ArchiveSize = 0;
+    ULONGLONG EndOfTable;
+
+    // This could only be called for MPQs version 4
+    assert(pHeader->wFormatVersion == MPQ_FORMAT_VERSION_4);
+
+    // Check position of BET table, if correct
+    if((pHeader->BetTablePos64 >> 0x20) == 0 && (pHeader->BetTableSize64 >> 0x20) == 0)
+    {
+        EndOfTable = pHeader->BetTablePos64 + pHeader->BetTableSize64;
+        if(EndOfTable > ArchiveSize)
+            ArchiveSize = EndOfTable;
+    }
+
+    // Check position of HET table, if correct
+    if((pHeader->HetTablePos64 >> 0x20) == 0 && (pHeader->HetTableSize64 >> 0x20) == 0)
+    {
+        EndOfTable = pHeader->HetTablePos64 + pHeader->HetTableSize64;
+        if(EndOfTable > ArchiveSize)
+            ArchiveSize = EndOfTable;
+    }
+
+    EndOfTable = pHeader->dwHashTablePos + pHeader->dwHashTableSize * sizeof(TMPQHash);
+    if(EndOfTable > ArchiveSize)
+        ArchiveSize = EndOfTable;
+
+    EndOfTable = pHeader->dwBlockTablePos + pHeader->dwBlockTableSize * sizeof(TMPQBlock);
+    if(EndOfTable > ArchiveSize)
+        ArchiveSize = EndOfTable;
+
+    // Return the calculated archive size
+    return ArchiveSize;
+}
+
 ULONGLONG FileOffsetFromMpqOffset(TMPQArchive * ha, ULONGLONG MpqOffset)
 {
     if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
@@ -311,7 +404,7 @@ ULONGLONG CalculateRawSectorOffset(
     // Must be used for files within a MPQ
     assert(hf->ha != NULL);
     assert(hf->ha->pHeader != NULL);
-    
+
     //
     // Some MPQ protectors place the sector offset table after the actual file data.
     // Sector offsets in the sector offset table are negative. When added
@@ -336,24 +429,30 @@ ULONGLONG CalculateRawSectorOffset(
 // This function converts the MPQ header so it always looks like version 4
 int ConvertMpqHeaderToFormat4(
     TMPQArchive * ha,
-    ULONGLONG MpqOffset,
+    ULONGLONG ByteOffset,
     ULONGLONG FileSize,
     DWORD dwFlags,
-    bool bIsWarcraft3Map)
+    MTYPE MapType)
 {
     TMPQHeader * pHeader = (TMPQHeader *)ha->HeaderData;
     ULONGLONG BlockTablePos64 = 0;
     ULONGLONG HashTablePos64 = 0;
     ULONGLONG BlockTableMask = (ULONGLONG)-1;
-    ULONGLONG ByteOffset;
+    ULONGLONG MaxOffset;
     USHORT wFormatVersion = BSWAP_INT16_UNSIGNED(pHeader->wFormatVersion);
+    bool bHashBlockOffsetOK = false;
+    bool bHetBetOffsetOK = false;
     int nError = ERROR_SUCCESS;
 
     // If version 1.0 is forced, then the format version is forced to be 1.0
     // Reason: Storm.dll in Warcraft III ignores format version value
-    if((dwFlags & MPQ_OPEN_FORCE_MPQ_V1) || bIsWarcraft3Map)
+    if((MapType == MapTypeWarcraft3) || (dwFlags & MPQ_OPEN_FORCE_MPQ_V1))
         wFormatVersion = MPQ_FORMAT_VERSION_1;
 
+    // Don't accept format 3 for Starcraft II maps
+    if((MapType == MapTypeStarcraft2) && (pHeader->wFormatVersion > MPQ_FORMAT_VERSION_2))
+        wFormatVersion = MPQ_FORMAT_VERSION_4;
+
     // Format-specific fixes
     switch(wFormatVersion)
     {
@@ -393,19 +492,27 @@ int ConvertMpqHeaderToFormat4(
             pHeader->BlockTableSize64 = pHeader->dwBlockTableSize * sizeof(TMPQBlock);
             pHeader->HashTableSize64 = pHeader->dwHashTableSize * sizeof(TMPQHash);
             pHeader->ArchiveSize64 = pHeader->dwArchiveSize;
-            
+
             // Block table position must be calculated as 32-bit value
             // Note: BOBA protector puts block table before the MPQ header, so it is negative
-            BlockTablePos64 = (ULONGLONG)((DWORD)MpqOffset + pHeader->dwBlockTablePos);
+            BlockTablePos64 = (ULONGLONG)((DWORD)ByteOffset + pHeader->dwBlockTablePos);
             BlockTableMask = 0xFFFFFFF0;
 
             // Determine the archive size on malformed MPQs
             if(ha->dwFlags & MPQ_FLAG_MALFORMED)
             {
                 // Calculate the archive size
-                pHeader->ArchiveSize64 = DetermineArchiveSize_V1(ha, pHeader, MpqOffset, FileSize);
+                pHeader->ArchiveSize64 = DetermineArchiveSize_V1(ha, pHeader, ByteOffset, FileSize);
                 pHeader->dwArchiveSize = (DWORD)pHeader->ArchiveSize64;
             }
+
+            // EWIX_v8_7.w3x: TMPQHeader::dwBlockTableSize = 0x00319601
+            // Size of TFileTable goes to ~200MB, so we artificially cut it
+            if(BlockTablePos64 + (pHeader->dwBlockTableSize * sizeof(TMPQBlock)) > FileSize)
+            {
+                pHeader->dwBlockTableSize = (DWORD)((FileSize - BlockTablePos64) / sizeof(TMPQBlock));
+                pHeader->BlockTableSize64 = pHeader->dwBlockTableSize * sizeof(TMPQBlock);
+            }
             break;
 
         case MPQ_FORMAT_VERSION_2:
@@ -447,7 +554,7 @@ int ConvertMpqHeaderToFormat4(
                     assert(pHeader->BlockTableSize64 <= (pHeader->dwBlockTableSize * sizeof(TMPQBlock)));
 
                     // Determine real archive size
-                    pHeader->ArchiveSize64 = DetermineArchiveSize_V2(pHeader, MpqOffset, FileSize);
+                    pHeader->ArchiveSize64 = DetermineArchiveSize_V2(pHeader, ByteOffset, FileSize);
 
                     // Calculate the size of the hi-block table
                     pHeader->HiBlockTableSize64 = pHeader->ArchiveSize64 - pHeader->HiBlockTablePos64;
@@ -456,7 +563,7 @@ int ConvertMpqHeaderToFormat4(
                 else
                 {
                     // Determine real archive size
-                    pHeader->ArchiveSize64 = DetermineArchiveSize_V2(pHeader, MpqOffset, FileSize);
+                    pHeader->ArchiveSize64 = DetermineArchiveSize_V2(pHeader, ByteOffset, FileSize);
 
                     // Calculate size of the block table
                     pHeader->BlockTableSize64 = pHeader->ArchiveSize64 - BlockTablePos64;
@@ -470,7 +577,7 @@ int ConvertMpqHeaderToFormat4(
             }
 
             // Add the MPQ Offset
-            BlockTablePos64 += MpqOffset;
+            BlockTablePos64 += ByteOffset;
             break;
 
         case MPQ_FORMAT_VERSION_3:
@@ -499,45 +606,45 @@ int ConvertMpqHeaderToFormat4(
             memset((LPBYTE)pHeader + MPQ_HEADER_SIZE_V3, 0, sizeof(TMPQHeader) - MPQ_HEADER_SIZE_V3);
             BlockTablePos64 = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
             HashTablePos64 = MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos);
-            ByteOffset = pHeader->ArchiveSize64;
+            MaxOffset = pHeader->ArchiveSize64;
 
             // Size of the hi-block table
             if(pHeader->HiBlockTablePos64)
             {
-                pHeader->HiBlockTableSize64 = ByteOffset - pHeader->HiBlockTablePos64;
-                ByteOffset = pHeader->HiBlockTablePos64;
+                pHeader->HiBlockTableSize64 = MaxOffset - pHeader->HiBlockTablePos64;
+                MaxOffset = pHeader->HiBlockTablePos64;
             }
 
             // Size of the block table
             if(BlockTablePos64)
             {
-                pHeader->BlockTableSize64 = ByteOffset - BlockTablePos64;
-                ByteOffset = BlockTablePos64;
+                pHeader->BlockTableSize64 = MaxOffset - BlockTablePos64;
+                MaxOffset = BlockTablePos64;
             }
 
             // Size of the hash table
             if(HashTablePos64)
             {
-                pHeader->HashTableSize64 = ByteOffset - HashTablePos64;
-                ByteOffset = HashTablePos64;
+                pHeader->HashTableSize64 = MaxOffset - HashTablePos64;
+                MaxOffset = HashTablePos64;
             }
 
             // Size of the BET table
             if(pHeader->BetTablePos64)
             {
-                pHeader->BetTableSize64 = ByteOffset - pHeader->BetTablePos64;
-                ByteOffset = pHeader->BetTablePos64;
+                pHeader->BetTableSize64 = MaxOffset - pHeader->BetTablePos64;
+                MaxOffset = pHeader->BetTablePos64;
             }
 
             // Size of the HET table
             if(pHeader->HetTablePos64)
             {
-                pHeader->HetTableSize64 = ByteOffset - pHeader->HetTablePos64;
-//              ByteOffset = pHeader->HetTablePos64;
+                pHeader->HetTableSize64 = MaxOffset - pHeader->HetTablePos64;
+//              MaxOffset = pHeader->HetTablePos64;
             }
-            
+
             // Add the MPQ Offset
-            BlockTablePos64 += MpqOffset;
+            BlockTablePos64 += ByteOffset;
             break;
 
         case MPQ_FORMAT_VERSION_4:
@@ -545,11 +652,52 @@ int ConvertMpqHeaderToFormat4(
             // Verify header MD5. Header MD5 is calculated from the MPQ header since the 'MPQ\x1A'
             // signature until the position of header MD5 at offset 0xC0
             BSWAP_TMPQHEADER(pHeader, MPQ_FORMAT_VERSION_4);
+
+            // Apparently, Starcraft II only accepts MPQ headers where the MPQ header hash matches
+            // If MD5 doesn't match, we ignore this offset. We also ignore it if there's no MD5 at all
+            if(!IsValidMD5(pHeader->MD5_MpqHeader))
+                return ERROR_FAKE_MPQ_HEADER;
             if(!VerifyDataBlockHash(pHeader, MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE, pHeader->MD5_MpqHeader))
-                nError = ERROR_FILE_CORRUPT;
+                return ERROR_FAKE_MPQ_HEADER;
+
+            // HiBlockTable must be 0 for archives under 4GB
+            if((pHeader->ArchiveSize64 >> 0x20) == 0 && pHeader->HiBlockTablePos64 != 0)
+                return ERROR_FAKE_MPQ_HEADER;
+
+            // Is the "HET&BET" table tandem OK?
+            bHetBetOffsetOK = VerifyTableTandemPositions(ByteOffset,
+                                                         pHeader->HetTablePos64, pHeader->HetTableSize64,
+                                                         pHeader->BetTablePos64, pHeader->BetTableSize64,
+                                                         FileSize);
+
+            // Is the "Hash&Block" table tandem OK?
+            bHashBlockOffsetOK = VerifyTableTandemPositions(ByteOffset,
+                                                            pHeader->dwHashTablePos, pHeader->HashTableSize64,
+                                                            pHeader->dwBlockTablePos, pHeader->BlockTableSize64,
+                                                            FileSize);
+
+            // At least one pair must be OK
+            if(bHetBetOffsetOK == false && bHashBlockOffsetOK == false)
+                return ERROR_FAKE_MPQ_HEADER;
+
+            // Check for malformed MPQs
+            if(pHeader->wFormatVersion != MPQ_FORMAT_VERSION_4 || (ByteOffset + pHeader->ArchiveSize64) != FileSize || (ByteOffset + pHeader->HiBlockTablePos64) >= FileSize)
+            {
+                pHeader->wFormatVersion = MPQ_FORMAT_VERSION_4;
+                pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V4;
+                ha->dwFlags |= MPQ_FLAG_MALFORMED;
+            }
+
+            // Recalculate archive size
+            if(ha->dwFlags & MPQ_FLAG_MALFORMED)
+            {
+                // Calculate the archive size
+                pHeader->ArchiveSize64 = DetermineArchiveSize_V4(pHeader, ByteOffset, FileSize);
+                pHeader->dwArchiveSize = (DWORD)pHeader->ArchiveSize64;
+            }
 
             // Calculate the block table position
-            BlockTablePos64 = MpqOffset + MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
+            BlockTablePos64 = ByteOffset + MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
             break;
 
         default:
@@ -565,13 +713,13 @@ int ConvertMpqHeaderToFormat4(
             }
 
             // Calculate the block table position
-            BlockTablePos64 = MpqOffset + MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
+            BlockTablePos64 = ByteOffset + MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
             break;
     }
 
     // Handle case when block table is placed before the MPQ header
     // Used by BOBA protector
-    if(BlockTablePos64 < MpqOffset)
+    if(BlockTablePos64 < ByteOffset)
         ha->dwFlags |= MPQ_FLAG_MALFORMED;
     return nError;
 }
@@ -583,14 +731,14 @@ int ConvertMpqHeaderToFormat4(
 bool IsValidHashEntry(TMPQArchive * ha, TMPQHash * pHash)
 {
     TFileEntry * pFileEntry = ha->pFileTable + MPQ_BLOCK_INDEX(pHash);
-    
+
     return ((MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize) && (pFileEntry->dwFlags & MPQ_FILE_EXISTS)) ? true : false;
 }
 
 // Hash entry verification when the file table does not exist yet
 static bool IsValidHashEntry1(TMPQArchive * ha, TMPQHash * pHash, TMPQBlock * pBlockTable)
 {
-    ULONGLONG ByteOffset;    
+    ULONGLONG ByteOffset;
     TMPQBlock * pBlock;
 
     // The block index is considered valid if it's less than block table size
@@ -644,7 +792,7 @@ static TMPQHash * GetHashEntryLocale(TMPQArchive * ha, const char * szFileName,
         }
 
         // Get the next hash entry for that file
-        pHash = GetNextHashEntry(ha, pFirstHash, pHash); 
+        pHash = GetNextHashEntry(ha, pFirstHash, pHash);
     }
 
     // At the end, return neutral hash (if found), otherwise NULL
@@ -665,9 +813,9 @@ static TMPQHash * GetHashEntryExact(TMPQArchive * ha, const char * szFileName, L
         // If the locales match, return it
         if(pHash->lcLocale == lcLocale)
             return pHash;
-        
+
         // Get the next hash entry for that file
-        pHash = GetNextHashEntry(ha, pFirstHash, pHash); 
+        pHash = GetNextHashEntry(ha, pFirstHash, pHash);
     }
 
     // Not found
@@ -1235,7 +1383,7 @@ TMPQHetTable * CreateHetTable(DWORD dwEntryCount, DWORD dwTotalCount, DWORD dwNa
             memset(pHetTable->pNameHashes, 0, dwTotalCount);
 
             // Allocate the bit array for file indexes
-            pHetTable->pBetIndexes = CreateBitArray(dwTotalCount * pHetTable->dwIndexSizeTotal, 0xFF);
+            pHetTable->pBetIndexes = TMPQBits::Create(dwTotalCount * pHetTable->dwIndexSizeTotal, 0xFF);
             if(pHetTable->pBetIndexes != NULL)
             {
                 // Initialize the HET table from the source data (if given)
@@ -1247,7 +1395,7 @@ TMPQHetTable * CreateHetTable(DWORD dwEntryCount, DWORD dwTotalCount, DWORD dwNa
                     // Copy the file indexes
                     memcpy(pHetTable->pBetIndexes->Elements, pbSrcData + dwTotalCount, pHetTable->pBetIndexes->NumberOfBytes);
                 }
-                
+
                 // Return the result HET table
                 return pHetTable;
             }
@@ -1283,7 +1431,7 @@ static int InsertHetEntry(TMPQHetTable * pHetTable, ULONGLONG FileNameHash, DWOR
             pHetTable->pNameHashes[Index] = NameHash1;
 
             // Set the entry in the file index table
-            SetBits(pHetTable->pBetIndexes, pHetTable->dwIndexSizeTotal * Index,
+            pHetTable->pBetIndexes->SetBits(pHetTable->dwIndexSizeTotal * Index,
                                             pHetTable->dwIndexSize,
                                            &dwFileIndex,
                                             4);
@@ -1316,7 +1464,7 @@ static TMPQHetTable * TranslateHetTable(TMPQHetHeader * pHetHeader)
     if(pHetHeader->ExtHdr.dwDataSize >= (sizeof(TMPQHetHeader) - sizeof(TMPQExtHeader)))
     {
         // Verify the size of the table in the header
-        if(pHetHeader->dwTableSize == pHetHeader->ExtHdr.dwDataSize)
+        if(pHetHeader->ExtHdr.dwDataSize >= pHetHeader->dwTableSize)
         {
             // The size of the HET table must be sum of header, hash and index table size
             assert((sizeof(TMPQHetHeader) - sizeof(TMPQExtHeader) + pHetHeader->dwTotalCount + pHetHeader->dwIndexTableSize) == pHetHeader->dwTableSize);
@@ -1331,7 +1479,7 @@ static TMPQHetTable * TranslateHetTable(TMPQHetHeader * pHetHeader)
             // The size of index table (in entries) is expected
             // to be the same like the hash table size (in bytes)
             assert(((pHetHeader->dwTotalCount * pHetHeader->dwIndexSizeTotal) + 7) / 8 == pHetHeader->dwIndexTableSize);
-            
+
             // Create translated table
             pHetTable = CreateHetTable(pHetHeader->dwEntryCount, pHetHeader->dwTotalCount, pHetHeader->dwNameHashBitSize, pbSrcData);
             if(pHetTable != NULL)
@@ -1425,7 +1573,7 @@ static DWORD GetFileIndex_Het(TMPQArchive * ha, const char * szFileName)
             DWORD dwFileIndex = 0;
 
             // Get the file index
-            GetBits(pHetTable->pBetIndexes, pHetTable->dwIndexSizeTotal * Index,
+            pHetTable->pBetIndexes->GetBits(pHetTable->dwIndexSizeTotal * Index,
                                             pHetTable->dwIndexSize,
                                            &dwFileIndex,
                                             sizeof(DWORD));
@@ -1586,10 +1734,11 @@ static TMPQBetTable * TranslateBetTable(
     if(pBetHeader->ExtHdr.dwDataSize >= (sizeof(TMPQBetHeader) - sizeof(TMPQExtHeader)))
     {
         // Verify the size of the table in the header
-        if(pBetHeader->dwTableSize == pBetHeader->ExtHdr.dwDataSize)
+        if(pBetHeader->ExtHdr.dwDataSize >= pBetHeader->dwTableSize)
         {
             // The number of entries in the BET table must be the same like number of entries in the block table
-            assert(pBetHeader->dwEntryCount == ha->pHeader->dwBlockTableSize);
+            // Note: Ignored if there is no block table
+            //assert(pBetHeader->dwEntryCount == ha->pHeader->dwBlockTableSize);
             assert(pBetHeader->dwEntryCount <= ha->dwMaxFileCount);
 
             // The number of entries in the BET table must be the same like number of entries in the HET table
@@ -1634,7 +1783,7 @@ static TMPQBetTable * TranslateBetTable(
                 }
 
                 // Load the bit-based file table
-                pBetTable->pFileTable = CreateBitArray(pBetTable->dwTableEntrySize * pBetHeader->dwEntryCount, 0);
+                pBetTable->pFileTable = TMPQBits::Create(pBetTable->dwTableEntrySize * pBetHeader->dwEntryCount, 0);
                 if(pBetTable->pFileTable != NULL)
                 {
                     LengthInBytes = (pBetTable->pFileTable->NumberOfBits + 7) / 8;
@@ -1646,9 +1795,9 @@ static TMPQBetTable * TranslateBetTable(
                 pBetTable->dwBitTotal_NameHash2 = pBetHeader->dwBitTotal_NameHash2;
                 pBetTable->dwBitExtra_NameHash2 = pBetHeader->dwBitExtra_NameHash2;
                 pBetTable->dwBitCount_NameHash2 = pBetHeader->dwBitCount_NameHash2;
-                
+
                 // Create and load the array of BET hashes
-                pBetTable->pNameHashes = CreateBitArray(pBetTable->dwBitTotal_NameHash2 * pBetHeader->dwEntryCount, 0);
+                pBetTable->pNameHashes = TMPQBits::Create(pBetTable->dwBitTotal_NameHash2 * pBetHeader->dwEntryCount, 0);
                 if(pBetTable->pNameHashes != NULL)
                 {
                     LengthInBytes = (pBetTable->pNameHashes->NumberOfBits + 7) / 8;
@@ -1673,7 +1822,7 @@ TMPQExtHeader * TranslateBetTable(
     TMPQBetHeader BetHeader;
     TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
     TFileEntry * pFileEntry;
-    TBitArray * pBitArray = NULL;
+    TMPQBits * pBitArray = NULL;
     LPBYTE pbLinearTable = NULL;
     LPBYTE pbTrgData;
     DWORD LengthInBytes;
@@ -1693,7 +1842,7 @@ TMPQExtHeader * TranslateBetTable(
         pbTrgData = (LPBYTE)(pBetHeader + 1);
 
         // Save the bit-based block table
-        pBitArray = CreateBitArray(BetHeader.dwEntryCount * BetHeader.dwTableEntrySize, 0);
+        pBitArray = TMPQBits::Create(BetHeader.dwEntryCount * BetHeader.dwTableEntrySize, 0);
         if(pBitArray != NULL)
         {
             DWORD dwFlagIndex = 0;
@@ -1708,22 +1857,22 @@ TMPQExtHeader * TranslateBetTable(
                 //
 
                 // Save the byte offset
-                SetBits(pBitArray, nBitOffset + BetHeader.dwBitIndex_FilePos,
+                pBitArray->SetBits(nBitOffset + BetHeader.dwBitIndex_FilePos,
                                    BetHeader.dwBitCount_FilePos,
                                   &pFileEntry->ByteOffset,
                                    8);
-                SetBits(pBitArray, nBitOffset + BetHeader.dwBitIndex_FileSize,
+                pBitArray->SetBits(nBitOffset + BetHeader.dwBitIndex_FileSize,
                                    BetHeader.dwBitCount_FileSize,
                                   &pFileEntry->dwFileSize,
                                    4);
-                SetBits(pBitArray, nBitOffset + BetHeader.dwBitIndex_CmpSize,
+                pBitArray->SetBits(nBitOffset + BetHeader.dwBitIndex_CmpSize,
                                    BetHeader.dwBitCount_CmpSize,
                                   &pFileEntry->dwCmpSize,
                                    4);
 
                 // Save the flag index
                 dwFlagIndex = GetFileFlagIndex(FlagArray, pFileEntry->dwFlags);
-                SetBits(pBitArray, nBitOffset + BetHeader.dwBitIndex_FlagIndex,
+                pBitArray->SetBits(nBitOffset + BetHeader.dwBitIndex_FlagIndex,
                                    BetHeader.dwBitCount_FlagIndex,
                                   &dwFlagIndex,
                                    4);
@@ -1748,7 +1897,7 @@ TMPQExtHeader * TranslateBetTable(
         }
 
         // Create bit array for name hashes
-        pBitArray = CreateBitArray(BetHeader.dwBitTotal_NameHash2 * BetHeader.dwEntryCount, 0);
+        pBitArray = TMPQBits::Create(BetHeader.dwBitTotal_NameHash2 * BetHeader.dwEntryCount, 0);
         if(pBitArray != NULL)
         {
             DWORD dwFileIndex = 0;
@@ -1756,11 +1905,11 @@ TMPQExtHeader * TranslateBetTable(
             for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
             {
                 // Insert the name hash to the bit array
-                SetBits(pBitArray, BetHeader.dwBitTotal_NameHash2 * dwFileIndex,
+                pBitArray->SetBits(BetHeader.dwBitTotal_NameHash2 * dwFileIndex,
                                    BetHeader.dwBitCount_NameHash2,
                                   &pFileEntry->FileNameHash,
                                    8);
-                
+
                 assert(dwFileIndex < BetHeader.dwEntryCount);
                 dwFileIndex++;
             }
@@ -1868,7 +2017,7 @@ TFileEntry * GetFileEntryExact(TMPQArchive * ha, const char * szFileName, LCID l
             return ha->pFileTable + dwFileIndex;
         }
     }
-   
+
     // Not found
     return NULL;
 }
@@ -1930,7 +2079,7 @@ TFileEntry * AllocateFileEntry(TMPQArchive * ha, const char * szFileName, LCID l
             if(pFreeEntry == NULL)
                 pFreeEntry = pFileEntry;
             dwFreeCount++;
-            
+
             // If the number of free items is greater than number
             // of reserved items, We can add the file
             if(dwFreeCount > dwReservedFiles)
@@ -2058,13 +2207,13 @@ int DeleteFileEntry(TMPQArchive * ha, TMPQFile * hf)
 
     pFileEntry->dwFlags &= ~MPQ_FILE_EXISTS;
     pFileEntry->FileNameHash = 0;
-    return ERROR_SUCCESS;    
+    return ERROR_SUCCESS;
 }
 
-DWORD InvalidateInternalFile(TMPQArchive * ha, const char * szFileName, DWORD dwFlagNone, DWORD dwFlagNew)
+DWORD InvalidateInternalFile(TMPQArchive * ha, const char * szFileName, DWORD dwFlagNone, DWORD dwFlagNew, DWORD dwForceAddTheFile = 0)
 {
     TMPQFile * hf = NULL;
-    DWORD dwFileFlags = 0;
+    DWORD dwFileFlags = MPQ_FILE_DEFAULT_INTERNAL;
     int nError = ERROR_FILE_NOT_FOUND;
 
     // Open the file from the MPQ
@@ -2076,17 +2225,25 @@ DWORD InvalidateInternalFile(TMPQArchive * ha, const char * szFileName, DWORD dw
         // Delete the file entry
         nError = DeleteFileEntry(ha, hf);
         if(nError == ERROR_SUCCESS)
-        {
-            ha->dwFlags |= dwFlagNew;
-            ha->dwReservedFiles++;
-        }
+            dwForceAddTheFile = 1;
 
-        // Free the file entry
+        // Close the file
         FreeFileHandle(hf);
     }
 
-    // If the deletion failed, set the "none" flag
-    ha->dwFlags |= (nError != ERROR_SUCCESS) ? dwFlagNone : 0;
+    // Are we going to add the file?
+    if(dwForceAddTheFile)
+    {
+        ha->dwFlags |= dwFlagNew;
+        ha->dwReservedFiles++;
+    }
+    else
+    {
+        ha->dwFlags |= dwFlagNone;
+        dwFileFlags = 0;
+    }
+
+    // Return the intended file flags
     return dwFileFlags;
 }
 
@@ -2097,14 +2254,14 @@ void InvalidateInternalFiles(TMPQArchive * ha)
     {
         //
         // We clear the file entries for (listfile), (attributes) and (signature)
-        // For each internal file cleared, we increment the number 
+        // For each internal file cleared, we increment the number
         // of reserved entries in the file table.
         //
 
         // Invalidate the (listfile), if not done yet
         if((ha->dwFlags & (MPQ_FLAG_LISTFILE_NONE | MPQ_FLAG_LISTFILE_NEW)) == 0)
         {
-            ha->dwFileFlags1 = InvalidateInternalFile(ha, LISTFILE_NAME, MPQ_FLAG_LISTFILE_NONE, MPQ_FLAG_LISTFILE_NEW);
+            ha->dwFileFlags1 = InvalidateInternalFile(ha, LISTFILE_NAME, MPQ_FLAG_LISTFILE_NONE, MPQ_FLAG_LISTFILE_NEW, (ha->dwFlags & MPQ_FLAG_LISTFILE_FORCE));
         }
 
         // Invalidate the (attributes), if not done yet
@@ -2181,7 +2338,7 @@ static TMPQHash * LoadHashTable(TMPQArchive * ha)
             dwCmpSize = (DWORD)pHeader->HashTableSize64;
 
             // Read, decrypt and uncompress the hash table
-            pHashTable = (TMPQHash *)LoadMpqTable(ha, ByteOffset, dwCmpSize, dwTableSize, MPQ_KEY_HASH_TABLE, &bHashTableIsCut);
+            pHashTable = (TMPQHash *)LoadMpqTable(ha, ByteOffset, pHeader->MD5_HashTable, dwCmpSize, dwTableSize, g_dwHashTableKey, &bHashTableIsCut);
 //          DumpHashTable(pHashTable, pHeader->dwHashTableSize);
 
             // If the hash table was cut, we can/have to defragment it
@@ -2198,7 +2355,7 @@ static TMPQHash * LoadHashTable(TMPQArchive * ha)
             break;
     }
 
-    // Remember the size of the hash table
+    // Return the loaded hash table
     return pHashTable;
 }
 
@@ -2242,8 +2399,8 @@ TMPQBlock * LoadBlockTable(TMPQArchive * ha, bool /* bDontFixEntries */)
             dwCmpSize = (DWORD)pHeader->BlockTableSize64;
 
             // Read, decrypt and uncompress the block table
-            pBlockTable = (TMPQBlock * )LoadMpqTable(ha, ByteOffset, dwCmpSize, dwTableSize, MPQ_KEY_BLOCK_TABLE, &bBlockTableIsCut);
-           
+            pBlockTable = (TMPQBlock * )LoadMpqTable(ha, ByteOffset, NULL, dwCmpSize, dwTableSize, g_dwBlockTableKey, &bBlockTableIsCut);
+
             // If the block table was cut, we need to remember it
             if(pBlockTable != NULL && bBlockTableIsCut)
                 ha->dwFlags |= (MPQ_FLAG_MALFORMED | MPQ_FLAG_BLOCK_TABLE_CUT);
@@ -2270,7 +2427,7 @@ TMPQHetTable * LoadHetTable(TMPQArchive * ha)
     TMPQHeader * pHeader = ha->pHeader;
 
     // If the HET table position is not 0, we expect the table to be present
-    if(pHeader->HetTablePos64 != 0 && pHeader->HetTableSize64 != 0)
+    if(pHeader->HetTablePos64 && pHeader->HetTableSize64)
     {
         // Attempt to load the HET table (Hash Extended Table)
         pExtTable = LoadExtTable(ha, pHeader->HetTablePos64, (size_t)pHeader->HetTableSize64, HET_TABLE_SIGNATURE, MPQ_KEY_HASH_TABLE);
@@ -2292,7 +2449,7 @@ TMPQBetTable * LoadBetTable(TMPQArchive * ha)
     TMPQHeader * pHeader = ha->pHeader;
 
     // If the BET table position is not 0, we expect the table to be present
-    if(pHeader->BetTablePos64 != 0 && pHeader->BetTableSize64 != 0)
+    if(pHeader->BetTablePos64 && pHeader->BetTableSize64)
     {
         // Attempt to load the HET table (Hash Extended Table)
         pExtTable = LoadExtTable(ha, pHeader->BetTablePos64, (size_t)pHeader->BetTableSize64, BET_TABLE_SIGNATURE, MPQ_KEY_BLOCK_TABLE);
@@ -2321,6 +2478,8 @@ int LoadAnyHashTable(TMPQArchive * ha)
         ha->pHetTable = LoadHetTable(ha);
 
     // Try to load classic hash table
+    // Note that we load the classic hash table even when HET table exists,
+    // because if the MPQ gets modified and saved, hash table must be there
     if(pHeader->dwHashTableSize)
         ha->pHashTable = LoadHashTable(ha);
 
@@ -2410,7 +2569,7 @@ static int BuildFileTable_HetBet(TMPQArchive * ha)
     TMPQHetTable * pHetTable = ha->pHetTable;
     TMPQBetTable * pBetTable;
     TFileEntry * pFileEntry = ha->pFileTable;
-    TBitArray * pBitArray;
+    TMPQBits * pBitArray;
     DWORD dwBitPosition = 0;
     DWORD i;
     int nError = ERROR_FILE_CORRUPT;
@@ -2426,7 +2585,7 @@ static int BuildFileTable_HetBet(TMPQArchive * ha)
             FreeBetTable(pBetTable);
             return ERROR_FILE_CORRUPT;
         }
-        
+
         // Step one: Fill the name indexes
         for(i = 0; i < pHetTable->dwTotalCount; i++)
         {
@@ -2436,7 +2595,7 @@ static int BuildFileTable_HetBet(TMPQArchive * ha)
             if(pHetTable->pNameHashes[i] != HET_ENTRY_FREE)
             {
                 // Load the index to the BET table
-                GetBits(pHetTable->pBetIndexes, pHetTable->dwIndexSizeTotal * i,
+                pHetTable->pBetIndexes->GetBits(pHetTable->dwIndexSizeTotal * i,
                                                 pHetTable->dwIndexSize,
                                                &dwFileIndex,
                                                 4);
@@ -2447,7 +2606,7 @@ static int BuildFileTable_HetBet(TMPQArchive * ha)
                     ULONGLONG NameHash2 = 0;
 
                     // Load the BET hash
-                    GetBits(pBetTable->pNameHashes, pBetTable->dwBitTotal_NameHash2 * dwFileIndex,
+                    pBetTable->pNameHashes->GetBits(pBetTable->dwBitTotal_NameHash2 * dwFileIndex,
                                                     pBetTable->dwBitCount_NameHash2,
                                                    &NameHash2,
                                                     8);
@@ -2461,25 +2620,25 @@ static int BuildFileTable_HetBet(TMPQArchive * ha)
 
         // Go through the entire BET table and convert it to the file table.
         pFileEntry = ha->pFileTable;
-        pBitArray = pBetTable->pFileTable; 
+        pBitArray = pBetTable->pFileTable;
         for(i = 0; i < pBetTable->dwEntryCount; i++)
         {
             DWORD dwFlagIndex = 0;
 
             // Read the file position
-            GetBits(pBitArray, dwBitPosition + pBetTable->dwBitIndex_FilePos,
+            pBitArray->GetBits(dwBitPosition + pBetTable->dwBitIndex_FilePos,
                                pBetTable->dwBitCount_FilePos,
                               &pFileEntry->ByteOffset,
                                8);
 
             // Read the file size
-            GetBits(pBitArray, dwBitPosition + pBetTable->dwBitIndex_FileSize,
+            pBitArray->GetBits(dwBitPosition + pBetTable->dwBitIndex_FileSize,
                                pBetTable->dwBitCount_FileSize,
                               &pFileEntry->dwFileSize,
                                4);
 
             // Read the compressed size
-            GetBits(pBitArray, dwBitPosition + pBetTable->dwBitIndex_CmpSize,
+            pBitArray->GetBits(dwBitPosition + pBetTable->dwBitIndex_CmpSize,
                                pBetTable->dwBitCount_CmpSize,
                               &pFileEntry->dwCmpSize,
                                4);
@@ -2488,7 +2647,7 @@ static int BuildFileTable_HetBet(TMPQArchive * ha)
             // Read the flag index
             if(pBetTable->dwFlagCount != 0)
             {
-                GetBits(pBitArray, dwBitPosition + pBetTable->dwBitIndex_FlagIndex,
+                pBitArray->GetBits(dwBitPosition + pBetTable->dwBitIndex_FlagIndex,
                                    pBetTable->dwBitCount_FlagIndex,
                                   &dwFlagIndex,
                                    4);
@@ -2572,7 +2731,7 @@ void UpdateBlockTableSize(TMPQArchive * ha)
     // Calculate the number of files
     for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
     {
-        // If the source table entry is valid, 
+        // If the source table entry is valid,
         if(pFileEntry->dwFlags & MPQ_FILE_EXISTS)
             dwBlockTableSize = (DWORD)(pFileEntry - ha->pFileTable) + 1;
     }
@@ -2603,7 +2762,7 @@ int DefragmentFileTable(TMPQArchive * ha)
         // Parse the entire file table and defragment it
         for(; pSource < pFileTableEnd; pSource++)
         {
-            // If the source table entry is valid, 
+            // If the source table entry is valid,
             if(pSource->dwFlags & MPQ_FILE_EXISTS)
             {
                 // Remember the index conversion
@@ -2795,7 +2954,7 @@ int SaveMPQTables(TMPQArchive * ha)
     // We expect this function to be called only when tables have been changed
     assert(ha->dwFlags & MPQ_FLAG_CHANGED);
 
-    // Find the space where the MPQ tables will be saved 
+    // Find the space where the MPQ tables will be saved
     TablePos = FindFreeMpqSpace(ha);
 
     // If the MPQ has HET table, we prepare a ready-to-save version
@@ -2886,7 +3045,7 @@ int SaveMPQTables(TMPQArchive * ha)
         pHeader->HiBlockTableSize64 = HiBlockTableSize64;
         pHeader->HiBlockTablePos64 = TablePos;
         BSWAP_ARRAY16_UNSIGNED(pHiBlockTable, HiBlockTableSize64);
-        
+
         if(!FileStream_Write(ha->pStream, &ByteOffset, pHiBlockTable, (DWORD)HiBlockTableSize64))
             nError = GetLastError();
         TablePos += HiBlockTableSize64;
@@ -2909,7 +3068,7 @@ int SaveMPQTables(TMPQArchive * ha)
         // Update the size of the archive
         pHeader->ArchiveSize64 = TablePos;
         pHeader->dwArchiveSize = (DWORD)TablePos;
-        
+
         // Update the MD5 of the archive header
         CalculateDataBlockHash(pHeader, MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE, pHeader->MD5_MpqHeader);
 
diff --git a/OpenSource/StormLib/src/SBaseSubTypes.cpp b/OpenSource/StormLib/src/SBaseSubTypes.cpp
index 47c205e47..afa7311ef 100644
--- a/OpenSource/StormLib/src/SBaseSubTypes.cpp
+++ b/OpenSource/StormLib/src/SBaseSubTypes.cpp
@@ -21,24 +21,24 @@
 typedef struct _TSQPHeader
 {
     // The ID_MPQ ('MPQ\x1A') signature
-    DWORD dwID;                         
+    DWORD dwID;
 
     // Size of the archive header
-    DWORD dwHeaderSize;                   
+    DWORD dwHeaderSize;
 
     // 32-bit size of MPQ archive
     DWORD dwArchiveSize;
 
     // 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;
 
@@ -66,7 +66,7 @@ typedef struct _TSQPHash
 
     // The hash of the file path, using method A.
     DWORD dwName1;
-    
+
     // The hash of the file path, using method B.
     DWORD dwName2;
 
@@ -76,16 +76,16 @@ typedef struct _TSQPBlock
 {
     // Offset of the beginning of the file, relative to the beginning of the archive.
     DWORD dwFilePos;
-    
+
     // Flags for the file. See MPQ_FILE_XXXX constants
-    DWORD dwFlags;                      
+    DWORD dwFlags;
 
     // Compressed file size
     DWORD dwCSize;
-    
+
     // Uncompressed file size
-    DWORD dwFSize;                      
-    
+    DWORD dwFSize;
+
 } TSQPBlock;
 
 //-----------------------------------------------------------------------------
@@ -131,7 +131,7 @@ int ConvertSqpHeaderToFormat4(
     Header.wSectorSize = BSWAP_INT16_UNSIGNED(pSqpHeader->wSectorSize);
 
     // Verify the SQP header
-    if(Header.dwID == ID_MPQ && Header.dwHeaderSize == sizeof(TSQPHeader) && Header.dwArchiveSize == FileSize)
+    if(Header.dwID == g_dwMpqSignature && Header.dwHeaderSize == sizeof(TSQPHeader) && Header.dwArchiveSize == FileSize)
     {
         // Check for fixed values of version and sector size
         if(Header.wFormatVersion == MPQ_FORMAT_VERSION_1 && Header.wSectorSize == 3)
@@ -143,7 +143,7 @@ int ConvertSqpHeaderToFormat4(
 
             // Copy the converted MPQ header back
             memcpy(ha->HeaderData, &Header, sizeof(TMPQHeader));
-            
+
             // Mark this file as SQP file
             ha->pfnHashString = HashStringSlash;
             ha->dwFlags |= MPQ_FLAG_READ_ONLY;
@@ -292,13 +292,13 @@ typedef struct _TMPKHeader
 {
     // The ID_MPK ('MPK\x1A') signature
     DWORD dwID;
-    
+
     // Contains '2000'
     DWORD dwVersion;
-    
+
     // 32-bit size of the archive
     DWORD dwArchiveSize;
-    
+
     // Size of the archive header
     DWORD dwHeaderSize;
 
@@ -315,7 +315,7 @@ typedef struct _TMPKHash
 {
     // The hash of the file path, using method A.
     DWORD dwName1;
-    
+
     // The hash of the file path, using method B.
     DWORD dwName2;
 
@@ -334,7 +334,7 @@ typedef struct _TMPKHash
 
 typedef struct _TMPKBlock
 {
-    DWORD  dwFlags;         // 0x1121 - Compressed , 0x1120 - Not compressed 
+    DWORD  dwFlags;         // 0x1121 - Compressed , 0x1120 - Not compressed
     DWORD  dwFilePos;       // Offset of the beginning of the file, relative to the beginning of the archive.
     DWORD  dwFSize;         // Uncompressed file size
     DWORD  dwCSize;         // Compressed file size
@@ -414,7 +414,7 @@ int ConvertMpkHeaderToFormat4(
     if(Header.dwID == ID_MPK && Header.dwHeaderSize == sizeof(TMPKHeader) && Header.dwArchiveSize == (DWORD)FileSize)
     {
         // The header ID must be ID_MPQ
-        Header.dwID = ID_MPQ;
+        Header.dwID = g_dwMpqSignature;
         Header.wFormatVersion = MPQ_FORMAT_VERSION_1;
         Header.wSectorSize = 3;
 
diff --git a/OpenSource/StormLib/src/SCompression.cpp b/OpenSource/StormLib/src/SCompression.cpp
index d706a6f37..93f80e104 100644
--- a/OpenSource/StormLib/src/SCompression.cpp
+++ b/OpenSource/StormLib/src/SCompression.cpp
@@ -2,7 +2,7 @@
 /* SCompression.cpp                       Copyright (c) Ladislav Zezula 2003 */
 /*---------------------------------------------------------------------------*/
 /* This module serves as a bridge between StormLib code and (de)compression  */
-/* functions. All (de)compression calls go (and should only go) through this */   
+/* functions. All (de)compression calls go (and should only go) through this */
 /* module. No system headers should be included in this module to prevent    */
 /* compile-time problems.                                                    */
 /*---------------------------------------------------------------------------*/
@@ -45,11 +45,11 @@ typedef int (*DECOMPRESS)(
     void * pvOutBuffer,                 // [out] Pointer to the buffer where to store decompressed data
     int  * pcbOutBuffer,                // [in]  Pointer to total size of the buffer pointed by pvOutBuffer
                                         // [out] Contains length of the decompressed data
-    void * pvInBuffer,                  // [in]  Pointer to data to be decompressed  
+    void * pvInBuffer,                  // [in]  Pointer to data to be decompressed
     int cbInBuffer);                    // [in]  Length of the data to be decompressed
 
 // Table of compression functions
-typedef struct  
+typedef struct
 {
     unsigned long uMask;                // Compression mask
     COMPRESS Compress;                  // Compression function
@@ -76,7 +76,7 @@ void Compress_huff(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, in
 
     STORMLIB_UNUSED(nCmpLevel);
     *pcbOutBuffer = ht.Compress(&os, pvInBuffer, cbInBuffer, *pCmpType);
-}                 
+}
 
 int Decompress_huff(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer)
 {
@@ -144,7 +144,7 @@ void Compress_ZLIB(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, in
     {
         // Call zlib to compress the data
         nResult = deflate(&z, Z_FINISH);
-        
+
         if(nResult == Z_OK || nResult == Z_STREAM_END)
             *pcbOutBuffer = z.total_out;
 
@@ -187,7 +187,7 @@ int Decompress_ZLIB(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, i
 // Function loads data from the input buffer. Used by Pklib's "implode"
 // and "explode" function as user-defined callback
 // Returns number of bytes loaded
-//    
+//
 //   char * buf          - Pointer to a buffer where to store loaded data
 //   unsigned int * size - Max. number of bytes to read
 //   void * param        - Custom pointer, parameter of implode/explode
@@ -201,7 +201,7 @@ static unsigned int ReadInputData(char * buf, unsigned int * size, void * param)
     // Check the case when not enough data available
     if(nToRead > nMaxAvail)
         nToRead = nMaxAvail;
-    
+
     // Load data and increment offsets
     memcpy(buf, pInfo->pbInBuff, nToRead);
     pInfo->pbInBuff += nToRead;
@@ -211,7 +211,7 @@ static unsigned int ReadInputData(char * buf, unsigned int * size, void * param)
 
 // Function for store output data. Used by Pklib's "implode" and "explode"
 // as user-defined callback
-//    
+//
 //   char * buf          - Pointer to data to be written
 //   unsigned int * size - Number of bytes to write
 //   void * param        - Custom pointer, parameter of implode/explode
@@ -293,7 +293,7 @@ static int Decompress_PKLIB(void * pvOutBuffer, int * pcbOutBuffer, void * pvInB
 
     // Do the decompression
     explode(ReadInputData, WriteOutputData, work_buf, &Info);
-    
+
     // If PKLIB is unable to decompress the data, return 0;
     if(Info.pbOutBuff == pvOutBuffer)
     {
@@ -376,8 +376,8 @@ static int Decompress_BZIP2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInB
         while(nResult != BZ_STREAM_END)
         {
             nResult = BZ2_bzDecompress(&strm);
-            
-            // If any error there, break the loop 
+
+            // If any error there, break the loop
             if(nResult < BZ_OK)
                 break;
         }
@@ -510,7 +510,7 @@ static int Decompress_LZMA(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBu
     SRes nResult;
 
     // There must be at least 0x0E bytes in the buffer
-    if(srcLen <= LZMA_HEADER_SIZE) 
+    if(srcLen <= LZMA_HEADER_SIZE)
         return 0;
 
     // We only accept blocks that have no filter used
@@ -527,7 +527,7 @@ static int Decompress_LZMA(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBu
                         &destLen,
                          srcBuffer + LZMA_HEADER_SIZE,
                         &srcLen,
-                         srcBuffer + 1, 
+                         srcBuffer + 1,
                          LZMA_PROPS_SIZE,
                          LZMA_FINISH_END,
                         &LzmaStatus,
@@ -568,7 +568,7 @@ static int Decompress_LZMA_MPK(void * pvOutBuffer, int * pcbOutBuffer, void * pv
                         &destLen,
                          srcBuffer + sizeof(LZMA_Props),
                         &srcLen,
-                         srcBuffer, 
+                         srcBuffer,
                          sizeof(LZMA_Props),
                          LZMA_FINISH_END,
                         &LzmaStatus,
@@ -728,7 +728,7 @@ int WINAPI SCompExplode(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffe
         memcpy(pvOutBuffer, pvInBuffer, cbInBuffer);
         return 1;
     }
-    
+
     // Perform decompression
     if(!Decompress_PKLIB(pvOutBuffer, &cbOutBuffer, pvInBuffer, cbInBuffer))
     {
@@ -992,7 +992,7 @@ int WINAPI SCompDecompress(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBu
             // Get the correct output buffer
             pbOutput = (nCompressIndex & 1) ? pbWorkBuffer : pbOutBuffer;
             nCompressIndex--;
-        
+
             // Perform the decompression
             cbOutBuffer = *pcbOutBuffer;
             nResult = dcmp_table[i].Decompress(pbOutput, &cbOutBuffer, pbInput, cbInLength);
@@ -1140,6 +1140,6 @@ int WINAPI SCompDecompress2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInB
 
 int SCompDecompressMpk(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer)
 {
-    return Decompress_LZMA_MPK(pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer);    
+    return Decompress_LZMA_MPK(pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer);
 }
 
diff --git a/OpenSource/StormLib/src/SFileAddFile.cpp b/OpenSource/StormLib/src/SFileAddFile.cpp
index 4572d89b8..63a00088d 100644
--- a/OpenSource/StormLib/src/SFileAddFile.cpp
+++ b/OpenSource/StormLib/src/SFileAddFile.cpp
@@ -36,8 +36,8 @@ typedef struct _WAVE_FILE_HEADER
     DWORD dwChunkId;                        // 0x52494646 ("RIFF")
     DWORD dwChunkSize;                      // Size of that chunk, in bytes
     DWORD dwFormat;                         // Must be 0x57415645 ("WAVE")
-   
-    // Format sub-chunk 
+
+    // Format sub-chunk
     DWORD dwSubChunk1Id;                    // 0x666d7420 ("fmt ")
     DWORD dwSubChunk1Size;                  // 0x16 for PCM
     USHORT wAudioFormat;                    // 1 = PCM. Other value means some sort of compression
@@ -150,11 +150,11 @@ static int WriteDataToMpqFile(
         DWORD dwSectorIndex = hf->dwFilePos / hf->dwSectorSize;
         DWORD dwBytesToCopy;
 
-        // Process all data. 
+        // Process all data.
         while(dwDataSize != 0)
         {
             dwBytesToCopy = dwDataSize;
-                
+
             // Check for sector overflow
             if(dwBytesToCopy > (hf->dwSectorSize - dwBytesInSector))
                 dwBytesToCopy = (hf->dwSectorSize - dwBytesInSector);
@@ -214,7 +214,7 @@ static int WriteDataToMpqFile(
                         // by the first sector compression. This is because the entire sector must
                         // be compressed by the same compression.
                         //
-                        // Test case:                        
+                        // Test case:
                         //
                         // WRITE_FILE(hFile, pvBuffer, 0x10, MPQ_COMPRESSION_PKWARE)       // Write 0x10 bytes (sector 0)
                         // WRITE_FILE(hFile, pvBuffer, 0x10, MPQ_COMPRESSION_ADPCM_MONO)   // Write 0x10 bytes (still sector 0)
@@ -236,7 +236,7 @@ static int WriteDataToMpqFile(
                     // We have to calculate sector CRC, if enabled
                     if(hf->SectorChksums != NULL)
                         hf->SectorChksums[dwSectorIndex] = adler32(0, pbCompressed, nOutBuffer);
-                }                 
+                }
 
                 // Encrypt the sector, if necessary
                 if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
@@ -370,7 +370,7 @@ static int RecryptFileData(
             }
 
             // If necessary, re-encrypt the sector
-            // Note: Recompression is not necessary here. Unlike encryption, 
+            // Note: Recompression is not necessary here. Unlike encryption,
             // the compression does not depend on the position of the file in MPQ.
             BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector);
             DecryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwOldKey + dwSector);
@@ -422,7 +422,7 @@ int SFileAddFile_Init(
     // Sector CRC is not allowed if the file is not compressed
     if(!(dwFlags & MPQ_FILE_COMPRESS_MASK))
         dwFlags &= ~MPQ_FILE_SECTOR_CRC;
-    
+
     // Fix Key is not allowed if the file is not enrypted
     if(!(dwFlags & MPQ_FILE_ENCRYPTED))
         dwFlags &= ~MPQ_FILE_FIX_KEY;
@@ -456,7 +456,7 @@ int SFileAddFile_Init(
             if(pFileEntry != NULL)
                 InvalidateInternalFiles(ha);
             else
-                nError = ERROR_DISK_FULL;   
+                nError = ERROR_DISK_FULL;
         }
 
         // Set the file entry to the file structure
@@ -592,7 +592,7 @@ int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD d
         if(hf->pPatchInfo == NULL && IsIncrementalPatchFile(pvData, dwSize, &hf->dwPatchedFileSize))
         {
             // Set the MPQ_FILE_PATCH_FILE flag
-            hf->pFileEntry->dwFlags |= MPQ_FILE_PATCH_FILE;
+            pFileEntry->dwFlags |= MPQ_FILE_PATCH_FILE;
 
             // Allocate the patch info
             hf->nAddFileError = nError = AllocatePatchInfo(hf, false);
@@ -621,7 +621,7 @@ int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD d
         {
             if(!FileStream_Write(ha->pStream, &RawFilePos, hf->pPatchInfo, hf->pPatchInfo->dwLength))
                 nError = GetLastError();
-  
+
             pFileEntry->dwCmpSize += hf->pPatchInfo->dwLength;
             RawFilePos += hf->pPatchInfo->dwLength;
         }
@@ -659,10 +659,10 @@ int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD d
         if(hf->dwFilePos >= pFileEntry->dwFileSize)
         {
             // Finish calculating CRC32
-            hf->pFileEntry->dwCrc32 = hf->dwCrc32;
+            pFileEntry->dwCrc32 = hf->dwCrc32;
 
             // Finish calculating MD5
-            md5_done((hash_state *)hf->hctx, hf->pFileEntry->md5);
+            md5_done((hash_state *)hf->hctx, pFileEntry->md5);
 
             // If we also have sector checksums, write them to the file
             if(hf->SectorChksums != NULL)
@@ -673,9 +673,9 @@ int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD d
             // Now write patch info
             if(hf->pPatchInfo != NULL)
             {
-                memcpy(hf->pPatchInfo->md5, hf->pFileEntry->md5, MD5_DIGEST_SIZE);
-                hf->pPatchInfo->dwDataSize  = hf->pFileEntry->dwFileSize;
-                hf->pFileEntry->dwFileSize = hf->dwPatchedFileSize;
+                memcpy(hf->pPatchInfo->md5, pFileEntry->md5, MD5_DIGEST_SIZE);
+                hf->pPatchInfo->dwDataSize  = pFileEntry->dwFileSize;
+                pFileEntry->dwFileSize = hf->dwPatchedFileSize;
                 nError = WritePatchInfo(hf);
             }
 
@@ -689,13 +689,17 @@ int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD d
             if(ha->pHeader->dwRawChunkSize != 0)
             {
                 nError = WriteMpqDataMD5(ha->pStream,
-                                         ha->MpqPos + hf->pFileEntry->ByteOffset,
+                                         ha->MpqPos + pFileEntry->ByteOffset,
                                          hf->pFileEntry->dwCmpSize,
                                          ha->pHeader->dwRawChunkSize);
             }
         }
     }
 
+    // Update the archive size
+    if((ha->MpqPos + pFileEntry->ByteOffset + pFileEntry->dwCmpSize) > ha->FileSize)
+        ha->FileSize = ha->MpqPos + pFileEntry->ByteOffset + pFileEntry->dwCmpSize;
+
     // Store the error code from the Write File operation
     hf->nAddFileError = nError;
     return nError;
@@ -750,7 +754,7 @@ int SFileAddFile_Finish(TMPQFile * hf)
 }
 
 //-----------------------------------------------------------------------------
-// Adds data as file to the archive 
+// Adds data as file to the archive
 
 bool WINAPI SFileCreateFile(
     HANDLE hMpq,
@@ -771,7 +775,7 @@ bool WINAPI SFileCreateFile(
         nError = ERROR_INVALID_PARAMETER;
     if(phFile == NULL)
         nError = ERROR_INVALID_PARAMETER;
-    
+
     // Don't allow to add file if the MPQ is open for read only
     if(nError == ERROR_SUCCESS)
     {
@@ -837,7 +841,7 @@ bool WINAPI SFileWriteFile(
 //
 //      if(dwFlags & MPQ_FILE_ENCRYPTED)
 //          nError = ERROR_INVALID_PARAMETER;
-        
+
         // Lossy compression is not allowed on single unit files
         if(dwCompression & MPQ_LOSSY_COMPRESSION_MASK)
             nError = ERROR_INVALID_PARAMETER;
@@ -847,7 +851,7 @@ bool WINAPI SFileWriteFile(
     // Write the data to the file
     if(nError == ERROR_SUCCESS)
         nError = SFileAddFile_Write(hf, pvData, dwSize, dwCompression);
-    
+
     // Deal with errors
     if(nError != ERROR_SUCCESS)
         SetLastError(nError);
@@ -868,7 +872,7 @@ bool WINAPI SFileFinishFile(HANDLE hFile)
     // Finish the file
     if(nError == ERROR_SUCCESS)
         nError = SFileAddFile_Finish(hf);
-    
+
     // Deal with errors
     if(nError != ERROR_SUCCESS)
         SetLastError(nError);
@@ -876,7 +880,7 @@ bool WINAPI SFileFinishFile(HANDLE hFile)
 }
 
 //-----------------------------------------------------------------------------
-// Adds a file to the archive 
+// Adds a file to the archive
 
 bool WINAPI SFileAddFileEx(
     HANDLE hMpq,
@@ -933,7 +937,7 @@ bool WINAPI SFileAddFileEx(
         // we will copy the compression for the first sector
         if(dwCompressionNext == MPQ_COMPRESSION_NEXT_SAME)
             dwCompressionNext = dwCompression;
-        
+
         // If the caller wants ADPCM compression, we make sure
         // that the first sector is not compressed with lossy compression
         if(dwCompressionNext & (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO))
@@ -942,7 +946,7 @@ bool WINAPI SFileAddFileEx(
             // in order not to corrupt the headers
             if(dwCompression & (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO))
                 dwCompression = MPQ_COMPRESSION_PKWARE;
-            
+
             // Remove both flag mono and stereo flags.
             // They will be re-added according to WAVE type
             dwCompressionNext &= ~(MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO);
@@ -950,7 +954,7 @@ bool WINAPI SFileAddFileEx(
         }
 
         // Initiate adding file to the MPQ
-        if(!SFileCreateFile(hMpq, szArchivedName, FileTime, (DWORD)FileSize, lcFileLocale, dwFlags, &hMpqFile))
+        if(!SFileCreateFile(hMpq, szArchivedName, FileTime, (DWORD)FileSize, g_lcFileLocale, dwFlags, &hMpqFile))
             nError = GetLastError();
     }
 
@@ -1016,7 +1020,7 @@ bool WINAPI SFileAddFileEx(
         SetLastError(nError);
     return (nError == ERROR_SUCCESS);
 }
-                                                                                                                                 
+
 // Adds a data file into the archive
 bool WINAPI SFileAddFile(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags)
 {
@@ -1043,7 +1047,7 @@ bool WINAPI SFileAddWave(HANDLE hMpq, const TCHAR * szFileName, const char * szA
     // Starcraft files are packed as Mono (0x41) on medium quality.
     // Because this compression is not used anymore, our compression functions
     // will default to WaveCompressionLevel = 4 when using ADPCM compression
-    // 
+    //
 
     // Convert quality to data compression
     switch(dwQuality)
@@ -1161,7 +1165,7 @@ bool WINAPI SFileRenameFile(HANDLE hMpq, const char * szFileName, const char * s
     // Open the new file. If exists, we don't allow rename operation
     if(nError == ERROR_SUCCESS)
     {
-        if(GetFileEntryLocale(ha, szNewFileName, lcFileLocale) != NULL)
+        if(GetFileEntryLocale(ha, szNewFileName, g_lcFileLocale) != NULL)
             nError = ERROR_ALREADY_EXISTS;
     }
 
@@ -1186,7 +1190,7 @@ bool WINAPI SFileRenameFile(HANDLE hMpq, const char * szFileName, const char * s
             {
                 // Recrypt the file data in the MPQ
                 nError = RecryptFileData(ha, hf, szFileName, szNewFileName);
-                
+
                 // Update the MD5 of the raw block
                 if(nError == ERROR_SUCCESS && ha->pHeader->dwRawChunkSize != 0)
                 {
diff --git a/OpenSource/StormLib/src/SFileAttributes.cpp b/OpenSource/StormLib/src/SFileAttributes.cpp
index d565be738..394cd9d28 100644
--- a/OpenSource/StormLib/src/SFileAttributes.cpp
+++ b/OpenSource/StormLib/src/SFileAttributes.cpp
@@ -151,7 +151,7 @@ static int LoadAttributesFile(TMPQArchive * ha, LPBYTE pbAttrFile, DWORD cbAttrF
     if((pbAttrPtr + sizeof(MPQ_ATTRIBUTES_HEADER)) <= pbAttrFileEnd)
     {
         PMPQ_ATTRIBUTES_HEADER pAttrHeader = (PMPQ_ATTRIBUTES_HEADER)pbAttrPtr;
-        
+
         // Verify the header version
         BSWAP_ARRAY32_UNSIGNED(pAttrHeader, sizeof(MPQ_ATTRIBUTES_HEADER));
         if(pAttrHeader->dwVersion != MPQ_ATTRIBUTES_V1)
@@ -378,7 +378,7 @@ int SAttrLoadAttributes(TMPQArchive * ha)
     {
         // Retrieve and check size of the (attributes) file
         cbAttrFile = SFileGetFileSize(hFile, NULL);
-        
+
         // Integer overflow check
         if((cbAttrFile + 1) > cbAttrFile)
         {
@@ -461,7 +461,7 @@ int SAttrFileSaveToMpq(TMPQArchive * ha)
             nError = (cbAttrFile == 0) ? ERROR_SUCCESS : ERROR_NOT_ENOUGH_MEMORY;
         }
     }
-    
+
     return nError;
 }
 
diff --git a/OpenSource/StormLib/src/SFileCompactArchive.cpp b/OpenSource/StormLib/src/SFileCompactArchive.cpp
index 7b3fcd6f4..f466b28ef 100644
--- a/OpenSource/StormLib/src/SFileCompactArchive.cpp
+++ b/OpenSource/StormLib/src/SFileCompactArchive.cpp
@@ -158,7 +158,7 @@ static int CopyMpqFileSectors(
     DWORD dwCmpSize = 0;                // Compressed file size, including patch header
     int nError = ERROR_SUCCESS;
 
-    // Resolve decryption keys. Note that the file key given 
+    // Resolve decryption keys. Note that the file key given
     // in the TMPQFile structure also includes the key adjustment
     if(nError == ERROR_SUCCESS && (pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED))
     {
@@ -240,7 +240,7 @@ static int CopyMpqFileSectors(
 
             // Calculate the raw file offset of the file sector
             RawFilePos = CalculateRawSectorOffset(hf, dwRawByteOffset);
-            
+
             // Read the file sector
             if(!FileStream_Read(ha->pStream, &RawFilePos, hf->pbFileSector, dwRawDataInSector))
             {
@@ -249,7 +249,7 @@ static int CopyMpqFileSectors(
             }
 
             // If necessary, re-encrypt the sector
-            // Note: Recompression is not necessary here. Unlike encryption, 
+            // Note: Recompression is not necessary here. Unlike encryption,
             // the compression does not depend on the position of the file in MPQ.
             if((pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) && dwFileKey1 != dwFileKey2)
             {
@@ -337,7 +337,7 @@ static int CopyMpqFileSectors(
     // Write the MD5's of the raw file data, if needed
     if(nError == ERROR_SUCCESS && ha->pHeader->dwRawChunkSize != 0)
     {
-        nError = WriteMpqDataMD5(pNewStream, 
+        nError = WriteMpqDataMD5(pNewStream,
                                  ha->MpqPos + MpqFilePos,
                                  pFileEntry->dwCmpSize,
                                  ha->pHeader->dwRawChunkSize);
@@ -349,7 +349,7 @@ static int CopyMpqFileSectors(
         // At this point, number of bytes written should be exactly
         // the same like the compressed file size. If it isn't,
         // there's something wrong (an unknown archive version, MPQ malformation, ...)
-        // 
+        //
         // Note: Diablo savegames have very weird layout, and the file "hero"
         // seems to have improper compressed size. Instead of real compressed size,
         // the "dwCmpSize" member of the block table entry contains
diff --git a/OpenSource/StormLib/src/SFileCreateArchive.cpp b/OpenSource/StormLib/src/SFileCreateArchive.cpp
index de4ab36f9..4185f3d7a 100644
--- a/OpenSource/StormLib/src/SFileCreateArchive.cpp
+++ b/OpenSource/StormLib/src/SFileCreateArchive.cpp
@@ -186,7 +186,7 @@ bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCrea
     if(!FileStream_SetSize(pStream, MpqPos))
         nError = GetLastError();
 
-#ifdef _DEBUG    
+#ifdef _DEBUG
     // Debug code, used for testing StormLib
 //  dwBlockTableSize = dwHashTableSize * 2;
 #endif
@@ -220,7 +220,7 @@ bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCrea
 
         // Fill the MPQ header
         memset(pHeader, 0, sizeof(ha->HeaderData));
-        pHeader->dwID             = ID_MPQ;
+        pHeader->dwID             = g_dwMpqSignature;
         pHeader->dwHeaderSize     = MpqHeaderSizes[pCreateInfo->dwMpqVersion];
         pHeader->dwArchiveSize    = pHeader->dwHeaderSize + dwHashTableSize * sizeof(TMPQHash);
         pHeader->wFormatVersion   = (USHORT)pCreateInfo->dwMpqVersion;
@@ -267,7 +267,7 @@ bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCrea
         SetLastError(nError);
         ha = NULL;
     }
-    
+
     // Return the values
     *phMpq = (HANDLE)ha;
     return (nError == ERROR_SUCCESS);
diff --git a/OpenSource/StormLib/src/SFileFindFile.cpp b/OpenSource/StormLib/src/SFileFindFile.cpp
index a27cf02f7..e85cf05f5 100644
--- a/OpenSource/StormLib/src/SFileFindFile.cpp
+++ b/OpenSource/StormLib/src/SFileFindFile.cpp
@@ -39,7 +39,7 @@ static TMPQSearch * IsValidSearchHandle(HANDLE hFind)
     return NULL;
 }
 
-bool CheckWildCard(const char * szString, const char * szWildCard)
+bool SFileCheckWildCard(const char * szString, const char * szWildCard)
 {
     const char * szWildCardPtr;
 
@@ -71,7 +71,7 @@ bool CheckWildCard(const char * szString, const char * szWildCard)
 
                 if(AsciiToUpperTable[szWildCardPtr[0]] == AsciiToUpperTable[szString[0]])
                 {
-                    if(CheckWildCard(szString, szWildCardPtr))
+                    if(SFileCheckWildCard(szString, szWildCardPtr))
                         return true;
                 }
             }
@@ -222,6 +222,10 @@ static bool DoMPQSearch_FileEntry(
     // Is it a file but not a patch file?
     if((pFileEntry->dwFlags & hs->dwFlagMask) == MPQ_FILE_EXISTS)
     {
+        // Ignore fake files which are not compressed but have size higher than the archive
+        if ((pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) == 0 && (pFileEntry->dwFileSize > ha->FileSize))
+            return false;
+
         // Now we have to check if this file was not enumerated before
         if(!FileWasFoundBefore(ha, hs, pFileEntry))
         {
@@ -234,13 +238,15 @@ static bool DoMPQSearch_FileEntry(
 
             // Prepare the block index
             dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable);
+            if(dwBlockIndex == 569)
+                szNameBuff[0] = 'F';
 
             // Get the file name. If it's not known, we will create pseudo-name
             szFileName = pFileEntry->szFileName;
             if(szFileName == NULL)
             {
                 // Open the file by its pseudo-name.
-                sprintf(szNameBuff, "File%08u.xxx", (unsigned int)dwBlockIndex);
+                StringCreatePseudoFileName(szNameBuff, _countof(szNameBuff), dwBlockIndex, "xxx");
                 if(SFileOpenFileEx((HANDLE)hs->ha, szNameBuff, SFILE_OPEN_BASE_FILE, &hFile))
                 {
                     SFileGetFileName(hFile, szNameBuff);
@@ -253,7 +259,7 @@ static bool DoMPQSearch_FileEntry(
             if(szFileName != NULL)
             {
                 // Check the file name against the wildcard
-                if(CheckWildCard(szFileName + nPrefixLength, hs->szSearchMask))
+                if(SFileCheckWildCard(szFileName + nPrefixLength, hs->szSearchMask))
                 {
                     // Fill the found entry. hash entry and block index are taken from the base MPQ
                     lpFindFileData->dwHashIndex  = HASH_ENTRY_FREE;
@@ -339,7 +345,7 @@ static int DoMPQSearch(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData)
 
     // Start searching with base MPQ
     while(ha != NULL)
-    { 
+    {
         // If the archive has hash table, we need to use hash table
         // in order to catch hash table index and file locale.
         // Note: If multiple hash table entries, point to the same block entry,
@@ -439,7 +445,7 @@ HANDLE WINAPI SFileFindFirstFile(HANDLE hMpq, const char * szMask, SFILE_FIND_DA
         FreeMPQSearch(hs);
         SetLastError(nError);
     }
-    
+
     // Return the result value
     return (HANDLE)hs;
 }
diff --git a/OpenSource/StormLib/src/SFileGetFileInfo.cpp b/OpenSource/StormLib/src/SFileGetFileInfo.cpp
index 226e8b8d6..449576466 100644
--- a/OpenSource/StormLib/src/SFileGetFileInfo.cpp
+++ b/OpenSource/StormLib/src/SFileGetFileInfo.cpp
@@ -12,36 +12,9 @@
 #include "StormLib.h"
 #include "StormCommon.h"
 
-//-----------------------------------------------------------------------------
-// Local defines
-
-// Information types for SFileGetFileInfo
-#define SFILE_INFO_TYPE_INVALID_HANDLE  0
-#define SFILE_INFO_TYPE_NOT_FOUND       1
-#define SFILE_INFO_TYPE_DIRECT_POINTER  2
-#define SFILE_INFO_TYPE_ALLOCATED       3
-#define SFILE_INFO_TYPE_READ_FROM_FILE  4
-#define SFILE_INFO_TYPE_TABLE_POINTER   5
-#define SFILE_INFO_TYPE_FILE_ENTRY      6
-
 //-----------------------------------------------------------------------------
 // Local functions
 
-static void ConvertFileEntryToSelfRelative(TFileEntry * pFileEntry, TFileEntry * pSrcFileEntry)
-{
-    // Copy the file entry itself
-    memcpy(pFileEntry, pSrcFileEntry, sizeof(TFileEntry));
-
-    // If source is NULL, leave it NULL
-    if(pSrcFileEntry->szFileName != NULL)
-    {
-        // Set the file name pointer after the file entry
-        pFileEntry->szFileName = (char *)(pFileEntry + 1);
-        strcpy(pFileEntry->szFileName, pSrcFileEntry->szFileName);
-    }
-}
-
-
 static DWORD GetMpqFileCount(TMPQArchive * ha)
 {
     TFileEntry * pFileTableEnd;
@@ -69,56 +42,138 @@ static DWORD GetMpqFileCount(TMPQArchive * ha)
     return dwFileCount;
 }
 
-static bool GetFilePatchChain(TMPQFile * hf, void * pvFileInfo, DWORD cbFileInfo, DWORD * pcbLengthNeeded)
+static bool GetInfo_ReturnError(DWORD dwErrCode)
+{
+    SetLastError(dwErrCode);
+    return false;
+}
+
+static bool GetInfo_BufferCheck(void * pvFileInfo, DWORD cbFileInfo, DWORD cbData, LPDWORD pcbLengthNeeded)
+{
+    // Give the length needed to store the info
+    if(pcbLengthNeeded != NULL)
+        pcbLengthNeeded[0] = cbData;
+
+    // Check for sufficient buffer
+    if(cbData > cbFileInfo)
+        return GetInfo_ReturnError(ERROR_INSUFFICIENT_BUFFER);
+
+    // If the buffer size is sufficient, check for valid user buffer
+    if(pvFileInfo == NULL)
+        return GetInfo_ReturnError(ERROR_INVALID_PARAMETER);
+
+    // Buffers and sizes are OK, we are ready to proceed file copying
+    return true;
+}
+
+static bool GetInfo(void * pvFileInfo, DWORD cbFileInfo, const void * pvData, DWORD cbData, LPDWORD pcbLengthNeeded)
+{
+    // Verify buffer pointer and buffer size
+    if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbData, pcbLengthNeeded))
+        return false;
+
+    // Copy the data to the caller-supplied buffer
+    memcpy(pvFileInfo, pvData, cbData);
+    return true;
+}
+
+static bool GetInfo_Allocated(void * pvFileInfo, DWORD cbFileInfo, void * pvData, DWORD cbData, LPDWORD pcbLengthNeeded)
+{
+    bool bResult;
+
+    // Verify buffer pointer and buffer size
+    if((bResult = GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbData, pcbLengthNeeded)) != false)
+        memcpy(pvFileInfo, pvData, cbData);
+
+    // Copy the data to the user buffer
+    STORM_FREE(pvData);
+    return bResult;
+}
+
+static bool GetInfo_TablePointer(void * pvFileInfo, DWORD cbFileInfo, void * pvTablePointer, SFileInfoClass InfoClass, LPDWORD pcbLengthNeeded)
+{
+    // Verify buffer pointer and buffer size
+    if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, sizeof(void *), pcbLengthNeeded))
+    {
+        SFileFreeFileInfo(pvTablePointer, InfoClass);
+        return false;
+    }
+
+    // The user buffer receives pointer to the table.
+    // When done, the caller needs to call SFileFreeFileInfo on it
+    *(void **)pvFileInfo = pvTablePointer;
+    return true;
+}
+
+static bool GetInfo_ReadFromFile(void * pvFileInfo, DWORD cbFileInfo, TFileStream * pStream, ULONGLONG ByteOffset, DWORD cbData, LPDWORD pcbLengthNeeded)
+{
+    // Verify buffer pointer and buffer size
+    if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbData, pcbLengthNeeded))
+        return false;
+
+    return FileStream_Read(pStream, &ByteOffset, pvFileInfo, cbData);
+}
+
+static bool GetInfo_FileEntry(void * pvFileInfo, DWORD cbFileInfo, TFileEntry * pFileEntry, LPDWORD pcbLengthNeeded)
+{
+    LPBYTE pbFileInfo = (LPBYTE)pvFileInfo;
+    DWORD cbSrcFileInfo = sizeof(TFileEntry);
+    DWORD cbFileName = 1;
+
+    // The file name belongs to the file entry
+    if(pFileEntry->szFileName)
+        cbFileName = (DWORD)strlen(pFileEntry->szFileName) + 1;
+    cbSrcFileInfo += cbFileName;
+
+    // Verify buffer pointer and buffer size
+    if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbSrcFileInfo, pcbLengthNeeded))
+        return false;
+
+    // Copy the file entry
+    memcpy(pbFileInfo, pFileEntry, sizeof(TFileEntry));
+    pbFileInfo += sizeof(TFileEntry);
+    pbFileInfo[0] = 0;
+
+    // Copy the file name
+    if(pFileEntry->szFileName)
+        memcpy(pbFileInfo, pFileEntry->szFileName, cbFileName);
+    return true;
+}
+
+static bool GetInfo_PatchChain(TMPQFile * hf, void * pvFileInfo, DWORD cbFileInfo, LPDWORD pcbLengthNeeded)
 {
     TMPQFile * hfTemp;
-    TCHAR * szFileInfo = (TCHAR *)pvFileInfo;
+    LPCTSTR szPatchName;
+    LPTSTR szFileInfo = (LPTSTR)pvFileInfo;
     size_t cchCharsNeeded = 1;
-    size_t cchFileInfo = (cbFileInfo / sizeof(TCHAR));
     size_t nLength;
 
-    // Patch chain is only supported on MPQ files.
+    // Patch chain is only supported on MPQ files. Local files are not supported.
     if(hf->pStream != NULL)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return false;
-    }
+        return GetInfo_ReturnError(ERROR_INVALID_PARAMETER);
 
     // Calculate the necessary length of the multi-string
     for(hfTemp = hf; hfTemp != NULL; hfTemp = hfTemp->hfPatch)
         cchCharsNeeded += _tcslen(FileStream_GetFileName(hfTemp->ha->pStream)) + 1;
 
-    // Give the caller the needed length
-    if(pcbLengthNeeded != NULL)
-        pcbLengthNeeded[0] = (DWORD)(cchCharsNeeded * sizeof(TCHAR)); 
+    // Verify whether the caller gave us valid buffer with enough size
+    if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, (DWORD)(cchCharsNeeded * sizeof(TCHAR)), pcbLengthNeeded))
+        return false;
 
-    // If the caller gave both buffer pointer and data length,
-    // try to copy the patch chain
-    if(szFileInfo != NULL && cchFileInfo != 0)
+    // Copy each patch name
+    for(hfTemp = hf; hfTemp != NULL; hfTemp = hfTemp->hfPatch)
     {
-        // If there is enough space in the buffer, copy the patch chain
-        if(cchCharsNeeded > cchFileInfo)
-        {
-            SetLastError(ERROR_INSUFFICIENT_BUFFER);
-            return false;
-        }
-
-        // Copy each patch
-        for(hfTemp = hf; hfTemp != NULL; hfTemp = hfTemp->hfPatch)
-        {
-            // Get the file name and its length
-            const TCHAR * szFileName = FileStream_GetFileName(hfTemp->ha->pStream);
-            nLength = _tcslen(szFileName) + 1;
-
-            // Copy the file name
-            memcpy(szFileInfo, szFileName, nLength * sizeof(TCHAR));
-            szFileInfo += nLength;
-        }
+        // Get the file name and its length
+        szPatchName = FileStream_GetFileName(hfTemp->ha->pStream);
+        nLength = _tcslen(szPatchName) + 1;
 
-        // Make it multi-string
-        szFileInfo[0] = 0;
+        // Copy the file name
+        memcpy(szFileInfo, szPatchName, nLength * sizeof(TCHAR));
+        szFileInfo += nLength;
     }
 
+    // Make it multi-string
+    szFileInfo[0] = 0;
     return true;
 }
 
@@ -139,719 +194,253 @@ bool WINAPI SFileGetFileInfo(
     LPDWORD pcbLengthNeeded)
 {
     MPQ_SIGNATURE_INFO SignatureInfo;
+    const TCHAR * szSrcFileInfo;
     TMPQArchive * ha = NULL;
     TFileEntry * pFileEntry = NULL;
+    TMPQHeader * pHeader = NULL;
     ULONGLONG Int64Value = 0;
-    ULONGLONG ByteOffset = 0;
     TMPQFile * hf = NULL;
     void * pvSrcFileInfo = NULL;
     DWORD cbSrcFileInfo = 0;
     DWORD dwInt32Value = 0;
-    int nInfoType = SFILE_INFO_TYPE_INVALID_HANDLE;
-    int nError = ERROR_SUCCESS;
 
+    // Validate archive/file handle
+    if((int)InfoClass <= (int)SFileMpqFlags)
+    {
+        if((ha = IsValidMpqHandle(hMpqOrFile)) == NULL)
+            return GetInfo_ReturnError(ERROR_INVALID_HANDLE);
+        pHeader = ha->pHeader;
+    }
+    else
+    {
+        if((hf = IsValidFileHandle(hMpqOrFile)) == NULL)
+            return GetInfo_ReturnError(ERROR_INVALID_HANDLE);
+        pFileEntry = hf->pFileEntry;
+    }
+
+    // Return info-class-specific data
     switch(InfoClass)
     {
         case SFileMpqFileName:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = (void *)FileStream_GetFileName(ha->pStream);
-                cbSrcFileInfo = (DWORD)(_tcslen((TCHAR *)pvSrcFileInfo) + 1) * sizeof(TCHAR);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            szSrcFileInfo = FileStream_GetFileName(ha->pStream);
+            cbSrcFileInfo = (DWORD)((_tcslen(szSrcFileInfo) + 1) * sizeof(TCHAR));
+            return GetInfo(pvFileInfo, cbFileInfo, szSrcFileInfo, cbSrcFileInfo, pcbLengthNeeded);
 
         case SFileMpqStreamBitmap:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-                return FileStream_GetBitmap(ha->pStream, pvFileInfo, cbFileInfo, pcbLengthNeeded);
-            break;
+            return FileStream_GetBitmap(ha->pStream, pvFileInfo, cbFileInfo, pcbLengthNeeded);
 
         case SFileMpqUserDataOffset:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
-                if(ha->pUserData != NULL)
-                {
-                    pvSrcFileInfo = &ha->UserDataPos;
-                    cbSrcFileInfo = sizeof(ULONGLONG);
-                    nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-                }
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &ha->UserDataPos, sizeof(ULONGLONG), pcbLengthNeeded);
 
         case SFileMpqUserDataHeader:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
-                if(ha->pUserData != NULL)
-                {
-                    ByteOffset = ha->UserDataPos;
-                    cbSrcFileInfo = sizeof(TMPQUserData);
-                    nInfoType = SFILE_INFO_TYPE_READ_FROM_FILE;
-                }
-            }
-            break;
+            return GetInfo_ReadFromFile(pvFileInfo, cbFileInfo, ha->pStream, ha->UserDataPos, sizeof(TMPQUserData), pcbLengthNeeded);
 
         case SFileMpqUserData:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
-                if(ha->pUserData != NULL)
-                {
-                    ByteOffset = ha->UserDataPos + sizeof(TMPQUserData);
-                    cbSrcFileInfo = ha->pUserData->dwHeaderOffs - sizeof(TMPQUserData);
-                    nInfoType = SFILE_INFO_TYPE_READ_FROM_FILE;
-                }
-            }
-            break;
+            return GetInfo_ReadFromFile(pvFileInfo, cbFileInfo, ha->pStream, ha->UserDataPos + sizeof(TMPQUserData), ha->pUserData->dwHeaderOffs - sizeof(TMPQUserData), pcbLengthNeeded);
 
         case SFileMpqHeaderOffset:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &ha->MpqPos;
-                cbSrcFileInfo = sizeof(ULONGLONG);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &ha->MpqPos, sizeof(ULONGLONG), pcbLengthNeeded);
 
         case SFileMpqHeaderSize:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &ha->pHeader->dwHeaderSize;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwHeaderSize, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileMpqHeader:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                ByteOffset = ha->MpqPos;
-                cbSrcFileInfo = ha->pHeader->dwHeaderSize;
-                nInfoType = SFILE_INFO_TYPE_READ_FROM_FILE;
-            }
-            break;
+            return GetInfo_ReadFromFile(pvFileInfo, cbFileInfo, ha->pStream, ha->MpqPos, pHeader->dwHeaderSize, pcbLengthNeeded);
 
         case SFileMpqHetTableOffset:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &ha->pHeader->HetTablePos64;
-                cbSrcFileInfo = sizeof(ULONGLONG);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HetTablePos64, sizeof(ULONGLONG), pcbLengthNeeded);
 
         case SFileMpqHetTableSize:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &ha->pHeader->HetTableSize64;
-                cbSrcFileInfo = sizeof(ULONGLONG);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HetTableSize64, sizeof(ULONGLONG), pcbLengthNeeded);
 
         case SFileMpqHetHeader:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
-                pvSrcFileInfo = LoadExtTable(ha, ha->pHeader->HetTablePos64, (size_t)ha->pHeader->HetTableSize64, HET_TABLE_SIGNATURE, MPQ_KEY_HASH_TABLE);
-                if(pvSrcFileInfo != NULL)
-                {
-                    cbSrcFileInfo = sizeof(TMPQHetHeader);
-                    nInfoType = SFILE_INFO_TYPE_ALLOCATED;
-                }
-            }
-            break;
+            pvSrcFileInfo = LoadExtTable(ha, pHeader->HetTablePos64, (size_t)pHeader->HetTableSize64, HET_TABLE_SIGNATURE, MPQ_KEY_HASH_TABLE);
+            if(pvSrcFileInfo == NULL)
+                return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+            return GetInfo_Allocated(pvFileInfo, cbFileInfo, pvSrcFileInfo, sizeof(TMPQHetHeader), pcbLengthNeeded);
 
         case SFileMpqHetTable:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
-                pvSrcFileInfo = LoadHetTable(ha);
-                if(pvSrcFileInfo != NULL)
-                {
-                    cbSrcFileInfo = sizeof(void *);
-                    nInfoType = SFILE_INFO_TYPE_TABLE_POINTER;
-                }
-            }
-            break;
+            if((pvSrcFileInfo = LoadHetTable(ha)) == NULL)
+                return GetInfo_ReturnError(ERROR_NOT_ENOUGH_MEMORY);
+            return GetInfo_TablePointer(pvFileInfo, cbFileInfo, pvSrcFileInfo, InfoClass, pcbLengthNeeded);
 
         case SFileMpqBetTableOffset:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &ha->pHeader->BetTablePos64;
-                cbSrcFileInfo = sizeof(ULONGLONG);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pHeader->BetTablePos64, sizeof(ULONGLONG), pcbLengthNeeded);
 
         case SFileMpqBetTableSize:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &ha->pHeader->BetTableSize64;
-                cbSrcFileInfo = sizeof(ULONGLONG);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pHeader->BetTableSize64, sizeof(ULONGLONG), pcbLengthNeeded);
 
         case SFileMpqBetHeader:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
-                pvSrcFileInfo = LoadExtTable(ha, ha->pHeader->BetTablePos64, (size_t)ha->pHeader->BetTableSize64, BET_TABLE_SIGNATURE, MPQ_KEY_BLOCK_TABLE);
-                if(pvSrcFileInfo != NULL)
-                {
-                    // It is allowed for the caller to only require BET header.
-                    cbSrcFileInfo = sizeof(TMPQBetHeader) + ((TMPQBetHeader *)pvSrcFileInfo)->dwFlagCount * sizeof(DWORD);
-                    if(cbFileInfo == sizeof(TMPQBetHeader))
-                        cbSrcFileInfo = sizeof(TMPQBetHeader);
-                    nInfoType = SFILE_INFO_TYPE_ALLOCATED;
-                }
-            }
-            break;
+
+            // Retrieve the table and its size
+            pvSrcFileInfo = LoadExtTable(ha, pHeader->BetTablePos64, (size_t)pHeader->BetTableSize64, BET_TABLE_SIGNATURE, MPQ_KEY_BLOCK_TABLE);
+            if(pvSrcFileInfo == NULL)
+                return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+            cbSrcFileInfo = sizeof(TMPQBetHeader) + ((TMPQBetHeader *)pvSrcFileInfo)->dwFlagCount * sizeof(DWORD);
+
+            // It is allowed for the caller to only require BET header
+            if(cbFileInfo == sizeof(TMPQBetHeader))
+                cbSrcFileInfo = sizeof(TMPQBetHeader);
+            return GetInfo_Allocated(pvFileInfo, cbFileInfo, pvSrcFileInfo, cbSrcFileInfo, pcbLengthNeeded);
 
         case SFileMpqBetTable:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
-                pvSrcFileInfo = LoadBetTable(ha);
-                if(pvSrcFileInfo != NULL)
-                {
-                    cbSrcFileInfo = sizeof(void *);
-                    nInfoType = SFILE_INFO_TYPE_TABLE_POINTER;
-                }
-            }
-            break;
+            if((pvSrcFileInfo = LoadBetTable(ha)) == NULL)
+                return GetInfo_ReturnError(ERROR_NOT_ENOUGH_MEMORY);
+            return GetInfo_TablePointer(pvFileInfo, cbFileInfo, pvSrcFileInfo, InfoClass, pcbLengthNeeded);
 
         case SFileMpqHashTableOffset:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                Int64Value = MAKE_OFFSET64(ha->pHeader->wHashTablePosHi, ha->pHeader->dwHashTablePos);
-                pvSrcFileInfo = &Int64Value;
-                cbSrcFileInfo = sizeof(ULONGLONG);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            Int64Value = MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos);
+            return GetInfo(pvFileInfo, cbFileInfo, &Int64Value, sizeof(ULONGLONG), pcbLengthNeeded);
 
         case SFileMpqHashTableSize64:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &ha->pHeader->HashTableSize64;
-                cbSrcFileInfo = sizeof(ULONGLONG);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HashTableSize64, sizeof(ULONGLONG), pcbLengthNeeded);
 
         case SFileMpqHashTableSize:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &ha->pHeader->dwHashTableSize;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwHashTableSize, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileMpqHashTable:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL && ha->pHashTable != NULL)
-            {
-                pvSrcFileInfo = ha->pHashTable;
-                cbSrcFileInfo = ha->pHeader->dwHashTableSize * sizeof(TMPQHash);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            cbSrcFileInfo = pHeader->dwHashTableSize * sizeof(TMPQHash);
+            return GetInfo(pvFileInfo, cbFileInfo, ha->pHashTable, cbSrcFileInfo, pcbLengthNeeded);
 
         case SFileMpqBlockTableOffset:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                Int64Value = MAKE_OFFSET64(ha->pHeader->wBlockTablePosHi, ha->pHeader->dwBlockTablePos);
-                pvSrcFileInfo = &Int64Value;
-                cbSrcFileInfo = sizeof(ULONGLONG);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            Int64Value = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
+            return GetInfo(pvFileInfo, cbFileInfo, &Int64Value, sizeof(ULONGLONG), pcbLengthNeeded);
 
         case SFileMpqBlockTableSize64:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &ha->pHeader->BlockTableSize64;
-                cbSrcFileInfo = sizeof(ULONGLONG);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pHeader->BlockTableSize64, sizeof(ULONGLONG), pcbLengthNeeded);
 
         case SFileMpqBlockTableSize:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &ha->pHeader->dwBlockTableSize;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwBlockTableSize, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileMpqBlockTable:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
-                if(MAKE_OFFSET64(ha->pHeader->wBlockTablePosHi, ha->pHeader->dwBlockTablePos) < ha->FileSize)
-                {
-                    cbSrcFileInfo = ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock);
-                    if(cbFileInfo >= cbSrcFileInfo)
-                        pvSrcFileInfo = LoadBlockTable(ha, true);
-                    nInfoType = SFILE_INFO_TYPE_ALLOCATED;
-                }
-            }
-            break;
+            if(MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos) >= ha->FileSize)
+                return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+            cbSrcFileInfo = pHeader->dwBlockTableSize * sizeof(TMPQBlock);
+            pvSrcFileInfo = LoadBlockTable(ha, true);
+            return GetInfo_Allocated(pvFileInfo, cbFileInfo, pvSrcFileInfo, cbSrcFileInfo, pcbLengthNeeded);
 
         case SFileMpqHiBlockTableOffset:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &ha->pHeader->HiBlockTablePos64;
-                cbSrcFileInfo = sizeof(ULONGLONG);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HiBlockTablePos64, sizeof(ULONGLONG), pcbLengthNeeded);
 
         case SFileMpqHiBlockTableSize64:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &ha->pHeader->HiBlockTableSize64;
-                cbSrcFileInfo = sizeof(ULONGLONG);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HiBlockTableSize64, sizeof(ULONGLONG), pcbLengthNeeded);
 
         case SFileMpqHiBlockTable:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
-                if(ha->pHeader->HiBlockTablePos64 && ha->pHeader->HiBlockTableSize64)
-                {
-                    assert(false);
-                }
-            }
-            break;
+            return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
 
         case SFileMpqSignatures:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL && QueryMpqSignatureInfo(ha, &SignatureInfo))
-            {
-                pvSrcFileInfo = &SignatureInfo.SignatureTypes;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            if(!QueryMpqSignatureInfo(ha, &SignatureInfo))
+                return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+            return GetInfo(pvFileInfo, cbFileInfo, &SignatureInfo.SignatureTypes, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileMpqStrongSignatureOffset:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
-                if(QueryMpqSignatureInfo(ha, &SignatureInfo) && (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG))
-                {
-                    pvSrcFileInfo = &SignatureInfo.EndMpqData;
-                    cbSrcFileInfo = sizeof(ULONGLONG);
-                    nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-                }
-            }
-            break;
+            if(QueryMpqSignatureInfo(ha, &SignatureInfo) == false || (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG) == 0)
+                return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+            return GetInfo(pvFileInfo, cbFileInfo, &SignatureInfo.EndMpqData, sizeof(ULONGLONG), pcbLengthNeeded);
 
         case SFileMpqStrongSignatureSize:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
-                if(QueryMpqSignatureInfo(ha, &SignatureInfo) && (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG))
-                {
-                    dwInt32Value = MPQ_STRONG_SIGNATURE_SIZE + 4;
-                    pvSrcFileInfo = &dwInt32Value;
-                    cbSrcFileInfo = sizeof(DWORD);
-                    nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-                }
-            }
-            break;
+            if(QueryMpqSignatureInfo(ha, &SignatureInfo) == false || (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG) == 0)
+                return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+            dwInt32Value = MPQ_STRONG_SIGNATURE_SIZE + 4;
+            return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileMpqStrongSignature:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
-                if(QueryMpqSignatureInfo(ha, &SignatureInfo) && (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG))
-                {
-                    pvSrcFileInfo = SignatureInfo.Signature;
-                    cbSrcFileInfo = MPQ_STRONG_SIGNATURE_SIZE + 4;
-                    nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-                }
-            }
-            break;
+            if(QueryMpqSignatureInfo(ha, &SignatureInfo) == false || (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG) == 0)
+                return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+            return GetInfo(pvFileInfo, cbFileInfo, SignatureInfo.Signature, MPQ_STRONG_SIGNATURE_SIZE + 4, pcbLengthNeeded);
 
         case SFileMpqArchiveSize64:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &ha->pHeader->ArchiveSize64;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pHeader->ArchiveSize64, sizeof(ULONGLONG), pcbLengthNeeded);
 
         case SFileMpqArchiveSize:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &ha->pHeader->dwArchiveSize;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwArchiveSize, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileMpqMaxFileCount:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &ha->dwMaxFileCount;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &ha->dwMaxFileCount, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileMpqFileTableSize:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &ha->dwFileTableSize;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &ha->dwFileTableSize, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileMpqSectorSize:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &ha->dwSectorSize;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &ha->dwSectorSize, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileMpqNumberOfFiles:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                pvSrcFileInfo = &dwInt32Value;
-                cbSrcFileInfo = sizeof(DWORD);
-                dwInt32Value = GetMpqFileCount(ha);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            dwInt32Value = GetMpqFileCount(ha);
+            return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileMpqRawChunkSize:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                nInfoType = SFILE_INFO_TYPE_NOT_FOUND;
-                if(ha->pHeader->dwRawChunkSize != 0)
-                {
-                    pvSrcFileInfo = &ha->pHeader->dwRawChunkSize;
-                    cbSrcFileInfo = sizeof(DWORD);
-                    nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-                }
-            }
-            break;
+            if(pHeader->dwRawChunkSize == 0)
+                return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+            return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwRawChunkSize, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileMpqStreamFlags:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                FileStream_GetFlags(ha->pStream, &dwInt32Value);
-                pvSrcFileInfo = &dwInt32Value;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            FileStream_GetFlags(ha->pStream, &dwInt32Value);
+            return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileMpqFlags:
-            ha = IsValidMpqHandle(hMpqOrFile);
-            if(ha != NULL)
-            {
-                dwInt32Value  = ha->dwFlags;
-                pvSrcFileInfo = &dwInt32Value;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &ha->dwFlags, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileInfoPatchChain:
-            hf = IsValidFileHandle(hMpqOrFile);
-            if(hf != NULL)
-                return GetFilePatchChain(hf, pvFileInfo, cbFileInfo, pcbLengthNeeded);
-            break;
+            return GetInfo_PatchChain(hf, pvFileInfo, cbFileInfo, pcbLengthNeeded);
 
         case SFileInfoFileEntry:
-            hf = IsValidFileHandle(hMpqOrFile);
-            if(hf != NULL && hf->pFileEntry != NULL)
-            {
-                pvSrcFileInfo = pFileEntry = hf->pFileEntry;
-                cbSrcFileInfo = sizeof(TFileEntry);
-                if(pFileEntry->szFileName != NULL)
-                    cbSrcFileInfo += (DWORD)strlen(pFileEntry->szFileName) + 1;
-                nInfoType = SFILE_INFO_TYPE_FILE_ENTRY;
-            }
-            break;
+            if(pFileEntry == NULL)
+                return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND);
+            return GetInfo_FileEntry(pvFileInfo, cbFileInfo, pFileEntry, pcbLengthNeeded);
 
         case SFileInfoHashEntry:
-            hf = IsValidFileHandle(hMpqOrFile);
-            if(hf != NULL && hf->pHashEntry != NULL)
-            {
-                pvSrcFileInfo = hf->pHashEntry;
-                cbSrcFileInfo = sizeof(TMPQHash);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, hf->pHashEntry, sizeof(TMPQHash), pcbLengthNeeded);
 
         case SFileInfoHashIndex:
-            hf = IsValidFileHandle(hMpqOrFile);
-            if(hf != NULL && hf->pHashEntry != NULL)
-            {
-                pvSrcFileInfo = &hf->dwHashIndex;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &hf->dwHashIndex, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileInfoNameHash1:
-            hf = IsValidFileHandle(hMpqOrFile);
-            if(hf != NULL && hf->pHashEntry != NULL)
-            {
-                dwInt32Value = hf->pHashEntry->dwName1;
-                pvSrcFileInfo = &dwInt32Value;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &hf->pHashEntry->dwName1, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileInfoNameHash2:
-            hf = IsValidFileHandle(hMpqOrFile);
-            if(hf != NULL && hf->pHashEntry != NULL)
-            {
-                dwInt32Value = hf->pHashEntry->dwName2;
-                pvSrcFileInfo = &dwInt32Value;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &hf->pHashEntry->dwName2, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileInfoNameHash3:
-            hf = IsValidFileHandle(hMpqOrFile);
-            if(hf != NULL && hf->pFileEntry != NULL)
-            {
-                pvSrcFileInfo = &hf->pFileEntry->FileNameHash;
-                cbSrcFileInfo = sizeof(ULONGLONG);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->FileNameHash, sizeof(ULONGLONG), pcbLengthNeeded);
 
         case SFileInfoLocale:
-            hf = IsValidFileHandle(hMpqOrFile);
-            if(hf != NULL && hf->pHashEntry != NULL)
-            {
-                dwInt32Value = hf->pHashEntry->lcLocale;
-                pvSrcFileInfo = &dwInt32Value;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            dwInt32Value = hf->pHashEntry->lcLocale;
+            return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileInfoFileIndex:
-            hf = IsValidFileHandle(hMpqOrFile);
-            if(hf != NULL && hf->ha != NULL && hf->pFileEntry != NULL)
-            {
-                dwInt32Value = (DWORD)(hf->pFileEntry - hf->ha->pFileTable);
-                pvSrcFileInfo = &dwInt32Value;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            dwInt32Value = (DWORD)(pFileEntry - hf->ha->pFileTable);
+            return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileInfoByteOffset:
-            hf = IsValidFileHandle(hMpqOrFile);
-            if(hf != NULL && hf->pFileEntry != NULL)
-            {
-                pvSrcFileInfo = &hf->pFileEntry->ByteOffset;
-                cbSrcFileInfo = sizeof(ULONGLONG);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->ByteOffset, sizeof(ULONGLONG), pcbLengthNeeded);
 
         case SFileInfoFileTime:
-            hf = IsValidFileHandle(hMpqOrFile);
-            if(hf != NULL && hf->pFileEntry != NULL)
-            {
-                pvSrcFileInfo = &hf->pFileEntry->FileTime;
-                cbSrcFileInfo = sizeof(ULONGLONG);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->FileTime, sizeof(ULONGLONG), pcbLengthNeeded);
 
         case SFileInfoFileSize:
-            hf = IsValidFileHandle(hMpqOrFile);
-            if(hf != NULL && hf->pFileEntry != NULL)
-            {
-                pvSrcFileInfo = &hf->pFileEntry->dwFileSize;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->dwFileSize, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileInfoCompressedSize:
-            hf = IsValidFileHandle(hMpqOrFile);
-            if(hf != NULL && hf->pFileEntry != NULL)
-            {
-                pvSrcFileInfo = &hf->pFileEntry->dwCmpSize;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->dwCmpSize, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileInfoFlags:
-            hf = IsValidFileHandle(hMpqOrFile);
-            if(hf != NULL && hf->pFileEntry != NULL)
-            {
-                pvSrcFileInfo = &hf->pFileEntry->dwFlags;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->dwFlags, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileInfoEncryptionKey:
-            hf = IsValidFileHandle(hMpqOrFile);
-            if(hf != NULL)
-            {
-                pvSrcFileInfo = &hf->dwFileKey;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            return GetInfo(pvFileInfo, cbFileInfo, &hf->dwFileKey, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileInfoEncryptionKeyRaw:
-            hf = IsValidFileHandle(hMpqOrFile);
-            if(hf != NULL && hf->pFileEntry != NULL)
-            {
-                dwInt32Value = hf->dwFileKey;
-                if(hf->pFileEntry->dwFlags & MPQ_FILE_FIX_KEY)
-                    dwInt32Value = (dwInt32Value ^ hf->pFileEntry->dwFileSize) - (DWORD)hf->MpqFilePos;
-                pvSrcFileInfo = &dwInt32Value;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
+            dwInt32Value = hf->dwFileKey;
+            if(pFileEntry->dwFlags & MPQ_FILE_FIX_KEY)
+                dwInt32Value = (dwInt32Value ^ pFileEntry->dwFileSize) - (DWORD)hf->MpqFilePos;
+            return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
 
         case SFileInfoCRC32:
-            hf = IsValidFileHandle(hMpqOrFile);
-            if(hf != NULL && hf->pFileEntry != NULL)
-            {
-                dwInt32Value = hf->pFileEntry->dwCrc32;
-                pvSrcFileInfo = &dwInt32Value;
-                cbSrcFileInfo = sizeof(DWORD);
-                nInfoType = SFILE_INFO_TYPE_DIRECT_POINTER;
-            }
-            break;
-
-        default:    // Invalid info class
-            SetLastError(ERROR_INVALID_PARAMETER);
-            return false;
-    }
-
-    // If we validated the handle and info class, give as much info as possible
-    if(nInfoType >= SFILE_INFO_TYPE_DIRECT_POINTER)
-    {
-        // Give the length needed, if wanted
-        if(pcbLengthNeeded != NULL)
-            pcbLengthNeeded[0] = cbSrcFileInfo;
-
-        // If the caller entered an output buffer, the output size must also be entered
-        if(pvFileInfo != NULL && cbFileInfo != 0)
-        {
-            // Check if there is enough space in the output buffer
-            if(cbSrcFileInfo <= cbFileInfo)
-            {
-                switch(nInfoType)
-                {
-                    case SFILE_INFO_TYPE_DIRECT_POINTER:
-                    case SFILE_INFO_TYPE_ALLOCATED:
-                        assert(pvSrcFileInfo != NULL);
-                        memcpy(pvFileInfo, pvSrcFileInfo, cbSrcFileInfo);
-                        break;
-
-                    case SFILE_INFO_TYPE_READ_FROM_FILE:
-                        if(!FileStream_Read(ha->pStream, &ByteOffset, pvFileInfo, cbSrcFileInfo))
-                            nError = GetLastError();
-                        break;
-
-                    case SFILE_INFO_TYPE_TABLE_POINTER:
-                        assert(pvSrcFileInfo != NULL);
-                        *(void **)pvFileInfo = pvSrcFileInfo;
-                        pvSrcFileInfo = NULL;
-                        break;
-
-                    case SFILE_INFO_TYPE_FILE_ENTRY:
-                        assert(pFileEntry != NULL);
-                        ConvertFileEntryToSelfRelative((TFileEntry *)pvFileInfo, pFileEntry);
-                        break;
-                }
-            }
-            else
-            {
-                nError = ERROR_INSUFFICIENT_BUFFER;
-            }
-        }
-
-        // Free the file info if needed
-        if(nInfoType == SFILE_INFO_TYPE_ALLOCATED && pvSrcFileInfo != NULL)
-            STORM_FREE(pvSrcFileInfo);
-        if(nInfoType == SFILE_INFO_TYPE_TABLE_POINTER && pvSrcFileInfo != NULL)
-            SFileFreeFileInfo(pvSrcFileInfo, InfoClass);
-    }
-    else
-    {
-        // Handle error cases
-        if(nInfoType == SFILE_INFO_TYPE_INVALID_HANDLE)
-            nError = ERROR_INVALID_HANDLE;
-        if(nInfoType == SFILE_INFO_TYPE_NOT_FOUND)
-            nError = ERROR_FILE_NOT_FOUND;
+            return GetInfo(pvFileInfo, cbFileInfo, &hf->pFileEntry->dwCrc32, sizeof(DWORD), pcbLengthNeeded);
     }
 
-    // Set the last error value, if needed
-    if(nError != ERROR_SUCCESS)
-        SetLastError(nError);
-    return (nError == ERROR_SUCCESS);
+    // Invalid info class
+    return GetInfo_ReturnError(ERROR_INVALID_PARAMETER);
 }
 
 bool WINAPI SFileFreeFileInfo(void * pvFileInfo, SFileInfoClass InfoClass)
@@ -886,7 +475,7 @@ struct TFileHeader2Ext
     const char * szExt;                 // Supplied extension, if the condition is true
 };
 
-static TFileHeader2Ext data2ext[] = 
+static TFileHeader2Ext data2ext[] =
 {
     {0x00005A4D, 0x0000FFFF, 0x00000000, 0x00000000, "exe"},    // EXE files
     {0x00000006, 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, "dc6"},    // EXE files
@@ -909,8 +498,15 @@ static TFileHeader2Ext data2ext[] =
     {0x47585053, 0xFFFFFFFF, 0x00000000, 0x00000000, "bls"},    // WoW pixel shaders
     {0xE0FFD8FF, 0xFFFFFFFF, 0x00000000, 0x00000000, "jpg"},    // JPEG image
     {0x503B4449, 0xFFFFFFFF, 0x3B4C5857, 0xFFFFFFFF, "slk"},    // SLK file (usually starts with "ID;PWXL;N;E")
+    {0x61754C1B, 0xFFFFFFFF, 0x00000000, 0x00000000, "lua"},    // Compiled LUA files
+    {0x20534444, 0xFFFFFFFF, 0x00000000, 0x00000000, "dds"},    // DDS textures
+    {0x43614C66, 0xFFFFFFFF, 0x00000000, 0x00000000, "flac"},   // FLAC sound files
+    {0x6F643357, 0xFFFFFFFF, 0x00000000, 0x00000000, "doo"},    // Warcraft III doodad files
+    {0x21453357, 0xFFFFFFFF, 0x00000000, 0x00000000, "w3e"},    // Warcraft III environment files
+    {0x5733504D, 0xFFFFFFFF, 0x00000000, 0x00000000, "wpm"},    // Warcraft III pathing map files
+    {0x21475457, 0xFFFFFFFF, 0x00000000, 0x00000000, "wtg"},    // Warcraft III trigger files
     {0x00000000, 0x00000000, 0x00000000, 0x00000000, "xxx"},    // Default extension
-    {0, 0, 0, 0, NULL}                                          // Terminator 
+    {0, 0, 0, 0, NULL}                                          // Terminator
 };
 
 static int CreatePseudoFileName(HANDLE hFile, TFileEntry * pFileEntry, char * szFileName)
@@ -919,9 +515,10 @@ static int CreatePseudoFileName(HANDLE hFile, TFileEntry * pFileEntry, char * sz
     DWORD FirstBytes[2] = {0, 0};       // The first 4 bytes of the file
     DWORD dwBytesRead = 0;
     DWORD dwFilePos;                    // Saved file position
+    char szPseudoName[20];
 
     // Read the first 2 DWORDs bytes from the file
-    dwFilePos = SFileSetFilePointer(hFile, 0, NULL, FILE_CURRENT);   
+    dwFilePos = SFileSetFilePointer(hFile, 0, NULL, FILE_CURRENT);
     SFileReadFile(hFile, FirstBytes, sizeof(FirstBytes), &dwBytesRead, NULL);
     SFileSetFilePointer(hFile, dwFilePos, NULL, FILE_BEGIN);
 
@@ -937,10 +534,8 @@ static int CreatePseudoFileName(HANDLE hFile, TFileEntry * pFileEntry, char * sz
             if((FirstBytes[0] & data2ext[i].dwOffset00Mask) == data2ext[i].dwOffset00Data &&
                (FirstBytes[1] & data2ext[i].dwOffset04Mask) == data2ext[i].dwOffset04Data)
             {
-                char szPseudoName[20] = "";    
-
                 // Format the pseudo-name
-                sprintf(szPseudoName, "File%08u.%s", (unsigned int)(pFileEntry - hf->ha->pFileTable), data2ext[i].szExt);
+                StringCreatePseudoFileName(szPseudoName, _countof(szPseudoName), (unsigned int)(pFileEntry - hf->ha->pFileTable), data2ext[i].szExt);
 
                 // Save the pseudo-name in the file entry as well
                 AllocateFileName(hf->ha, pFileEntry, szPseudoName);
diff --git a/OpenSource/StormLib/src/SFileListFile.cpp b/OpenSource/StormLib/src/SFileListFile.cpp
index 777bba3cf..87a28a2ba 100644
--- a/OpenSource/StormLib/src/SFileListFile.cpp
+++ b/OpenSource/StormLib/src/SFileListFile.cpp
@@ -17,7 +17,7 @@
 // Listfile entry structure
 
 #define CACHE_BUFFER_SIZE  0x1000       // Size of the cache buffer
-#define MAX_LISTFILE_SIZE  0x04000000   // Maximum accepted listfile size is about 68 MB
+#define MAX_LISTFILE_SIZE  0x8000000    // Maximum accepted listfile size is 128 MB
 
 union TListFileHandle
 {
@@ -42,6 +42,9 @@ typedef bool (*LOAD_LISTFILE)(TListFileHandle * pHandle, void * pvBuffer, DWORD
 //-----------------------------------------------------------------------------
 // Local functions (cache)
 
+// In SFileFindFile.cll
+bool SFileCheckWildCard(const char * szString, const char * szWildCard);
+
 static char * CopyListLine(char * szListLine, const char * szFileName)
 {
     // Copy the string
@@ -112,7 +115,7 @@ static TListFileCache * CreateListFileCache(
             pCache->szWildCard = (char *)(pCache + 1);
             memcpy(pCache->szWildCard, szWildCard, cchWildCard);
         }
-                          
+
         // Fill-in the rest of the cache pointers
         pCache->pBegin = (LPBYTE)(pCache + 1) + cchWildCard;
 
@@ -145,6 +148,10 @@ static TListFileCache * CreateListFileCache(
     TListFileCache * pCache = NULL;
     TListFileHandle ListHandle = {NULL};
 
+    // Put default value to dwMaxSize
+    if(dwMaxSize == 0)
+        dwMaxSize = MAX_LISTFILE_SIZE;
+
     // Internal listfile: hMPQ must be non NULL and szListFile must be NULL.
     // We load the MPQ::(listfile) file
     if(hMpq != NULL && szListFile == NULL)
@@ -178,7 +185,7 @@ static TListFileCache * CreateListFileCache(
         {
             // Verify the file size
             FileStream_GetSize(ListHandle.pStream, &FileSize);
-            if(0 < FileSize && FileSize < MAX_LISTFILE_SIZE)
+            if(0 < FileSize && FileSize < dwMaxSize)
             {
                 pCache = CreateListFileCache(LoadListFile_Stream, &ListHandle, szWildCard, (DWORD)FileSize, dwMaxSize, dwFlags);
             }
@@ -265,11 +272,11 @@ static char * ReadListFileLine(TListFileCache * pCache, size_t * PtrLength)
 {
     LPBYTE pbLineBegin;
     LPBYTE pbLineEnd;
-    
+
     // Skip newlines. Keep spaces and tabs, as they can be a legal part of the file name
     while(pCache->pPos < pCache->pEnd && (pCache->pPos[0] == 0x0A || pCache->pPos[0] == 0x0D))
         pCache->pPos++;
-    
+
     // Set the line begin and end
     if(pCache->pPos >= pCache->pEnd)
         return NULL;
@@ -289,7 +296,7 @@ static char * ReadListFileLine(TListFileCache * pCache, size_t * PtrLength)
     return (char *)pbLineBegin;
 }
 
-static int CompareFileNodes(const void * p1, const void * p2) 
+static int STORMLIB_CDECL CompareFileNodes(const void * p1, const void * p2)
 {
     char * szFileName1 = *(char **)p1;
     char * szFileName2 = *(char **)p2;
@@ -519,7 +526,7 @@ static int SFileAddArbitraryListFile(
         // Delete the cache
         FreeListFileCache(pCache);
     }
-    
+
     return (pCache != NULL) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT;
 }
 
@@ -529,7 +536,7 @@ static int SFileAddInternalListFile(
 {
     TMPQHash * pFirstHash;
     TMPQHash * pHash;
-    LCID lcSaveLocale = lcFileLocale;
+    LCID lcSaveLocale = g_lcFileLocale;
     DWORD dwMaxSize = MAX_LISTFILE_SIZE;
     int nError = ERROR_SUCCESS;
 
@@ -543,7 +550,7 @@ static int SFileAddInternalListFile(
 
         pFirstHash = pHash = GetFirstHashEntry(ha, LISTFILE_NAME);
         while(nError == ERROR_SUCCESS && pHash != NULL)
-        {                                
+        {
             // Set the prefered locale to that from list file
             SFileSetLocale(pHash->lcLocale);
 
@@ -579,7 +586,7 @@ static bool DoListFileSearch(TListFileCache * pCache, SFILE_FIND_DATA * lpFindFi
         while((szFileName = ReadListFileLine(pCache, &nLength)) != NULL)
         {
             // Check search mask
-            if(nLength != 0 && CheckWildCard(szFileName, pCache->szWildCard))
+            if(nLength != 0 && SFileCheckWildCard(szFileName, pCache->szWildCard))
             {
                 if(nLength >= sizeof(lpFindFileData->cFileName))
                     nLength = sizeof(lpFindFileData->cFileName) - 1;
diff --git a/OpenSource/StormLib/src/SFileOpenArchive.cpp b/OpenSource/StormLib/src/SFileOpenArchive.cpp
index a896eaf67..e8ef64aa7 100644
--- a/OpenSource/StormLib/src/SFileOpenArchive.cpp
+++ b/OpenSource/StormLib/src/SFileOpenArchive.cpp
@@ -5,11 +5,11 @@
 /* E-mail : ladik@zezula.net                                                 */
 /* WWW    : www.zezula.net                                                   */
 /*---------------------------------------------------------------------------*/
-/*                       Archive functions of Storm.dll                      */
+/* Implementation of archive functions                                       */
 /*---------------------------------------------------------------------------*/
 /*   Date    Ver   Who  Comment                                              */
 /* --------  ----  ---  -------                                              */
-/* xx.xx.xx  1.00  Lad  The first version of SFileOpenArchive.cpp            */
+/* xx.xx.xx  1.00  Lad  Created                                              */
 /* 19.11.03  1.01  Dan  Big endian handling                                  */
 /*****************************************************************************/
 
@@ -19,26 +19,53 @@
 
 #define HEADER_SEARCH_BUFFER_SIZE   0x1000
 
-/*****************************************************************************/
-/* Local functions                                                           */
-/*****************************************************************************/
+//-----------------------------------------------------------------------------
+// Local functions
 
-static bool IsAviFile(DWORD * HeaderData)
+static MTYPE CheckMapType(LPCTSTR szFileName, LPBYTE pbHeaderBuffer, size_t cbHeaderBuffer)
 {
-    DWORD DwordValue0 = BSWAP_INT32_UNSIGNED(HeaderData[0]);
-    DWORD DwordValue2 = BSWAP_INT32_UNSIGNED(HeaderData[2]);
-    DWORD DwordValue3 = BSWAP_INT32_UNSIGNED(HeaderData[3]);
+    LPDWORD HeaderInt32 = (LPDWORD)pbHeaderBuffer;
+    LPCTSTR szExtension;
 
-    // Test for 'RIFF', 'AVI ' or 'LIST'
-    return (DwordValue0 == 0x46464952 && DwordValue2 == 0x20495641 && DwordValue3 == 0x5453494C);
-}
+    // Don't do any checks if there is not at least 16 bytes
+    if(cbHeaderBuffer > 0x10)
+    {
+        DWORD DwordValue0 = BSWAP_INT32_UNSIGNED(HeaderInt32[0]);
+        DWORD DwordValue1 = BSWAP_INT32_UNSIGNED(HeaderInt32[1]);
+        DWORD DwordValue2 = BSWAP_INT32_UNSIGNED(HeaderInt32[2]);
+        DWORD DwordValue3 = BSWAP_INT32_UNSIGNED(HeaderInt32[3]);
 
-static bool IsWarcraft3Map(DWORD * HeaderData)
-{
-    DWORD DwordValue0 = BSWAP_INT32_UNSIGNED(HeaderData[0]);
-    DWORD DwordValue1 = BSWAP_INT32_UNSIGNED(HeaderData[1]);
+        // Test for AVI files (Warcraft III cinematics) - 'RIFF', 'AVI ' or 'LIST'
+        if(DwordValue0 == 0x46464952 && DwordValue2 == 0x20495641 && DwordValue3 == 0x5453494C)
+            return MapTypeAviFile;
+
+        // Check for Starcraft II maps
+        if((szExtension = _tcsrchr(szFileName, _T('.'))) != NULL)
+        {
+            // The "NP_Protect" protector places fake Warcraft III header
+            // into the Starcraft II maps, whilst SC2 maps have no other header but MPQ v4
+            if(!_tcsicmp(szExtension, _T(".s2ma")) || !_tcsicmp(szExtension, _T(".SC2Map")) || !_tcsicmp(szExtension, _T(".SC2Mod")))
+            {
+                return MapTypeStarcraft2;
+            }
+        }
 
-    return (DwordValue0 == 0x57334D48 && DwordValue1 == 0x00000000);
+        // Check for Warcraft III maps
+        if(DwordValue0 == 0x57334D48 && DwordValue1 == 0x00000000)
+            return MapTypeWarcraft3;
+    }
+
+    // MIX files are DLL files that contain MPQ in overlay.
+    // Only Warcraft III is able to load them, so we consider them Warcraft III maps
+    if(cbHeaderBuffer > 0x200 && pbHeaderBuffer[0] == 'M' && pbHeaderBuffer[1] == 'Z')
+    {
+        // Check the value of IMAGE_DOS_HEADER::e_lfanew at offset 0x3C
+        if(0 < HeaderInt32[0x0F] && HeaderInt32[0x0F] < 0x10000)
+            return MapTypeWarcraft3;
+    }
+
+    // No special map type recognized
+    return MapTypeNotRecognized;
 }
 
 static TMPQUserData * IsValidMpqUserData(ULONGLONG ByteOffset, ULONGLONG FileSize, void * pvUserData)
@@ -46,7 +73,7 @@ static TMPQUserData * IsValidMpqUserData(ULONGLONG ByteOffset, ULONGLONG FileSiz
     TMPQUserData * pUserData;
 
     // BSWAP the source data and copy them to our buffer
-    BSWAP_ARRAY32_UNSIGNED(&pvUserData, sizeof(TMPQUserData));
+    BSWAP_ARRAY32_UNSIGNED(pvUserData, sizeof(TMPQUserData));
     pUserData = (TMPQUserData *)pvUserData;
 
     // Check the sizes
@@ -73,6 +100,7 @@ static int VerifyMpqTablePositions(TMPQArchive * ha, ULONGLONG FileSize)
 {
     TMPQHeader * pHeader = ha->pHeader;
     ULONGLONG ByteOffset;
+    //bool bMalformed = (ha->dwFlags & MPQ_FLAG_MALFORMED) ? true : false;
 
     // Check the begin of HET table
     if(pHeader->HetTablePos64)
@@ -107,21 +135,48 @@ static int VerifyMpqTablePositions(TMPQArchive * ha, ULONGLONG FileSize)
     }
 
     // Check the begin of hi-block table
-    if(pHeader->HiBlockTablePos64 != 0)
-    {
-        ByteOffset = ha->MpqPos + pHeader->HiBlockTablePos64;
-        if(ByteOffset > FileSize)
-            return ERROR_BAD_FORMAT;
-    }
+    //if(pHeader->HiBlockTablePos64 != 0)
+    //{
+    //    ByteOffset = ha->MpqPos + pHeader->HiBlockTablePos64;
+    //    if(ByteOffset > FileSize)
+    //        return ERROR_BAD_FORMAT;
+    //}
 
     // All OK.
     return ERROR_SUCCESS;
 }
 
+//-----------------------------------------------------------------------------
+// Support for alternate markers. Call before opening an archive
 
-/*****************************************************************************/
-/* Public functions                                                          */
-/*****************************************************************************/
+#define SFILE_MARKERS_MIN_SIZE   (sizeof(DWORD) + sizeof(DWORD) + sizeof(const char *) + sizeof(const char *))
+
+bool WINAPI SFileSetArchiveMarkers(PSFILE_MARKERS pMarkers)
+{
+    // Check structure minimum size
+    if(pMarkers == NULL || pMarkers->dwSize < SFILE_MARKERS_MIN_SIZE)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return false;
+    }
+
+    // Make sure that the MPQ cryptography is initialized at this time
+    InitializeMpqCryptography();
+
+    // Remember the marker for MPQ header
+    g_dwMpqSignature = pMarkers->dwSignature;
+
+    // Remember the encryption key for hash table
+    if(pMarkers->szHashTableKey != NULL)
+        g_dwHashTableKey = HashString(pMarkers->szHashTableKey, MPQ_HASH_FILE_KEY);
+
+    // Remember the encryption key for block table
+    if(pMarkers->szBlockTableKey != NULL)
+        g_dwBlockTableKey = HashString(pMarkers->szBlockTableKey, MPQ_HASH_FILE_KEY);
+
+    // Succeeded
+    return true;
+}
 
 //-----------------------------------------------------------------------------
 // SFileGetLocale and SFileSetLocale
@@ -129,13 +184,13 @@ static int VerifyMpqTablePositions(TMPQArchive * ha, ULONGLONG FileSize)
 
 LCID WINAPI SFileGetLocale()
 {
-    return lcFileLocale;
+    return g_lcFileLocale;
 }
 
 LCID WINAPI SFileSetLocale(LCID lcNewLocale)
 {
-    lcFileLocale = lcNewLocale;
-    return lcFileLocale;
+    g_lcFileLocale = lcNewLocale;
+    return g_lcFileLocale;
 }
 
 //-----------------------------------------------------------------------------
@@ -159,8 +214,8 @@ bool WINAPI SFileOpenArchive(
     ULONGLONG FileSize = 0;             // Size of the file
     LPBYTE pbHeaderBuffer = NULL;       // Buffer for searching MPQ header
     DWORD dwStreamFlags = (dwFlags & STREAM_FLAGS_MASK);
-    bool bIsWarcraft3Map = false;
-    int nError = ERROR_SUCCESS;   
+    MTYPE MapType = MapTypeNotChecked;
+    int nError = ERROR_SUCCESS;
 
     // Verify the parameters
     if(szMpqName == NULL || *szMpqName == 0 || phMpq == NULL)
@@ -207,7 +262,7 @@ bool WINAPI SFileOpenArchive(
     // Find the position of MPQ header
     if(nError == ERROR_SUCCESS)
     {
-        ULONGLONG SearchOffset = 0;
+        ULONGLONG ByteOffset = 0;
         ULONGLONG EndOfSearch = FileSize;
         DWORD dwStrmFlags = 0;
         DWORD dwHeaderSize;
@@ -228,44 +283,42 @@ bool WINAPI SFileOpenArchive(
 
         // Also remember if this MPQ is a patch
         ha->dwFlags |= (dwFlags & MPQ_OPEN_PATCH) ? MPQ_FLAG_PATCH : 0;
-       
+
         // Limit the header searching to about 130 MB of data
         if(EndOfSearch > 0x08000000)
             EndOfSearch = 0x08000000;
 
         // Find the offset of MPQ header within the file
-        while(bSearchComplete == false && SearchOffset < EndOfSearch)
+        while(bSearchComplete == false && ByteOffset < EndOfSearch)
         {
             // Always read at least 0x1000 bytes for performance.
             // This is what Storm.dll (2002) does.
             DWORD dwBytesAvailable = HEADER_SEARCH_BUFFER_SIZE;
-            DWORD dwInBufferOffset = 0;
 
             // Cut the bytes available, if needed
-            if((FileSize - SearchOffset) < HEADER_SEARCH_BUFFER_SIZE)
-                dwBytesAvailable = (DWORD)(FileSize - SearchOffset);
+            if((FileSize - ByteOffset) < HEADER_SEARCH_BUFFER_SIZE)
+                dwBytesAvailable = (DWORD)(FileSize - ByteOffset);
 
             // Read the eventual MPQ header
-            if(!FileStream_Read(ha->pStream, &SearchOffset, pbHeaderBuffer, dwBytesAvailable))
+            if(!FileStream_Read(ha->pStream, &ByteOffset, pbHeaderBuffer, dwBytesAvailable))
             {
                 nError = GetLastError();
                 break;
             }
 
-            // There are AVI files from Warcraft III with 'MPQ' extension.
-            if(SearchOffset == 0)
+            // Check whether the file is AVI file or a Warcraft III/Starcraft II map
+            if(MapType == MapTypeNotChecked)
             {
-                if(IsAviFile((DWORD *)pbHeaderBuffer))
+                // Do nothing if the file is an AVI file
+                if((MapType = CheckMapType(szMpqName, pbHeaderBuffer, dwBytesAvailable)) == MapTypeAviFile)
                 {
                     nError = ERROR_AVI_FILE;
                     break;
                 }
-
-                bIsWarcraft3Map = IsWarcraft3Map((DWORD *)pbHeaderBuffer);
             }
 
             // Search the header buffer
-            while(dwInBufferOffset < dwBytesAvailable)
+            for(DWORD dwInBufferOffset = 0; dwInBufferOffset < dwBytesAvailable; dwInBufferOffset += 0x200)
             {
                 // Copy the data from the potential header buffer to the MPQ header
                 memcpy(ha->HeaderData, pbHeaderBuffer + dwInBufferOffset, sizeof(ha->HeaderData));
@@ -273,21 +326,21 @@ bool WINAPI SFileOpenArchive(
                 // If there is the MPQ user data, process it
                 // Note that Warcraft III does not check for user data, which is abused by many map protectors
                 dwHeaderID = BSWAP_INT32_UNSIGNED(ha->HeaderData[0]);
-                if(bIsWarcraft3Map == false && (dwFlags & MPQ_OPEN_FORCE_MPQ_V1) == 0)
+                if(MapType != MapTypeWarcraft3 && (dwFlags & MPQ_OPEN_FORCE_MPQ_V1) == 0)
                 {
                     if(ha->pUserData == NULL && dwHeaderID == ID_MPQ_USERDATA)
                     {
                         // Verify if this looks like a valid user data
-                        pUserData = IsValidMpqUserData(SearchOffset, FileSize, ha->HeaderData);
+                        pUserData = IsValidMpqUserData(ByteOffset, FileSize, ha->HeaderData);
                         if(pUserData != NULL)
                         {
                             // Fill the user data header
-                            ha->UserDataPos = SearchOffset;
+                            ha->UserDataPos = ByteOffset;
                             ha->pUserData = &ha->UserData;
                             memcpy(ha->pUserData, pUserData, sizeof(TMPQUserData));
 
                             // Continue searching from that position
-                            SearchOffset += ha->pUserData->dwHeaderOffs;
+                            ByteOffset += ha->pUserData->dwHeaderOffs;
                             break;
                         }
                     }
@@ -298,16 +351,19 @@ bool WINAPI SFileOpenArchive(
                 // Abused by Spazzler Map protector. Note that the size check is not present
                 // in Storm.dll v 1.00, so Diablo I code would load the MPQ anyway.
                 dwHeaderSize = BSWAP_INT32_UNSIGNED(ha->HeaderData[1]);
-                if(dwHeaderID == ID_MPQ && dwHeaderSize >= MPQ_HEADER_SIZE_V1)
+                if(dwHeaderID == g_dwMpqSignature && dwHeaderSize >= MPQ_HEADER_SIZE_V1)
                 {
                     // Now convert the header to version 4
-                    nError = ConvertMpqHeaderToFormat4(ha, SearchOffset, FileSize, dwFlags, bIsWarcraft3Map);
-                    bSearchComplete = true;
-                    break;
+                    nError = ConvertMpqHeaderToFormat4(ha, ByteOffset, FileSize, dwFlags, MapType);
+                    if(nError != ERROR_FAKE_MPQ_HEADER)
+                    {
+                        bSearchComplete = true;
+                        break;
+                    }
                 }
 
                 // Check for MPK archives (Longwu Online - MPQ fork)
-                if(bIsWarcraft3Map == false && dwHeaderID == ID_MPK)
+                if(MapType == MapTypeNotRecognized && dwHeaderID == ID_MPK)
                 {
                     // Now convert the MPK header to MPQ Header version 4
                     nError = ConvertMpkHeaderToFormat4(ha, FileSize, dwFlags);
@@ -324,8 +380,7 @@ bool WINAPI SFileOpenArchive(
                 }
 
                 // Move the pointers
-                SearchOffset += 0x200;
-                dwInBufferOffset += 0x200;
+                ByteOffset += 0x200;
             }
         }
 
@@ -334,15 +389,15 @@ bool WINAPI SFileOpenArchive(
         {
             // Set the user data position to the MPQ header, if none
             if(ha->pUserData == NULL)
-                ha->UserDataPos = SearchOffset;
+                ha->UserDataPos = ByteOffset;
 
             // Set the position of the MPQ header
             ha->pHeader  = (TMPQHeader *)ha->HeaderData;
-            ha->MpqPos   = SearchOffset;
+            ha->MpqPos   = ByteOffset;
             ha->FileSize = FileSize;
 
             // Sector size must be nonzero.
-            if(SearchOffset >= FileSize || ha->pHeader->wSectorSize == 0)
+            if(ByteOffset >= FileSize || ha->pHeader->wSectorSize == 0)
                 nError = ERROR_BAD_FORMAT;
         }
     }
@@ -376,8 +431,12 @@ bool WINAPI SFileOpenArchive(
         if(dwFlags & (MPQ_OPEN_NO_LISTFILE | MPQ_OPEN_NO_ATTRIBUTES))
             ha->dwFlags |= MPQ_FLAG_READ_ONLY;
 
+        // Check if the caller wants to force adding listfile
+        if(dwFlags & MPQ_OPEN_FORCE_LISTFILE)
+            ha->dwFlags |= MPQ_FLAG_LISTFILE_FORCE;
+
         // Remember whether whis is a map for Warcraft III
-        if(bIsWarcraft3Map)
+        if(MapType == MapTypeWarcraft3)
             ha->dwFlags |= MPQ_FLAG_WAR3_MAP;
 
         // Set the size of file sector
@@ -523,7 +582,7 @@ bool WINAPI SFileFlushArchive(HANDLE hMpq)
                 nResultError = nError;
         }
 
-        if(ha->dwFlags & MPQ_FLAG_LISTFILE_NEW)
+        if(ha->dwFlags & (MPQ_FLAG_LISTFILE_NEW | MPQ_FLAG_LISTFILE_FORCE))
         {
             nError = SListFileSaveToMpq(ha);
             if(nError != ERROR_SUCCESS)
diff --git a/OpenSource/StormLib/src/SFileOpenFileEx.cpp b/OpenSource/StormLib/src/SFileOpenFileEx.cpp
index a25cc7214..1e02a2202 100644
--- a/OpenSource/StormLib/src/SFileOpenFileEx.cpp
+++ b/OpenSource/StormLib/src/SFileOpenFileEx.cpp
@@ -124,37 +124,38 @@ bool OpenPatchedFile(HANDLE hMpq, const char * szFileName, HANDLE * PtrFile)
     }
 
     // If we couldn't find the base file in any of the patches, it doesn't exist
-    if((ha = haBase) == NULL)
+    if((ha = haBase) != NULL)
     {
-        SetLastError(ERROR_FILE_NOT_FOUND);
-        return false;
-    }
-
-    // Now open the base file
-    if(SFileOpenFileEx((HANDLE)ha, GetPatchFileName(ha, szFileName, szNameBuffer), SFILE_OPEN_BASE_FILE, (HANDLE *)&hfBase))
-    {
-        // The file must be a base file, i.e. without MPQ_FILE_PATCH_FILE
-        assert((hfBase->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0);
-        hf = hfBase;
-
-        // Now open all patches and attach them on top of the base file
-        for(ha = ha->haPatch; ha != NULL; ha = ha->haPatch)
+        // Now open the base file
+        if(SFileOpenFileEx((HANDLE)ha, GetPatchFileName(ha, szFileName, szNameBuffer), SFILE_OPEN_BASE_FILE, (HANDLE *)&hfBase))
         {
-            // Prepare the file name with a correct prefix
-            if(SFileOpenFileEx((HANDLE)ha, GetPatchFileName(ha, szFileName, szNameBuffer), SFILE_OPEN_BASE_FILE, &hPatchFile))
+            // The file must be a base file, i.e. without MPQ_FILE_PATCH_FILE
+            assert((hfBase->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0);
+            hf = hfBase;
+
+            // Now open all patches and attach them on top of the base file
+            for(ha = ha->haPatch; ha != NULL; ha = ha->haPatch)
             {
-                // Remember the new version
-                hfPatch = (TMPQFile *)hPatchFile;
+                // Prepare the file name with a correct prefix
+                if(SFileOpenFileEx((HANDLE)ha, GetPatchFileName(ha, szFileName, szNameBuffer), SFILE_OPEN_BASE_FILE, &hPatchFile))
+                {
+                    // Remember the new version
+                    hfPatch = (TMPQFile *)hPatchFile;
 
-                // We should not find patch file
-                assert((hfPatch->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) != 0);
+                    // We should not find patch file
+                    assert((hfPatch->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) != 0);
 
-                // Attach the patch to the base file
-                hf->hfPatch = hfPatch;
-                hf = hfPatch;
+                    // Attach the patch to the base file
+                    hf->hfPatch = hfPatch;
+                    hf = hfPatch;
+                }
             }
         }
     }
+    else
+    {
+        SetLastError(ERROR_FILE_NOT_FOUND);
+    }
 
     // Give the updated base MPQ
     if(PtrFile != NULL)
@@ -167,7 +168,7 @@ bool OpenPatchedFile(HANDLE hMpq, const char * szFileName, HANDLE * PtrFile)
 /*****************************************************************************/
 
 //-----------------------------------------------------------------------------
-// SFileEnumLocales enums all locale versions within MPQ. 
+// SFileEnumLocales enums all locale versions within MPQ.
 // Functions fills all available language identifiers on a file into the buffer
 // pointed by plcLocales. There must be enough entries to copy the localed,
 // otherwise the function returns ERROR_INSUFFICIENT_BUFFER.
@@ -197,7 +198,7 @@ int WINAPI SFileEnumLocales(
         return ERROR_INVALID_PARAMETER;
     if(IsPseudoFileName(szFileName, &dwFileIndex))
         return ERROR_INVALID_PARAMETER;
-    
+
     // Keep compiler happy
     dwMaxLocales = PtrMaxLocales[0];
     dwSearchScope = dwSearchScope;
@@ -258,11 +259,11 @@ bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearch
             case SFILE_OPEN_FROM_MPQ:
             case SFILE_OPEN_BASE_FILE:
             case SFILE_OPEN_CHECK_EXISTS:
-                
+
                 // If this MPQ has no patches, open the file from this MPQ directly
                 if(ha->haPatch == NULL || dwSearchScope == SFILE_OPEN_BASE_FILE)
                 {
-                    pFileEntry = GetFileEntryLocale2(ha, szFileName, lcFileLocale, &dwHashIndex);
+                    pFileEntry = GetFileEntryLocale2(ha, szFileName, g_lcFileLocale, &dwHashIndex);
                 }
 
                 // If this MPQ is a patched archive, open the file as patched
@@ -283,7 +284,7 @@ bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearch
             case SFILE_OPEN_LOCAL_FILE:
 
                 // Open a local file
-                return OpenLocalFile(szFileName, PtrFile); 
+                return OpenLocalFile(szFileName, PtrFile);
 
             default:
 
@@ -296,24 +297,45 @@ bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearch
     // Check whether the file really exists in the MPQ
     if(nError == ERROR_SUCCESS)
     {
-        if(pFileEntry == NULL || (pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0)
+        // If we didn't find the file, try to open it using pseudo file name ("File
+        if (pFileEntry == NULL || (pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0)
         {
-            // Check the pseudo-file name
-            if((bOpenByIndex = IsPseudoFileName(szFileName, &dwFileIndex)) == true)
+            // Check the pseudo-file name ("File00000001.ext")
+            if ((bOpenByIndex = IsPseudoFileName(szFileName, &dwFileIndex)) == true)
             {
                 // Get the file entry for the file
-                if(dwFileIndex < ha->dwFileTableSize)
+                if (dwFileIndex < ha->dwFileTableSize)
                 {
                     pFileEntry = ha->pFileTable + dwFileIndex;
                 }
             }
 
-            nError = ERROR_FILE_NOT_FOUND;
+            // Still not found?
+            if (pFileEntry == NULL)
+            {
+                nError = ERROR_FILE_NOT_FOUND;
+            }
         }
 
-        // Ignore unknown loading flags (example: MPQ_2016_v1_WME4_4.w3x)
-//      if(pFileEntry != NULL && pFileEntry->dwFlags & ~MPQ_FILE_VALID_FLAGS)
-//          nError = ERROR_NOT_SUPPORTED;
+        // Perform some checks of invalid files
+        if (pFileEntry != NULL)
+        {
+            // MPQ protectors use insanely amount of fake files, often with very high size.
+            // We won't open any files whose compressed size is bigger than archive size
+            // If the file is not compressed, its size cannot be bigger than archive size
+            if ((pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) == 0 && (pFileEntry->dwFileSize > ha->FileSize))
+            {
+                nError = ERROR_FILE_CORRUPT;
+                pFileEntry = NULL;
+            }
+
+            // Ignore unknown loading flags (example: MPQ_2016_v1_WME4_4.w3x)
+//          if(pFileEntry->dwFlags & ~MPQ_FILE_VALID_FLAGS)
+//          {
+//              nError = ERROR_NOT_SUPPORTED;
+//              pFileEntry = NULL;
+//          }
+        }
     }
 
     // Did the caller just wanted to know if the file exists?
@@ -383,7 +405,7 @@ bool WINAPI SFileHasFile(HANDLE hMpq, const char * szFileName)
 bool WINAPI SFileCloseFile(HANDLE hFile)
 {
     TMPQFile * hf = (TMPQFile *)hFile;
-    
+
     if(!IsValidFileHandle(hFile))
     {
         SetLastError(ERROR_INVALID_HANDLE);
diff --git a/OpenSource/StormLib/src/SFilePatchArchives.cpp b/OpenSource/StormLib/src/SFilePatchArchives.cpp
index dc16631bc..040434fbd 100644
--- a/OpenSource/StormLib/src/SFilePatchArchives.cpp
+++ b/OpenSource/StormLib/src/SFilePatchArchives.cpp
@@ -31,7 +31,7 @@ typedef struct _MPQ_PATCH_HEADER
     DWORD dwSizeOfPatchData;                    // Size of the entire patch (decompressed)
     DWORD dwSizeBeforePatch;                    // Size of the file before patch
     DWORD dwSizeAfterPatch;                     // Size of file after patch
-    
+
     //-- MD5 block --------------------------------------
     DWORD dwMD5;                                // 'MD5_'
     DWORD dwMd5BlockSize;                       // Size of the MD5 block, including the signature and size itself
@@ -78,14 +78,14 @@ static const char * LanguageList = "baseteenenUSenGBenCNenTWdeDEesESesMXfrFRitIT
 // List of localized MPQs for World of Warcraft
 static LOCALIZED_MPQ_INFO LocaleMpqs_WoW[] =
 {
-    {"expansion1-locale-####", 18, 22}, 
-    {"expansion1-speech-####", 18, 22}, 
-    {"expansion2-locale-####", 18, 22}, 
-    {"expansion2-speech-####", 18, 22}, 
-    {"expansion3-locale-####", 18, 22}, 
-    {"expansion3-speech-####", 18, 22}, 
-    {"locale-####",             7, 11}, 
-    {"speech-####",             7, 11}, 
+    {"expansion1-locale-####", 18, 22},
+    {"expansion1-speech-####", 18, 22},
+    {"expansion2-locale-####", 18, 22},
+    {"expansion2-speech-####", 18, 22},
+    {"expansion3-locale-####", 18, 22},
+    {"expansion3-speech-####", 18, 22},
+    {"locale-####",             7, 11},
+    {"speech-####",             7, 11},
     {NULL, 0, 0}
 };
 
@@ -113,7 +113,7 @@ static void Decompress_RLE(LPBYTE pbDecompressed, DWORD cbDecompressed, LPBYTE p
 {
     LPBYTE pbDecompressedEnd = pbDecompressed + cbDecompressed;
     LPBYTE pbCompressedEnd = pbCompressed + cbCompressed;
-    BYTE RepeatCount; 
+    BYTE RepeatCount;
     BYTE OneByte;
 
     // Cut the initial DWORD from the compressed chunk
@@ -126,7 +126,7 @@ static void Decompress_RLE(LPBYTE pbDecompressed, DWORD cbDecompressed, LPBYTE p
     while(pbCompressed < pbCompressedEnd && pbDecompressed < pbDecompressedEnd)
     {
         OneByte = *pbCompressed++;
-        
+
         // Is it a repetition byte ?
         if(OneByte & 0x80)
         {
@@ -285,8 +285,8 @@ static int ApplyFilePatch_BSD0(
         // Now combine the patch data with the original file
         for(i = 0; i < dwCombineSize; i++)
             pbNewData[dwNewOffset + i] = pbNewData[dwNewOffset + i] + pbOldData[dwOldOffset + i];
-        
-        // Move the offsets 
+
+        // Move the offsets
         dwNewOffset += dwAddDataLength;
         dwOldOffset += dwAddDataLength;
 
@@ -399,7 +399,7 @@ static int ApplyFilePatch(
         // Verify the patched file
         if(!VerifyDataBlockHash(pbTarget, pFullPatch->dwSizeAfterPatch, pFullPatch->md5_after_patch))
             nError = ERROR_FILE_CORRUPT;
-        
+
         // Copy the MD5 of the new block
         memcpy(pPatcher->this_md5, pFullPatch->md5_after_patch, MD5_DIGEST_SIZE);
     }
@@ -491,7 +491,7 @@ static bool IsMatchingPatchFile(
         {
             // TODO: How to match it if it's not an incremental patch?
             // Example: StarCraft II\Updates\enGB\s2-update-enGB-23258.MPQ:
-            //          Mods\Core.SC2Mod\enGB.SC2Assets\StreamingBuckets.txt" 
+            //          Mods\Core.SC2Mod\enGB.SC2Assets\StreamingBuckets.txt"
             bResult = false;
         }
 
@@ -697,7 +697,7 @@ static bool ExtractPatchPrefixFromFile(const TCHAR * szHelperFile, char * szPatc
                 {
                     char * szLinePtr = szFileData + 11;
                     char * szLineEnd;
-                    
+
                     // Skip spaces or '='
                     while(szLinePtr[0] == ' ' || szLinePtr[0] == '=')
                         szLinePtr++;
@@ -867,8 +867,8 @@ static bool FindPatchPrefix_SC2(TMPQArchive * haBase, TMPQArchive * haPatch, TFi
 // Example 3:
 // Main MPQ:  %GAME%\Battle.net\Battle.net.MPQ
 // Patch MPQ: s2-update-base-26147.MPQ
-// File in main MPQ: Battle.net\i18n\deDE\String\CLIENT_ACHIEVEMENTS.xml 
-// File in patch MPQ: Battle.net\Battle.net.MPQ\Battle.net\i18n\deDE\String\CLIENT_ACHIEVEMENTS.xml 
+// File in main MPQ: Battle.net\i18n\deDE\String\CLIENT_ACHIEVEMENTS.xml
+// File in patch MPQ: Battle.net\Battle.net.MPQ\Battle.net\i18n\deDE\String\CLIENT_ACHIEVEMENTS.xml
 // Path prefix: Battle.net\Battle.net.MPQ
 //
 // Example 4:
@@ -894,7 +894,7 @@ static bool FindPatchPrefix(TMPQArchive * haBase, TMPQArchive * haPatch, const c
         return FindPatchPrefix_WoW_13164_13623(haBase, haPatch);
 
     // Updates for Starcraft II
-    // Match: LocalizedData\GameHotkeys.txt <==> Campaigns\Liberty.SC2Campaign\enGB.SC2Data\LocalizedData\GameHotkeys.txt 
+    // Match: LocalizedData\GameHotkeys.txt <==> Campaigns\Liberty.SC2Campaign\enGB.SC2Data\LocalizedData\GameHotkeys.txt
     // All Starcraft II base archives seem to have the file "StreamingBuckets.txt" present
     pFileEntry = GetFileEntryLocale(haBase, "StreamingBuckets.txt", 0);
     if(pFileEntry != NULL)
@@ -1076,7 +1076,7 @@ void Patch_Finalize(TMPQPatcher * pPatcher)
             STORM_FREE(pPatcher->pbFileData1);
         if(pPatcher->pbFileData2 != NULL)
             STORM_FREE(pPatcher->pbFileData2);
-        
+
         memset(pPatcher, 0, sizeof(TMPQPatcher));
     }
 }
diff --git a/OpenSource/StormLib/src/SFileReadFile.cpp b/OpenSource/StormLib/src/SFileReadFile.cpp
index a6b3bc45c..a9d070f24 100644
--- a/OpenSource/StormLib/src/SFileReadFile.cpp
+++ b/OpenSource/StormLib/src/SFileReadFile.cpp
@@ -212,10 +212,10 @@ static int ReadMpqSectors(TMPQFile * hf, LPBYTE pbBuffer, DWORD dwByteOffset, DW
     // Free all used buffers
     if(pbRawSector != NULL)
         STORM_FREE(pbRawSector);
-    
+
     // Give the caller thenumber of bytes read
     *pdwBytesRead = dwBytesRead;
-    return nError; 
+    return nError;
 }
 
 static int ReadMpqFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead)
@@ -252,7 +252,7 @@ static int ReadMpqFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos
                 return ERROR_NOT_ENOUGH_MEMORY;
             pbRawData = pbCompressed;
         }
-        
+
         // Load the raw (compressed, encrypted) data
         if(!FileStream_Read(ha->pStream, &RawFilePos, pbRawData, pFileEntry->dwCmpSize))
         {
@@ -285,7 +285,7 @@ static int ReadMpqFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos
             // --------------------------------------  ---------- -------- -------- ---------------
             // esES\DBFilesClient\LightSkyBox.dbc      0xBE->0xA2  0xBC     0xBC     Yes
             // deDE\DBFilesClient\MountCapability.dbc  0x93->0x77  0x77     0x77     No
-            // 
+            //
 
             if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE)
                 cbInBuffer = cbInBuffer - sizeof(TPatchInfo);
@@ -344,11 +344,10 @@ static int ReadMpqFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos
 
         // Give the number of bytes read
         *pdwBytesRead = dwToRead;
-        return ERROR_SUCCESS;
     }
 
     // An error, sorry
-    return ERROR_CAN_NOT_COMPLETE;
+    return nError;
 }
 
 static int ReadMpkFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead)
@@ -384,7 +383,7 @@ static int ReadMpkFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos
                 return ERROR_NOT_ENOUGH_MEMORY;
             pbRawData = pbCompressed;
         }
-        
+
         // Load the raw (compressed, encrypted) data
         if(!FileStream_Read(ha->pStream, &RawFilePos, pbRawData, pFileEntry->dwCmpSize))
         {
@@ -486,7 +485,7 @@ static int ReadMpqFileSectorFile(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos
     {
         DWORD dwBytesInSector = ha->dwSectorSize;
         DWORD dwBufferOffs = dwFilePos & dwSectorSizeMask;
-        DWORD dwToCopy;                                     
+        DWORD dwToCopy;
 
         // Is the file sector already loaded ?
         if(hf->dwSectorOffs != dwFileSectorPos)
@@ -560,7 +559,7 @@ static int ReadMpqFileSectorFile(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos
 
         // Copy the data from the cached last sector to the caller's buffer
         memcpy(pbBuffer, hf->pbFileSector, dwToCopy);
-        
+
         // Update pointers
         dwTotalBytesRead += dwToCopy;
     }
@@ -718,7 +717,7 @@ bool WINAPI SFileReadFile(HANDLE hFile, void * pvBuffer, DWORD dwToRead, LPDWORD
         nError = ReadMpkFileSingleUnit(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead);
     }
 
-    // If the file is single unit file, redirect it to read file 
+    // If the file is single unit file, redirect it to read file
     else if(hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT)
     {
         nError = ReadMpqFileSingleUnit(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead);
@@ -726,7 +725,7 @@ bool WINAPI SFileReadFile(HANDLE hFile, void * pvBuffer, DWORD dwToRead, LPDWORD
 
     // Otherwise read it as sector based MPQ file
     else
-    {                                                                   
+    {
         nError = ReadMpqFileSectorFile(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead);
     }
 
@@ -838,7 +837,7 @@ DWORD WINAPI SFileSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * plFilePosHi
             break;
 
         case FILE_CURRENT:
-            
+
             // Retrieve the current file position
             if(hf->pStream != NULL)
             {
diff --git a/OpenSource/StormLib/src/SFileVerify.cpp b/OpenSource/StormLib/src/SFileVerify.cpp
index 45ff58ef0..2b2058df6 100644
--- a/OpenSource/StormLib/src/SFileVerify.cpp
+++ b/OpenSource/StormLib/src/SFileVerify.cpp
@@ -216,7 +216,7 @@ static bool CalculateMpqHashMd5(
         if(dwToRead == 0)
             break;
 
-        // Read the next chunk 
+        // Read the next chunk
         if(!FileStream_Read(ha->pStream, &BeginBuffer, pbDigestBuffer, dwToRead))
         {
             STORM_FREE(pbDigestBuffer);
@@ -312,7 +312,7 @@ static bool CalculateMpqHashSha1(
         if(dwToRead == 0)
             break;
 
-        // Read the next chunk 
+        // Read the next chunk
         if(!FileStream_Read(ha->pStream, &BeginBuffer, pbDigestBuffer, dwToRead))
         {
             STORM_FREE(pbDigestBuffer);
@@ -482,7 +482,7 @@ static DWORD VerifyStrongSignatureWithKey(
     // Verify the signature
     if(rsa_verify_simple(reversed_signature, MPQ_STRONG_SIGNATURE_SIZE, padded_digest, MPQ_STRONG_SIGNATURE_SIZE, &result, &key) != CRYPT_OK)
         return ERROR_VERIFY_FAILED;
-    
+
     // Free the key and return result
     rsa_free(&key);
     return result ? ERROR_STRONG_SIGNATURE_OK : ERROR_STRONG_SIGNATURE_ERROR;
@@ -592,7 +592,7 @@ static DWORD VerifyFile(
                 dwVerifyResult |= VERIFY_FILE_HAS_RAW_MD5;
 
                 // Find file entry for the file
-                pFileEntry = GetFileEntryLocale(ha, szFileName, lcFileLocale);
+                pFileEntry = GetFileEntryLocale(ha, szFileName, g_lcFileLocale);
                 if(pFileEntry != NULL)
                 {
                     // If the file's raw MD5 doesn't match, don't bother with more checks
@@ -639,7 +639,7 @@ static DWORD VerifyFile(
             // Update CRC32 value
             if(dwFlags & SFILE_VERIFY_FILE_CRC)
                 dwCrc32 = crc32(dwCrc32, Buffer, dwBytesRead);
-            
+
             // Update MD5 value
             if(dwFlags & SFILE_VERIFY_FILE_MD5)
                 md5_process(&md5_state, Buffer, dwBytesRead);
@@ -714,7 +714,7 @@ static DWORD VerifyFile(
     if(pdwCrc32 != NULL)
         *pdwCrc32 = dwCrc32;
     if(pMD5 != NULL)
-        memcpy(pMD5, md5, MD5_DIGEST_SIZE); 
+        memcpy(pMD5, md5, MD5_DIGEST_SIZE);
 
     return dwVerifyResult;
 }
@@ -767,7 +767,7 @@ bool QueryMpqSignatureInfo(
 
         // Check the signature header "NGIS"
         if(pSI->Signature[0] != 'N' || pSI->Signature[1] != 'G' || pSI->Signature[2] != 'I' || pSI->Signature[3] != 'S')
-            return false;
+            return true; //Not a valid signature, but another filetype could've been appended so not always an error.
 
         pSI->SignatureTypes |= SIGNATURE_TYPE_STRONG;
         return true;
@@ -853,7 +853,7 @@ int SSignFileFinish(TMPQArchive * ha)
     // Sign the hash
     memset(WeakSignature, 0, sizeof(WeakSignature));
     rsa_sign_hash_ex(Md5Digest, sizeof(Md5Digest), WeakSignature + 8, &signature_len, LTC_LTC_PKCS_1_V1_5, 0, 0, hash_idx, 0, &key);
-	memrev(WeakSignature + 8, MPQ_WEAK_SIGNATURE_SIZE); 
+	memrev(WeakSignature + 8, MPQ_WEAK_SIGNATURE_SIZE);
     rsa_free(&key);
 
     // Write the signature to the MPQ. Don't use SFile* functions, but write the hash directly
@@ -922,7 +922,7 @@ int WINAPI SFileVerifyRawData(HANDLE hMpq, DWORD dwWhatToVerify, const char * sz
     switch(dwWhatToVerify)
     {
         case SFILE_VERIFY_MPQ_HEADER:
-            
+
             // Only if the header is of version 4 or newer
             if(pHeader->dwHeaderSize >= (MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE))
                 return VerifyRawMpqData(ha, 0, MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE);
@@ -964,7 +964,7 @@ int WINAPI SFileVerifyRawData(HANDLE hMpq, DWORD dwWhatToVerify, const char * sz
                 return ERROR_INVALID_PARAMETER;
 
             // Get the offset of a file
-            pFileEntry = GetFileEntryLocale(ha, szFileName, lcFileLocale);
+            pFileEntry = GetFileEntryLocale(ha, szFileName, g_lcFileLocale);
             if(pFileEntry == NULL)
                 return ERROR_FILE_NOT_FOUND;
 
diff --git a/OpenSource/StormLib/src/StormCommon.h b/OpenSource/StormLib/src/StormCommon.h
index 9d9f43cfd..3679726bb 100644
--- a/OpenSource/StormLib/src/StormCommon.h
+++ b/OpenSource/StormLib/src/StormCommon.h
@@ -70,12 +70,24 @@
 // Macro for building 64-bit file offset from two 32-bit
 #define MAKE_OFFSET64(hi, lo)      (((ULONGLONG)hi << 32) | (ULONGLONG)lo)
 
+//-----------------------------------------------------------------------------
+// MTYPE definition - specifies what kind of MPQ is the map type
+
+typedef enum _MTYPE
+{
+    MapTypeNotChecked,                  // The map type was not checked yet
+    MapTypeNotRecognized,               // The file does not seems to be a map
+    MapTypeAviFile,                     // The file is actually an AVI file (Warcraft III cinematics)
+    MapTypeWarcraft3,                   // The file is a Warcraft III map
+    MapTypeStarcraft2                   // The file is a Starcraft II map
+} MTYPE, *PMTYPE;
+
 //-----------------------------------------------------------------------------
 // MPQ signature information
 
 // Size of each signature type
 #define MPQ_WEAK_SIGNATURE_SIZE                 64
-#define MPQ_STRONG_SIGNATURE_SIZE              256 
+#define MPQ_STRONG_SIGNATURE_SIZE              256
 #define MPQ_STRONG_SIGNATURE_ID         0x5349474E      // ID of the strong signature ("NGIS")
 #define MPQ_SIGNATURE_FILE_SIZE (MPQ_WEAK_SIGNATURE_SIZE + 8)
 
@@ -122,7 +134,10 @@ typedef struct _MPQ_SIGNATURE_INFO
 //-----------------------------------------------------------------------------
 // StormLib internal global variables
 
-extern LCID lcFileLocale;                       // Preferred file locale
+extern DWORD g_dwMpqSignature;                  // Marker for MPQ header
+extern DWORD g_dwHashTableKey;                  // Key for hash table
+extern DWORD g_dwBlockTableKey;                 // Key for block table
+extern LCID  g_lcFileLocale;                    // Preferred file locale
 
 //-----------------------------------------------------------------------------
 // Conversion to uppercase/lowercase (and "/" to "\")
@@ -133,8 +148,46 @@ extern unsigned char AsciiToUpperTable[256];
 //-----------------------------------------------------------------------------
 // Safe string functions
 
-void StringCopy(char * szTarget, size_t cchTarget, const char * szSource);
+template <typename XCHAR, typename XINT>
+XCHAR * IntToString(XCHAR * szBuffer, size_t cchMaxChars, XINT nValue, size_t nDigitCount = 0)
+{
+    XCHAR * szBufferEnd = szBuffer + cchMaxChars - 1;
+    XCHAR szNumberRev[0x20];
+    size_t nLength = 0;
+
+    // Always put the first digit
+    szNumberRev[nLength++] = (XCHAR)(nValue % 10) + '0';
+    nValue /= 10;
+
+    // Continue as long as we have non-zero
+    while(nValue != 0)
+    {
+        szNumberRev[nLength++] = (XCHAR)(nValue % 10) + '0';
+        nValue /= 10;
+    }
+
+    // Fill zeros, if needed
+    while(szBuffer < szBufferEnd && nLength < nDigitCount)
+    {
+        *szBuffer++ = '0';
+        nDigitCount--;
+    }
+
+    // Fill the buffer
+    while(szBuffer < szBufferEnd && nLength > 0)
+    {
+        nLength--;
+        *szBuffer++ = szNumberRev[nLength];
+    }
+
+    // Terminate the number with zeros
+    szBuffer[0] = 0;
+    return szBuffer;
+}
+
+char * StringCopy(char * szTarget, size_t cchTarget, const char * szSource);
 void StringCat(char * szTarget, size_t cchTargetMax, const char * szSource);
+void StringCreatePseudoFileName(char * szBuffer, size_t cchMaxChars, unsigned int nIndex, const char * szExtension);
 
 #ifdef _UNICODE
 void StringCopy(TCHAR * szTarget, size_t cchTarget, const char * szSource);
@@ -189,7 +242,7 @@ TMPQFile * IsValidFileHandle(HANDLE hFile);
 ULONGLONG FileOffsetFromMpqOffset(TMPQArchive * ha, ULONGLONG MpqOffset);
 ULONGLONG CalculateRawSectorOffset(TMPQFile * hf, DWORD dwSectorOffset);
 
-int ConvertMpqHeaderToFormat4(TMPQArchive * ha, ULONGLONG MpqOffset, ULONGLONG FileSize, DWORD dwFlags, bool bIsWarcraft3Map);
+int ConvertMpqHeaderToFormat4(TMPQArchive * ha, ULONGLONG MpqOffset, ULONGLONG FileSize, DWORD dwFlags, MTYPE MapType);
 
 bool IsValidHashEntry(TMPQArchive * ha, TMPQHash * pHash);
 
@@ -261,7 +314,7 @@ int SCompDecompressMpk(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer
 
 TMPQFile * CreateFileHandle(TMPQArchive * ha, TFileEntry * pFileEntry);
 TMPQFile * CreateWritableHandle(TMPQArchive * ha, DWORD dwFileSize);
-void * LoadMpqTable(TMPQArchive * ha, ULONGLONG ByteOffset, DWORD dwCompressedSize, DWORD dwRealSize, DWORD dwKey, bool * pbTableIsCut);
+void * LoadMpqTable(TMPQArchive * ha, ULONGLONG ByteOffset, LPBYTE pbTableHash, DWORD dwCompressedSize, DWORD dwRealSize, DWORD dwKey, bool * pbTableIsCut);
 int  AllocateSectorBuffer(TMPQFile * hf);
 int  AllocatePatchInfo(TMPQFile * hf, bool bLoadFromFile);
 int  AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile);
@@ -297,7 +350,6 @@ void Patch_Finalize(TMPQPatcher * pPatcher);
 //-----------------------------------------------------------------------------
 // Utility functions
 
-bool CheckWildCard(const char * szString, const char * szWildCard);
 bool IsInternalMpqFileName(const char * szFileName);
 
 template <typename XCHAR>
diff --git a/OpenSource/StormLib/src/StormLib.h b/OpenSource/StormLib/src/StormLib.h
index b9f60a411..145cf58c7 100644
--- a/OpenSource/StormLib/src/StormLib.h
+++ b/OpenSource/StormLib/src/StormLib.h
@@ -79,9 +79,9 @@
 #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: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                                             
+#endif
 
 #include "StormPort.h"
 
@@ -94,7 +94,7 @@ extern "C" {
 //
 // 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
@@ -105,32 +105,34 @@ extern "C" {
 #endif
 
 #if defined(_MSC_VER) && !defined(STORMLIB_NO_AUTO_LINK)
-  #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
+  #ifndef WDK_BUILD
+    #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
-      #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
+    #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
@@ -140,8 +142,8 @@ extern "C" {
 //-----------------------------------------------------------------------------
 // Defines
 
-#define STORMLIB_VERSION                0x0916  // Current version of StormLib (9.21)
-#define STORMLIB_VERSION_STRING         "9.22"  // String version of StormLib version
+#define STORMLIB_VERSION                0x0917  // Current version of StormLib (9.23)
+#define STORMLIB_VERSION_STRING         "9.23"  // 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')
@@ -156,6 +158,7 @@ extern "C" {
 #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
+#define ERROR_FAKE_MPQ_HEADER            10009  // The header at this position is fake header
 
 // Values for SFileCreateArchive
 #define HASH_TABLE_SIZE_MIN         0x00000004  // Verified: If there is 1 file, hash table size is 4
@@ -181,7 +184,7 @@ extern "C" {
 #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
+// Flags for TMPQArchive::dwFlags. Used internally
 #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)
@@ -193,10 +196,11 @@ extern "C" {
 #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
+#define MPQ_FLAG_LISTFILE_FORCE     0x00000800  // Save updated listfile on exit
+#define MPQ_FLAG_ATTRIBUTES_NONE    0x00001000  // Set when no (attributes) was found in InvalidateInternalFiles
+#define MPQ_FLAG_ATTRIBUTES_NEW     0x00002000  // Set when (attributes) invalidated by InvalidateInternalFiles
+#define MPQ_FLAG_SIGNATURE_NONE     0x00004000  // Set when no (signature) was found in InvalidateInternalFiles
+#define MPQ_FLAG_SIGNATURE_NEW      0x00008000  // Set when (signature) invalidated by InvalidateInternalFiles
 
 // Values for TMPQArchive::dwSubType
 #define MPQ_SUBTYPE_MPQ             0x00000000  // The file is a MPQ file (Blizzard games)
@@ -211,7 +215,7 @@ extern "C" {
 // 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_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)
@@ -283,7 +287,7 @@ extern "C" {
 #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_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
 
@@ -322,6 +326,7 @@ extern "C" {
 #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_FORCE_LISTFILE     0x00400000  // Force add listfile even if there is none at the moment of opening
 #define MPQ_OPEN_READ_ONLY          STREAM_FLAG_READ_ONLY
 
 // Flags for SFileCreateArchive
@@ -377,7 +382,7 @@ extern "C" {
 #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
@@ -469,25 +474,13 @@ typedef enum _SFileInfoClass
 #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);
+struct TFileStream;
+struct TMPQBits;
 
 //-----------------------------------------------------------------------------
 // Structures related to MPQ format
@@ -552,14 +545,14 @@ typedef struct _TMPQHeader
 
     // 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;
 
@@ -604,7 +597,7 @@ typedef struct _TMPQHeader
 
     // Size of raw data chunk to calculate MD5.
     // MD5 of each data chunk follows the raw file data.
-    DWORD dwRawChunkSize;                                 
+    DWORD dwRawChunkSize;
 
     // MD5 of MPQ tables
     unsigned char MD5_BlockTable[MD5_DIGEST_SIZE];      // MD5 of the block table before decryption
@@ -621,11 +614,11 @@ 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
+#ifdef STORMLIB_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.
@@ -658,16 +651,16 @@ 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;                      
-    
+    DWORD dwFSize;
+
     // Flags for the file. See MPQ_FILE_XXXX constants
-    DWORD dwFlags;                      
+    DWORD dwFlags;
 } TMPQBlock;
 
 // Patch file information, preceding the sector offset table
@@ -714,14 +707,14 @@ 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)
+    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;
 
@@ -730,32 +723,32 @@ 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 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
+    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
+    TMPQBits * 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
@@ -771,8 +764,8 @@ typedef struct _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
+    TMPQBits * pNameHashes;                     // Array of NameHash2 entries (lower 24 bits of FileName hash)
+    TMPQBits * pFileTable;                      // Bit-based file table
     LPDWORD pFileFlags;                         // Array of file flags
 
     DWORD dwTableEntrySize;                     // Size of one table entry, in bits
@@ -832,7 +825,7 @@ typedef struct _TMPQArchive
     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
 
@@ -856,7 +849,7 @@ typedef struct _TMPQArchive
     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;                                      
+} TMPQArchive;
 
 // File handle structure
 typedef struct _TMPQFile
@@ -931,11 +924,24 @@ typedef struct _SFILE_CREATE_MPQ
 
 } SFILE_CREATE_MPQ, *PSFILE_CREATE_MPQ;
 
+typedef struct _SFILE_MARKERS
+{
+    DWORD dwSize;                               // Size of this structure, in bytes
+    DWORD dwSignature;                          // Alternate MPQ header marker
+    const char * szHashTableKey;                // Replacement for "(hash table)"
+    const char * szBlockTableKey;               // Replacement for "(block table)"
+} SFILE_MARKERS, *PSFILE_MARKERS;
+
+//-----------------------------------------------------------------------------
+// TMPQBits support - functions
+
+void GetMPQBits(TMPQBits * pBits, unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultByteSize);
+
 //-----------------------------------------------------------------------------
 // Stream support - functions
 
 // Structure used by FileStream_GetBitmap
-typedef struct _TStreamBitmap
+struct TStreamBitmap
 {
     ULONGLONG StreamSize;                       // Size of the stream, in bytes
     DWORD BitmapSize;                           // Size of the block map, in bytes
@@ -944,8 +950,7 @@ typedef struct _TStreamBitmap
     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);
@@ -955,7 +960,7 @@ 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_GetBitmap(TFileStream * pStream, void * pvBitmap, DWORD cbBitmap, DWORD * 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);
@@ -982,6 +987,11 @@ typedef bool  (WINAPI * SFILEREADFILE)(HANDLE, void *, DWORD, LPDWORD, LPOVERLAP
 //-----------------------------------------------------------------------------
 // Functions for manipulation with StormLib global flags
 
+// Alternate marker support. This is for MPQs masked as DLLs (*.asi), which
+// patch Storm.dll at runtime. Call before SFileOpenArchive
+bool   WINAPI SFileSetArchiveMarkers(PSFILE_MARKERS pMarkers);
+
+// Call before SFileOpenFileEx
 LCID   WINAPI SFileGetLocale();
 LCID   WINAPI SFileSetLocale(LCID lcNewLocale);
 
@@ -1078,8 +1088,8 @@ bool   WINAPI SFileWriteFile(HANDLE hFile, const void * pvData, DWORD dwSize, DW
 bool   WINAPI SFileFinishFile(HANDLE hFile);
 
 bool   WINAPI SFileAddFileEx(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwCompression, DWORD dwCompressionNext = MPQ_COMPRESSION_NEXT_SAME);
-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 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);
@@ -1099,10 +1109,10 @@ int    WINAPI SCompDecompress2(void * pvOutBuffer, int * pcbOutBuffer, void * pv
 //-----------------------------------------------------------------------------
 // Non-Windows support for SetLastError/GetLastError
 
-#ifndef PLATFORM_WINDOWS
+#ifndef STORMLIB_WINDOWS
 
-void  SetLastError(DWORD err);
-DWORD   GetLastError();
+void  SetLastError(DWORD dwErrCode);
+DWORD GetLastError();
 
 #endif
 
diff --git a/OpenSource/StormLib/src/StormPort.h b/OpenSource/StormLib/src/StormPort.h
index 1da974bca..ee00db8c4 100644
--- a/OpenSource/StormLib/src/StormPort.h
+++ b/OpenSource/StormLib/src/StormPort.h
@@ -36,7 +36,7 @@
 //-----------------------------------------------------------------------------
 // Defines for Windows
 
-#if !defined(PLATFORM_DEFINED) && defined(_WIN32)
+#if !defined(STORMLIB_PLATFORM_DEFINED) && defined(_WIN32)
 
   // In MSVC 8.0, there are some functions declared as deprecated.
   #if _MSC_VER >= 1400
@@ -48,25 +48,31 @@
   #include <assert.h>
   #include <ctype.h>
   #include <stdio.h>
+
+  // Suppress definitions of `min` and `max` macros by <windows.h>:
+  #define NOMINMAX 1
   #include <windows.h>
+
   #include <wininet.h>
-  #define PLATFORM_LITTLE_ENDIAN
+  #define STORMLIB_LITTLE_ENDIAN
 
   #ifdef _WIN64
-    #define PLATFORM_64BIT
+    #define STORMLIB_64BIT
   #else
-    #define PLATFORM_32BIT
+    #define STORMLIB_32BIT
   #endif
 
-  #define PLATFORM_WINDOWS
-  #define PLATFORM_DEFINED                  // The platform is known now
+  #define STORMLIB_CDECL __cdecl
+
+  #define STORMLIB_WINDOWS
+  #define STORMLIB_PLATFORM_DEFINED             // The platform is known now
 
 #endif
 
 //-----------------------------------------------------------------------------
 // Defines for Mac
 
-#if !defined(PLATFORM_DEFINED) && defined(__APPLE__)  // Mac BSD API
+#if !defined(STORMLIB_PLATFORM_DEFINED) && defined(__APPLE__)  // Mac BSD API
 
   // Macintosh
   #include <sys/types.h>
@@ -81,25 +87,50 @@
   #if (__ppc__ == 1) || (__POWERPC__ == 1) || (_ARCH_PPC == 1)
     #include <stdint.h>
     #include <CoreFoundation/CFByteOrder.h>
-  #endif 
+  #endif
 
   #define    PKEXPORT
   #define    __SYS_ZLIB
   #define    __SYS_BZLIB
 
   #ifndef __BIG_ENDIAN__
-    #define PLATFORM_LITTLE_ENDIAN
+    #define STORMLIB_LITTLE_ENDIAN
+  #endif
+
+  #define STORMLIB_MAC
+  #define STORMLIB_PLATFORM_DEFINED                  // The platform is known now
+
+#endif
+
+#if !defined(STORMLIB_PLATFORM_DEFINED) && defined(__HAIKU__)
+
+  #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>
+
+  #ifndef __BIG_ENDIAN__
+    #define STORMLIB_LITTLE_ENDIAN
   #endif
 
-  #define PLATFORM_MAC
-  #define PLATFORM_DEFINED                  // The platform is known now
+  #define STORMLIB_HAIKU
+  #define STORMLIB_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)
+#if !defined(STORMLIB_PLATFORM_DEFINED)
 
   #include <sys/types.h>
   #include <sys/stat.h>
@@ -111,26 +142,30 @@
   #include <stdio.h>
   #include <stdarg.h>
   #include <string.h>
+  #include <strings.h>
   #include <ctype.h>
   #include <assert.h>
   #include <errno.h>
 
-  #define PLATFORM_LITTLE_ENDIAN
-  #define PLATFORM_LINUX
-  #define PLATFORM_DEFINED
+  #define STORMLIB_LITTLE_ENDIAN
+  #define STORMLIB_LINUX
+  #define STORMLIB_PLATFORM_DEFINED
 
 #endif
 
 //-----------------------------------------------------------------------------
 // Definition of Windows-specific types for non-Windows platforms
 
-#ifndef PLATFORM_WINDOWS
+#ifndef STORMLIB_WINDOWS
   #if __LP64__
-    #define PLATFORM_64BIT
+    #define STORMLIB_64BIT
   #else
-    #define PLATFORM_32BIT
+    #define STORMLIB_32BIT
   #endif
 
+  // __cdecl meand nothing on non-Windows
+  #define STORMLIB_CDECL /* */
+
   // Typedefs for ANSI C
   typedef unsigned char  BYTE;
   typedef unsigned short USHORT;
@@ -153,7 +188,7 @@
   typedef char         * LPTSTR;
   typedef char         * LPSTR;
 
-  #ifdef PLATFORM_32BIT
+  #ifdef STORMLIB_32BIT
     #define _LZMA_UINT32_IS_ULONG
   #endif
 
@@ -162,11 +197,7 @@
     #define MAX_PATH 1024
   #endif
 
-  #ifndef _countof
-    #define _countof(x)  (sizeof(x) / sizeof(x[0]))
-  #endif
-  
-  #define WINAPI 
+  #define WINAPI
 
   #define FILE_BEGIN    SEEK_SET
   #define FILE_CURRENT  SEEK_CUR
@@ -190,10 +221,10 @@
   #define _tcsicmp  strcasecmp
   #define _tcsnicmp strncasecmp
 
-#endif // !PLATFORM_WINDOWS
+#endif // !STORMLIB_WINDOWS
 
 // 64-bit calls are supplied by "normal" calls on Mac
-#if defined(PLATFORM_MAC)
+#if defined(STORMLIB_MAC) || defined(STORMLIB_HAIKU)
   #define stat64  stat
   #define fstat64 fstat
   #define lseek64 lseek
@@ -201,9 +232,9 @@
   #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)
+#if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX) || defined(STORMLIB_HAIKU)
   #define ERROR_SUCCESS                  0
   #define ERROR_FILE_NOT_FOUND           ENOENT
   #define ERROR_ACCESS_DENIED            EPERM
@@ -211,7 +242,7 @@
   #define ERROR_NOT_ENOUGH_MEMORY        ENOMEM
   #define ERROR_NOT_SUPPORTED            ENOTSUP
   #define ERROR_INVALID_PARAMETER        EINVAL
-  #define ERROR_NEGATIVE_SEEK            EINVAL
+  #define ERROR_NEGATIVE_SEEK            ESPIPE
   #define ERROR_DISK_FULL                ENOSPC
   #define ERROR_ALREADY_EXISTS           EEXIST
   #define ERROR_INSUFFICIENT_BUFFER      ENOBUFS
@@ -222,10 +253,14 @@
   #define ERROR_FILE_CORRUPT             1004        // No such error code under Linux
 #endif
 
+#ifndef _countof
+  #define _countof(x)  (sizeof(x) / sizeof(x[0]))
+#endif
+
 //-----------------------------------------------------------------------------
 // Swapping functions
 
-#ifdef PLATFORM_LITTLE_ENDIAN
+#ifdef STORMLIB_LITTLE_ENDIAN
     #define    BSWAP_INT16_UNSIGNED(a)          (a)
     #define    BSWAP_INT16_SIGNED(a)            (a)
     #define    BSWAP_INT32_UNSIGNED(a)          (a)
diff --git a/OpenSource/StormLib/src/adpcm/adpcm.cpp b/OpenSource/StormLib/src/adpcm/adpcm.cpp
index c8086ab6b..fb0efbfd7 100644
--- a/OpenSource/StormLib/src/adpcm/adpcm.cpp
+++ b/OpenSource/StormLib/src/adpcm/adpcm.cpp
@@ -108,7 +108,7 @@ class TADPCMStream
 
     unsigned char * pbBufferEnd;
     unsigned char * pbBuffer;
-};                    
+};
 
 //----------------------------------------------------------------------------
 // Local functions
@@ -215,7 +215,7 @@ int CompressADPCM(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int cb
 
     // Get the initial index
     ChannelIndex = ChannelCount - 1;
-    
+
     // Now keep reading the input data as long as there is something in the input buffer
     while(is.ReadWordSample(InputSample))
     {
@@ -240,7 +240,7 @@ int CompressADPCM(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int cb
         {
             if(StepIndexes[ChannelIndex] != 0)
                 StepIndexes[ChannelIndex]--;
-            
+
             os.WriteByteSample(0x80);
         }
         else
@@ -284,7 +284,7 @@ int CompressADPCM(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int cb
             // Write the encoded sample to the output stream
             if(!os.WriteByteSample((unsigned char)EncodedSample))
                 break;
-            
+
             // Calculates the step index to use for the next encode
             StepIndexes[ChannelIndex] = GetNextStepIndex(StepIndexes[ChannelIndex], EncodedSample);
         }
@@ -377,7 +377,7 @@ int DecompressADPCM(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int
 
             // Encode one sample
             PredictedSamples[ChannelIndex] = (short)DecodeSample(PredictedSamples[ChannelIndex],
-                                                                 EncodedSample, 
+                                                                 EncodedSample,
                                                                  StepSize,
                                                                  StepSize >> BitShift);
 
diff --git a/OpenSource/StormLib/src/adpcm/adpcm_old.cpp b/OpenSource/StormLib/src/adpcm/adpcm_old.cpp
deleted file mode 100644
index 916fa3811..000000000
--- a/OpenSource/StormLib/src/adpcm/adpcm_old.cpp
+++ /dev/null
@@ -1,358 +0,0 @@
-/*****************************************************************************/
-/* adpcm.cpp                              Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* This module contains implementation of adpcm decompression method used by */
-/* Storm.dll to decompress WAVE files. Thanks to Tom Amigo for releasing     */
-/* his sources.                                                              */
-/*---------------------------------------------------------------------------*/
-/*   Date    Ver   Who  Comment                                              */
-/* --------  ----  ---  -------                                              */
-/* 11.03.03  1.00  Lad  Splitted from Pkware.cpp                             */
-/* 20.05.03  2.00  Lad  Added compression                                    */
-/* 19.11.03  2.01  Dan  Big endian handling                                  */
-/*****************************************************************************/
-
-#include "adpcm.h"
-
-//------------------------------------------------------------------------------
-// Structures
-
-typedef union _BYTE_AND_WORD_PTR
-{
-    short * pw;
-    unsigned char * pb;
-} BYTE_AND_WORD_PTR;
-
-typedef union _WORD_AND_BYTE_ARRAY
-{
-    short w;
-    unsigned char b[2];
-} WORD_AND_BYTE_ARRAY;
-
-//-----------------------------------------------------------------------------
-// Tables necessary dor decompression
-
-static long Table1503F120[] =
-{
-    0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000006,
-    0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007,
-    0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007,  
-    0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000006, 0xFFFFFFFF, 0x00000008  
-};
-
-static long step_table[] =
-{
-    0x00000007, 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E,
-    0x00000010, 0x00000011, 0x00000013, 0x00000015, 0x00000017, 0x00000019, 0x0000001C, 0x0000001F,
-    0x00000022, 0x00000025, 0x00000029, 0x0000002D, 0x00000032, 0x00000037, 0x0000003C, 0x00000042,
-    0x00000049, 0x00000050, 0x00000058, 0x00000061, 0x0000006B, 0x00000076, 0x00000082, 0x0000008F,
-    0x0000009D, 0x000000AD, 0x000000BE, 0x000000D1, 0x000000E6, 0x000000FD, 0x00000117, 0x00000133,
-    0x00000151, 0x00000173, 0x00000198, 0x000001C1, 0x000001EE, 0x00000220, 0x00000256, 0x00000292,
-    0x000002D4, 0x0000031C, 0x0000036C, 0x000003C3, 0x00000424, 0x0000048E, 0x00000502, 0x00000583,
-    0x00000610, 0x000006AB, 0x00000756, 0x00000812, 0x000008E0, 0x000009C3, 0x00000ABD, 0x00000BD0,
-    0x00000CFF, 0x00000E4C, 0x00000FBA, 0x0000114C, 0x00001307, 0x000014EE, 0x00001706, 0x00001954,
-    0x00001BDC, 0x00001EA5, 0x000021B6, 0x00002515, 0x000028CA, 0x00002CDF, 0x0000315B, 0x0000364B,
-    0x00003BB9, 0x000041B2, 0x00004844, 0x00004F7E, 0x00005771, 0x0000602F, 0x000069CE, 0x00007462,
-    0x00007FFF
-};
-
-//----------------------------------------------------------------------------
-// CompressWave
-
-// 1500EF70
-int CompressADPCM(unsigned char * pbOutBuffer, int dwOutLength, short * pwInBuffer, int dwInLength, int nChannels, int nCmpLevel)
-//                ECX                          EDX
-{
-    WORD_AND_BYTE_ARRAY Wcmp;
-    BYTE_AND_WORD_PTR out;                    // Pointer to the output buffer
-    long SInt32Array1[2];
-    long SInt32Array2[2];
-    long SInt32Array3[2];
-    long nBytesRemains = dwOutLength;       // Number of bytes remaining
-    long nWordsRemains;                     // Number of words remaining
-//  unsigned char * pbSaveOutBuffer;        // Copy of output buffer (actually not used)
-    unsigned long dwBitBuff;
-    unsigned long dwStopBit;
-    unsigned long dwBit;
-    unsigned long ebx;
-    unsigned long esi;
-    long nTableValue;
-    long nOneWord;
-    long var_1C;
-    long var_2C;
-    int nLength;
-    int nIndex;
-    int nValue;
-    int i, chnl;
-
-    // If less than 2 bytes remain, don't decompress anything
-//  pbSaveOutBuffer = pbOutBuffer;
-    out.pb = pbOutBuffer;
-    if(nBytesRemains < 2)
-        return 2;
-
-    Wcmp.b[1] = (unsigned char)(nCmpLevel - 1);
-    Wcmp.b[0] = (unsigned char)0;
-
-    *out.pw++ = BSWAP_INT16_SIGNED(Wcmp.w);
-    if((out.pb - pbOutBuffer + (nChannels * 2)) > nBytesRemains)
-        return (int)(out.pb - pbOutBuffer + (nChannels * 2));
-
-    SInt32Array1[0] = SInt32Array1[1] = 0x2C;
-
-    for(i = 0; i < nChannels; i++)
-    {
-        nOneWord = BSWAP_INT16_SIGNED(*pwInBuffer++);
-        *out.pw++ = BSWAP_INT16_SIGNED((short)nOneWord);
-        SInt32Array2[i] = nOneWord;
-    }
-
-    // Weird. But it's there
-    nLength = dwInLength;
-    if(nLength < 0)                     // mov eax, dwInLength; cdq; sub eax, edx;
-        nLength++;
-
-    nLength = (nLength / 2) - (int)(out.pb - pbOutBuffer);
-    nLength = (nLength < 0) ? 0 : nLength;
-    
-    nIndex  = nChannels - 1;            // edi
-    nWordsRemains = dwInLength / 2;     // eax
-    
-    // ebx - nChannels
-    // ecx - pwOutPos
-    for(chnl = nChannels; chnl < nWordsRemains; chnl++)
-    {
-        // 1500F030
-        if((out.pb - pbOutBuffer + 2) > nBytesRemains)
-            return (int)(out.pb - pbOutBuffer + 2);
-
-        // Switch index
-        if(nChannels == 2)
-            nIndex = (nIndex == 0) ? 1 : 0;
-
-        // Load one word from the input stream
-        nOneWord = BSWAP_INT16_SIGNED(*pwInBuffer++);   // ecx - nOneWord
-        SInt32Array3[nIndex] = nOneWord;
-
-        // esi - SInt32Array2[nIndex]
-        // eax - nValue
-        nValue = nOneWord - SInt32Array2[nIndex];
-        nValue = (nValue < 0) ? ((nValue ^ 0xFFFFFFFF) + 1) : nValue;
-
-        ebx = (nOneWord >= SInt32Array2[nIndex]) ? 0 : 0x40;
-
-        // esi - SInt32Array2[nIndex]
-        // edx - step_table[SInt32Array2[nIndex]]
-        // edi - (step_table[SInt32Array1[nIndex]] >> nCmpLevel)
-        nTableValue = step_table[SInt32Array1[nIndex]];
-        dwStopBit = (unsigned long)nCmpLevel;
-
-        // edi - nIndex;
-        if(nValue < (nTableValue >> nCmpLevel))
-        {
-            if(SInt32Array1[nIndex] != 0)
-                SInt32Array1[nIndex]--;
-            *out.pb++ = 0x80;
-        }
-        else
-        {
-            while(nValue > nTableValue * 2)
-            {
-                if(SInt32Array1[nIndex] >= 0x58 || nLength == 0)
-                    break;
-
-                SInt32Array1[nIndex] += 8;
-                if(SInt32Array1[nIndex] > 0x58)
-                    SInt32Array1[nIndex] = 0x58;
-
-                nTableValue = step_table[SInt32Array1[nIndex]];
-                *out.pb++ = 0x81;
-                nLength--;
-            }
-
-            var_2C = nTableValue >> Wcmp.b[1];
-            dwBitBuff = 0;
-
-            esi = (1 << (dwStopBit - 2));
-            dwStopBit = (esi <= 0x20) ? esi : 0x20;
-
-            for(var_1C = 0, dwBit = 1; ; dwBit <<= 1)
-            {
-//              esi = var_1C + nTableValue;
-                if((var_1C + nTableValue) <= nValue)
-                {
-                    var_1C += nTableValue;
-                    dwBitBuff |= dwBit;
-                }
-                if(dwBit == dwStopBit)
-                    break;
-               
-                nTableValue >>= 1;
-            }
-
-            nValue = SInt32Array2[nIndex];
-            if(ebx != 0)
-            {
-                nValue -= (var_1C + var_2C);
-                if(nValue < -32768)
-                    nValue = -32768;
-            }
-            else
-            {
-                nValue += (var_1C + var_2C);
-                if(nValue > 32767)
-                    nValue = 32767;
-            }
-
-            SInt32Array2[nIndex]  = nValue;
-            *out.pb++ = (unsigned char)(dwBitBuff | ebx);
-            nTableValue = Table1503F120[dwBitBuff & 0x1F];
-            SInt32Array1[nIndex]  = SInt32Array1[nIndex] + nTableValue; 
-            if(SInt32Array1[nIndex] < 0)
-                SInt32Array1[nIndex] = 0;
-            else if(SInt32Array1[nIndex] > 0x58)
-                SInt32Array1[nIndex] = 0x58;
-        }
-    }
-
-    return (int)(out.pb - pbOutBuffer);
-}
-
-//----------------------------------------------------------------------------
-// DecompressADPCM
-
-// 1500F230
-int DecompressADPCM(unsigned char * pbOutBuffer, int dwOutLength, unsigned char * pbInBuffer, int dwInLength, int nChannels)
-{
-    BYTE_AND_WORD_PTR out;                // Output buffer
-    BYTE_AND_WORD_PTR in;
-    unsigned char * pbInBufferEnd = (pbInBuffer + dwInLength);
-    long SInt32Array1[2];
-    long SInt32Array2[2];
-    long nOneWord;
-    int nIndex;
-    int i;
-
-    SInt32Array1[0] = SInt32Array1[1] = 0x2C;
-    out.pb = pbOutBuffer;
-    in.pb = pbInBuffer;
-    in.pw++;
-
-    // Fill the Uint32Array2 array by channel values.
-    for(i = 0; i < nChannels; i++)
-    {
-        nOneWord = BSWAP_INT16_SIGNED(*in.pw++);
-        SInt32Array2[i] = nOneWord;
-        if(dwOutLength < 2)
-            return (int)(out.pb - pbOutBuffer);
-
-        *out.pw++ = BSWAP_INT16_SIGNED((short)nOneWord);
-        dwOutLength -= sizeof(short);
-    }
-
-    // Get the initial index
-    nIndex = nChannels - 1;
-
-    // Perform the decompression
-    while(in.pb < pbInBufferEnd)
-    {
-        unsigned char nOneByte = *in.pb++;
-
-        // Switch index
-        if(nChannels == 2)
-            nIndex = (nIndex == 0) ? 1 : 0;
-
-        // 1500F2A2: Get one byte from input buffer
-        if(nOneByte & 0x80)
-        {
-            switch(nOneByte & 0x7F)
-            {
-                case 0:     // 1500F315
-                    if(SInt32Array1[nIndex] != 0)
-                        SInt32Array1[nIndex]--;
-
-                    if(dwOutLength < 2)
-                        return (int)(out.pb - pbOutBuffer);
-
-                    *out.pw++ = BSWAP_INT16_SIGNED((unsigned short)SInt32Array2[nIndex]);
-                    dwOutLength -= sizeof(unsigned short);
-                    break;
-
-                case 1:     // 1500F2E8
-                    SInt32Array1[nIndex] += 8;
-                    if(SInt32Array1[nIndex] > 0x58)
-                        SInt32Array1[nIndex] = 0x58;
-                    
-                    if(nChannels == 2)
-                        nIndex = (nIndex == 0) ? 1 : 0;
-                    break;
-
-                case 2:     // 1500F41E
-                    break;
-
-                default:    // 1500F2C4
-                    SInt32Array1[nIndex] -= 8;
-                    if(SInt32Array1[nIndex] < 0)
-                        SInt32Array1[nIndex] = 0;
-
-                    if(nChannels == 2)
-                        nIndex = (nIndex == 0) ? 1 : 0;
-                    break;
-            }
-        }
-        else
-        {
-            // 1500F349
-            long temp1 = step_table[SInt32Array1[nIndex]];     // EDI
-            long temp2 = temp1 >> pbInBuffer[1];               // ESI
-            long temp3 = SInt32Array2[nIndex];                 // ECX
-
-            if(nOneByte & 0x01)          // EBX = nOneByte
-                temp2 += (temp1 >> 0);
-
-            if(nOneByte & 0x02)
-                temp2 += (temp1 >> 1);
-
-            if(nOneByte & 0x04)
-                temp2 += (temp1 >> 2);
-
-            if(nOneByte & 0x08)
-                temp2 += (temp1 >> 3);
-
-            if(nOneByte & 0x10)
-                temp2 += (temp1 >> 4);
-
-            if(nOneByte & 0x20)
-                temp2 += (temp1 >> 5);
-
-            if(nOneByte & 0x40)
-            {
-                temp3 = temp3 - temp2;
-                if(temp3 <= -32768)
-                    temp3 = -32768;
-            }
-            else
-            {
-                temp3 = temp3 + temp2;
-                if(temp3 >= 32767)
-                    temp3 = 32767;
-            }
-
-            SInt32Array2[nIndex] = temp3;
-            if(dwOutLength < 2)
-                break;
-
-            // Store the output 16-bit value
-            *out.pw++ = BSWAP_INT16_SIGNED((short)SInt32Array2[nIndex]);
-            dwOutLength -= 2;
-
-            SInt32Array1[nIndex] += Table1503F120[nOneByte & 0x1F];
-
-            if(SInt32Array1[nIndex] < 0)
-                SInt32Array1[nIndex] = 0;
-            else if(SInt32Array1[nIndex] > 0x58)
-                SInt32Array1[nIndex] = 0x58;
-        }
-    }
-    return (int)(out.pb - pbOutBuffer);
-}
diff --git a/OpenSource/StormLib/src/adpcm/adpcm_old.h b/OpenSource/StormLib/src/adpcm/adpcm_old.h
deleted file mode 100644
index 7b76affac..000000000
--- a/OpenSource/StormLib/src/adpcm/adpcm_old.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*****************************************************************************/
-/* adpcm.h                                Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* Header file for adpcm decompress functions                                */
-/*---------------------------------------------------------------------------*/
-/*   Date    Ver   Who  Comment                                              */
-/* --------  ----  ---  -------                                              */
-/* 31.03.03  1.00  Lad  The first version of adpcm.h                         */
-/*****************************************************************************/
-
-#ifndef __ADPCM_H__
-#define __ADPCM_H__
-
-//-----------------------------------------------------------------------------
-// Functions
-
-#include <StormPort.h>
-
-int  CompressADPCM  (unsigned char * pbOutBuffer, int dwOutLength, short * pwInBuffer, int dwInLength, int nCmpType, int nChannels);
-int  DecompressADPCM(unsigned char * pbOutBuffer, int dwOutLength, unsigned char * pbInBuffer, int dwInLength, int nChannels);
-
-#endif // __ADPCM_H__
diff --git a/OpenSource/StormLib/src/huffman/huff.cpp b/OpenSource/StormLib/src/huffman/huff.cpp
index 9de5acb51..6930354bb 100644
--- a/OpenSource/StormLib/src/huffman/huff.cpp
+++ b/OpenSource/StormLib/src/huffman/huff.cpp
@@ -15,10 +15,10 @@
 /* 08.12.03  2.01  Dan  High-memory handling (> 0x80000000)                  */
 /* 09.01.13  3.00  Lad  Refactored, beautified, documented :-)               */
 /*****************************************************************************/
- 
+
 #include <assert.h>
 #include <string.h>
- 
+
 #include "huff.h"
 
 //-----------------------------------------------------------------------------
@@ -67,7 +67,7 @@ static unsigned char ByteToWeight_01[] =
     0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B,
     0x00, 0x00
 };
-   
+
 // Data for compression type 0x02
 static unsigned char ByteToWeight_02[] =
 {
@@ -89,7 +89,7 @@ static unsigned char ByteToWeight_02[] =
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00
 };
-   
+
 // Data for compression type 0x03
 static unsigned char ByteToWeight_03[] =
 {
@@ -111,7 +111,7 @@ static unsigned char ByteToWeight_03[] =
     0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11,
     0x00, 0x00
 };
-   
+
 // Data for compression type 0x04
 static unsigned char ByteToWeight_04[] =
 {
@@ -133,7 +133,7 @@ static unsigned char ByteToWeight_04[] =
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00
 };
-   
+
 // Data for compression type 0x05
 static unsigned char ByteToWeight_05[] =
 {
@@ -155,7 +155,7 @@ static unsigned char ByteToWeight_05[] =
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00
 };
-   
+
     // Data for compression type 0x06
 static unsigned char ByteToWeight_06[] =
 {
@@ -177,7 +177,7 @@ static unsigned char ByteToWeight_06[] =
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00
 };
-   
+
 // Data for compression type 0x07
 static unsigned char ByteToWeight_07[] =
 {
@@ -199,7 +199,7 @@ static unsigned char ByteToWeight_07[] =
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00
 };
-   
+
 // Data for compression type 0x08
 static unsigned char ByteToWeight_08[] =
 {
@@ -235,7 +235,7 @@ static unsigned char * WeightTables[0x09] =
     ByteToWeight_08
 };
 
-//----------------------------------------------------------------------------- 
+//-----------------------------------------------------------------------------
 // Debug/diagnostics
 
 #ifdef _DEBUG
@@ -306,7 +306,7 @@ unsigned int TInputStream::Get1Bit()
     BitCount--;
 
     return OneBit;
-}   
+}
 
 // Gets the whole byte from the input stream.
 unsigned int TInputStream::Get8Bits()
@@ -363,13 +363,13 @@ void TOutputStream::PutBits(unsigned int dwValue, unsigned int nBitCount)
 {
     BitBuffer |= (dwValue << BitCount);
     BitCount += nBitCount;
- 
+
     // Flush completed bytes
     while(BitCount >= 8)
     {
         if(pbOutBuffer < pbOutBufferEnd)
             *pbOutBuffer++ = (unsigned char)BitBuffer;
- 
+
         BitBuffer >>= 8;
         BitCount -= 8;
     }
@@ -402,7 +402,7 @@ void THTreeItem::RemoveItem()
 
 //-----------------------------------------------------------------------------
 // THuffmannTree class functions
- 
+
 THuffmannTree::THuffmannTree(bool bCompression)
 {
     pFirst = pLast = LIST_HEAD();
@@ -439,7 +439,7 @@ void THuffmannTree::InsertItem(THTreeItem * pNewItem, TInsertPoint InsertPoint,
 {
     // Remove the item from the tree
     pNewItem->RemoveItem();
- 
+
     if(pInsertPoint == NULL)
         pInsertPoint = LIST_HEAD();
 
@@ -448,7 +448,7 @@ void THuffmannTree::InsertItem(THTreeItem * pNewItem, TInsertPoint InsertPoint,
         case InsertAfter:
             LinkTwoItems(pInsertPoint, pNewItem);
             return;
-       
+
         case InsertBefore:
             pNewItem->pNext = pInsertPoint;             // Set next item (or pointer to pointer to first item)
             pNewItem->pPrev = pInsertPoint->pPrev;      // Set prev item (or last item in the tree)
@@ -478,19 +478,24 @@ THTreeItem * THuffmannTree::FindHigherOrEqualItem(THTreeItem * pItem, unsigned i
 
 THTreeItem * THuffmannTree::CreateNewItem(unsigned int DecompressedValue, unsigned int Weight, TInsertPoint InsertPoint)
 {
-    THTreeItem * pNewItem;
+    THTreeItem * pNewItem = NULL;
+
+    // Don't let the item buffer run out of space
+    if(ItemsUsed < HUFF_ITEM_COUNT)
+    {
+        // Allocate new item from the item pool
+        pNewItem = &ItemBuffer[ItemsUsed++];
 
-    // Allocate new item from the item pool
-    pNewItem = &ItemBuffer[ItemsUsed++];
+        // Insert this item to the top of the tree
+        InsertItem(pNewItem, InsertPoint, NULL);
 
-    // Insert this item to the top of the tree
-    InsertItem(pNewItem, InsertPoint, NULL);
+        // Fill the rest of the item
+        pNewItem->DecompressedValue = DecompressedValue;
+        pNewItem->Weight = Weight;
+        pNewItem->pParent = NULL;
+        pNewItem->pChildLo = NULL;
+    }
 
-    // Fill the rest of the item
-    pNewItem->DecompressedValue = DecompressedValue;
-    pNewItem->Weight = Weight;
-    pNewItem->pParent = NULL;
-    pNewItem->pChildLo = NULL;
     return pNewItem;
 }
 
@@ -524,16 +529,16 @@ bool THuffmannTree::BuildTree(unsigned int CompressionType)
     THTreeItem * pChildHi;
     unsigned char * WeightTable;
     unsigned int MaxWeight;                     // [ESP+10] - The greatest character found in table
- 
+
     // Clear all pointers in HTree item array
     memset(ItemsByByte, 0, sizeof(ItemsByByte));
     MaxWeight = 0;
- 
+
     // Ensure that the compression type is in range
     if((CompressionType & 0x0F) > 0x08)
         return false;
     WeightTable  = WeightTables[CompressionType & 0x0F];
- 
+
     // Build the linear list of entries that is sorted by byte weight
     for(unsigned int i = 0; i < 0x100; i++)
     {
@@ -547,11 +552,11 @@ bool THuffmannTree::BuildTree(unsigned int CompressionType)
             MaxWeight = FixupItemPosByWeight(pNewItem, MaxWeight);
         }
     }
- 
+
     // Insert termination entries at the end of the list
     ItemsByByte[0x100] = CreateNewItem(0x100, 1, InsertBefore);
     ItemsByByte[0x101] = CreateNewItem(0x101, 1, InsertBefore);
- 
+
     // Now we need to build the tree. We start at the last entry
     // and go backwards to the first one
     pChildLo = pLast;
@@ -567,6 +572,8 @@ bool THuffmannTree::BuildTree(unsigned int CompressionType)
 
         // Create new parent item for the children
         pNewItem = CreateNewItem(0, pChildHi->Weight + pChildLo->Weight, InsertAfter);
+        if(pNewItem == NULL)
+            return false;
 
         // Link both child items to their new parent
         pChildLo->pParent = pNewItem;
@@ -591,7 +598,7 @@ void THuffmannTree::IncWeightsAndRebalance(THTreeItem * pItem)
     THTreeItem * pChildHi;              // The higher-weight child
     THTreeItem * pChildLo;              // The lower-weight child
     THTreeItem * pParent;
- 
+
     // Climb up the tree and increment weight of each tree item
     for(; pItem != NULL; pItem = pItem->pParent)
     {
@@ -608,11 +615,11 @@ void THuffmannTree::IncWeightsAndRebalance(THTreeItem * pItem)
             // Move the previous item to the RIGHT from the given item
             pChildHi->RemoveItem();
             LinkTwoItems(pItem, pChildHi);
-            
+
             // Move the given item AFTER the greater-weight tree item
             pItem->RemoveItem();
             LinkTwoItems(pHigherItem, pItem);
-     
+
             // We need to maintain the tree so that pChildHi->Weight is >= pChildLo->Weight.
             // Rebalance the tree accordingly.
             pChildLo = pChildHi->pParent->pChildLo;
@@ -631,7 +638,7 @@ void THuffmannTree::IncWeightsAndRebalance(THTreeItem * pItem)
     }
 }
 
-void THuffmannTree::InsertNewBranchAndRebalance(unsigned int Value1, unsigned int Value2)
+bool THuffmannTree::InsertNewBranchAndRebalance(unsigned int Value1, unsigned int Value2)
 {
     THTreeItem * pLastItem = pLast;
     THTreeItem * pChildHi;
@@ -639,16 +646,26 @@ void THuffmannTree::InsertNewBranchAndRebalance(unsigned int Value1, unsigned in
 
     // Create higher-weight child
     pChildHi = CreateNewItem(Value1, pLastItem->Weight, InsertBefore);
-    pChildHi->pParent = pLastItem;
-    ItemsByByte[Value1] = pChildHi;
+    if(pChildHi != NULL)
+    {
+        pChildHi->pParent = pLastItem;
+        ItemsByByte[Value1] = pChildHi;
 
-    // Create lower-weight child
-    pChildLo = CreateNewItem(Value2, 0, InsertBefore);
-    pChildLo->pParent = pLastItem;
-    pLastItem->pChildLo = pChildLo;
-    ItemsByByte[Value2] = pChildLo;
+        // Create lower-weight child
+        pChildLo = CreateNewItem(Value2, 0, InsertBefore);
+        if(pChildLo != NULL)
+        {
+            pChildLo->pParent = pLastItem;
+            pLastItem->pChildLo = pChildLo;
+            ItemsByByte[Value2] = pChildLo;
 
-    IncWeightsAndRebalance(pChildLo);
+            IncWeightsAndRebalance(pChildLo);
+            return true;
+        }
+    }
+
+    // No more space in the tree buffer
+    return false;
 }
 
 void THuffmannTree::EncodeOneByte(TOutputStream * os, THTreeItem * pItem)
@@ -686,7 +703,7 @@ unsigned int THuffmannTree::DecodeOneByte(TInputStream * is)
 
     // Get the eventual quick-link index
     ItemLinkIndex = is->Peek7Bits();
-    
+
     // Is the quick-link item valid?
     if(QuickLinks[ItemLinkIndex].ValidValue > MinValidValue)
     {
@@ -766,14 +783,14 @@ unsigned int THuffmannTree::Compress(TOutputStream * os, void * pvInBuffer, int
     unsigned char * pbInBuffer = (unsigned char *)pvInBuffer;
     unsigned char * pbOutBuff = os->pbOutBuffer;
     unsigned char InputByte;
- 
+
     if(!BuildTree(CompressionType))
         return 0;
     bIsCmp0 = (CompressionType == 0);
 
     // Store the compression type into output buffer
     os->PutBits(CompressionType, 8);
- 
+
     // Process the entire input buffer
     while(pbInBuffer < pbInBufferEnd)
     {
@@ -785,39 +802,40 @@ unsigned int THuffmannTree::Compress(TOutputStream * os, void * pvInBuffer, int
         {
             // Encode the relationship
             EncodeOneByte(os, ItemsByByte[0x101]);
- 
+
             // Store the loaded byte into output stream
             os->PutBits(InputByte, 8);
- 
-            InsertNewBranchAndRebalance(pLast->DecompressedValue, InputByte);
+
+            if(!InsertNewBranchAndRebalance(pLast->DecompressedValue, InputByte))
+                return 0;
 
             if(bIsCmp0)
             {
                 IncWeightsAndRebalance(ItemsByByte[InputByte]);
                 continue;
             }
-  
+
             IncWeightsAndRebalance(ItemsByByte[InputByte]);
         }
         else
         {
             EncodeOneByte(os, ItemsByByte[InputByte]);
         }
- 
+
         if(bIsCmp0)
         {
             IncWeightsAndRebalance(ItemsByByte[InputByte]);
         }
     }
- 
+
     // Put the termination mark to the compressed stream
     EncodeOneByte(os, ItemsByByte[0x100]);
- 
+
     // Flush the remaining bits
     os->Flush();
     return (unsigned int)(os->pbOutBuffer - pbOutBuff);
 }
- 
+
 // Decompression using Huffman tree (1500E450)
 unsigned int THuffmannTree::Decompress(void * pvOutBuffer, unsigned int cbOutLength, TInputStream * is)
 {
@@ -825,19 +843,19 @@ unsigned int THuffmannTree::Decompress(void * pvOutBuffer, unsigned int cbOutLen
     unsigned char * pbOutBuffer = (unsigned char *)pvOutBuffer;
     unsigned int DecompressedValue = 0;
     unsigned int CompressionType = 0;
-   
+
     // Test the output length. Must not be NULL.
     if(cbOutLength == 0)
         return 0;
- 
+
     // Get the compression type from the input stream
     CompressionType = is->Get8Bits();
     bIsCmp0 = (CompressionType == 0) ? 1 : 0;
- 
+
     // Build the Huffman tree
     if(!BuildTree(CompressionType))
         return 0;
- 
+
     // Process the entire input buffer until end of the stream
     while((DecompressedValue = DecodeOneByte(is)) != 0x100)
     {
@@ -851,23 +869,24 @@ unsigned int THuffmannTree::Decompress(void * pvOutBuffer, unsigned int cbOutLen
             // The decompressed byte is stored in the next 8 bits
             DecompressedValue = is->Get8Bits();
 
-            InsertNewBranchAndRebalance(pLast->DecompressedValue, DecompressedValue);
+            if(!InsertNewBranchAndRebalance(pLast->DecompressedValue, DecompressedValue))
+                return 0;
 
             if(bIsCmp0 == 0)
                 IncWeightsAndRebalance(ItemsByByte[DecompressedValue]);
         }
- 
+
         // A byte successfully decoded - store it in the output stream
         *pbOutBuffer++ = (unsigned char)DecompressedValue;
         if(pbOutBuffer >= pbOutBufferEnd)
             break;
- 
+
         if(bIsCmp0)
         {
             IncWeightsAndRebalance(ItemsByByte[DecompressedValue]);
         }
     }
- 
+
     return (unsigned int)(pbOutBuffer - (unsigned char *)pvOutBuffer);
 }
 
diff --git a/OpenSource/StormLib/src/huffman/huff.h b/OpenSource/StormLib/src/huffman/huff.h
index 89993fdef..b75acbb86 100644
--- a/OpenSource/StormLib/src/huffman/huff.h
+++ b/OpenSource/StormLib/src/huffman/huff.h
@@ -9,13 +9,13 @@
 /* 03.05.03  2.00  Lad  Added compression                                    */
 /* 08.12.03  2.01  Dan  High-memory handling (> 0x80000000)                  */
 /*****************************************************************************/
- 
+
 #ifndef __HUFFMAN_H__
 #define __HUFFMAN_H__
 
 //-----------------------------------------------------------------------------
 // Defines
- 
+
 #define HUFF_ITEM_COUNT    0x203        // Number of items in the item pool
 #define LINK_ITEM_COUNT    0x80         // Maximum number of quick-link items
 
@@ -32,23 +32,23 @@ class TInputStream
     unsigned int Peek7Bits();
     unsigned int Get8Bits();
     void SkipBits(unsigned int BitCount);
- 
+
     unsigned char * pbInBufferEnd;      // End position in the the input buffer
     unsigned char * pbInBuffer;         // Current position in the the input buffer
     unsigned int BitBuffer;             // Input bit buffer
     unsigned int BitCount;              // Number of bits remaining in 'dwBitBuff'
 };
- 
+
 
 // Output stream for Huffmann compression
 class TOutputStream
 {
     public:
- 
+
     TOutputStream(void * pvOutBuffer, size_t cbOutLength);
     void PutBits(unsigned int dwValue, unsigned int nBitCount);
     void Flush();
- 
+
     unsigned char * pbOutBufferEnd;     // End position in the output buffer
     unsigned char * pbOutBuffer;        // Current position in the output buffer
     unsigned int BitBuffer;             // Bit buffer
@@ -72,7 +72,7 @@ struct THTreeItem
 
     void         RemoveItem();
 //  void         RemoveEntry();
- 
+
     THTreeItem  * pNext;                // Pointer to lower-weight tree item
     THTreeItem  * pPrev;                // Pointer to higher-weight item
     unsigned int  DecompressedValue;    // 08 - Decompressed byte value (also index in the array)
@@ -87,7 +87,7 @@ struct THTreeItem
 // decompressing a bit faster. Sometimes it can even get the decompressed
 // byte directly.
 struct TQuickLink
-{      
+{
     unsigned int ValidValue;            // If greater than THuffmannTree::MinValidValue, the entry is valid
     unsigned int ValidBits;             // Number of bits that are valid for this item link
     union
@@ -96,7 +96,7 @@ struct TQuickLink
         unsigned int DecompressedValue; // Value for direct decompression
     };
 };
-                                           
+
 
 // Structure for Huffman tree (Size 0x3674 bytes). Because I'm not expert
 // for the decompression, I do not know actually if the class is really a Hufmann
@@ -104,7 +104,7 @@ struct TQuickLink
 class THuffmannTree
 {
     public:
-    
+
     THuffmannTree(bool bCompression);
     ~THuffmannTree();
 
@@ -118,24 +118,24 @@ class THuffmannTree
     bool  BuildTree(unsigned int CompressionType);
 
     void  IncWeightsAndRebalance(THTreeItem * pItem);
-    void  InsertNewBranchAndRebalance(unsigned int Value1, unsigned int Value2);
+    bool  InsertNewBranchAndRebalance(unsigned int Value1, unsigned int Value2);
 
     void  EncodeOneByte(TOutputStream * os, THTreeItem * pItem);
     unsigned int DecodeOneByte(TInputStream * is);
 
     unsigned int Compress(TOutputStream * os, void * pvInBuffer, int cbInBuffer, int nCmpType);
     unsigned int Decompress(void * pvOutBuffer, unsigned int cbOutLength, TInputStream * is);
- 
+
     THTreeItem   ItemBuffer[HUFF_ITEM_COUNT];   // Buffer for tree items. No memory allocation is needed
     unsigned int ItemsUsed;                     // Number of tree items used from ItemBuffer
- 
+
     // Head of the linear item list
     THTreeItem * pFirst;                        // Pointer to the highest weight item
     THTreeItem * pLast;                         // Pointer to the lowest weight item
 
     THTreeItem * ItemsByByte[0x102];            // Array of item pointers, one for each possible byte value
     TQuickLink   QuickLinks[LINK_ITEM_COUNT];   // Array of quick-link items
-    
+
     unsigned int MinValidValue;                 // A minimum value of TQDecompress::ValidValue to be considered valid
     unsigned int bIsCmp0;                       // 1 if compression type 0
 };
diff --git a/OpenSource/StormLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h b/OpenSource/StormLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h
index 7feae6e8b..e266a497e 100644
--- a/OpenSource/StormLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h
+++ b/OpenSource/StormLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h
@@ -28,7 +28,7 @@ LTC_EXPORT void * LTC_CALL XREALLOC(void *p, size_t n);
 LTC_EXPORT void * LTC_CALL XCALLOC(size_t n, size_t s);
 LTC_EXPORT void LTC_CALL XFREE(void *p);
 
-LTC_EXPORT void LTC_CALL XQSORT(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
+LTC_EXPORT void LTC_CALL XQSORT(void *base, size_t nmemb, size_t size, int(LTC_CALL * compar)(const void *, const void *));
 
 
 /* change the clock function too */
diff --git a/OpenSource/StormLib/src/libtomcrypt/src/misc/crypt_libc.c b/OpenSource/StormLib/src/libtomcrypt/src/misc/crypt_libc.c
index bcc89f4f9..3457a5209 100644
--- a/OpenSource/StormLib/src/libtomcrypt/src/misc/crypt_libc.c
+++ b/OpenSource/StormLib/src/libtomcrypt/src/misc/crypt_libc.c
@@ -12,32 +12,32 @@
 #include <stdlib.h>
 #include "../headers/tomcrypt.h"
 
-void * LibTomMalloc(size_t n)
+LTC_EXPORT void * LTC_CALL LibTomMalloc(size_t n)
 {
     return malloc(n);
 }
 
-void * LibTomCalloc(size_t n, size_t s)
+LTC_EXPORT void * LTC_CALL LibTomCalloc(size_t n, size_t s)
 {
     return calloc(n, s);
 }
 
-void * LibTomRealloc(void *p, size_t n)
+LTC_EXPORT void * LTC_CALL LibTomRealloc(void *p, size_t n)
 {
     return realloc(p, n);
 }
 
-void LibTomFree(void * p)
+LTC_EXPORT void LTC_CALL LibTomFree(void * p)
 {
     free(p);
 }
 
-clock_t LibTomClock(void)
+LTC_EXPORT clock_t LTC_CALL LibTomClock(void)
 {
     return clock();
 }
 
-void LibTomQsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *))
+LTC_EXPORT void LTC_CALL LibTomQsort(void *base, size_t nmemb, size_t size, int(LTC_CALL * compar)(const void *, const void *))
 {
     qsort(base, nmemb, size, compar);
 }
diff --git a/OpenSource/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_set.c b/OpenSource/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_set.c
index 41f658722..25d247d18 100644
--- a/OpenSource/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_set.c
+++ b/OpenSource/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_set.c
@@ -40,7 +40,7 @@ static int ltc_to_asn1(int v)
 }         
       
 
-static int qsort_helper(const void *a, const void *b)
+static int LTC_CALL qsort_helper1(const void *a, const void *b)
 {
    ltc_asn1_list *A = (ltc_asn1_list *)a, *B = (ltc_asn1_list *)b;
    int            r;
@@ -84,7 +84,7 @@ int der_encode_set(ltc_asn1_list *list, unsigned long inlen,
    }       
    
    /* sort it by the "type" field */
-   XQSORT(copy, inlen, sizeof(*copy), &qsort_helper);   
+   XQSORT(copy, inlen, sizeof(*copy), &qsort_helper1);   
    
    /* call der_encode_sequence_ex() */
    err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET);   
diff --git a/OpenSource/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_setof.c b/OpenSource/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_setof.c
index b4e97b5e6..0987cabe8 100644
--- a/OpenSource/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_setof.c
+++ b/OpenSource/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_setof.c
@@ -22,7 +22,7 @@ struct edge {
    unsigned long  size;
 };
 
-static int qsort_helper(const void *a, const void *b)
+static int LTC_CALL qsort_helper2(const void *a, const void *b)
 {
    struct edge   *A = (struct edge *)a, *B = (struct edge *)b;
    int            r;
@@ -133,7 +133,7 @@ int der_encode_setof(ltc_asn1_list *list, unsigned long inlen,
    }      
       
    /* sort based on contents (using edges) */
-   XQSORT(edges, inlen, sizeof(*edges), &qsort_helper);
+   XQSORT(edges, inlen, sizeof(*edges), &qsort_helper2);
    
    /* copy static header */
    XMEMCPY(out, buf, hdrlen);
diff --git a/OpenSource/StormLib/src/pklib/explode.c b/OpenSource/StormLib/src/pklib/explode.c
index 979617399..0f551d8ed 100644
--- a/OpenSource/StormLib/src/pklib/explode.c
+++ b/OpenSource/StormLib/src/pklib/explode.c
@@ -16,7 +16,7 @@
 
 #include "pklib.h"
 
-#define PKDCL_OK                    0       
+#define PKDCL_OK                    0
 #define PKDCL_STREAM_END            1   // All data from the input stream is read
 #define PKDCL_NEED_DICT             2   // Need more data (dictionary)
 #define PKDCL_CONTINUE             10   // Internal flag, not returned to user
@@ -31,7 +31,7 @@ char CopyrightPkware[] = "PKWARE Data Compression Library for Win32\r\n"
 //-----------------------------------------------------------------------------
 // Tables
 
-static unsigned char DistBits[] = 
+unsigned char DistBits[0x40] =
 {
     0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
     0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
@@ -39,7 +39,7 @@ static unsigned char DistBits[] =
     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
 };
 
-static unsigned char DistCode[] = 
+unsigned char DistCode[0x40] =
 {
     0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A,
     0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C,
@@ -47,28 +47,28 @@ static unsigned char DistCode[] =
     0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00
 };
 
-static unsigned char ExLenBits[] =
+unsigned char ExLenBits[0x10] =
 {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
 };
 
-static unsigned short LenBase[] =
+unsigned short LenBase[0x10] =
 {
     0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
     0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106
 };
 
-static unsigned char LenBits[] =
+unsigned char LenBits[0x10] =
 {
     0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07
 };
 
-static unsigned char LenCode[] =
+unsigned char LenCode[0x10] =
 {
     0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00
 };
 
-static unsigned char ChBitsAsc[] =
+unsigned char ChBitsAsc[0x100] =
 {
     0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C,
     0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
@@ -88,7 +88,7 @@ static unsigned char ChBitsAsc[] =
     0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D
 };
 
-static unsigned short ChCodeAsc[] = 
+unsigned short ChCodeAsc[0x100] =
 {
     0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0,
     0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0,
@@ -121,7 +121,7 @@ static unsigned short ChCodeAsc[] =
     0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900,
     0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600,
     0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200,
-    0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000  
+    0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000
 };
 
 //-----------------------------------------------------------------------------
@@ -278,11 +278,11 @@ static unsigned int DecodeLit(TDcmpStruct * pWork)
     {
         // Remove one bit from the input data
         if(WasteBits(pWork, 1))
-            return 0x306;   
-                      
+            return 0x306;
+
         // The next 8 bits hold the index to the length code table
         length_code = pWork->LengthCodes[pWork->bit_buff & 0xFF];
-        
+
         // Remove the apropriate number of bits
         if(WasteBits(pWork, pWork->LenBits[length_code]))
             return 0x306;
@@ -442,7 +442,7 @@ static unsigned int Expand(TDcmpStruct * pWork)
         {
             pWork->out_buff[pWork->outputPos++] = (unsigned char)next_literal;
         }
-    
+
         // Flush the output buffer, if number of extracted bytes has reached the end
         if(pWork->outputPos >= 0x2000)
         {
@@ -470,7 +470,7 @@ static unsigned int Expand(TDcmpStruct * pWork)
 //-----------------------------------------------------------------------------
 // Main exploding function.
 
-unsigned int explode(
+unsigned int PKEXPORT explode(
         unsigned int (*read_buf)(char *buf, unsigned  int *size, void *param),
         void         (*write_buf)(char *buf, unsigned  int *size, void *param),
         char         *work_buf,
@@ -495,7 +495,7 @@ unsigned int explode(
     pWork->in_pos     = 3;                 // Position in input buffer
 
     // Test for the valid dictionary size
-    if(4 > pWork->dsize_bits || pWork->dsize_bits > 6) 
+    if(4 > pWork->dsize_bits || pWork->dsize_bits > 6)
         return CMP_INVALID_DICTSIZE;
 
     pWork->dsize_mask = 0xFFFF >> (0x10 - pWork->dsize_bits); // Shifted by 'sar' instruction
@@ -517,6 +517,6 @@ unsigned int explode(
     GenDecodeTabs(pWork->DistPosCodes, DistCode, pWork->DistBits, sizeof(pWork->DistBits));
     if(Expand(pWork) != 0x306)
         return CMP_NO_ERROR;
-        
+
     return CMP_ABORT;
 }
diff --git a/OpenSource/StormLib/src/pklib/implode.c b/OpenSource/StormLib/src/pklib/implode.c
index f29f54d64..90cb4821c 100644
--- a/OpenSource/StormLib/src/pklib/implode.c
+++ b/OpenSource/StormLib/src/pklib/implode.c
@@ -24,96 +24,6 @@
 
 #define MAX_REP_LENGTH 0x204            // The longest allowed repetition
 
-//-----------------------------------------------------------------------------
-// Tables
-
-static unsigned char DistBits[] = 
-{
-    0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
-};
-
-static unsigned char DistCode[] = 
-{
-    0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A,
-    0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C,
-    0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
-    0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00
-};
-
-static unsigned char ExLenBits[] =
-{
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
-};
-
-static unsigned char LenBits[] =
-{
-    0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07
-};
-
-static unsigned char LenCode[] =
-{
-    0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00
-};
-
-static unsigned char ChBitsAsc[] =
-{
-    0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C,
-    0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
-    0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08,
-    0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B,
-    0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06,
-    0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08,
-    0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05,
-    0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C,
-    0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
-    0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
-    0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
-    0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
-    0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
-    0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
-    0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D,
-    0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D
-};
-
-static unsigned short ChCodeAsc[] = 
-{
-    0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0,
-    0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0,
-    0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360,
-    0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60,
-    0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8,
-    0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098,
-    0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C,
-    0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710,
-    0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8,
-    0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E,
-    0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8,
-    0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088,
-    0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A,
-    0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D,
-    0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078,
-    0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0,
-    0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040,
-    0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380,
-    0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180,
-    0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280,
-    0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080,
-    0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300,
-    0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0,
-    0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320,
-    0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220,
-    0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0,
-    0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0,
-    0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340,
-    0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900,
-    0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600,
-    0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200,
-    0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000  
-};
-
 //-----------------------------------------------------------------------------
 // Macros
 
@@ -140,7 +50,7 @@ static void SortBuffer(TCmpStruct * pWork, unsigned char * buffer_begin, unsigne
 
     // Zero the entire "phash_to_index" table
     memset(pWork->phash_to_index, 0, sizeof(pWork->phash_to_index));
-    
+
     // Step 1: Count amount of each PAIR_HASH in the input buffer
     // The table will look like this:
     //  offs 0x000: Number of occurences of PAIR_HASH 0
@@ -150,7 +60,7 @@ static void SortBuffer(TCmpStruct * pWork, unsigned char * buffer_begin, unsigne
     for(buffer_ptr = buffer_begin; buffer_ptr < buffer_end; buffer_ptr++)
         pWork->phash_to_index[BYTE_PAIR_HASH(buffer_ptr)]++;
 
-    // Step 2: Convert the table to the array of PAIR_HASH amounts. 
+    // Step 2: Convert the table to the array of PAIR_HASH amounts.
     // Each element contains count of PAIR_HASHes that is less or equal
     // to element index
     // The table will look like this:
@@ -218,7 +128,7 @@ static void OutputBits(TCmpStruct * pWork, unsigned int nbits, unsigned long bit
     {
         pWork->out_bytes++;
         bit_buff >>= (8 - out_bits);
-        
+
         pWork->out_buff[pWork->out_bytes] = (unsigned char)bit_buff;
         pWork->out_bits &= 7;
     }
@@ -236,7 +146,7 @@ static void OutputBits(TCmpStruct * pWork, unsigned int nbits, unsigned long bit
 
 // This function searches for a repetition
 // (a previous occurence of the current byte sequence)
-// Returns length of the repetition, and stores the backward distance 
+// Returns length of the repetition, and stores the backward distance
 // to pWork structure.
 static unsigned int FindRep(TCmpStruct * pWork, unsigned char * input_data)
 {
@@ -277,7 +187,7 @@ static unsigned int FindRep(TCmpStruct * pWork, unsigned char * input_data)
     phash_offs = pWork->phash_offs + phash_offs_index;
     prev_repetition = pWork->work_buff + phash_offs[0];
     repetition_limit = input_data - 1;
-    
+
     // If the current PAIR_HASH was not encountered before,
     // we haven't found a repetition.
     if(prev_repetition >= repetition_limit)
@@ -303,7 +213,7 @@ static unsigned int FindRep(TCmpStruct * pWork, unsigned char * input_data)
             {
                 prev_repetition++;
                 input_data_ptr++;
-                
+
                 // Are the bytes different ?
                 if(*prev_repetition != *input_data_ptr)
                     break;
@@ -399,7 +309,7 @@ static unsigned int FindRep(TCmpStruct * pWork, unsigned char * input_data)
         pWork->offs09BC[++offs_in_rep] = ++di_val;
     }
 
-    // 
+    //
     // Now go through all the repetitions from the first found one
     // to the current input data, and check if any of them migh be
     // a start of a greater sequence match.
@@ -408,7 +318,7 @@ static unsigned int FindRep(TCmpStruct * pWork, unsigned char * input_data)
     prev_repetition = pWork->work_buff + phash_offs[0];
     prev_rep_end = prev_repetition + rep_length;
     rep_length2 = rep_length;
-    
+
     for(;;)
     {
         rep_length2 = pWork->offs09BC[rep_length2];
@@ -502,7 +412,7 @@ static void WriteCmpData(TCmpStruct * pWork)
     unsigned int save_rep_length;           // Saved length of current repetition
     unsigned int save_distance = 0;         // Saved distance of current repetition
     unsigned int rep_length;                // Length of the found repetition
-    unsigned int phase = 0;                 // 
+    unsigned int phase = 0;                 //
 
     // Store the compression type and dictionary size
     pWork->out_buff[0] = (char)pWork->ctype;
@@ -542,12 +452,12 @@ static void WriteCmpData(TCmpStruct * pWork)
         input_data_end = pWork->work_buff + pWork->dsize_bytes + total_loaded;
         if(input_data_ended)
             input_data_end += 0x204;
-        
+
         //
         // Warning: The end of the buffer passed to "SortBuffer" is actually 2 bytes beyond
         // valid data. It is questionable if this is actually a bug or not,
         // but it might cause the compressed data output to be dependent on random bytes
-        // that are in the buffer. 
+        // that are in the buffer.
         // To prevent that, the calling application must always zero the compression
         // buffer before passing it to "implode"
         //
@@ -556,7 +466,7 @@ static void WriteCmpData(TCmpStruct * pWork)
         // previously compressed data, if any.
         switch(phase)
         {
-            case 0: 
+            case 0:
                 SortBuffer(pWork, input_data, input_data_end + 1);
                 phase++;
                 if(pWork->dsize_bytes != 0x1000)
@@ -750,14 +660,11 @@ unsigned int PKEXPORT implode(
 
     for(i = 0; i < 0x10; i++)
     {
-        if(1 << ExLenBits[i])
+        for(nCount2 = 0; nCount2 < (1 << ExLenBits[i]); nCount2++)
         {
-            for(nCount2 = 0; nCount2 < (1 << ExLenBits[i]); nCount2++)
-            {
-                pWork->nChBits[nCount]  = (unsigned char)(ExLenBits[i] + LenBits[i] + 1);
-                pWork->nChCodes[nCount] = (unsigned short)((nCount2 << (LenBits[i] + 1)) | ((LenCode[i] & 0xFFFF00FF) * 2) | 1);
-                nCount++;
-            }
+            pWork->nChBits[nCount]  = (unsigned char)(ExLenBits[i] + LenBits[i] + 1);
+            pWork->nChCodes[nCount] = (unsigned short)((nCount2 << (LenBits[i] + 1)) | ((LenCode[i] & 0xFFFF00FF) * 2) | 1);
+            nCount++;
         }
     }
 
diff --git a/OpenSource/StormLib/src/pklib/pklib.h b/OpenSource/StormLib/src/pklib/pklib.h
index 9eb2915b7..d9b2a70a8 100644
--- a/OpenSource/StormLib/src/pklib/pklib.h
+++ b/OpenSource/StormLib/src/pklib/pklib.h
@@ -32,7 +32,7 @@
 
 #ifndef PKEXPORT
 #ifdef WIN32
-#define PKEXPORT  __cdecl                   // Use for normal __cdecl calling 
+#define PKEXPORT  __cdecl                   // Use for normal __cdecl calling
 #else
 #define PKEXPORT
 #endif
@@ -45,7 +45,7 @@
 typedef struct
 {
     unsigned int   distance;                // 0000: Backward distance of the currently found repetition, decreased by 1
-    unsigned int   out_bytes;               // 0004: # bytes available in out_buff            
+    unsigned int   out_bytes;               // 0004: # bytes available in out_buff
     unsigned int   out_bits;                // 0008: # of bits available in the last out byte
     unsigned int   dsize_bits;              // 000C: Number of bits needed for dictionary size. 4 = 0x400, 5 = 0x800, 6 = 0x1000
     unsigned int   dsize_mask;              // 0010: Bit mask for dictionary. 0x0F = 0x400, 0x1F = 0x800, 0x3F = 0x1000
@@ -55,14 +55,14 @@ typedef struct
     unsigned char  dist_codes[0x40];        // 005C: Distance codes
     unsigned char  nChBits[0x306];          // 009C: Table of literal bit lengths to be put to the output stream
     unsigned short nChCodes[0x306];         // 03A2: Table of literal codes to be put to the output stream
-    unsigned short offs09AE;                // 09AE: 
+    unsigned short offs09AE;                // 09AE:
 
     void         * param;                   // 09B0: User parameter
     unsigned int (*read_buf)(char *buf, unsigned int *size, void *param);  // 9B4
     void         (*write_buf)(char *buf, unsigned int *size, void *param); // 9B8
 
     unsigned short offs09BC[0x204];         // 09BC:
-    unsigned long  offs0DC4;                // 0DC4: 
+    unsigned long  offs0DC4;                // 0DC4:
     unsigned short phash_to_index[0x900];   // 0DC8: Array of indexes (one for each PAIR_HASH) to the "pair_hash_offsets" table
     unsigned short phash_to_index_end;      // 1FC8: End marker for "phash_to_index" table
     char           out_buff[0x802];         // 1FCA: Compressed data
@@ -99,20 +99,32 @@ typedef struct
     unsigned char in_buff[0x800];           // 2234: Buffer for data to be decompressed
     unsigned char DistPosCodes[0x100];      // 2A34: Table of distance position codes
     unsigned char LengthCodes[0x100];       // 2B34: Table of length codes
-    unsigned char offs2C34[0x100];          // 2C34: Buffer for 
-    unsigned char offs2D34[0x100];          // 2D34: Buffer for 
-    unsigned char offs2E34[0x80];           // 2EB4: Buffer for 
-    unsigned char offs2EB4[0x100];          // 2EB4: Buffer for 
-    unsigned char ChBitsAsc[0x100];         // 2FB4: Buffer for 
+    unsigned char offs2C34[0x100];          // 2C34: Buffer for
+    unsigned char offs2D34[0x100];          // 2D34: Buffer for
+    unsigned char offs2E34[0x80];           // 2E34: Buffer for
+    unsigned char offs2EB4[0x100];          // 2EB4: Buffer for
+    unsigned char ChBitsAsc[0x100];         // 2FB4: Buffer for
     unsigned char DistBits[0x40];           // 30B4: Numbers of bytes to skip copied block length
     unsigned char LenBits[0x10];            // 30F4: Numbers of bits for skip copied block length
     unsigned char ExLenBits[0x10];          // 3104: Number of valid bits for copied block
-    unsigned short LenBase[0x10];           // 3114: Buffer for 
+    unsigned short LenBase[0x10];           // 3114: Buffer for
 } TDcmpStruct;
 
 #define EXP_BUFFER_SIZE sizeof(TDcmpStruct) // Size of decompression structure
                                             // Defined as 12596 in pkware headers
 
+//-----------------------------------------------------------------------------
+// Tables (in explode.c)
+
+extern unsigned char DistBits[0x40];
+extern unsigned char DistCode[0x40];
+extern unsigned char ExLenBits[0x10];
+extern unsigned short LenBase[0x10];
+extern unsigned char LenBits[0x10];
+extern unsigned char LenCode[0x10];
+extern unsigned char ChBitsAsc[0x100];
+extern unsigned short ChCodeAsc[0x100];
+
 //-----------------------------------------------------------------------------
 // Public functions
 
diff --git a/OpenSource/StormLib/src/resource.h b/OpenSource/StormLib/src/resource.h
new file mode 100644
index 000000000..8821947c1
--- /dev/null
+++ b/OpenSource/StormLib/src/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by DllMain.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        101
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1000
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
diff --git a/OpenSource/StormLib/src/sparse/sparse.cpp b/OpenSource/StormLib/src/sparse/sparse.cpp
index 4fe09810e..6d1b621d0 100644
--- a/OpenSource/StormLib/src/sparse/sparse.cpp
+++ b/OpenSource/StormLib/src/sparse/sparse.cpp
@@ -14,10 +14,10 @@
 /* 19.11.03  1.01  Dan  Big endian handling                                  */
 /* 08.12.03  2.01  Dan  High-memory handling (> 0x80000000)                  */
 /*****************************************************************************/
- 
+
 #include <assert.h>
 #include <string.h>
- 
+
 #include "sparse.h"
 
 //-----------------------------------------------------------------------------
@@ -88,7 +88,7 @@ void CompressSparse(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, i
                 // Put marker that means "0x80 of nonzeros"
                 *pbOutBuffer++ = 0xFF;
                 memcpy(pbOutBuffer, pbInBuffer, 0x80);
-                
+
                 // Adjust counter of nonzeros and both pointers
                 NumberOfNonZeros -= 0x80;
                 pbOutBuffer += 0x80;
@@ -108,7 +108,7 @@ void CompressSparse(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, i
                 // Put marker that means "1 nonzero byte"
                 *pbOutBuffer++ = 0x80;
                 memcpy(pbOutBuffer, pbInBuffer, 1);
-                
+
                 // Adjust counter of nonzeros and both pointers
                 NumberOfNonZeros--;
                 pbOutBuffer++;
@@ -171,7 +171,7 @@ void CompressSparse(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, i
 
             // Put marker that means "Several zeros"
             *pbOutBuffer++ = (unsigned char)(NumberOfZeros - 3);
-    
+
             // Adjust pointer
             pbInBuffer += NumberOfZeros;
         }
@@ -196,7 +196,7 @@ void CompressSparse(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, i
                 // Terminate with a marker that means "0x80 of nonzeros"
                 *pbOutBuffer++ = 0xFF;
                 memcpy(pbOutBuffer, pbInBuffer, NumberOfNonZeros);
-                
+
                 // Adjust pointer
                 pbOutBuffer += NumberOfNonZeros;
                 break;
diff --git a/OpenSource/StormLib/src/wdk/sources-cpp.cpp b/OpenSource/StormLib/src/wdk/sources-cpp.cpp
new file mode 100644
index 000000000..f2899759a
--- /dev/null
+++ b/OpenSource/StormLib/src/wdk/sources-cpp.cpp
@@ -0,0 +1,26 @@
+// This is a source file for WDK build of StormLib
+// It is copied to the root folder during the build process
+
+#include "src\adpcm\adpcm.cpp"
+#include "src\huffman\huff.cpp"
+#include "src\sparse\sparse.cpp"
+
+#include "src\FileStream.cpp"
+#include "src\SBaseCommon.cpp"
+#include "src\SBaseDumpData.cpp"
+#include "src\SBaseFileTable.cpp"
+#include "src\SBaseSubTypes.cpp"
+#include "src\SCompression.cpp"
+#include "src\SFileAddFile.cpp"
+#include "src\SFileAttributes.cpp"
+#include "src\SFileCompactArchive.cpp"
+#include "src\SFileCreateArchive.cpp"
+#include "src\SFileExtractFile.cpp"
+#include "src\SFileFindFile.cpp"
+#include "src\SFileGetFileInfo.cpp"
+#include "src\SFileListFile.cpp"
+#include "src\SFileOpenArchive.cpp"
+#include "src\SFileOpenFileEx.cpp"
+#include "src\SFilePatchArchives.cpp"
+#include "src\SFileReadFile.cpp"
+#include "src\SFileVerify.cpp"
diff --git a/OpenSource/StormLib/src/wdk/sources-wdk-bzip2.c b/OpenSource/StormLib/src/wdk/sources-wdk-bzip2.c
new file mode 100644
index 000000000..74cf92a1b
--- /dev/null
+++ b/OpenSource/StormLib/src/wdk/sources-wdk-bzip2.c
@@ -0,0 +1,13 @@
+// This is a source file for WDK build of StormLib
+// It is copied to the root folder during the build process
+
+#pragma warning(disable: 4242)                      // '=' : conversion from 'Int32' to 'UChar', possible loss of data
+#pragma warning(disable: 4244)                      // '=' : conversion from '__int64' to 'Int32', possible loss of data
+
+#include "src\bzip2\blocksort.c"
+#include "src\bzip2\bzlib.c"
+#include "src\bzip2\compress.c"
+#include "src\bzip2\crctable.c"
+#include "src\bzip2\decompress.c"
+#include "src\bzip2\huffman.c"
+#include "src\bzip2\randtable.c"
diff --git a/OpenSource/StormLib/src/wdk/sources-wdk-ltc.c b/OpenSource/StormLib/src/wdk/sources-wdk-ltc.c
new file mode 100644
index 000000000..7a7f90cc9
--- /dev/null
+++ b/OpenSource/StormLib/src/wdk/sources-wdk-ltc.c
@@ -0,0 +1,4 @@
+// This is a source file for WDK build of StormLib
+// It is copied to the root folder during the build process
+
+#include "src\libtomcrypt\src\math\ltm_desc.c"
diff --git a/OpenSource/StormLib/src/wdk/sources-wdk-lzma.c b/OpenSource/StormLib/src/wdk/sources-wdk-lzma.c
new file mode 100644
index 000000000..1fe46ee54
--- /dev/null
+++ b/OpenSource/StormLib/src/wdk/sources-wdk-lzma.c
@@ -0,0 +1,8 @@
+// This is a source file for WDK build of StormLib
+// It is copied to the root folder during the build process
+
+#include "src\lzma\C\LzFind.c"
+#include "src\lzma\C\LzFindMt.c"
+#include "src\lzma\C\LzmaDec.c"
+#include "src\lzma\C\LzmaEnc.c"
+#include "src\lzma\C\Threads.c"
diff --git a/OpenSource/StormLib/src/wdk/sources-wdk-misc.c b/OpenSource/StormLib/src/wdk/sources-wdk-misc.c
new file mode 100644
index 000000000..d1c36f0ba
--- /dev/null
+++ b/OpenSource/StormLib/src/wdk/sources-wdk-misc.c
@@ -0,0 +1,6 @@
+// This is a source file for WDK build of StormLib
+// It is copied to the root folder during the build process
+
+#include "src\jenkins\lookup3.c"
+#include "src\pklib\explode.c"
+#include "src\pklib\implode.c"
diff --git a/OpenSource/StormLib/src/wdk/sources-wdk-tomcrypt.c b/OpenSource/StormLib/src/wdk/sources-wdk-tomcrypt.c
new file mode 100644
index 000000000..60453d6e4
--- /dev/null
+++ b/OpenSource/StormLib/src/wdk/sources-wdk-tomcrypt.c
@@ -0,0 +1,82 @@
+// This is a source file for WDK build of StormLib
+// It is copied to the root folder during the build process
+
+#pragma warning(disable:4242)            // der_decode_ia5_string.c(84) : warning C4242: '=' : conversion from 'int' to 'unsigned char', possible loss of data
+
+#include "src\libtomcrypt\src\hashes\hash_memory.c"
+#include "src\libtomcrypt\src\hashes\md5.c"
+#include "src\libtomcrypt\src\hashes\sha1.c"
+#include "src\libtomcrypt\src\math\multi.c"
+#include "src\libtomcrypt\src\math\rand_prime.c"
+#include "src\libtomcrypt\src\misc\base64_decode.c"
+#include "src\libtomcrypt\src\misc\crypt_argchk.c"
+#include "src\libtomcrypt\src\misc\crypt_find_hash.c"
+#include "src\libtomcrypt\src\misc\crypt_find_prng.c"
+#include "src\libtomcrypt\src\misc\crypt_hash_descriptor.c"
+#include "src\libtomcrypt\src\misc\crypt_hash_is_valid.c"
+#include "src\libtomcrypt\src\misc\crypt_libc.c"
+#include "src\libtomcrypt\src\misc\crypt_ltc_mp_descriptor.c"
+#include "src\libtomcrypt\src\misc\crypt_prng_descriptor.c"
+#include "src\libtomcrypt\src\misc\crypt_prng_is_valid.c"
+#include "src\libtomcrypt\src\misc\crypt_register_hash.c"
+#include "src\libtomcrypt\src\misc\crypt_register_prng.c"
+#include "src\libtomcrypt\src\misc\zeromem.c"
+#include "src\libtomcrypt\src\pk\asn1\der_decode_bit_string.c"
+#include "src\libtomcrypt\src\pk\asn1\der_decode_boolean.c"
+#include "src\libtomcrypt\src\pk\asn1\der_decode_choice.c"
+#include "src\libtomcrypt\src\pk\asn1\der_decode_ia5_string.c"
+#include "src\libtomcrypt\src\pk\asn1\der_decode_integer.c"
+#include "src\libtomcrypt\src\pk\asn1\der_decode_object_identifier.c"
+#include "src\libtomcrypt\src\pk\asn1\der_decode_octet_string.c"
+#include "src\libtomcrypt\src\pk\asn1\der_decode_printable_string.c"
+#include "src\libtomcrypt\src\pk\asn1\der_decode_sequence_ex.c"
+#include "src\libtomcrypt\src\pk\asn1\der_decode_sequence_flexi.c"
+#include "src\libtomcrypt\src\pk\asn1\der_decode_sequence_multi.c"
+#include "src\libtomcrypt\src\pk\asn1\der_decode_short_integer.c"
+#include "src\libtomcrypt\src\pk\asn1\der_decode_utctime.c"
+#include "src\libtomcrypt\src\pk\asn1\der_decode_utf8_string.c"
+#include "src\libtomcrypt\src\pk\asn1\der_encode_bit_string.c"
+#include "src\libtomcrypt\src\pk\asn1\der_encode_boolean.c"
+#include "src\libtomcrypt\src\pk\asn1\der_encode_ia5_string.c"
+#include "src\libtomcrypt\src\pk\asn1\der_encode_integer.c"
+#include "src\libtomcrypt\src\pk\asn1\der_encode_object_identifier.c"
+#include "src\libtomcrypt\src\pk\asn1\der_encode_octet_string.c"
+#include "src\libtomcrypt\src\pk\asn1\der_encode_printable_string.c"
+#include "src\libtomcrypt\src\pk\asn1\der_encode_sequence_ex.c"
+#include "src\libtomcrypt\src\pk\asn1\der_encode_sequence_multi.c"
+#include "src\libtomcrypt\src\pk\asn1\der_encode_set.c"
+#include "src\libtomcrypt\src\pk\asn1\der_encode_setof.c"
+#include "src\libtomcrypt\src\pk\asn1\der_encode_short_integer.c"
+#include "src\libtomcrypt\src\pk\asn1\der_encode_utctime.c"
+#include "src\libtomcrypt\src\pk\asn1\der_encode_utf8_string.c"
+#include "src\libtomcrypt\src\pk\asn1\der_length_bit_string.c"
+#include "src\libtomcrypt\src\pk\asn1\der_length_boolean.c"
+#include "src\libtomcrypt\src\pk\asn1\der_length_ia5_string.c"
+#include "src\libtomcrypt\src\pk\asn1\der_length_integer.c"
+#include "src\libtomcrypt\src\pk\asn1\der_length_object_identifier.c"
+#include "src\libtomcrypt\src\pk\asn1\der_length_octet_string.c"
+#include "src\libtomcrypt\src\pk\asn1\der_length_printable_string.c"
+#include "src\libtomcrypt\src\pk\asn1\der_length_sequence.c"
+#include "src\libtomcrypt\src\pk\asn1\der_length_short_integer.c"
+#include "src\libtomcrypt\src\pk\asn1\der_length_utctime.c"
+#include "src\libtomcrypt\src\pk\asn1\der_length_utf8_string.c"
+#include "src\libtomcrypt\src\pk\asn1\der_sequence_free.c"
+#include "src\libtomcrypt\src\pk\ecc\ltc_ecc_map.c"
+#include "src\libtomcrypt\src\pk\ecc\ltc_ecc_mul2add.c"
+#include "src\libtomcrypt\src\pk\ecc\ltc_ecc_mulmod.c"
+#include "src\libtomcrypt\src\pk\ecc\ltc_ecc_points.c"
+#include "src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_add_point.c"
+#include "src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_dbl_point.c"
+#include "src\libtomcrypt\src\pk\pkcs1\pkcs_1_mgf1.c"
+#include "src\libtomcrypt\src\pk\pkcs1\pkcs_1_oaep_decode.c"
+#include "src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_decode.c"
+#include "src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_encode.c"
+#include "src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_decode.c"
+#include "src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_encode.c"
+#include "src\libtomcrypt\src\pk\rsa\rsa_exptmod.c"
+#include "src\libtomcrypt\src\pk\rsa\rsa_free.c"
+#include "src\libtomcrypt\src\pk\rsa\rsa_import.c"
+#include "src\libtomcrypt\src\pk\rsa\rsa_make_key.c"
+#include "src\libtomcrypt\src\pk\rsa\rsa_sign_hash.c"
+#include "src\libtomcrypt\src\pk\rsa\rsa_verify_hash.c"
+#include "src\libtomcrypt\src\pk\rsa\rsa_verify_simple.c"
diff --git a/OpenSource/StormLib/src/wdk/sources-wdk-tommath.c b/OpenSource/StormLib/src/wdk/sources-wdk-tommath.c
new file mode 100644
index 000000000..78e86a2e2
--- /dev/null
+++ b/OpenSource/StormLib/src/wdk/sources-wdk-tommath.c
@@ -0,0 +1,124 @@
+// This is a source file for WDK build of StormLib
+// It is copied to the root folder during the build process
+
+#pragma warning(disable:4334)             // warning C4334: '<<' : result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
+
+#include "src\libtommath\bn_fast_mp_invmod.c"
+#include "src\libtommath\bn_fast_mp_montgomery_reduce.c"
+#include "src\libtommath\bn_fast_s_mp_mul_digs.c"
+#include "src\libtommath\bn_fast_s_mp_mul_high_digs.c"
+#include "src\libtommath\bn_fast_s_mp_sqr.c"
+#include "src\libtommath\bn_mp_2expt.c"
+#include "src\libtommath\bn_mp_abs.c"
+#include "src\libtommath\bn_mp_add.c"
+#include "src\libtommath\bn_mp_add_d.c"
+#include "src\libtommath\bn_mp_addmod.c"
+#include "src\libtommath\bn_mp_and.c"
+#include "src\libtommath\bn_mp_clamp.c"
+#include "src\libtommath\bn_mp_clear.c"
+#include "src\libtommath\bn_mp_clear_multi.c"
+#include "src\libtommath\bn_mp_cmp.c"
+#include "src\libtommath\bn_mp_cmp_d.c"
+#include "src\libtommath\bn_mp_cmp_mag.c"
+#include "src\libtommath\bn_mp_cnt_lsb.c"
+#include "src\libtommath\bn_mp_copy.c"
+#include "src\libtommath\bn_mp_count_bits.c"
+#include "src\libtommath\bn_mp_div.c"
+#include "src\libtommath\bn_mp_div_2.c"
+#include "src\libtommath\bn_mp_div_2d.c"
+#include "src\libtommath\bn_mp_div_3.c"
+#include "src\libtommath\bn_mp_div_d.c"
+#include "src\libtommath\bn_mp_dr_is_modulus.c"
+#include "src\libtommath\bn_mp_dr_reduce.c"
+#include "src\libtommath\bn_mp_dr_setup.c"
+#include "src\libtommath\bn_mp_exch.c"
+#include "src\libtommath\bn_mp_expt_d.c"
+#include "src\libtommath\bn_mp_exptmod.c"
+#include "src\libtommath\bn_mp_exptmod_fast.c"
+#include "src\libtommath\bn_mp_exteuclid.c"
+#include "src\libtommath\bn_mp_fread.c"
+#include "src\libtommath\bn_mp_fwrite.c"
+#include "src\libtommath\bn_mp_gcd.c"
+#include "src\libtommath\bn_mp_get_int.c"
+#include "src\libtommath\bn_mp_grow.c"
+#include "src\libtommath\bn_mp_init.c"
+#include "src\libtommath\bn_mp_init_copy.c"
+#include "src\libtommath\bn_mp_init_multi.c"
+#include "src\libtommath\bn_mp_init_set.c"
+#include "src\libtommath\bn_mp_init_set_int.c"
+#include "src\libtommath\bn_mp_init_size.c"
+#include "src\libtommath\bn_mp_invmod.c"
+#include "src\libtommath\bn_mp_invmod_slow.c"
+#include "src\libtommath\bn_mp_is_square.c"
+#include "src\libtommath\bn_mp_jacobi.c"
+#include "src\libtommath\bn_mp_karatsuba_mul.c"
+#include "src\libtommath\bn_mp_karatsuba_sqr.c"
+#include "src\libtommath\bn_mp_lcm.c"
+#include "src\libtommath\bn_mp_lshd.c"
+#include "src\libtommath\bn_mp_mod.c"
+#include "src\libtommath\bn_mp_mod_2d.c"
+#include "src\libtommath\bn_mp_mod_d.c"
+#include "src\libtommath\bn_mp_montgomery_calc_normalization.c"
+#include "src\libtommath\bn_mp_montgomery_reduce.c"
+#include "src\libtommath\bn_mp_montgomery_setup.c"
+#include "src\libtommath\bn_mp_mul.c"
+#include "src\libtommath\bn_mp_mul_2.c"
+#include "src\libtommath\bn_mp_mul_2d.c"
+#include "src\libtommath\bn_mp_mul_d.c"
+#include "src\libtommath\bn_mp_mulmod.c"
+#include "src\libtommath\bn_mp_n_root.c"
+#include "src\libtommath\bn_mp_neg.c"
+#include "src\libtommath\bn_mp_or.c"
+#include "src\libtommath\bn_mp_prime_fermat.c"
+#include "src\libtommath\bn_mp_prime_is_divisible.c"
+#include "src\libtommath\bn_mp_prime_is_prime.c"
+#include "src\libtommath\bn_mp_prime_miller_rabin.c"
+#include "src\libtommath\bn_mp_prime_next_prime.c"
+#include "src\libtommath\bn_mp_prime_rabin_miller_trials.c"
+#include "src\libtommath\bn_mp_prime_random_ex.c"
+#include "src\libtommath\bn_mp_radix_size.c"
+#include "src\libtommath\bn_mp_radix_smap.c"
+#include "src\libtommath\bn_mp_rand.c"
+#include "src\libtommath\bn_mp_read_radix.c"
+#include "src\libtommath\bn_mp_read_signed_bin.c"
+#include "src\libtommath\bn_mp_read_unsigned_bin.c"
+#include "src\libtommath\bn_mp_reduce.c"
+#include "src\libtommath\bn_mp_reduce_2k.c"
+#include "src\libtommath\bn_mp_reduce_2k_l.c"
+#include "src\libtommath\bn_mp_reduce_2k_setup.c"
+#include "src\libtommath\bn_mp_reduce_2k_setup_l.c"
+#include "src\libtommath\bn_mp_reduce_is_2k.c"
+#include "src\libtommath\bn_mp_reduce_is_2k_l.c"
+#include "src\libtommath\bn_mp_reduce_setup.c"
+#include "src\libtommath\bn_mp_rshd.c"
+#include "src\libtommath\bn_mp_set.c"
+#include "src\libtommath\bn_mp_set_int.c"
+#include "src\libtommath\bn_mp_shrink.c"
+#include "src\libtommath\bn_mp_signed_bin_size.c"
+#include "src\libtommath\bn_mp_sqr.c"
+#include "src\libtommath\bn_mp_sqrmod.c"
+#include "src\libtommath\bn_mp_sqrt.c"
+#include "src\libtommath\bn_mp_sub.c"
+#include "src\libtommath\bn_mp_sub_d.c"
+#include "src\libtommath\bn_mp_submod.c"
+#include "src\libtommath\bn_mp_to_signed_bin.c"
+#include "src\libtommath\bn_mp_to_signed_bin_n.c"
+#include "src\libtommath\bn_mp_to_unsigned_bin.c"
+#include "src\libtommath\bn_mp_to_unsigned_bin_n.c"
+#include "src\libtommath\bn_mp_toom_mul.c"
+#include "src\libtommath\bn_mp_toom_sqr.c"
+#include "src\libtommath\bn_mp_toradix.c"
+#include "src\libtommath\bn_mp_toradix_n.c"
+#include "src\libtommath\bn_mp_unsigned_bin_size.c"
+#include "src\libtommath\bn_mp_xor.c"
+#include "src\libtommath\bn_mp_zero.c"
+#include "src\libtommath\bn_prime_tab.c"
+#include "src\libtommath\bn_reverse.c"
+#include "src\libtommath\bn_s_mp_add.c"
+#include "src\libtommath\bn_s_mp_exptmod.c"
+#include "src\libtommath\bn_s_mp_mul_digs.c"
+#include "src\libtommath\bn_s_mp_mul_high_digs.c"
+#include "src\libtommath\bn_s_mp_sqr.c"
+#include "src\libtommath\bn_s_mp_sub.c"
+#include "src\libtommath\bncore.c"
+
diff --git a/OpenSource/StormLib/src/wdk/sources-wdk-zlib.c b/OpenSource/StormLib/src/wdk/sources-wdk-zlib.c
new file mode 100644
index 000000000..2455a9a67
--- /dev/null
+++ b/OpenSource/StormLib/src/wdk/sources-wdk-zlib.c
@@ -0,0 +1,21 @@
+// This is a source file for WDK build of StormLib
+// It is copied to the root folder during the build process
+
+#pragma warning(disable:4242)            // deflate.c(1693) : warning C4242: '=' : conversion from 'unsigned int' to 'Bytef', possible loss of data
+
+#define NO_DUMMY_DECL
+#define NO_GZIP
+#include "src\zlib\adler32.c"
+#undef DO1
+#undef DO8
+#undef MIN
+#include "src\zlib\compress.c"
+#include "src\zlib\crc32.c"
+#include "src\zlib\deflate.c"
+#include "src\zlib\trees.c"
+#include "src\zlib\zutil.c"
+
+#undef COPY                             // Conflicting definition
+#include "src\zlib\inflate.c"
+#include "src\zlib\inffast.c"
+#include "src\zlib\inftrees.c"
diff --git a/OpenSource/StormLib/src/zlib/gzguts.h b/OpenSource/StormLib/src/zlib/gzguts.h
new file mode 100644
index 000000000..990a4d251
--- /dev/null
+++ b/OpenSource/StormLib/src/zlib/gzguts.h
@@ -0,0 +1,218 @@
+/* gzguts.h -- zlib internal header definitions for gz* operations
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifdef _LARGEFILE64_SOURCE
+#  ifndef _LARGEFILE_SOURCE
+#    define _LARGEFILE_SOURCE 1
+#  endif
+#  ifdef _FILE_OFFSET_BITS
+#    undef _FILE_OFFSET_BITS
+#  endif
+#endif
+
+#ifdef HAVE_HIDDEN
+#  define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+#  define ZLIB_INTERNAL
+#endif
+
+#include <stdio.h>
+#include "zlib.h"
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#  include <limits.h>
+#endif
+
+#ifndef _POSIX_SOURCE
+#  define _POSIX_SOURCE
+#endif
+#include <fcntl.h>
+
+#ifdef _WIN32
+#  include <stddef.h>
+#endif
+
+#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
+#  include <io.h>
+#endif
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+#  define WIDECHAR
+#endif
+
+#ifdef WINAPI_FAMILY
+#  define open _open
+#  define read _read
+#  define write _write
+#  define close _close
+#endif
+
+#ifdef NO_DEFLATE       /* for compatibility with old definition */
+#  define NO_GZCOMPRESS
+#endif
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+
+#if defined(__CYGWIN__)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+
+#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+
+#ifndef HAVE_VSNPRINTF
+#  ifdef MSDOS
+/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+   but for now we just assume it doesn't. */
+#    define NO_vsnprintf
+#  endif
+#  ifdef __TURBOC__
+#    define NO_vsnprintf
+#  endif
+#  ifdef WIN32
+/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+#    if !defined(vsnprintf) && !defined(NO_vsnprintf)
+#      if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
+#         define vsnprintf _vsnprintf
+#      endif
+#    endif
+#  endif
+#  ifdef __SASC
+#    define NO_vsnprintf
+#  endif
+#  ifdef VMS
+#    define NO_vsnprintf
+#  endif
+#  ifdef __OS400__
+#    define NO_vsnprintf
+#  endif
+#  ifdef __MVS__
+#    define NO_vsnprintf
+#  endif
+#endif
+
+/* unlike snprintf (which is required in C99), _snprintf does not guarantee
+   null termination of the result -- however this is only used in gzlib.c where
+   the result is assured to fit in the space provided */
+#if defined(_MSC_VER) && _MSC_VER < 1900
+#  define snprintf _snprintf
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* since "static" is used to mean two completely different things in C, we
+   define "local" for the non-static meaning of "static", for readability
+   (compile with -Dlocal if your debugger can't find static symbols) */
+
+/* gz* functions always use library allocation functions */
+#ifndef STDC
+  extern voidp  malloc OF((uInt size));
+  extern void   free   OF((voidpf ptr));
+#endif
+
+/* get errno and strerror definition */
+#if defined UNDER_CE
+#  include <windows.h>
+#  define zstrerror() gz_strwinerror((DWORD)GetLastError())
+#else
+#  ifndef NO_STRERROR
+#    include <errno.h>
+#    define zstrerror() strerror(errno)
+#  else
+#    define zstrerror() "stdio error (consult errno)"
+#  endif
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
+    ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+    ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+    ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+    ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+#endif
+
+/* default memLevel */
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+
+/* default i/o buffer size -- double this for output when reading (this and
+   twice this must be able to fit in an unsigned type) */
+#define GZBUFSIZE 8192
+
+/* gzip modes, also provide a little integrity check on the passed structure */
+#define GZ_NONE 0
+#define GZ_READ 7247
+#define GZ_WRITE 31153
+#define GZ_APPEND 1     /* mode set to GZ_WRITE after the file is opened */
+
+/* values for gz_state how */
+#define LOOK 0      /* look for a gzip header */
+#define COPY 1      /* copy input directly */
+#define GZIP 2      /* decompress a gzip stream */
+
+/* internal gzip file state data structure */
+typedef struct {
+        /* exposed contents for gzgetc() macro */
+    struct gzFile_s x;      /* "x" for exposed */
+                            /* x.have: number of bytes available at x.next */
+                            /* x.next: next output data to deliver or write */
+                            /* x.pos: current position in uncompressed data */
+        /* used for both reading and writing */
+    int mode;               /* see gzip modes above */
+    int fd;                 /* file descriptor */
+    char *path;             /* path or fd for error messages */
+    unsigned size;          /* buffer size, zero if not allocated yet */
+    unsigned want;          /* requested buffer size, default is GZBUFSIZE */
+    unsigned char *in;      /* input buffer (double-sized when writing) */
+    unsigned char *out;     /* output buffer (double-sized when reading) */
+    int direct;             /* 0 if processing gzip, 1 if transparent */
+        /* just for reading */
+    int how;                /* 0: get header, 1: copy, 2: decompress */
+    z_off64_t start;        /* where the gzip data started, for rewinding */
+    int eof;                /* true if end of input file reached */
+    int past;               /* true if read requested past end */
+        /* just for writing */
+    int level;              /* compression level */
+    int strategy;           /* compression strategy */
+        /* seek request */
+    z_off64_t skip;         /* amount to skip (already rewound if backwards) */
+    int seek;               /* true if seek request pending */
+        /* error information */
+    int err;                /* error code */
+    char *msg;              /* error message */
+        /* zlib inflate or deflate stream */
+    z_stream strm;          /* stream structure in-place (not a pointer) */
+} gz_state;
+typedef gz_state FAR *gz_statep;
+
+/* shared functions */
+void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
+#if defined UNDER_CE
+char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
+#endif
+
+/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
+   value -- needed when comparing unsigned to z_off64_t, which is signed
+   (possible z_off64_t types off_t, off64_t, and long are all signed) */
+#ifdef INT_MAX
+#  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
+#else
+unsigned ZLIB_INTERNAL gz_intmax OF((void));
+#  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
+#endif
diff --git a/OpenSource/StormLib/src/zlib/inflate.h b/OpenSource/StormLib/src/zlib/inflate.h
index 95f4986d4..eaef3dc08 100644
--- a/OpenSource/StormLib/src/zlib/inflate.h
+++ b/OpenSource/StormLib/src/zlib/inflate.h
@@ -1,5 +1,5 @@
 /* inflate.h -- internal inflate state definition
- * Copyright (C) 1995-2009 Mark Adler
+ * Copyright (C) 1995-2016 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -8,6 +8,9 @@
    subject to change. Applications should only use zlib.h.
  */
 
+#ifndef __INFLATE_H_
+#define __INFLATE_H_
+
 /* define NO_GZIP when compiling if you want to disable gzip header and
    trailer decoding by inflate().  NO_GZIP would be used to avoid linking in
    the crc code when it is not needed.  For shared libraries, gzip decoding
@@ -18,7 +21,7 @@
 
 /* Possible inflate modes between inflate() calls */
 typedef enum {
-    HEAD,       /* i: waiting for magic header */
+    HEAD = 16180,   /* i: waiting for magic header */
     FLAGS,      /* i: waiting for method and flags (gzip) */
     TIME,       /* i: waiting for modification time (gzip) */
     OS,         /* i: waiting for extra flags and operating system (gzip) */
@@ -77,11 +80,14 @@ typedef enum {
         CHECK -> LENGTH -> DONE
  */
 
-/* state maintained between inflate() calls.  Approximately 10K bytes. */
+/* State maintained between inflate() calls -- approximately 7K bytes, not
+   including the allocated sliding window, which is up to 32K bytes. */
 struct inflate_state {
+    z_streamp strm;             /* pointer back to this zlib stream */
     inflate_mode mode;          /* current inflate mode */
     int last;                   /* true if processing last block */
-    int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip */
+    int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip,
+                                   bit 2 true to validate check value */
     int havedict;               /* true if dictionary provided */
     int flags;                  /* gzip header method and flags (0 if zlib) */
     unsigned dmax;              /* zlib header max distance (INFLATE_STRICT) */
@@ -120,3 +126,5 @@ struct inflate_state {
     int back;                   /* bits back of last unprocessed length/lit */
     unsigned was;               /* initial length of match */
 };
+
+#endif __INFLATE_H_
diff --git a/OpenSource/StormLib/src/zlib/inftrees.h b/OpenSource/StormLib/src/zlib/inftrees.h
index baa53a0b1..14429f37f 100644
--- a/OpenSource/StormLib/src/zlib/inftrees.h
+++ b/OpenSource/StormLib/src/zlib/inftrees.h
@@ -8,6 +8,9 @@
    subject to change. Applications should only use zlib.h.
  */
 
+#ifndef __INFTREES_H_
+#define __INFTREES_H_
+
 /* Structure for decoding tables.  Each entry provides either the
    information needed to do the operation requested by the code that
    indexed that table entry, or it provides a pointer to another
@@ -60,3 +63,5 @@ typedef enum {
 int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
                              unsigned codes, code FAR * FAR *table,
                              unsigned FAR *bits, unsigned short FAR *work));
+
+#endif  // __INFTREES_H_
diff --git a/OpenSource/StormLib/storm_dll/Storm_dll.sln b/OpenSource/StormLib/storm_dll/Storm_dll.sln
new file mode 100644
index 000000000..286e6135f
--- /dev/null
+++ b/OpenSource/StormLib/storm_dll/Storm_dll.sln
@@ -0,0 +1,35 @@
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "storm_dll", "storm_dll.vcproj", "{BD600973-C6FA-4CE3-8821-67F6418B7F9C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "storm_test", "storm_test_vs08.vcproj", "{5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{BD600973-C6FA-4CE3-8821-67F6418B7F9C}.Debug|Win32.ActiveCfg = Debug|Win32
+		{BD600973-C6FA-4CE3-8821-67F6418B7F9C}.Debug|Win32.Build.0 = Debug|Win32
+		{BD600973-C6FA-4CE3-8821-67F6418B7F9C}.Debug|x64.ActiveCfg = Debug|x64
+		{BD600973-C6FA-4CE3-8821-67F6418B7F9C}.Debug|x64.Build.0 = Debug|x64
+		{BD600973-C6FA-4CE3-8821-67F6418B7F9C}.Release|Win32.ActiveCfg = Release|Win32
+		{BD600973-C6FA-4CE3-8821-67F6418B7F9C}.Release|Win32.Build.0 = Release|Win32
+		{BD600973-C6FA-4CE3-8821-67F6418B7F9C}.Release|x64.ActiveCfg = Release|x64
+		{BD600973-C6FA-4CE3-8821-67F6418B7F9C}.Release|x64.Build.0 = Release|x64
+		{5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}.Debug|Win32.ActiveCfg = Debug|Win32
+		{5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}.Debug|Win32.Build.0 = Debug|Win32
+		{5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}.Debug|x64.ActiveCfg = Debug|x64
+		{5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}.Debug|x64.Build.0 = Debug|x64
+		{5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}.Release|Win32.ActiveCfg = Release|Win32
+		{5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}.Release|Win32.Build.0 = Release|Win32
+		{5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}.Release|x64.ActiveCfg = Release|x64
+		{5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/OpenSource/StormLib/storm_dll/Storm_dll.vcproj b/OpenSource/StormLib/storm_dll/Storm_dll.vcproj
new file mode 100644
index 000000000..6b123ff16
--- /dev/null
+++ b/OpenSource/StormLib/storm_dll/Storm_dll.vcproj
@@ -0,0 +1,363 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="storm_dll"
+	ProjectGUID="{BD600973-C6FA-4CE3-8821-67F6418B7F9C}"
+	RootNamespace="storm_dll"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\bin\$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory=".\bin\$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;storm_dll_EXPORTS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\storm.dll"
+				LinkIncremental="2"
+				GenerateManifest="false"
+				ModuleDefinitionFile=".\storm_dll.def"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				BaseAddress="0x15000000"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory=".\bin\$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory=".\bin\$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;storm_dll_EXPORTS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\storm.dll"
+				LinkIncremental="2"
+				GenerateManifest="false"
+				ModuleDefinitionFile=".\storm_dll.def"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				BaseAddress="0x15000000"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\bin\$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory=".\bin\$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;storm_dll_EXPORTS"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\storm.dll"
+				LinkIncremental="1"
+				GenerateManifest="false"
+				ModuleDefinitionFile=".\storm_dll.def"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				BaseAddress="0x15000000"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory=".\bin\$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory=".\bin\$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;storm_dll_EXPORTS"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\storm.dll"
+				LinkIncremental="1"
+				GenerateManifest="false"
+				ModuleDefinitionFile=".\storm_dll.def"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				BaseAddress="0x15000000"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\storm_dll.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\storm_dll.def"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\storm_dll.h"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/OpenSource/StormLib/storm_dll/storm.lib b/OpenSource/StormLib/storm_dll/storm.lib
new file mode 100644
index 000000000..3a68346f7
Binary files /dev/null and b/OpenSource/StormLib/storm_dll/storm.lib differ
diff --git a/OpenSource/StormLib/storm_dll/storm_dll.cpp b/OpenSource/StormLib/storm_dll/storm_dll.cpp
new file mode 100644
index 000000000..2941f2a37
--- /dev/null
+++ b/OpenSource/StormLib/storm_dll/storm_dll.cpp
@@ -0,0 +1,117 @@
+/*****************************************************************************/
+/* Storm.cpp                              Copyright (c) Ladislav Zezula 2003 */
+/*---------------------------------------------------------------------------*/
+/* This is just a dummy module for building import library for Storm.dll     */
+/*---------------------------------------------------------------------------*/
+/*   Date    Ver   Who  Comment                                              */
+/* --------  ----  ---  -------                                              */
+/* 11.04.03  1.00  Lad  The first version of Storm.cpp                       */
+/*****************************************************************************/
+
+#include <windows.h>
+
+#define BUILDING_STORM_CPP
+#define STORM_ALTERNATE_NAMES
+#include "storm_dll.h"
+
+BOOL WINAPI SFILE(OpenArchive)(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, HANDLE *hMPQ)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+BOOL WINAPI SFILE(CloseArchive)(HANDLE hMPQ)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+BOOL WINAPI SFILE(GetArchiveName)(HANDLE hMPQ, LPCSTR lpBuffer, DWORD dwBufferLength)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+BOOL WINAPI SFILE(OpenFile)(LPCSTR lpFileName, HANDLE *hFile)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+BOOL WINAPI SFILE(OpenFileEx)(HANDLE hMPQ, LPCSTR lpFileName, DWORD dwSearchScope, HANDLE *hFile)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+BOOL WINAPI SFILE(CloseFile)(HANDLE hFile)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+DWORD WINAPI SFILE(GetFileSize)(HANDLE hFile, LPDWORD lpFileSizeHigh)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+BOOL WINAPI SFILE(GetFileArchive)(HANDLE hFile, HANDLE *hMPQ)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+BOOL WINAPI SFILE(GetFileName)(HANDLE hFile, LPCSTR lpBuffer, DWORD dwBufferLength)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+DWORD WINAPI SFILE(SetFilePointer)(HANDLE hFile, long lDistanceToMove, PLONG lplDistanceToMoveHigh, DWORD dwMoveMethod)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+BOOL WINAPI SFILE(ReadFile)(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+LCID WINAPI SFILE(SetLocale)(LCID nNewLocale)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+BOOL WINAPI SFILE(GetBasePath)(LPCSTR lpBuffer, DWORD dwBufferLength)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+BOOL WINAPI SFILE(SetBasePath)(LPCSTR lpNewBasePath)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+BOOL WINAPI SFILE(Destroy)()
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+BOOL WINAPI SCOMP(Compress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int uCmp, int uCmpType, int nCmpLevel)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+BOOL WINAPI SCOMP(Decompress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
diff --git a/OpenSource/StormLib/storm_dll/storm_dll.def b/OpenSource/StormLib/storm_dll/storm_dll.def
new file mode 100644
index 000000000..8de88f5db
--- /dev/null
+++ b/OpenSource/StormLib/storm_dll/storm_dll.def
@@ -0,0 +1,25 @@
+; Storm definition file with alternate Storm.dll names
+LIBRARY      "Storm"
+
+EXPORTS
+    StormCloseArchive      @252      ; 0x0FC
+    StormCloseFile         @253      ; 0x0FD
+    StormDestroy           @262      ; 0x106
+    StormGetFileArchive    @264      ; 0x108
+    StormGetFileSize       @265      ; 0x109
+    StormOpenArchive       @266      ; 0x10A
+    StormOpenFile          @267      ; 0x10B
+    StormOpenFileEx        @268      ; 0x10C
+    StormReadFile          @269      ; 0x10D
+    StormSetBasePath       @270      ; 0x10E
+    StormSetFilePointer    @271      ; 0x10F
+    StormSetLocale         @272      ; 0x110
+    StormGetBasePath       @273      ; 0x111
+    StormGetArchiveName    @275      ; 0x113
+    StormGetFileName       @276      ; 0x114
+
+;   StormSetLastError      @465      ; 0x
+
+    StormCompress          @551      ; 0x227
+    StormDecompress        @552      ; 0x228
+    
\ No newline at end of file
diff --git a/OpenSource/StormLib/storm_dll/storm_dll.h b/OpenSource/StormLib/storm_dll/storm_dll.h
new file mode 100644
index 000000000..75681b8c3
--- /dev/null
+++ b/OpenSource/StormLib/storm_dll/storm_dll.h
@@ -0,0 +1,65 @@
+/*****************************************************************************/
+/* Storm.h                           Copyright Justin Olbrantz(Quantam) 2000 */
+/*---------------------------------------------------------------------------*/
+/* Storm Interface Library v1.0 for Windows                                  */
+/*                                                                           */
+/* Author : Justin Olbrantz(Quantam)                                         */
+/* E-mail : omega@dragonfire.net                                             */
+/* WWW    : www.campaigncreations.com/starcraft/mpq2k/inside_mopaq/          */
+/*---------------------------------------------------------------------------*/
+/*   Date    Ver   Who  Comment                                              */
+/* --------  ----  ---  -------                                              */
+/* xx.xx.00  1.00  Qua  The first version of Storm.h                         */
+/* 11.04.03  1.00  Lad  Added some functions                                 */
+/*****************************************************************************/
+
+#ifndef __STORM_H__
+#define __STORM_H__
+
+// We need the Windows data types for the Storm prototypes
+#include <windows.h>
+
+// Sometimes is necessary to change the function names so they
+// will not conflict with other MPQ tools.
+#ifdef STORM_ALTERNATE_NAMES
+  #define SFILE(Name) Storm##Name
+  #define SCOMP(Name) Storm##Name
+#else
+  #define SFILE(Name) SFile##Name
+  #define SCOMP(Name) SComp##Name
+#endif
+
+// Make sure the functions are exported as C functions
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Storm file function prototypes
+BOOL  WINAPI SFILE(OpenArchive)(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, HANDLE *hMPQ);
+BOOL  WINAPI SFILE(CloseArchive)(HANDLE hMPQ);
+BOOL  WINAPI SFILE(GetArchiveName)(HANDLE hMPQ, LPCSTR lpBuffer, DWORD dwBufferLength);
+BOOL  WINAPI SFILE(OpenFile)(LPCSTR lpFileName, HANDLE *hFile);
+BOOL  WINAPI SFILE(OpenFileEx)(HANDLE hMPQ, LPCSTR lpFileName, DWORD dwSearchScope, HANDLE *hFile);
+BOOL  WINAPI SFILE(CloseFile)(HANDLE hFile);
+DWORD WINAPI SFILE(GetFileSize)(HANDLE hFile, LPDWORD lpFileSizeHigh);
+BOOL  WINAPI SFILE(GetFileArchive)(HANDLE hFile, HANDLE *hMPQ);
+BOOL  WINAPI SFILE(GetFileName)(HANDLE hFile, LPCSTR lpBuffer, DWORD dwBufferLength);
+DWORD WINAPI SFILE(SetFilePointer)(HANDLE hFile, long lDistanceToMove, PLONG lplDistanceToMoveHigh, DWORD dwMoveMethod);
+BOOL  WINAPI SFILE(ReadFile)(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
+LCID  WINAPI SFILE(SetLocale)(LCID nNewLocale);
+BOOL  WINAPI SFILE(GetBasePath)(LPCSTR lpBuffer, DWORD dwBufferLength);
+BOOL  WINAPI SFILE(SetBasePath)(LPCSTR lpNewBasePath);
+
+// Storm (de)compression functions
+BOOL  WINAPI SCOMP(Compress)  (char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int uCmp, int uCmpType, int nCmpLevel);
+BOOL  WINAPI SCOMP(Decompress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength);
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(_MSC_VER) && !defined(BUILDING_STORM_CPP)
+#pragma comment(lib, "Storm.lib")    // Force linking Storm.lib and thus Storm.dll
+#endif
+
+#endif // __STORM_H__
diff --git a/OpenSource/StormLib/storm_dll/storm_test.cpp b/OpenSource/StormLib/storm_dll/storm_test.cpp
new file mode 100644
index 000000000..92ff061f9
--- /dev/null
+++ b/OpenSource/StormLib/storm_dll/storm_test.cpp
@@ -0,0 +1,46 @@
+/*****************************************************************************/
+/* Storm_test.cpp                         Copyright (c) Ladislav Zezula 2014 */
+/*---------------------------------------------------------------------------*/
+/* Test module for storm.dll (original Blizzard MPQ dynalic library          */
+/*---------------------------------------------------------------------------*/
+/*   Date    Ver   Who  Comment                                              */
+/* --------  ----  ---  -------                                              */
+/* 24.08.14  1.00  Lad  The first version of Storm_test.cpp                  */
+/*****************************************************************************/
+
+#define _CRT_NON_CONFORMING_SWPRINTFS
+#define _CRT_SECURE_NO_DEPRECATE
+#include <stdio.h>
+
+#ifdef _MSC_VER
+#include <crtdbg.h>
+#endif
+
+#define STORM_ALTERNATE_NAMES               // Use Storm* prefix for functions
+#include "storm_dll.h"                      // Header file for Storm.dll
+
+//-----------------------------------------------------------------------------
+// Main
+
+int main()
+{
+    LPCSTR szArchiveName = "e:\\war3.mpq";
+    HANDLE hMpq = NULL;
+    HANDLE hFile = NULL;
+    BYTE Buffer[0x100];
+    DWORD dwBytesRead = 0;
+
+    if(StormOpenArchive(szArchiveName, 0, 0, &hMpq))
+    {
+        if(StormOpenFileEx(hMpq, "(1)TheDeathSheep.w3m", 0, &hFile))
+        {
+            dwBytesRead = StormGetFileSize(hFile, NULL);
+            StormReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL);
+            StormCloseFile(hFile);
+        }
+
+        StormCloseArchive(hMpq);
+    }
+
+    return 0;
+}
diff --git a/OpenSource/StormLib/storm_dll/storm_test_vs08.vcproj b/OpenSource/StormLib/storm_dll/storm_test_vs08.vcproj
new file mode 100644
index 000000000..456b11e37
--- /dev/null
+++ b/OpenSource/StormLib/storm_dll/storm_test_vs08.vcproj
@@ -0,0 +1,359 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="storm_test"
+	ProjectGUID="{5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}"
+	RootNamespace="storm_test"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\bin\$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory=".\bin\$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../aaa/inc;exif"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/storm_test.exe"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories="../aaa/lib32"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/storm_test.pdb"
+				SubSystem="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory=".\bin\$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory=".\bin\$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../aaa/inc"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/storm_test.exe"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories="../aaa/lib64"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/storm_test.pdb"
+				SubSystem="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\bin\$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory=".\bin\$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../aaa/inc"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/storm_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../aaa/lib32"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory=".\bin\$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory=".\bin\$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../aaa/inc"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/storm_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../aaa/lib64"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine=""
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\storm_test.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			>
+			<File
+				RelativePath=".\storm_dll.h"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/OpenSource/StormLib/test/StormTest.cpp b/OpenSource/StormLib/test/StormTest.cpp
index ebdc7a169..a420880c7 100644
--- a/OpenSource/StormLib/test/StormTest.cpp
+++ b/OpenSource/StormLib/test/StormTest.cpp
@@ -28,25 +28,45 @@
 #pragma comment(lib, "winmm.lib")
 #endif
 
-#ifndef PLATFORM_WINDOWS
+#ifndef STORMLIB_WINDOWS
 #include <dirent.h>
 #endif
 
 //------------------------------------------------------------------------------
-// Defines
+// Local structures
 
-#ifdef PLATFORM_WINDOWS
-#define WORK_PATH_ROOT _T("E:\\Multimedia\\MPQs")
+#define TEST_FLAG_PROTECTED  0x01000000
+#define TEST_FLAG_FILE_COUNT 0x00FFFFFF
+
+typedef struct _TEST_INFO
+{
+    LPCTSTR szMpqName1;
+    LPCTSTR szMpqName2;
+    DWORD   dwFlags;
+    LPCSTR  szFileName1;
+    LPCSTR  szFileName2;
+} TEST_INFO, PTEST_INFO;
+
+//------------------------------------------------------------------------------
+// Local variables
+
+#ifdef STORMLIB_WINDOWS
+#define WORK_PATH_ROOT _T("\\Multimedia\\MPQs")
 static const TCHAR szListFileDir[] = { '1', '9', '9', '5', ' ', '-', ' ', 'T', 'e', 's', 't', ' ', 'M', 'P', 'Q', 's', '\\', 'l', 'i', 's', 't', 'f', 'i', 'l', 'e', 's', '-', (TCHAR)0x65B0, (TCHAR)0x5EFA, (TCHAR)0x6587, (TCHAR)0x4EF6, (TCHAR)0x5939, 0 };
 #endif
 
-#ifdef PLATFORM_LINUX
-#define WORK_PATH_ROOT "/home/ladik/MPQs"
+#ifdef STORMLIB_LINUX
+#define WORK_PATH_ROOT "/media/ladik/MPQs"
+static const TCHAR szListFileDir[] = { '1', '9', '9', '5', ' ', '-', ' ', 'T', 'e', 's', 't', ' ', 'M', 'P', 'Q', 's', '\\', 'l', 'i', 's', 't', 'f', 'i', 'l', 'e', 's', '-', (TCHAR)0xe6, (TCHAR)0x96, (TCHAR)0xB0, (TCHAR)0xE5, (TCHAR)0xBB, (TCHAR)0xBA, (TCHAR)0xE6, (TCHAR)0x96, (TCHAR)0x87, (TCHAR)0xE4, (TCHAR)0xBB, (TCHAR)0xB6, (TCHAR)0xE5, (TCHAR)0xA4, (TCHAR)0xB9, 0 };
+#endif
+
+#ifdef STORMLIB_MAC
+#define WORK_PATH_ROOT "/home/sam/StormLib/test"
 static const TCHAR szListFileDir[] = { '1', '9', '9', '5', ' ', '-', ' ', 'T', 'e', 's', 't', ' ', 'M', 'P', 'Q', 's', '\\', 'l', 'i', 's', 't', 'f', 'i', 'l', 'e', 's', '-', (TCHAR)0xe6, (TCHAR)0x96, (TCHAR)0xB0, (TCHAR)0xE5, (TCHAR)0xBB, (TCHAR)0xBA, (TCHAR)0xE6, (TCHAR)0x96, (TCHAR)0x87, (TCHAR)0xE4, (TCHAR)0xBB, (TCHAR)0xB6, (TCHAR)0xE5, (TCHAR)0xA4, (TCHAR)0xB9, 0 };
 #endif
 
-#ifdef PLATFORM_MAC
-#define WORK_PATH_ROOT "/Users/sam/StormLib/test"
+#ifdef STORMLIB_HAIKU
+#define WORK_PATH_ROOT "~/StormLib/test"
 static const TCHAR szListFileDir[] = { '1', '9', '9', '5', ' ', '-', ' ', 'T', 'e', 's', 't', ' ', 'M', 'P', 'Q', 's', '\\', 'l', 'i', 's', 't', 'f', 'i', 'l', 'e', 's', '-', (TCHAR)0xe6, (TCHAR)0x96, (TCHAR)0xB0, (TCHAR)0xE5, (TCHAR)0xBB, (TCHAR)0xBA, (TCHAR)0xE6, (TCHAR)0x96, (TCHAR)0x87, (TCHAR)0xE4, (TCHAR)0xBB, (TCHAR)0xB6, (TCHAR)0xE5, (TCHAR)0xA4, (TCHAR)0xB9, 0 };
 #endif
 
@@ -62,7 +82,7 @@ typedef int (*FIND_PAIR_CALLBACK)(LPCTSTR szFullPath1, LPCTSTR szFullPath2);
 //-----------------------------------------------------------------------------
 // Testing data
 
-static DWORD AddFlags[] = 
+static DWORD AddFlags[] =
 {
 //  Compression          Encryption             Fixed key           Single Unit            Sector CRC
     0                 |  0                   |  0                 | 0                    | 0,
@@ -92,7 +112,7 @@ static DWORD AddFlags[] =
     0xFFFFFFFF
 };
 
-static DWORD WaveCompressions[] = 
+static DWORD WaveCompressions[] =
 {
     MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_HUFFMANN,
     MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN,
@@ -160,7 +180,7 @@ static LPCTSTR PatchList_WoW_15050[] =
     NULL
 };
 
-static LPCTSTR PatchList_WoW_16965[] = 
+static LPCTSTR PatchList_WoW_16965[] =
 {
     _T("MPQ_2013_v4_locale-enGB.MPQ"),
     _T("wow-update-enGB-16016.MPQ"),
@@ -175,7 +195,7 @@ static LPCTSTR PatchList_WoW_16965[] =
     NULL
 };
 
-static LPCTSTR PatchList_SC2_32283[] = 
+static LPCTSTR PatchList_SC2_32283[] =
 {
     _T("MPQ_2013_v4_Base1.SC2Data"),
     _T("s2-update-base-23258.MPQ"),
@@ -187,7 +207,7 @@ static LPCTSTR PatchList_SC2_32283[] =
     NULL
 };
 
-static LPCTSTR PatchList_SC2_34644[] = 
+static LPCTSTR PatchList_SC2_34644[] =
 {
     _T("MPQ_2013_v4_Base1.SC2Data"),
     _T("s2-update-base-23258.MPQ"),
@@ -199,7 +219,7 @@ static LPCTSTR PatchList_SC2_34644[] =
     NULL
 };
 
-static LPCTSTR PatchList_SC2_34644_Maps[] = 
+static LPCTSTR PatchList_SC2_34644_Maps[] =
 {
     _T("MPQ_2013_v4_Base3.SC2Maps"),
     _T("s2-update-base-23258.MPQ"),
@@ -211,7 +231,7 @@ static LPCTSTR PatchList_SC2_34644_Maps[] =
     NULL
 };
 
-static LPCTSTR PatchList_SC2_32283_enGB[] = 
+static LPCTSTR PatchList_SC2_32283_enGB[] =
 {
     _T("MPQ_2013_v4_Mods#Core.SC2Mod#enGB.SC2Assets"),
     _T("s2-update-enGB-23258.MPQ"),
@@ -223,7 +243,7 @@ static LPCTSTR PatchList_SC2_32283_enGB[] =
     NULL
 };
 
-static LPCTSTR PatchList_SC2_36281_enGB[] = 
+static LPCTSTR PatchList_SC2_36281_enGB[] =
 {
     _T("MPQ_2013_v4_Mods#Liberty.SC2Mod#enGB.SC2Data"),
     _T("s2-update-enGB-23258.MPQ"),
@@ -236,14 +256,14 @@ static LPCTSTR PatchList_SC2_36281_enGB[] =
     NULL
 };
 
-static LPCTSTR PatchList_HS_3604_enGB[] = 
+static LPCTSTR PatchList_HS_3604_enGB[] =
 {
     _T("MPQ_2014_v4_base-Win.MPQ"),
     _T("hs-0-3604-Win-final.MPQ"),
     NULL
 };
 
-static LPCTSTR PatchList_HS_6898_enGB[] = 
+static LPCTSTR PatchList_HS_6898_enGB[] =
 {
     _T("MPQ_2014_v4_base-Win.MPQ"),
     _T("hs-0-5314-Win-final.MPQ"),
@@ -263,7 +283,7 @@ static LPCTSTR PatchList_HS_6898_enGB[] =
 // Local file functions
 
 // Definition of the path separator
-#ifdef PLATFORM_WINDOWS
+#ifdef STORMLIB_WINDOWS
 static LPCTSTR g_szPathSeparator = _T("\\");
 static const TCHAR PATH_SEPARATOR = _T('\\');       // Path separator for Windows platforms
 #else
@@ -272,14 +292,14 @@ static const TCHAR PATH_SEPARATOR = '/';            // Path separator for Non-Wi
 #endif
 
 // This must be the directory where our test MPQs are stored.
-// We also expect a subdirectory named 
+// We also expect a subdirectory named
 static TCHAR szMpqDirectory[MAX_PATH+1];
 size_t cchMpqDirectory = 0;
 
 template <typename XCHAR>
 static bool IsFullPath(const XCHAR * szFileName)
 {
-#ifdef PLATFORM_WINDOWS
+#ifdef STORMLIB_WINDOWS
     if(('A' <= szFileName[0] && szFileName[0] <= 'Z') || ('a' <= szFileName[0] && szFileName[0] <= 'z'))
     {
         return (szFileName[1] == ':' && szFileName[2] == PATH_SEPARATOR);
@@ -302,6 +322,8 @@ static bool IsMpqExtension(LPCTSTR szFileName)
             return true;
         if(!_tcsicmp(szExtension, _T(".w3x")))
             return true;
+        if(!_tcsicmp(szExtension, _T(".asi")))
+            return true;
         if(!_tcsicmp(szExtension, _T(".mpqe")))
             return true;
         if(!_tcsicmp(szExtension, _T(".part")))
@@ -312,12 +334,14 @@ static bool IsMpqExtension(LPCTSTR szFileName)
             return true;
         if(!_tcsicmp(szExtension, _T(".SC2Map")))
             return true;
+        if(!_tcsicmp(szExtension, _T(".SC2Mod")))
+            return true;
         if(!_tcsicmp(szExtension, _T(".0")))        // .MPQ.0
             return true;
 //      if(!_tcsicmp(szExtension, ".link"))
 //          return true;
     }
-    
+
     return false;
 }
 
@@ -462,62 +486,6 @@ static bool CopyStringAndVerifyConversion(
     return (_tcsicmp(szBufferT, szFoundFile) == 0) ? true : false;
 }
 
-static void CalculateRelativePath(LPCSTR szFullPath1, LPCSTR szFullPath2, char * szBuffer)
-{
-    LPCSTR szPathPart1 = szFullPath1;
-    LPCSTR szPathPart2 = szFullPath2;
-    LPCSTR szNextPart1;
-    LPCSTR szNextPart2;
-    int nEqualParts = 0;
-    int nStepsUp = 0;
-
-    // Parse both paths and find all path parts that are equal
-    for(;;)
-    {
-        // Find the next part of the first path
-        szNextPart1 = FindNextPathPart(szPathPart1, 1);
-        if(szNextPart1 == szPathPart1)
-            break;
-
-        szNextPart2 = FindNextPathPart(szPathPart2, 1);
-        if(szNextPart2 == szPathPart2)
-            break;
-
-        // Are these equal?
-        if((szNextPart2 - szPathPart2) != (szNextPart1 - szPathPart1))
-            break;
-        if(_strnicmp(szPathPart1, szPathPart2, (szNextPart1 - szPathPart1 - 1)))
-            break;
-
-        // Increment the number of path parts that are equal
-        szPathPart1 = szNextPart1;
-        szPathPart2 = szNextPart2;
-        nEqualParts++;
-    }
-
-    // If we found at least one equal part, we can create relative path
-    if(nEqualParts != 0)
-    {
-        // Calculate how many steps up we need to go
-        nStepsUp = GetPathSeparatorCount(szPathPart2);
-
-        // Append "../" nStepsUp-times
-        for(int i = 0; i < nStepsUp; i++)
-        {
-            *szBuffer++ = '.';
-            *szBuffer++ = '.';
-            *szBuffer++ = '/';
-        }
-
-        // Append the rest of the path. Also change DOS backslashes to slashes
-        CopyPathPart(szBuffer, szPathPart1);
-        return;
-    }
-
-    // Failed. Just copy the source path as it is
-    strcpy(szBuffer, szFullPath1);
-}
-
 static size_t ConvertSha1ToText(const unsigned char * sha1_digest, TCHAR * szSha1Text)
 {
     LPCSTR szTable = "0123456789abcdef";
@@ -698,7 +666,7 @@ static int CalculateFileSha1(TLogHelper * pLogger, LPCTSTR szFullPath, TCHAR * s
 
 static HANDLE InitDirectorySearch(LPCTSTR szDirectory)
 {
-#ifdef PLATFORM_WINDOWS
+#ifdef STORMLIB_WINDOWS
 
     WIN32_FIND_DATA wf;
     HANDLE hFind;
@@ -713,7 +681,7 @@ static HANDLE InitDirectorySearch(LPCTSTR szDirectory)
 
 #endif
 
-#ifdef PLATFORM_LINUX
+#if defined(STORMLIB_LINUX) || defined(STORMLIB_HAIKU)
 
     // Keep compilers happy
     return (HANDLE)opendir(szDirectory);
@@ -723,7 +691,7 @@ static HANDLE InitDirectorySearch(LPCTSTR szDirectory)
 
 static bool SearchDirectory(HANDLE hFind, TCHAR * szDirEntry, size_t cchDirEntry, bool & IsDirectory)
 {
-#ifdef PLATFORM_WINDOWS
+#ifdef STORMLIB_WINDOWS
 
     WIN32_FIND_DATA wf;
     TCHAR szDirEntryT[MAX_PATH];
@@ -748,7 +716,7 @@ static bool SearchDirectory(HANDLE hFind, TCHAR * szDirEntry, size_t cchDirEntry
 
 #endif
 
-#ifdef PLATFORM_LINUX
+#if defined(STORMLIB_LINUX) || defined(STORMLIB_HAIKU)
 
     struct dirent * directory_entry;
 
@@ -767,11 +735,11 @@ static bool SearchDirectory(HANDLE hFind, TCHAR * szDirEntry, size_t cchDirEntry
 
 static void FreeDirectorySearch(HANDLE hFind)
 {
-#ifdef PLATFORM_WINDOWS
+#ifdef STORMLIB_WINDOWS
     FindClose(hFind);
 #endif
 
-#ifdef PLATFORM_LINUX
+#if defined(STORMLIB_LINUX) || defined(STORMLIB_HAIKU)
     closedir((DIR *)hFind);
 #endif
 }
@@ -835,93 +803,28 @@ static int FindFiles(FIND_FILE_CALLBACK pfnFindFile, LPCTSTR szSubDirectory)
     return FindFilesInternal(pfnFindFile, szWorkBuff);
 }
 
-static int FindFilePairsInternal(
-    FIND_PAIR_CALLBACK pfnFilePair, 
-    TCHAR * szSource,
-    TCHAR * szTarget)
-{
-    TCHAR * szPlainName1;
-    TCHAR * szPlainName2;
-    int nError = ERROR_SUCCESS;
-
-    // Setup the search masks
-    _tcscat(szSource, _T("\\*"));
-    szPlainName1 = _tcsrchr(szSource, '*');
-    _tcscat(szTarget, _T("\\*"));
-    szPlainName2 = _tcsrchr(szTarget, '*');
-
-    // If both paths are OK, perform the search
-    if(szPlainName1 != NULL && szPlainName2 != NULL)
-    {
-#ifdef PLATFORM_WINDOWS
-        WIN32_FIND_DATA wf;
-        HANDLE hFind;
-
-        // Search the second directory
-        hFind = FindFirstFile(szTarget, &wf);
-        if(hFind != INVALID_HANDLE_VALUE)
-        {
-            // Skip the first entry, since it's always "." or ".."
-            while(FindNextFile(hFind, &wf) && nError == ERROR_SUCCESS)
-            {
-                // Found a directory?
-                if(wf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-                {
-                    if(wf.cFileName[0] != '.')
-                    {
-                        _tcscpy(szPlainName1, wf.cFileName);
-                        _tcscpy(szPlainName2, wf.cFileName);
-                        nError = FindFilePairsInternal(pfnFilePair, szSource, szTarget);
-                    }
-                }
-                else
-                {
-                    if(pfnFilePair != NULL)
-                    {
-                        _tcscpy(szPlainName1, wf.cFileName);
-                        _tcscpy(szPlainName2, wf.cFileName);
-                        nError = pfnFilePair(szSource, szTarget);
-                    }
-                }
-            }
-
-            FindClose(hFind);
-        }
-#endif
-    }
-
-    return nError;
-}
-
-static int FindFilePairs(FIND_PAIR_CALLBACK pfnFindPair, LPCTSTR szSourceSubDir, LPCTSTR szTargetSubDir)
-{
-    TCHAR szSource[MAX_PATH];
-    TCHAR szTarget[MAX_PATH];
-
-    // Create the source search mask
-    CreateFullPathName(szSource, _countof(szSource), szSourceSubDir, NULL);
-    CreateFullPathName(szTarget, _countof(szTarget), szTargetSubDir, NULL);
-    return FindFilePairsInternal(pfnFindPair, szSource, szTarget);
-}
-
 static int InitializeMpqDirectory(TCHAR * argv[], int argc)
 {
     TLogHelper Logger("InitWorkDir");
     TFileStream * pStream;
     TCHAR szFullPath[MAX_PATH];
-    LPCTSTR szWhereFrom = NULL;
-    LPCTSTR szDirName;
+    LPCTSTR szWhereFrom = _T("default");
+    LPCTSTR szDirName = WORK_PATH_ROOT;
 
-    // Retrieve the name of the MPQ directory
+    // Retrieve the first argument
     if(argc > 1 && argv[1] != NULL)
     {
-        szWhereFrom = _T("command line");
-        szDirName = argv[1];
-    }
-    else
-    {
-        szWhereFrom = _T("default");
-        szDirName = WORK_PATH_ROOT;
+        // Check if it's a directory
+        pStream = FileStream_OpenFile(argv[1], STREAM_FLAG_READ_ONLY);
+        if(pStream == NULL)
+        {
+            szWhereFrom = _T("command line");
+            szDirName = argv[1];
+        }
+        else
+        {
+            FileStream_Close(pStream);
+        }
     }
 
     // Copy the name of the MPQ directory.
@@ -954,36 +857,36 @@ static int InitializeMpqDirectory(TCHAR * argv[], int argc)
 
     // Close the stream
     FileStream_Close(pStream);
-    return ERROR_SUCCESS;                                
+    return ERROR_SUCCESS;
 }
 
-static int GetFilePatchCount(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileName)
+static DWORD GetFilePatchCount(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileName)
 {
     TCHAR * szPatchName;
     HANDLE hFile;
     TCHAR szPatchChain[0x400];
+    DWORD dwErrCode = ERROR_SUCCESS;
     int nPatchCount = 0;
-    int nError = ERROR_SUCCESS;
 
     // Open the MPQ file
     if(SFileOpenFileEx(hMpq, szFileName, 0, &hFile))
     {
         // Notify the user
-        pLogger->PrintProgress(_T("Verifying patch chain for %s ..."), GetShortPlainName(szFileName));
+        pLogger->PrintProgress("Verifying patch chain for %s ...", GetShortPlainName(szFileName));
 
         // Query the patch chain
         if(!SFileGetFileInfo(hFile, SFileInfoPatchChain, szPatchChain, sizeof(szPatchChain), NULL))
-            nError = pLogger->PrintError("Failed to retrieve the patch chain on %s", szFileName);
+            dwErrCode = pLogger->PrintError("Failed to retrieve the patch chain on %s", szFileName);
 
         // Is there anything at all in the patch chain?
-        if(nError == ERROR_SUCCESS && szPatchChain[0] == 0)
+        if(dwErrCode == ERROR_SUCCESS && szPatchChain[0] == 0)
         {
             pLogger->PrintError("The patch chain for %s is empty", szFileName);
-            nError = ERROR_FILE_CORRUPT;
+            dwErrCode = ERROR_FILE_CORRUPT;
         }
 
         // Now calculate the number of patches
-        if(nError == ERROR_SUCCESS)
+        if(dwErrCode == ERROR_SUCCESS)
         {
             // Get the pointer to the patch
             szPatchName = szPatchChain;
@@ -1011,7 +914,7 @@ static int GetFilePatchCount(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileNam
     return nPatchCount;
 }
 
-static int VerifyFilePatchCount(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileName, int nExpectedPatchCount)
+static DWORD VerifyFilePatchCount(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileName, int nExpectedPatchCount)
 {
     int nPatchCount = 0;
 
@@ -1022,21 +925,21 @@ static int VerifyFilePatchCount(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFile
     // Check if there are any patches at all
     if(nExpectedPatchCount != 0 && nPatchCount == 0)
     {
-        pLogger->PrintMessage(_T("There are no patches for %s"), szFileName);
+        pLogger->PrintMessage("There are no patches for %s", szFileName);
         return ERROR_FILE_CORRUPT;
     }
 
     // Check if the number of patches fits
     if(nPatchCount != nExpectedPatchCount)
     {
-        pLogger->PrintMessage(_T("Unexpected number of patches for %s"), szFileName);
+        pLogger->PrintMessage("Unexpected number of patches for %s", szFileName);
         return ERROR_FILE_CORRUPT;
     }
 
     return ERROR_SUCCESS;
 }
 
-static int CreateEmptyFile(TLogHelper * pLogger, LPCTSTR szPlainName, ULONGLONG FileSize, TCHAR * szBuffer)
+static DWORD CreateEmptyFile(TLogHelper * pLogger, LPCTSTR szPlainName, ULONGLONG FileSize, TCHAR * szBuffer)
 {
     TFileStream * pStream;
     TCHAR szFullPath[MAX_PATH];
@@ -1060,13 +963,13 @@ static int CreateEmptyFile(TLogHelper * pLogger, LPCTSTR szPlainName, ULONGLONG
     return ERROR_SUCCESS;
 }
 
-static int VerifyFilePosition(
+static DWORD VerifyFilePosition(
     TLogHelper * pLogger,
     TFileStream * pStream,
     ULONGLONG ExpectedPosition)
 {
     ULONGLONG ByteOffset = 0;
-    int nError = ERROR_SUCCESS;
+    DWORD dwErrCode = ERROR_SUCCESS;
 
     // Retrieve the file position
     if(FileStream_GetPos(pStream, &ByteOffset))
@@ -1074,15 +977,15 @@ static int VerifyFilePosition(
         if(ByteOffset != ExpectedPosition)
         {
             pLogger->PrintMessage(_T("The file position is different than expected (expected: ") I64u_t _T(", current: ") I64u_t, ExpectedPosition, ByteOffset);
-            nError = ERROR_FILE_CORRUPT;
+            dwErrCode = ERROR_FILE_CORRUPT;
         }
     }
     else
     {
-        nError = pLogger->PrintError(_T("Failed to retrieve the file offset"));
+        dwErrCode = pLogger->PrintError(_T("Failed to retrieve the file offset"));
     }
 
-    return nError;
+    return dwErrCode;
 }
 
 static int VerifyFileMpqHeader(TLogHelper * pLogger, TFileStream * pStream, ULONGLONG * pByteOffset)
@@ -1093,7 +996,7 @@ static int VerifyFileMpqHeader(TLogHelper * pLogger, TFileStream * pStream, ULON
     memset(&Header, 0xFE, sizeof(TMPQHeader));
     if(FileStream_Read(pStream, pByteOffset, &Header, sizeof(TMPQHeader)))
     {
-        if(Header.dwID != ID_MPQ)
+        if(Header.dwID != g_dwMpqSignature)
         {
             pLogger->PrintMessage(_T("Read error - the data is not a MPQ header"));
             nError = ERROR_FILE_CORRUPT;
@@ -1298,7 +1201,7 @@ static int CreateFileCopy(
     // Create the full file name of the target file, including prefix
     if(szBuffer && cchBuffer)
         CreateFullPathName(szBuffer, cchBuffer, NULL, szFileCopy);
-    
+
     // Report error, if any
     if(nError != ERROR_SUCCESS)
         pLogger->PrintError("Failed to create copy of MPQ");
@@ -1324,7 +1227,7 @@ static int CreateMasterAndMirrorPaths(
     // Copy the mirrored file from the source to the work directory
     if(bCopyMirrorFile)
         nError = CreateFileCopy(pLogger, szMirrorName, szMirrorName);
-    
+
     // Create the mirror*master path
     if(nError == ERROR_SUCCESS)
         _stprintf(szMirrorPath, _T("%s*%s"), szCopyPath, szMasterPath);
@@ -1386,17 +1289,18 @@ static void WINAPI CompactCallback(void * pvUserData, DWORD dwWork, ULONGLONG By
 //-----------------------------------------------------------------------------
 // MPQ file utilities
 
-#define TEST_FLAG_LOAD_FILES          0x00000001    // Test function should load all files in the MPQ
-#define TEST_FLAG_HASH_FILES          0x00000002    // Test function should load all files in the MPQ
-#define TEST_FLAG_PLAY_WAVES          0x00000004    // Play extracted WAVE files
-#define TEST_FLAG_MOST_PATCHED        0x00000008    // Find the most patched file
+#define SEARCH_FLAG_LOAD_FILES      0x00000001      // Test function should load all files in the MPQ
+#define SEARCH_FLAG_HASH_FILES      0x00000002      // Test function should load all files in the MPQ
+#define SEARCH_FLAG_PLAY_WAVES      0x00000004      // Play extracted WAVE files
+#define SEARCH_FLAG_MOST_PATCHED    0x00000008      // Find the most patched file
+#define SEARCH_FLAG_IGNORE_ERRORS   0x00000010      // Ignore files that failed to open
 
 struct TFileData
 {
     DWORD dwBlockIndex;
     DWORD dwFileSize;
     DWORD dwFlags;
-    DWORD dwReserved;                               // Alignment
+    DWORD dwCrc32;
     BYTE FileData[1];
 };
 
@@ -1466,7 +1370,7 @@ static TFileData * LoadLocalFile(TLogHelper * pLogger, LPCTSTR szFileName, bool
 }
 
 static int CompareTwoLocalFilesRR(
-    TLogHelper * pLogger, 
+    TLogHelper * pLogger,
     TFileStream * pStream1,                         // Master file
     TFileStream * pStream2,                         // Mirror file
     int nIterations)                                // Number of iterations
@@ -1515,7 +1419,7 @@ static int CompareTwoLocalFilesRR(
 
                 memset(pbBuffer1, 0xEE, cbBuffer);
                 memset(pbBuffer2, 0xAA, cbBuffer);
-                
+
                 FileStream_Read(pStream1, &ByteOffset, pbBuffer1, BytesToRead);
                 FileStream_Read(pStream2, &ByteOffset, pbBuffer2, BytesToRead);
 
@@ -1541,90 +1445,103 @@ static int CompareTwoLocalFilesRR(
     return nError;
 }
 
-static TFileData * LoadMpqFile(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileName, LCID lcLocale = 0)
+static TFileData * LoadMpqFile(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileName, LCID lcLocale = 0, bool bIgnoreOpenErrors = false)
 {
     TFileData * pFileData = NULL;
     HANDLE hFile;
     DWORD dwFileSizeHi = 0xCCCCCCCC;
     DWORD dwFileSizeLo = 0;
     DWORD dwBytesRead;
-    int nError = ERROR_SUCCESS;
+    DWORD dwCrc32 = 0;
+    DWORD dwErrCode = ERROR_SUCCESS;
 
     // Notify the user that we are loading a file from MPQ
     pLogger->PrintProgress("Loading file %s ...", GetShortPlainName(szFileName));
 
 #if defined(_MSC_VER) && defined(_DEBUG)
-//  if(!_stricmp(szFileName, "manifest-cards.csv"))
-//      DebugBreak();
+//  if(!_stricmp(szFileName, "File00000733.wav"))
+//      __debugbreak();
 #endif
 
     // Make sure that we open the proper locale file
     SFileSetLocale(lcLocale);
 
     // Open the file from MPQ
-    if(!SFileOpenFileEx(hMpq, szFileName, 0, &hFile))
-        nError = pLogger->PrintError("Open failed: %s", szFileName);
-
-    // Get the size of the file
-    if(nError == ERROR_SUCCESS)
+    if(SFileOpenFileEx(hMpq, szFileName, 0, &hFile))
     {
-        dwFileSizeLo = SFileGetFileSize(hFile, &dwFileSizeHi);
-        if(dwFileSizeLo == SFILE_INVALID_SIZE || dwFileSizeHi != 0)
-            nError = pLogger->PrintError("Failed to query the file size");
-    }
+        // Get the CRC32 of the file
+        SFileGetFileInfo(hFile, SFileInfoCRC32, &dwCrc32, sizeof(dwCrc32), NULL);
 
-    // Spazzler protector: Creates fake files with size of 0x7FFFE7CA
-    if(nError == ERROR_SUCCESS)
-    {
-        if(dwFileSizeLo > 0x1FFFFFFF)
-            nError = ERROR_FILE_CORRUPT;
-    }
+        // Get the size of the file
+        if(dwErrCode == ERROR_SUCCESS)
+        {
+            dwFileSizeLo = SFileGetFileSize(hFile, &dwFileSizeHi);
+            if(dwFileSizeLo == SFILE_INVALID_SIZE || dwFileSizeHi != 0)
+                dwErrCode = pLogger->PrintError("Failed to query the file size");
+        }
 
-    // Allocate buffer for the file content
-    if(nError == ERROR_SUCCESS)
-    {
-        pFileData = (TFileData *)STORM_ALLOC(BYTE, sizeof(TFileData) + dwFileSizeLo);
-        if(pFileData == NULL)
+        // Spazzler protector: Creates fake files with size of 0x7FFFE7CA
+        if(dwErrCode == ERROR_SUCCESS)
         {
-            pLogger->PrintError("Failed to allocate buffer for the file content");
-            nError = ERROR_NOT_ENOUGH_MEMORY;
+            if(dwFileSizeLo > 0x1FFFFFFF)
+                dwErrCode = ERROR_FILE_CORRUPT;
         }
-    }
 
-    // get the file index of the MPQ file
-    if(nError == ERROR_SUCCESS)
-    {
-        // Store the file size
-        memset(pFileData, 0, sizeof(TFileData) + dwFileSizeLo);
-        pFileData->dwFileSize = dwFileSizeLo;
+        // Allocate buffer for the file content
+        if(dwErrCode == ERROR_SUCCESS)
+        {
+            pFileData = (TFileData *)STORM_ALLOC(BYTE, sizeof(TFileData) + dwFileSizeLo);
+            if(pFileData == NULL)
+            {
+                pLogger->PrintError("Failed to allocate buffer for the file content");
+                dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
+            }
+        }
 
-        // Retrieve the block index and file flags
-        if(!SFileGetFileInfo(hFile, SFileInfoFileIndex, &pFileData->dwBlockIndex, sizeof(DWORD), NULL))
-            nError = pLogger->PrintError("Failed retrieve the file index of %s", szFileName);
-        if(!SFileGetFileInfo(hFile, SFileInfoFlags, &pFileData->dwFlags, sizeof(DWORD), NULL))
-            nError = pLogger->PrintError("Failed retrieve the file flags of %s", szFileName);
-    }
+        // get the file index of the MPQ file
+        if(dwErrCode == ERROR_SUCCESS)
+        {
+            // Store the file size
+            memset(pFileData, 0, sizeof(TFileData) + dwFileSizeLo);
+            pFileData->dwFileSize = dwFileSizeLo;
+            pFileData->dwCrc32 = dwCrc32;
+
+            // Retrieve the block index and file flags
+            if(!SFileGetFileInfo(hFile, SFileInfoFileIndex, &pFileData->dwBlockIndex, sizeof(DWORD), NULL))
+                dwErrCode = pLogger->PrintError("Failed retrieve the file index of %s", szFileName);
+            if(!SFileGetFileInfo(hFile, SFileInfoFlags, &pFileData->dwFlags, sizeof(DWORD), NULL))
+                dwErrCode = pLogger->PrintError("Failed retrieve the file flags of %s", szFileName);
+        }
 
-    // Load the entire file
-    if(nError == ERROR_SUCCESS)
-    {
-        // Read the file data
-        SFileReadFile(hFile, pFileData->FileData, dwFileSizeLo, &dwBytesRead, NULL);
-        if(dwBytesRead != dwFileSizeLo)
-            nError = pLogger->PrintError("Read failed: %s", szFileName);
-    }
+        // Load the entire file
+        if(dwErrCode == ERROR_SUCCESS)
+        {
+            // Read the file data
+            SFileReadFile(hFile, pFileData->FileData, dwFileSizeLo, &dwBytesRead, NULL);
+            if(dwBytesRead != dwFileSizeLo)
+                dwErrCode = ERROR_FILE_CORRUPT;
+        }
 
-    // If failed, free the buffer
-    if(nError != ERROR_SUCCESS)
+        // If failed, free the buffer
+        if(dwErrCode != ERROR_SUCCESS)
+        {
+            SetLastError(dwErrCode);
+            if(pFileData != NULL)
+                STORM_FREE(pFileData);
+            pFileData = NULL;
+        }
+
+        SFileCloseFile(hFile);
+    }
+    else
     {
-        STORM_FREE(pFileData);
-        SetLastError(nError);
-        pFileData = NULL;
+        if(bIgnoreOpenErrors == false)
+        {
+            dwErrCode = pLogger->PrintError("Open failed: %s", szFileName);
+        }
     }
 
-    // Close the file and return what we got
-    if(hFile != NULL)
-        SFileCloseFile(hFile);
+    // Return what we got
     return pFileData;
 }
 
@@ -1653,10 +1570,10 @@ static bool CompareTwoFiles(TLogHelper * pLogger, TFileData * pFileData1, TFileD
     return true;
 }
 
-static int SearchArchive(
+static DWORD SearchArchive(
     TLogHelper * pLogger,
     HANDLE hMpq,
-    DWORD dwTestFlags = 0,
+    DWORD dwSearchFlags = 0,
     DWORD * pdwFileCount = NULL,
     LPBYTE pbFileHash = NULL)
 {
@@ -1667,10 +1584,11 @@ static int SearchArchive(
     hash_state md5state;
     TCHAR szListFile[MAX_PATH] = _T("");
     char szMostPatched[MAX_PATH] = "";
+    DWORD dwErrCode = ERROR_SUCCESS;
+    bool bIgnoreOpenErrors = (dwSearchFlags & SEARCH_FLAG_IGNORE_ERRORS) ? true : false;
     bool bFound = true;
     int nMaxPatchCount = 0;
     int nPatchCount = 0;
-    int nError = ERROR_SUCCESS;
 
     // Construct the full name of the listfile
     CreateFullPathName(szListFile, _countof(szListFile), szListFileDir, _T("ListFile_Blizzard.txt"));
@@ -1679,16 +1597,17 @@ static int SearchArchive(
     md5_init(&md5state);
 
     // Initiate the MPQ search
-    pLogger->PrintProgress("Searching the archive ...");
+    pLogger->PrintProgress("Searching the archive (initializing) ...");
     hFind = SFileFindFirstFile(hMpq, "*", &sf, szListFile);
     if(hFind == NULL)
     {
-        nError = GetLastError();
-        nError = (nError == ERROR_NO_MORE_FILES) ? ERROR_SUCCESS : nError;
-        return nError;
+        dwErrCode = GetLastError();
+        dwErrCode = (dwErrCode == ERROR_NO_MORE_FILES) ? ERROR_SUCCESS : dwErrCode;
+        return dwErrCode;
     }
 
     // Perform the search
+    pLogger->PrintProgress("Searching the archive ...");
     while(bFound == true)
     {
         // Increment number of files
@@ -1697,7 +1616,7 @@ static int SearchArchive(
 //      if(!_stricmp(sf.cFileName, "war3map.j"))
 //          DebugBreak();
 
-        if(dwTestFlags & TEST_FLAG_MOST_PATCHED)
+        if(dwSearchFlags & SEARCH_FLAG_MOST_PATCHED)
         {
             // Load the patch count
             nPatchCount = GetFilePatchCount(pLogger, hMpq, sf.cFileName);
@@ -1711,18 +1630,18 @@ static int SearchArchive(
         }
 
         // Load the file to memory, if required
-        if(dwTestFlags & TEST_FLAG_LOAD_FILES)
+        if(dwSearchFlags & SEARCH_FLAG_LOAD_FILES)
         {
             // Load the entire file to the MPQ
-            pFileData = LoadMpqFile(pLogger, hMpq, sf.cFileName, sf.lcLocale);
+            pFileData = LoadMpqFile(pLogger, hMpq, sf.cFileName, sf.lcLocale, bIgnoreOpenErrors);
             if(pFileData != NULL)
             {
                 // Hash the file data, if needed
-                if((dwTestFlags & TEST_FLAG_HASH_FILES) && !IsInternalMpqFileName(sf.cFileName))
+                if((dwSearchFlags & SEARCH_FLAG_HASH_FILES) && !IsInternalMpqFileName(sf.cFileName))
                     md5_process(&md5state, pFileData->FileData, pFileData->dwFileSize);
 
                 // Play sound files, if required
-                if((dwTestFlags & TEST_FLAG_PLAY_WAVES) && strstr(sf.cFileName, ".wav") != NULL)
+                if((dwSearchFlags & SEARCH_FLAG_PLAY_WAVES) && strstr(sf.cFileName, ".wav") != NULL)
                 {
 #ifdef _MSC_VER
                     pLogger->PrintProgress("Playing sound %s", sf.cFileName);
@@ -1743,10 +1662,10 @@ static int SearchArchive(
         pdwFileCount[0] = dwFileCount;
 
     // Give the hash, if required
-    if(pbFileHash != NULL && (dwTestFlags & TEST_FLAG_HASH_FILES))
+    if(pbFileHash != NULL && (dwSearchFlags & SEARCH_FLAG_HASH_FILES))
         md5_done(&md5state, pbFileHash);
 
-    return nError;
+    return dwErrCode;
 }
 
 static int CreateNewArchive(TLogHelper * pLogger, LPCTSTR szPlainName, DWORD dwCreateFlags, DWORD dwMaxFileCount, HANDLE * phMpq)
@@ -1920,7 +1839,7 @@ static int OpenExistingArchiveWithCopy(TLogHelper * pLogger, LPCTSTR szFileName,
         if(nError != ERROR_SUCCESS)
             return nError;
     }
-    
+
     // If only source name entered, open it for read-only access
     else if(szFileName != NULL && szCopyName == NULL)
     {
@@ -2130,7 +2049,7 @@ static int TestSetFilePointer(
         if(NewPos != ExpectedPos)
             nError = ERROR_HANDLE_EOF;
     }
-    
+
     return nError;
 }
 
@@ -2171,35 +2090,42 @@ static void TestGetFileInfo(
     DWORD cbFileInfo,
     DWORD * pcbLengthNeeded,
     bool bExpectedResult,
-    int nExpectedError)
+    DWORD dwExpectedErrCode)
 {
+    DWORD dwErrCode = ERROR_SUCCESS;
     bool bResult;
-    int nError = ERROR_SUCCESS;
 
     // Call the get file info
     bResult = SFileGetFileInfo(hMpqOrFile, InfoClass, pvFileInfo, cbFileInfo, pcbLengthNeeded);
     if(!bResult)
-        nError = GetLastError();
+        dwErrCode = GetLastError();
 
     if(bResult != bExpectedResult)
         pLogger->PrintMessage("Different result of SFileGetFileInfo.");
-    if(nError != nExpectedError)
-        pLogger->PrintMessage("Different error from SFileGetFileInfo (expected %u, returned %u)", nExpectedError, nError);
+    if(dwErrCode != dwExpectedErrCode)
+        pLogger->PrintMessage("Different error from SFileGetFileInfo (expected %u, returned %u)", dwExpectedErrCode, dwErrCode);
 }
 
 // StormLib is able to open local files (as well as the original Storm.dll)
 // I want to keep this for occasional use
-static int TestOpenLocalFile(LPCTSTR szPlainName)
+static DWORD TestOnLocalListFile(LPCTSTR szPlainName)
 {
-    TLogHelper Logger("OpenLocalFile", szPlainName);
+    TLogHelper Logger("LocalListFile", szPlainName);
+    SFILE_FIND_DATA sf;
     HANDLE hFile;
+    HANDLE hFind;
     DWORD dwFileSizeHi = 0;
     DWORD dwFileSizeLo = 0;
+    TCHAR szFullPath[MAX_PATH];
     char szFileName1[MAX_PATH];
     char szFileName2[MAX_PATH];
-    char szFileLine[0x40];
-    
+    char szFileLine[0x40] = {0};
+    int nFileCount = 0;
+
+    // Get the full name of the local file
     CreateFullPathName(szFileName1, _countof(szFileName1), szMpqSubDir, szPlainName);
+
+    // Test opening the local file
     if(SFileOpenFileEx(NULL, szFileName1, SFILE_OPEN_LOCAL_FILE, &hFile))
     {
         // Retrieve the file name. It must match the name under which the file was open
@@ -2209,30 +2135,23 @@ static int TestOpenLocalFile(LPCTSTR szPlainName)
 
         // Retrieve the file size
         dwFileSizeLo = SFileGetFileSize(hFile, &dwFileSizeHi);
-        if(dwFileSizeHi != 0 || dwFileSizeLo != 3904784)
+        if(dwFileSizeHi != 0 || dwFileSizeLo != 0x04385a4e)
             Logger.PrintMessage("Local file size mismatch");
 
         // Read the first line
-        memset(szFileLine, 0, sizeof(szFileLine));
         SFileReadFile(hFile, szFileLine, 18, NULL, NULL);
-        if(strcmp(szFileLine, "(1)Enslavers01.scm"))
+        if(strcmp(szFileLine, "accountbilling.url"))
             Logger.PrintMessage("Content of the listfile does not match");
 
         SFileCloseFile(hFile);
     }
+    else
+        return Logger.PrintError("Failed to open local listfile");
 
-    return ERROR_SUCCESS;
-}
+    // We need unicode listfile name
+    StringCopy(szFullPath, _countof(szFullPath), szFileName1);
 
-static int TestSearchListFile(LPCTSTR szPlainName)
-{
-    SFILE_FIND_DATA sf;
-    TLogHelper Logger("SearchListFile", szPlainName);
-    TCHAR szFullPath[MAX_PATH];
-    HANDLE hFind;
-    int nFileCount = 0;
-    
-    CreateFullPathName(szFullPath, _countof(szFullPath), szMpqSubDir, szPlainName);
+    // Start searching in the listfile
     hFind = SListFileFindFirstFile(NULL, szFullPath, "*", &sf);
     if(hFind != NULL)
     {
@@ -2245,6 +2164,9 @@ static int TestSearchListFile(LPCTSTR szPlainName)
 
         SListFileFindClose(hFind);
     }
+    else
+        return Logger.PrintError("Failed to search local listfile");
+
     return ERROR_SUCCESS;
 }
 
@@ -2267,16 +2189,16 @@ static int TestReadFile_MasterMirror(LPCTSTR szMirrorName, LPCTSTR szMasterName,
     TFileStream * pStream1;                     // Master file
     TFileStream * pStream2;                     // Mirror file
     TLogHelper Logger("OpenMirrorFile", szMirrorName);
-    TCHAR szMirrorPath[MAX_PATH + MAX_PATH];     
+    TCHAR szMirrorPath[MAX_PATH + MAX_PATH];
     TCHAR szMasterPath[MAX_PATH];
-    DWORD dwProvider = 0;    
+    DWORD dwProvider = 0;
     int nIterations = 0x10000;
     int nError;
 
     // Retrieve the provider
-    FileStream_Prefix(szMasterName, &dwProvider); 
+    FileStream_Prefix(szMasterName, &dwProvider);
 
-#ifndef PLATFORM_WINDOWS
+#ifndef STORMLIB_WINDOWS
     if((dwProvider & BASE_PROVIDER_MASK) == BASE_PROVIDER_HTTP)
         return ERROR_SUCCESS;
 #endif
@@ -2307,31 +2229,6 @@ static int TestReadFile_MasterMirror(LPCTSTR szMirrorName, LPCTSTR szMasterName,
     return nError;
 }
 
-// Test of the TFileStream object
-static int TestSparseCompression()
-{
-    BYTE InpBuffer[0x1000];
-    BYTE Compressed[0x1000];
-    BYTE Decompressed[0x1000];
-    int cbCompressed = sizeof(Compressed);
-    int cbDecompressed = sizeof(Compressed);
-
-    // Prepare compressed buffer
-    memset(InpBuffer, 0, sizeof(InpBuffer));
-
-    // Compress and decompress
-    CompressSparse(Compressed, &cbCompressed, InpBuffer, sizeof(InpBuffer));
-    DecompressSparse(Decompressed, &cbDecompressed, Compressed, cbCompressed);
-
-    // Check the result of decompression
-    if(cbDecompressed != sizeof(InpBuffer))
-        return ERROR_FILE_CORRUPT;
-    if(memcmp(Decompressed, InpBuffer, sizeof(InpBuffer)))
-        return ERROR_FILE_CORRUPT;
-    
-    return ERROR_SUCCESS;
-}
-
 // Test of the TFileStream object
 static int TestFileStreamOperations(LPCTSTR szPlainName, DWORD dwStreamFlags)
 {
@@ -2349,7 +2246,7 @@ static int TestFileStreamOperations(LPCTSTR szPlainName, DWORD dwStreamFlags)
         CreateFullPathName(szFullPath, _countof(szFullPath), szMpqSubDir, szPlainName);
     else
         nError = CreateFileCopy(&Logger, szPlainName, szPlainName, szFullPath, _countof(szFullPath));
-    
+
     // Open the file stream
     if(nError == ERROR_SUCCESS)
     {
@@ -2388,7 +2285,7 @@ static int TestFileStreamOperations(LPCTSTR szPlainName, DWORD dwStreamFlags)
     // Read the MPQ header from the current file offset.
     if(nError == ERROR_SUCCESS)
         nError = VerifyFileMpqHeader(&Logger, pStream, NULL);
-    
+
     // After successful open, the stream position must sizeof(TMPQHeader)
     if(nError == ERROR_SUCCESS)
         nError = VerifyFilePosition(&Logger, pStream, sizeof(TMPQHeader));
@@ -2455,277 +2352,205 @@ static int TestFileStreamOperations(LPCTSTR szPlainName, DWORD dwStreamFlags)
     return nError;
 }
 
-static int TestOpenFile_OpenById(LPCTSTR szPlainName)
+static DWORD TestArchive_LoadFiles(TLogHelper * pLogger, HANDLE hMpq, bool bIgnoreOpenErrors, ...)
 {
-    TLogHelper Logger("OpenFileById", szPlainName);
-    TFileData * pFileData1 = NULL;
-    TFileData * pFileData2 = NULL;
-    HANDLE hMpq;
-    int nError;
-
-    // Copy the archive so we won't fuck up the original one
-    nError = OpenExistingArchiveWithCopy(&Logger, szPlainName, NULL, &hMpq);
-
-    // Now try to open a file without knowing the file name
-    if(nError == ERROR_SUCCESS)
-    {
-        // File00000023.xxx = music\dintro.wav
-        pFileData1 = LoadMpqFile(&Logger, hMpq, "File00000023.xxx");
-        if(pFileData1 == NULL)
-            nError = Logger.PrintError("Failed to load the file %s", "File00000023.xxx");
-    }
-
-    // Now try to open the file again with its original name
-    if(nError == ERROR_SUCCESS)
-    {
-        // File00000023.xxx = music\dintro.wav
-        pFileData2 = LoadMpqFile(&Logger, hMpq, "music\\dintro.wav");
-        if(pFileData2 == NULL)
-            nError = Logger.PrintError("Failed to load the file %s", "music\\dintro.wav");
-    }
+    TFileData * pFileData;
+    const char * szFileName;
+    va_list argList;
+    DWORD dwErrCode = ERROR_SUCCESS;
 
-    // Now compare both files
-    if(nError == ERROR_SUCCESS)
+    va_start(argList, bIgnoreOpenErrors);
+    while((szFileName = va_arg(argList, const char *)) != NULL)
     {
-        if(!CompareTwoFiles(&Logger, pFileData1, pFileData1))
-            nError = Logger.PrintError("The file has different size/content when open without name");
+        if(SFileHasFile(hMpq, szFileName))
+        {
+            pFileData = LoadMpqFile(pLogger, hMpq, szFileName);
+            if(pFileData == NULL && bIgnoreOpenErrors == false)
+            {
+                pLogger->PrintError("Error loading the file %s", szFileName);
+                dwErrCode = ERROR_FILE_CORRUPT;
+                break;
+            }
+            else
+            {
+                STORM_FREE(pFileData);
+                pFileData = NULL;
+            }
+        }
     }
+    va_end(argList);
 
-    // Close the archive
-    if(pFileData2 != NULL)
-        STORM_FREE(pFileData2);
-    if(pFileData1 != NULL)
-        STORM_FREE(pFileData1);
-    if(hMpq != NULL)
-        SFileCloseArchive(hMpq);
-    return nError;
+    return dwErrCode;
 }
 
-static int TestOpenFile_OpenByName(LPCTSTR szPlainName, LPCSTR szFileName)
+static DWORD TestArchive_SetPos(HANDLE hMpq, const char * szFileName)
 {
-    TLogHelper Logger("OpenFileById", szPlainName);
-    TFileData * pFileData = NULL;
-    HANDLE hFile;
-    HANDLE hMpq;
-    DWORD dwCrc32_1 = 0;
-    DWORD dwCrc32_2 = 0;
-    int nError;
-
-    // Copy the archive so we won't fuck up the original one
-    nError = OpenExistingArchiveWithCopy(&Logger, szPlainName, NULL, &hMpq);
+    HANDLE hFile = NULL;
+    DWORD dwErrCode = ERROR_SUCCESS;
 
-    // Now try to open the given file
-    if(nError == ERROR_SUCCESS)
+    if(SFileOpenFileEx(hMpq, szFileName, 0, &hFile))
     {
-        // Retrieve the CRC32
-        if(SFileOpenFileEx(hMpq, szFileName, 0, &hFile))
-        {
-            SFileGetFileInfo(hFile, SFileInfoCRC32, &dwCrc32_1, sizeof(dwCrc32_1), NULL);
-            SFileCloseFile(hFile);
-        }
+        // First, use the SFileSetFilePointer WITHOUT the high-dword position
+        dwErrCode = TestSetFilePointers(hFile, false);
 
-        // Load the entire file
-        pFileData = LoadMpqFile(&Logger, hMpq, szFileName);
-        if(pFileData != NULL)
-        {
-            // Compare the CRC32, if available
-            dwCrc32_2 = crc32(0, (Bytef *)pFileData->FileData, (uInt)pFileData->dwFileSize);
-            STORM_FREE(pFileData);
-        }
-        else
-            nError = Logger.PrintError("Failed to load the file %s", szFileName);
+        // First, use the SFileSetFilePointer WITH the high-dword position
+        if(dwErrCode == ERROR_SUCCESS)
+            dwErrCode = TestSetFilePointers(hFile, true);
 
-        // Compare the CRC32
-        if(nError == ERROR_SUCCESS && dwCrc32_1 && dwCrc32_2)
-        {
-            if(dwCrc32_1 != dwCrc32_2)
-                Logger.PrintError("Warning: CRC32 error on %s", szFileName);
-        }
+        // Close the file
+        SFileCloseFile(hFile);
     }
 
-    // Close the archive
-    if(hMpq != NULL)
-        SFileCloseArchive(hMpq);
-    return nError;
+    return dwErrCode;
 }
 
-static int TestOpenArchive(LPCTSTR szPlainName, LPCTSTR szListFile = NULL, LPCSTR szFileName = NULL, bool bDontCopyArchive = false)
+static DWORD TestArchive(
+    LPCTSTR szPlainName,                // Plain name of the MPQ
+    LPCTSTR szListFile,                 // Listfile name (NULL if none)
+    DWORD  dwFlags,                     // Flags
+    LPCSTR szFileName1,
+    LPCSTR szFileName2)
 {
-    TLogHelper Logger("OpenMpqTest", szPlainName);
-    TFileData * pFileData;
-    LPCTSTR szCopyName = (bDontCopyArchive) ? NULL : szPlainName;
-    HANDLE hMpq;
-    HANDLE hFile;
+    TFileData * pFileData1 = NULL;
+    TFileData * pFileData2 = NULL;
+    TLogHelper Logger("TestMpq", szPlainName);
+    LPCSTR szExpectedMD5 = NULL;
+    HANDLE hMpq = NULL;
     DWORD dwFileCount = 0;
-    DWORD dwTestFlags;
-    TCHAR szListFileBuff[MAX_PATH];
-    bool bIsPartialMpq = false;
-    int nError;
+    DWORD dwSearchFlags = 0;
+    DWORD dwErrCode;
+    DWORD dwCrc32 = 0;
+    DWORD dwExpectedFileCount = 0;
+    DWORD dwMpqFlags = 0;
+    TCHAR szFullName[MAX_PATH];
+    BYTE ExpectedMD5[MD5_DIGEST_SIZE];
+    BYTE OverallMD5[MD5_DIGEST_SIZE];
+    bool bIgnoreOpenErrors = false;
 
     // If the file is a partial MPQ, don't load all files
-    bIsPartialMpq = (_tcsstr(szPlainName, _T(".MPQ.part")) != NULL);
+    if(_tcsstr(szPlainName, _T(".MPQ.part")) == NULL)
+        dwSearchFlags |= SEARCH_FLAG_LOAD_FILES;
+
+    // If the MPQ is a protected MPQ, do different tests
+    if(dwFlags & TEST_FLAG_PROTECTED)
+    {
+        dwExpectedFileCount = (dwFlags & TEST_FLAG_FILE_COUNT);
+        if((szExpectedMD5 = szFileName1) != NULL)
+            dwSearchFlags |= SEARCH_FLAG_HASH_FILES;
+        szFileName2 = szFileName1 = NULL;
+    }
 
     // Copy the archive so we won't fuck up the original one
-    nError = OpenExistingArchiveWithCopy(&Logger, szPlainName, szCopyName, &hMpq);
-    if(nError == ERROR_SUCCESS)
+    dwErrCode = OpenExistingArchiveWithCopy(&Logger, szPlainName, NULL, &hMpq);
+    while(dwErrCode == ERROR_SUCCESS)
     {
+        // Check for malformed MPQs
+        SFileGetFileInfo(hMpq, SFileMpqFlags, &dwMpqFlags, sizeof(dwMpqFlags), NULL);
+        if(dwMpqFlags & MPQ_FLAG_MALFORMED)
+        {
+            dwSearchFlags |= SEARCH_FLAG_IGNORE_ERRORS;
+            bIgnoreOpenErrors = true;
+        }
+
         // If the listfile was given, add it to the MPQ
-        if(szListFile != NULL)
+        if(szListFile && szListFile[0])
         {
             Logger.PrintProgress(_T("Adding listfile %s ..."), szListFile);
-            CreateFullPathName(szListFileBuff, _countof(szListFileBuff), szListFileDir, szListFile);
-            nError = SFileAddListFile(hMpq, szListFileBuff);
-            if(nError != ERROR_SUCCESS)
+            CreateFullPathName(szFullName, _countof(szFullName), szListFileDir, szListFile);
+            if((dwErrCode = SFileAddListFile(hMpq, szFullName)) != ERROR_SUCCESS)
                 Logger.PrintMessage("Failed to add the listfile to the MPQ");
         }
 
-        // Attempt to open the (listfile)
-        if(SFileHasFile(hMpq, LISTFILE_NAME))
+        // Attempt to open the (listfile), (attributes), (signature)
+        dwErrCode = TestArchive_LoadFiles(&Logger, hMpq, bIgnoreOpenErrors, LISTFILE_NAME, ATTRIBUTES_NAME, SIGNATURE_NAME, NULL);
+        if(dwErrCode != ERROR_SUCCESS)
+            break;
+
+        // If szFileName1 was given, load it and check its CRC
+        if(szFileName1 && szFileName1[0])
         {
-            pFileData = LoadMpqFile(&Logger, hMpq, LISTFILE_NAME);
-            if(pFileData != NULL)
-                STORM_FREE(pFileData);
+            // Test setting position
+            dwErrCode = TestArchive_SetPos(hMpq, szFileName1);
+            if(dwErrCode != ERROR_SUCCESS)
+                break;
+
+            // Load the entire file 1
+            pFileData1 = LoadMpqFile(&Logger, hMpq, szFileName1);
+            if(pFileData1 == NULL)
+            {
+                dwErrCode = Logger.PrintError("Failed to load the file %s", szFileName1);
+                break;
+            }
+
+            // Check the CRC of file1, if available
+            if(pFileData1->dwCrc32)
+            {
+                // Compare the CRC32, if available
+                dwCrc32 = crc32(0, (Bytef *)pFileData1->FileData, (uInt)pFileData1->dwFileSize);
+                if(dwCrc32 != pFileData1->dwCrc32)
+                    Logger.PrintError("Warning: CRC32 error on %s", szFileName1);
+            }
         }
 
-        // Attempt to open the (attributes)
-        if(SFileHasFile(hMpq, ATTRIBUTES_NAME))
+        // If szFileName2 was given, load it
+        if(szFileName2 && szFileName2[0])
         {
-            pFileData = LoadMpqFile(&Logger, hMpq, ATTRIBUTES_NAME);
-            if(pFileData != NULL)
-                STORM_FREE(pFileData);
-        }
-
-        // Attempt to open the (signature)
-        if(SFileHasFile(hMpq, SIGNATURE_NAME))
-        {
-            pFileData = LoadMpqFile(&Logger, hMpq, SIGNATURE_NAME);
-            if(pFileData != NULL)
-                STORM_FREE(pFileData);
-        }
-
-        // Attempt to open an arbitrary file
-        if(szFileName != NULL && szFileName[0] != 0)
-        {
-            if(SFileOpenFileEx(hMpq, "1.blp", 0, &hFile))
+            // Load the entire file 2
+            pFileData2 = LoadMpqFile(&Logger, hMpq, szFileName2);
+            if(pFileData2 == NULL)
             {
-                DWORD dwFileSize;
-                DWORD dwBytesRead = 0;
-                BYTE Buffer[0x10];
-
-                dwFileSize = SFileGetFileSize(hFile, NULL);
-                if(dwFileSize > sizeof(Buffer))
-                {
-                    SFileSetFilePointer(hFile, dwFileSize - sizeof(Buffer), NULL, FILE_BEGIN);
-                    SFileReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL);
-                }
-
-                SFileCloseFile(hFile);
+                dwErrCode = Logger.PrintError("Failed to load the file %s", szFileName2);
+                break;
             }
         }
 
-        // Search the archive and load every file
-        dwTestFlags = bIsPartialMpq ? 0 : TEST_FLAG_LOAD_FILES;
-        nError = SearchArchive(&Logger, hMpq, dwTestFlags, &dwFileCount);
-        SFileCloseArchive(hMpq);
-    }
-
-    return nError;
-}
-
-static int TestOpenArchive_SetPos(LPCTSTR szPlainName, LPCSTR szFileName)
-{
-    TLogHelper Logger("SetPosTest", szPlainName);
-    HANDLE hFile = NULL;
-    HANDLE hMpq = NULL;
-    TCHAR szMpqName[MAX_PATH];
-    char szFullPath[MAX_PATH];
-    int nError = ERROR_SUCCESS;
-
-    // Create the full path name for the archive
-    CreateFullPathName(szFullPath, _countof(szFullPath), szMpqSubDir, szPlainName);
-    StringCopy(szMpqName, _countof(szMpqName), szFullPath);
-
-    // Try to open the archive. It is expected to fail
-    Logger.PrintProgress("Opening archive %s", szPlainName);
-    if(SFileOpenArchive(szMpqName, 0, MPQ_OPEN_READ_ONLY, &hMpq))
-    {
-        if(SFileOpenFileEx(hMpq, szFileName, 0, &hFile))
-        {
-            // First, use the SFileSetFilePointer WITHOUT the high-dword position
-            if(nError == ERROR_SUCCESS)
-                nError = TestSetFilePointers(hFile, false);
-
-            // First, use the SFileSetFilePointer WITH the high-dword position
-            if(nError == ERROR_SUCCESS)
-                nError = TestSetFilePointers(hFile, false);
-
-            // Close the file
-            SFileCloseFile(hFile);
-        }
-        else
-            nError = GetLastError();
-
-        // Close the archive
-        SFileCloseArchive(hMpq);
-    }
-    else
-        nError = GetLastError();
-
-    return nError;
-}
-
-static int TestOpenArchive_ProtectedMap(LPCTSTR szPlainName, LPCTSTR szListFile = NULL, DWORD dwExpectedFileCount = 0, LPCSTR szExpectedMD5 = NULL)
-{
-    TLogHelper Logger("ProtectedMapTest", szPlainName);
-    HANDLE hMpq;
-    DWORD dwTestFlags = TEST_FLAG_LOAD_FILES | TEST_FLAG_HASH_FILES;
-    DWORD dwFileCount = 0;
-    BYTE ExpectedMD5[MD5_DIGEST_SIZE];
-    BYTE OverallMD5[MD5_DIGEST_SIZE];
-    TCHAR szListFileBuff[MAX_PATH];
-    int nError;
-
-    // Copy the archive so we won't fuck up the original one
-    nError = OpenExistingArchiveWithCopy(&Logger, szPlainName, szPlainName, &hMpq);
-    if(nError == ERROR_SUCCESS)
-    {
-        // If the listfile was given, add it to the MPQ
-        if(szListFile != NULL)
+        // If two files were given, compare them
+        if(pFileData1 && pFileData2)
         {
-            Logger.PrintProgress(_T("Adding listfile %s ..."), szListFile);
-            CreateFullPathName(szListFileBuff, _countof(szListFileBuff), szMpqSubDir, szListFile);
-            nError = SFileAddListFile(hMpq, szListFileBuff);
-            if(nError != ERROR_SUCCESS)
-                Logger.PrintMessage("Failed to add the listfile to the MPQ");
+            // Compare both files
+            if(!CompareTwoFiles(&Logger, pFileData1, pFileData2))
+            {
+                dwErrCode = Logger.PrintError("The file has different size/content of files");
+                break;
+            }
         }
 
-        // Search the archive and load every file
-        nError = SearchArchive(&Logger, hMpq, dwTestFlags, &dwFileCount, OverallMD5);
-        SFileCloseArchive(hMpq);
-    }
+        // Search the archive
+        dwErrCode = SearchArchive(&Logger, hMpq, dwSearchFlags, &dwFileCount, OverallMD5);
 
-    // Check the file count and hash, if required
-    if(nError == ERROR_SUCCESS && dwExpectedFileCount != 0)
-    {
-        if(dwFileCount != dwExpectedFileCount)
+        // Shall we check the file count and overall MD5?
+        if(dwExpectedFileCount != 0)
         {
-            Logger.PrintMessage("File count mismatch(expected: %u, found:%u)", dwExpectedFileCount, dwFileCount);
-            nError = ERROR_CAN_NOT_COMPLETE;
+            if(dwFileCount != dwExpectedFileCount)
+            {
+                Logger.PrintMessage("File count mismatch(expected: %u, found:%u)", dwExpectedFileCount, dwFileCount);
+                dwErrCode = ERROR_CAN_NOT_COMPLETE;
+                break;
+            }
         }
-    }
 
-    // Check the overall hash, if required
-    if(nError == ERROR_SUCCESS && szExpectedMD5 != NULL && szExpectedMD5[0] != 0)
-    {
-        BinaryFromString(szExpectedMD5, ExpectedMD5, MD5_DIGEST_SIZE);
-        if(memcmp(ExpectedMD5, OverallMD5, MD5_DIGEST_SIZE))
+        // Shall we check overall MD5?
+        if(szExpectedMD5 && szExpectedMD5[0])
         {
-            Logger.PrintMessage("Extracted files MD5 mismatch");
-            nError = ERROR_CAN_NOT_COMPLETE;
+            BinaryFromString(szExpectedMD5, ExpectedMD5, MD5_DIGEST_SIZE);
+            if(memcmp(ExpectedMD5, OverallMD5, MD5_DIGEST_SIZE))
+            {
+                Logger.PrintMessage("Extracted files MD5 mismatch");
+                dwErrCode = ERROR_CAN_NOT_COMPLETE;
+                break;
+            }
         }
+        break;
     }
 
-    return nError;
+    // Common cleanup
+    if(pFileData2 != NULL)
+        STORM_FREE(pFileData2);
+    if(pFileData1 != NULL)
+        STORM_FREE(pFileData1);
+    if(hMpq != NULL)
+        SFileCloseArchive(hMpq);
+    return dwErrCode;
 }
 
 // Open an empty archive (found in WoW cache - it's just a header)
@@ -2770,7 +2595,7 @@ static int TestOpenArchive_Corrupt(LPCTSTR szPlainName)
 
 
 // Opens a patched MPQ archive
-static int TestOpenArchive_Patched(LPCTSTR PatchList[], LPCSTR szPatchedFile, int nExpectedPatchCount, bool bExpectedToFail = false)
+static DWORD TestOpenArchive_Patched(LPCTSTR PatchList[], LPCSTR szPatchedFile, int nExpectedPatchCount, bool bExpectedToFail = false)
 {
     TLogHelper Logger("OpenPatchedMpqTest", PatchList[0]);
     HANDLE hMpq;
@@ -2778,18 +2603,18 @@ static int TestOpenArchive_Patched(LPCTSTR PatchList[], LPCSTR szPatchedFile, in
     BYTE Buffer[0x100];
     DWORD dwFileCount = 0;
     DWORD BytesRead = 0;
-    int nError;
+    DWORD dwErrCode;
 
     // Open a patched MPQ archive
-    nError = OpenPatchedArchive(&Logger, &hMpq, PatchList);
-    if(nError == ERROR_SUCCESS)
+    dwErrCode = OpenPatchedArchive(&Logger, &hMpq, PatchList);
+    if(dwErrCode == ERROR_SUCCESS)
     {
         // Check patch count
         if(szPatchedFile != NULL)
-            nError = VerifyFilePatchCount(&Logger, hMpq, szPatchedFile, nExpectedPatchCount);
+            dwErrCode = VerifyFilePatchCount(&Logger, hMpq, szPatchedFile, nExpectedPatchCount);
 
         // Try to open and read the file
-        if(nError == ERROR_SUCCESS)
+        if(dwErrCode == ERROR_SUCCESS)
         {
             if(SFileOpenFileEx(hMpq, szPatchedFile, 0, &hFile))
             {
@@ -2799,17 +2624,17 @@ static int TestOpenArchive_Patched(LPCTSTR PatchList[], LPCSTR szPatchedFile, in
         }
 
         // Search the archive and load every file
-        if(nError == ERROR_SUCCESS)
-            nError = SearchArchive(&Logger, hMpq, TEST_FLAG_LOAD_FILES, &dwFileCount);
-        
+        if(dwErrCode == ERROR_SUCCESS)
+            dwErrCode = SearchArchive(&Logger, hMpq, SEARCH_FLAG_LOAD_FILES | SEARCH_FLAG_IGNORE_ERRORS, &dwFileCount);
+
         // Close the archive
         SFileCloseArchive(hMpq);
     }
 
     // Clear the error if patch prefix was not found
-    if(nError == ERROR_CANT_FIND_PATCH_PREFIX && bExpectedToFail)
-        nError = ERROR_SUCCESS;
-    return nError;
+    if(dwErrCode == ERROR_CANT_FIND_PATCH_PREFIX && bExpectedToFail)
+        dwErrCode = ERROR_SUCCESS;
+    return dwErrCode;
 }
 
 // Open an archive for read-only access
@@ -2878,21 +2703,21 @@ static int TestOpenArchive_GetFileInfo(LPCTSTR szPlainName1, LPCTSTR szPlainName
         TestGetFileInfo(&Logger, NULL, SFileMpqBetHeader, NULL, 0, NULL, false, ERROR_INVALID_HANDLE);
 
         // Valid handle but invalid value of file info class (false, ERROR_INVALID_PARAMETER)
-        TestGetFileInfo(&Logger, NULL, (SFileInfoClass)0xFFF, NULL, 0, NULL, false, ERROR_INVALID_PARAMETER);
+        TestGetFileInfo(&Logger, NULL, (SFileInfoClass)0xFFF, NULL, 0, NULL, false, ERROR_INVALID_HANDLE);
 
-        // Valid archive handle but file info class is for file (false, ERROR_INVALID_HANDLE)
+        // Invalid archive handle and file info class is for file (false, ERROR_INVALID_HANDLE)
         TestGetFileInfo(&Logger, NULL, SFileInfoNameHash1, NULL, 0, NULL, false, ERROR_INVALID_HANDLE);
 
         // Valid handle and all parameters NULL
-        // Returns (true, ERROR_SUCCESS), if BET table is present, otherwise (false, ERROR_CAN_NOT_COMPLETE)
+        // Returns (true, ERROR_SUCCESS), if BET table is present, otherwise (false, ERROR_FILE_NOT_FOUND)
         TestGetFileInfo(&Logger, hMpq1, SFileMpqBetHeader, NULL, 0, NULL, false, ERROR_FILE_NOT_FOUND);
-        TestGetFileInfo(&Logger, hMpq4, SFileMpqBetHeader, NULL, 0, NULL, true, ERROR_SUCCESS);
+        TestGetFileInfo(&Logger, hMpq4, SFileMpqBetHeader, NULL, 0, NULL, false, ERROR_INSUFFICIENT_BUFFER);
 
         // Now try to retrieve the required size of the BET table header
-        TestGetFileInfo(&Logger, hMpq4, SFileMpqBetHeader, NULL, 0, &cbLength, true, ERROR_SUCCESS);
+        TestGetFileInfo(&Logger, hMpq4, SFileMpqBetHeader, NULL, 0, &cbLength, false, ERROR_INSUFFICIENT_BUFFER);
 
         // When we call SFileInfo with buffer = NULL and nonzero buffer size, it is ignored
-        TestGetFileInfo(&Logger, hMpq4, SFileMpqBetHeader, NULL, 3, &cbLength, true, ERROR_SUCCESS);
+        TestGetFileInfo(&Logger, hMpq4, SFileMpqBetHeader, NULL, 3, &cbLength, false, ERROR_INSUFFICIENT_BUFFER);
 
         // When we call SFileInfo with buffer != NULL and nonzero buffer size, it should return error
         TestGetFileInfo(&Logger, hMpq4, SFileMpqBetHeader, DataBuff, 3, &cbLength, false, ERROR_INSUFFICIENT_BUFFER);
@@ -2904,21 +2729,21 @@ static int TestOpenArchive_GetFileInfo(LPCTSTR szPlainName1, LPCTSTR szPlainName
         TestGetFileInfo(&Logger, hMpq4, SFileMpqBetHeader, DataBuff, sizeof(DataBuff), &cbLength, true, ERROR_SUCCESS);
 
         // Try to retrieve strong signature from the MPQ
-        TestGetFileInfo(&Logger, hMpq1, SFileMpqStrongSignature, NULL, 0, NULL, true, ERROR_SUCCESS);
+        TestGetFileInfo(&Logger, hMpq1, SFileMpqStrongSignature, NULL, 0, NULL, false, ERROR_INSUFFICIENT_BUFFER);
         TestGetFileInfo(&Logger, hMpq4, SFileMpqStrongSignature, NULL, 0, NULL, false, ERROR_FILE_NOT_FOUND);
 
         // Strong signature is returned including the signature ID
-        TestGetFileInfo(&Logger, hMpq1, SFileMpqStrongSignature, NULL, 0, &cbLength, true, ERROR_SUCCESS);
+        TestGetFileInfo(&Logger, hMpq1, SFileMpqStrongSignature, NULL, 0, &cbLength, false, ERROR_INSUFFICIENT_BUFFER);
         assert(cbLength == MPQ_STRONG_SIGNATURE_SIZE + 4);
 
         // Retrieve the signature
         TestGetFileInfo(&Logger, hMpq1, SFileMpqStrongSignature, DataBuff, sizeof(DataBuff), &cbLength, true, ERROR_SUCCESS);
         assert(memcmp(DataBuff, "NGIS", 4) == 0);
 
-        // Check SFileGetFileInfo on 
+        // Check SFileGetFileInfo on
         if(SFileOpenFileEx(hMpq4, LISTFILE_NAME, 0, &hFile))
         {
-            // Valid parameters but the handle should be file handle 
+            // Valid parameters but the handle should be file handle
             TestGetFileInfo(&Logger, hMpq4, SFileInfoFileTime, DataBuff, sizeof(DataBuff), &cbLength, false, ERROR_INVALID_HANDLE);
 
             // Valid parameters
@@ -2955,7 +2780,7 @@ static int TestOpenArchive_MasterMirror(LPCTSTR szMirrorName, LPCTSTR szMasterNa
         nError = OpenExistingArchive(&Logger, szMirrorPath, 0, &hMpq);
     }
 
-    // The MPQ must be read-only. Writing to mirrored MPQ is not allowed 
+    // The MPQ must be read-only. Writing to mirrored MPQ is not allowed
     if(nError == ERROR_SUCCESS)
     {
         if(SFileCreateFile(hMpq, "AddedFile.bin", 0, 0x10, 0, MPQ_FILE_COMPRESS, &hFile))
@@ -3138,8 +2963,7 @@ static int TestOpenArchive_SignExisting(LPCTSTR szPlainName)
     return nError;
 }
 
-// Open an empty archive (found in WoW cache - it's just a header)
-static int TestOpenArchive_CompactArchive(LPCTSTR szPlainName, LPCTSTR szCopyName, bool bAddUserData)
+static DWORD TestOpenArchive_CompactArchive(LPCTSTR szPlainName, LPCTSTR szCopyName, bool bAddUserData)
 {
     TLogHelper Logger("CompactMpqTest", szPlainName);
 	ULONGLONG PreMpqDataSize = (bAddUserData) ? 0x400 : 0;
@@ -3150,73 +2974,73 @@ static int TestOpenArchive_CompactArchive(LPCTSTR szPlainName, LPCTSTR szCopyNam
     TCHAR szFullPath[MAX_PATH];
     BYTE FileHash1[MD5_DIGEST_SIZE];
     BYTE FileHash2[MD5_DIGEST_SIZE];
-    int nError;
+    DWORD dwErrCode;
 
     // Create copy of the archive, with interleaving some user data
-    nError = CreateFileCopy(&Logger, szPlainName, szCopyName, szFullPath, _countof(szFullPath), PreMpqDataSize, UserDataSize);
-    
+    dwErrCode = CreateFileCopy(&Logger, szPlainName, szCopyName, szFullPath, _countof(szFullPath), PreMpqDataSize, UserDataSize);
+
     // Open the archive and load some files
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
         // Open the archive
-        nError = OpenExistingArchive(&Logger, szFullPath, 0, &hMpq);
-        if(nError != ERROR_SUCCESS)
-            return nError;
+        dwErrCode = OpenExistingArchive(&Logger, szFullPath, 0, &hMpq);
+        if(dwErrCode != ERROR_SUCCESS)
+            return dwErrCode;
 
         // Verify presence of (listfile) and (attributes)
         CheckIfFileIsPresent(&Logger, hMpq, LISTFILE_NAME, true);
         CheckIfFileIsPresent(&Logger, hMpq, ATTRIBUTES_NAME, true);
-        
+
         // Search the archive and load every file
-        nError = SearchArchive(&Logger, hMpq, TEST_FLAG_LOAD_FILES | TEST_FLAG_HASH_FILES, &dwFileCount1, FileHash1);
+        dwErrCode = SearchArchive(&Logger, hMpq, SEARCH_FLAG_LOAD_FILES | SEARCH_FLAG_HASH_FILES, &dwFileCount1, FileHash1);
         SFileCloseArchive(hMpq);
     }
 
     // Try to compact the MPQ
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
         // Open the archive again
-        nError = OpenExistingArchive(&Logger, szFullPath, 0, &hMpq);
-        if(nError != ERROR_SUCCESS)
-            return nError;
-        
+        dwErrCode = OpenExistingArchive(&Logger, szFullPath, 0, &hMpq);
+        if(dwErrCode != ERROR_SUCCESS)
+            return dwErrCode;
+
         // Compact the archive
         Logger.PrintProgress("Compacting archive %s ...", GetShortPlainName(szFullPath));
         if(!SFileSetCompactCallback(hMpq, CompactCallback, &Logger))
-            nError = Logger.PrintError(_T("Failed to compact archive %s"), szFullPath);
+            dwErrCode = Logger.PrintError(_T("Failed to compact archive %s"), szFullPath);
 
         SFileCompactArchive(hMpq, NULL, false);
         SFileCloseArchive(hMpq);
     }
 
     // Open the archive and load some files
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
         // Open the archive
-        nError = OpenExistingArchive(&Logger, szFullPath, 0, &hMpq);
-        if(nError != ERROR_SUCCESS)
-            return nError;
+        dwErrCode = OpenExistingArchive(&Logger, szFullPath, 0, &hMpq);
+        if(dwErrCode != ERROR_SUCCESS)
+            return dwErrCode;
 
         // Verify presence of (listfile) and (attributes)
         CheckIfFileIsPresent(&Logger, hMpq, LISTFILE_NAME, true);
         CheckIfFileIsPresent(&Logger, hMpq, ATTRIBUTES_NAME, true);
-        
+
         // Search the archive and load every file
-        nError = SearchArchive(&Logger, hMpq, TEST_FLAG_LOAD_FILES | TEST_FLAG_HASH_FILES, &dwFileCount2, FileHash2);
+        dwErrCode = SearchArchive(&Logger, hMpq, SEARCH_FLAG_LOAD_FILES | SEARCH_FLAG_HASH_FILES, &dwFileCount2, FileHash2);
         SFileCloseArchive(hMpq);
     }
 
     // Compare the file counts and their hashes
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
         if(dwFileCount2 != dwFileCount1)
             Logger.PrintMessage("Different file count after compacting archive: %u vs %u", dwFileCount2, dwFileCount1);
-        
+
         if(memcmp(FileHash2, FileHash1, MD5_DIGEST_SIZE))
             Logger.PrintMessage("Different file hash after compacting archive");
     }
 
-    return nError;
+    return dwErrCode;
 }
 
 static int ForEachFile_VerifyFileChecksum(LPCTSTR szFullPath)
@@ -3291,6 +3115,12 @@ static int ForEachFile_OpenArchive(LPCTSTR szFullPath)
             nError = SearchArchive(&Logger, hMpq, 0, &dwFileCount);
             SFileCloseArchive(hMpq);
         }
+
+        // Show warning if no files found
+        if(dwFileCount == 0)
+        {
+            Logger.PrintMessage("Warning: no files in the archive");
+        }
     }
 
     // Correct some errors
@@ -3404,7 +3234,7 @@ static int TestCreateArchive_Deprotect(LPCSTR szPlainName)
     BYTE FileHash2[MD5_DIGEST_SIZE];
     DWORD dwFileCount1 = 0;
     DWORD dwFileCount2 = 0;
-    DWORD dwTestFlags = TEST_FLAG_LOAD_FILES | TEST_FLAG_HASH_FILES;
+    DWORD dwTestFlags = SEARCH_FLAG_LOAD_FILES | SEARCH_FLAG_HASH_FILES;
     int nError = ERROR_SUCCESS;
 
     // First copy: The original (untouched) file
@@ -3450,7 +3280,7 @@ static int TestCreateArchive_Deprotect(LPCSTR szPlainName)
     if(nError == ERROR_SUCCESS)
     {
         if(dwFileCount1 != dwFileCount2)
-            Logger.PrintMessage("Different file count (%u in %s; %u in %s)", dwFileCount1, szMpqName1, dwFileCount2, szMpqName2); 
+            Logger.PrintMessage("Different file count (%u in %s; %u in %s)", dwFileCount1, szMpqName1, dwFileCount2, szMpqName2);
         if(memcmp(FileHash1, FileHash2, MD5_DIGEST_SIZE))
             Logger.PrintMessage("Different file hash (%s vs %s)", szMpqName1, szMpqName2);
     }
@@ -3469,7 +3299,7 @@ static int TestCreateArchive_EmptyMpq(LPCTSTR szPlainName, DWORD dwCreateFlags)
     TLogHelper Logger("CreateEmptyMpq", szPlainName);
     HANDLE hMpq = NULL;
     DWORD dwFileCount = 0;
-    int nError;                                                     
+    int nError;
 
     // Create the full path name
     nError = CreateNewArchive(&Logger, szPlainName, dwCreateFlags, 0, &hMpq);
@@ -3560,7 +3390,7 @@ static int TestCreateArchive_TestGaps(LPCTSTR szPlainName)
         if(ByteOffset1 != ByteOffset2)
         {
             Logger.PrintError("The added file was not written to the position of (listfile)");
-            nError = ERROR_FILE_CORRUPT;    
+            nError = ERROR_FILE_CORRUPT;
         }
     }
 
@@ -3899,10 +3729,10 @@ static int TestCreateArchive_UnicodeNames()
     return nError;
 }
 
-static int TestCreateArchive_FileFlagTest(LPCTSTR szPlainName)
+static DWORD TestCreateArchive_FileFlagTest(LPCTSTR szPlainName)
 {
     TLogHelper Logger("FileFlagTest", szPlainName);
-    HANDLE hMpq = NULL;                 // Handle of created archive 
+    HANDLE hMpq = NULL;                 // Handle of created archive
     TCHAR szFileName1[MAX_PATH];
     TCHAR szFileName2[MAX_PATH];
     TCHAR szFullPath[MAX_PATH];
@@ -3911,71 +3741,70 @@ static int TestCreateArchive_FileFlagTest(LPCTSTR szPlainName)
     char szArchivedName[MAX_PATH];
     DWORD dwMaxFileCount = 0;
     DWORD dwFileCount = 0;
-    size_t i;
-    int nError;
+    DWORD dwErrCode;
 
     // Create paths for local file to be added
     CreateFullPathName(szFileName1, _countof(szFileName1), szMpqSubDir, _T("AddFile.exe"));
     CreateFullPathName(szFileName2, _countof(szFileName2), szMpqSubDir, _T("AddFile.bin"));
 
     // Create an empty file that will serve as holder for the MPQ
-    nError = CreateEmptyFile(&Logger, szPlainName, 0x100000, szFullPath);
+    dwErrCode = CreateEmptyFile(&Logger, szPlainName, 0x100000, szFullPath);
 
     // Create new MPQ archive over that file
-    if(nError == ERROR_SUCCESS)
-        nError = CreateNewArchive(&Logger, szPlainName, MPQ_CREATE_ARCHIVE_V1 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES, 17, &hMpq);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = CreateNewArchive(&Logger, szPlainName, MPQ_CREATE_ARCHIVE_V1 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES, 17, &hMpq);
 
     // Add the same file multiple times
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
         dwMaxFileCount = SFileGetMaxFileCount(hMpq);
-        for(i = 0; AddFlags[i] != 0xFFFFFFFF; i++)
+        for(size_t i = 0; AddFlags[i] != 0xFFFFFFFF; i++)
         {
             sprintf(szArchivedName, "FileTest_%02u.exe", (unsigned int)i);
-            nError = AddLocalFileToMpq(&Logger, hMpq, szArchivedName, szFileName1, AddFlags[i], 0);
-            if(nError != ERROR_SUCCESS)
+            dwErrCode = AddLocalFileToMpq(&Logger, hMpq, szArchivedName, szFileName1, AddFlags[i], 0);
+            if(dwErrCode != ERROR_SUCCESS)
                 break;
 
             dwFileCount++;
         }
     }
-        
+
     // Delete a file in the middle of the file table
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
         Logger.PrintProgress("Removing file %s ...", szMiddleFile);
-        nError = RemoveMpqFile(&Logger, hMpq, szMiddleFile, ERROR_SUCCESS);
+        dwErrCode = RemoveMpqFile(&Logger, hMpq, szMiddleFile, ERROR_SUCCESS);
         dwFileCount--;
     }
 
     // Add one more file
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
-        nError = AddLocalFileToMpq(&Logger, hMpq, "FileTest_xx.exe", szFileName1);
+        dwErrCode = AddLocalFileToMpq(&Logger, hMpq, "FileTest_xx.exe", szFileName1);
         dwFileCount++;
     }
-    
+
     // Try to decrement max file count. This must succeed
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
         Logger.PrintProgress("Attempting to decrement max file count ...");
         if(SFileSetMaxFileCount(hMpq, 5))
-            nError = Logger.PrintError("Max file count decremented, even if it should fail");
+            dwErrCode = Logger.PrintError("Max file count decremented, even if it should fail");
     }
 
     // Add ZeroSize.txt several times under a different locale
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
-        for(i = 0; LocaleIDs[i] != 0xFFFF; i++)
+        for(size_t i = 0; LocaleIDs[i] != 0xFFFF; i++)
         {
             bool bMustSucceed = ((dwFileCount + 2) < dwMaxFileCount);
 
             SFileSetLocale(LocaleIDs[i]);
-            nError = AddLocalFileToMpq(&Logger, hMpq, "ZeroSize_1.txt", szFileName2);
-            if(nError != ERROR_SUCCESS)
+            dwErrCode = AddLocalFileToMpq(&Logger, hMpq, "ZeroSize_1.txt", szFileName2);
+            if(dwErrCode != ERROR_SUCCESS)
             {
                 if(bMustSucceed == false)
-                    nError = ERROR_SUCCESS;
+                    dwErrCode = ERROR_SUCCESS;
                 break;
             }
 
@@ -3984,65 +3813,65 @@ static int TestCreateArchive_FileFlagTest(LPCTSTR szPlainName)
     }
 
     // Add ZeroSize.txt again several times under a different locale
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
-        for(i = 0; LocaleIDs[i] != 0xFFFF; i++)
+        for(size_t i = 0; LocaleIDs[i] != 0xFFFF; i++)
         {
             bool bMustSucceed = ((dwFileCount + 2) < dwMaxFileCount);
 
             SFileSetLocale(LocaleIDs[i]);
-            nError = AddLocalFileToMpq(&Logger, hMpq, "ZeroSize_2.txt", szFileName2, 0, 0, bMustSucceed);
-            if(nError != ERROR_SUCCESS)
+            dwErrCode = AddLocalFileToMpq(&Logger, hMpq, "ZeroSize_2.txt", szFileName2, 0, 0, bMustSucceed);
+            if(dwErrCode != ERROR_SUCCESS)
             {
                 if(bMustSucceed == false)
-                    nError = ERROR_SUCCESS;
+                    dwErrCode = ERROR_SUCCESS;
                 break;
             }
-            
+
             dwFileCount++;
         }
     }
 
     // Verify how many files did we add to the MPQ
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
         if(dwFileCount + 2 != dwMaxFileCount)
         {
             Logger.PrintErrorVa("Number of files added to MPQ was unexpected (expected %u, added %u)", dwFileCount, dwMaxFileCount - 2);
-            nError = ERROR_FILE_CORRUPT;
+            dwErrCode = ERROR_FILE_CORRUPT;
         }
     }
 
     // Test rename function
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
         Logger.PrintProgress("Testing rename files ...");
         SFileSetLocale(LANG_NEUTRAL);
         if(!SFileRenameFile(hMpq, "FileTest_08.exe", "FileTest_08a.exe"))
-            nError = Logger.PrintError("Failed to rename the file");
+            dwErrCode = Logger.PrintError("Failed to rename the file");
     }
 
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
         if(!SFileRenameFile(hMpq, "FileTest_08a.exe", "FileTest_08.exe"))
-            nError = Logger.PrintError("Failed to rename the file");
+            dwErrCode = Logger.PrintError("Failed to rename the file");
     }
 
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
         if(SFileRenameFile(hMpq, "FileTest_10.exe", "FileTest_10a.exe"))
         {
             Logger.PrintError("Rename test succeeded even if it shouldn't");
-            nError = ERROR_FILE_CORRUPT;
+            dwErrCode = ERROR_FILE_CORRUPT;
         }
     }
 
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
         if(SFileRenameFile(hMpq, "FileTest_10a.exe", "FileTest_10.exe"))
         {
             Logger.PrintError("Rename test succeeded even if it shouldn't");
-            nError = ERROR_FILE_CORRUPT;
+            dwErrCode = ERROR_FILE_CORRUPT;
         }
     }
 
@@ -4052,15 +3881,15 @@ static int TestCreateArchive_FileFlagTest(LPCTSTR szPlainName)
     hMpq = NULL;
 
     // Try to reopen the archive
-    if(nError == ERROR_SUCCESS)
-        nError = OpenExistingArchive(&Logger, szFullPath, 0, NULL);
-    return nError;
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = OpenExistingArchive(&Logger, szFullPath, 0, NULL);
+    return dwErrCode;
 }
 
 static int TestCreateArchive_WaveCompressionsTest(LPCTSTR szPlainName, LPCTSTR szWaveFile)
 {
     TLogHelper Logger("CompressionsTest", szPlainName);
-    HANDLE hMpq = NULL;                 // Handle of created archive 
+    HANDLE hMpq = NULL;                 // Handle of created archive
     TCHAR szFileName[MAX_PATH];          // Source file to be added
     char szArchivedName[MAX_PATH];
     DWORD dwCmprCount = sizeof(WaveCompressions) / sizeof(DWORD);
@@ -4072,7 +3901,7 @@ static int TestCreateArchive_WaveCompressionsTest(LPCTSTR szPlainName, LPCTSTR s
     CreateFullPathName(szFileName, _countof(szFileName), szMpqSubDir, szWaveFile);
 
     // Create new archive
-    nError = CreateNewArchive(&Logger, szPlainName, MPQ_CREATE_ARCHIVE_V1 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES, 0x40, &hMpq); 
+    nError = CreateNewArchive(&Logger, szPlainName, MPQ_CREATE_ARCHIVE_V1 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES, 0x40, &hMpq);
 
     // Add the same file multiple times
     if(nError == ERROR_SUCCESS)
@@ -4098,7 +3927,7 @@ static int TestCreateArchive_WaveCompressionsTest(LPCTSTR szPlainName, LPCTSTR s
         nError = OpenExistingArchiveWithCopy(&Logger, NULL, szPlainName, &hMpq);
         if(nError == ERROR_SUCCESS)
         {
-            SearchArchive(&Logger, hMpq, TEST_FLAG_LOAD_FILES | TEST_FLAG_PLAY_WAVES, &dwFoundFiles, NULL);
+            SearchArchive(&Logger, hMpq, SEARCH_FLAG_LOAD_FILES | SEARCH_FLAG_PLAY_WAVES, &dwFoundFiles, NULL);
             SFileCloseArchive(hMpq);
         }
 
@@ -4120,7 +3949,7 @@ static int TestCreateArchive_ListFilePos(LPCTSTR szPlainName)
     LPCSTR szReaddedFile = "AddedFile_##.txt";
     LPCSTR szFileMask = "AddedFile_%02u.txt";
     TLogHelper Logger("ListFilePos", szPlainName);
-    HANDLE hMpq = NULL;                 // Handle of created archive 
+    HANDLE hMpq = NULL;                 // Handle of created archive
     char szArchivedName[MAX_PATH];
     DWORD dwMaxFileCount = 0x0E;
     DWORD dwFileCount = 0;
@@ -4212,7 +4041,7 @@ static int TestCreateArchive_ListFilePos(LPCTSTR szPlainName)
 static int TestCreateArchive_BigArchive(LPCTSTR szPlainName)
 {
     TLogHelper Logger("BigMpqTest", szPlainName);
-    HANDLE hMpq = NULL;                 // Handle of created archive 
+    HANDLE hMpq = NULL;                 // Handle of created archive
     TCHAR szLocalFileName[MAX_PATH];
     char szArchivedName[MAX_PATH];
     DWORD dwMaxFileCount = 0x20;
@@ -4264,20 +4093,20 @@ static int TestCreateArchive_BigArchive(LPCTSTR szPlainName)
 }
 
 // "MPQ_2014_v4_Heroes_Replay.MPQ", "AddFile-replay.message.events"
-static int TestModifyArchive_ReplaceFile(LPCTSTR szMpqPlainName, LPCTSTR szFileName)
+static DWORD TestModifyArchive_ReplaceFile(LPCTSTR szMpqPlainName, LPCTSTR szFileName)
 {
     TLogHelper Logger("ModifyTest", szMpqPlainName);
     HANDLE hMpq = NULL;
     TCHAR szLocalFileName[MAX_PATH];
     char szArchivedName[MAX_PATH];
     size_t nOffset = 0;
-    int nError;
+    DWORD dwErrCode;
 
     // Open an existing archive
-    nError = OpenExistingArchiveWithCopy(&Logger, szMpqPlainName, szMpqPlainName, &hMpq);
+    dwErrCode = OpenExistingArchiveWithCopy(&Logger, szMpqPlainName, szMpqPlainName, &hMpq);
 
     // Add the given file
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
         // Get the name of archived file
         if(!_tcsnicmp(szFileName, _T("AddFile-"), 8))
@@ -4288,112 +4117,123 @@ static int TestModifyArchive_ReplaceFile(LPCTSTR szMpqPlainName, LPCTSTR szFileN
         CreateFullPathName(szLocalFileName, _countof(szLocalFileName), szMpqSubDir, szFileName);
 
         // Add the file to MPQ
-        nError = AddLocalFileToMpq(&Logger, hMpq,
-                                            szArchivedName,
-                                            szLocalFileName,
-                                            MPQ_FILE_REPLACEEXISTING | MPQ_FILE_COMPRESS | MPQ_FILE_SINGLE_UNIT,
-                                            MPQ_COMPRESSION_ZLIB,
-                                            true);
+        dwErrCode = AddLocalFileToMpq(&Logger, hMpq,
+                                               szArchivedName,
+                                               szLocalFileName,
+                                               MPQ_FILE_REPLACEEXISTING | MPQ_FILE_COMPRESS | MPQ_FILE_SINGLE_UNIT,
+                                               MPQ_COMPRESSION_ZLIB,
+                                               true);
     }
 
     // Reopen the MPQ and compact it
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
         // Compact the archive
         Logger.PrintProgress("Compacting archive %s ...", szMpqPlainName);
         if(!SFileSetCompactCallback(hMpq, CompactCallback, &Logger))
-            nError = Logger.PrintError(_T("Failed to compact archive %s"), szMpqPlainName);
+            dwErrCode = Logger.PrintError(_T("Failed to compact archive %s"), szMpqPlainName);
 
         if(!SFileCompactArchive(hMpq, NULL, 0))
-            nError = GetLastError();
+            dwErrCode = GetLastError();
 
         SFileCloseArchive(hMpq);
     }
 
     // Try to open the archive again
-    if(nError == ERROR_SUCCESS)
+    if(dwErrCode == ERROR_SUCCESS)
     {
         CreateFullPathName(szLocalFileName, _countof(szLocalFileName), NULL, szMpqPlainName);
-        nError = OpenExistingArchive(&Logger, szLocalFileName, 0, &hMpq);
-        if(nError == ERROR_SUCCESS)
+        dwErrCode = OpenExistingArchive(&Logger, szLocalFileName, 0, &hMpq);
+        if(dwErrCode == ERROR_SUCCESS)
             SFileCloseArchive(hMpq);
     }
 
-    return nError;
+    return dwErrCode;
 }
 
 //-----------------------------------------------------------------------------
-// Comparing two directories, creating links
+// Tables
 
-#define LINK_COMPARE_BLOCK_SIZE 0x200
-/*
-static int CreateArchiveLinkFile(LPCTSTR szFullPath1, LPCTSTR szFullPath2, LPCSTR szFileHash)
+static const TEST_INFO TestList_StreamOps[] =
 {
-    TFileStream * pStream;
-    TCHAR szLinkData[MAX_PATH + 0x80];
-    TCHAR szLinkFile[MAX_PATH];
-    TCHAR szLinkPath[MAX_PATH];
-    int nLength;
-    int nError = ERROR_SUCCESS;
-
-    // Construct the link file name
-    CalculateRelativePath(szFullPath1, szFullPath2, szLinkPath);
-    sprintf(szLinkFile, "%s.link", szFullPath2);
-
-    // Format the content of the link file
-    nLength = sprintf(szLinkData, "LINK:%s\x0D\x0ASHA1:%s", szLinkPath, szFileHash);
-
-    // Create the link file
-    pStream = FileStream_CreateFile(szLinkFile, 0);
-    if(pStream == NULL)
-        return GetLastError();
-
-    // Write the content of the link file
-    if(!FileStream_Write(pStream, NULL, szLinkData, (DWORD)nLength))
-        nError = GetLastError();
-
-    FileStream_Close(pStream);
-    return ERROR_SUCCESS;
-}
+    {_T("MPQ_2013_v4_alternate-original.MPQ"),         NULL, 0},
+    {_T("MPQ_2013_v4_alternate-original.MPQ"),         NULL, STREAM_FLAG_READ_ONLY},
+    {_T("MPQ_2013_v4_alternate-complete.MPQ"),         NULL, STREAM_FLAG_USE_BITMAP},
+    {_T("part-file://MPQ_2009_v2_WoW_patch.MPQ.part"), NULL, 0},
+    {_T("blk4-file://streaming/model.MPQ.0"),          NULL, STREAM_PROVIDER_BLOCK4},
+    {_T("mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE"),  NULL, STREAM_PROVIDER_MPQE}
+};
 
-static int ForEachFile_CreateArchiveLink(LPCTSTR szFullPath1, LPCTSTR szFullPath2)
+static const TEST_INFO TestList_MasterMirror[] =
 {
-    TLogHelper Logger("CreateMpqLink");
-    TCHAR szFileHash1[0x40];
-    TCHAR szFileHash2[0x40];
-    int nError;
-
-    // Prevent logger from witing any result messages
-    Logger.bDontPrintResult = true;
+    {_T("part-file://MPQ_2009_v1_patch-created.MPQ.part"),  _T("MPQ_2009_v1_patch-original.MPQ"),       0},
+    {_T("part-file://MPQ_2009_v1_patch-partial.MPQ.part"),  _T("MPQ_2009_v1_patch-original.MPQ"),       1},
+    {_T("part-file://MPQ_2009_v1_patch-complete.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"),       1},
+    {_T("MPQ_2013_v4_alternate-created.MPQ"),               _T("MPQ_2013_v4_alternate-original.MPQ"),   0},
+    {_T("MPQ_2013_v4_alternate-incomplete.MPQ"),            _T("MPQ_2013_v4_alternate-incomplete.MPQ"), 1},
+    {_T("MPQ_2013_v4_alternate-complete.MPQ"),              _T("MPQ_2013_v4_alternate-original.MPQ"),   1},
+
+    // Takes hell a lot of time!!!
+//  {_T("MPQ_2013_v4_alternate-downloaded.MPQ"),            _T("http://www.zezula.net\\mpqs\\alternate.zip"), 0}
+};
 
-    // Create SHA1 of both files
-    nError = CalculateFileSha1(&Logger, szFullPath1, szFileHash1);
-    if(nError == ERROR_SUCCESS)
-    {
-        nError = CalculateFileSha1(&Logger, szFullPath2, szFileHash2);
-        if(nError == ERROR_SUCCESS)
-        {
-            // If the hashes are identical, we can create link
-            if(!_tcscmp(szFileHash1, szFileHash2))
-            {
-                nError = CreateArchiveLinkFile(szFullPath1, szFullPath2, szFileHash1);
-                if(nError == ERROR_SUCCESS)
-                {
-                    Logger.PrintMessage("Created link to %s", szFullPath2);
-                }
-            }
-        }
-    }
+static const TEST_INFO Test_Mpqs[] =
+{
+    // Correct or damaged archives
+    {_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"),    NULL, 0, "music\\dintro.wav", "File00000023.xxx"},
+    {_T("MPQ_2016_v1_D2XP_IX86_1xx_114a.mpq"), NULL, 0, "waitingroombkgd.dc6"},                   // Update MPQ from Diablo II (patch 2016)
+    {_T("MPQ_2018_v1_icon_error.w3m"),         NULL, 0, "file00000002.blp"},
+    {_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"),   _T("ListFile_Blizzard.txt")},                      // File whose archive's (signature) file has flags = 0x90000000
+    {_T("MPQ_2012_v2_EmptyMpq.MPQ") },                                                            // Empty archive (found in WoW cache - it's just a header)
+    {_T("MPQ_2013_v4_EmptyMpq.MPQ") },                                                            // Empty archive (created artificially - it's just a header)
+    {_T("MPQ_2013_v4_patch-base-16357.MPQ") },                                                    // Empty archive (found in WoW cache - it's just a header)
+    {_T("MPQ_2011_v4_InvalidHetEntryCount.MPQ") },                                                // Empty archive (A buggy MPQ with invalid HET entry count)
+    {_T("MPQ_2002_v1_BlockTableCut.MPQ") },                                                       // Truncated archive
+    {_T("MPQ_2010_v2_HasUserData.s2ma") },                                                        // MPQ that actually has user data
+    {_T("MPQ_2014_v1_AttributesOneEntryLess.w3x") },                                              // Warcraft III map whose "(attributes)" file has (BlockTableSize-1) entries
+    {_T("MPQ_2020_v1_AHF04patch.mix") },                                                          // MIX file
+    {_T("MPQ_2010_v3_expansion-locale-frFR.MPQ") },                                               // MPQ archive v 3.0
+    {_T("mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE") },                                           // Encrypted archive from Starcraft II installer
+    {_T("MPx_2013_v1_LongwuOnline.mpk") },                                                        // MPK archive from Longwu online
+    {_T("MPx_2013_v1_WarOfTheImmortals.sqp"), _T("ListFile_WarOfTheImmortals.txt") },             // SQP archive from War of the Immortals
+    {_T("part-file://MPQ_2010_v2_HashTableCompressed.MPQ.part") },                                // Partial MPQ with compressed hash table
+    {_T("blk4-file://streaming/model.MPQ.0")},                                                      // Archive that is merged with multiple files
+    {_T("MPQ_2002_v1_ProtectedMap_InvalidUserData.w3x")},
+    {_T("MPQ_2002_v1_ProtectedMap_InvalidMpqFormat.w3x")},
+    {_T("MPQ_2002_v1_ProtectedMap_Spazzler.w3x")},                                                  // Warcraft III map locked by the Spazzler protector
+    {_T("MPQ_2014_v1_ProtectedMap_Spazzler2.w3x")},                                                 // Warcraft III map locked by the Spazzler protector
+    {_T("MPQ_2014_v1_ProtectedMap_Spazzler3.w3x")},                                                 // Warcraft III map locked by the Spazzler protector
+    {_T("MPQ_2002_v1_ProtectedMap_BOBA.w3m")},                                                      // Warcraft III map locked by the BOBA protector
+    {_T("MPQ_2015_v1_ProtectedMap_KangTooJee.w3x")},
+    {_T("MPQ_2015_v1_ProtectedMap_Somj2hM16.w3x")},
+    {_T("MPQ_2015_v1_ProtectedMap_Spazy.w3x")},                                                     // Warcraft III map locked by Spazy protector
+    {_T("MPQ_2015_v1_MessListFile.mpq")},
+    {_T("MPQ_2016_v1_ProtectedMap_TableSizeOverflow.w3x")},
+    {_T("MPQ_2016_v1_ProtectedMap_HashOffsIsZero.w3x")},
+    {_T("MPQ_2016_v1_ProtectedMap_Somj2.w3x")},                                                     // Something like Somj 2.0
+    {_T("MPQ_2016_v1_WME4_4.w3x")},                                                                 // Protector from China (2016-05-27)
+    {_T("MPQ_2016_v1_SP_(4)Adrenaline.w3x")},
+    {_T("MPQ_2016_v1_ProtectedMap_1.4.w3x")},
+    {_T("MPQ_2016_v1_KoreanFile.w3m")},
+    {_T("MPQ_2017_v1_Eden_RPG_S2_2.5J.w3x")},                                                       // Load map protected by PG1.11.973
+    {_T("MPQ_2017_v1_BigDummyFiles.w3x")},
+    {_T("MPQ_2017_v1_TildeInFileName.mpq")},
+    {_T("MPQ_2018_v1_EWIX_v8_7.w3x"), NULL, 0, "BlueCrystal.mdx"},
+    {_T("MPQ_2020_v4_FakeMpqHeaders.SC2Mod")},                                                      // Archive that has two fake headers before the real one
+    {_T("MPQ_2020_v4_NP_Protect_1.s2ma")},                                                          // SC2 map that is protected by the NP_Protect
+    {_T("MPQ_2020_v4_NP_Protect_2.s2ma")},                                                          // SC2 map that is protected by the NP_Protect
+
+    // Protected archives
+    {_T("MPQ_2015_v1_flem1.w3x"), NULL, TEST_FLAG_PROTECTED | 20, "1c4c13e627658c473e84d94371e31f37"},
+    {_T("MPQ_2002_v1_ProtectedMap_HashTable_FakeValid.w3x"), NULL, TEST_FLAG_PROTECTED | 114, "5250975ed917375fc6540d7be436d4de"},
+};
 
-    return ERROR_SUCCESS;
-}
-*/
 //-----------------------------------------------------------------------------
 // Main
 
 int _tmain(int argc, TCHAR * argv[])
 {
-    int nError = ERROR_SUCCESS;
+    DWORD dwErrCode = ERROR_SUCCESS;
 
 #if defined(_MSC_VER) && defined(_DEBUG)
     _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
@@ -4401,444 +4241,300 @@ int _tmain(int argc, TCHAR * argv[])
 
     // Initialize storage and mix the random number generator
     printf("==== Test Suite for StormLib version %s ====\n", STORMLIB_VERSION_STRING);
-    nError = InitializeMpqDirectory(argv, argc);
+    dwErrCode = InitializeMpqDirectory(argv, argc);
 
-    // Not a test, but rather a tool for creating links to duplicated files
-//  if(nError == ERROR_SUCCESS)
-//      nError = FindFilePairs(ForEachFile_CreateArchiveLink, "2004 - WoW\\06080", "2004 - WoW\\06299");
-/*
-    // Search all testing archives and verify their SHA1 hash
-    if(nError == ERROR_SUCCESS)
-        nError = FindFiles(ForEachFile_VerifyFileChecksum, szMpqSubDir);
-
-    // Test sparse compression
-    if(nError == ERROR_SUCCESS)
-        nError = TestSparseCompression();
-
-    // Test reading linear file without bitmap
-    if(nError == ERROR_SUCCESS)
-        nError = TestFileStreamOperations(_T("MPQ_2013_v4_alternate-original.MPQ"), 0);
-
-    // Test reading linear file without bitmap (read only)
-    if(nError == ERROR_SUCCESS)
-        nError = TestFileStreamOperations(_T("MPQ_2013_v4_alternate-original.MPQ"), STREAM_FLAG_READ_ONLY);
-
-    // Test reading linear file with bitmap
-    if(nError == ERROR_SUCCESS)
-        nError = TestFileStreamOperations(_T("MPQ_2013_v4_alternate-complete.MPQ"), STREAM_FLAG_USE_BITMAP);
-
-    // Test reading partial file
-    if(nError == ERROR_SUCCESS)
-        nError = TestFileStreamOperations(_T("part-file://MPQ_2009_v2_WoW_patch.MPQ.part"), 0);
-
-    // Test reading Block4K file
-    if(nError == ERROR_SUCCESS)
-        nError = TestFileStreamOperations(_T("blk4-file://streaming/model.MPQ.0"), STREAM_PROVIDER_BLOCK4);
-
-    // Test reading encrypted file
-    if(nError == ERROR_SUCCESS)
-        nError = TestFileStreamOperations(_T("mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE"), STREAM_PROVIDER_MPQE);
-
-    // Open a stream, paired with local master. The mirror file is created new
-    if(nError == ERROR_SUCCESS)
-        nError = TestReadFile_MasterMirror(_T("part-file://MPQ_2009_v1_patch-created.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), false);
-
-    // Open a stream, paired with local master. Only part of the mirror exists
-    if(nError == ERROR_SUCCESS)
-        nError = TestReadFile_MasterMirror(_T("part-file://MPQ_2009_v1_patch-partial.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), true);
-
-    // Open a stream, paired with local master. Only part of the mirror exists
-    if(nError == ERROR_SUCCESS)
-        nError = TestReadFile_MasterMirror(_T("part-file://MPQ_2009_v1_patch-complete.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), true);
-
-    // Open a stream, paired with local master
-    if(nError == ERROR_SUCCESS)
-        nError = TestReadFile_MasterMirror(_T("MPQ_2013_v4_alternate-created.MPQ"), _T("MPQ_2013_v4_alternate-original.MPQ"), false);
-
-    // Open a stream, paired with local master
-    if(nError == ERROR_SUCCESS)
-        nError = TestReadFile_MasterMirror(_T("MPQ_2013_v4_alternate-incomplete.MPQ"), _T("MPQ_2013_v4_alternate-incomplete.MPQ"), true);
-
-    // Open a stream, paired with local master
-    if(nError == ERROR_SUCCESS)
-        nError = TestReadFile_MasterMirror(_T("MPQ_2013_v4_alternate-complete.MPQ"), _T("MPQ_2013_v4_alternate-original.MPQ"), true);
-
-    // Open a stream, paired with remote master (takes hell lot of time!!!)
-    if(nError == ERROR_SUCCESS)
-        nError = TestReadFile_MasterMirror(_T("MPQ_2013_v4_alternate-downloaded.MPQ"), _T("http://www.zezula.net\\mpqs\\alternate.zip"), false);
-
-    // Search in listfile
-    if(nError == ERROR_SUCCESS)
-        nError = TestSearchListFile(_T("ListFile_Blizzard.txt"));
-
-    // Test opening local file with SFileOpenFileEx
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenLocalFile(_T("ListFile_Blizzard.txt"));
-
-    // Test working with an archive that has no listfile
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenFile_OpenById(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"));
-
-    // Open the update MPQ from Diablo II (patch 2016)
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenFile_OpenByName(_T("MPQ_2016_v1_D2XP_IX86_1xx_114a.mpq"), "waitingroombkgd.dc6");
-*/
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenFile_OpenByName(_T("MPQ_2018_v1_icon_error.w3m"), "file00000002.blp");
-/*
-    // Open a file whose archive's (signature) file has flags = 0x90000000
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), _T("ListFile_Blizzard.txt"));
-
-    // Test the SFileSetFilePointer operations
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_SetPos(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), "music\\dtowne.wav");
-
-    // Open an empty archive (found in WoW cache - it's just a header)
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2012_v2_EmptyMpq.MPQ"));
-
-    // Open an empty archive (created artificially - it's just a header)
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2013_v4_EmptyMpq.MPQ"));
-
-    // Open an empty archive (found in WoW cache - it's just a header)
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2013_v4_patch-base-16357.MPQ"));
-
-    // Open an empty archive (A buggy MPQ with invalid HET entry count)
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2011_v4_InvalidHetEntryCount.MPQ"));
-
-    // Open a truncated archive
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2002_v1_BlockTableCut.MPQ"));
-
-    // Open a MPQ that actually has user data
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2010_v2_HasUserData.s2ma"));
-
-    // Open a file whose archive's (signature) file has flags = 0x90000000
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), _T("ListFile_Blizzard.txt"));
-
-    // Open an Warcraft III map whose "(attributes)" file has (BlockTableSize-1) entries
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2014_v1_AttributesOneEntryLess.w3x"));
-
-    // Open a MPQ archive v 3.0
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2010_v3_expansion-locale-frFR.MPQ"));
-
-    // Open an encrypted archive from Starcraft II installer
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE"));
-
-    // Open a MPK archive from Longwu online
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPx_2013_v1_LongwuOnline.mpk"));
-
-    // Open a SQP archive from War of the Immortals
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPx_2013_v1_WarOfTheImmortals.sqp"), _T("ListFile_WarOfTheImmortals.txt"));
-
-    // Open a partial MPQ with compressed hash table
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("part-file://MPQ_2010_v2_HashTableCompressed.MPQ.part"));
-  
-    // Open an protected map
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_ProtectedMap(_T("MPQ_2015_v1_flem1.w3x"), NULL, 20, "1c4c13e627658c473e84d94371e31f37");
-
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_ProtectedMap(_T("MPQ_2002_v1_ProtectedMap_HashTable_FakeValid.w3x"), NULL, 114, "5250975ed917375fc6540d7be436d4de");
-
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2002_v1_ProtectedMap_InvalidUserData.w3x"));
-
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2002_v1_ProtectedMap_InvalidMpqFormat.w3x"));
-
-    // Open an Warcraft III map locked by the Spazzler protector
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2002_v1_ProtectedMap_Spazzler.w3x"));
-
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2014_v1_ProtectedMap_Spazzler2.w3x"));
-
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2014_v1_ProtectedMap_Spazzler3.w3x"));
-
-    // Open an Warcraft III map locked by the BOBA protector
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2002_v1_ProtectedMap_BOBA.w3m"));
-
-    // Open an Warcraft III map locked by a protector
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2015_v1_ProtectedMap_KangTooJee.w3x"));
-
-    // Open an Warcraft III map locked by a protector
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2015_v1_ProtectedMap_Somj2hM16.w3x"));
-
-    // Open an Warcraft III map locked by Spazy protector
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2015_v1_ProtectedMap_Spazy.w3x"));
+    //
+    // Tests on a local listfile
+    //
 
-    // Open an Warcraft III map locked by Spazy protector
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2015_v1_MessListFile.mpq"));
+    //if(dwErrCode == ERROR_SUCCESS)
+    //{
+    //    dwErrCode = TestOnLocalListFile(_T("ListFile_Blizzard.txt"));
+    //}
 
-    // Open another protected map
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2016_v1_ProtectedMap_TableSizeOverflow.w3x"));
+    //
+    // Open all files from the command line
+    //
+    /*
+    SFILE_MARKERS Markers = { sizeof(SFILE_MARKERS) };
+    Markers.dwSignature = 'XHSC';
+    Markers.szHashTableKey = "(cash table)";
+    Markers.szBlockTableKey = "(clock table)";
+    SFileSetArchiveMarkers(&Markers);
+    */
 
-    // Open another protected map
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2016_v1_ProtectedMap_HashOffsIsZero.w3x"));
+    for(int i = 1; i < argc; i++)
+    {
+        ForEachFile_OpenArchive(argv[i]);
+    }
 
-    // Something like Somj 2.0
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2016_v1_ProtectedMap_Somj2.w3x"));
+    //
+    // Search all testing archives and verify their SHA1 hash
+    //
 
-    // Protector from China (2016-05-27)
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2016_v1_WME4_4.w3x"));
+    if(dwErrCode == ERROR_SUCCESS)
+    {
+        dwErrCode = FindFiles(ForEachFile_VerifyFileChecksum, szMpqSubDir);
+    }
 
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2016_v1_SP_(4)Adrenaline.w3x"));
+    //
+    // Test file stream operations
+    //
 
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2016_v1_ProtectedMap_1.4.w3x"));
+    if(dwErrCode == ERROR_SUCCESS)
+    {
+        for(size_t i = 0; i < _countof(TestList_StreamOps); i++)
+        {
+            dwErrCode = TestFileStreamOperations(TestList_StreamOps[i].szMpqName1, TestList_StreamOps[i].dwFlags);
+            if(dwErrCode != ERROR_SUCCESS)
+                break;
+        }
+    }
 
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2016_v1_KoreanFile.w3m"));
+    //
+    // Test master-mirror reading operations
+    //
 
-    // Load map protected by PG1.11.973
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2017_v1_Eden_RPG_S2_2.5J.w3x"));
+    if(dwErrCode == ERROR_SUCCESS)
+    {
+        for(size_t i = 0; i < _countof(TestList_MasterMirror); i++)
+        {
+            dwErrCode = TestReadFile_MasterMirror(TestList_MasterMirror[i].szMpqName1,
+                                                  TestList_MasterMirror[i].szMpqName2,
+                                                  TestList_MasterMirror[i].dwFlags != 0);
+            if(dwErrCode != ERROR_SUCCESS)
+                break;
+        }
+    }
 
-    // Load map protected by PG1.11.973
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2017_v1_BigDummyFiles.w3x"), NULL, "1.blp");
+    //
+    // Test opening various archives - correct, damaged, protected
+    //
 
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("MPQ_2017_v1_TildeInFileName.mpq"), NULL, "1.blp");
+    if(dwErrCode == ERROR_SUCCESS)
+    {
+        for(size_t i = 0; i < _countof(Test_Mpqs); i++)
+        {
+            dwErrCode = TestArchive(Test_Mpqs[i].szMpqName1,         // Plain archive name
+                                    Test_Mpqs[i].szMpqName2,         // List file (NULL if none)
+                                    Test_Mpqs[i].dwFlags,            // What exactly to do
+                                    Test_Mpqs[i].szFileName1,        // The first name of the open file
+                                    Test_Mpqs[i].szFileName2);       // The second name of the open file
+            if(dwErrCode != ERROR_SUCCESS)
+                break;
+        }
+    }
 
     // Open the multi-file archive with wrong prefix to see how StormLib deals with it
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_WillFail(_T("flat-file://streaming/model.MPQ.0"));
-
-    // Open an archive that is merged with multiple files
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive(_T("blk4-file://streaming/model.MPQ.0"), NULL, NULL, true);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_WillFail(_T("flat-file://streaming/model.MPQ.0"));
 
     // Open every MPQ that we have in the storage
-    if(nError == ERROR_SUCCESS)
-        nError = FindFiles(ForEachFile_OpenArchive, NULL);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = FindFiles(ForEachFile_OpenArchive, NULL);
 
     // Test on an archive that has been invalidated by extending an old valid MPQ
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_Corrupt(_T("MPQ_2013_vX_Battle.net.MPQ"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_Corrupt(_T("MPQ_2013_vX_Battle.net.MPQ"));
 
     // Open a patched archive
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_Patched(PatchList_StarCraft, "music\\terran1.wav", 0);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_Patched(PatchList_StarCraft, "music\\terran1.wav", 0);
 
     // Open a patched archive
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_Patched(PatchList_WoW_OldWorld13286, "OldWorld\\World\\Model.blob", 2);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_Patched(PatchList_WoW_OldWorld13286, "OldWorld\\World\\Model.blob", 2);
 
     // Open a patched archive
-    if(nError == ERROR_SUCCESS)                               
-        nError = TestOpenArchive_Patched(PatchList_WoW_15050, "World\\Model.blob", 8);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_Patched(PatchList_WoW_15050, "World\\Model.blob", 8);
 
     // Open a patched archive
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_Patched(PatchList_WoW_16965, "DBFilesClient\\BattlePetNPCTeamMember.db2", 0);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_Patched(PatchList_WoW_16965, "DBFilesClient\\BattlePetNPCTeamMember.db2", 0);
 
     // Open a patched archive
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_Patched(PatchList_SC2_32283, "TriggerLibs\\natives.galaxy", 6);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_Patched(PatchList_SC2_32283, "TriggerLibs\\natives.galaxy", 6);
 
     // Open a patched archive
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_Patched(PatchList_SC2_34644, "TriggerLibs\\GameData\\GameData.galaxy", 2);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_Patched(PatchList_SC2_34644, "TriggerLibs\\GameData\\GameData.galaxy", 2);
 
     // Open a patched archive with new format of BSDIFF patch
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_Patched(PatchList_SC2_34644_Maps, "Maps\\Campaign\\THorner03.SC2Map\\BankList.xml", 3);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_Patched(PatchList_SC2_34644_Maps, "Maps\\Campaign\\THorner03.SC2Map\\BankList.xml", 3);
 
     // Open a patched archive
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_Patched(PatchList_SC2_32283_enGB, "LocalizedData\\GameHotkeys.txt", 0, true);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_Patched(PatchList_SC2_32283_enGB, "Assets\\Textures\\startupimage.dds", 0, true);
 
     // Open a patched archive where the "StreamingBuckets.txt" in the patch doesn't contain MPQ_FILE_PATCH_FILE
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_Patched(PatchList_SC2_36281_enGB, "LocalizedData\\GameHotkeys.txt", 6);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_Patched(PatchList_SC2_36281_enGB, "LocalizedData\\GameHotkeys.txt", 6);
 
     // Open a patched archive
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_Patched(PatchList_HS_3604_enGB, "Hearthstone.exe", 1);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_Patched(PatchList_HS_3604_enGB, "Hearthstone.exe", 1);
 
     // Open a patched archive
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_Patched(PatchList_HS_6898_enGB, "Hearthstone_Data\\Managed\\Assembly-Csharp.dll", 10);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_Patched(PatchList_HS_6898_enGB, "Hearthstone_Data\\Managed\\Assembly-Csharp.dll", 10);
 
     // Check the opening archive for read-only
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_ReadOnly(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), true);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_ReadOnly(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), true);
 
     // Check the opening archive for read-only
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_ReadOnly(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), false);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_ReadOnly(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), false);
 
     // Check the SFileGetFileInfo function
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_GetFileInfo(_T("MPQ_2002_v1_StrongSignature.w3m"), _T("MPQ_2013_v4_SC2_EmptyMap.SC2Map"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_GetFileInfo(_T("MPQ_2002_v1_StrongSignature.w3m"), _T("MPQ_2013_v4_SC2_EmptyMap.SC2Map"));
 
     // Downloadable MPQ archive
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_MasterMirror(_T("part-file://MPQ_2009_v1_patch-partial.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), "world\\Azeroth\\DEADMINES\\PASSIVEDOODADS\\GOBLINMELTINGPOT\\DUST2.BLP", false);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_MasterMirror(_T("part-file://MPQ_2009_v1_patch-partial.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), "world\\Azeroth\\DEADMINES\\PASSIVEDOODADS\\GOBLINMELTINGPOT\\DUST2.BLP", false);
 
     // Downloadable MPQ archive
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_MasterMirror(_T("MPQ_2013_v4_alternate-downloaded.MPQ"), _T("MPQ_2013_v4_alternate-original.MPQ"), "alternate\\DUNGEONS\\TEXTURES\\ICECROWN\\GATE\\jlo_IceC_Floor_Thrown.blp", false);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_MasterMirror(_T("MPQ_2013_v4_alternate-downloaded.MPQ"), _T("MPQ_2013_v4_alternate-original.MPQ"), "alternate\\DUNGEONS\\TEXTURES\\ICECROWN\\GATE\\jlo_IceC_Floor_Thrown.blp", false);
 
     // Check archive signature
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_VerifySignature(_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), _T("STANDARD.SNP"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_VerifySignature(_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), _T("STANDARD.SNP"));
 
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_VerifySignature(_T("MPQ_1999_v1_WeakSignature.exe"), _T("War2Patch_202.exe"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_VerifySignature(_T("MPQ_1999_v1_WeakSignature.exe"), _T("War2Patch_202.exe"));
 
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_VerifySignature(_T("MPQ_2003_v1_WeakSignatureEmpty.exe"), _T("WoW-1.2.3.4211-enUS-patch.exe"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_VerifySignature(_T("MPQ_2003_v1_WeakSignatureEmpty.exe"), _T("WoW-1.2.3.4211-enUS-patch.exe"));
 
     // Check archive signature
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_VerifySignature(_T("MPQ_2002_v1_StrongSignature.w3m"), _T("(10)DustwallowKeys.w3m"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_VerifySignature(_T("MPQ_2002_v1_StrongSignature.w3m"), _T("(10)DustwallowKeys.w3m"));
 
     // Compact the archive
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_CompactArchive(_T("MPQ_2010_v3_expansion-locale-frFR.MPQ"), _T("StormLibTest_CraftedMpq1_v3.mpq"), true);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_CompactArchive(_T("MPQ_2010_v3_expansion-locale-frFR.MPQ"), _T("StormLibTest_CraftedMpq1_v3.mpq"), true);
 
     // Compact the archive
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_CompactArchive(_T("MPQ_2016_v1_00000.pak"), _T("MPQ_2016_v1_00000.pak"), false);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_CompactArchive(_T("MPQ_2016_v1_00000.pak"), _T("MPQ_2016_v1_00000.pak"), false);
 
     // Open a MPQ (add custom user data to it)
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_CompactArchive(_T("MPQ_2013_v4_SC2_EmptyMap.SC2Map"), _T("StormLibTest_CraftedMpq2_v4.mpq"), true);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_CompactArchive(_T("MPQ_2013_v4_SC2_EmptyMap.SC2Map"), _T("StormLibTest_CraftedMpq2_v4.mpq"), true);
 
     // Open a MPQ (add custom user data to it)
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_CompactArchive(_T("MPQ_2013_v4_expansion1.MPQ"), _T("StormLibTest_CraftedMpq3_v4.mpq"), true);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_CompactArchive(_T("MPQ_2013_v4_expansion1.MPQ"), _T("StormLibTest_CraftedMpq3_v4.mpq"), true);
 
-    if(nError == ERROR_SUCCESS)
-        nError = TestAddFile_FullTable(_T("MPQ_2014_v1_out1.w3x"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestAddFile_FullTable(_T("MPQ_2014_v1_out1.w3x"));
 
-    if(nError == ERROR_SUCCESS)
-        nError = TestAddFile_FullTable(_T("MPQ_2014_v1_out2.w3x"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestAddFile_FullTable(_T("MPQ_2014_v1_out2.w3x"));
 
     // Test modifying file with no (listfile) and no (attributes)
-    if(nError == ERROR_SUCCESS)
-        nError = TestAddFile_ListFileTest(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), false, false);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestAddFile_ListFileTest(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), false, false);
 
     // Test modifying an archive that contains (listfile) and (attributes)
-    if(nError == ERROR_SUCCESS)
-        nError = TestAddFile_ListFileTest(_T("MPQ_2013_v4_SC2_EmptyMap.SC2Map"), true, true);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestAddFile_ListFileTest(_T("MPQ_2013_v4_SC2_EmptyMap.SC2Map"), true, true);
 
     // Create an empty archive v2
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_EmptyMpq(_T("StormLibTest_EmptyMpq_v2.mpq"), MPQ_CREATE_ARCHIVE_V2 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_EmptyMpq(_T("StormLibTest_EmptyMpq_v2.mpq"), MPQ_CREATE_ARCHIVE_V2 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES);
 
     // Create an empty archive v4
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_EmptyMpq(_T("StormLibTest_EmptyMpq_v4.mpq"), MPQ_CREATE_ARCHIVE_V4 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_EmptyMpq(_T("StormLibTest_EmptyMpq_v4.mpq"), MPQ_CREATE_ARCHIVE_V4 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES);
 
     // Test creating of an archive the same way like MPQ Editor does
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_TestGaps(_T("StormLibTest_GapsTest.mpq"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_TestGaps(_T("StormLibTest_GapsTest.mpq"));
 
     // Test creating of an archive with non standard file names
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_NonStdNames(_T("StormLibTest_NonStdNames.mpq"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_NonStdNames(_T("StormLibTest_NonStdNames.mpq"));
 
     // Sign an existing non-signed archive
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_SignExisting(_T("MPQ_1998_v1_StarDat.mpq"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_SignExisting(_T("MPQ_1998_v1_StarDat.mpq"));
 
     // Open a signed archive, add a file and verify the signature
-    if(nError == ERROR_SUCCESS)
-        nError = TestOpenArchive_ModifySigned(_T("MPQ_1999_v1_WeakSignature.exe"), _T("War2Patch_202.exe"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestOpenArchive_ModifySigned(_T("MPQ_1999_v1_WeakSignature.exe"), _T("War2Patch_202.exe"));
 
     // Create new archive and sign it
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_Signed(_T("MPQ_1999_v1_WeakSigned1.mpq"), true);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_Signed(_T("MPQ_1999_v1_WeakSigned1.mpq"), true);
 
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_Signed(_T("MPQ_1999_v1_WeakSigned2.mpq"), false);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_Signed(_T("MPQ_1999_v1_WeakSigned2.mpq"), false);
 
     // Test creating of an archive the same way like MPQ Editor does
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_MpqEditor(_T("StormLibTest_MpqEditorTest.mpq"), "AddedFile.exe");
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_MpqEditor(_T("StormLibTest_MpqEditorTest.mpq"), "AddedFile.exe");
 
     // Create an archive and fill it with files up to the max file count
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), 0);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), 0);
 
     // Create an archive and fill it with files up to the max file count
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), MPQ_CREATE_LISTFILE);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), MPQ_CREATE_LISTFILE);
 
     // Create an archive and fill it with files up to the max file count
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), MPQ_CREATE_ATTRIBUTES);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), MPQ_CREATE_ATTRIBUTES);
 
     // Create an archive and fill it with files up to the max file count
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), MPQ_CREATE_ATTRIBUTES | MPQ_CREATE_LISTFILE);
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), MPQ_CREATE_ATTRIBUTES | MPQ_CREATE_LISTFILE);
 
     // Create an archive, and increment max file count several times
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_IncMaxFileCount(_T("StormLibTest_IncMaxFileCount.mpq"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_IncMaxFileCount(_T("StormLibTest_IncMaxFileCount.mpq"));
 
     // Create a MPQ archive with UNICODE names
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_UnicodeNames();
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_UnicodeNames();
 
     // Create a MPQ file, add files with various flags
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_FileFlagTest(_T("StormLibTest_FileFlagTest.mpq"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_FileFlagTest(_T("StormLibTest_FileFlagTest.mpq"));
 
     // Create a MPQ file, add a mono-WAVE file with various compressions
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_WaveCompressionsTest(_T("StormLibTest_AddWaveMonoTest.mpq"), _T("AddFile-Mono.wav"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_WaveCompressionsTest(_T("StormLibTest_AddWaveMonoTest.mpq"), _T("AddFile-Mono.wav"));
 
     // Create a MPQ file, add a mono-WAVE with 8 bits per sample file with various compressions
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_WaveCompressionsTest(_T("StormLibTest_AddWaveMonoBadTest.mpq"), _T("AddFile-MonoBad.wav"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_WaveCompressionsTest(_T("StormLibTest_AddWaveMonoBadTest.mpq"), _T("AddFile-MonoBad.wav"));
 
     // Create a MPQ file, add a stereo-WAVE file with various compressions
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_WaveCompressionsTest(_T("StormLibTest_AddWaveStereoTest.mpq"), _T("AddFile-Stereo.wav"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_WaveCompressionsTest(_T("StormLibTest_AddWaveStereoTest.mpq"), _T("AddFile-Stereo.wav"));
 
     // Check if the listfile is always created at the end of the file table in the archive
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_ListFilePos(_T("StormLibTest_ListFilePos.mpq"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_ListFilePos(_T("StormLibTest_ListFilePos.mpq"));
 
     // Open a MPQ (add custom user data to it)
-    if(nError == ERROR_SUCCESS)
-        nError = TestCreateArchive_BigArchive(_T("StormLibTest_BigArchive_v4.mpq"));
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestCreateArchive_BigArchive(_T("StormLibTest_BigArchive_v4.mpq"));
 
     // Test replacing a file with zero size file
-    if(nError == ERROR_SUCCESS)
-        nError = TestModifyArchive_ReplaceFile(_T("MPQ_2014_v4_Base.StormReplay"), _T("AddFile-replay.message.events"));
-*/
+    if(dwErrCode == ERROR_SUCCESS)
+        dwErrCode = TestModifyArchive_ReplaceFile(_T("MPQ_2014_v4_Base.StormReplay"), _T("AddFile-replay.message.events"));
+
 #ifdef _MSC_VER
     _CrtDumpMemoryLeaks();
 #endif  // _MSC_VER
 
-    return nError;
+    return dwErrCode;
 }
diff --git a/OpenSource/StormLib/test/TLogHelper.cpp b/OpenSource/StormLib/test/TLogHelper.cpp
index 585ceee0d..003b0f532 100644
--- a/OpenSource/StormLib/test/TLogHelper.cpp
+++ b/OpenSource/StormLib/test/TLogHelper.cpp
@@ -30,11 +30,11 @@ class TLogHelper
 #endif  // defined(UNICODE) || defined(UNICODE)
 
     // ANSI functions
-    int  PrintWithClreol(const char * szFormat, va_list argList, bool bPrintPrefix, bool bPrintLastError, bool bPrintEndOfLine);
-    void PrintProgress(const char * szFormat, ...);
-    void PrintMessage(const char * szFormat, ...);
-    int  PrintErrorVa(const char * szFormat, ...);
-    int  PrintError(const char * szFormat, const char * szFileName = NULL);
+    DWORD PrintWithClreol(const char * szFormat, va_list argList, bool bPrintPrefix, bool bPrintLastError, bool bPrintEndOfLine);
+    void  PrintProgress(const char * szFormat, ...);
+    void  PrintMessage(const char * szFormat, ...);
+    DWORD PrintErrorVa(const char * szFormat, ...);
+    DWORD PrintError(const char * szFormat, const char * szFileName = NULL);
 
     const char * UserString;
     unsigned int UserCount;
@@ -45,7 +45,7 @@ class TLogHelper
 
 #if defined(UNICODE) || defined(UNICODE)
     TCHAR * CopyFormatCharacter(TCHAR * szBuffer, const TCHAR *& szFormat);
-#endif    
+#endif
     char * CopyFormatCharacter(char * szBuffer, const char *& szFormat);
     int  GetConsoleWidth();
 
@@ -73,7 +73,7 @@ class TLogHelper
 
 //-----------------------------------------------------------------------------
 // Constructor and destructor
-    
+
 
 TLogHelper::TLogHelper(const char * szNewMainTitle, const TCHAR * szNewSubTitle1, const TCHAR * szNewSubTitle2)
 {
@@ -140,7 +140,7 @@ TLogHelper::~TLogHelper()
 #if defined(_MSC_VER) && defined(_DEBUG)
     if(_CrtDumpMemoryLeaks())
     {
-        PrintMessage("Memory leak detected after %s\n.", szSaveMainTitle);
+        PrintMessage(_T("Memory leak(s) detected after %s.\n"), szSaveMainTitle);
     }
 #endif  // _MSC_VER
 }
@@ -168,7 +168,7 @@ int TLogHelper::PrintWithClreol(const TCHAR * szFormat, va_list argList, bool bP
     {
         while(szMainTitle[nLength] != 0)
             *szBuffer++ = szMainTitle[nLength++];
-        
+
         *szBuffer++ = ':';
         *szBuffer++ = ' ';
     }
@@ -257,7 +257,7 @@ int TLogHelper::PrintError(const TCHAR * szFormat, const TCHAR * szFileName)
 //-----------------------------------------------------------------------------
 // ANSI functions
 
-int TLogHelper::PrintWithClreol(const char * szFormat, va_list argList, bool bPrintPrefix, bool bPrintLastError, bool bPrintEndOfLine)
+DWORD TLogHelper::PrintWithClreol(const char * szFormat, va_list argList, bool bPrintPrefix, bool bPrintLastError, bool bPrintEndOfLine)
 {
     char szFormatBuff[0x200];
     char szMessage[0x200];
@@ -265,7 +265,7 @@ int TLogHelper::PrintWithClreol(const char * szFormat, va_list argList, bool bPr
     int nRemainingWidth;
     int nConsoleWidth = GetConsoleWidth();
     int nLength = 0;
-    int nError = GetLastError();
+    DWORD dwErrCode = GetLastError();
 
     // Always start the buffer with '\r'
     *szBuffer++ = '\r';
@@ -275,7 +275,7 @@ int TLogHelper::PrintWithClreol(const char * szFormat, va_list argList, bool bPr
     {
         while(szMainTitle[nLength] != 0)
             *szBuffer++ = (char)szMainTitle[nLength++];
-        
+
         *szBuffer++ = ':';
         *szBuffer++ = ' ';
     }
@@ -292,7 +292,7 @@ int TLogHelper::PrintWithClreol(const char * szFormat, va_list argList, bool bPr
     // Append the last error
     if(bPrintLastError)
     {
-        nLength = sprintf(szBuffer, " (error code: %u)", nError);
+        nLength = sprintf(szBuffer, " (error code: %u)", dwErrCode);
         szBuffer += nLength;
     }
 
@@ -322,7 +322,7 @@ int TLogHelper::PrintWithClreol(const char * szFormat, va_list argList, bool bPr
 
     // Spit out the text in one single printf
     printf("%s", szMessage);
-    return nError;
+    return dwErrCode;
 }
 
 void TLogHelper::PrintProgress(const char * szFormat, ...)
@@ -343,19 +343,19 @@ void TLogHelper::PrintMessage(const char * szFormat, ...)
     va_end(argList);
 }
 
-int TLogHelper::PrintErrorVa(const char * szFormat, ...)
+DWORD TLogHelper::PrintErrorVa(const char * szFormat, ...)
 {
     va_list argList;
-    int nResult;
+    DWORD dwErrCode;
 
     va_start(argList, szFormat);
-    nResult = PrintWithClreol(szFormat, argList, true, true, true);
+    dwErrCode = PrintWithClreol(szFormat, argList, true, true, true);
     va_end(argList);
 
-    return nResult;
+    return dwErrCode;
 }
 
-int TLogHelper::PrintError(const char * szFormat, const char * szFileName)
+DWORD TLogHelper::PrintError(const char * szFormat, const char * szFileName)
 {
     return PrintErrorVa(szFormat, szFileName);
 }
@@ -425,7 +425,7 @@ char * TLogHelper::CopyFormatCharacter(char * szBuffer, const char *& szFormat)
 
 int TLogHelper::GetConsoleWidth()
 {
-#ifdef PLATFORM_WINDOWS
+#ifdef STORMLIB_WINDOWS
 
     CONSOLE_SCREEN_BUFFER_INFO ScreenInfo;
     GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ScreenInfo);