stormlib 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CMakeCCompiler.cmake +72 -0
- data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CMakeCXXCompiler.cmake +83 -0
- data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CMakeDetermineCompilerABI_C.bin +0 -0
- data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CMakeDetermineCompilerABI_CXX.bin +0 -0
- data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CMakeSystem.cmake +15 -0
- data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CompilerIdC/CMakeCCompilerId.c +803 -0
- data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CompilerIdC/a.out +0 -0
- data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CompilerIdCXX/CMakeCXXCompilerId.cpp +791 -0
- data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CompilerIdCXX/a.out +0 -0
- data/ext/stormlib/StormLib/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
- data/ext/stormlib/StormLib/CMakeFiles/CMakeOutput.log +478 -0
- data/ext/stormlib/StormLib/CMakeFiles/Export/share/StormLib/StormLibConfig-noconfig.cmake +19 -0
- data/ext/stormlib/StormLib/CMakeFiles/Export/share/StormLib/StormLibConfig.cmake +99 -0
- data/ext/stormlib/StormLib/CMakeFiles/Makefile.cmake +61 -0
- data/ext/stormlib/StormLib/CMakeFiles/Makefile2 +112 -0
- data/ext/stormlib/StormLib/CMakeFiles/TargetDirectories.txt +9 -0
- data/ext/stormlib/StormLib/CMakeFiles/cmake.check_cache +1 -0
- data/ext/stormlib/StormLib/CMakeFiles/progress.marks +1 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/DependInfo.cmake +243 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/build.make +3695 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/cmake_clean.cmake +459 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/cmake_clean_target.cmake +3 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/compiler_depend.make +2 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/compiler_depend.ts +2 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/depend.make +2 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/flags.make +17 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/link.txt +2 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/progress.make +227 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/FileStream.cpp.o.d +160 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SBaseCommon.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SBaseDumpData.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SBaseFileTable.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SBaseSubTypes.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SCompression.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileAddFile.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileAttributes.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileCompactArchive.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileCreateArchive.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileExtractFile.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileFindFile.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileGetFileInfo.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileListFile.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileOpenArchive.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileOpenFileEx.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFilePatchArchives.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileReadFile.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileVerify.cpp.o.d +159 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/adpcm/adpcm.cpp.o.d +12 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/huffman/huff.cpp.o.d +16 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/jenkins/lookup3.c.o.d +88 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/hashes/hash_memory.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/hashes/md5.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/hashes/sha1.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/hashes/sha256.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/math/ltm_desc.c.o.d +105 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/math/multi.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/math/rand_prime.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/base64_decode.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_argchk.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_find_hash.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_find_prng.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_hash_descriptor.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_hash_is_valid.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_libc.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_prng_descriptor.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_prng_is_valid.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_register_hash.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_register_prng.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/zeromem.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_boolean.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_choice.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_integer.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_utctime.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_bit_string.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_boolean.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_ia5_string.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_integer.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_object_identifier.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_octet_string.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_printable_string.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_sequence_ex.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_sequence_multi.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_set.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_setof.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_short_integer.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_utctime.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_utf8_string.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_bit_string.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_boolean.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_integer.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_octet_string.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_printable_string.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_sequence.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_short_integer.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_utctime.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_sequence_free.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_encode.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_encode.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/rsa/rsa_exptmod.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/rsa/rsa_free.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/rsa/rsa_import.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/rsa/rsa_make_key.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/rsa/rsa_sign_hash.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c.o.d +102 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_fast_mp_invmod.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_fast_mp_montgomery_reduce.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_fast_s_mp_mul_digs.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_fast_s_mp_mul_high_digs.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_fast_s_mp_sqr.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_2expt.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_abs.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_add.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_add_d.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_addmod.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_and.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_clamp.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_clear.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_clear_multi.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_cmp.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_cmp_d.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_cmp_mag.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_cnt_lsb.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_copy.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_count_bits.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_div.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_div_2.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_div_2d.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_div_3.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_div_d.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_dr_is_modulus.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_dr_reduce.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_dr_setup.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_exch.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_expt_d.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_exptmod.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_exptmod_fast.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_exteuclid.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_fread.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_fwrite.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_gcd.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_get_int.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_grow.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_init.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_init_copy.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_init_multi.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_init_set.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_init_set_int.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_init_size.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_invmod.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_invmod_slow.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_is_square.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_jacobi.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_karatsuba_mul.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_karatsuba_sqr.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_lcm.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_lshd.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_mod.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_mod_2d.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_mod_d.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_montgomery_calc_normalization.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_montgomery_reduce.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_montgomery_setup.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_mul.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_mul_2.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_mul_2d.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_mul_d.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_mulmod.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_n_root.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_neg.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_or.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_prime_fermat.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_prime_is_divisible.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_prime_is_prime.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_prime_miller_rabin.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_prime_next_prime.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_prime_rabin_miller_trials.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_prime_random_ex.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_radix_size.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_radix_smap.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_rand.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_read_radix.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_read_signed_bin.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_read_unsigned_bin.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_reduce.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_reduce_2k.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_reduce_2k_l.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_reduce_2k_setup.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_reduce_2k_setup_l.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_reduce_is_2k.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_reduce_is_2k_l.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_reduce_setup.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_rshd.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_set.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_set_int.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_shrink.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_signed_bin_size.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_sqr.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_sqrmod.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_sqrt.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_sub.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_sub_d.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_submod.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_to_signed_bin.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_to_signed_bin_n.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_to_unsigned_bin.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_to_unsigned_bin_n.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_toom_mul.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_toom_sqr.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_toradix.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_toradix_n.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_unsigned_bin_size.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_xor.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_zero.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_prime_tab.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_reverse.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_s_mp_add.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_s_mp_exptmod.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_s_mp_mul_digs.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_s_mp_mul_high_digs.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_s_mp_sqr.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_s_mp_sub.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bncore.c.o.d +65 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/lzma/C/LzFind.c.o.d +18 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/lzma/C/LzmaDec.c.o.d +17 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/lzma/C/LzmaEnc.c.o.d +18 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/pklib/explode.c.o.d +16 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/pklib/implode.c.o.d +23 -0
- data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/sparse/sparse.cpp.o.d +16 -0
- data/ext/stormlib/StormLib/CMakeLists.txt +418 -0
- data/ext/stormlib/StormLib/Info.plist +22 -0
- data/ext/stormlib/StormLib/LICENSE +21 -0
- data/ext/stormlib/StormLib/Premake5.lua +132 -0
- data/ext/stormlib/StormLib/README.md +39 -0
- data/ext/stormlib/StormLib/StormLib.sln +162 -0
- data/ext/stormlib/StormLib/StormLib.vcxproj +1024 -0
- data/ext/stormlib/StormLib/StormLib.vcxproj.filters +221 -0
- data/ext/stormlib/StormLib/StormLib.xcodeproj/project.pbxproj +2104 -0
- data/ext/stormlib/StormLib/StormLib_dll.vcxproj +348 -0
- data/ext/stormlib/StormLib/StormLib_dll.vcxproj.filters +229 -0
- data/ext/stormlib/StormLib/StormLib_test.vcxproj +360 -0
- data/ext/stormlib/StormLib/StormLib_test.vcxproj.filters +230 -0
- data/ext/stormlib/StormLib/StormLib_vs08.sln +139 -0
- data/ext/stormlib/StormLib/StormLib_vs08.vcproj +4205 -0
- data/ext/stormlib/StormLib/StormLib_vs08_dll.vcproj +1851 -0
- data/ext/stormlib/StormLib/StormLib_vs08_test.vcproj +1289 -0
- data/ext/stormlib/StormLib/doc/History.txt +78 -0
- data/ext/stormlib/StormLib/doc/The MoPaQ File Format 0.9.txt +318 -0
- data/ext/stormlib/StormLib/doc/The MoPaQ File Format 1.0.txt +433 -0
- data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-deDE.txt +1 -0
- data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-enGB.txt +1 -0
- data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-enSG.txt +1 -0
- data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-enUS.txt +1 -0
- data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-esES.txt +1 -0
- data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-esMX.txt +1 -0
- data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-frFR.txt +1 -0
- data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-itIT.txt +1 -0
- data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-koKR.txt +1 -0
- data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-plPL.txt +1 -0
- data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-ptBR.txt +1 -0
- data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-zhTW.txt +1 -0
- data/ext/stormlib/StormLib/doc/hots-authenticationcode/hots-authenticationcode-bgdl.txt +1 -0
- data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-deDE.txt +1 -0
- data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-enGB.txt +1 -0
- data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-enUS.txt +1 -0
- data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-esES.txt +1 -0
- data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-esMX.txt +1 -0
- data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-frFR.txt +1 -0
- data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-itIT.txt +1 -0
- data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-koKR.txt +1 -0
- data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-plPL.txt +1 -0
- data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-ptBR.txt +1 -0
- data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-ruRU.txt +1 -0
- data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-zhTW.txt +1 -0
- data/ext/stormlib/StormLib/make-msvc.bat +95 -0
- data/ext/stormlib/StormLib/make.bat +46 -0
- data/ext/stormlib/StormLib/sources +14 -0
- data/ext/stormlib/StormLib/src/DllMain.c +24 -0
- data/ext/stormlib/StormLib/src/DllMain.def +79 -0
- data/ext/stormlib/StormLib/src/DllMain.rc +110 -0
- data/ext/stormlib/StormLib/src/FileStream.cpp +2928 -0
- data/ext/stormlib/StormLib/src/FileStream.h +217 -0
- data/ext/stormlib/StormLib/src/LibTomCrypt.c +85 -0
- data/ext/stormlib/StormLib/src/LibTomMath.c +125 -0
- data/ext/stormlib/StormLib/src/LibTomMathDesc.c +4 -0
- data/ext/stormlib/StormLib/src/SBaseCommon.cpp +1970 -0
- data/ext/stormlib/StormLib/src/SBaseDumpData.cpp +183 -0
- data/ext/stormlib/StormLib/src/SBaseFileTable.cpp +3194 -0
- data/ext/stormlib/StormLib/src/SBaseSubTypes.cpp +688 -0
- data/ext/stormlib/StormLib/src/SCompression.cpp +1183 -0
- data/ext/stormlib/StormLib/src/SFileAddFile.cpp +1337 -0
- data/ext/stormlib/StormLib/src/SFileAttributes.cpp +573 -0
- data/ext/stormlib/StormLib/src/SFileCompactArchive.cpp +654 -0
- data/ext/stormlib/StormLib/src/SFileCreateArchive.cpp +285 -0
- data/ext/stormlib/StormLib/src/SFileExtractFile.cpp +64 -0
- data/ext/stormlib/StormLib/src/SFileFindFile.cpp +484 -0
- data/ext/stormlib/StormLib/src/SFileGetFileInfo.cpp +627 -0
- data/ext/stormlib/StormLib/src/SFileListFile.cpp +750 -0
- data/ext/stormlib/StormLib/src/SFileOpenArchive.cpp +723 -0
- data/ext/stormlib/StormLib/src/SFileOpenFileEx.cpp +423 -0
- data/ext/stormlib/StormLib/src/SFilePatchArchives.cpp +1175 -0
- data/ext/stormlib/StormLib/src/SFileReadFile.cpp +922 -0
- data/ext/stormlib/StormLib/src/SFileVerify.cpp +1059 -0
- data/ext/stormlib/StormLib/src/StormCommon.h +450 -0
- data/ext/stormlib/StormLib/src/StormLib.exp +74 -0
- data/ext/stormlib/StormLib/src/StormLib.h +1157 -0
- data/ext/stormlib/StormLib/src/StormPort.h +474 -0
- data/ext/stormlib/StormLib/src/adpcm/adpcm.cpp +539 -0
- data/ext/stormlib/StormLib/src/adpcm/adpcm.h +27 -0
- data/ext/stormlib/StormLib/src/bzip2/blocksort.c +1094 -0
- data/ext/stormlib/StormLib/src/bzip2/bzlib.c +1573 -0
- data/ext/stormlib/StormLib/src/bzip2/bzlib.h +282 -0
- data/ext/stormlib/StormLib/src/bzip2/bzlib_private.h +509 -0
- data/ext/stormlib/StormLib/src/bzip2/compress.c +672 -0
- data/ext/stormlib/StormLib/src/bzip2/crctable.c +104 -0
- data/ext/stormlib/StormLib/src/bzip2/decompress.c +626 -0
- data/ext/stormlib/StormLib/src/bzip2/huffman.c +205 -0
- data/ext/stormlib/StormLib/src/bzip2/randtable.c +84 -0
- data/ext/stormlib/StormLib/src/huffman/huff.cpp +915 -0
- data/ext/stormlib/StormLib/src/huffman/huff.h +143 -0
- data/ext/stormlib/StormLib/src/jenkins/lookup.h +24 -0
- data/ext/stormlib/StormLib/src/jenkins/lookup3.c +1003 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/hashes/hash_memory.c +69 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/hashes/md5.c +368 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/hashes/sha1.c +288 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/hashes/sha256.c +340 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt.h +91 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_argchk.h +38 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h +144 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_cipher.h +891 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_custom.h +424 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_hash.h +378 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_mac.h +384 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_macros.h +424 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_math.h +500 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_misc.h +23 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_pk.h +558 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_pkcs.h +89 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_prng.h +199 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/math/ltm_desc.c +483 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/math/multi.c +61 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/math/rand_prime.c +87 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/base64_decode.c +104 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_argchk.c +30 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_find_hash.c +40 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_find_prng.c +41 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_hash_descriptor.c +27 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_hash_is_valid.c +36 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_libc.c +43 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c +13 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_prng_descriptor.c +26 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_prng_is_valid.c +36 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_register_hash.c +54 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_register_prng.c +54 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/zeromem.c +34 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c +102 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_boolean.c +47 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_choice.c +182 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c +96 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_integer.c +110 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c +99 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c +91 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c +96 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c +287 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c +386 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c +139 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c +68 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utctime.c +127 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c +111 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_bit_string.c +89 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_boolean.c +51 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_ia5_string.c +85 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_integer.c +130 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_object_identifier.c +111 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_octet_string.c +86 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_printable_string.c +85 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_sequence_ex.c +335 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_sequence_multi.c +138 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_set.c +103 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_setof.c +162 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_short_integer.c +97 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_utctime.c +83 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_utf8_string.c +105 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_bit_string.c +54 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_boolean.c +35 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c +194 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_integer.c +82 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c +89 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_octet_string.c +53 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_printable_string.c +166 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_sequence.c +169 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_short_integer.c +70 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utctime.c +46 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c +83 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_sequence_free.c +65 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c +76 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c +207 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c +222 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c +60 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c +196 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c +147 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c +108 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c +189 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c +177 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_encode.c +175 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c +110 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_encode.c +111 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/rsa/rsa_exptmod.c +113 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/rsa/rsa_free.c +34 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/rsa/rsa_import.c +143 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/rsa/rsa_make_key.c +112 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/rsa/rsa_sign_hash.c +134 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c +167 -0
- data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c +87 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_fast_mp_invmod.c +148 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_fast_mp_montgomery_reduce.c +172 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_fast_s_mp_mul_digs.c +107 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_fast_s_mp_mul_high_digs.c +98 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_fast_s_mp_sqr.c +114 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_2expt.c +48 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_abs.c +43 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_add.c +53 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_add_d.c +112 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_addmod.c +41 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_and.c +57 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_clamp.c +44 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_clear.c +44 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_clear_multi.c +34 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_cmp.c +43 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_cmp_d.c +44 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_cmp_mag.c +55 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_cnt_lsb.c +53 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_copy.c +68 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_count_bits.c +45 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_div.c +292 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_div_2.c +68 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_div_2d.c +97 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_div_3.c +79 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_div_d.c +115 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_dr_is_modulus.c +43 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_dr_reduce.c +94 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_dr_setup.c +32 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_exch.c +34 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_expt_d.c +57 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_exptmod.c +112 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_exptmod_fast.c +321 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_exteuclid.c +82 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_fread.c +67 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_fwrite.c +52 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_gcd.c +105 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_get_int.c +45 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_grow.c +57 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_init.c +46 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_init_copy.c +32 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_init_multi.c +59 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_init_set.c +32 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_init_set_int.c +31 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_init_size.c +48 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_invmod.c +43 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_invmod_slow.c +175 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_is_square.c +109 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_jacobi.c +105 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_karatsuba_mul.c +167 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_karatsuba_sqr.c +121 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_lcm.c +60 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_lshd.c +67 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_mod.c +48 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_mod_2d.c +55 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_mod_d.c +27 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_montgomery_calc_normalization.c +59 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_montgomery_reduce.c +118 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_montgomery_setup.c +59 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_mul.c +66 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_mul_2.c +82 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_mul_2d.c +85 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_mul_d.c +79 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_mulmod.c +40 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_n_root.c +132 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_neg.c +40 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_or.c +50 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_prime_fermat.c +62 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_prime_is_divisible.c +50 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_prime_is_prime.c +83 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_prime_miller_rabin.c +103 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_prime_next_prime.c +170 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_prime_rabin_miller_trials.c +52 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_prime_random_ex.c +125 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_radix_size.c +78 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_radix_smap.c +24 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_rand.c +55 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_read_radix.c +85 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_read_signed_bin.c +41 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_read_unsigned_bin.c +55 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_reduce.c +100 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_reduce_2k.c +61 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_reduce_2k_l.c +62 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_reduce_2k_setup.c +47 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_reduce_2k_setup_l.c +44 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_reduce_is_2k.c +52 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_reduce_is_2k_l.c +44 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_reduce_setup.c +34 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_rshd.c +72 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_set.c +29 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_set_int.c +48 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_shrink.c +35 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_signed_bin_size.c +27 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_sqr.c +58 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_sqrmod.c +41 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_sqrt.c +81 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_sub.c +59 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_sub_d.c +93 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_submod.c +42 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_to_signed_bin.c +33 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_to_signed_bin_n.c +31 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_to_unsigned_bin.c +48 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_to_unsigned_bin_n.c +31 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_toom_mul.c +284 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_toom_sqr.c +226 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_toradix.c +75 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_toradix_n.c +88 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_unsigned_bin_size.c +28 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_xor.c +51 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_mp_zero.c +36 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_prime_tab.c +61 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_reverse.c +39 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_s_mp_add.c +109 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_s_mp_exptmod.c +252 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_s_mp_mul_digs.c +90 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_s_mp_mul_high_digs.c +81 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_s_mp_sqr.c +84 -0
- data/ext/stormlib/StormLib/src/libtommath/bn_s_mp_sub.c +89 -0
- data/ext/stormlib/StormLib/src/libtommath/bncore.c +36 -0
- data/ext/stormlib/StormLib/src/libtommath/tommath.h +584 -0
- data/ext/stormlib/StormLib/src/libtommath/tommath_class.h +999 -0
- data/ext/stormlib/StormLib/src/libtommath/tommath_superclass.h +76 -0
- data/ext/stormlib/StormLib/src/lzma/C/LzFind.c +761 -0
- data/ext/stormlib/StormLib/src/lzma/C/LzFind.h +115 -0
- data/ext/stormlib/StormLib/src/lzma/C/LzFindMt.c +793 -0
- data/ext/stormlib/StormLib/src/lzma/C/LzFindMt.h +105 -0
- data/ext/stormlib/StormLib/src/lzma/C/LzHash.h +54 -0
- data/ext/stormlib/StormLib/src/lzma/C/LzmaDec.c +999 -0
- data/ext/stormlib/StormLib/src/lzma/C/LzmaDec.h +231 -0
- data/ext/stormlib/StormLib/src/lzma/C/LzmaEnc.c +2268 -0
- data/ext/stormlib/StormLib/src/lzma/C/LzmaEnc.h +80 -0
- data/ext/stormlib/StormLib/src/lzma/C/Threads.c +84 -0
- data/ext/stormlib/StormLib/src/lzma/C/Threads.h +59 -0
- data/ext/stormlib/StormLib/src/lzma/C/Types.h +236 -0
- data/ext/stormlib/StormLib/src/lzma/info.txt +1 -0
- data/ext/stormlib/StormLib/src/pklib/crc32.c +66 -0
- data/ext/stormlib/StormLib/src/pklib/explode.c +521 -0
- data/ext/stormlib/StormLib/src/pklib/implode.c +674 -0
- data/ext/stormlib/StormLib/src/pklib/pklib.h +160 -0
- data/ext/stormlib/StormLib/src/resource.h +15 -0
- data/ext/stormlib/StormLib/src/sparse/sparse.cpp +287 -0
- data/ext/stormlib/StormLib/src/sparse/sparse.h +17 -0
- data/ext/stormlib/StormLib/src/wdk/sources-cpp.cpp +26 -0
- data/ext/stormlib/StormLib/src/wdk/sources-wdk-bzip2.c +13 -0
- data/ext/stormlib/StormLib/src/wdk/sources-wdk-ltc.c +4 -0
- data/ext/stormlib/StormLib/src/wdk/sources-wdk-lzma.c +8 -0
- data/ext/stormlib/StormLib/src/wdk/sources-wdk-misc.c +6 -0
- data/ext/stormlib/StormLib/src/wdk/sources-wdk-tomcrypt.c +82 -0
- data/ext/stormlib/StormLib/src/wdk/sources-wdk-tommath.c +123 -0
- data/ext/stormlib/StormLib/src/wdk/sources-wdk-zlib.c +21 -0
- data/ext/stormlib/StormLib/src/zlib/adler32.c +169 -0
- data/ext/stormlib/StormLib/src/zlib/compress.c +80 -0
- data/ext/stormlib/StormLib/src/zlib/compress_zlib.c +5 -0
- data/ext/stormlib/StormLib/src/zlib/crc32.c +442 -0
- data/ext/stormlib/StormLib/src/zlib/crc32.h +441 -0
- data/ext/stormlib/StormLib/src/zlib/deflate.c +1834 -0
- data/ext/stormlib/StormLib/src/zlib/deflate.h +342 -0
- data/ext/stormlib/StormLib/src/zlib/gzguts.h +218 -0
- data/ext/stormlib/StormLib/src/zlib/inffast.c +340 -0
- data/ext/stormlib/StormLib/src/zlib/inffast.h +11 -0
- data/ext/stormlib/StormLib/src/zlib/inffixed.h +94 -0
- data/ext/stormlib/StormLib/src/zlib/inflate.c +1480 -0
- data/ext/stormlib/StormLib/src/zlib/inflate.h +130 -0
- data/ext/stormlib/StormLib/src/zlib/inftrees.c +330 -0
- data/ext/stormlib/StormLib/src/zlib/inftrees.h +67 -0
- data/ext/stormlib/StormLib/src/zlib/trees.c +1244 -0
- data/ext/stormlib/StormLib/src/zlib/trees.h +128 -0
- data/ext/stormlib/StormLib/src/zlib/zconf.h +428 -0
- data/ext/stormlib/StormLib/src/zlib/zlib.h +1613 -0
- data/ext/stormlib/StormLib/src/zlib/zutil.c +318 -0
- data/ext/stormlib/StormLib/src/zlib/zutil.h +274 -0
- data/ext/stormlib/StormLib/storm_dll/storm.cpp +117 -0
- data/ext/stormlib/StormLib/storm_dll/storm.def +25 -0
- data/ext/stormlib/StormLib/storm_dll/storm.h +65 -0
- data/ext/stormlib/StormLib/storm_dll/storm.vcxproj +209 -0
- data/ext/stormlib/StormLib/storm_dll/storm.vcxproj.filters +28 -0
- data/ext/stormlib/StormLib/storm_dll/storm_test.cpp +182 -0
- data/ext/stormlib/StormLib/storm_dll/storm_test.vcxproj +202 -0
- data/ext/stormlib/StormLib/storm_dll/storm_test.vcxproj.filters +22 -0
- data/ext/stormlib/StormLib/test/StormTest.cpp +4393 -0
- data/ext/stormlib/StormLib/test/TLogHelper.cpp +567 -0
- data/ext/stormlib/StormLib/test/stormlib-test-001.txt +164 -0
- data/ext/stormlib/extconf.rb +0 -2
- data/lib/stormlib/version.rb +1 -1
- data/stormlib.gemspec +1 -1
- metadata +621 -2
|
@@ -0,0 +1,1970 @@
|
|
|
1
|
+
/*****************************************************************************/
|
|
2
|
+
/* SBaseCommon.cpp Copyright (c) Ladislav Zezula 2003 */
|
|
3
|
+
/*---------------------------------------------------------------------------*/
|
|
4
|
+
/* Common functions for StormLib, used by all SFile*** modules */
|
|
5
|
+
/*---------------------------------------------------------------------------*/
|
|
6
|
+
/* Date Ver Who Comment */
|
|
7
|
+
/* -------- ---- --- ------- */
|
|
8
|
+
/* 24.03.03 1.00 Lad The first version of SFileCommon.cpp */
|
|
9
|
+
/* 19.11.03 1.01 Dan Big endian handling */
|
|
10
|
+
/* 12.06.04 1.01 Lad Renamed to SCommon.cpp */
|
|
11
|
+
/* 06.09.10 1.01 Lad Renamed to SBaseCommon.cpp */
|
|
12
|
+
/*****************************************************************************/
|
|
13
|
+
|
|
14
|
+
#define __STORMLIB_SELF__
|
|
15
|
+
#include "StormLib.h"
|
|
16
|
+
#include "StormCommon.h"
|
|
17
|
+
|
|
18
|
+
char StormLibCopyright[] = "StormLib v " STORMLIB_VERSION_STRING " Copyright Ladislav Zezula 1998-2023";
|
|
19
|
+
|
|
20
|
+
//-----------------------------------------------------------------------------
|
|
21
|
+
// Local variables
|
|
22
|
+
|
|
23
|
+
DWORD g_dwMpqSignature = ID_MPQ; // Marker for MPQ header
|
|
24
|
+
DWORD g_dwHashTableKey = MPQ_KEY_HASH_TABLE; // Key for hash table
|
|
25
|
+
DWORD g_dwBlockTableKey = MPQ_KEY_BLOCK_TABLE; // Key for block table
|
|
26
|
+
LCID g_lcFileLocale = 0; // Compound of file locale and platform
|
|
27
|
+
|
|
28
|
+
//-----------------------------------------------------------------------------
|
|
29
|
+
// Conversion to uppercase/lowercase
|
|
30
|
+
|
|
31
|
+
// Converts ASCII characters to lowercase
|
|
32
|
+
// Converts slash (0x2F) to backslash (0x5C)
|
|
33
|
+
unsigned char AsciiToLowerTable[256] =
|
|
34
|
+
{
|
|
35
|
+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
|
36
|
+
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
|
37
|
+
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x5C,
|
|
38
|
+
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
|
39
|
+
0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
|
40
|
+
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
|
41
|
+
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
|
42
|
+
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
|
43
|
+
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
|
44
|
+
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
|
45
|
+
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
|
46
|
+
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
|
47
|
+
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
|
48
|
+
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
|
49
|
+
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
|
50
|
+
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Converts ASCII characters to uppercase
|
|
54
|
+
// Converts slash (0x2F) to backslash (0x5C)
|
|
55
|
+
unsigned char AsciiToUpperTable[256] =
|
|
56
|
+
{
|
|
57
|
+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
|
58
|
+
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
|
59
|
+
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x5C,
|
|
60
|
+
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
|
61
|
+
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
|
62
|
+
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
|
63
|
+
0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
|
64
|
+
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
|
65
|
+
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
|
66
|
+
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
|
67
|
+
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
|
68
|
+
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
|
69
|
+
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
|
70
|
+
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
|
71
|
+
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
|
72
|
+
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// Converts ASCII characters to uppercase
|
|
76
|
+
// Does NOT convert slash (0x2F) to backslash (0x5C)
|
|
77
|
+
unsigned char AsciiToUpperTable_Slash[256] =
|
|
78
|
+
{
|
|
79
|
+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
|
80
|
+
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
|
81
|
+
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
|
82
|
+
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
|
83
|
+
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
|
84
|
+
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
|
85
|
+
0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
|
86
|
+
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
|
87
|
+
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
|
88
|
+
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
|
89
|
+
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
|
90
|
+
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
|
91
|
+
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
|
92
|
+
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
|
93
|
+
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
|
94
|
+
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
//-----------------------------------------------------------------------------
|
|
98
|
+
// Safe string functions (for ANSI builds)
|
|
99
|
+
|
|
100
|
+
char * StringCopy(char * szTarget, size_t cchTarget, const char * szSource)
|
|
101
|
+
{
|
|
102
|
+
size_t cchSource = 0;
|
|
103
|
+
|
|
104
|
+
if(cchTarget > 0)
|
|
105
|
+
{
|
|
106
|
+
cchSource = strlen(szSource);
|
|
107
|
+
|
|
108
|
+
if(cchSource >= cchTarget)
|
|
109
|
+
cchSource = cchTarget - 1;
|
|
110
|
+
|
|
111
|
+
memcpy(szTarget, szSource, cchSource);
|
|
112
|
+
szTarget[cchSource] = 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return szTarget + cchSource;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
void StringCat(char * szTarget, size_t cchTargetMax, const char * szSource)
|
|
119
|
+
{
|
|
120
|
+
// Get the current length of the target
|
|
121
|
+
size_t cchTarget = strlen(szTarget);
|
|
122
|
+
|
|
123
|
+
// Copy the string to the target
|
|
124
|
+
if(cchTarget < cchTargetMax)
|
|
125
|
+
{
|
|
126
|
+
StringCopy(szTarget + cchTarget, (cchTargetMax - cchTarget), szSource);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
void StringCreatePseudoFileName(char * szBuffer, size_t cchMaxChars, unsigned int nIndex, const char * szExtension)
|
|
131
|
+
{
|
|
132
|
+
char * szBufferEnd = szBuffer + cchMaxChars;
|
|
133
|
+
|
|
134
|
+
// "File"
|
|
135
|
+
szBuffer = StringCopy(szBuffer, (szBufferEnd - szBuffer), "File");
|
|
136
|
+
|
|
137
|
+
// Number
|
|
138
|
+
szBuffer = IntToString(szBuffer, szBufferEnd - szBuffer + 1, nIndex, 8);
|
|
139
|
+
|
|
140
|
+
// Dot
|
|
141
|
+
if(szBuffer < szBufferEnd)
|
|
142
|
+
*szBuffer++ = '.';
|
|
143
|
+
|
|
144
|
+
// Extension
|
|
145
|
+
while(szExtension[0] == '.')
|
|
146
|
+
szExtension++;
|
|
147
|
+
StringCopy(szBuffer, (szBufferEnd - szBuffer), szExtension);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
//-----------------------------------------------------------------------------
|
|
151
|
+
// Utility functions (UNICODE) only exist in the ANSI version of the library
|
|
152
|
+
// In ANSI builds, TCHAR = char, so we don't need these functions implemented
|
|
153
|
+
|
|
154
|
+
#ifdef _UNICODE
|
|
155
|
+
void StringCopy(TCHAR * szTarget, size_t cchTarget, const char * szSource)
|
|
156
|
+
{
|
|
157
|
+
int ccResult;
|
|
158
|
+
|
|
159
|
+
ccResult = MultiByteToWideChar(CP_UTF8, 0, szSource, -1, szTarget, (int)(cchTarget));
|
|
160
|
+
szTarget[ccResult] = 0;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
void StringCopy(char * szTarget, size_t cchTarget, const TCHAR * szSource)
|
|
164
|
+
{
|
|
165
|
+
int ccResult;
|
|
166
|
+
|
|
167
|
+
ccResult = WideCharToMultiByte(CP_UTF8, 0, szSource, -1, szTarget, (int)(cchTarget), NULL, NULL);
|
|
168
|
+
szTarget[ccResult] = 0;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
void StringCopy(TCHAR * szTarget, size_t cchTarget, const TCHAR * szSource)
|
|
172
|
+
{
|
|
173
|
+
if(cchTarget > 0)
|
|
174
|
+
{
|
|
175
|
+
size_t cchSource = _tcslen(szSource);
|
|
176
|
+
|
|
177
|
+
if(cchSource >= cchTarget)
|
|
178
|
+
cchSource = cchTarget - 1;
|
|
179
|
+
|
|
180
|
+
memcpy(szTarget, szSource, cchSource * sizeof(TCHAR));
|
|
181
|
+
szTarget[cchSource] = 0;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
void StringCat(TCHAR * szTarget, size_t cchTargetMax, const TCHAR * szSource)
|
|
186
|
+
{
|
|
187
|
+
// Get the current length of the target
|
|
188
|
+
size_t cchTarget = _tcslen(szTarget);
|
|
189
|
+
|
|
190
|
+
// Copy the string to the target
|
|
191
|
+
if(cchTarget < cchTargetMax)
|
|
192
|
+
{
|
|
193
|
+
StringCopy(szTarget + cchTarget, (cchTargetMax - cchTarget), szSource);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
void StringCat(TCHAR * szTarget, size_t cchTargetMax, const char * szSource)
|
|
198
|
+
{
|
|
199
|
+
// Get the current length of the target
|
|
200
|
+
size_t cchTarget = _tcslen(szTarget);
|
|
201
|
+
|
|
202
|
+
// Copy the string to the target
|
|
203
|
+
if(cchTarget < cchTargetMax)
|
|
204
|
+
{
|
|
205
|
+
StringCopy(szTarget + cchTarget, (cchTargetMax - cchTarget), szSource);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
#endif
|
|
209
|
+
|
|
210
|
+
//-----------------------------------------------------------------------------
|
|
211
|
+
// Storm hashing functions
|
|
212
|
+
|
|
213
|
+
#define STORM_BUFFER_SIZE 0x500
|
|
214
|
+
#define HASH_INDEX_MASK(ha) (ha->pHeader->dwHashTableSize ? (ha->pHeader->dwHashTableSize - 1) : 0)
|
|
215
|
+
|
|
216
|
+
static DWORD StormBuffer[STORM_BUFFER_SIZE]; // Buffer for the decryption engine
|
|
217
|
+
static bool bMpqCryptographyInitialized = false;
|
|
218
|
+
|
|
219
|
+
void InitializeMpqCryptography()
|
|
220
|
+
{
|
|
221
|
+
DWORD dwSeed = 0x00100001;
|
|
222
|
+
DWORD index1 = 0;
|
|
223
|
+
DWORD index2 = 0;
|
|
224
|
+
int i;
|
|
225
|
+
|
|
226
|
+
// Initialize the decryption buffer.
|
|
227
|
+
// Do nothing if already done.
|
|
228
|
+
if(bMpqCryptographyInitialized == false)
|
|
229
|
+
{
|
|
230
|
+
for(index1 = 0; index1 < 0x100; index1++)
|
|
231
|
+
{
|
|
232
|
+
for(index2 = index1, i = 0; i < 5; i++, index2 += 0x100)
|
|
233
|
+
{
|
|
234
|
+
DWORD temp1, temp2;
|
|
235
|
+
|
|
236
|
+
dwSeed = (dwSeed * 125 + 3) % 0x2AAAAB;
|
|
237
|
+
temp1 = (dwSeed & 0xFFFF) << 0x10;
|
|
238
|
+
|
|
239
|
+
dwSeed = (dwSeed * 125 + 3) % 0x2AAAAB;
|
|
240
|
+
temp2 = (dwSeed & 0xFFFF);
|
|
241
|
+
|
|
242
|
+
StormBuffer[index2] = (temp1 | temp2);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Also register both MD5 and SHA1 hash algorithms
|
|
247
|
+
register_hash(&sha1_desc);
|
|
248
|
+
register_hash(&md5_desc);
|
|
249
|
+
|
|
250
|
+
// Use LibTomMath as support math library for LibTomCrypt
|
|
251
|
+
ltc_mp = ltm_desc;
|
|
252
|
+
|
|
253
|
+
// Don't do that again
|
|
254
|
+
bMpqCryptographyInitialized = true;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
//
|
|
259
|
+
// Note: Implementation of this function in WorldEdit.exe and storm.dll
|
|
260
|
+
// incorrectly treats the character as signed, which leads to the
|
|
261
|
+
// a buffer underflow if the character in the file name >= 0x80:
|
|
262
|
+
// The following steps happen when *pbKey == 0xBF and dwHashType == 0x0000
|
|
263
|
+
// (calculating hash index)
|
|
264
|
+
//
|
|
265
|
+
// 1) Result of AsciiToUpperTable_Slash[*pbKey++] is sign-extended to 0xffffffbf
|
|
266
|
+
// 2) The "ch" is added to dwHashType (0xffffffbf + 0x0000 => 0xffffffbf)
|
|
267
|
+
// 3) The result is used as index to the StormBuffer table,
|
|
268
|
+
// thus dereferences a random value BEFORE the begin of StormBuffer.
|
|
269
|
+
//
|
|
270
|
+
// As result, MPQs containing files with non-ANSI characters will not work between
|
|
271
|
+
// various game versions and localizations. Even WorldEdit, after importing a file
|
|
272
|
+
// with Korean characters in the name, cannot open the file back.
|
|
273
|
+
//
|
|
274
|
+
DWORD HashString(const char * szFileName, DWORD dwHashType)
|
|
275
|
+
{
|
|
276
|
+
LPBYTE pbKey = (BYTE *)szFileName;
|
|
277
|
+
DWORD dwSeed1 = 0x7FED7FED;
|
|
278
|
+
DWORD dwSeed2 = 0xEEEEEEEE;
|
|
279
|
+
DWORD ch;
|
|
280
|
+
|
|
281
|
+
while(*pbKey != 0)
|
|
282
|
+
{
|
|
283
|
+
// Convert the input character to uppercase
|
|
284
|
+
// Convert slash (0x2F) to backslash (0x5C)
|
|
285
|
+
ch = AsciiToUpperTable[*pbKey++];
|
|
286
|
+
|
|
287
|
+
dwSeed1 = StormBuffer[dwHashType + ch] ^ (dwSeed1 + dwSeed2);
|
|
288
|
+
dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return dwSeed1;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
DWORD HashStringSlash(const char * szFileName, DWORD dwHashType)
|
|
295
|
+
{
|
|
296
|
+
LPBYTE pbKey = (BYTE *)szFileName;
|
|
297
|
+
DWORD dwSeed1 = 0x7FED7FED;
|
|
298
|
+
DWORD dwSeed2 = 0xEEEEEEEE;
|
|
299
|
+
DWORD ch;
|
|
300
|
+
|
|
301
|
+
while(*pbKey != 0)
|
|
302
|
+
{
|
|
303
|
+
// Convert the input character to uppercase
|
|
304
|
+
// DON'T convert slash (0x2F) to backslash (0x5C)
|
|
305
|
+
ch = AsciiToUpperTable_Slash[*pbKey++];
|
|
306
|
+
|
|
307
|
+
dwSeed1 = StormBuffer[dwHashType + ch] ^ (dwSeed1 + dwSeed2);
|
|
308
|
+
dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return dwSeed1;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
DWORD HashStringLower(const char * szFileName, DWORD dwHashType)
|
|
315
|
+
{
|
|
316
|
+
LPBYTE pbKey = (BYTE *)szFileName;
|
|
317
|
+
DWORD dwSeed1 = 0x7FED7FED;
|
|
318
|
+
DWORD dwSeed2 = 0xEEEEEEEE;
|
|
319
|
+
DWORD ch;
|
|
320
|
+
|
|
321
|
+
while(*pbKey != 0)
|
|
322
|
+
{
|
|
323
|
+
// Convert the input character to lower
|
|
324
|
+
// DON'T convert slash (0x2F) to backslash (0x5C)
|
|
325
|
+
ch = AsciiToLowerTable[*pbKey++];
|
|
326
|
+
|
|
327
|
+
dwSeed1 = StormBuffer[dwHashType + ch] ^ (dwSeed1 + dwSeed2);
|
|
328
|
+
dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return dwSeed1;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
//-----------------------------------------------------------------------------
|
|
335
|
+
// Calculates the hash table size for a given amount of files
|
|
336
|
+
|
|
337
|
+
// Returns the nearest higher power of two.
|
|
338
|
+
// If the value is already a power of two, returns the same value
|
|
339
|
+
DWORD GetNearestPowerOfTwo(DWORD dwFileCount)
|
|
340
|
+
{
|
|
341
|
+
dwFileCount --;
|
|
342
|
+
|
|
343
|
+
dwFileCount |= dwFileCount >> 1;
|
|
344
|
+
dwFileCount |= dwFileCount >> 2;
|
|
345
|
+
dwFileCount |= dwFileCount >> 4;
|
|
346
|
+
dwFileCount |= dwFileCount >> 8;
|
|
347
|
+
dwFileCount |= dwFileCount >> 16;
|
|
348
|
+
|
|
349
|
+
return dwFileCount + 1;
|
|
350
|
+
}
|
|
351
|
+
/*
|
|
352
|
+
DWORD GetNearestPowerOfTwo(DWORD dwFileCount)
|
|
353
|
+
{
|
|
354
|
+
DWORD dwPowerOfTwo = HASH_TABLE_SIZE_MIN;
|
|
355
|
+
|
|
356
|
+
// For zero files, there is no hash table needed
|
|
357
|
+
if(dwFileCount == 0)
|
|
358
|
+
return 0;
|
|
359
|
+
|
|
360
|
+
// Round the hash table size up to the nearest power of two
|
|
361
|
+
// Don't allow the hash table size go over allowed maximum
|
|
362
|
+
while(dwPowerOfTwo < HASH_TABLE_SIZE_MAX && dwPowerOfTwo < dwFileCount)
|
|
363
|
+
dwPowerOfTwo <<= 1;
|
|
364
|
+
return dwPowerOfTwo;
|
|
365
|
+
}
|
|
366
|
+
*/
|
|
367
|
+
//-----------------------------------------------------------------------------
|
|
368
|
+
// Calculates a Jenkin's Encrypting and decrypting MPQ file data
|
|
369
|
+
|
|
370
|
+
ULONGLONG HashStringJenkins(const char * szFileName)
|
|
371
|
+
{
|
|
372
|
+
LPBYTE pbFileName = (LPBYTE)szFileName;
|
|
373
|
+
char szNameBuff[0x108];
|
|
374
|
+
size_t nLength = 0;
|
|
375
|
+
unsigned int primary_hash = 1;
|
|
376
|
+
unsigned int secondary_hash = 2;
|
|
377
|
+
|
|
378
|
+
// Normalize the file name - convert to uppercase, and convert "/" to "\\".
|
|
379
|
+
if(pbFileName != NULL)
|
|
380
|
+
{
|
|
381
|
+
char * szNamePtr = szNameBuff;
|
|
382
|
+
char * szNameEnd = szNamePtr + sizeof(szNameBuff);
|
|
383
|
+
|
|
384
|
+
// Normalize the file name. Doesn't have to be zero terminated for hashing
|
|
385
|
+
while(szNamePtr < szNameEnd && pbFileName[0] != 0)
|
|
386
|
+
*szNamePtr++ = (char)AsciiToLowerTable[*pbFileName++];
|
|
387
|
+
nLength = szNamePtr - szNameBuff;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Thanks Quantam for finding out what the algorithm is.
|
|
391
|
+
// I am really getting old for reversing large chunks of assembly
|
|
392
|
+
// that does hashing :-)
|
|
393
|
+
hashlittle2(szNameBuff, nLength, &secondary_hash, &primary_hash);
|
|
394
|
+
|
|
395
|
+
// Combine those 2 together
|
|
396
|
+
return ((ULONGLONG)primary_hash << 0x20) | (ULONGLONG)secondary_hash;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
//-----------------------------------------------------------------------------
|
|
400
|
+
// Default flags for (attributes) and (listfile)
|
|
401
|
+
|
|
402
|
+
DWORD GetDefaultSpecialFileFlags(DWORD dwFileSize, USHORT wFormatVersion)
|
|
403
|
+
{
|
|
404
|
+
// Fixed for format 1.0
|
|
405
|
+
if(wFormatVersion == MPQ_FORMAT_VERSION_1)
|
|
406
|
+
return MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | MPQ_FILE_KEY_V2;
|
|
407
|
+
|
|
408
|
+
// Size-dependent for formats 2.0-4.0
|
|
409
|
+
return (dwFileSize > 0x4000) ? (MPQ_FILE_COMPRESS | MPQ_FILE_SECTOR_CRC) : (MPQ_FILE_COMPRESS | MPQ_FILE_SINGLE_UNIT);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
//-----------------------------------------------------------------------------
|
|
414
|
+
// Encrypting/Decrypting MPQ data block
|
|
415
|
+
|
|
416
|
+
static DWORD EncryptUInt32Unaligned(LPDWORD DataPointer, DWORD i, DWORD dwXorKey)
|
|
417
|
+
{
|
|
418
|
+
LPBYTE pbDataPointer = (LPBYTE)(DataPointer + i);
|
|
419
|
+
LPBYTE pbXorKey = (LPBYTE)(&dwXorKey);
|
|
420
|
+
DWORD dwValue32;
|
|
421
|
+
|
|
422
|
+
// Retrieve the value
|
|
423
|
+
dwValue32 = ((DWORD)pbDataPointer[0] << 0x00) |
|
|
424
|
+
((DWORD)pbDataPointer[1] << 0x08) |
|
|
425
|
+
((DWORD)pbDataPointer[2] << 0x10) |
|
|
426
|
+
((DWORD)pbDataPointer[3] << 0x18);
|
|
427
|
+
|
|
428
|
+
// Perform unaligned XOR
|
|
429
|
+
pbDataPointer[0] = (pbDataPointer[0] ^ pbXorKey[0]);
|
|
430
|
+
pbDataPointer[1] = (pbDataPointer[1] ^ pbXorKey[1]);
|
|
431
|
+
pbDataPointer[2] = (pbDataPointer[2] ^ pbXorKey[2]);
|
|
432
|
+
pbDataPointer[3] = (pbDataPointer[3] ^ pbXorKey[3]);
|
|
433
|
+
return dwValue32;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
void EncryptMpqBlock(void * pvDataBlock, DWORD dwLength, DWORD dwKey1)
|
|
437
|
+
{
|
|
438
|
+
LPDWORD DataPointer = (LPDWORD)pvDataBlock;
|
|
439
|
+
DWORD dwValue32;
|
|
440
|
+
DWORD dwKey2 = 0xEEEEEEEE;
|
|
441
|
+
|
|
442
|
+
// Round to DWORDs
|
|
443
|
+
dwLength >>= 2;
|
|
444
|
+
|
|
445
|
+
// We need different approach on non-aligned buffers
|
|
446
|
+
if(STORMLIB_DWORD_ALIGNED(DataPointer))
|
|
447
|
+
{
|
|
448
|
+
for(DWORD i = 0; i < dwLength; i++)
|
|
449
|
+
{
|
|
450
|
+
// Modify the second key
|
|
451
|
+
dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)];
|
|
452
|
+
|
|
453
|
+
// We can use 32-bit approach, when the buffer is aligned
|
|
454
|
+
DataPointer[i] = (dwValue32 = DataPointer[i]) ^ (dwKey1 + dwKey2);
|
|
455
|
+
|
|
456
|
+
dwKey1 = ((~dwKey1 << 0x15) + 0x11111111) | (dwKey1 >> 0x0B);
|
|
457
|
+
dwKey2 = dwValue32 + dwKey2 + (dwKey2 << 5) + 3;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
else
|
|
461
|
+
{
|
|
462
|
+
for(DWORD i = 0; i < dwLength; i++)
|
|
463
|
+
{
|
|
464
|
+
// Modify the second key
|
|
465
|
+
dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)];
|
|
466
|
+
|
|
467
|
+
// The data are unaligned. Make sure we don't cause data misalignment error
|
|
468
|
+
dwValue32 = EncryptUInt32Unaligned(DataPointer, i, (dwKey1 + dwKey2));
|
|
469
|
+
|
|
470
|
+
dwKey1 = ((~dwKey1 << 0x15) + 0x11111111) | (dwKey1 >> 0x0B);
|
|
471
|
+
dwKey2 = dwValue32 + dwKey2 + (dwKey2 << 5) + 3;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
static DWORD DecryptUInt32Unaligned(LPDWORD DataPointer, DWORD i, DWORD dwXorKey)
|
|
477
|
+
{
|
|
478
|
+
LPBYTE pbDataPointer = (LPBYTE)(DataPointer + i);
|
|
479
|
+
LPBYTE pbXorKey = (LPBYTE)(&dwXorKey);
|
|
480
|
+
|
|
481
|
+
// Perform unaligned XOR
|
|
482
|
+
pbDataPointer[0] = (pbDataPointer[0] ^ pbXorKey[0]);
|
|
483
|
+
pbDataPointer[1] = (pbDataPointer[1] ^ pbXorKey[1]);
|
|
484
|
+
pbDataPointer[2] = (pbDataPointer[2] ^ pbXorKey[2]);
|
|
485
|
+
pbDataPointer[3] = (pbDataPointer[3] ^ pbXorKey[3]);
|
|
486
|
+
|
|
487
|
+
// Retrieve the value
|
|
488
|
+
return ((DWORD)pbDataPointer[0] << 0x00) |
|
|
489
|
+
((DWORD)pbDataPointer[1] << 0x08) |
|
|
490
|
+
((DWORD)pbDataPointer[2] << 0x10) |
|
|
491
|
+
((DWORD)pbDataPointer[3] << 0x18);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
void DecryptMpqBlock(void * pvDataBlock, DWORD dwLength, DWORD dwKey1)
|
|
495
|
+
{
|
|
496
|
+
LPDWORD DataPointer = (LPDWORD)pvDataBlock;
|
|
497
|
+
DWORD dwValue32;
|
|
498
|
+
DWORD dwKey2 = 0xEEEEEEEE;
|
|
499
|
+
|
|
500
|
+
// Round to DWORDs
|
|
501
|
+
dwLength >>= 2;
|
|
502
|
+
|
|
503
|
+
// We need different approach on non-aligned buffers
|
|
504
|
+
if(STORMLIB_DWORD_ALIGNED(DataPointer))
|
|
505
|
+
{
|
|
506
|
+
for(DWORD i = 0; i < dwLength; i++)
|
|
507
|
+
{
|
|
508
|
+
// Modify the second key
|
|
509
|
+
dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)];
|
|
510
|
+
|
|
511
|
+
// We can use 32-bit approach, when the buffer is aligned
|
|
512
|
+
DataPointer[i] = dwValue32 = DataPointer[i] ^ (dwKey1 + dwKey2);
|
|
513
|
+
|
|
514
|
+
dwKey1 = ((~dwKey1 << 0x15) + 0x11111111) | (dwKey1 >> 0x0B);
|
|
515
|
+
dwKey2 = dwValue32 + dwKey2 + (dwKey2 << 5) + 3;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
else
|
|
519
|
+
{
|
|
520
|
+
for(DWORD i = 0; i < dwLength; i++)
|
|
521
|
+
{
|
|
522
|
+
// Modify the second key
|
|
523
|
+
dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)];
|
|
524
|
+
|
|
525
|
+
// The data are unaligned. Make sure we don't cause data misalignment error
|
|
526
|
+
dwValue32 = DecryptUInt32Unaligned(DataPointer, i, (dwKey1 + dwKey2));
|
|
527
|
+
|
|
528
|
+
dwKey1 = ((~dwKey1 << 0x15) + 0x11111111) | (dwKey1 >> 0x0B);
|
|
529
|
+
dwKey2 = dwValue32 + dwKey2 + (dwKey2 << 5) + 3;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* Functions tries to get file decryption key. This comes from these facts
|
|
536
|
+
*
|
|
537
|
+
* - We know the decrypted value of the first DWORD in the encrypted data
|
|
538
|
+
* - We know the decrypted value of the second DWORD (at least aproximately)
|
|
539
|
+
* - There is only 256 variants of how the second key is modified
|
|
540
|
+
*
|
|
541
|
+
* The first iteration of dwKey1 and dwKey2 is this:
|
|
542
|
+
*
|
|
543
|
+
* dwKey2 = 0xEEEEEEEE + StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)]
|
|
544
|
+
* dwDecrypted0 = DataBlock[0] ^ (dwKey1 + dwKey2);
|
|
545
|
+
*
|
|
546
|
+
* This means:
|
|
547
|
+
*
|
|
548
|
+
* (dwKey1 + dwKey2) = DataBlock[0] ^ dwDecrypted0;
|
|
549
|
+
*
|
|
550
|
+
*/
|
|
551
|
+
|
|
552
|
+
DWORD DetectFileKeyBySectorSize(LPDWORD EncryptedData, DWORD dwSectorSize, DWORD dwDecrypted0)
|
|
553
|
+
{
|
|
554
|
+
// We must have at least 2 DWORDs there to be able to decrypt something
|
|
555
|
+
if(dwSectorSize >= 0x08)
|
|
556
|
+
{
|
|
557
|
+
// Also try subsequent three values. This is because the value of the sector offset[0]
|
|
558
|
+
// could be higher than the total size of the sector table.
|
|
559
|
+
// Example MPQ: MPQ_2021_v1_CantExtractCHK.scx
|
|
560
|
+
for(DWORD dwDecrypted4 = dwDecrypted0 + 4; dwDecrypted0 < dwDecrypted4; dwDecrypted0++)
|
|
561
|
+
{
|
|
562
|
+
DWORD dwDecrypted1Max = dwSectorSize + dwDecrypted0;
|
|
563
|
+
DWORD dwKey1PlusKey2;
|
|
564
|
+
DWORD DataBlock[2];
|
|
565
|
+
|
|
566
|
+
// Get the value of the combined encryption key
|
|
567
|
+
dwKey1PlusKey2 = (EncryptedData[0] ^ dwDecrypted0) - 0xEEEEEEEE;
|
|
568
|
+
|
|
569
|
+
// Try all 256 combinations of dwKey1
|
|
570
|
+
for(DWORD i = 0; i < 0x100; i++)
|
|
571
|
+
{
|
|
572
|
+
DWORD dwSaveKey1;
|
|
573
|
+
DWORD dwKey1 = dwKey1PlusKey2 - StormBuffer[MPQ_HASH_KEY2_MIX + i];
|
|
574
|
+
DWORD dwKey2 = 0xEEEEEEEE;
|
|
575
|
+
|
|
576
|
+
// Modify the second key and decrypt the first DWORD
|
|
577
|
+
dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)];
|
|
578
|
+
DataBlock[0] = EncryptedData[0] ^ (dwKey1 + dwKey2);
|
|
579
|
+
|
|
580
|
+
// Did we obtain the same value like dwDecrypted0?
|
|
581
|
+
if(DataBlock[0] == dwDecrypted0)
|
|
582
|
+
{
|
|
583
|
+
// Save this key value. Increment by one because
|
|
584
|
+
// we are decrypting sector offset table
|
|
585
|
+
dwSaveKey1 = dwKey1 + 1;
|
|
586
|
+
|
|
587
|
+
// Rotate both keys
|
|
588
|
+
dwKey1 = ((~dwKey1 << 0x15) + 0x11111111) | (dwKey1 >> 0x0B);
|
|
589
|
+
dwKey2 = DataBlock[0] + dwKey2 + (dwKey2 << 5) + 3;
|
|
590
|
+
|
|
591
|
+
// Modify the second key again and decrypt the second DWORD
|
|
592
|
+
dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)];
|
|
593
|
+
DataBlock[1] = EncryptedData[1] ^ (dwKey1 + dwKey2);
|
|
594
|
+
|
|
595
|
+
// Now compare the results
|
|
596
|
+
if(DataBlock[1] <= dwDecrypted1Max)
|
|
597
|
+
return dwSaveKey1;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// Key not found
|
|
604
|
+
return 0;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// Function tries to detect file encryption key based on expected file content
|
|
608
|
+
// It is the same function like before, except that we know the value of the second DWORD
|
|
609
|
+
DWORD DetectFileKeyByKnownContent(void * pvEncryptedData, DWORD dwDecrypted0, DWORD dwDecrypted1)
|
|
610
|
+
{
|
|
611
|
+
LPDWORD EncryptedData = (LPDWORD)pvEncryptedData;
|
|
612
|
+
DWORD dwKey1PlusKey2;
|
|
613
|
+
DWORD DataBlock[2];
|
|
614
|
+
|
|
615
|
+
// Get the value of the combined encryption key
|
|
616
|
+
dwKey1PlusKey2 = (EncryptedData[0] ^ dwDecrypted0) - 0xEEEEEEEE;
|
|
617
|
+
|
|
618
|
+
// Try all 256 combinations of dwKey1
|
|
619
|
+
for(DWORD i = 0; i < 0x100; i++)
|
|
620
|
+
{
|
|
621
|
+
DWORD dwSaveKey1;
|
|
622
|
+
DWORD dwKey1 = dwKey1PlusKey2 - StormBuffer[MPQ_HASH_KEY2_MIX + i];
|
|
623
|
+
DWORD dwKey2 = 0xEEEEEEEE;
|
|
624
|
+
|
|
625
|
+
// Modify the second key and decrypt the first DWORD
|
|
626
|
+
dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)];
|
|
627
|
+
DataBlock[0] = EncryptedData[0] ^ (dwKey1 + dwKey2);
|
|
628
|
+
|
|
629
|
+
// Did we obtain the same value like dwDecrypted0?
|
|
630
|
+
if(DataBlock[0] == dwDecrypted0)
|
|
631
|
+
{
|
|
632
|
+
// Save this key value
|
|
633
|
+
dwSaveKey1 = dwKey1;
|
|
634
|
+
|
|
635
|
+
// Rotate both keys
|
|
636
|
+
dwKey1 = ((~dwKey1 << 0x15) + 0x11111111) | (dwKey1 >> 0x0B);
|
|
637
|
+
dwKey2 = DataBlock[0] + dwKey2 + (dwKey2 << 5) + 3;
|
|
638
|
+
|
|
639
|
+
// Modify the second key again and decrypt the second DWORD
|
|
640
|
+
dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)];
|
|
641
|
+
DataBlock[1] = EncryptedData[1] ^ (dwKey1 + dwKey2);
|
|
642
|
+
|
|
643
|
+
// Now compare the results
|
|
644
|
+
if(DataBlock[1] == dwDecrypted1)
|
|
645
|
+
return dwSaveKey1;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
// Key not found
|
|
650
|
+
return 0;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
DWORD DetectFileKeyByContent(void * pvEncryptedData, DWORD dwSectorSize, DWORD dwFileSize)
|
|
654
|
+
{
|
|
655
|
+
DWORD dwFileKey;
|
|
656
|
+
|
|
657
|
+
// Try to break the file encryption key as if it was a WAVE file
|
|
658
|
+
if(dwSectorSize >= 0x0C)
|
|
659
|
+
{
|
|
660
|
+
dwFileKey = DetectFileKeyByKnownContent(pvEncryptedData, 0x46464952, dwFileSize - 8);
|
|
661
|
+
if(dwFileKey != 0)
|
|
662
|
+
return dwFileKey;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// Try to break the encryption key as if it was an EXE file
|
|
666
|
+
if(dwSectorSize > 0x40)
|
|
667
|
+
{
|
|
668
|
+
dwFileKey = DetectFileKeyByKnownContent(pvEncryptedData, 0x00905A4D, 0x00000003);
|
|
669
|
+
if(dwFileKey != 0)
|
|
670
|
+
return dwFileKey;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// Try to break the encryption key as if it was a XML file
|
|
674
|
+
if(dwSectorSize > 0x04)
|
|
675
|
+
{
|
|
676
|
+
dwFileKey = DetectFileKeyByKnownContent(pvEncryptedData, 0x6D783F3C, 0x6576206C);
|
|
677
|
+
if(dwFileKey != 0)
|
|
678
|
+
return dwFileKey;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// Not detected, sorry
|
|
682
|
+
return 0;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
DWORD DecryptFileKey(
|
|
686
|
+
const char * szFileName,
|
|
687
|
+
ULONGLONG MpqPos,
|
|
688
|
+
DWORD dwFileSize,
|
|
689
|
+
DWORD dwFlags)
|
|
690
|
+
{
|
|
691
|
+
DWORD dwFileKey;
|
|
692
|
+
DWORD dwMpqPos = (DWORD)MpqPos;
|
|
693
|
+
|
|
694
|
+
// File key is calculated from plain name
|
|
695
|
+
szFileName = GetPlainFileName(szFileName);
|
|
696
|
+
dwFileKey = HashString(szFileName, MPQ_HASH_FILE_KEY);
|
|
697
|
+
|
|
698
|
+
// Fix the key, if needed
|
|
699
|
+
if(dwFlags & MPQ_FILE_KEY_V2)
|
|
700
|
+
dwFileKey = (dwFileKey + dwMpqPos) ^ dwFileSize;
|
|
701
|
+
|
|
702
|
+
// Return the key
|
|
703
|
+
return dwFileKey;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
//-----------------------------------------------------------------------------
|
|
707
|
+
// Handle validation functions
|
|
708
|
+
|
|
709
|
+
TMPQArchive * IsValidMpqHandle(HANDLE hMpq)
|
|
710
|
+
{
|
|
711
|
+
TMPQArchive * ha = (TMPQArchive *)hMpq;
|
|
712
|
+
|
|
713
|
+
return (ha != NULL && ha->pHeader != NULL && ha->pHeader->dwID == g_dwMpqSignature) ? ha : NULL;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
TMPQFile * IsValidFileHandle(HANDLE hFile)
|
|
717
|
+
{
|
|
718
|
+
TMPQFile * hf = (TMPQFile *)hFile;
|
|
719
|
+
|
|
720
|
+
// Must not be NULL
|
|
721
|
+
if(hf != NULL && hf->dwMagic == ID_MPQ_FILE)
|
|
722
|
+
{
|
|
723
|
+
// Local file handle?
|
|
724
|
+
if(hf->pStream != NULL)
|
|
725
|
+
return hf;
|
|
726
|
+
|
|
727
|
+
// Also verify the MPQ handle within the file handle
|
|
728
|
+
if(IsValidMpqHandle(hf->ha))
|
|
729
|
+
return hf;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
return NULL;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
//-----------------------------------------------------------------------------
|
|
736
|
+
// Hash table and block table manipulation
|
|
737
|
+
|
|
738
|
+
// Attempts to search a free hash entry, or an entry whose names and locale matches
|
|
739
|
+
TMPQHash * FindFreeHashEntry(TMPQArchive * ha, DWORD dwStartIndex, DWORD dwName1, DWORD dwName2, LCID lcFileLocale)
|
|
740
|
+
{
|
|
741
|
+
TMPQHash * pDeletedEntry = NULL; // If a deleted entry was found in the continuous hash range
|
|
742
|
+
TMPQHash * pFreeEntry = NULL; // If a free entry was found in the continuous hash range
|
|
743
|
+
DWORD dwHashIndexMask = HASH_INDEX_MASK(ha);
|
|
744
|
+
DWORD dwIndex;
|
|
745
|
+
USHORT Locale = SFILE_LOCALE(lcFileLocale);
|
|
746
|
+
|
|
747
|
+
// Set the initial index
|
|
748
|
+
dwStartIndex = dwIndex = (dwStartIndex & dwHashIndexMask);
|
|
749
|
+
|
|
750
|
+
// Search the hash table and return the found entries in the following priority:
|
|
751
|
+
// 1) <MATCHING_ENTRY>
|
|
752
|
+
// 2) <DELETED-ENTRY>
|
|
753
|
+
// 3) <FREE-ENTRY>
|
|
754
|
+
// 4) NULL
|
|
755
|
+
for(;;)
|
|
756
|
+
{
|
|
757
|
+
TMPQHash * pHash = ha->pHashTable + dwIndex;
|
|
758
|
+
|
|
759
|
+
// If we found a matching entry, return that one
|
|
760
|
+
if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && pHash->Locale == Locale)
|
|
761
|
+
return pHash;
|
|
762
|
+
|
|
763
|
+
// If we found a deleted entry, remember it but keep searching
|
|
764
|
+
if(pHash->dwBlockIndex == HASH_ENTRY_DELETED && pDeletedEntry == NULL)
|
|
765
|
+
pDeletedEntry = pHash;
|
|
766
|
+
|
|
767
|
+
// If we found a free entry, we need to stop searching
|
|
768
|
+
if(pHash->dwBlockIndex == HASH_ENTRY_FREE)
|
|
769
|
+
{
|
|
770
|
+
pFreeEntry = pHash;
|
|
771
|
+
break;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// Move to the next hash entry.
|
|
775
|
+
// If we reached the starting entry, it's failure.
|
|
776
|
+
dwIndex = (dwIndex + 1) & dwHashIndexMask;
|
|
777
|
+
if(dwIndex == dwStartIndex)
|
|
778
|
+
break;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
// If we found a deleted entry, return that one preferentially
|
|
782
|
+
return (pDeletedEntry != NULL) ? pDeletedEntry : pFreeEntry;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
// Retrieves the first hash entry for the given file.
|
|
786
|
+
// Every locale version of a file has its own hash entry
|
|
787
|
+
TMPQHash * GetFirstHashEntry(TMPQArchive * ha, const char * szFileName)
|
|
788
|
+
{
|
|
789
|
+
DWORD dwHashIndexMask = HASH_INDEX_MASK(ha);
|
|
790
|
+
DWORD dwStartIndex = ha->pfnHashString(szFileName, MPQ_HASH_TABLE_INDEX);
|
|
791
|
+
DWORD dwName1 = ha->pfnHashString(szFileName, MPQ_HASH_NAME_A);
|
|
792
|
+
DWORD dwName2 = ha->pfnHashString(szFileName, MPQ_HASH_NAME_B);
|
|
793
|
+
DWORD dwIndex;
|
|
794
|
+
|
|
795
|
+
// Set the initial index
|
|
796
|
+
dwStartIndex = dwIndex = (dwStartIndex & dwHashIndexMask);
|
|
797
|
+
|
|
798
|
+
// Search the hash table
|
|
799
|
+
for(;;)
|
|
800
|
+
{
|
|
801
|
+
TMPQHash * pHash = ha->pHashTable + dwIndex;
|
|
802
|
+
|
|
803
|
+
// If the entry matches, we found it.
|
|
804
|
+
if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize)
|
|
805
|
+
return pHash;
|
|
806
|
+
|
|
807
|
+
// If that hash entry is a free entry, it means we haven't found the file
|
|
808
|
+
if(pHash->dwBlockIndex == HASH_ENTRY_FREE)
|
|
809
|
+
return NULL;
|
|
810
|
+
|
|
811
|
+
// Move to the next hash entry. Stop searching
|
|
812
|
+
// if we got reached the original hash entry
|
|
813
|
+
dwIndex = (dwIndex + 1) & dwHashIndexMask;
|
|
814
|
+
if(dwIndex == dwStartIndex)
|
|
815
|
+
return NULL;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
TMPQHash * GetNextHashEntry(TMPQArchive * ha, TMPQHash * pFirstHash, TMPQHash * pHash)
|
|
820
|
+
{
|
|
821
|
+
DWORD dwHashIndexMask = HASH_INDEX_MASK(ha);
|
|
822
|
+
DWORD dwStartIndex = (DWORD)(pFirstHash - ha->pHashTable);
|
|
823
|
+
DWORD dwName1 = pHash->dwName1;
|
|
824
|
+
DWORD dwName2 = pHash->dwName2;
|
|
825
|
+
DWORD dwIndex = (DWORD)(pHash - ha->pHashTable);
|
|
826
|
+
|
|
827
|
+
// Now go for any next entry that follows the pHash,
|
|
828
|
+
// until either free hash entry was found, or the start entry was reached
|
|
829
|
+
for(;;)
|
|
830
|
+
{
|
|
831
|
+
// Move to the next hash entry. Stop searching
|
|
832
|
+
// if we got reached the original hash entry
|
|
833
|
+
dwIndex = (dwIndex + 1) & dwHashIndexMask;
|
|
834
|
+
if(dwIndex == dwStartIndex)
|
|
835
|
+
return NULL;
|
|
836
|
+
pHash = ha->pHashTable + dwIndex;
|
|
837
|
+
|
|
838
|
+
// If the entry matches, we found it.
|
|
839
|
+
if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize)
|
|
840
|
+
return pHash;
|
|
841
|
+
|
|
842
|
+
// If that hash entry is a free entry, it means we haven't found the file
|
|
843
|
+
if(pHash->dwBlockIndex == HASH_ENTRY_FREE)
|
|
844
|
+
return NULL;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
// Allocates an entry in the hash table
|
|
849
|
+
TMPQHash * AllocateHashEntry(
|
|
850
|
+
TMPQArchive * ha,
|
|
851
|
+
TFileEntry * pFileEntry,
|
|
852
|
+
LCID lcFileLocale)
|
|
853
|
+
{
|
|
854
|
+
TMPQHash * pHash;
|
|
855
|
+
DWORD dwStartIndex = ha->pfnHashString(pFileEntry->szFileName, MPQ_HASH_TABLE_INDEX);
|
|
856
|
+
DWORD dwName1 = ha->pfnHashString(pFileEntry->szFileName, MPQ_HASH_NAME_A);
|
|
857
|
+
DWORD dwName2 = ha->pfnHashString(pFileEntry->szFileName, MPQ_HASH_NAME_B);
|
|
858
|
+
|
|
859
|
+
// Attempt to find a free hash entry
|
|
860
|
+
pHash = FindFreeHashEntry(ha, dwStartIndex, dwName1, dwName2, lcFileLocale);
|
|
861
|
+
if(pHash != NULL)
|
|
862
|
+
{
|
|
863
|
+
// Fill the free hash entry
|
|
864
|
+
pHash->dwName1 = dwName1;
|
|
865
|
+
pHash->dwName2 = dwName2;
|
|
866
|
+
pHash->Locale = SFILE_LOCALE(lcFileLocale);
|
|
867
|
+
pHash->Platform = SFILE_PLATFORM(lcFileLocale);
|
|
868
|
+
pHash->Reserved = 0;
|
|
869
|
+
pHash->dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
return pHash;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
// Finds a free space in the MPQ where to store next data
|
|
876
|
+
// The free space begins beyond the file that is stored at the fuhrtest
|
|
877
|
+
// position in the MPQ. (listfile), (attributes) and (signature) are ignored,
|
|
878
|
+
// unless the MPQ is being flushed.
|
|
879
|
+
ULONGLONG FindFreeMpqSpace(TMPQArchive * ha)
|
|
880
|
+
{
|
|
881
|
+
TMPQHeader * pHeader = ha->pHeader;
|
|
882
|
+
TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
|
|
883
|
+
TFileEntry * pFileEntry;
|
|
884
|
+
ULONGLONG FreeSpacePos = ha->pHeader->dwHeaderSize;
|
|
885
|
+
DWORD dwChunkCount;
|
|
886
|
+
|
|
887
|
+
// Parse the entire block table
|
|
888
|
+
for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
|
|
889
|
+
{
|
|
890
|
+
// Only take existing files with nonzero size
|
|
891
|
+
if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) && (pFileEntry->dwCmpSize != 0))
|
|
892
|
+
{
|
|
893
|
+
// If we are not saving MPQ tables, ignore internal MPQ files
|
|
894
|
+
if((ha->dwFlags & MPQ_FLAG_SAVING_TABLES) == 0 && IsInternalMpqFileName(pFileEntry->szFileName))
|
|
895
|
+
continue;
|
|
896
|
+
|
|
897
|
+
// If the end of the file is bigger than current MPQ table pos, update it
|
|
898
|
+
if((pFileEntry->ByteOffset + pFileEntry->dwCmpSize) > FreeSpacePos)
|
|
899
|
+
{
|
|
900
|
+
// Get the end of the file data
|
|
901
|
+
FreeSpacePos = pFileEntry->ByteOffset + pFileEntry->dwCmpSize;
|
|
902
|
+
|
|
903
|
+
// Add the MD5 chunks, if present
|
|
904
|
+
if(pHeader->dwRawChunkSize != 0 && pFileEntry->dwCmpSize != 0)
|
|
905
|
+
{
|
|
906
|
+
dwChunkCount = ((pFileEntry->dwCmpSize - 1) / pHeader->dwRawChunkSize) + 1;
|
|
907
|
+
FreeSpacePos += dwChunkCount * MD5_DIGEST_SIZE;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
// Give the free space position to the caller
|
|
914
|
+
return FreeSpacePos;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
//-----------------------------------------------------------------------------
|
|
918
|
+
// Common functions - MPQ File
|
|
919
|
+
|
|
920
|
+
TMPQFile * CreateFileHandle(TMPQArchive * ha, TFileEntry * pFileEntry)
|
|
921
|
+
{
|
|
922
|
+
TMPQFile * hf;
|
|
923
|
+
|
|
924
|
+
// Allocate space for TMPQFile
|
|
925
|
+
hf = STORM_ALLOC(TMPQFile, 1);
|
|
926
|
+
if(hf != NULL)
|
|
927
|
+
{
|
|
928
|
+
// Fill the file structure
|
|
929
|
+
memset(hf, 0, sizeof(TMPQFile));
|
|
930
|
+
hf->dwMagic = ID_MPQ_FILE;
|
|
931
|
+
hf->pStream = NULL;
|
|
932
|
+
hf->ha = ha;
|
|
933
|
+
|
|
934
|
+
// If the called entered a file entry, we also copy informations from the file entry
|
|
935
|
+
if(ha != NULL && pFileEntry != NULL)
|
|
936
|
+
{
|
|
937
|
+
// Set the raw position and MPQ position
|
|
938
|
+
hf->RawFilePos = FileOffsetFromMpqOffset(ha, pFileEntry->ByteOffset);
|
|
939
|
+
hf->MpqFilePos = pFileEntry->ByteOffset;
|
|
940
|
+
|
|
941
|
+
// Set the data size
|
|
942
|
+
hf->dwDataSize = pFileEntry->dwFileSize;
|
|
943
|
+
hf->pFileEntry = pFileEntry;
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
return hf;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
TMPQFile * CreateWritableHandle(TMPQArchive * ha, DWORD dwFileSize)
|
|
951
|
+
{
|
|
952
|
+
ULONGLONG FreeMpqSpace;
|
|
953
|
+
ULONGLONG TempPos;
|
|
954
|
+
TMPQFile * hf;
|
|
955
|
+
|
|
956
|
+
// We need to find the position in the MPQ where we save the file data
|
|
957
|
+
FreeMpqSpace = FindFreeMpqSpace(ha);
|
|
958
|
+
|
|
959
|
+
// When format V1, the size of the archive cannot exceed 4 GB
|
|
960
|
+
if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
|
|
961
|
+
{
|
|
962
|
+
TempPos = FreeMpqSpace +
|
|
963
|
+
dwFileSize +
|
|
964
|
+
(ha->pHeader->dwHashTableSize * sizeof(TMPQHash)) +
|
|
965
|
+
(ha->dwFileTableSize * sizeof(TMPQBlock));
|
|
966
|
+
if((TempPos >> 32) != 0)
|
|
967
|
+
{
|
|
968
|
+
SetLastError(ERROR_DISK_FULL);
|
|
969
|
+
return NULL;
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
// Allocate the file handle
|
|
974
|
+
hf = CreateFileHandle(ha, NULL);
|
|
975
|
+
if(hf == NULL)
|
|
976
|
+
{
|
|
977
|
+
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
978
|
+
return NULL;
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
// We need to find the position in the MPQ where we save the file data
|
|
982
|
+
hf->MpqFilePos = FreeMpqSpace;
|
|
983
|
+
hf->bIsWriteHandle = true;
|
|
984
|
+
return hf;
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
// Loads a table from MPQ.
|
|
988
|
+
// Can be used for hash table, block table, sector offset table or sector checksum table
|
|
989
|
+
void * LoadMpqTable(
|
|
990
|
+
TMPQArchive * ha,
|
|
991
|
+
ULONGLONG ByteOffset,
|
|
992
|
+
LPBYTE pbTableHash,
|
|
993
|
+
DWORD dwCompressedSize,
|
|
994
|
+
DWORD dwTableSize,
|
|
995
|
+
DWORD dwKey,
|
|
996
|
+
DWORD * PtrRealTableSize)
|
|
997
|
+
{
|
|
998
|
+
ULONGLONG FileSize = 0;
|
|
999
|
+
LPBYTE pbCompressed = NULL;
|
|
1000
|
+
LPBYTE pbMpqTable;
|
|
1001
|
+
LPBYTE pbToRead;
|
|
1002
|
+
DWORD dwBytesToRead = dwTableSize;
|
|
1003
|
+
DWORD dwErrCode = ERROR_SUCCESS;
|
|
1004
|
+
|
|
1005
|
+
// Allocate the MPQ table
|
|
1006
|
+
pbMpqTable = pbToRead = STORM_ALLOC(BYTE, dwTableSize);
|
|
1007
|
+
if(pbMpqTable != NULL)
|
|
1008
|
+
{
|
|
1009
|
+
// Check if the MPQ table is compressed
|
|
1010
|
+
if(dwCompressedSize < dwTableSize)
|
|
1011
|
+
{
|
|
1012
|
+
// Allocate temporary buffer for holding compressed data
|
|
1013
|
+
pbCompressed = pbToRead = STORM_ALLOC(BYTE, dwCompressedSize);
|
|
1014
|
+
dwBytesToRead = dwCompressedSize;
|
|
1015
|
+
|
|
1016
|
+
if(pbCompressed == NULL)
|
|
1017
|
+
{
|
|
1018
|
+
STORM_FREE(pbMpqTable);
|
|
1019
|
+
return NULL;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
// Get the file offset from which we will read the table
|
|
1024
|
+
// Note: According to Storm.dll from Warcraft III (version 2002),
|
|
1025
|
+
// if the hash table position is 0xFFFFFFFF, no SetFilePointer call is done
|
|
1026
|
+
// and the table is loaded from the current file offset
|
|
1027
|
+
if(ByteOffset == SFILE_INVALID_POS)
|
|
1028
|
+
FileStream_GetPos(ha->pStream, &ByteOffset);
|
|
1029
|
+
|
|
1030
|
+
// The hash table and block table can go beyond EOF.
|
|
1031
|
+
// Storm.dll reads as much as possible, then fills the missing part with zeros.
|
|
1032
|
+
// Abused by Spazzler map protector which sets hash table size to 0x00100000
|
|
1033
|
+
// Abused by NP_Protect in MPQs v4 as well
|
|
1034
|
+
FileStream_GetSize(ha->pStream, &FileSize);
|
|
1035
|
+
if((ByteOffset + dwBytesToRead) > FileSize)
|
|
1036
|
+
{
|
|
1037
|
+
// Fill the extra data with zeros
|
|
1038
|
+
dwBytesToRead = (DWORD)(FileSize - ByteOffset);
|
|
1039
|
+
memset(pbMpqTable + dwBytesToRead, 0, (dwTableSize - dwBytesToRead));
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
// Give the caller information that the table was cut
|
|
1043
|
+
if(PtrRealTableSize != NULL)
|
|
1044
|
+
{
|
|
1045
|
+
PtrRealTableSize[0] = dwBytesToRead;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
// If everything succeeded, read the raw table from the MPQ
|
|
1049
|
+
if(FileStream_Read(ha->pStream, &ByteOffset, pbToRead, dwBytesToRead))
|
|
1050
|
+
{
|
|
1051
|
+
// Verify the MD5 of the table, if present
|
|
1052
|
+
if(!VerifyDataBlockHash(pbToRead, dwBytesToRead, pbTableHash))
|
|
1053
|
+
{
|
|
1054
|
+
dwErrCode = ERROR_FILE_CORRUPT;
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
else
|
|
1058
|
+
{
|
|
1059
|
+
dwErrCode = GetLastError();
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
if(dwErrCode == ERROR_SUCCESS)
|
|
1063
|
+
{
|
|
1064
|
+
// First of all, decrypt the table
|
|
1065
|
+
if(dwKey != 0)
|
|
1066
|
+
{
|
|
1067
|
+
BSWAP_ARRAY32_UNSIGNED(pbToRead, dwCompressedSize);
|
|
1068
|
+
DecryptMpqBlock(pbToRead, dwCompressedSize, dwKey);
|
|
1069
|
+
BSWAP_ARRAY32_UNSIGNED(pbToRead, dwCompressedSize);
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
// If the table is compressed, decompress it
|
|
1073
|
+
if(dwCompressedSize < dwTableSize)
|
|
1074
|
+
{
|
|
1075
|
+
int cbOutBuffer = (int)dwTableSize;
|
|
1076
|
+
int cbInBuffer = (int)dwCompressedSize;
|
|
1077
|
+
|
|
1078
|
+
if(!SCompDecompress2(pbMpqTable, &cbOutBuffer, pbCompressed, cbInBuffer))
|
|
1079
|
+
dwErrCode = GetLastError();
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
// Make sure that the table is properly byte-swapped
|
|
1083
|
+
BSWAP_ARRAY32_UNSIGNED(pbMpqTable, dwTableSize);
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
// If read failed, free the table and return
|
|
1087
|
+
if(dwErrCode != ERROR_SUCCESS)
|
|
1088
|
+
{
|
|
1089
|
+
STORM_FREE(pbMpqTable);
|
|
1090
|
+
pbMpqTable = NULL;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
// Free the compression buffer, if any
|
|
1094
|
+
if(pbCompressed != NULL)
|
|
1095
|
+
STORM_FREE(pbCompressed);
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
// Return the MPQ table
|
|
1099
|
+
return pbMpqTable;
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
unsigned char * AllocateMd5Buffer(
|
|
1103
|
+
DWORD dwRawDataSize,
|
|
1104
|
+
DWORD dwChunkSize,
|
|
1105
|
+
LPDWORD pcbMd5Size)
|
|
1106
|
+
{
|
|
1107
|
+
unsigned char * md5_array;
|
|
1108
|
+
DWORD cbMd5Size;
|
|
1109
|
+
|
|
1110
|
+
// Sanity check
|
|
1111
|
+
assert(dwRawDataSize != 0);
|
|
1112
|
+
assert(dwChunkSize != 0);
|
|
1113
|
+
|
|
1114
|
+
// Calculate how many MD5's we will calculate
|
|
1115
|
+
cbMd5Size = (((dwRawDataSize - 1) / dwChunkSize) + 1) * MD5_DIGEST_SIZE;
|
|
1116
|
+
|
|
1117
|
+
// Allocate space for array or MD5s
|
|
1118
|
+
md5_array = STORM_ALLOC(BYTE, cbMd5Size);
|
|
1119
|
+
|
|
1120
|
+
// Give the size of the MD5 array
|
|
1121
|
+
if(pcbMd5Size != NULL)
|
|
1122
|
+
*pcbMd5Size = cbMd5Size;
|
|
1123
|
+
return md5_array;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
// Allocates sector buffer and sector offset table
|
|
1127
|
+
DWORD AllocateSectorBuffer(TMPQFile * hf)
|
|
1128
|
+
{
|
|
1129
|
+
TMPQArchive * ha = hf->ha;
|
|
1130
|
+
|
|
1131
|
+
// Caller of AllocateSectorBuffer must ensure these
|
|
1132
|
+
assert(hf->pbFileSector == NULL);
|
|
1133
|
+
assert(hf->pFileEntry != NULL);
|
|
1134
|
+
assert(hf->ha != NULL);
|
|
1135
|
+
|
|
1136
|
+
// Don't allocate anything if the file has zero size
|
|
1137
|
+
if(hf->pFileEntry->dwFileSize == 0 || hf->dwDataSize == 0)
|
|
1138
|
+
return ERROR_SUCCESS;
|
|
1139
|
+
|
|
1140
|
+
// Determine the file sector size and allocate buffer for it
|
|
1141
|
+
hf->dwSectorSize = (hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) ? hf->dwDataSize : ha->dwSectorSize;
|
|
1142
|
+
hf->pbFileSector = STORM_ALLOC(BYTE, hf->dwSectorSize);
|
|
1143
|
+
hf->dwSectorOffs = SFILE_INVALID_POS;
|
|
1144
|
+
|
|
1145
|
+
// Return result
|
|
1146
|
+
return (hf->pbFileSector != NULL) ? ERROR_SUCCESS : ERROR_NOT_ENOUGH_MEMORY;
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
// Allocates sector offset table
|
|
1150
|
+
DWORD AllocatePatchInfo(TMPQFile * hf, bool bLoadFromFile)
|
|
1151
|
+
{
|
|
1152
|
+
TMPQArchive * ha = hf->ha;
|
|
1153
|
+
TPatchInfo * pPatchInfo;
|
|
1154
|
+
DWORD dwLength = sizeof(TPatchInfo);
|
|
1155
|
+
|
|
1156
|
+
// The following conditions must be true
|
|
1157
|
+
assert(hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE);
|
|
1158
|
+
assert(hf->pPatchInfo == NULL);
|
|
1159
|
+
|
|
1160
|
+
__AllocateAndLoadPatchInfo:
|
|
1161
|
+
|
|
1162
|
+
// Allocate space for patch header. Start with default size,
|
|
1163
|
+
// and if its size if bigger, then we reload them
|
|
1164
|
+
pPatchInfo = (TPatchInfo *)(STORM_ALLOC(BYTE, dwLength));
|
|
1165
|
+
if(pPatchInfo == NULL)
|
|
1166
|
+
return ERROR_NOT_ENOUGH_MEMORY;
|
|
1167
|
+
|
|
1168
|
+
// Do we have to load the patch header from the file ?
|
|
1169
|
+
if(bLoadFromFile)
|
|
1170
|
+
{
|
|
1171
|
+
// Load the patch header
|
|
1172
|
+
if(!FileStream_Read(ha->pStream, &hf->RawFilePos, pPatchInfo, dwLength))
|
|
1173
|
+
{
|
|
1174
|
+
STORM_FREE(pPatchInfo);
|
|
1175
|
+
return GetLastError();
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
// Perform necessary swapping
|
|
1179
|
+
pPatchInfo->dwLength = BSWAP_INT32_UNSIGNED(pPatchInfo->dwLength);
|
|
1180
|
+
pPatchInfo->dwFlags = BSWAP_INT32_UNSIGNED(pPatchInfo->dwFlags);
|
|
1181
|
+
pPatchInfo->dwDataSize = BSWAP_INT32_UNSIGNED(pPatchInfo->dwDataSize);
|
|
1182
|
+
|
|
1183
|
+
// Do nothing if the patch info is not valid
|
|
1184
|
+
if(!(pPatchInfo->dwFlags & MPQ_PATCH_INFO_VALID))
|
|
1185
|
+
{
|
|
1186
|
+
STORM_FREE(pPatchInfo);
|
|
1187
|
+
return ERROR_FILE_CORRUPT;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
// Verify the size of the patch header
|
|
1191
|
+
// If it's not default size, we have to reload them
|
|
1192
|
+
if(pPatchInfo->dwLength > dwLength)
|
|
1193
|
+
{
|
|
1194
|
+
// Free the patch info
|
|
1195
|
+
dwLength = pPatchInfo->dwLength;
|
|
1196
|
+
STORM_FREE(pPatchInfo);
|
|
1197
|
+
|
|
1198
|
+
// If the length is out of all possible ranges, fail the operation
|
|
1199
|
+
if(dwLength > 0x400)
|
|
1200
|
+
return ERROR_FILE_CORRUPT;
|
|
1201
|
+
goto __AllocateAndLoadPatchInfo;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
// Patch file data size according to the patch header
|
|
1205
|
+
hf->dwDataSize = pPatchInfo->dwDataSize;
|
|
1206
|
+
}
|
|
1207
|
+
else
|
|
1208
|
+
{
|
|
1209
|
+
memset(pPatchInfo, 0, dwLength);
|
|
1210
|
+
pPatchInfo->dwLength = dwLength;
|
|
1211
|
+
pPatchInfo->dwFlags = MPQ_PATCH_INFO_VALID;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
// Save the final length to the patch header
|
|
1215
|
+
hf->pPatchInfo = pPatchInfo;
|
|
1216
|
+
return ERROR_SUCCESS;
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
// Allocates sector offset table
|
|
1220
|
+
DWORD AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile)
|
|
1221
|
+
{
|
|
1222
|
+
TMPQArchive * ha = hf->ha;
|
|
1223
|
+
TFileEntry * pFileEntry = hf->pFileEntry;
|
|
1224
|
+
DWORD dwSectorOffsLen;
|
|
1225
|
+
bool bSectorOffsetTableCorrupt = false;
|
|
1226
|
+
|
|
1227
|
+
// Caller of AllocateSectorOffsets must ensure these
|
|
1228
|
+
assert(hf->SectorOffsets == NULL);
|
|
1229
|
+
assert(hf->pFileEntry != NULL);
|
|
1230
|
+
assert(hf->dwDataSize != 0);
|
|
1231
|
+
assert(hf->ha != NULL);
|
|
1232
|
+
|
|
1233
|
+
// If the file is stored as single unit, just set number of sectors to 1
|
|
1234
|
+
if(pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT)
|
|
1235
|
+
{
|
|
1236
|
+
hf->dwSectorCount = 1;
|
|
1237
|
+
return ERROR_SUCCESS;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
// Calculate the number of data sectors
|
|
1241
|
+
// Note that this doesn't work if the file size is zero
|
|
1242
|
+
hf->dwSectorCount = ((hf->dwDataSize - 1) / hf->dwSectorSize) + 1;
|
|
1243
|
+
|
|
1244
|
+
// Calculate the number of file sectors
|
|
1245
|
+
dwSectorOffsLen = (hf->dwSectorCount + 1) * sizeof(DWORD);
|
|
1246
|
+
|
|
1247
|
+
// If MPQ_FILE_SECTOR_CRC flag is set, there will either be extra DWORD
|
|
1248
|
+
// or an array of MD5's. Either way, we read at least 4 bytes more
|
|
1249
|
+
// in order to save additional read from the file.
|
|
1250
|
+
if(pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC)
|
|
1251
|
+
dwSectorOffsLen += sizeof(DWORD);
|
|
1252
|
+
|
|
1253
|
+
// Only allocate and load the table if the file is compressed
|
|
1254
|
+
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK)
|
|
1255
|
+
{
|
|
1256
|
+
__LoadSectorOffsets:
|
|
1257
|
+
|
|
1258
|
+
// Allocate the sector offset table
|
|
1259
|
+
hf->SectorOffsets = STORM_ALLOC(DWORD, (dwSectorOffsLen / sizeof(DWORD)));
|
|
1260
|
+
if(hf->SectorOffsets == NULL)
|
|
1261
|
+
return ERROR_NOT_ENOUGH_MEMORY;
|
|
1262
|
+
|
|
1263
|
+
// Only read from the file if we are supposed to do so
|
|
1264
|
+
if(bLoadFromFile)
|
|
1265
|
+
{
|
|
1266
|
+
ULONGLONG RawFilePos = hf->RawFilePos;
|
|
1267
|
+
|
|
1268
|
+
// Append the length of the patch info, if any
|
|
1269
|
+
if(hf->pPatchInfo != NULL)
|
|
1270
|
+
{
|
|
1271
|
+
if((RawFilePos + hf->pPatchInfo->dwLength) < RawFilePos)
|
|
1272
|
+
return ERROR_FILE_CORRUPT;
|
|
1273
|
+
RawFilePos += hf->pPatchInfo->dwLength;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
// Load the sector offsets from the file
|
|
1277
|
+
if(!FileStream_Read(ha->pStream, &RawFilePos, hf->SectorOffsets, dwSectorOffsLen))
|
|
1278
|
+
{
|
|
1279
|
+
// Free the sector offsets
|
|
1280
|
+
STORM_FREE(hf->SectorOffsets);
|
|
1281
|
+
hf->SectorOffsets = NULL;
|
|
1282
|
+
return GetLastError();
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
// Swap the sector positions
|
|
1286
|
+
BSWAP_ARRAY32_UNSIGNED(hf->SectorOffsets, dwSectorOffsLen);
|
|
1287
|
+
|
|
1288
|
+
// Decrypt loaded sector positions if necessary
|
|
1289
|
+
if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
|
|
1290
|
+
{
|
|
1291
|
+
// If we don't know the file key, try to find it.
|
|
1292
|
+
if(hf->dwFileKey == 0)
|
|
1293
|
+
{
|
|
1294
|
+
hf->dwFileKey = DetectFileKeyBySectorSize(hf->SectorOffsets, ha->dwSectorSize, dwSectorOffsLen);
|
|
1295
|
+
if(hf->dwFileKey == 0)
|
|
1296
|
+
{
|
|
1297
|
+
STORM_FREE(hf->SectorOffsets);
|
|
1298
|
+
hf->SectorOffsets = NULL;
|
|
1299
|
+
return ERROR_UNKNOWN_FILE_KEY;
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
// Decrypt sector positions
|
|
1304
|
+
DecryptMpqBlock(hf->SectorOffsets, dwSectorOffsLen, hf->dwFileKey - 1);
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
//
|
|
1308
|
+
// Validate the sector offset table
|
|
1309
|
+
//
|
|
1310
|
+
// Note: Some MPQ protectors put the actual file data before the sector offset table.
|
|
1311
|
+
// In this case, the sector offsets are negative (> 0x80000000).
|
|
1312
|
+
//
|
|
1313
|
+
|
|
1314
|
+
for(DWORD i = 0; i < hf->dwSectorCount; i++)
|
|
1315
|
+
{
|
|
1316
|
+
DWORD dwSectorOffset1 = hf->SectorOffsets[i+1];
|
|
1317
|
+
DWORD dwSectorOffset0 = hf->SectorOffsets[i];
|
|
1318
|
+
|
|
1319
|
+
// Every following sector offset must be bigger than the previous one
|
|
1320
|
+
if(dwSectorOffset1 < dwSectorOffset0)
|
|
1321
|
+
{
|
|
1322
|
+
bSectorOffsetTableCorrupt = true;
|
|
1323
|
+
break;
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
// The sector size must not be bigger than compressed file size
|
|
1327
|
+
// Edit: Yes, but apparently, in original Storm.dll, the compressed
|
|
1328
|
+
// size is not checked anywhere. However, we need to do this check
|
|
1329
|
+
// in order to sector offset table malformed by MPQ protectors
|
|
1330
|
+
if((dwSectorOffset1 - dwSectorOffset0) > ha->dwSectorSize)
|
|
1331
|
+
{
|
|
1332
|
+
bSectorOffsetTableCorrupt = true;
|
|
1333
|
+
break;
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
// If data corruption detected, free the sector offset table
|
|
1338
|
+
if(bSectorOffsetTableCorrupt)
|
|
1339
|
+
{
|
|
1340
|
+
STORM_FREE(hf->SectorOffsets);
|
|
1341
|
+
hf->SectorOffsets = NULL;
|
|
1342
|
+
return ERROR_FILE_CORRUPT;
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
//
|
|
1346
|
+
// There may be various extra DWORDs loaded after the sector offset table.
|
|
1347
|
+
// They are mostly empty on WoW release MPQs, but on MPQs from PTR,
|
|
1348
|
+
// they contain random non-zero data. Their meaning is unknown.
|
|
1349
|
+
//
|
|
1350
|
+
// These extra values are, however, included in the dwCmpSize in the file
|
|
1351
|
+
// table. We cannot ignore them, because compacting archive would fail
|
|
1352
|
+
//
|
|
1353
|
+
|
|
1354
|
+
// Clear the lower 2 bits in order to make sure that the value is aligned to 4 bytes
|
|
1355
|
+
if((hf->SectorOffsets[0] & 0xFFFFFFFC) > dwSectorOffsLen)
|
|
1356
|
+
{
|
|
1357
|
+
// MPQ protectors put some ridiculous values there. We must limit the extra bytes
|
|
1358
|
+
if(hf->SectorOffsets[0] > (dwSectorOffsLen + 0x400))
|
|
1359
|
+
return ERROR_FILE_CORRUPT;
|
|
1360
|
+
|
|
1361
|
+
// Free the old sector offset table
|
|
1362
|
+
dwSectorOffsLen = hf->SectorOffsets[0];
|
|
1363
|
+
STORM_FREE(hf->SectorOffsets);
|
|
1364
|
+
goto __LoadSectorOffsets;
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
else
|
|
1368
|
+
{
|
|
1369
|
+
memset(hf->SectorOffsets, 0, dwSectorOffsLen);
|
|
1370
|
+
hf->SectorOffsets[0] = dwSectorOffsLen;
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
return ERROR_SUCCESS;
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
DWORD AllocateSectorChecksums(TMPQFile * hf, bool bLoadFromFile)
|
|
1378
|
+
{
|
|
1379
|
+
TMPQArchive * ha = hf->ha;
|
|
1380
|
+
TFileEntry * pFileEntry = hf->pFileEntry;
|
|
1381
|
+
ULONGLONG RawFilePos;
|
|
1382
|
+
DWORD dwCompressedSize = 0;
|
|
1383
|
+
DWORD dwExpectedSize;
|
|
1384
|
+
DWORD dwCrcOffset; // Offset of the CRC table, relative to file offset in the MPQ
|
|
1385
|
+
DWORD dwCrcSize;
|
|
1386
|
+
|
|
1387
|
+
// Caller of AllocateSectorChecksums must ensure these
|
|
1388
|
+
assert(hf->SectorChksums == NULL);
|
|
1389
|
+
assert(hf->SectorOffsets != NULL);
|
|
1390
|
+
assert(hf->pFileEntry != NULL);
|
|
1391
|
+
assert(hf->ha != NULL);
|
|
1392
|
+
|
|
1393
|
+
// Single unit files don't have sector checksums
|
|
1394
|
+
if(pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT)
|
|
1395
|
+
return ERROR_SUCCESS;
|
|
1396
|
+
|
|
1397
|
+
// Caller must ensure that we are only called when we have sector checksums
|
|
1398
|
+
assert(pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC);
|
|
1399
|
+
|
|
1400
|
+
//
|
|
1401
|
+
// Older MPQs store an array of CRC32's after
|
|
1402
|
+
// the raw file data in the MPQ.
|
|
1403
|
+
//
|
|
1404
|
+
// In newer MPQs, the (since Cataclysm BETA) the (attributes) file
|
|
1405
|
+
// contains additional 32-bit values beyond the sector table.
|
|
1406
|
+
// Their number depends on size of the (attributes), but their
|
|
1407
|
+
// meaning is unknown. They are usually zeroed in retail game files,
|
|
1408
|
+
// but contain some sort of checksum in BETA MPQs
|
|
1409
|
+
//
|
|
1410
|
+
|
|
1411
|
+
// Does the size of the file table match with the CRC32-based checksums?
|
|
1412
|
+
dwExpectedSize = (hf->dwSectorCount + 2) * sizeof(DWORD);
|
|
1413
|
+
if(hf->SectorOffsets[0] != 0 && hf->SectorOffsets[0] == dwExpectedSize)
|
|
1414
|
+
{
|
|
1415
|
+
// If we are not loading from the MPQ file, we just allocate the sector table
|
|
1416
|
+
// In that case, do not check any sizes
|
|
1417
|
+
if(bLoadFromFile == false)
|
|
1418
|
+
{
|
|
1419
|
+
hf->SectorChksums = STORM_ALLOC(DWORD, hf->dwSectorCount);
|
|
1420
|
+
if(hf->SectorChksums == NULL)
|
|
1421
|
+
return ERROR_NOT_ENOUGH_MEMORY;
|
|
1422
|
+
|
|
1423
|
+
// Fill the checksum table with zeros
|
|
1424
|
+
memset(hf->SectorChksums, 0, hf->dwSectorCount * sizeof(DWORD));
|
|
1425
|
+
return ERROR_SUCCESS;
|
|
1426
|
+
}
|
|
1427
|
+
else
|
|
1428
|
+
{
|
|
1429
|
+
// Is there valid size of the sector checksums?
|
|
1430
|
+
if(hf->SectorOffsets[hf->dwSectorCount + 1] >= hf->SectorOffsets[hf->dwSectorCount])
|
|
1431
|
+
dwCompressedSize = hf->SectorOffsets[hf->dwSectorCount + 1] - hf->SectorOffsets[hf->dwSectorCount];
|
|
1432
|
+
|
|
1433
|
+
// Ignore cases when the length is too small or too big.
|
|
1434
|
+
if(dwCompressedSize < sizeof(DWORD) || dwCompressedSize > hf->dwSectorSize)
|
|
1435
|
+
return ERROR_SUCCESS;
|
|
1436
|
+
|
|
1437
|
+
// Calculate offset of the CRC table
|
|
1438
|
+
dwCrcSize = hf->dwSectorCount * sizeof(DWORD);
|
|
1439
|
+
dwCrcOffset = hf->SectorOffsets[hf->dwSectorCount];
|
|
1440
|
+
RawFilePos = CalculateRawSectorOffset(hf, dwCrcOffset);
|
|
1441
|
+
|
|
1442
|
+
// Now read the table from the MPQ
|
|
1443
|
+
hf->SectorChksums = (DWORD *)LoadMpqTable(ha, RawFilePos, NULL, dwCompressedSize, dwCrcSize, 0, NULL);
|
|
1444
|
+
if(hf->SectorChksums == NULL)
|
|
1445
|
+
return ERROR_NOT_ENOUGH_MEMORY;
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
// If the size doesn't match, we ignore sector checksums
|
|
1450
|
+
// assert(false);
|
|
1451
|
+
return ERROR_SUCCESS;
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
DWORD WritePatchInfo(TMPQFile * hf)
|
|
1455
|
+
{
|
|
1456
|
+
TMPQArchive * ha = hf->ha;
|
|
1457
|
+
TPatchInfo * pPatchInfo = hf->pPatchInfo;
|
|
1458
|
+
|
|
1459
|
+
// The caller must make sure that this function is only called
|
|
1460
|
+
// when the following is true.
|
|
1461
|
+
assert(hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE);
|
|
1462
|
+
assert(pPatchInfo != NULL);
|
|
1463
|
+
|
|
1464
|
+
BSWAP_ARRAY32_UNSIGNED(pPatchInfo, 3 * sizeof(DWORD));
|
|
1465
|
+
if(!FileStream_Write(ha->pStream, &hf->RawFilePos, pPatchInfo, sizeof(TPatchInfo)))
|
|
1466
|
+
return GetLastError();
|
|
1467
|
+
|
|
1468
|
+
return ERROR_SUCCESS;
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
DWORD WriteSectorOffsets(TMPQFile * hf)
|
|
1472
|
+
{
|
|
1473
|
+
TMPQArchive * ha = hf->ha;
|
|
1474
|
+
TFileEntry * pFileEntry = hf->pFileEntry;
|
|
1475
|
+
ULONGLONG RawFilePos = hf->RawFilePos;
|
|
1476
|
+
DWORD dwSectorOffsLen;
|
|
1477
|
+
|
|
1478
|
+
// The caller must make sure that this function is only called
|
|
1479
|
+
// when the following is true.
|
|
1480
|
+
assert(hf->pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK);
|
|
1481
|
+
assert(hf->SectorOffsets != NULL);
|
|
1482
|
+
dwSectorOffsLen = hf->SectorOffsets[0];
|
|
1483
|
+
|
|
1484
|
+
// If file is encrypted, sector positions are also encrypted
|
|
1485
|
+
if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
|
|
1486
|
+
EncryptMpqBlock(hf->SectorOffsets, dwSectorOffsLen, hf->dwFileKey - 1);
|
|
1487
|
+
BSWAP_ARRAY32_UNSIGNED(hf->SectorOffsets, dwSectorOffsLen);
|
|
1488
|
+
|
|
1489
|
+
// Adjust sector offset table position, if we also have patch info
|
|
1490
|
+
if(hf->pPatchInfo != NULL)
|
|
1491
|
+
RawFilePos += hf->pPatchInfo->dwLength;
|
|
1492
|
+
|
|
1493
|
+
// Write sector offsets to the archive
|
|
1494
|
+
if(!FileStream_Write(ha->pStream, &RawFilePos, hf->SectorOffsets, dwSectorOffsLen))
|
|
1495
|
+
return GetLastError();
|
|
1496
|
+
|
|
1497
|
+
// Not necessary, as the sector checksums
|
|
1498
|
+
// are going to be freed when this is done.
|
|
1499
|
+
// BSWAP_ARRAY32_UNSIGNED(hf->SectorOffsets, dwSectorOffsLen);
|
|
1500
|
+
return ERROR_SUCCESS;
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
DWORD WriteSectorChecksums(TMPQFile * hf)
|
|
1504
|
+
{
|
|
1505
|
+
TMPQArchive * ha = hf->ha;
|
|
1506
|
+
ULONGLONG RawFilePos;
|
|
1507
|
+
TFileEntry * pFileEntry = hf->pFileEntry;
|
|
1508
|
+
LPBYTE pbCompressed;
|
|
1509
|
+
DWORD dwCompressedSize = 0;
|
|
1510
|
+
DWORD dwErrCode = ERROR_SUCCESS;
|
|
1511
|
+
DWORD dwCrcSize;
|
|
1512
|
+
int nOutSize;
|
|
1513
|
+
|
|
1514
|
+
// The caller must make sure that this function is only called
|
|
1515
|
+
// when the following is true.
|
|
1516
|
+
assert(hf->pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC);
|
|
1517
|
+
assert(hf->SectorOffsets != NULL);
|
|
1518
|
+
assert(hf->SectorChksums != NULL);
|
|
1519
|
+
|
|
1520
|
+
// If the MPQ has MD5 of each raw data chunk,
|
|
1521
|
+
// we leave sector offsets empty
|
|
1522
|
+
if(ha->pHeader->dwRawChunkSize != 0)
|
|
1523
|
+
{
|
|
1524
|
+
hf->SectorOffsets[hf->dwSectorCount + 1] = hf->SectorOffsets[hf->dwSectorCount];
|
|
1525
|
+
return ERROR_SUCCESS;
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
// Calculate size of the checksum array
|
|
1529
|
+
dwCrcSize = hf->dwSectorCount * sizeof(DWORD);
|
|
1530
|
+
|
|
1531
|
+
// Allocate buffer for compressed sector CRCs.
|
|
1532
|
+
pbCompressed = STORM_ALLOC(BYTE, dwCrcSize);
|
|
1533
|
+
if(pbCompressed == NULL)
|
|
1534
|
+
return ERROR_NOT_ENOUGH_MEMORY;
|
|
1535
|
+
|
|
1536
|
+
// Perform the compression
|
|
1537
|
+
BSWAP_ARRAY32_UNSIGNED(hf->SectorChksums, dwCrcSize);
|
|
1538
|
+
|
|
1539
|
+
nOutSize = (int)dwCrcSize;
|
|
1540
|
+
SCompCompress(pbCompressed, &nOutSize, hf->SectorChksums, (int)dwCrcSize, MPQ_COMPRESSION_ZLIB, 0, 0);
|
|
1541
|
+
dwCompressedSize = (DWORD)nOutSize;
|
|
1542
|
+
|
|
1543
|
+
// Write the sector CRCs to the archive
|
|
1544
|
+
RawFilePos = hf->RawFilePos + hf->SectorOffsets[hf->dwSectorCount];
|
|
1545
|
+
if(hf->pPatchInfo != NULL)
|
|
1546
|
+
RawFilePos += hf->pPatchInfo->dwLength;
|
|
1547
|
+
if(!FileStream_Write(ha->pStream, &RawFilePos, pbCompressed, dwCompressedSize))
|
|
1548
|
+
dwErrCode = GetLastError();
|
|
1549
|
+
|
|
1550
|
+
// Not necessary, as the sector checksums
|
|
1551
|
+
// are going to be freed when this is done.
|
|
1552
|
+
// BSWAP_ARRAY32_UNSIGNED(hf->SectorChksums, dwCrcSize);
|
|
1553
|
+
|
|
1554
|
+
// Store the sector CRCs
|
|
1555
|
+
hf->SectorOffsets[hf->dwSectorCount + 1] = hf->SectorOffsets[hf->dwSectorCount] + dwCompressedSize;
|
|
1556
|
+
pFileEntry->dwCmpSize += dwCompressedSize;
|
|
1557
|
+
STORM_FREE(pbCompressed);
|
|
1558
|
+
return dwErrCode;
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
DWORD WriteMemDataMD5(
|
|
1562
|
+
TFileStream * pStream,
|
|
1563
|
+
ULONGLONG RawDataOffs,
|
|
1564
|
+
void * pvRawData,
|
|
1565
|
+
DWORD dwRawDataSize,
|
|
1566
|
+
DWORD dwChunkSize,
|
|
1567
|
+
LPDWORD pcbTotalSize)
|
|
1568
|
+
{
|
|
1569
|
+
unsigned char * md5_array;
|
|
1570
|
+
unsigned char * md5;
|
|
1571
|
+
LPBYTE pbRawData = (LPBYTE)pvRawData;
|
|
1572
|
+
DWORD dwBytesRemaining = dwRawDataSize;
|
|
1573
|
+
DWORD dwMd5ArraySize = 0;
|
|
1574
|
+
DWORD dwErrCode = ERROR_SUCCESS;
|
|
1575
|
+
|
|
1576
|
+
// Allocate buffer for array of MD5
|
|
1577
|
+
md5_array = md5 = AllocateMd5Buffer(dwRawDataSize, dwChunkSize, &dwMd5ArraySize);
|
|
1578
|
+
if(md5_array == NULL)
|
|
1579
|
+
return ERROR_NOT_ENOUGH_MEMORY;
|
|
1580
|
+
|
|
1581
|
+
// For every file chunk, calculate MD5
|
|
1582
|
+
while(dwBytesRemaining != 0)
|
|
1583
|
+
{
|
|
1584
|
+
// Get the remaining number of bytes to read
|
|
1585
|
+
dwChunkSize = STORMLIB_MIN(dwBytesRemaining, dwChunkSize);
|
|
1586
|
+
|
|
1587
|
+
// Calculate MD5
|
|
1588
|
+
CalculateDataBlockHash(pbRawData, dwChunkSize, md5);
|
|
1589
|
+
md5 += MD5_DIGEST_SIZE;
|
|
1590
|
+
|
|
1591
|
+
// Move offset and size
|
|
1592
|
+
dwBytesRemaining -= dwChunkSize;
|
|
1593
|
+
pbRawData += dwChunkSize;
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
// Write the array od MD5's to the file
|
|
1597
|
+
RawDataOffs += dwRawDataSize;
|
|
1598
|
+
if(!FileStream_Write(pStream, &RawDataOffs, md5_array, dwMd5ArraySize))
|
|
1599
|
+
dwErrCode = GetLastError();
|
|
1600
|
+
|
|
1601
|
+
// Give the caller the size of the MD5 array
|
|
1602
|
+
if(pcbTotalSize != NULL)
|
|
1603
|
+
*pcbTotalSize = dwRawDataSize + dwMd5ArraySize;
|
|
1604
|
+
|
|
1605
|
+
// Free buffers and exit
|
|
1606
|
+
STORM_FREE(md5_array);
|
|
1607
|
+
return dwErrCode;
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
|
|
1611
|
+
// Writes the MD5 for each chunk of the raw file data
|
|
1612
|
+
DWORD WriteMpqDataMD5(
|
|
1613
|
+
TFileStream * pStream,
|
|
1614
|
+
ULONGLONG RawDataOffs,
|
|
1615
|
+
DWORD dwRawDataSize,
|
|
1616
|
+
DWORD dwChunkSize)
|
|
1617
|
+
{
|
|
1618
|
+
unsigned char * md5_array;
|
|
1619
|
+
unsigned char * md5;
|
|
1620
|
+
LPBYTE pbFileChunk;
|
|
1621
|
+
DWORD dwMd5ArraySize = 0;
|
|
1622
|
+
DWORD dwToRead = dwRawDataSize;
|
|
1623
|
+
DWORD dwErrCode = ERROR_SUCCESS;
|
|
1624
|
+
|
|
1625
|
+
// Allocate buffer for array of MD5
|
|
1626
|
+
md5_array = md5 = AllocateMd5Buffer(dwRawDataSize, dwChunkSize, &dwMd5ArraySize);
|
|
1627
|
+
if(md5_array == NULL)
|
|
1628
|
+
return ERROR_NOT_ENOUGH_MEMORY;
|
|
1629
|
+
|
|
1630
|
+
// Allocate space for file chunk
|
|
1631
|
+
pbFileChunk = STORM_ALLOC(BYTE, dwChunkSize);
|
|
1632
|
+
if(pbFileChunk == NULL)
|
|
1633
|
+
{
|
|
1634
|
+
STORM_FREE(md5_array);
|
|
1635
|
+
return ERROR_NOT_ENOUGH_MEMORY;
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
// For every file chunk, calculate MD5
|
|
1639
|
+
while(dwRawDataSize != 0)
|
|
1640
|
+
{
|
|
1641
|
+
// Get the remaining number of bytes to read
|
|
1642
|
+
dwToRead = STORMLIB_MIN(dwRawDataSize, dwChunkSize);
|
|
1643
|
+
|
|
1644
|
+
// Read the chunk
|
|
1645
|
+
if(!FileStream_Read(pStream, &RawDataOffs, pbFileChunk, dwToRead))
|
|
1646
|
+
{
|
|
1647
|
+
dwErrCode = GetLastError();
|
|
1648
|
+
break;
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
// Calculate MD5
|
|
1652
|
+
CalculateDataBlockHash(pbFileChunk, dwToRead, md5);
|
|
1653
|
+
md5 += MD5_DIGEST_SIZE;
|
|
1654
|
+
|
|
1655
|
+
// Move offset and size
|
|
1656
|
+
RawDataOffs += dwToRead;
|
|
1657
|
+
dwRawDataSize -= dwToRead;
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
// Write the array od MD5's to the file
|
|
1661
|
+
if(dwErrCode == ERROR_SUCCESS)
|
|
1662
|
+
{
|
|
1663
|
+
if(!FileStream_Write(pStream, NULL, md5_array, dwMd5ArraySize))
|
|
1664
|
+
dwErrCode = GetLastError();
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
// Free buffers and exit
|
|
1668
|
+
STORM_FREE(pbFileChunk);
|
|
1669
|
+
STORM_FREE(md5_array);
|
|
1670
|
+
return dwErrCode;
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
// Frees the structure for MPQ file
|
|
1674
|
+
void FreeFileHandle(TMPQFile *& hf)
|
|
1675
|
+
{
|
|
1676
|
+
if(hf != NULL)
|
|
1677
|
+
{
|
|
1678
|
+
// If we have patch file attached to this one, free it first
|
|
1679
|
+
if(hf->hfPatch != NULL)
|
|
1680
|
+
FreeFileHandle(hf->hfPatch);
|
|
1681
|
+
|
|
1682
|
+
// Then free all buffers allocated in the file structure
|
|
1683
|
+
if(hf->pbFileData != NULL)
|
|
1684
|
+
STORM_FREE(hf->pbFileData);
|
|
1685
|
+
if(hf->pPatchInfo != NULL)
|
|
1686
|
+
STORM_FREE(hf->pPatchInfo);
|
|
1687
|
+
if(hf->SectorOffsets != NULL)
|
|
1688
|
+
STORM_FREE(hf->SectorOffsets);
|
|
1689
|
+
if(hf->SectorChksums != NULL)
|
|
1690
|
+
STORM_FREE(hf->SectorChksums);
|
|
1691
|
+
if(hf->hctx != NULL)
|
|
1692
|
+
STORM_FREE(hf->hctx);
|
|
1693
|
+
if(hf->pbFileSector != NULL)
|
|
1694
|
+
STORM_FREE(hf->pbFileSector);
|
|
1695
|
+
if(hf->pStream != NULL)
|
|
1696
|
+
FileStream_Close(hf->pStream);
|
|
1697
|
+
STORM_FREE(hf);
|
|
1698
|
+
hf = NULL;
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
|
|
1702
|
+
// Frees the MPQ archive
|
|
1703
|
+
void FreeArchiveHandle(TMPQArchive *& ha)
|
|
1704
|
+
{
|
|
1705
|
+
if(ha != NULL)
|
|
1706
|
+
{
|
|
1707
|
+
// First of all, free the patch archive, if any
|
|
1708
|
+
if(ha->haPatch != NULL)
|
|
1709
|
+
FreeArchiveHandle(ha->haPatch);
|
|
1710
|
+
|
|
1711
|
+
// Free the patch prefix, if any
|
|
1712
|
+
if(ha->pPatchPrefix != NULL)
|
|
1713
|
+
STORM_FREE(ha->pPatchPrefix);
|
|
1714
|
+
|
|
1715
|
+
// Close the file stream
|
|
1716
|
+
FileStream_Close(ha->pStream);
|
|
1717
|
+
ha->pStream = NULL;
|
|
1718
|
+
|
|
1719
|
+
// Free the file names from the file table
|
|
1720
|
+
if(ha->pFileTable != NULL)
|
|
1721
|
+
{
|
|
1722
|
+
for(DWORD i = 0; i < ha->dwFileTableSize; i++)
|
|
1723
|
+
{
|
|
1724
|
+
if(ha->pFileTable[i].szFileName != NULL)
|
|
1725
|
+
STORM_FREE(ha->pFileTable[i].szFileName);
|
|
1726
|
+
ha->pFileTable[i].szFileName = NULL;
|
|
1727
|
+
}
|
|
1728
|
+
|
|
1729
|
+
// Then free all buffers allocated in the archive structure
|
|
1730
|
+
STORM_FREE(ha->pFileTable);
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
if(ha->pHashTable != NULL)
|
|
1734
|
+
STORM_FREE(ha->pHashTable);
|
|
1735
|
+
if(ha->pHetTable != NULL)
|
|
1736
|
+
FreeHetTable(ha->pHetTable);
|
|
1737
|
+
STORM_FREE(ha);
|
|
1738
|
+
ha = NULL;
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
bool IsInternalMpqFileName(const char * szFileName)
|
|
1743
|
+
{
|
|
1744
|
+
if(szFileName != NULL && szFileName[0] == '(')
|
|
1745
|
+
{
|
|
1746
|
+
if(!_stricmp(szFileName, LISTFILE_NAME) ||
|
|
1747
|
+
!_stricmp(szFileName, ATTRIBUTES_NAME) ||
|
|
1748
|
+
!_stricmp(szFileName, SIGNATURE_NAME))
|
|
1749
|
+
{
|
|
1750
|
+
return true;
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
return false;
|
|
1755
|
+
}
|
|
1756
|
+
|
|
1757
|
+
// Verifies if the file name is a pseudo-name
|
|
1758
|
+
bool IsPseudoFileName(const char * szFileName, DWORD * pdwFileIndex)
|
|
1759
|
+
{
|
|
1760
|
+
DWORD dwFileIndex = 0;
|
|
1761
|
+
|
|
1762
|
+
if(szFileName != NULL)
|
|
1763
|
+
{
|
|
1764
|
+
// Must be "File########.ext"
|
|
1765
|
+
if(!_strnicmp(szFileName, "File", 4))
|
|
1766
|
+
{
|
|
1767
|
+
// Check 8 digits
|
|
1768
|
+
for(int i = 4; i < 4+8; i++)
|
|
1769
|
+
{
|
|
1770
|
+
if(szFileName[i] < '0' || szFileName[i] > '9')
|
|
1771
|
+
return false;
|
|
1772
|
+
dwFileIndex = (dwFileIndex * 10) + (szFileName[i] - '0');
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
// An extension must follow
|
|
1776
|
+
if(szFileName[12] == '.')
|
|
1777
|
+
{
|
|
1778
|
+
if(pdwFileIndex != NULL)
|
|
1779
|
+
*pdwFileIndex = dwFileIndex;
|
|
1780
|
+
return true;
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
// Not a pseudo-name
|
|
1786
|
+
return false;
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
//-----------------------------------------------------------------------------
|
|
1790
|
+
// Functions calculating and verifying the MD5 signature
|
|
1791
|
+
|
|
1792
|
+
bool IsValidMD5(LPBYTE pbMd5)
|
|
1793
|
+
{
|
|
1794
|
+
LPDWORD Md5 = (LPDWORD)pbMd5;
|
|
1795
|
+
|
|
1796
|
+
return ((Md5 != NULL) && (Md5[0] | Md5[1] | Md5[2] | Md5[3])) ? true : false;
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
bool IsValidSignature(LPBYTE pbSignature)
|
|
1800
|
+
{
|
|
1801
|
+
LPDWORD Signature = (LPDWORD)pbSignature;
|
|
1802
|
+
DWORD SigValid = 0;
|
|
1803
|
+
|
|
1804
|
+
for(int i = 0; i < MPQ_WEAK_SIGNATURE_SIZE / sizeof(DWORD); i++)
|
|
1805
|
+
SigValid |= Signature[i];
|
|
1806
|
+
|
|
1807
|
+
return (SigValid != 0) ? true : false;
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
|
|
1811
|
+
bool VerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5)
|
|
1812
|
+
{
|
|
1813
|
+
hash_state md5_state;
|
|
1814
|
+
BYTE md5_digest[MD5_DIGEST_SIZE];
|
|
1815
|
+
bool bResult = true;
|
|
1816
|
+
|
|
1817
|
+
// Don't verify the block if the MD5 is not valid.
|
|
1818
|
+
if(IsValidMD5(expected_md5))
|
|
1819
|
+
{
|
|
1820
|
+
// Calculate the MD5 of the data block
|
|
1821
|
+
md5_init(&md5_state);
|
|
1822
|
+
md5_process(&md5_state, (unsigned char *)pvDataBlock, cbDataBlock);
|
|
1823
|
+
md5_done(&md5_state, md5_digest);
|
|
1824
|
+
|
|
1825
|
+
// Does the MD5's match?
|
|
1826
|
+
bResult = (memcmp(md5_digest, expected_md5, MD5_DIGEST_SIZE) == 0);
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
return bResult;
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
void CalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_hash)
|
|
1833
|
+
{
|
|
1834
|
+
hash_state md5_state;
|
|
1835
|
+
|
|
1836
|
+
md5_init(&md5_state);
|
|
1837
|
+
md5_process(&md5_state, (unsigned char *)pvDataBlock, cbDataBlock);
|
|
1838
|
+
md5_done(&md5_state, md5_hash);
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1841
|
+
//-----------------------------------------------------------------------------
|
|
1842
|
+
// Swapping functions
|
|
1843
|
+
|
|
1844
|
+
#ifndef STORMLIB_LITTLE_ENDIAN
|
|
1845
|
+
|
|
1846
|
+
// Swaps a signed 16-bit integer
|
|
1847
|
+
int16_t SwapInt16(uint16_t val)
|
|
1848
|
+
{
|
|
1849
|
+
return (val << 8) | ((val >> 8) & 0xFF);
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1852
|
+
// Swaps an unsigned 16-bit integer
|
|
1853
|
+
uint16_t SwapUInt16(uint16_t val)
|
|
1854
|
+
{
|
|
1855
|
+
return (val << 8) | (val >> 8 );
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1858
|
+
// Swaps a signed 32-bit integer
|
|
1859
|
+
int32_t SwapInt32(uint32_t val)
|
|
1860
|
+
{
|
|
1861
|
+
val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF );
|
|
1862
|
+
return (val << 16) | ((val >> 16) & 0xFFFF);
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1865
|
+
// Swaps an unsigned 32-bit integer
|
|
1866
|
+
uint32_t SwapUInt32(uint32_t val)
|
|
1867
|
+
{
|
|
1868
|
+
val = ((val << 8) & 0xFF00FF00 ) | ((val >> 8) & 0xFF00FF );
|
|
1869
|
+
return (val << 16) | (val >> 16);
|
|
1870
|
+
}
|
|
1871
|
+
|
|
1872
|
+
// Swaps a signed 64-bit integer
|
|
1873
|
+
int64_t SwapInt64(uint64_t val)
|
|
1874
|
+
{
|
|
1875
|
+
val = ((val << 8) & 0xFF00FF00FF00FF00ULL ) | ((val >> 8) & 0x00FF00FF00FF00FFULL );
|
|
1876
|
+
val = ((val << 16) & 0xFFFF0000FFFF0000ULL ) | ((val >> 16) & 0x0000FFFF0000FFFFULL );
|
|
1877
|
+
return (val << 32) | ((val >> 32) & 0xFFFFFFFFULL);
|
|
1878
|
+
}
|
|
1879
|
+
|
|
1880
|
+
// Swaps an unsigned 64-bit integer
|
|
1881
|
+
uint64_t SwapUInt64(uint64_t val)
|
|
1882
|
+
{
|
|
1883
|
+
val = ((val << 8) & 0xFF00FF00FF00FF00ULL ) | ((val >> 8) & 0x00FF00FF00FF00FFULL );
|
|
1884
|
+
val = ((val << 16) & 0xFFFF0000FFFF0000ULL ) | ((val >> 16) & 0x0000FFFF0000FFFFULL );
|
|
1885
|
+
return (val << 32) | (val >> 32);
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1888
|
+
// Swaps array of unsigned 16-bit integers
|
|
1889
|
+
void ConvertUInt16Buffer(void * ptr, size_t length)
|
|
1890
|
+
{
|
|
1891
|
+
uint16_t * buffer = (uint16_t *)ptr;
|
|
1892
|
+
uint32_t nElements = (uint32_t)(length / sizeof(uint16_t));
|
|
1893
|
+
|
|
1894
|
+
while(nElements-- > 0)
|
|
1895
|
+
{
|
|
1896
|
+
*buffer = SwapUInt16(*buffer);
|
|
1897
|
+
buffer++;
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
|
|
1901
|
+
// Swaps array of unsigned 32-bit integers
|
|
1902
|
+
void ConvertUInt32Buffer(void * ptr, size_t length)
|
|
1903
|
+
{
|
|
1904
|
+
uint32_t * buffer = (uint32_t *)ptr;
|
|
1905
|
+
uint32_t nElements = (uint32_t)(length / sizeof(uint32_t));
|
|
1906
|
+
|
|
1907
|
+
while(nElements-- > 0)
|
|
1908
|
+
{
|
|
1909
|
+
*buffer = SwapUInt32(*buffer);
|
|
1910
|
+
buffer++;
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1914
|
+
// Swaps array of unsigned 64-bit integers
|
|
1915
|
+
void ConvertUInt64Buffer(void * ptr, size_t length)
|
|
1916
|
+
{
|
|
1917
|
+
uint64_t * buffer = (uint64_t *)ptr;
|
|
1918
|
+
uint32_t nElements = (uint32_t)(length / sizeof(uint64_t));
|
|
1919
|
+
|
|
1920
|
+
while(nElements-- > 0)
|
|
1921
|
+
{
|
|
1922
|
+
*buffer = SwapUInt64(*buffer);
|
|
1923
|
+
buffer++;
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
|
|
1927
|
+
// Swaps the TMPQHeader structure
|
|
1928
|
+
void ConvertTMPQHeader(void *header, uint16_t version)
|
|
1929
|
+
{
|
|
1930
|
+
TMPQHeader * theHeader = (TMPQHeader *)header;
|
|
1931
|
+
|
|
1932
|
+
// Swap header part version 1
|
|
1933
|
+
if(version >= MPQ_FORMAT_VERSION_1)
|
|
1934
|
+
{
|
|
1935
|
+
theHeader->dwID = SwapUInt32(theHeader->dwID);
|
|
1936
|
+
theHeader->dwHeaderSize = SwapUInt32(theHeader->dwHeaderSize);
|
|
1937
|
+
theHeader->dwArchiveSize = SwapUInt32(theHeader->dwArchiveSize);
|
|
1938
|
+
theHeader->wFormatVersion = SwapUInt16(theHeader->wFormatVersion);
|
|
1939
|
+
theHeader->wSectorSize = SwapUInt16(theHeader->wSectorSize);
|
|
1940
|
+
theHeader->dwHashTablePos = SwapUInt32(theHeader->dwHashTablePos);
|
|
1941
|
+
theHeader->dwBlockTablePos = SwapUInt32(theHeader->dwBlockTablePos);
|
|
1942
|
+
theHeader->dwHashTableSize = SwapUInt32(theHeader->dwHashTableSize);
|
|
1943
|
+
theHeader->dwBlockTableSize = SwapUInt32(theHeader->dwBlockTableSize);
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
if(version >= MPQ_FORMAT_VERSION_2)
|
|
1947
|
+
{
|
|
1948
|
+
theHeader->HiBlockTablePos64 = SwapUInt64(theHeader->HiBlockTablePos64);
|
|
1949
|
+
theHeader->wHashTablePosHi = SwapUInt16(theHeader->wHashTablePosHi);
|
|
1950
|
+
theHeader->wBlockTablePosHi = SwapUInt16(theHeader->wBlockTablePosHi);
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
if(version >= MPQ_FORMAT_VERSION_3)
|
|
1954
|
+
{
|
|
1955
|
+
theHeader->ArchiveSize64 = SwapUInt64(theHeader->ArchiveSize64);
|
|
1956
|
+
theHeader->BetTablePos64 = SwapUInt64(theHeader->BetTablePos64);
|
|
1957
|
+
theHeader->HetTablePos64 = SwapUInt64(theHeader->HetTablePos64);
|
|
1958
|
+
}
|
|
1959
|
+
|
|
1960
|
+
if(version >= MPQ_FORMAT_VERSION_4)
|
|
1961
|
+
{
|
|
1962
|
+
theHeader->HashTableSize64 = SwapUInt64(theHeader->HashTableSize64);
|
|
1963
|
+
theHeader->BlockTableSize64 = SwapUInt64(theHeader->BlockTableSize64);
|
|
1964
|
+
theHeader->HiBlockTableSize64 = SwapUInt64(theHeader->HiBlockTableSize64);
|
|
1965
|
+
theHeader->HetTableSize64 = SwapUInt64(theHeader->HetTableSize64);
|
|
1966
|
+
theHeader->BetTableSize64 = SwapUInt64(theHeader->BetTableSize64);
|
|
1967
|
+
}
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1970
|
+
#endif // STORMLIB_LITTLE_ENDIAN
|