From b3e299dbdee829c12ada556a1c3aa1f109a0e05b Mon Sep 17 00:00:00 2001 From: Nicholas Estelami Date: Wed, 1 Jun 2022 16:05:05 -0400 Subject: [PATCH] Replaced StormLib .lib files with source code. Some modifications to handle backslashes and forward slashes, along with some optimizations to speed up OTR generation. --- OTRExporter/OTRExporter.sln | 11 + OTRExporter/OTRExporter/OTRExporter.vcxproj | 4 +- StormLib/.gitignore | 167 + StormLib/Info.plist | 22 + StormLib/LICENSE | 21 + StormLib/PostBuild.bat | 34 + StormLib/Premake5.lua | 132 + StormLib/Publish.bat | 25 + StormLib/README.md | 39 + StormLib/StormLib.kdev4 | 3 + StormLib/StormLib.xcodeproj/project.pbxproj | 2104 +++++++ StormLib/StormLib_vs08.sln | 139 + StormLib/StormLib_vs08.vcproj | 5017 +++++++++++++++++ StormLib/StormLib_vs08_dll.vcproj | 2663 +++++++++ StormLib/StormLib_vs08_test.vcproj | 2101 +++++++ StormLib/StormLib_vs19.sln | 162 + StormLib/StormLib_vs19.vcxproj | 1187 ++++ StormLib/StormLib_vs19.vcxproj.filters | 830 +++ StormLib/StormLib_vs19_dll.vcxproj | 537 ++ StormLib/StormLib_vs19_dll.vcxproj.filters | 838 +++ StormLib/StormLib_vs19_test.vcxproj | 549 ++ StormLib/StormLib_vs19_test.vcxproj.filters | 839 +++ StormLib/doc/History.txt | 78 + StormLib/doc/The MoPaQ File Format 0.9.txt | 318 ++ StormLib/doc/The MoPaQ File Format 1.0.txt | 433 ++ .../d3-authenticationcode-deDE.txt | 1 + .../d3-authenticationcode-enGB.txt | 1 + .../d3-authenticationcode-enSG.txt | 1 + .../d3-authenticationcode-enUS.txt | 1 + .../d3-authenticationcode-esES.txt | 1 + .../d3-authenticationcode-esMX.txt | 1 + .../d3-authenticationcode-frFR.txt | 1 + .../d3-authenticationcode-itIT.txt | 1 + .../d3-authenticationcode-koKR.txt | 1 + .../d3-authenticationcode-plPL.txt | 1 + .../d3-authenticationcode-ptBR.txt | 1 + .../d3-authenticationcode-zhTW.txt | 1 + .../hots-authenticationcode-bgdl.txt | 1 + .../sc2-authenticationcode-deDE.txt | 1 + .../sc2-authenticationcode-enGB.txt | 1 + .../sc2-authenticationcode-enUS.txt | 1 + .../sc2-authenticationcode-esES.txt | 1 + .../sc2-authenticationcode-esMX.txt | 1 + .../sc2-authenticationcode-frFR.txt | 1 + .../sc2-authenticationcode-itIT.txt | 1 + .../sc2-authenticationcode-koKR.txt | 1 + .../sc2-authenticationcode-plPL.txt | 1 + .../sc2-authenticationcode-ptBR.txt | 1 + .../sc2-authenticationcode-ruRU.txt | 1 + .../sc2-authenticationcode-zhTW.txt | 1 + StormLib/make-msvc.bat | 60 + StormLib/make.bat | 46 + StormLib/sources | 14 + StormLib/src/DllMain.c | 24 + StormLib/src/DllMain.def | 79 + StormLib/src/DllMain.rc | 114 + StormLib/src/FileStream.cpp | 2923 ++++++++++ StormLib/src/FileStream.h | 217 + StormLib/src/SBaseCommon.cpp | 1967 +++++++ StormLib/src/SBaseDumpData.cpp | 183 + StormLib/src/SBaseFileTable.cpp | 3101 ++++++++++ StormLib/src/SBaseSubTypes.cpp | 618 ++ StormLib/src/SCompression.cpp | 1124 ++++ StormLib/src/SFileAddFile.cpp | 1316 +++++ StormLib/src/SFileAttributes.cpp | 570 ++ StormLib/src/SFileCompactArchive.cpp | 654 +++ StormLib/src/SFileCreateArchive.cpp | 276 + StormLib/src/SFileExtractFile.cpp | 64 + StormLib/src/SFileFindFile.cpp | 483 ++ StormLib/src/SFileGetFileInfo.cpp | 607 ++ StormLib/src/SFileListFile.cpp | 686 +++ StormLib/src/SFileOpenArchive.cpp | 658 +++ StormLib/src/SFileOpenFileEx.cpp | 418 ++ StormLib/src/SFilePatchArchives.cpp | 1175 ++++ StormLib/src/SFileReadFile.cpp | 897 +++ StormLib/src/SFileVerify.cpp | 1054 ++++ StormLib/src/StormCommon.h | 440 ++ StormLib/src/StormLib.exp | 74 + .../Lib/StormLib => StormLib/src}/StormLib.h | 16 +- .../Lib/StormLib => StormLib/src}/StormPort.h | 0 StormLib/src/adpcm/adpcm.cpp | 401 ++ StormLib/src/adpcm/adpcm.h | 26 + StormLib/src/bzip2/blocksort.c | 1094 ++++ StormLib/src/bzip2/bzlib.c | 1573 ++++++ StormLib/src/bzip2/bzlib.h | 282 + StormLib/src/bzip2/bzlib_private.h | 509 ++ StormLib/src/bzip2/compress.c | 672 +++ StormLib/src/bzip2/crctable.c | 104 + StormLib/src/bzip2/decompress.c | 626 ++ StormLib/src/bzip2/huffman.c | 205 + StormLib/src/bzip2/randtable.c | 84 + StormLib/src/huffman/huff.cpp | 892 +++ StormLib/src/huffman/huff.h | 143 + StormLib/src/jenkins/lookup.h | 24 + StormLib/src/jenkins/lookup3.c | 1003 ++++ .../src/libtomcrypt/src/hashes/hash_memory.c | 69 + StormLib/src/libtomcrypt/src/hashes/md5.c | 368 ++ StormLib/src/libtomcrypt/src/hashes/sha1.c | 288 + .../src/libtomcrypt/src/headers/tomcrypt.h | 91 + .../libtomcrypt/src/headers/tomcrypt_argchk.h | 38 + .../libtomcrypt/src/headers/tomcrypt_cfg.h | 144 + .../libtomcrypt/src/headers/tomcrypt_cipher.h | 891 +++ .../libtomcrypt/src/headers/tomcrypt_custom.h | 424 ++ .../libtomcrypt/src/headers/tomcrypt_hash.h | 378 ++ .../libtomcrypt/src/headers/tomcrypt_mac.h | 384 ++ .../libtomcrypt/src/headers/tomcrypt_macros.h | 424 ++ .../libtomcrypt/src/headers/tomcrypt_math.h | 500 ++ .../libtomcrypt/src/headers/tomcrypt_misc.h | 23 + .../src/libtomcrypt/src/headers/tomcrypt_pk.h | 558 ++ .../libtomcrypt/src/headers/tomcrypt_pkcs.h | 89 + .../libtomcrypt/src/headers/tomcrypt_prng.h | 199 + StormLib/src/libtomcrypt/src/math/ltm_desc.c | 483 ++ StormLib/src/libtomcrypt/src/math/multi.c | 61 + .../src/libtomcrypt/src/math/rand_prime.c | 87 + .../src/libtomcrypt/src/misc/base64_decode.c | 104 + .../src/libtomcrypt/src/misc/crypt_argchk.c | 30 + .../libtomcrypt/src/misc/crypt_find_hash.c | 40 + .../libtomcrypt/src/misc/crypt_find_prng.c | 41 + .../src/misc/crypt_hash_descriptor.c | 27 + .../src/misc/crypt_hash_is_valid.c | 36 + .../src/libtomcrypt/src/misc/crypt_libc.c | 43 + .../src/misc/crypt_ltc_mp_descriptor.c | 13 + .../src/misc/crypt_prng_descriptor.c | 26 + .../src/misc/crypt_prng_is_valid.c | 36 + .../src/misc/crypt_register_hash.c | 54 + .../src/misc/crypt_register_prng.c | 54 + StormLib/src/libtomcrypt/src/misc/zeromem.c | 34 + .../src/pk/asn1/der_decode_bit_string.c | 102 + .../src/pk/asn1/der_decode_boolean.c | 47 + .../src/pk/asn1/der_decode_choice.c | 182 + .../src/pk/asn1/der_decode_ia5_string.c | 96 + .../src/pk/asn1/der_decode_integer.c | 110 + .../pk/asn1/der_decode_object_identifier.c | 99 + .../src/pk/asn1/der_decode_octet_string.c | 91 + .../src/pk/asn1/der_decode_printable_string.c | 96 + .../src/pk/asn1/der_decode_sequence_ex.c | 287 + .../src/pk/asn1/der_decode_sequence_flexi.c | 386 ++ .../src/pk/asn1/der_decode_sequence_multi.c | 139 + .../src/pk/asn1/der_decode_short_integer.c | 68 + .../src/pk/asn1/der_decode_utctime.c | 127 + .../src/pk/asn1/der_decode_utf8_string.c | 111 + .../src/pk/asn1/der_encode_bit_string.c | 89 + .../src/pk/asn1/der_encode_boolean.c | 51 + .../src/pk/asn1/der_encode_ia5_string.c | 85 + .../src/pk/asn1/der_encode_integer.c | 130 + .../pk/asn1/der_encode_object_identifier.c | 111 + .../src/pk/asn1/der_encode_octet_string.c | 86 + .../src/pk/asn1/der_encode_printable_string.c | 85 + .../src/pk/asn1/der_encode_sequence_ex.c | 335 ++ .../src/pk/asn1/der_encode_sequence_multi.c | 138 + .../libtomcrypt/src/pk/asn1/der_encode_set.c | 103 + .../src/pk/asn1/der_encode_setof.c | 162 + .../src/pk/asn1/der_encode_short_integer.c | 97 + .../src/pk/asn1/der_encode_utctime.c | 83 + .../src/pk/asn1/der_encode_utf8_string.c | 105 + .../src/pk/asn1/der_length_bit_string.c | 54 + .../src/pk/asn1/der_length_boolean.c | 35 + .../src/pk/asn1/der_length_ia5_string.c | 194 + .../src/pk/asn1/der_length_integer.c | 82 + .../pk/asn1/der_length_object_identifier.c | 89 + .../src/pk/asn1/der_length_octet_string.c | 53 + .../src/pk/asn1/der_length_printable_string.c | 166 + .../src/pk/asn1/der_length_sequence.c | 169 + .../src/pk/asn1/der_length_short_integer.c | 70 + .../src/pk/asn1/der_length_utctime.c | 46 + .../src/pk/asn1/der_length_utf8_string.c | 83 + .../src/pk/asn1/der_sequence_free.c | 65 + .../src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c | 76 + .../libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c | 207 + .../libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c | 222 + .../libtomcrypt/src/pk/ecc/ltc_ecc_points.c | 60 + .../src/pk/ecc/ltc_ecc_projective_add_point.c | 196 + .../src/pk/ecc/ltc_ecc_projective_dbl_point.c | 147 + .../libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c | 108 + .../src/pk/pkcs1/pkcs_1_oaep_decode.c | 189 + .../src/pk/pkcs1/pkcs_1_pss_decode.c | 177 + .../src/pk/pkcs1/pkcs_1_pss_encode.c | 175 + .../src/pk/pkcs1/pkcs_1_v1_5_decode.c | 110 + .../src/pk/pkcs1/pkcs_1_v1_5_encode.c | 111 + .../src/libtomcrypt/src/pk/rsa/rsa_exptmod.c | 113 + .../src/libtomcrypt/src/pk/rsa/rsa_free.c | 34 + .../src/libtomcrypt/src/pk/rsa/rsa_import.c | 143 + .../src/libtomcrypt/src/pk/rsa/rsa_make_key.c | 112 + .../libtomcrypt/src/pk/rsa/rsa_sign_hash.c | 134 + .../libtomcrypt/src/pk/rsa/rsa_verify_hash.c | 167 + .../src/pk/rsa/rsa_verify_simple.c | 87 + StormLib/src/libtommath/bn_fast_mp_invmod.c | 148 + .../libtommath/bn_fast_mp_montgomery_reduce.c | 172 + .../src/libtommath/bn_fast_s_mp_mul_digs.c | 107 + .../libtommath/bn_fast_s_mp_mul_high_digs.c | 98 + StormLib/src/libtommath/bn_fast_s_mp_sqr.c | 114 + StormLib/src/libtommath/bn_mp_2expt.c | 48 + StormLib/src/libtommath/bn_mp_abs.c | 43 + StormLib/src/libtommath/bn_mp_add.c | 53 + StormLib/src/libtommath/bn_mp_add_d.c | 112 + StormLib/src/libtommath/bn_mp_addmod.c | 41 + StormLib/src/libtommath/bn_mp_and.c | 57 + StormLib/src/libtommath/bn_mp_clamp.c | 44 + StormLib/src/libtommath/bn_mp_clear.c | 44 + StormLib/src/libtommath/bn_mp_clear_multi.c | 34 + StormLib/src/libtommath/bn_mp_cmp.c | 43 + StormLib/src/libtommath/bn_mp_cmp_d.c | 44 + StormLib/src/libtommath/bn_mp_cmp_mag.c | 55 + StormLib/src/libtommath/bn_mp_cnt_lsb.c | 53 + StormLib/src/libtommath/bn_mp_copy.c | 68 + StormLib/src/libtommath/bn_mp_count_bits.c | 45 + StormLib/src/libtommath/bn_mp_div.c | 292 + StormLib/src/libtommath/bn_mp_div_2.c | 68 + StormLib/src/libtommath/bn_mp_div_2d.c | 97 + StormLib/src/libtommath/bn_mp_div_3.c | 79 + StormLib/src/libtommath/bn_mp_div_d.c | 115 + StormLib/src/libtommath/bn_mp_dr_is_modulus.c | 43 + StormLib/src/libtommath/bn_mp_dr_reduce.c | 94 + StormLib/src/libtommath/bn_mp_dr_setup.c | 32 + StormLib/src/libtommath/bn_mp_exch.c | 34 + StormLib/src/libtommath/bn_mp_expt_d.c | 57 + StormLib/src/libtommath/bn_mp_exptmod.c | 112 + StormLib/src/libtommath/bn_mp_exptmod_fast.c | 321 ++ StormLib/src/libtommath/bn_mp_exteuclid.c | 82 + StormLib/src/libtommath/bn_mp_fread.c | 67 + StormLib/src/libtommath/bn_mp_fwrite.c | 52 + StormLib/src/libtommath/bn_mp_gcd.c | 105 + StormLib/src/libtommath/bn_mp_get_int.c | 45 + StormLib/src/libtommath/bn_mp_grow.c | 57 + StormLib/src/libtommath/bn_mp_init.c | 46 + StormLib/src/libtommath/bn_mp_init_copy.c | 32 + StormLib/src/libtommath/bn_mp_init_multi.c | 59 + StormLib/src/libtommath/bn_mp_init_set.c | 32 + StormLib/src/libtommath/bn_mp_init_set_int.c | 31 + StormLib/src/libtommath/bn_mp_init_size.c | 48 + StormLib/src/libtommath/bn_mp_invmod.c | 43 + StormLib/src/libtommath/bn_mp_invmod_slow.c | 175 + StormLib/src/libtommath/bn_mp_is_square.c | 109 + StormLib/src/libtommath/bn_mp_jacobi.c | 105 + StormLib/src/libtommath/bn_mp_karatsuba_mul.c | 167 + StormLib/src/libtommath/bn_mp_karatsuba_sqr.c | 121 + StormLib/src/libtommath/bn_mp_lcm.c | 60 + StormLib/src/libtommath/bn_mp_lshd.c | 67 + StormLib/src/libtommath/bn_mp_mod.c | 48 + StormLib/src/libtommath/bn_mp_mod_2d.c | 55 + StormLib/src/libtommath/bn_mp_mod_d.c | 27 + .../bn_mp_montgomery_calc_normalization.c | 59 + .../src/libtommath/bn_mp_montgomery_reduce.c | 118 + .../src/libtommath/bn_mp_montgomery_setup.c | 59 + StormLib/src/libtommath/bn_mp_mul.c | 66 + StormLib/src/libtommath/bn_mp_mul_2.c | 82 + StormLib/src/libtommath/bn_mp_mul_2d.c | 85 + StormLib/src/libtommath/bn_mp_mul_d.c | 79 + StormLib/src/libtommath/bn_mp_mulmod.c | 40 + StormLib/src/libtommath/bn_mp_n_root.c | 132 + StormLib/src/libtommath/bn_mp_neg.c | 40 + StormLib/src/libtommath/bn_mp_or.c | 50 + StormLib/src/libtommath/bn_mp_prime_fermat.c | 62 + .../src/libtommath/bn_mp_prime_is_divisible.c | 50 + .../src/libtommath/bn_mp_prime_is_prime.c | 83 + .../src/libtommath/bn_mp_prime_miller_rabin.c | 103 + .../src/libtommath/bn_mp_prime_next_prime.c | 170 + .../bn_mp_prime_rabin_miller_trials.c | 52 + .../src/libtommath/bn_mp_prime_random_ex.c | 125 + StormLib/src/libtommath/bn_mp_radix_size.c | 78 + StormLib/src/libtommath/bn_mp_radix_smap.c | 24 + StormLib/src/libtommath/bn_mp_rand.c | 55 + StormLib/src/libtommath/bn_mp_read_radix.c | 85 + .../src/libtommath/bn_mp_read_signed_bin.c | 41 + .../src/libtommath/bn_mp_read_unsigned_bin.c | 55 + StormLib/src/libtommath/bn_mp_reduce.c | 100 + StormLib/src/libtommath/bn_mp_reduce_2k.c | 61 + StormLib/src/libtommath/bn_mp_reduce_2k_l.c | 62 + .../src/libtommath/bn_mp_reduce_2k_setup.c | 47 + .../src/libtommath/bn_mp_reduce_2k_setup_l.c | 44 + StormLib/src/libtommath/bn_mp_reduce_is_2k.c | 52 + .../src/libtommath/bn_mp_reduce_is_2k_l.c | 44 + StormLib/src/libtommath/bn_mp_reduce_setup.c | 34 + StormLib/src/libtommath/bn_mp_rshd.c | 72 + StormLib/src/libtommath/bn_mp_set.c | 29 + StormLib/src/libtommath/bn_mp_set_int.c | 48 + StormLib/src/libtommath/bn_mp_shrink.c | 35 + .../src/libtommath/bn_mp_signed_bin_size.c | 27 + StormLib/src/libtommath/bn_mp_sqr.c | 58 + StormLib/src/libtommath/bn_mp_sqrmod.c | 41 + StormLib/src/libtommath/bn_mp_sqrt.c | 81 + StormLib/src/libtommath/bn_mp_sub.c | 59 + StormLib/src/libtommath/bn_mp_sub_d.c | 93 + StormLib/src/libtommath/bn_mp_submod.c | 42 + StormLib/src/libtommath/bn_mp_to_signed_bin.c | 33 + .../src/libtommath/bn_mp_to_signed_bin_n.c | 31 + .../src/libtommath/bn_mp_to_unsigned_bin.c | 48 + .../src/libtommath/bn_mp_to_unsigned_bin_n.c | 31 + StormLib/src/libtommath/bn_mp_toom_mul.c | 284 + StormLib/src/libtommath/bn_mp_toom_sqr.c | 226 + StormLib/src/libtommath/bn_mp_toradix.c | 75 + StormLib/src/libtommath/bn_mp_toradix_n.c | 88 + .../src/libtommath/bn_mp_unsigned_bin_size.c | 28 + StormLib/src/libtommath/bn_mp_xor.c | 51 + StormLib/src/libtommath/bn_mp_zero.c | 36 + StormLib/src/libtommath/bn_prime_tab.c | 61 + StormLib/src/libtommath/bn_reverse.c | 39 + StormLib/src/libtommath/bn_s_mp_add.c | 109 + StormLib/src/libtommath/bn_s_mp_exptmod.c | 252 + StormLib/src/libtommath/bn_s_mp_mul_digs.c | 90 + .../src/libtommath/bn_s_mp_mul_high_digs.c | 81 + StormLib/src/libtommath/bn_s_mp_sqr.c | 84 + StormLib/src/libtommath/bn_s_mp_sub.c | 89 + StormLib/src/libtommath/bncore.c | 36 + StormLib/src/libtommath/tommath.h | 584 ++ StormLib/src/libtommath/tommath_class.h | 999 ++++ StormLib/src/libtommath/tommath_superclass.h | 76 + StormLib/src/lzma/C/LzFind.c | 761 +++ StormLib/src/lzma/C/LzFind.h | 115 + StormLib/src/lzma/C/LzFindMt.c | 793 +++ StormLib/src/lzma/C/LzFindMt.h | 105 + StormLib/src/lzma/C/LzHash.h | 54 + StormLib/src/lzma/C/LzmaDec.c | 999 ++++ StormLib/src/lzma/C/LzmaDec.h | 231 + StormLib/src/lzma/C/LzmaEnc.c | 2268 ++++++++ StormLib/src/lzma/C/LzmaEnc.h | 80 + StormLib/src/lzma/C/Threads.c | 84 + StormLib/src/lzma/C/Threads.h | 59 + StormLib/src/lzma/C/Types.h | 236 + StormLib/src/lzma/info.txt | 1 + StormLib/src/pklib/crc32.c | 66 + StormLib/src/pklib/explode.c | 522 ++ StormLib/src/pklib/implode.c | 676 +++ StormLib/src/pklib/pklib.h | 158 + StormLib/src/resource.h | 15 + StormLib/src/sparse/sparse.cpp | 282 + StormLib/src/sparse/sparse.h | 17 + StormLib/src/wdk/sources-cpp.cpp | 26 + StormLib/src/wdk/sources-wdk-bzip2.c | 13 + StormLib/src/wdk/sources-wdk-ltc.c | 4 + StormLib/src/wdk/sources-wdk-lzma.c | 8 + StormLib/src/wdk/sources-wdk-misc.c | 6 + StormLib/src/wdk/sources-wdk-tomcrypt.c | 82 + StormLib/src/wdk/sources-wdk-tommath.c | 124 + StormLib/src/wdk/sources-wdk-zlib.c | 21 + StormLib/src/zlib/adler32.c | 169 + StormLib/src/zlib/compress.c | 80 + StormLib/src/zlib/compress_zlib.c | 5 + StormLib/src/zlib/crc32.c | 442 ++ StormLib/src/zlib/crc32.h | 441 ++ StormLib/src/zlib/deflate.c | 1834 ++++++ StormLib/src/zlib/deflate.h | 342 ++ StormLib/src/zlib/gzguts.h | 218 + StormLib/src/zlib/inffast.c | 340 ++ StormLib/src/zlib/inffast.h | 11 + StormLib/src/zlib/inffixed.h | 94 + StormLib/src/zlib/inflate.c | 1480 +++++ StormLib/src/zlib/inflate.h | 130 + StormLib/src/zlib/inftrees.c | 330 ++ StormLib/src/zlib/inftrees.h | 67 + StormLib/src/zlib/trees.c | 1244 ++++ StormLib/src/zlib/trees.h | 128 + StormLib/src/zlib/zconf.h | 428 ++ StormLib/src/zlib/zlib.h | 1613 ++++++ StormLib/src/zlib/zutil.c | 318 ++ StormLib/src/zlib/zutil.h | 274 + StormLib/storm_dll/Storm_dll.sln | 35 + StormLib/storm_dll/Storm_dll.vcproj | 363 ++ StormLib/storm_dll/storm_dll.cpp | 117 + StormLib/storm_dll/storm_dll.def | 25 + StormLib/storm_dll/storm_dll.h | 65 + StormLib/storm_dll/storm_test.cpp | 46 + StormLib/storm_dll/storm_test_vs08.vcproj | 359 ++ StormLib/test/Readme.txt | 90 + StormLib/test/StormTest.cpp | 4580 +++++++++++++++ StormLib/test/TLogHelper.cpp | 441 ++ ZAPDTR/ZAPD/ZAPD.vcxproj | 8 +- libultraship/libultraship/Archive.cpp | 20 +- libultraship/libultraship/Archive.h | 2 +- libultraship/libultraship/ResourceMgr.cpp | 2 +- libultraship/libultraship/StormLibDUS32.lib | Bin 2619046 -> 0 bytes libultraship/libultraship/StormLibDUS64.lib | Bin 2923852 -> 0 bytes libultraship/libultraship/StormLibRUS32.lib | Bin 3042768 -> 0 bytes libultraship/libultraship/StormLibRUS64.lib | Bin 3233804 -> 0 bytes .../libultraship/libultraship.vcxproj | 8 +- soh/soh.sln | 11 + soh/soh.vcxproj | 4 +- soh/soh/OTRGlobals.cpp | 4 + 378 files changed, 93684 insertions(+), 29 deletions(-) create mode 100644 StormLib/.gitignore create mode 100644 StormLib/Info.plist create mode 100644 StormLib/LICENSE create mode 100644 StormLib/PostBuild.bat create mode 100644 StormLib/Premake5.lua create mode 100644 StormLib/Publish.bat create mode 100644 StormLib/README.md create mode 100644 StormLib/StormLib.kdev4 create mode 100644 StormLib/StormLib.xcodeproj/project.pbxproj create mode 100644 StormLib/StormLib_vs08.sln create mode 100644 StormLib/StormLib_vs08.vcproj create mode 100644 StormLib/StormLib_vs08_dll.vcproj create mode 100644 StormLib/StormLib_vs08_test.vcproj create mode 100644 StormLib/StormLib_vs19.sln create mode 100644 StormLib/StormLib_vs19.vcxproj create mode 100644 StormLib/StormLib_vs19.vcxproj.filters create mode 100644 StormLib/StormLib_vs19_dll.vcxproj create mode 100644 StormLib/StormLib_vs19_dll.vcxproj.filters create mode 100644 StormLib/StormLib_vs19_test.vcxproj create mode 100644 StormLib/StormLib_vs19_test.vcxproj.filters create mode 100644 StormLib/doc/History.txt create mode 100644 StormLib/doc/The MoPaQ File Format 0.9.txt create mode 100644 StormLib/doc/The MoPaQ File Format 1.0.txt create mode 100644 StormLib/doc/d3-authenticationcode/d3-authenticationcode-deDE.txt create mode 100644 StormLib/doc/d3-authenticationcode/d3-authenticationcode-enGB.txt create mode 100644 StormLib/doc/d3-authenticationcode/d3-authenticationcode-enSG.txt create mode 100644 StormLib/doc/d3-authenticationcode/d3-authenticationcode-enUS.txt create mode 100644 StormLib/doc/d3-authenticationcode/d3-authenticationcode-esES.txt create mode 100644 StormLib/doc/d3-authenticationcode/d3-authenticationcode-esMX.txt create mode 100644 StormLib/doc/d3-authenticationcode/d3-authenticationcode-frFR.txt create mode 100644 StormLib/doc/d3-authenticationcode/d3-authenticationcode-itIT.txt create mode 100644 StormLib/doc/d3-authenticationcode/d3-authenticationcode-koKR.txt create mode 100644 StormLib/doc/d3-authenticationcode/d3-authenticationcode-plPL.txt create mode 100644 StormLib/doc/d3-authenticationcode/d3-authenticationcode-ptBR.txt create mode 100644 StormLib/doc/d3-authenticationcode/d3-authenticationcode-zhTW.txt create mode 100644 StormLib/doc/hots-authenticationcode/hots-authenticationcode-bgdl.txt create mode 100644 StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-deDE.txt create mode 100644 StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-enGB.txt create mode 100644 StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-enUS.txt create mode 100644 StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-esES.txt create mode 100644 StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-esMX.txt create mode 100644 StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-frFR.txt create mode 100644 StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-itIT.txt create mode 100644 StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-koKR.txt create mode 100644 StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-plPL.txt create mode 100644 StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-ptBR.txt create mode 100644 StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-ruRU.txt create mode 100644 StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-zhTW.txt create mode 100644 StormLib/make-msvc.bat create mode 100644 StormLib/make.bat create mode 100644 StormLib/sources create mode 100644 StormLib/src/DllMain.c create mode 100644 StormLib/src/DllMain.def create mode 100644 StormLib/src/DllMain.rc create mode 100644 StormLib/src/FileStream.cpp create mode 100644 StormLib/src/FileStream.h create mode 100644 StormLib/src/SBaseCommon.cpp create mode 100644 StormLib/src/SBaseDumpData.cpp create mode 100644 StormLib/src/SBaseFileTable.cpp create mode 100644 StormLib/src/SBaseSubTypes.cpp create mode 100644 StormLib/src/SCompression.cpp create mode 100644 StormLib/src/SFileAddFile.cpp create mode 100644 StormLib/src/SFileAttributes.cpp create mode 100644 StormLib/src/SFileCompactArchive.cpp create mode 100644 StormLib/src/SFileCreateArchive.cpp create mode 100644 StormLib/src/SFileExtractFile.cpp create mode 100644 StormLib/src/SFileFindFile.cpp create mode 100644 StormLib/src/SFileGetFileInfo.cpp create mode 100644 StormLib/src/SFileListFile.cpp create mode 100644 StormLib/src/SFileOpenArchive.cpp create mode 100644 StormLib/src/SFileOpenFileEx.cpp create mode 100644 StormLib/src/SFilePatchArchives.cpp create mode 100644 StormLib/src/SFileReadFile.cpp create mode 100644 StormLib/src/SFileVerify.cpp create mode 100644 StormLib/src/StormCommon.h create mode 100644 StormLib/src/StormLib.exp rename {libultraship/libultraship/Lib/StormLib => StormLib/src}/StormLib.h (99%) rename {libultraship/libultraship/Lib/StormLib => StormLib/src}/StormPort.h (100%) create mode 100644 StormLib/src/adpcm/adpcm.cpp create mode 100644 StormLib/src/adpcm/adpcm.h create mode 100644 StormLib/src/bzip2/blocksort.c create mode 100644 StormLib/src/bzip2/bzlib.c create mode 100644 StormLib/src/bzip2/bzlib.h create mode 100644 StormLib/src/bzip2/bzlib_private.h create mode 100644 StormLib/src/bzip2/compress.c create mode 100644 StormLib/src/bzip2/crctable.c create mode 100644 StormLib/src/bzip2/decompress.c create mode 100644 StormLib/src/bzip2/huffman.c create mode 100644 StormLib/src/bzip2/randtable.c create mode 100644 StormLib/src/huffman/huff.cpp create mode 100644 StormLib/src/huffman/huff.h create mode 100644 StormLib/src/jenkins/lookup.h create mode 100644 StormLib/src/jenkins/lookup3.c create mode 100644 StormLib/src/libtomcrypt/src/hashes/hash_memory.c create mode 100644 StormLib/src/libtomcrypt/src/hashes/md5.c create mode 100644 StormLib/src/libtomcrypt/src/hashes/sha1.c create mode 100644 StormLib/src/libtomcrypt/src/headers/tomcrypt.h create mode 100644 StormLib/src/libtomcrypt/src/headers/tomcrypt_argchk.h create mode 100644 StormLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h create mode 100644 StormLib/src/libtomcrypt/src/headers/tomcrypt_cipher.h create mode 100644 StormLib/src/libtomcrypt/src/headers/tomcrypt_custom.h create mode 100644 StormLib/src/libtomcrypt/src/headers/tomcrypt_hash.h create mode 100644 StormLib/src/libtomcrypt/src/headers/tomcrypt_mac.h create mode 100644 StormLib/src/libtomcrypt/src/headers/tomcrypt_macros.h create mode 100644 StormLib/src/libtomcrypt/src/headers/tomcrypt_math.h create mode 100644 StormLib/src/libtomcrypt/src/headers/tomcrypt_misc.h create mode 100644 StormLib/src/libtomcrypt/src/headers/tomcrypt_pk.h create mode 100644 StormLib/src/libtomcrypt/src/headers/tomcrypt_pkcs.h create mode 100644 StormLib/src/libtomcrypt/src/headers/tomcrypt_prng.h create mode 100644 StormLib/src/libtomcrypt/src/math/ltm_desc.c create mode 100644 StormLib/src/libtomcrypt/src/math/multi.c create mode 100644 StormLib/src/libtomcrypt/src/math/rand_prime.c create mode 100644 StormLib/src/libtomcrypt/src/misc/base64_decode.c create mode 100644 StormLib/src/libtomcrypt/src/misc/crypt_argchk.c create mode 100644 StormLib/src/libtomcrypt/src/misc/crypt_find_hash.c create mode 100644 StormLib/src/libtomcrypt/src/misc/crypt_find_prng.c create mode 100644 StormLib/src/libtomcrypt/src/misc/crypt_hash_descriptor.c create mode 100644 StormLib/src/libtomcrypt/src/misc/crypt_hash_is_valid.c create mode 100644 StormLib/src/libtomcrypt/src/misc/crypt_libc.c create mode 100644 StormLib/src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c create mode 100644 StormLib/src/libtomcrypt/src/misc/crypt_prng_descriptor.c create mode 100644 StormLib/src/libtomcrypt/src/misc/crypt_prng_is_valid.c create mode 100644 StormLib/src/libtomcrypt/src/misc/crypt_register_hash.c create mode 100644 StormLib/src/libtomcrypt/src/misc/crypt_register_prng.c create mode 100644 StormLib/src/libtomcrypt/src/misc/zeromem.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_decode_boolean.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_decode_choice.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_decode_integer.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utctime.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_encode_bit_string.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_encode_boolean.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_encode_ia5_string.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_encode_integer.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_encode_object_identifier.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_encode_octet_string.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_encode_printable_string.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_encode_sequence_ex.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_encode_sequence_multi.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_encode_set.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_encode_setof.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_encode_short_integer.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_encode_utctime.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_encode_utf8_string.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_length_bit_string.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_length_boolean.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_length_integer.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_length_octet_string.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_length_printable_string.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_length_sequence.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_length_short_integer.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_length_utctime.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c create mode 100644 StormLib/src/libtomcrypt/src/pk/asn1/der_sequence_free.c create mode 100644 StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c create mode 100644 StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c create mode 100644 StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c create mode 100644 StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c create mode 100644 StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c create mode 100644 StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c create mode 100644 StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c create mode 100644 StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c create mode 100644 StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c create mode 100644 StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_encode.c create mode 100644 StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c create mode 100644 StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_encode.c create mode 100644 StormLib/src/libtomcrypt/src/pk/rsa/rsa_exptmod.c create mode 100644 StormLib/src/libtomcrypt/src/pk/rsa/rsa_free.c create mode 100644 StormLib/src/libtomcrypt/src/pk/rsa/rsa_import.c create mode 100644 StormLib/src/libtomcrypt/src/pk/rsa/rsa_make_key.c create mode 100644 StormLib/src/libtomcrypt/src/pk/rsa/rsa_sign_hash.c create mode 100644 StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c create mode 100644 StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c create mode 100644 StormLib/src/libtommath/bn_fast_mp_invmod.c create mode 100644 StormLib/src/libtommath/bn_fast_mp_montgomery_reduce.c create mode 100644 StormLib/src/libtommath/bn_fast_s_mp_mul_digs.c create mode 100644 StormLib/src/libtommath/bn_fast_s_mp_mul_high_digs.c create mode 100644 StormLib/src/libtommath/bn_fast_s_mp_sqr.c create mode 100644 StormLib/src/libtommath/bn_mp_2expt.c create mode 100644 StormLib/src/libtommath/bn_mp_abs.c create mode 100644 StormLib/src/libtommath/bn_mp_add.c create mode 100644 StormLib/src/libtommath/bn_mp_add_d.c create mode 100644 StormLib/src/libtommath/bn_mp_addmod.c create mode 100644 StormLib/src/libtommath/bn_mp_and.c create mode 100644 StormLib/src/libtommath/bn_mp_clamp.c create mode 100644 StormLib/src/libtommath/bn_mp_clear.c create mode 100644 StormLib/src/libtommath/bn_mp_clear_multi.c create mode 100644 StormLib/src/libtommath/bn_mp_cmp.c create mode 100644 StormLib/src/libtommath/bn_mp_cmp_d.c create mode 100644 StormLib/src/libtommath/bn_mp_cmp_mag.c create mode 100644 StormLib/src/libtommath/bn_mp_cnt_lsb.c create mode 100644 StormLib/src/libtommath/bn_mp_copy.c create mode 100644 StormLib/src/libtommath/bn_mp_count_bits.c create mode 100644 StormLib/src/libtommath/bn_mp_div.c create mode 100644 StormLib/src/libtommath/bn_mp_div_2.c create mode 100644 StormLib/src/libtommath/bn_mp_div_2d.c create mode 100644 StormLib/src/libtommath/bn_mp_div_3.c create mode 100644 StormLib/src/libtommath/bn_mp_div_d.c create mode 100644 StormLib/src/libtommath/bn_mp_dr_is_modulus.c create mode 100644 StormLib/src/libtommath/bn_mp_dr_reduce.c create mode 100644 StormLib/src/libtommath/bn_mp_dr_setup.c create mode 100644 StormLib/src/libtommath/bn_mp_exch.c create mode 100644 StormLib/src/libtommath/bn_mp_expt_d.c create mode 100644 StormLib/src/libtommath/bn_mp_exptmod.c create mode 100644 StormLib/src/libtommath/bn_mp_exptmod_fast.c create mode 100644 StormLib/src/libtommath/bn_mp_exteuclid.c create mode 100644 StormLib/src/libtommath/bn_mp_fread.c create mode 100644 StormLib/src/libtommath/bn_mp_fwrite.c create mode 100644 StormLib/src/libtommath/bn_mp_gcd.c create mode 100644 StormLib/src/libtommath/bn_mp_get_int.c create mode 100644 StormLib/src/libtommath/bn_mp_grow.c create mode 100644 StormLib/src/libtommath/bn_mp_init.c create mode 100644 StormLib/src/libtommath/bn_mp_init_copy.c create mode 100644 StormLib/src/libtommath/bn_mp_init_multi.c create mode 100644 StormLib/src/libtommath/bn_mp_init_set.c create mode 100644 StormLib/src/libtommath/bn_mp_init_set_int.c create mode 100644 StormLib/src/libtommath/bn_mp_init_size.c create mode 100644 StormLib/src/libtommath/bn_mp_invmod.c create mode 100644 StormLib/src/libtommath/bn_mp_invmod_slow.c create mode 100644 StormLib/src/libtommath/bn_mp_is_square.c create mode 100644 StormLib/src/libtommath/bn_mp_jacobi.c create mode 100644 StormLib/src/libtommath/bn_mp_karatsuba_mul.c create mode 100644 StormLib/src/libtommath/bn_mp_karatsuba_sqr.c create mode 100644 StormLib/src/libtommath/bn_mp_lcm.c create mode 100644 StormLib/src/libtommath/bn_mp_lshd.c create mode 100644 StormLib/src/libtommath/bn_mp_mod.c create mode 100644 StormLib/src/libtommath/bn_mp_mod_2d.c create mode 100644 StormLib/src/libtommath/bn_mp_mod_d.c create mode 100644 StormLib/src/libtommath/bn_mp_montgomery_calc_normalization.c create mode 100644 StormLib/src/libtommath/bn_mp_montgomery_reduce.c create mode 100644 StormLib/src/libtommath/bn_mp_montgomery_setup.c create mode 100644 StormLib/src/libtommath/bn_mp_mul.c create mode 100644 StormLib/src/libtommath/bn_mp_mul_2.c create mode 100644 StormLib/src/libtommath/bn_mp_mul_2d.c create mode 100644 StormLib/src/libtommath/bn_mp_mul_d.c create mode 100644 StormLib/src/libtommath/bn_mp_mulmod.c create mode 100644 StormLib/src/libtommath/bn_mp_n_root.c create mode 100644 StormLib/src/libtommath/bn_mp_neg.c create mode 100644 StormLib/src/libtommath/bn_mp_or.c create mode 100644 StormLib/src/libtommath/bn_mp_prime_fermat.c create mode 100644 StormLib/src/libtommath/bn_mp_prime_is_divisible.c create mode 100644 StormLib/src/libtommath/bn_mp_prime_is_prime.c create mode 100644 StormLib/src/libtommath/bn_mp_prime_miller_rabin.c create mode 100644 StormLib/src/libtommath/bn_mp_prime_next_prime.c create mode 100644 StormLib/src/libtommath/bn_mp_prime_rabin_miller_trials.c create mode 100644 StormLib/src/libtommath/bn_mp_prime_random_ex.c create mode 100644 StormLib/src/libtommath/bn_mp_radix_size.c create mode 100644 StormLib/src/libtommath/bn_mp_radix_smap.c create mode 100644 StormLib/src/libtommath/bn_mp_rand.c create mode 100644 StormLib/src/libtommath/bn_mp_read_radix.c create mode 100644 StormLib/src/libtommath/bn_mp_read_signed_bin.c create mode 100644 StormLib/src/libtommath/bn_mp_read_unsigned_bin.c create mode 100644 StormLib/src/libtommath/bn_mp_reduce.c create mode 100644 StormLib/src/libtommath/bn_mp_reduce_2k.c create mode 100644 StormLib/src/libtommath/bn_mp_reduce_2k_l.c create mode 100644 StormLib/src/libtommath/bn_mp_reduce_2k_setup.c create mode 100644 StormLib/src/libtommath/bn_mp_reduce_2k_setup_l.c create mode 100644 StormLib/src/libtommath/bn_mp_reduce_is_2k.c create mode 100644 StormLib/src/libtommath/bn_mp_reduce_is_2k_l.c create mode 100644 StormLib/src/libtommath/bn_mp_reduce_setup.c create mode 100644 StormLib/src/libtommath/bn_mp_rshd.c create mode 100644 StormLib/src/libtommath/bn_mp_set.c create mode 100644 StormLib/src/libtommath/bn_mp_set_int.c create mode 100644 StormLib/src/libtommath/bn_mp_shrink.c create mode 100644 StormLib/src/libtommath/bn_mp_signed_bin_size.c create mode 100644 StormLib/src/libtommath/bn_mp_sqr.c create mode 100644 StormLib/src/libtommath/bn_mp_sqrmod.c create mode 100644 StormLib/src/libtommath/bn_mp_sqrt.c create mode 100644 StormLib/src/libtommath/bn_mp_sub.c create mode 100644 StormLib/src/libtommath/bn_mp_sub_d.c create mode 100644 StormLib/src/libtommath/bn_mp_submod.c create mode 100644 StormLib/src/libtommath/bn_mp_to_signed_bin.c create mode 100644 StormLib/src/libtommath/bn_mp_to_signed_bin_n.c create mode 100644 StormLib/src/libtommath/bn_mp_to_unsigned_bin.c create mode 100644 StormLib/src/libtommath/bn_mp_to_unsigned_bin_n.c create mode 100644 StormLib/src/libtommath/bn_mp_toom_mul.c create mode 100644 StormLib/src/libtommath/bn_mp_toom_sqr.c create mode 100644 StormLib/src/libtommath/bn_mp_toradix.c create mode 100644 StormLib/src/libtommath/bn_mp_toradix_n.c create mode 100644 StormLib/src/libtommath/bn_mp_unsigned_bin_size.c create mode 100644 StormLib/src/libtommath/bn_mp_xor.c create mode 100644 StormLib/src/libtommath/bn_mp_zero.c create mode 100644 StormLib/src/libtommath/bn_prime_tab.c create mode 100644 StormLib/src/libtommath/bn_reverse.c create mode 100644 StormLib/src/libtommath/bn_s_mp_add.c create mode 100644 StormLib/src/libtommath/bn_s_mp_exptmod.c create mode 100644 StormLib/src/libtommath/bn_s_mp_mul_digs.c create mode 100644 StormLib/src/libtommath/bn_s_mp_mul_high_digs.c create mode 100644 StormLib/src/libtommath/bn_s_mp_sqr.c create mode 100644 StormLib/src/libtommath/bn_s_mp_sub.c create mode 100644 StormLib/src/libtommath/bncore.c create mode 100644 StormLib/src/libtommath/tommath.h create mode 100644 StormLib/src/libtommath/tommath_class.h create mode 100644 StormLib/src/libtommath/tommath_superclass.h create mode 100644 StormLib/src/lzma/C/LzFind.c create mode 100644 StormLib/src/lzma/C/LzFind.h create mode 100644 StormLib/src/lzma/C/LzFindMt.c create mode 100644 StormLib/src/lzma/C/LzFindMt.h create mode 100644 StormLib/src/lzma/C/LzHash.h create mode 100644 StormLib/src/lzma/C/LzmaDec.c create mode 100644 StormLib/src/lzma/C/LzmaDec.h create mode 100644 StormLib/src/lzma/C/LzmaEnc.c create mode 100644 StormLib/src/lzma/C/LzmaEnc.h create mode 100644 StormLib/src/lzma/C/Threads.c create mode 100644 StormLib/src/lzma/C/Threads.h create mode 100644 StormLib/src/lzma/C/Types.h create mode 100644 StormLib/src/lzma/info.txt create mode 100644 StormLib/src/pklib/crc32.c create mode 100644 StormLib/src/pklib/explode.c create mode 100644 StormLib/src/pklib/implode.c create mode 100644 StormLib/src/pklib/pklib.h create mode 100644 StormLib/src/resource.h create mode 100644 StormLib/src/sparse/sparse.cpp create mode 100644 StormLib/src/sparse/sparse.h create mode 100644 StormLib/src/wdk/sources-cpp.cpp create mode 100644 StormLib/src/wdk/sources-wdk-bzip2.c create mode 100644 StormLib/src/wdk/sources-wdk-ltc.c create mode 100644 StormLib/src/wdk/sources-wdk-lzma.c create mode 100644 StormLib/src/wdk/sources-wdk-misc.c create mode 100644 StormLib/src/wdk/sources-wdk-tomcrypt.c create mode 100644 StormLib/src/wdk/sources-wdk-tommath.c create mode 100644 StormLib/src/wdk/sources-wdk-zlib.c create mode 100644 StormLib/src/zlib/adler32.c create mode 100644 StormLib/src/zlib/compress.c create mode 100644 StormLib/src/zlib/compress_zlib.c create mode 100644 StormLib/src/zlib/crc32.c create mode 100644 StormLib/src/zlib/crc32.h create mode 100644 StormLib/src/zlib/deflate.c create mode 100644 StormLib/src/zlib/deflate.h create mode 100644 StormLib/src/zlib/gzguts.h create mode 100644 StormLib/src/zlib/inffast.c create mode 100644 StormLib/src/zlib/inffast.h create mode 100644 StormLib/src/zlib/inffixed.h create mode 100644 StormLib/src/zlib/inflate.c create mode 100644 StormLib/src/zlib/inflate.h create mode 100644 StormLib/src/zlib/inftrees.c create mode 100644 StormLib/src/zlib/inftrees.h create mode 100644 StormLib/src/zlib/trees.c create mode 100644 StormLib/src/zlib/trees.h create mode 100644 StormLib/src/zlib/zconf.h create mode 100644 StormLib/src/zlib/zlib.h create mode 100644 StormLib/src/zlib/zutil.c create mode 100644 StormLib/src/zlib/zutil.h create mode 100644 StormLib/storm_dll/Storm_dll.sln create mode 100644 StormLib/storm_dll/Storm_dll.vcproj create mode 100644 StormLib/storm_dll/storm_dll.cpp create mode 100644 StormLib/storm_dll/storm_dll.def create mode 100644 StormLib/storm_dll/storm_dll.h create mode 100644 StormLib/storm_dll/storm_test.cpp create mode 100644 StormLib/storm_dll/storm_test_vs08.vcproj create mode 100644 StormLib/test/Readme.txt create mode 100644 StormLib/test/StormTest.cpp create mode 100644 StormLib/test/TLogHelper.cpp delete mode 100644 libultraship/libultraship/StormLibDUS32.lib delete mode 100644 libultraship/libultraship/StormLibDUS64.lib delete mode 100644 libultraship/libultraship/StormLibRUS32.lib delete mode 100644 libultraship/libultraship/StormLibRUS64.lib diff --git a/OTRExporter/OTRExporter.sln b/OTRExporter/OTRExporter.sln index 496851f24..5379a92c8 100644 --- a/OTRExporter/OTRExporter.sln +++ b/OTRExporter/OTRExporter.sln @@ -11,6 +11,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libultraship", "..\libultra EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAPD", "..\ZAPDTR\ZAPD\ZAPD.vcxproj", "{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}" ProjectSection(ProjectDependencies) = postProject + {78424708-1F6E-4D4B-920C-FB6D26847055} = {78424708-1F6E-4D4B-920C-FB6D26847055} {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8} = {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8} {A2E01C3E-D647-45D1-9788-043DEBC1A908} = {A2E01C3E-D647-45D1-9788-043DEBC1A908} {A6103FD3-0709-4FC7-B066-1A6E056D6306} = {A6103FD3-0709-4FC7-B066-1A6E056D6306} @@ -18,6 +19,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAPD", "..\ZAPDTR\ZAPD\ZAPD EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAPDUtils", "..\ZAPDTR\ZAPDUtils\ZAPDUtils.vcxproj", "{A2E01C3E-D647-45D1-9788-043DEBC1A908}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib", "..\StormLib\StormLib_vs19.vcxproj", "{78424708-1F6E-4D4B-920C-FB6D26847055}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -58,6 +61,14 @@ Global {A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x64.Build.0 = Release|x64 {A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x86.ActiveCfg = Release|Win32 {A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x86.Build.0 = Release|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.ActiveCfg = DebugUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.Build.0 = DebugUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x86.ActiveCfg = DebugAD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x86.Build.0 = DebugAD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.ActiveCfg = ReleaseUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.Build.0 = ReleaseUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x86.ActiveCfg = ReleaseAS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x86.Build.0 = ReleaseAS|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/OTRExporter/OTRExporter/OTRExporter.vcxproj b/OTRExporter/OTRExporter/OTRExporter.vcxproj index 9ec691d79..cecb9eaf3 100644 --- a/OTRExporter/OTRExporter/OTRExporter.vcxproj +++ b/OTRExporter/OTRExporter/OTRExporter.vcxproj @@ -138,7 +138,7 @@ true - $(ProjectDir)..\..\ZAPDTR\ZAPD;$(ProjectDir)..\..\ZAPDTR\lib\tinyxml2;$(ProjectDir)..\..\ZAPDTR\lib\libgfxd;$(ProjectDir)..\..\ZAPDTR\ZAPDUtils;$(ProjectDir)..\..\libultraship\libultraship;$(ProjectDir)..\..\libultraship\libultraship\lib\spdlog\include;$(ProjectDir)..\..\libultraship\libultraship\Lib\Fast3D\U64;$(IncludePath) + $(ProjectDir)..\..\ZAPDTR\ZAPD;$(ProjectDir)..\..\ZAPDTR\lib\tinyxml2;$(ProjectDir)..\..\ZAPDTR\lib\libgfxd;$(ProjectDir)..\..\ZAPDTR\ZAPDUtils;$(ProjectDir)..\..\libultraship\libultraship;$(ProjectDir)..\..\libultraship\libultraship\lib\spdlog\include;$(ProjectDir)..\..\libultraship\libultraship\Lib\Fast3D\U64;$(ProjectDir)..\..\StormLib\src\;$(IncludePath) $(ProjectDir)..\..\libultraship\libultraship;$(LibraryPath) MinimumRecommendedRules.ruleset @@ -146,7 +146,7 @@ false - $(ProjectDir)..\..\ZAPDTR\ZAPD;$(ProjectDir)..\..\ZAPDTR\lib\tinyxml2;$(ProjectDir)..\..\ZAPDTR\lib\libgfxd;$(ProjectDir)..\..\ZAPDTR\ZAPDUtils;$(ProjectDir)..\..\libultraship\libultraship;$(ProjectDir)..\..\libultraship\libultraship\lib\spdlog\include;$(ProjectDir)..\..\libultraship\libultraship\Lib\Fast3D\U64;$(IncludePath) + $(ProjectDir)..\..\ZAPDTR\ZAPD;$(ProjectDir)..\..\ZAPDTR\lib\tinyxml2;$(ProjectDir)..\..\ZAPDTR\lib\libgfxd;$(ProjectDir)..\..\ZAPDTR\ZAPDUtils;$(ProjectDir)..\..\libultraship\libultraship;$(ProjectDir)..\..\libultraship\libultraship\lib\spdlog\include;$(ProjectDir)..\..\libultraship\libultraship\Lib\Fast3D\U64;$(ProjectDir)..\..\StormLib\src\;$(IncludePath) $(ProjectDir)..\..\libultraship\libultraship;$(LibraryPath) MinimumRecommendedRules.ruleset diff --git a/StormLib/.gitignore b/StormLib/.gitignore new file mode 100644 index 000000000..3d764df91 --- /dev/null +++ b/StormLib/.gitignore @@ -0,0 +1,167 @@ +################# +## Eclipse +################# + +*.pydevproject +.project +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Rr]elease/ +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.vspscc +.builds +*.dotCover +*.o +*.dylib + +## TODO: If you have NuGet Package Restore enabled, uncomment this +#packages/ + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf + +# Visual Studio profiler +*.psess +*.vsp + +# ReSharper is a .NET coding add-in +_ReSharper* + +# Installshield output folder +[Ee]xpress + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish + +# Others +[Bb]in +[Oo]bj +sql +TestResults +*.Cache +ClientBin +stylecop.* +~$* +*.dbmdl +Generated_Code #added for RIA/Silverlight projects + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML + + + +############ +## Windows +############ + +# Windows image file caches +Thumbs.db + +# Folder config file +Desktop.ini + + +############# +## Python +############# + +*.py[co] + +# Packages +*.egg +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg + +# Mac crap +.DS_Store +**/project.xcworkspace +**/xcuserdata diff --git a/StormLib/Info.plist b/StormLib/Info.plist new file mode 100644 index 000000000..0e1ae014f --- /dev/null +++ b/StormLib/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + net.zezula.${PRODUCT_NAME:rfc1034Identifier} + CFBundleName + ${PRODUCT_NAME} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + FMWK + CFBundleSignature + ???? + CFBundleVersion + 8.01 + + diff --git a/StormLib/LICENSE b/StormLib/LICENSE new file mode 100644 index 000000000..136cae4f4 --- /dev/null +++ b/StormLib/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 1999-2013 Ladislav Zezula + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/StormLib/PostBuild.bat b/StormLib/PostBuild.bat new file mode 100644 index 000000000..c2d253499 --- /dev/null +++ b/StormLib/PostBuild.bat @@ -0,0 +1,34 @@ +@echo off +rem Post-build batch for StormLib project +rem Called as PostBuild.bat $(ProjectName) $(PlatformName) $(ConfigurationName) [vs2008] +rem Example: PostBuild.bat StormLib_dll x64 Debug vs2008 + +rem Select build type +if "%1" == "StormLib_dll" goto PostBuild_DLL +if "%1" == "StormLib" goto PostBuild_LIB +goto:eof + +:PostBuild_DLL + +rem Build steps for the DLL. On 32-bit Release version, increment the build number +if not "x%2" == "xWin32" goto:eof +if not "x%3" == "xRelease" goto:eof +PostBuild.exe .\src\DllMain.rc +goto:eof + +:PostBuild_LIB + +rem Set target folders +if "x%2" == "xWin32" set TARGET_DIR_LEVEL2=lib32 +if "x%2" == "xx64" set TARGET_DIR_LEVEL2=lib64 +if "x%4" == "xvs2008" set TARGET_DIR_LEVEL3=vs2008 + +rem Check & create target folder structure +if not exist ..\aaa goto:eof +if not exist ..\aaa\%TARGET_DIR_LEVEL2% md ..\aaa\%TARGET_DIR_LEVEL2% +if not exist ..\aaa\%TARGET_DIR_LEVEL2%\%TARGET_DIR_LEVEL3% md ..\aaa\%TARGET_DIR_LEVEL2%\%TARGET_DIR_LEVEL3% + +rem Copy include and LIB files to the target folder +copy /Y .\src\StormLib.h ..\aaa\inc >nul +copy /Y .\src\StormPort.h ..\aaa\inc >nul +copy /Y .\bin\%1\%2\%3\StormLib???.lib ..\aaa\%TARGET_DIR_LEVEL2%\%TARGET_DIR_LEVEL3% >nul diff --git a/StormLib/Premake5.lua b/StormLib/Premake5.lua new file mode 100644 index 000000000..957ed36c6 --- /dev/null +++ b/StormLib/Premake5.lua @@ -0,0 +1,132 @@ + +solution 'StormLib' + location 'build' + language 'C++' + configurations { 'Debug', 'Release', } + platforms { 'x32', 'x64' } + + targetdir 'bin' + objdir 'bin' + + files { + 'src/**.h', + 'src/**.c', + 'src/**.cpp', + 'doc/*.txt', + } + + removefiles { + 'src/adpcm/*_old.*', + 'src/huffman/*_old.*', + 'src/huffman/huff_patch.*', + 'src/pklib/crc32.c', + 'src/zlib/compress.c', + } + + filter 'configurations:Debug*' + flags { 'Symbols' } + defines { '_DEBUG' } + optimize 'Debug' + + filter 'configurations:Release*' + defines { 'NDEBUG' } + optimize 'Full' + + filter 'system:windows' + links { 'wininet', } + defines { 'WINDOWS', '_WINDOWS' } + + filter { 'system:windows', 'platforms:x32' } + defines { 'WIN32', '_WIN32' } + + filter { 'system:windows', 'platforms:x64' } + defines { 'WIN64', '_WIN64' } + + filter 'system:linux' + defines { '_7ZIP_ST', 'BZ_STRICT_ANSI' } + removefiles { + 'src/lzma/C/LzFindMt.*', + 'src/lzma/C/Threads.*', + } + +-------------------------------------------------------------------------------- + +project 'StormLib' + kind 'StaticLib' + + removefiles 'src/SBaseDumpData.cpp' + + configurations { + 'DebugAD', -- Debug Ansi Dynamic + 'DebugAS', -- Debug Ansi Static + 'DebugUD', -- Debug Unicode Dynamic + 'DebugUS', -- Debug Unicode Static + 'ReleaseAD', -- Release Ansi Dynamic + 'ReleaseAS', -- Release Ansi Static + 'ReleaseUD', -- Release Unicode Dynamic' + 'ReleaseUS', -- Release Unicode Static + } + + configmap { + ['Debug'] = 'DebugUS', + ['Release'] = 'ReleaseUS', + } + + filter 'configurations:*S' + flags { 'StaticRuntime' } + + filter { 'configurations:*U*', 'action:vs*' } + flags { 'Unicode' } + + filter { 'configurations:*U*', 'not action:vs*' } + defines { 'UNICODE', '_UNICODE' } + + filter 'DebugAD' + targetsuffix 'DAD' + filter 'ReleaseAD' + targetsuffix 'RAD' + filter 'DebugAS' + targetsuffix 'DAS' + filter 'ReleaseAS' + targetsuffix 'RAS' + filter 'DebugUD' + targetsuffix 'DUD' + filter 'ReleaseUD' + targetsuffix 'RUD' + filter 'DebugUS' + targetsuffix 'DUS' + filter 'ReleaseUS' + targetsuffix 'RUS' + +-------------------------------------------------------------------------------- + +project 'StormLib_dll' + kind 'SharedLib' + + targetname 'Stormlib' + + files { + 'stormlib_dll/DllMain.c', + 'stormlib_dll/StormLib.def', + } + + removefiles 'src/SBaseDumpData.cpp' + + filter { 'system:windows', 'action:gmake' } + linkoptions { + '-Xlinker --enable-stdcall-fixup', + '../stormlib_dll/StormLib.def', + } + + filter 'Debug' + targetsuffix '_d' + +-------------------------------------------------------------------------------- + +project 'StormLib_test' + kind 'ConsoleApp' + + files { + 'test/StormTest.cpp', + } + diff --git a/StormLib/Publish.bat b/StormLib/Publish.bat new file mode 100644 index 000000000..b5c71fcb4 --- /dev/null +++ b/StormLib/Publish.bat @@ -0,0 +1,25 @@ +@echo off +rem This BAT file updates the ZIP file that is to be uploaded to web +rem Only use when both 32-bit and 64-bit are properly compiled + +set STORMLIB_NAME=stormlib-9.00 + +echo Creating %STORMLIB_NAME%.zip ... +cd \Ladik\Appdir +zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\doc\* +zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\src\* +zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\storm_dll\* +zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\StormLib.xcodeproj\* +zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\stormlib_dll\* +zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\test\* +zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\CMakeLists.txt +zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\makefile.* +zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\Info.plist +zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\*.bat +zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\*.sln +zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\*.vcproj +zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\*.vcxproj +echo. + +echo Press any key to exit ... +pause >nul diff --git a/StormLib/README.md b/StormLib/README.md new file mode 100644 index 000000000..919b54ad1 --- /dev/null +++ b/StormLib/README.md @@ -0,0 +1,39 @@ +# StormLib + +This is official repository for the StomLib library, an open-source project that can work with Blizzard MPQ archives. + +## Installation and basic usage +### Linux +1. Download latest release +2. Install StormLib: +``` +$ cd +$ cmake CMakeLists.txt +$ make +$ make install +``` +3. Include StormLib in your project: `#include ` +4. Make sure you compile your project with `-lstorm -lz -lbz2` + +### Windows (Visual Studio 2008) +1. Download the latest release of StormLib +2. Open the solution file `StormLib_vs08.sln` in Visual Studio 2008 +3. Choose "Build / Batch Build" and select every build of "StormLib" +4. Choose "Rebuild" +5. The result libraries are in `.\bin\Win32` and `.\bin\x64` + +### Windows (Visual Studio 2017 or 2019) +0. Make sure you have SDK 10.0.17134.0 installed +1. Download the latest release of StormLib +2. Open the solution file `StormLib_vs19.sln` in Visual Studio 2017/2019 +3. Choose "Build / Batch Build" and select every build of "StormLib" +4. Choose "Rebuild" +5. The result libraries are in `.\bin\Win32` and `.\bin\x64` + +### Windows (Test Project) +1. Include the main StormLib header: `#include ` +2. Set the correct library directory for StormLibXYZ.lib: + * X: D = Debug, R = Release + * Y: A = ANSI build, U = Unicode build + * Z: S = Using static CRT library, D = Using Dynamic CRT library +3. Rebuild diff --git a/StormLib/StormLib.kdev4 b/StormLib/StormLib.kdev4 new file mode 100644 index 000000000..c9a6ab551 --- /dev/null +++ b/StormLib/StormLib.kdev4 @@ -0,0 +1,3 @@ +[Project] +Manager=KDevCMakeManager +Name=StormLib diff --git a/StormLib/StormLib.xcodeproj/project.pbxproj b/StormLib/StormLib.xcodeproj/project.pbxproj new file mode 100644 index 000000000..cc77a682d --- /dev/null +++ b/StormLib/StormLib.xcodeproj/project.pbxproj @@ -0,0 +1,2104 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 221F6A741168529C0026C852 /* LzmaDec.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6A721168529C0026C852 /* LzmaDec.h */; }; + 221F6A751168529C0026C852 /* LzmaEnc.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6A731168529C0026C852 /* LzmaEnc.h */; }; + 221F6A761168529C0026C852 /* LzmaDec.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6A721168529C0026C852 /* LzmaDec.h */; }; + 221F6A771168529C0026C852 /* LzmaEnc.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6A731168529C0026C852 /* LzmaEnc.h */; }; + 221F6A7B116852AA0026C852 /* LzmaEnc.c in Sources */ = {isa = PBXBuildFile; fileRef = 221F6A7A116852AA0026C852 /* LzmaEnc.c */; }; + 221F6A7C116852AA0026C852 /* LzmaEnc.c in Sources */ = {isa = PBXBuildFile; fileRef = 221F6A7A116852AA0026C852 /* LzmaEnc.c */; }; + 221F6A7E116852B20026C852 /* LzmaDec.c in Sources */ = {isa = PBXBuildFile; fileRef = 221F6A7D116852B20026C852 /* LzmaDec.c */; }; + 221F6A7F116852B20026C852 /* LzmaDec.c in Sources */ = {isa = PBXBuildFile; fileRef = 221F6A7D116852B20026C852 /* LzmaDec.c */; }; + 221F6AB51168545B0026C852 /* LzFind.c in Sources */ = {isa = PBXBuildFile; fileRef = 221F6AB31168545B0026C852 /* LzFind.c */; }; + 221F6AB61168545B0026C852 /* LzFind.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6AB41168545B0026C852 /* LzFind.h */; }; + 221F6AB71168545B0026C852 /* LzFind.c in Sources */ = {isa = PBXBuildFile; fileRef = 221F6AB31168545B0026C852 /* LzFind.c */; }; + 221F6AB81168545B0026C852 /* LzFind.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6AB41168545B0026C852 /* LzFind.h */; }; + 221F6ABA116854730026C852 /* LzHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6AB9116854730026C852 /* LzHash.h */; }; + 221F6ABB116854730026C852 /* LzHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6AB9116854730026C852 /* LzHash.h */; }; + 221F6ABD116854870026C852 /* Types.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6ABC116854870026C852 /* Types.h */; }; + 221F6ABE116854870026C852 /* Types.h in Headers */ = {isa = PBXBuildFile; fileRef = 221F6ABC116854870026C852 /* Types.h */; }; + 2254917B11948CE70044424D /* crypt_ltc_mp_descriptor.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184811933FCF0083AC69 /* crypt_ltc_mp_descriptor.c */; settings = {COMPILER_FLAGS = "-fno-common"; }; }; + 225530DB1056BC7900FA646A /* huff.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED009D0D03542A00AB0B4E /* huff.h */; }; + 225530DE1056BC7900FA646A /* pklib.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED00A80D03542A00AB0B4E /* pklib.h */; }; + 225530DF1056BC7900FA646A /* StormCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED00AB0D03542A00AB0B4E /* StormCommon.h */; }; + 225530E01056BC7900FA646A /* StormLib.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED00B60D03542A00AB0B4E /* StormLib.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 225530E11056BC7900FA646A /* StormPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED00B70D03542A00AB0B4E /* StormPort.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 225530E31056BC8700FA646A /* huff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED009C0D03542A00AB0B4E /* huff.cpp */; }; + 225530E61056BC8700FA646A /* explode.c in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00A60D03542A00AB0B4E /* explode.c */; }; + 225530E71056BC8700FA646A /* implode.c in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00A70D03542A00AB0B4E /* implode.c */; }; + 225530E81056BC8700FA646A /* SFileAttributes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00A90D03542A00AB0B4E /* SFileAttributes.cpp */; }; + 225530E91056BC8700FA646A /* SBaseCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AA0D03542A00AB0B4E /* SBaseCommon.cpp */; }; + 225530EA1056BC8700FA646A /* SCompression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AC0D03542A00AB0B4E /* SCompression.cpp */; }; + 225530EB1056BC8700FA646A /* SFileCompactArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AD0D03542A00AB0B4E /* SFileCompactArchive.cpp */; }; + 225530EC1056BC8700FA646A /* SFileCreateArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AE0D03542A00AB0B4E /* SFileCreateArchive.cpp */; }; + 225530ED1056BC8700FA646A /* SFileExtractFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AF0D03542A00AB0B4E /* SFileExtractFile.cpp */; }; + 225530EE1056BC8700FA646A /* SFileFindFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B00D03542A00AB0B4E /* SFileFindFile.cpp */; }; + 225530EF1056BC8700FA646A /* SFileOpenArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B10D03542A00AB0B4E /* SFileOpenArchive.cpp */; }; + 225530F01056BC8700FA646A /* SFileOpenFileEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B20D03542A00AB0B4E /* SFileOpenFileEx.cpp */; }; + 225530F11056BC8700FA646A /* SFileReadFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B30D03542A00AB0B4E /* SFileReadFile.cpp */; }; + 225530F21056BC8700FA646A /* SFileListFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B40D03542A00AB0B4E /* SFileListFile.cpp */; }; + 225C734D1257CCC70009E8DA /* lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = 225C734B1257CCC70009E8DA /* lookup.h */; }; + 225C734F1257CCC70009E8DA /* lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = 225C734B1257CCC70009E8DA /* lookup.h */; }; + 225C73501257CCC70009E8DA /* lookup3.c in Sources */ = {isa = PBXBuildFile; fileRef = 225C734C1257CCC70009E8DA /* lookup3.c */; }; + 225C73541257CD0C0009E8DA /* SBaseFileTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 225C73531257CD0C0009E8DA /* SBaseFileTable.cpp */; }; + 225C73551257CD0C0009E8DA /* SBaseFileTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 225C73531257CD0C0009E8DA /* SBaseFileTable.cpp */; }; + 225C735A1257CD1F0009E8DA /* lookup3.c in Sources */ = {isa = PBXBuildFile; fileRef = 225C734C1257CCC70009E8DA /* lookup3.c */; }; + 225FAC9C0E53BAA100DA2CAE /* huff.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED009D0D03542A00AB0B4E /* huff.h */; }; + 225FAC9F0E53BAA100DA2CAE /* pklib.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED00A80D03542A00AB0B4E /* pklib.h */; }; + 225FACA00E53BAA100DA2CAE /* StormCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED00AB0D03542A00AB0B4E /* StormCommon.h */; }; + 225FACA10E53BAA100DA2CAE /* StormLib.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED00B60D03542A00AB0B4E /* StormLib.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 225FACA20E53BAA100DA2CAE /* StormPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 32ED00B70D03542A00AB0B4E /* StormPort.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 225FACA50E53BAB400DA2CAE /* huff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED009C0D03542A00AB0B4E /* huff.cpp */; }; + 225FACA90E53BAB400DA2CAE /* explode.c in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00A60D03542A00AB0B4E /* explode.c */; }; + 225FACAA0E53BAB400DA2CAE /* implode.c in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00A70D03542A00AB0B4E /* implode.c */; }; + 225FACAB0E53BAB400DA2CAE /* SFileAttributes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00A90D03542A00AB0B4E /* SFileAttributes.cpp */; }; + 225FACAC0E53BAB400DA2CAE /* SBaseCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AA0D03542A00AB0B4E /* SBaseCommon.cpp */; }; + 225FACAD0E53BAB400DA2CAE /* SCompression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AC0D03542A00AB0B4E /* SCompression.cpp */; }; + 225FACAE0E53BAB400DA2CAE /* SFileCompactArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AD0D03542A00AB0B4E /* SFileCompactArchive.cpp */; }; + 225FACAF0E53BAB400DA2CAE /* SFileCreateArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AE0D03542A00AB0B4E /* SFileCreateArchive.cpp */; }; + 225FACB00E53BAB400DA2CAE /* SFileExtractFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00AF0D03542A00AB0B4E /* SFileExtractFile.cpp */; }; + 225FACB10E53BAB400DA2CAE /* SFileFindFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B00D03542A00AB0B4E /* SFileFindFile.cpp */; }; + 225FACB20E53BAB400DA2CAE /* SFileOpenArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B10D03542A00AB0B4E /* SFileOpenArchive.cpp */; }; + 225FACB30E53BAB400DA2CAE /* SFileOpenFileEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B20D03542A00AB0B4E /* SFileOpenFileEx.cpp */; }; + 225FACB40E53BAB400DA2CAE /* SFileReadFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B30D03542A00AB0B4E /* SFileReadFile.cpp */; }; + 225FACB50E53BAB400DA2CAE /* SFileListFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32ED00B40D03542A00AB0B4E /* SFileListFile.cpp */; }; + 225FADD40E53C06600DA2CAE /* libbz2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 32D20A8A0CF3902D00230E7A /* libbz2.dylib */; settings = {ATTRIBUTES = (Required, ); }; }; + 225FADD50E53C06600DA2CAE /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 32D20A8B0CF3902D00230E7A /* libz.dylib */; settings = {ATTRIBUTES = (Required, ); }; }; + 226C7CA71857DE9400AB689C /* SBaseDumpData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 226C7CA61857DE9400AB689C /* SBaseDumpData.cpp */; }; + 226C7CA81857DE9400AB689C /* SBaseDumpData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 226C7CA61857DE9400AB689C /* SBaseDumpData.cpp */; }; + 226C7CAA1857DEAC00AB689C /* SBaseSubTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 226C7CA91857DEAC00AB689C /* SBaseSubTypes.cpp */; }; + 226C7CAB1857DEAC00AB689C /* SBaseSubTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 226C7CA91857DEAC00AB689C /* SBaseSubTypes.cpp */; }; + 226C7CAD1857DEEB00AB689C /* SFileGetFileInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 226C7CAC1857DEEB00AB689C /* SFileGetFileInfo.cpp */; }; + 226C7CAE1857DEEB00AB689C /* SFileGetFileInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 226C7CAC1857DEEB00AB689C /* SFileGetFileInfo.cpp */; }; + 228B538411BF7D0D001A58DA /* FileStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 228B538311BF7D0D001A58DA /* FileStream.cpp */; }; + 228B538511BF7D0D001A58DA /* FileStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 228B538311BF7D0D001A58DA /* FileStream.cpp */; }; + 22954AD211D463AB0064B264 /* Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2295488911D45A820064B264 /* Test.cpp */; }; + 22954AD311D463B50064B264 /* libStormLib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 225530D41056BAC800FA646A /* libStormLib.a */; }; + 22954AD611D463BE0064B264 /* libbz2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 32D20A8A0CF3902D00230E7A /* libbz2.dylib */; }; + 22954AD711D463BE0064B264 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 32D20A8B0CF3902D00230E7A /* libz.dylib */; }; + 2299D9D71167EFA8005C19BF /* adpcm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2299D9D51167EFA8005C19BF /* adpcm.cpp */; }; + 2299D9D81167EFA8005C19BF /* adpcm.h in Headers */ = {isa = PBXBuildFile; fileRef = 2299D9D61167EFA8005C19BF /* adpcm.h */; }; + 2299D9D91167EFA8005C19BF /* adpcm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2299D9D51167EFA8005C19BF /* adpcm.cpp */; }; + 2299D9DA1167EFA8005C19BF /* adpcm.h in Headers */ = {isa = PBXBuildFile; fileRef = 2299D9D61167EFA8005C19BF /* adpcm.h */; }; + 2299D9DE1167EFC6005C19BF /* sparse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2299D9DC1167EFC6005C19BF /* sparse.cpp */; }; + 2299D9DF1167EFC6005C19BF /* sparse.h in Headers */ = {isa = PBXBuildFile; fileRef = 2299D9DD1167EFC6005C19BF /* sparse.h */; }; + 2299D9E01167EFC6005C19BF /* sparse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2299D9DC1167EFC6005C19BF /* sparse.cpp */; }; + 2299D9E11167EFC6005C19BF /* sparse.h in Headers */ = {isa = PBXBuildFile; fileRef = 2299D9DD1167EFC6005C19BF /* sparse.h */; }; + 2299DA4E1167FD16005C19BF /* SFileAddFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2299DA4D1167FD16005C19BF /* SFileAddFile.cpp */; }; + 2299DA4F1167FD16005C19BF /* SFileAddFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2299DA4D1167FD16005C19BF /* SFileAddFile.cpp */; }; + 22AEA122123125D800359B16 /* SFilePatchArchives.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 22AEA121123125D800359B16 /* SFilePatchArchives.cpp */; }; + 22AEA123123125D800359B16 /* SFilePatchArchives.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 22AEA121123125D800359B16 /* SFilePatchArchives.cpp */; }; + 22C9187D11933FCF0083AC69 /* hash_memory.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9182B11933FCF0083AC69 /* hash_memory.c */; }; + 22C9187E11933FCF0083AC69 /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9182C11933FCF0083AC69 /* md5.c */; }; + 22C9187F11933FCF0083AC69 /* sha1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9182D11933FCF0083AC69 /* sha1.c */; }; + 22C9188011933FCF0083AC69 /* tomcrypt.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9182F11933FCF0083AC69 /* tomcrypt.h */; }; + 22C9188111933FCF0083AC69 /* tomcrypt_argchk.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183011933FCF0083AC69 /* tomcrypt_argchk.h */; }; + 22C9188211933FCF0083AC69 /* tomcrypt_cfg.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183111933FCF0083AC69 /* tomcrypt_cfg.h */; }; + 22C9188311933FCF0083AC69 /* tomcrypt_cipher.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183211933FCF0083AC69 /* tomcrypt_cipher.h */; }; + 22C9188411933FCF0083AC69 /* tomcrypt_custom.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183311933FCF0083AC69 /* tomcrypt_custom.h */; }; + 22C9188511933FCF0083AC69 /* tomcrypt_hash.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183411933FCF0083AC69 /* tomcrypt_hash.h */; }; + 22C9188611933FCF0083AC69 /* tomcrypt_mac.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183511933FCF0083AC69 /* tomcrypt_mac.h */; }; + 22C9188711933FCF0083AC69 /* tomcrypt_macros.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183611933FCF0083AC69 /* tomcrypt_macros.h */; }; + 22C9188811933FCF0083AC69 /* tomcrypt_math.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183711933FCF0083AC69 /* tomcrypt_math.h */; }; + 22C9188911933FCF0083AC69 /* tomcrypt_misc.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183811933FCF0083AC69 /* tomcrypt_misc.h */; }; + 22C9188A11933FCF0083AC69 /* tomcrypt_pk.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183911933FCF0083AC69 /* tomcrypt_pk.h */; }; + 22C9188B11933FCF0083AC69 /* tomcrypt_pkcs.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183A11933FCF0083AC69 /* tomcrypt_pkcs.h */; }; + 22C9188C11933FCF0083AC69 /* tomcrypt_prng.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183B11933FCF0083AC69 /* tomcrypt_prng.h */; }; + 22C9188D11933FCF0083AC69 /* ltm_desc.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9183D11933FCF0083AC69 /* ltm_desc.c */; }; + 22C9188E11933FCF0083AC69 /* multi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9183E11933FCF0083AC69 /* multi.c */; }; + 22C9188F11933FCF0083AC69 /* rand_prime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9183F11933FCF0083AC69 /* rand_prime.c */; }; + 22C9189011933FCF0083AC69 /* base64_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184111933FCF0083AC69 /* base64_decode.c */; }; + 22C9189111933FCF0083AC69 /* crypt_argchk.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184211933FCF0083AC69 /* crypt_argchk.c */; }; + 22C9189211933FCF0083AC69 /* crypt_find_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184311933FCF0083AC69 /* crypt_find_hash.c */; }; + 22C9189311933FCF0083AC69 /* crypt_find_prng.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184411933FCF0083AC69 /* crypt_find_prng.c */; }; + 22C9189411933FCF0083AC69 /* crypt_hash_descriptor.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184511933FCF0083AC69 /* crypt_hash_descriptor.c */; }; + 22C9189511933FCF0083AC69 /* crypt_hash_is_valid.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184611933FCF0083AC69 /* crypt_hash_is_valid.c */; }; + 22C9189611933FCF0083AC69 /* crypt_libc.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184711933FCF0083AC69 /* crypt_libc.c */; }; + 22C9189811933FCF0083AC69 /* crypt_prng_descriptor.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184911933FCF0083AC69 /* crypt_prng_descriptor.c */; }; + 22C9189911933FCF0083AC69 /* crypt_prng_is_valid.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184A11933FCF0083AC69 /* crypt_prng_is_valid.c */; }; + 22C9189A11933FCF0083AC69 /* crypt_register_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184B11933FCF0083AC69 /* crypt_register_hash.c */; }; + 22C9189B11933FCF0083AC69 /* crypt_register_prng.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184C11933FCF0083AC69 /* crypt_register_prng.c */; }; + 22C9189C11933FCF0083AC69 /* zeromem.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184D11933FCF0083AC69 /* zeromem.c */; }; + 22C9189D11933FCF0083AC69 /* der_decode_bit_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185011933FCF0083AC69 /* der_decode_bit_string.c */; }; + 22C9189E11933FCF0083AC69 /* der_decode_boolean.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185111933FCF0083AC69 /* der_decode_boolean.c */; }; + 22C9189F11933FCF0083AC69 /* der_decode_choice.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185211933FCF0083AC69 /* der_decode_choice.c */; }; + 22C918A011933FCF0083AC69 /* der_decode_ia5_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185311933FCF0083AC69 /* der_decode_ia5_string.c */; }; + 22C918A111933FCF0083AC69 /* der_decode_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185411933FCF0083AC69 /* der_decode_integer.c */; }; + 22C918A211933FCF0083AC69 /* der_decode_object_identifier.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185511933FCF0083AC69 /* der_decode_object_identifier.c */; }; + 22C918A311933FCF0083AC69 /* der_decode_octet_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185611933FCF0083AC69 /* der_decode_octet_string.c */; }; + 22C918A411933FCF0083AC69 /* der_decode_printable_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185711933FCF0083AC69 /* der_decode_printable_string.c */; }; + 22C918A511933FCF0083AC69 /* der_decode_sequence_ex.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185811933FCF0083AC69 /* der_decode_sequence_ex.c */; }; + 22C918A611933FCF0083AC69 /* der_decode_sequence_flexi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185911933FCF0083AC69 /* der_decode_sequence_flexi.c */; }; + 22C918A711933FCF0083AC69 /* der_decode_sequence_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185A11933FCF0083AC69 /* der_decode_sequence_multi.c */; }; + 22C918A811933FCF0083AC69 /* der_decode_short_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185B11933FCF0083AC69 /* der_decode_short_integer.c */; }; + 22C918A911933FCF0083AC69 /* der_decode_utctime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185C11933FCF0083AC69 /* der_decode_utctime.c */; }; + 22C918AA11933FCF0083AC69 /* der_decode_utf8_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185D11933FCF0083AC69 /* der_decode_utf8_string.c */; }; + 22C918AB11933FCF0083AC69 /* der_length_bit_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185E11933FCF0083AC69 /* der_length_bit_string.c */; }; + 22C918AC11933FCF0083AC69 /* der_length_boolean.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185F11933FCF0083AC69 /* der_length_boolean.c */; }; + 22C918AD11933FCF0083AC69 /* der_length_ia5_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186011933FCF0083AC69 /* der_length_ia5_string.c */; }; + 22C918AE11933FCF0083AC69 /* der_length_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186111933FCF0083AC69 /* der_length_integer.c */; }; + 22C918AF11933FCF0083AC69 /* der_length_object_identifier.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186211933FCF0083AC69 /* der_length_object_identifier.c */; }; + 22C918B011933FCF0083AC69 /* der_length_octet_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186311933FCF0083AC69 /* der_length_octet_string.c */; }; + 22C918B111933FCF0083AC69 /* der_length_printable_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186411933FCF0083AC69 /* der_length_printable_string.c */; }; + 22C918B211933FCF0083AC69 /* der_length_sequence.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186511933FCF0083AC69 /* der_length_sequence.c */; }; + 22C918B311933FCF0083AC69 /* der_length_short_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186611933FCF0083AC69 /* der_length_short_integer.c */; }; + 22C918B411933FCF0083AC69 /* der_length_utctime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186711933FCF0083AC69 /* der_length_utctime.c */; }; + 22C918B511933FCF0083AC69 /* der_length_utf8_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186811933FCF0083AC69 /* der_length_utf8_string.c */; }; + 22C918B611933FCF0083AC69 /* der_sequence_free.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186911933FCF0083AC69 /* der_sequence_free.c */; }; + 22C918B711933FCF0083AC69 /* ltc_ecc_map.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186B11933FCF0083AC69 /* ltc_ecc_map.c */; }; + 22C918B811933FCF0083AC69 /* ltc_ecc_mul2add.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186C11933FCF0083AC69 /* ltc_ecc_mul2add.c */; }; + 22C918B911933FCF0083AC69 /* ltc_ecc_mulmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186D11933FCF0083AC69 /* ltc_ecc_mulmod.c */; }; + 22C918BA11933FCF0083AC69 /* ltc_ecc_points.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186E11933FCF0083AC69 /* ltc_ecc_points.c */; }; + 22C918BB11933FCF0083AC69 /* ltc_ecc_projective_add_point.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186F11933FCF0083AC69 /* ltc_ecc_projective_add_point.c */; }; + 22C918BC11933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187011933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c */; }; + 22C918BD11933FCF0083AC69 /* pkcs_1_mgf1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187211933FCF0083AC69 /* pkcs_1_mgf1.c */; }; + 22C918BE11933FCF0083AC69 /* pkcs_1_oaep_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187311933FCF0083AC69 /* pkcs_1_oaep_decode.c */; }; + 22C918BF11933FCF0083AC69 /* pkcs_1_pss_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187411933FCF0083AC69 /* pkcs_1_pss_decode.c */; }; + 22C918C011933FCF0083AC69 /* pkcs_1_v1_5_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187511933FCF0083AC69 /* pkcs_1_v1_5_decode.c */; }; + 22C918C111933FCF0083AC69 /* rsa_exptmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187711933FCF0083AC69 /* rsa_exptmod.c */; }; + 22C918C211933FCF0083AC69 /* rsa_free.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187811933FCF0083AC69 /* rsa_free.c */; }; + 22C918C311933FCF0083AC69 /* rsa_import.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187911933FCF0083AC69 /* rsa_import.c */; }; + 22C918C411933FCF0083AC69 /* rsa_make_key.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187A11933FCF0083AC69 /* rsa_make_key.c */; }; + 22C918C511933FCF0083AC69 /* rsa_verify_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187B11933FCF0083AC69 /* rsa_verify_hash.c */; }; + 22C918C611933FCF0083AC69 /* rsa_verify_simple.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187C11933FCF0083AC69 /* rsa_verify_simple.c */; }; + 22C918C711933FCF0083AC69 /* hash_memory.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9182B11933FCF0083AC69 /* hash_memory.c */; }; + 22C918C811933FCF0083AC69 /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9182C11933FCF0083AC69 /* md5.c */; }; + 22C918C911933FCF0083AC69 /* sha1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9182D11933FCF0083AC69 /* sha1.c */; }; + 22C918CA11933FCF0083AC69 /* tomcrypt.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9182F11933FCF0083AC69 /* tomcrypt.h */; }; + 22C918CB11933FCF0083AC69 /* tomcrypt_argchk.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183011933FCF0083AC69 /* tomcrypt_argchk.h */; }; + 22C918CC11933FCF0083AC69 /* tomcrypt_cfg.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183111933FCF0083AC69 /* tomcrypt_cfg.h */; }; + 22C918CD11933FCF0083AC69 /* tomcrypt_cipher.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183211933FCF0083AC69 /* tomcrypt_cipher.h */; }; + 22C918CE11933FCF0083AC69 /* tomcrypt_custom.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183311933FCF0083AC69 /* tomcrypt_custom.h */; }; + 22C918CF11933FCF0083AC69 /* tomcrypt_hash.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183411933FCF0083AC69 /* tomcrypt_hash.h */; }; + 22C918D011933FCF0083AC69 /* tomcrypt_mac.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183511933FCF0083AC69 /* tomcrypt_mac.h */; }; + 22C918D111933FCF0083AC69 /* tomcrypt_macros.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183611933FCF0083AC69 /* tomcrypt_macros.h */; }; + 22C918D211933FCF0083AC69 /* tomcrypt_math.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183711933FCF0083AC69 /* tomcrypt_math.h */; }; + 22C918D311933FCF0083AC69 /* tomcrypt_misc.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183811933FCF0083AC69 /* tomcrypt_misc.h */; }; + 22C918D411933FCF0083AC69 /* tomcrypt_pk.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183911933FCF0083AC69 /* tomcrypt_pk.h */; }; + 22C918D511933FCF0083AC69 /* tomcrypt_pkcs.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183A11933FCF0083AC69 /* tomcrypt_pkcs.h */; }; + 22C918D611933FCF0083AC69 /* tomcrypt_prng.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C9183B11933FCF0083AC69 /* tomcrypt_prng.h */; }; + 22C918D711933FCF0083AC69 /* ltm_desc.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9183D11933FCF0083AC69 /* ltm_desc.c */; }; + 22C918D811933FCF0083AC69 /* multi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9183E11933FCF0083AC69 /* multi.c */; }; + 22C918D911933FCF0083AC69 /* rand_prime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9183F11933FCF0083AC69 /* rand_prime.c */; }; + 22C918DA11933FCF0083AC69 /* base64_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184111933FCF0083AC69 /* base64_decode.c */; }; + 22C918DB11933FCF0083AC69 /* crypt_argchk.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184211933FCF0083AC69 /* crypt_argchk.c */; }; + 22C918DC11933FCF0083AC69 /* crypt_find_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184311933FCF0083AC69 /* crypt_find_hash.c */; }; + 22C918DD11933FCF0083AC69 /* crypt_find_prng.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184411933FCF0083AC69 /* crypt_find_prng.c */; }; + 22C918DE11933FCF0083AC69 /* crypt_hash_descriptor.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184511933FCF0083AC69 /* crypt_hash_descriptor.c */; }; + 22C918DF11933FCF0083AC69 /* crypt_hash_is_valid.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184611933FCF0083AC69 /* crypt_hash_is_valid.c */; }; + 22C918E011933FCF0083AC69 /* crypt_libc.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184711933FCF0083AC69 /* crypt_libc.c */; }; + 22C918E111933FCF0083AC69 /* crypt_ltc_mp_descriptor.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184811933FCF0083AC69 /* crypt_ltc_mp_descriptor.c */; }; + 22C918E211933FCF0083AC69 /* crypt_prng_descriptor.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184911933FCF0083AC69 /* crypt_prng_descriptor.c */; }; + 22C918E311933FCF0083AC69 /* crypt_prng_is_valid.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184A11933FCF0083AC69 /* crypt_prng_is_valid.c */; }; + 22C918E411933FCF0083AC69 /* crypt_register_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184B11933FCF0083AC69 /* crypt_register_hash.c */; }; + 22C918E511933FCF0083AC69 /* crypt_register_prng.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184C11933FCF0083AC69 /* crypt_register_prng.c */; }; + 22C918E611933FCF0083AC69 /* zeromem.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9184D11933FCF0083AC69 /* zeromem.c */; }; + 22C918E711933FCF0083AC69 /* der_decode_bit_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185011933FCF0083AC69 /* der_decode_bit_string.c */; }; + 22C918E811933FCF0083AC69 /* der_decode_boolean.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185111933FCF0083AC69 /* der_decode_boolean.c */; }; + 22C918E911933FCF0083AC69 /* der_decode_choice.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185211933FCF0083AC69 /* der_decode_choice.c */; }; + 22C918EA11933FCF0083AC69 /* der_decode_ia5_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185311933FCF0083AC69 /* der_decode_ia5_string.c */; }; + 22C918EB11933FCF0083AC69 /* der_decode_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185411933FCF0083AC69 /* der_decode_integer.c */; }; + 22C918EC11933FCF0083AC69 /* der_decode_object_identifier.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185511933FCF0083AC69 /* der_decode_object_identifier.c */; }; + 22C918ED11933FCF0083AC69 /* der_decode_octet_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185611933FCF0083AC69 /* der_decode_octet_string.c */; }; + 22C918EE11933FCF0083AC69 /* der_decode_printable_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185711933FCF0083AC69 /* der_decode_printable_string.c */; }; + 22C918EF11933FCF0083AC69 /* der_decode_sequence_ex.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185811933FCF0083AC69 /* der_decode_sequence_ex.c */; }; + 22C918F011933FCF0083AC69 /* der_decode_sequence_flexi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185911933FCF0083AC69 /* der_decode_sequence_flexi.c */; }; + 22C918F111933FCF0083AC69 /* der_decode_sequence_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185A11933FCF0083AC69 /* der_decode_sequence_multi.c */; }; + 22C918F211933FCF0083AC69 /* der_decode_short_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185B11933FCF0083AC69 /* der_decode_short_integer.c */; }; + 22C918F311933FCF0083AC69 /* der_decode_utctime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185C11933FCF0083AC69 /* der_decode_utctime.c */; }; + 22C918F411933FCF0083AC69 /* der_decode_utf8_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185D11933FCF0083AC69 /* der_decode_utf8_string.c */; }; + 22C918F511933FCF0083AC69 /* der_length_bit_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185E11933FCF0083AC69 /* der_length_bit_string.c */; }; + 22C918F611933FCF0083AC69 /* der_length_boolean.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9185F11933FCF0083AC69 /* der_length_boolean.c */; }; + 22C918F711933FCF0083AC69 /* der_length_ia5_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186011933FCF0083AC69 /* der_length_ia5_string.c */; }; + 22C918F811933FCF0083AC69 /* der_length_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186111933FCF0083AC69 /* der_length_integer.c */; }; + 22C918F911933FCF0083AC69 /* der_length_object_identifier.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186211933FCF0083AC69 /* der_length_object_identifier.c */; }; + 22C918FA11933FCF0083AC69 /* der_length_octet_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186311933FCF0083AC69 /* der_length_octet_string.c */; }; + 22C918FB11933FCF0083AC69 /* der_length_printable_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186411933FCF0083AC69 /* der_length_printable_string.c */; }; + 22C918FC11933FCF0083AC69 /* der_length_sequence.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186511933FCF0083AC69 /* der_length_sequence.c */; }; + 22C918FD11933FCF0083AC69 /* der_length_short_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186611933FCF0083AC69 /* der_length_short_integer.c */; }; + 22C918FE11933FCF0083AC69 /* der_length_utctime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186711933FCF0083AC69 /* der_length_utctime.c */; }; + 22C918FF11933FCF0083AC69 /* der_length_utf8_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186811933FCF0083AC69 /* der_length_utf8_string.c */; }; + 22C9190011933FCF0083AC69 /* der_sequence_free.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186911933FCF0083AC69 /* der_sequence_free.c */; }; + 22C9190111933FCF0083AC69 /* ltc_ecc_map.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186B11933FCF0083AC69 /* ltc_ecc_map.c */; }; + 22C9190211933FCF0083AC69 /* ltc_ecc_mul2add.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186C11933FCF0083AC69 /* ltc_ecc_mul2add.c */; }; + 22C9190311933FCF0083AC69 /* ltc_ecc_mulmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186D11933FCF0083AC69 /* ltc_ecc_mulmod.c */; }; + 22C9190411933FCF0083AC69 /* ltc_ecc_points.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186E11933FCF0083AC69 /* ltc_ecc_points.c */; }; + 22C9190511933FCF0083AC69 /* ltc_ecc_projective_add_point.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9186F11933FCF0083AC69 /* ltc_ecc_projective_add_point.c */; }; + 22C9190611933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187011933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c */; }; + 22C9190711933FCF0083AC69 /* pkcs_1_mgf1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187211933FCF0083AC69 /* pkcs_1_mgf1.c */; }; + 22C9190811933FCF0083AC69 /* pkcs_1_oaep_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187311933FCF0083AC69 /* pkcs_1_oaep_decode.c */; }; + 22C9190911933FCF0083AC69 /* pkcs_1_pss_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187411933FCF0083AC69 /* pkcs_1_pss_decode.c */; }; + 22C9190A11933FCF0083AC69 /* pkcs_1_v1_5_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187511933FCF0083AC69 /* pkcs_1_v1_5_decode.c */; }; + 22C9190B11933FCF0083AC69 /* rsa_exptmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187711933FCF0083AC69 /* rsa_exptmod.c */; }; + 22C9190C11933FCF0083AC69 /* rsa_free.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187811933FCF0083AC69 /* rsa_free.c */; }; + 22C9190D11933FCF0083AC69 /* rsa_import.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187911933FCF0083AC69 /* rsa_import.c */; }; + 22C9190E11933FCF0083AC69 /* rsa_make_key.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187A11933FCF0083AC69 /* rsa_make_key.c */; }; + 22C9190F11933FCF0083AC69 /* rsa_verify_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187B11933FCF0083AC69 /* rsa_verify_hash.c */; }; + 22C9191011933FCF0083AC69 /* rsa_verify_simple.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9187C11933FCF0083AC69 /* rsa_verify_simple.c */; }; + 22C9198A1193400A0083AC69 /* bn_fast_mp_invmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919111193400A0083AC69 /* bn_fast_mp_invmod.c */; }; + 22C9198B1193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919121193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c */; }; + 22C9198C1193400A0083AC69 /* bn_fast_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919131193400A0083AC69 /* bn_fast_s_mp_mul_digs.c */; }; + 22C9198D1193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919141193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c */; }; + 22C9198E1193400A0083AC69 /* bn_fast_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919151193400A0083AC69 /* bn_fast_s_mp_sqr.c */; }; + 22C9198F1193400A0083AC69 /* bn_mp_2expt.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919161193400A0083AC69 /* bn_mp_2expt.c */; }; + 22C919901193400A0083AC69 /* bn_mp_abs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919171193400A0083AC69 /* bn_mp_abs.c */; }; + 22C919911193400A0083AC69 /* bn_mp_add_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919181193400A0083AC69 /* bn_mp_add_d.c */; }; + 22C919921193400A0083AC69 /* bn_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919191193400A0083AC69 /* bn_mp_add.c */; }; + 22C919931193400A0083AC69 /* bn_mp_addmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191A1193400A0083AC69 /* bn_mp_addmod.c */; }; + 22C919941193400A0083AC69 /* bn_mp_and.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191B1193400A0083AC69 /* bn_mp_and.c */; }; + 22C919951193400A0083AC69 /* bn_mp_clamp.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191C1193400A0083AC69 /* bn_mp_clamp.c */; }; + 22C919961193400A0083AC69 /* bn_mp_clear_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191D1193400A0083AC69 /* bn_mp_clear_multi.c */; }; + 22C919971193400A0083AC69 /* bn_mp_clear.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191E1193400A0083AC69 /* bn_mp_clear.c */; }; + 22C919981193400A0083AC69 /* bn_mp_cmp_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191F1193400A0083AC69 /* bn_mp_cmp_d.c */; }; + 22C919991193400A0083AC69 /* bn_mp_cmp_mag.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919201193400A0083AC69 /* bn_mp_cmp_mag.c */; }; + 22C9199A1193400A0083AC69 /* bn_mp_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919211193400A0083AC69 /* bn_mp_cmp.c */; }; + 22C9199B1193400A0083AC69 /* bn_mp_cnt_lsb.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919221193400A0083AC69 /* bn_mp_cnt_lsb.c */; }; + 22C9199C1193400A0083AC69 /* bn_mp_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919231193400A0083AC69 /* bn_mp_copy.c */; }; + 22C9199D1193400A0083AC69 /* bn_mp_count_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919241193400A0083AC69 /* bn_mp_count_bits.c */; }; + 22C9199E1193400A0083AC69 /* bn_mp_div_2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919251193400A0083AC69 /* bn_mp_div_2.c */; }; + 22C9199F1193400A0083AC69 /* bn_mp_div_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919261193400A0083AC69 /* bn_mp_div_2d.c */; }; + 22C919A01193400A0083AC69 /* bn_mp_div_3.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919271193400A0083AC69 /* bn_mp_div_3.c */; }; + 22C919A11193400A0083AC69 /* bn_mp_div_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919281193400A0083AC69 /* bn_mp_div_d.c */; }; + 22C919A21193400A0083AC69 /* bn_mp_div.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919291193400A0083AC69 /* bn_mp_div.c */; }; + 22C919A31193400A0083AC69 /* bn_mp_dr_is_modulus.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192A1193400A0083AC69 /* bn_mp_dr_is_modulus.c */; }; + 22C919A41193400A0083AC69 /* bn_mp_dr_reduce.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192B1193400A0083AC69 /* bn_mp_dr_reduce.c */; }; + 22C919A51193400A0083AC69 /* bn_mp_dr_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192C1193400A0083AC69 /* bn_mp_dr_setup.c */; }; + 22C919A61193400A0083AC69 /* bn_mp_exch.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192D1193400A0083AC69 /* bn_mp_exch.c */; }; + 22C919A71193400A0083AC69 /* bn_mp_expt_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192E1193400A0083AC69 /* bn_mp_expt_d.c */; }; + 22C919A81193400A0083AC69 /* bn_mp_exptmod_fast.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192F1193400A0083AC69 /* bn_mp_exptmod_fast.c */; }; + 22C919A91193400A0083AC69 /* bn_mp_exptmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919301193400A0083AC69 /* bn_mp_exptmod.c */; }; + 22C919AA1193400A0083AC69 /* bn_mp_exteuclid.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919311193400A0083AC69 /* bn_mp_exteuclid.c */; }; + 22C919AB1193400A0083AC69 /* bn_mp_fread.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919321193400A0083AC69 /* bn_mp_fread.c */; }; + 22C919AC1193400A0083AC69 /* bn_mp_fwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919331193400A0083AC69 /* bn_mp_fwrite.c */; }; + 22C919AD1193400A0083AC69 /* bn_mp_gcd.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919341193400A0083AC69 /* bn_mp_gcd.c */; }; + 22C919AE1193400A0083AC69 /* bn_mp_get_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919351193400A0083AC69 /* bn_mp_get_int.c */; }; + 22C919AF1193400A0083AC69 /* bn_mp_grow.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919361193400A0083AC69 /* bn_mp_grow.c */; }; + 22C919B01193400A0083AC69 /* bn_mp_init_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919371193400A0083AC69 /* bn_mp_init_copy.c */; }; + 22C919B11193400A0083AC69 /* bn_mp_init_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919381193400A0083AC69 /* bn_mp_init_multi.c */; }; + 22C919B21193400A0083AC69 /* bn_mp_init_set_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919391193400A0083AC69 /* bn_mp_init_set_int.c */; }; + 22C919B31193400A0083AC69 /* bn_mp_init_set.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193A1193400A0083AC69 /* bn_mp_init_set.c */; }; + 22C919B41193400A0083AC69 /* bn_mp_init_size.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193B1193400A0083AC69 /* bn_mp_init_size.c */; }; + 22C919B51193400A0083AC69 /* bn_mp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193C1193400A0083AC69 /* bn_mp_init.c */; }; + 22C919B61193400A0083AC69 /* bn_mp_invmod_slow.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193D1193400A0083AC69 /* bn_mp_invmod_slow.c */; }; + 22C919B71193400A0083AC69 /* bn_mp_invmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193E1193400A0083AC69 /* bn_mp_invmod.c */; }; + 22C919B81193400A0083AC69 /* bn_mp_is_square.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193F1193400A0083AC69 /* bn_mp_is_square.c */; }; + 22C919B91193400A0083AC69 /* bn_mp_jacobi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919401193400A0083AC69 /* bn_mp_jacobi.c */; }; + 22C919BA1193400A0083AC69 /* bn_mp_karatsuba_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919411193400A0083AC69 /* bn_mp_karatsuba_mul.c */; }; + 22C919BB1193400A0083AC69 /* bn_mp_karatsuba_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919421193400A0083AC69 /* bn_mp_karatsuba_sqr.c */; }; + 22C919BC1193400A0083AC69 /* bn_mp_lcm.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919431193400A0083AC69 /* bn_mp_lcm.c */; }; + 22C919BD1193400A0083AC69 /* bn_mp_lshd.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919441193400A0083AC69 /* bn_mp_lshd.c */; }; + 22C919BE1193400A0083AC69 /* bn_mp_mod_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919451193400A0083AC69 /* bn_mp_mod_2d.c */; }; + 22C919BF1193400A0083AC69 /* bn_mp_mod_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919461193400A0083AC69 /* bn_mp_mod_d.c */; }; + 22C919C01193400A0083AC69 /* bn_mp_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919471193400A0083AC69 /* bn_mp_mod.c */; }; + 22C919C11193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919481193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c */; }; + 22C919C21193400A0083AC69 /* bn_mp_montgomery_reduce.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919491193400A0083AC69 /* bn_mp_montgomery_reduce.c */; }; + 22C919C31193400A0083AC69 /* bn_mp_montgomery_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194A1193400A0083AC69 /* bn_mp_montgomery_setup.c */; }; + 22C919C41193400A0083AC69 /* bn_mp_mul_2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194B1193400A0083AC69 /* bn_mp_mul_2.c */; }; + 22C919C51193400A0083AC69 /* bn_mp_mul_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194C1193400A0083AC69 /* bn_mp_mul_2d.c */; }; + 22C919C61193400A0083AC69 /* bn_mp_mul_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194D1193400A0083AC69 /* bn_mp_mul_d.c */; }; + 22C919C71193400A0083AC69 /* bn_mp_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194E1193400A0083AC69 /* bn_mp_mul.c */; }; + 22C919C81193400A0083AC69 /* bn_mp_mulmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194F1193400A0083AC69 /* bn_mp_mulmod.c */; }; + 22C919C91193400A0083AC69 /* bn_mp_n_root.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919501193400A0083AC69 /* bn_mp_n_root.c */; }; + 22C919CA1193400A0083AC69 /* bn_mp_neg.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919511193400A0083AC69 /* bn_mp_neg.c */; }; + 22C919CB1193400A0083AC69 /* bn_mp_or.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919521193400A0083AC69 /* bn_mp_or.c */; }; + 22C919CC1193400A0083AC69 /* bn_mp_prime_fermat.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919531193400A0083AC69 /* bn_mp_prime_fermat.c */; }; + 22C919CD1193400A0083AC69 /* bn_mp_prime_is_divisible.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919541193400A0083AC69 /* bn_mp_prime_is_divisible.c */; }; + 22C919CE1193400A0083AC69 /* bn_mp_prime_is_prime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919551193400A0083AC69 /* bn_mp_prime_is_prime.c */; }; + 22C919CF1193400A0083AC69 /* bn_mp_prime_miller_rabin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919561193400A0083AC69 /* bn_mp_prime_miller_rabin.c */; }; + 22C919D01193400A0083AC69 /* bn_mp_prime_next_prime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919571193400A0083AC69 /* bn_mp_prime_next_prime.c */; }; + 22C919D11193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919581193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c */; }; + 22C919D21193400A0083AC69 /* bn_mp_prime_random_ex.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919591193400A0083AC69 /* bn_mp_prime_random_ex.c */; }; + 22C919D31193400A0083AC69 /* bn_mp_radix_size.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195A1193400A0083AC69 /* bn_mp_radix_size.c */; }; + 22C919D41193400A0083AC69 /* bn_mp_radix_smap.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195B1193400A0083AC69 /* bn_mp_radix_smap.c */; }; + 22C919D51193400A0083AC69 /* bn_mp_rand.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195C1193400A0083AC69 /* bn_mp_rand.c */; }; + 22C919D61193400A0083AC69 /* bn_mp_read_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195D1193400A0083AC69 /* bn_mp_read_radix.c */; }; + 22C919D71193400A0083AC69 /* bn_mp_read_signed_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195E1193400A0083AC69 /* bn_mp_read_signed_bin.c */; }; + 22C919D81193400A0083AC69 /* bn_mp_read_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195F1193400A0083AC69 /* bn_mp_read_unsigned_bin.c */; }; + 22C919D91193400A0083AC69 /* bn_mp_reduce_2k_l.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919601193400A0083AC69 /* bn_mp_reduce_2k_l.c */; }; + 22C919DA1193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919611193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c */; }; + 22C919DB1193400A0083AC69 /* bn_mp_reduce_2k_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919621193400A0083AC69 /* bn_mp_reduce_2k_setup.c */; }; + 22C919DC1193400A0083AC69 /* bn_mp_reduce_2k.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919631193400A0083AC69 /* bn_mp_reduce_2k.c */; }; + 22C919DD1193400A0083AC69 /* bn_mp_reduce_is_2k_l.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919641193400A0083AC69 /* bn_mp_reduce_is_2k_l.c */; }; + 22C919DE1193400A0083AC69 /* bn_mp_reduce_is_2k.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919651193400A0083AC69 /* bn_mp_reduce_is_2k.c */; }; + 22C919DF1193400A0083AC69 /* bn_mp_reduce_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919661193400A0083AC69 /* bn_mp_reduce_setup.c */; }; + 22C919E01193400A0083AC69 /* bn_mp_reduce.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919671193400A0083AC69 /* bn_mp_reduce.c */; }; + 22C919E11193400A0083AC69 /* bn_mp_rshd.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919681193400A0083AC69 /* bn_mp_rshd.c */; }; + 22C919E21193400A0083AC69 /* bn_mp_set_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919691193400A0083AC69 /* bn_mp_set_int.c */; }; + 22C919E31193400A0083AC69 /* bn_mp_set.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196A1193400A0083AC69 /* bn_mp_set.c */; }; + 22C919E41193400A0083AC69 /* bn_mp_shrink.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196B1193400A0083AC69 /* bn_mp_shrink.c */; }; + 22C919E51193400A0083AC69 /* bn_mp_signed_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196C1193400A0083AC69 /* bn_mp_signed_bin_size.c */; }; + 22C919E61193400A0083AC69 /* bn_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196D1193400A0083AC69 /* bn_mp_sqr.c */; }; + 22C919E71193400A0083AC69 /* bn_mp_sqrmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196E1193400A0083AC69 /* bn_mp_sqrmod.c */; }; + 22C919E81193400A0083AC69 /* bn_mp_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196F1193400A0083AC69 /* bn_mp_sqrt.c */; }; + 22C919E91193400A0083AC69 /* bn_mp_sub_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919701193400A0083AC69 /* bn_mp_sub_d.c */; }; + 22C919EA1193400A0083AC69 /* bn_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919711193400A0083AC69 /* bn_mp_sub.c */; }; + 22C919EB1193400A0083AC69 /* bn_mp_submod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919721193400A0083AC69 /* bn_mp_submod.c */; }; + 22C919EC1193400A0083AC69 /* bn_mp_to_signed_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919731193400A0083AC69 /* bn_mp_to_signed_bin_n.c */; }; + 22C919ED1193400A0083AC69 /* bn_mp_to_signed_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919741193400A0083AC69 /* bn_mp_to_signed_bin.c */; }; + 22C919EE1193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919751193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c */; }; + 22C919EF1193400A0083AC69 /* bn_mp_to_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919761193400A0083AC69 /* bn_mp_to_unsigned_bin.c */; }; + 22C919F01193400A0083AC69 /* bn_mp_toom_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919771193400A0083AC69 /* bn_mp_toom_mul.c */; }; + 22C919F11193400A0083AC69 /* bn_mp_toom_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919781193400A0083AC69 /* bn_mp_toom_sqr.c */; }; + 22C919F21193400A0083AC69 /* bn_mp_toradix_n.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919791193400A0083AC69 /* bn_mp_toradix_n.c */; }; + 22C919F31193400A0083AC69 /* bn_mp_toradix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197A1193400A0083AC69 /* bn_mp_toradix.c */; }; + 22C919F41193400A0083AC69 /* bn_mp_unsigned_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197B1193400A0083AC69 /* bn_mp_unsigned_bin_size.c */; }; + 22C919F51193400A0083AC69 /* bn_mp_xor.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197C1193400A0083AC69 /* bn_mp_xor.c */; }; + 22C919F61193400A0083AC69 /* bn_mp_zero.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197D1193400A0083AC69 /* bn_mp_zero.c */; }; + 22C919F71193400A0083AC69 /* bn_prime_tab.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197E1193400A0083AC69 /* bn_prime_tab.c */; }; + 22C919F81193400A0083AC69 /* bn_reverse.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197F1193400A0083AC69 /* bn_reverse.c */; }; + 22C919F91193400A0083AC69 /* bn_s_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919801193400A0083AC69 /* bn_s_mp_add.c */; }; + 22C919FA1193400A0083AC69 /* bn_s_mp_exptmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919811193400A0083AC69 /* bn_s_mp_exptmod.c */; }; + 22C919FB1193400A0083AC69 /* bn_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919821193400A0083AC69 /* bn_s_mp_mul_digs.c */; }; + 22C919FC1193400A0083AC69 /* bn_s_mp_mul_high_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919831193400A0083AC69 /* bn_s_mp_mul_high_digs.c */; }; + 22C919FD1193400A0083AC69 /* bn_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919841193400A0083AC69 /* bn_s_mp_sqr.c */; }; + 22C919FE1193400A0083AC69 /* bn_s_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919851193400A0083AC69 /* bn_s_mp_sub.c */; }; + 22C919FF1193400A0083AC69 /* bncore.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919861193400A0083AC69 /* bncore.c */; }; + 22C91A001193400A0083AC69 /* tommath_class.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C919871193400A0083AC69 /* tommath_class.h */; }; + 22C91A011193400A0083AC69 /* tommath_superclass.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C919881193400A0083AC69 /* tommath_superclass.h */; }; + 22C91A021193400A0083AC69 /* tommath.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C919891193400A0083AC69 /* tommath.h */; }; + 22C91A031193400A0083AC69 /* bn_fast_mp_invmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919111193400A0083AC69 /* bn_fast_mp_invmod.c */; }; + 22C91A041193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919121193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c */; }; + 22C91A051193400A0083AC69 /* bn_fast_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919131193400A0083AC69 /* bn_fast_s_mp_mul_digs.c */; }; + 22C91A061193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919141193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c */; }; + 22C91A071193400A0083AC69 /* bn_fast_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919151193400A0083AC69 /* bn_fast_s_mp_sqr.c */; }; + 22C91A081193400A0083AC69 /* bn_mp_2expt.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919161193400A0083AC69 /* bn_mp_2expt.c */; }; + 22C91A091193400A0083AC69 /* bn_mp_abs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919171193400A0083AC69 /* bn_mp_abs.c */; }; + 22C91A0A1193400A0083AC69 /* bn_mp_add_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919181193400A0083AC69 /* bn_mp_add_d.c */; }; + 22C91A0B1193400A0083AC69 /* bn_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919191193400A0083AC69 /* bn_mp_add.c */; }; + 22C91A0C1193400A0083AC69 /* bn_mp_addmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191A1193400A0083AC69 /* bn_mp_addmod.c */; }; + 22C91A0D1193400A0083AC69 /* bn_mp_and.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191B1193400A0083AC69 /* bn_mp_and.c */; }; + 22C91A0E1193400A0083AC69 /* bn_mp_clamp.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191C1193400A0083AC69 /* bn_mp_clamp.c */; }; + 22C91A0F1193400A0083AC69 /* bn_mp_clear_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191D1193400A0083AC69 /* bn_mp_clear_multi.c */; }; + 22C91A101193400A0083AC69 /* bn_mp_clear.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191E1193400A0083AC69 /* bn_mp_clear.c */; }; + 22C91A111193400A0083AC69 /* bn_mp_cmp_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9191F1193400A0083AC69 /* bn_mp_cmp_d.c */; }; + 22C91A121193400A0083AC69 /* bn_mp_cmp_mag.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919201193400A0083AC69 /* bn_mp_cmp_mag.c */; }; + 22C91A131193400A0083AC69 /* bn_mp_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919211193400A0083AC69 /* bn_mp_cmp.c */; }; + 22C91A141193400A0083AC69 /* bn_mp_cnt_lsb.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919221193400A0083AC69 /* bn_mp_cnt_lsb.c */; }; + 22C91A151193400A0083AC69 /* bn_mp_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919231193400A0083AC69 /* bn_mp_copy.c */; }; + 22C91A161193400A0083AC69 /* bn_mp_count_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919241193400A0083AC69 /* bn_mp_count_bits.c */; }; + 22C91A171193400A0083AC69 /* bn_mp_div_2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919251193400A0083AC69 /* bn_mp_div_2.c */; }; + 22C91A181193400A0083AC69 /* bn_mp_div_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919261193400A0083AC69 /* bn_mp_div_2d.c */; }; + 22C91A191193400A0083AC69 /* bn_mp_div_3.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919271193400A0083AC69 /* bn_mp_div_3.c */; }; + 22C91A1A1193400A0083AC69 /* bn_mp_div_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919281193400A0083AC69 /* bn_mp_div_d.c */; }; + 22C91A1B1193400A0083AC69 /* bn_mp_div.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919291193400A0083AC69 /* bn_mp_div.c */; }; + 22C91A1C1193400A0083AC69 /* bn_mp_dr_is_modulus.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192A1193400A0083AC69 /* bn_mp_dr_is_modulus.c */; }; + 22C91A1D1193400A0083AC69 /* bn_mp_dr_reduce.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192B1193400A0083AC69 /* bn_mp_dr_reduce.c */; }; + 22C91A1E1193400A0083AC69 /* bn_mp_dr_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192C1193400A0083AC69 /* bn_mp_dr_setup.c */; }; + 22C91A1F1193400A0083AC69 /* bn_mp_exch.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192D1193400A0083AC69 /* bn_mp_exch.c */; }; + 22C91A201193400A0083AC69 /* bn_mp_expt_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192E1193400A0083AC69 /* bn_mp_expt_d.c */; }; + 22C91A211193400A0083AC69 /* bn_mp_exptmod_fast.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9192F1193400A0083AC69 /* bn_mp_exptmod_fast.c */; }; + 22C91A221193400A0083AC69 /* bn_mp_exptmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919301193400A0083AC69 /* bn_mp_exptmod.c */; }; + 22C91A231193400A0083AC69 /* bn_mp_exteuclid.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919311193400A0083AC69 /* bn_mp_exteuclid.c */; }; + 22C91A241193400A0083AC69 /* bn_mp_fread.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919321193400A0083AC69 /* bn_mp_fread.c */; }; + 22C91A251193400A0083AC69 /* bn_mp_fwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919331193400A0083AC69 /* bn_mp_fwrite.c */; }; + 22C91A261193400A0083AC69 /* bn_mp_gcd.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919341193400A0083AC69 /* bn_mp_gcd.c */; }; + 22C91A271193400A0083AC69 /* bn_mp_get_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919351193400A0083AC69 /* bn_mp_get_int.c */; }; + 22C91A281193400A0083AC69 /* bn_mp_grow.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919361193400A0083AC69 /* bn_mp_grow.c */; }; + 22C91A291193400A0083AC69 /* bn_mp_init_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919371193400A0083AC69 /* bn_mp_init_copy.c */; }; + 22C91A2A1193400A0083AC69 /* bn_mp_init_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919381193400A0083AC69 /* bn_mp_init_multi.c */; }; + 22C91A2B1193400A0083AC69 /* bn_mp_init_set_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919391193400A0083AC69 /* bn_mp_init_set_int.c */; }; + 22C91A2C1193400A0083AC69 /* bn_mp_init_set.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193A1193400A0083AC69 /* bn_mp_init_set.c */; }; + 22C91A2D1193400A0083AC69 /* bn_mp_init_size.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193B1193400A0083AC69 /* bn_mp_init_size.c */; }; + 22C91A2E1193400A0083AC69 /* bn_mp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193C1193400A0083AC69 /* bn_mp_init.c */; }; + 22C91A2F1193400A0083AC69 /* bn_mp_invmod_slow.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193D1193400A0083AC69 /* bn_mp_invmod_slow.c */; }; + 22C91A301193400A0083AC69 /* bn_mp_invmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193E1193400A0083AC69 /* bn_mp_invmod.c */; }; + 22C91A311193400A0083AC69 /* bn_mp_is_square.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9193F1193400A0083AC69 /* bn_mp_is_square.c */; }; + 22C91A321193400A0083AC69 /* bn_mp_jacobi.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919401193400A0083AC69 /* bn_mp_jacobi.c */; }; + 22C91A331193400A0083AC69 /* bn_mp_karatsuba_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919411193400A0083AC69 /* bn_mp_karatsuba_mul.c */; }; + 22C91A341193400A0083AC69 /* bn_mp_karatsuba_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919421193400A0083AC69 /* bn_mp_karatsuba_sqr.c */; }; + 22C91A351193400A0083AC69 /* bn_mp_lcm.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919431193400A0083AC69 /* bn_mp_lcm.c */; }; + 22C91A361193400A0083AC69 /* bn_mp_lshd.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919441193400A0083AC69 /* bn_mp_lshd.c */; }; + 22C91A371193400A0083AC69 /* bn_mp_mod_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919451193400A0083AC69 /* bn_mp_mod_2d.c */; }; + 22C91A381193400A0083AC69 /* bn_mp_mod_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919461193400A0083AC69 /* bn_mp_mod_d.c */; }; + 22C91A391193400A0083AC69 /* bn_mp_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919471193400A0083AC69 /* bn_mp_mod.c */; }; + 22C91A3A1193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919481193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c */; }; + 22C91A3B1193400A0083AC69 /* bn_mp_montgomery_reduce.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919491193400A0083AC69 /* bn_mp_montgomery_reduce.c */; }; + 22C91A3C1193400A0083AC69 /* bn_mp_montgomery_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194A1193400A0083AC69 /* bn_mp_montgomery_setup.c */; }; + 22C91A3D1193400A0083AC69 /* bn_mp_mul_2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194B1193400A0083AC69 /* bn_mp_mul_2.c */; }; + 22C91A3E1193400A0083AC69 /* bn_mp_mul_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194C1193400A0083AC69 /* bn_mp_mul_2d.c */; }; + 22C91A3F1193400A0083AC69 /* bn_mp_mul_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194D1193400A0083AC69 /* bn_mp_mul_d.c */; }; + 22C91A401193400A0083AC69 /* bn_mp_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194E1193400A0083AC69 /* bn_mp_mul.c */; }; + 22C91A411193400A0083AC69 /* bn_mp_mulmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9194F1193400A0083AC69 /* bn_mp_mulmod.c */; }; + 22C91A421193400A0083AC69 /* bn_mp_n_root.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919501193400A0083AC69 /* bn_mp_n_root.c */; }; + 22C91A431193400A0083AC69 /* bn_mp_neg.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919511193400A0083AC69 /* bn_mp_neg.c */; }; + 22C91A441193400A0083AC69 /* bn_mp_or.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919521193400A0083AC69 /* bn_mp_or.c */; }; + 22C91A451193400A0083AC69 /* bn_mp_prime_fermat.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919531193400A0083AC69 /* bn_mp_prime_fermat.c */; }; + 22C91A461193400A0083AC69 /* bn_mp_prime_is_divisible.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919541193400A0083AC69 /* bn_mp_prime_is_divisible.c */; }; + 22C91A471193400A0083AC69 /* bn_mp_prime_is_prime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919551193400A0083AC69 /* bn_mp_prime_is_prime.c */; }; + 22C91A481193400A0083AC69 /* bn_mp_prime_miller_rabin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919561193400A0083AC69 /* bn_mp_prime_miller_rabin.c */; }; + 22C91A491193400A0083AC69 /* bn_mp_prime_next_prime.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919571193400A0083AC69 /* bn_mp_prime_next_prime.c */; }; + 22C91A4A1193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919581193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c */; }; + 22C91A4B1193400A0083AC69 /* bn_mp_prime_random_ex.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919591193400A0083AC69 /* bn_mp_prime_random_ex.c */; }; + 22C91A4C1193400A0083AC69 /* bn_mp_radix_size.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195A1193400A0083AC69 /* bn_mp_radix_size.c */; }; + 22C91A4D1193400A0083AC69 /* bn_mp_radix_smap.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195B1193400A0083AC69 /* bn_mp_radix_smap.c */; }; + 22C91A4E1193400A0083AC69 /* bn_mp_rand.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195C1193400A0083AC69 /* bn_mp_rand.c */; }; + 22C91A4F1193400A0083AC69 /* bn_mp_read_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195D1193400A0083AC69 /* bn_mp_read_radix.c */; }; + 22C91A501193400A0083AC69 /* bn_mp_read_signed_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195E1193400A0083AC69 /* bn_mp_read_signed_bin.c */; }; + 22C91A511193400A0083AC69 /* bn_mp_read_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9195F1193400A0083AC69 /* bn_mp_read_unsigned_bin.c */; }; + 22C91A521193400A0083AC69 /* bn_mp_reduce_2k_l.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919601193400A0083AC69 /* bn_mp_reduce_2k_l.c */; }; + 22C91A531193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919611193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c */; }; + 22C91A541193400A0083AC69 /* bn_mp_reduce_2k_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919621193400A0083AC69 /* bn_mp_reduce_2k_setup.c */; }; + 22C91A551193400A0083AC69 /* bn_mp_reduce_2k.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919631193400A0083AC69 /* bn_mp_reduce_2k.c */; }; + 22C91A561193400A0083AC69 /* bn_mp_reduce_is_2k_l.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919641193400A0083AC69 /* bn_mp_reduce_is_2k_l.c */; }; + 22C91A571193400A0083AC69 /* bn_mp_reduce_is_2k.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919651193400A0083AC69 /* bn_mp_reduce_is_2k.c */; }; + 22C91A581193400A0083AC69 /* bn_mp_reduce_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919661193400A0083AC69 /* bn_mp_reduce_setup.c */; }; + 22C91A591193400A0083AC69 /* bn_mp_reduce.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919671193400A0083AC69 /* bn_mp_reduce.c */; }; + 22C91A5A1193400A0083AC69 /* bn_mp_rshd.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919681193400A0083AC69 /* bn_mp_rshd.c */; }; + 22C91A5B1193400A0083AC69 /* bn_mp_set_int.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919691193400A0083AC69 /* bn_mp_set_int.c */; }; + 22C91A5C1193400A0083AC69 /* bn_mp_set.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196A1193400A0083AC69 /* bn_mp_set.c */; }; + 22C91A5D1193400A0083AC69 /* bn_mp_shrink.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196B1193400A0083AC69 /* bn_mp_shrink.c */; }; + 22C91A5E1193400A0083AC69 /* bn_mp_signed_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196C1193400A0083AC69 /* bn_mp_signed_bin_size.c */; }; + 22C91A5F1193400A0083AC69 /* bn_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196D1193400A0083AC69 /* bn_mp_sqr.c */; }; + 22C91A601193400A0083AC69 /* bn_mp_sqrmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196E1193400A0083AC69 /* bn_mp_sqrmod.c */; }; + 22C91A611193400A0083AC69 /* bn_mp_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9196F1193400A0083AC69 /* bn_mp_sqrt.c */; }; + 22C91A621193400A0083AC69 /* bn_mp_sub_d.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919701193400A0083AC69 /* bn_mp_sub_d.c */; }; + 22C91A631193400A0083AC69 /* bn_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919711193400A0083AC69 /* bn_mp_sub.c */; }; + 22C91A641193400A0083AC69 /* bn_mp_submod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919721193400A0083AC69 /* bn_mp_submod.c */; }; + 22C91A651193400A0083AC69 /* bn_mp_to_signed_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919731193400A0083AC69 /* bn_mp_to_signed_bin_n.c */; }; + 22C91A661193400A0083AC69 /* bn_mp_to_signed_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919741193400A0083AC69 /* bn_mp_to_signed_bin.c */; }; + 22C91A671193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919751193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c */; }; + 22C91A681193400A0083AC69 /* bn_mp_to_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919761193400A0083AC69 /* bn_mp_to_unsigned_bin.c */; }; + 22C91A691193400A0083AC69 /* bn_mp_toom_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919771193400A0083AC69 /* bn_mp_toom_mul.c */; }; + 22C91A6A1193400A0083AC69 /* bn_mp_toom_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919781193400A0083AC69 /* bn_mp_toom_sqr.c */; }; + 22C91A6B1193400A0083AC69 /* bn_mp_toradix_n.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919791193400A0083AC69 /* bn_mp_toradix_n.c */; }; + 22C91A6C1193400A0083AC69 /* bn_mp_toradix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197A1193400A0083AC69 /* bn_mp_toradix.c */; }; + 22C91A6D1193400A0083AC69 /* bn_mp_unsigned_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197B1193400A0083AC69 /* bn_mp_unsigned_bin_size.c */; }; + 22C91A6E1193400A0083AC69 /* bn_mp_xor.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197C1193400A0083AC69 /* bn_mp_xor.c */; }; + 22C91A6F1193400A0083AC69 /* bn_mp_zero.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197D1193400A0083AC69 /* bn_mp_zero.c */; }; + 22C91A701193400A0083AC69 /* bn_prime_tab.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197E1193400A0083AC69 /* bn_prime_tab.c */; }; + 22C91A711193400A0083AC69 /* bn_reverse.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C9197F1193400A0083AC69 /* bn_reverse.c */; }; + 22C91A721193400A0083AC69 /* bn_s_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919801193400A0083AC69 /* bn_s_mp_add.c */; }; + 22C91A731193400A0083AC69 /* bn_s_mp_exptmod.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919811193400A0083AC69 /* bn_s_mp_exptmod.c */; }; + 22C91A741193400A0083AC69 /* bn_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919821193400A0083AC69 /* bn_s_mp_mul_digs.c */; }; + 22C91A751193400A0083AC69 /* bn_s_mp_mul_high_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919831193400A0083AC69 /* bn_s_mp_mul_high_digs.c */; }; + 22C91A761193400A0083AC69 /* bn_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919841193400A0083AC69 /* bn_s_mp_sqr.c */; }; + 22C91A771193400A0083AC69 /* bn_s_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919851193400A0083AC69 /* bn_s_mp_sub.c */; }; + 22C91A781193400A0083AC69 /* bncore.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C919861193400A0083AC69 /* bncore.c */; }; + 22C91A791193400A0083AC69 /* tommath_class.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C919871193400A0083AC69 /* tommath_class.h */; }; + 22C91A7A1193400A0083AC69 /* tommath_superclass.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C919881193400A0083AC69 /* tommath_superclass.h */; }; + 22C91A7B1193400A0083AC69 /* tommath.h in Headers */ = {isa = PBXBuildFile; fileRef = 22C919891193400A0083AC69 /* tommath.h */; }; + 22EC6044154B28A000679228 /* FileStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 22EC6043154B28A000679228 /* FileStream.h */; }; + 22EC6045154B28A000679228 /* FileStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 22EC6043154B28A000679228 /* FileStream.h */; }; + 22F5A9C51193DFBA00F8B121 /* SFileVerify.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 22F5A9C41193DFBA00F8B121 /* SFileVerify.cpp */; }; + 22F5A9C61193DFBA00F8B121 /* SFileVerify.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 22F5A9C41193DFBA00F8B121 /* SFileVerify.cpp */; }; + E60816D61B707A9000B283F7 /* rsa_sign_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816D51B707A9000B283F7 /* rsa_sign_hash.c */; }; + E60816D71B707A9B00B283F7 /* rsa_sign_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816D51B707A9000B283F7 /* rsa_sign_hash.c */; }; + E60816D91B707B1800B283F7 /* pkcs_1_pss_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816D81B707B1800B283F7 /* pkcs_1_pss_encode.c */; }; + E60816DA1B707B1800B283F7 /* pkcs_1_pss_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816D81B707B1800B283F7 /* pkcs_1_pss_encode.c */; }; + E60816DC1B707B2700B283F7 /* pkcs_1_v1_5_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816DB1B707B2700B283F7 /* pkcs_1_v1_5_encode.c */; }; + E60816DD1B707B2700B283F7 /* pkcs_1_v1_5_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816DB1B707B2700B283F7 /* pkcs_1_v1_5_encode.c */; }; + E60816DF1B707B5700B283F7 /* der_encode_sequence_ex.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816DE1B707B5700B283F7 /* der_encode_sequence_ex.c */; }; + E60816E01B707B5700B283F7 /* der_encode_sequence_ex.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816DE1B707B5700B283F7 /* der_encode_sequence_ex.c */; }; + E60816EE1B707B7200B283F7 /* der_encode_bit_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E11B707B7200B283F7 /* der_encode_bit_string.c */; }; + E60816EF1B707B7200B283F7 /* der_encode_bit_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E11B707B7200B283F7 /* der_encode_bit_string.c */; }; + E60816F01B707B7200B283F7 /* der_encode_boolean.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E21B707B7200B283F7 /* der_encode_boolean.c */; }; + E60816F11B707B7200B283F7 /* der_encode_boolean.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E21B707B7200B283F7 /* der_encode_boolean.c */; }; + E60816F21B707B7200B283F7 /* der_encode_ia5_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E31B707B7200B283F7 /* der_encode_ia5_string.c */; }; + E60816F31B707B7200B283F7 /* der_encode_ia5_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E31B707B7200B283F7 /* der_encode_ia5_string.c */; }; + E60816F41B707B7200B283F7 /* der_encode_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E41B707B7200B283F7 /* der_encode_integer.c */; }; + E60816F51B707B7200B283F7 /* der_encode_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E41B707B7200B283F7 /* der_encode_integer.c */; }; + E60816F61B707B7200B283F7 /* der_encode_object_identifier.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E51B707B7200B283F7 /* der_encode_object_identifier.c */; }; + E60816F71B707B7200B283F7 /* der_encode_object_identifier.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E51B707B7200B283F7 /* der_encode_object_identifier.c */; }; + E60816F81B707B7200B283F7 /* der_encode_octet_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E61B707B7200B283F7 /* der_encode_octet_string.c */; }; + E60816F91B707B7200B283F7 /* der_encode_octet_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E61B707B7200B283F7 /* der_encode_octet_string.c */; }; + E60816FA1B707B7200B283F7 /* der_encode_printable_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E71B707B7200B283F7 /* der_encode_printable_string.c */; }; + E60816FB1B707B7200B283F7 /* der_encode_printable_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E71B707B7200B283F7 /* der_encode_printable_string.c */; }; + E60816FC1B707B7200B283F7 /* der_encode_sequence_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E81B707B7200B283F7 /* der_encode_sequence_multi.c */; }; + E60816FD1B707B7200B283F7 /* der_encode_sequence_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E81B707B7200B283F7 /* der_encode_sequence_multi.c */; }; + E60816FE1B707B7200B283F7 /* der_encode_set.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E91B707B7200B283F7 /* der_encode_set.c */; }; + E60816FF1B707B7200B283F7 /* der_encode_set.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816E91B707B7200B283F7 /* der_encode_set.c */; }; + E60817001B707B7200B283F7 /* der_encode_setof.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816EA1B707B7200B283F7 /* der_encode_setof.c */; }; + E60817011B707B7200B283F7 /* der_encode_setof.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816EA1B707B7200B283F7 /* der_encode_setof.c */; }; + E60817021B707B7200B283F7 /* der_encode_short_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816EB1B707B7200B283F7 /* der_encode_short_integer.c */; }; + E60817031B707B7200B283F7 /* der_encode_short_integer.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816EB1B707B7200B283F7 /* der_encode_short_integer.c */; }; + E60817041B707B7200B283F7 /* der_encode_utctime.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816EC1B707B7200B283F7 /* der_encode_utctime.c */; }; + E60817051B707B7200B283F7 /* der_encode_utctime.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816EC1B707B7200B283F7 /* der_encode_utctime.c */; }; + E60817061B707B7200B283F7 /* der_encode_utf8_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816ED1B707B7200B283F7 /* der_encode_utf8_string.c */; }; + E60817071B707B7200B283F7 /* der_encode_utf8_string.c in Sources */ = {isa = PBXBuildFile; fileRef = E60816ED1B707B7200B283F7 /* der_encode_utf8_string.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 2229F62E11D4653600118914 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 225530D31056BAC800FA646A; + remoteInfo = StormLib; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 221F6A721168529C0026C852 /* LzmaDec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LzmaDec.h; path = C/LzmaDec.h; sourceTree = ""; }; + 221F6A731168529C0026C852 /* LzmaEnc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LzmaEnc.h; path = C/LzmaEnc.h; sourceTree = ""; }; + 221F6A7A116852AA0026C852 /* LzmaEnc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = LzmaEnc.c; path = C/LzmaEnc.c; sourceTree = ""; }; + 221F6A7D116852B20026C852 /* LzmaDec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = LzmaDec.c; path = C/LzmaDec.c; sourceTree = ""; }; + 221F6AB31168545B0026C852 /* LzFind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = LzFind.c; path = C/LzFind.c; sourceTree = ""; }; + 221F6AB41168545B0026C852 /* LzFind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LzFind.h; path = C/LzFind.h; sourceTree = ""; }; + 221F6AB9116854730026C852 /* LzHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LzHash.h; path = C/LzHash.h; sourceTree = ""; }; + 221F6ABC116854870026C852 /* Types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Types.h; path = C/Types.h; sourceTree = ""; }; + 2253A19F10568A83001909F9 /* StormLib.exp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.exports; name = StormLib.exp; path = stormlib_dll/StormLib.exp; sourceTree = ""; }; + 225530D41056BAC800FA646A /* libStormLib.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libStormLib.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 225C734B1257CCC70009E8DA /* lookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lookup.h; sourceTree = ""; }; + 225C734C1257CCC70009E8DA /* lookup3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lookup3.c; sourceTree = ""; }; + 225C73531257CD0C0009E8DA /* SBaseFileTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBaseFileTable.cpp; path = src/SBaseFileTable.cpp; sourceTree = ""; }; + 225FAC940E53B7F800DA2CAE /* StormLib.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = StormLib.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 225FAC950E53B7F800DA2CAE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 226C7CA61857DE9400AB689C /* SBaseDumpData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBaseDumpData.cpp; path = src/SBaseDumpData.cpp; sourceTree = ""; }; + 226C7CA91857DEAC00AB689C /* SBaseSubTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBaseSubTypes.cpp; path = src/SBaseSubTypes.cpp; sourceTree = ""; }; + 226C7CAC1857DEEB00AB689C /* SFileGetFileInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileGetFileInfo.cpp; path = src/SFileGetFileInfo.cpp; sourceTree = ""; }; + 228B538311BF7D0D001A58DA /* FileStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FileStream.cpp; path = src/FileStream.cpp; sourceTree = ""; }; + 2295488911D45A820064B264 /* Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Test.cpp; path = test/Test.cpp; sourceTree = ""; }; + 22954ACE11D463A30064B264 /* StormLib_Test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = StormLib_Test; sourceTree = BUILT_PRODUCTS_DIR; }; + 2299D9D51167EFA8005C19BF /* adpcm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = adpcm.cpp; sourceTree = ""; }; + 2299D9D61167EFA8005C19BF /* adpcm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = adpcm.h; sourceTree = ""; }; + 2299D9DC1167EFC6005C19BF /* sparse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sparse.cpp; sourceTree = ""; }; + 2299D9DD1167EFC6005C19BF /* sparse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sparse.h; sourceTree = ""; }; + 2299DA4D1167FD16005C19BF /* SFileAddFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileAddFile.cpp; path = src/SFileAddFile.cpp; sourceTree = ""; }; + 22AEA121123125D800359B16 /* SFilePatchArchives.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFilePatchArchives.cpp; path = src/SFilePatchArchives.cpp; sourceTree = ""; }; + 22C9182B11933FCF0083AC69 /* hash_memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hash_memory.c; sourceTree = ""; }; + 22C9182C11933FCF0083AC69 /* md5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = md5.c; sourceTree = ""; }; + 22C9182D11933FCF0083AC69 /* sha1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sha1.c; sourceTree = ""; }; + 22C9182F11933FCF0083AC69 /* tomcrypt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt.h; sourceTree = ""; }; + 22C9183011933FCF0083AC69 /* tomcrypt_argchk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_argchk.h; sourceTree = ""; }; + 22C9183111933FCF0083AC69 /* tomcrypt_cfg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_cfg.h; sourceTree = ""; }; + 22C9183211933FCF0083AC69 /* tomcrypt_cipher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_cipher.h; sourceTree = ""; }; + 22C9183311933FCF0083AC69 /* tomcrypt_custom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_custom.h; sourceTree = ""; }; + 22C9183411933FCF0083AC69 /* tomcrypt_hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_hash.h; sourceTree = ""; }; + 22C9183511933FCF0083AC69 /* tomcrypt_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_mac.h; sourceTree = ""; }; + 22C9183611933FCF0083AC69 /* tomcrypt_macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_macros.h; sourceTree = ""; }; + 22C9183711933FCF0083AC69 /* tomcrypt_math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_math.h; sourceTree = ""; }; + 22C9183811933FCF0083AC69 /* tomcrypt_misc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_misc.h; sourceTree = ""; }; + 22C9183911933FCF0083AC69 /* tomcrypt_pk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_pk.h; sourceTree = ""; }; + 22C9183A11933FCF0083AC69 /* tomcrypt_pkcs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_pkcs.h; sourceTree = ""; }; + 22C9183B11933FCF0083AC69 /* tomcrypt_prng.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_prng.h; sourceTree = ""; }; + 22C9183D11933FCF0083AC69 /* ltm_desc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltm_desc.c; sourceTree = ""; }; + 22C9183E11933FCF0083AC69 /* multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = multi.c; sourceTree = ""; }; + 22C9183F11933FCF0083AC69 /* rand_prime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rand_prime.c; sourceTree = ""; }; + 22C9184111933FCF0083AC69 /* base64_decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = base64_decode.c; sourceTree = ""; }; + 22C9184211933FCF0083AC69 /* crypt_argchk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_argchk.c; sourceTree = ""; }; + 22C9184311933FCF0083AC69 /* crypt_find_hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_find_hash.c; sourceTree = ""; }; + 22C9184411933FCF0083AC69 /* crypt_find_prng.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_find_prng.c; sourceTree = ""; }; + 22C9184511933FCF0083AC69 /* crypt_hash_descriptor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_hash_descriptor.c; sourceTree = ""; }; + 22C9184611933FCF0083AC69 /* crypt_hash_is_valid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_hash_is_valid.c; sourceTree = ""; }; + 22C9184711933FCF0083AC69 /* crypt_libc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_libc.c; sourceTree = ""; }; + 22C9184811933FCF0083AC69 /* crypt_ltc_mp_descriptor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_ltc_mp_descriptor.c; sourceTree = ""; }; + 22C9184911933FCF0083AC69 /* crypt_prng_descriptor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_prng_descriptor.c; sourceTree = ""; }; + 22C9184A11933FCF0083AC69 /* crypt_prng_is_valid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_prng_is_valid.c; sourceTree = ""; }; + 22C9184B11933FCF0083AC69 /* crypt_register_hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_register_hash.c; sourceTree = ""; }; + 22C9184C11933FCF0083AC69 /* crypt_register_prng.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_register_prng.c; sourceTree = ""; }; + 22C9184D11933FCF0083AC69 /* zeromem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = zeromem.c; sourceTree = ""; }; + 22C9185011933FCF0083AC69 /* der_decode_bit_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_bit_string.c; sourceTree = ""; }; + 22C9185111933FCF0083AC69 /* der_decode_boolean.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_boolean.c; sourceTree = ""; }; + 22C9185211933FCF0083AC69 /* der_decode_choice.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_choice.c; sourceTree = ""; }; + 22C9185311933FCF0083AC69 /* der_decode_ia5_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_ia5_string.c; sourceTree = ""; }; + 22C9185411933FCF0083AC69 /* der_decode_integer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_integer.c; sourceTree = ""; }; + 22C9185511933FCF0083AC69 /* der_decode_object_identifier.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_object_identifier.c; sourceTree = ""; }; + 22C9185611933FCF0083AC69 /* der_decode_octet_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_octet_string.c; sourceTree = ""; }; + 22C9185711933FCF0083AC69 /* der_decode_printable_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_printable_string.c; sourceTree = ""; }; + 22C9185811933FCF0083AC69 /* der_decode_sequence_ex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_sequence_ex.c; sourceTree = ""; }; + 22C9185911933FCF0083AC69 /* der_decode_sequence_flexi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_sequence_flexi.c; sourceTree = ""; }; + 22C9185A11933FCF0083AC69 /* der_decode_sequence_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_sequence_multi.c; sourceTree = ""; }; + 22C9185B11933FCF0083AC69 /* der_decode_short_integer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_short_integer.c; sourceTree = ""; }; + 22C9185C11933FCF0083AC69 /* der_decode_utctime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_utctime.c; sourceTree = ""; }; + 22C9185D11933FCF0083AC69 /* der_decode_utf8_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_utf8_string.c; sourceTree = ""; }; + 22C9185E11933FCF0083AC69 /* der_length_bit_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_bit_string.c; sourceTree = ""; }; + 22C9185F11933FCF0083AC69 /* der_length_boolean.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_boolean.c; sourceTree = ""; }; + 22C9186011933FCF0083AC69 /* der_length_ia5_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_ia5_string.c; sourceTree = ""; }; + 22C9186111933FCF0083AC69 /* der_length_integer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_integer.c; sourceTree = ""; }; + 22C9186211933FCF0083AC69 /* der_length_object_identifier.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_object_identifier.c; sourceTree = ""; }; + 22C9186311933FCF0083AC69 /* der_length_octet_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_octet_string.c; sourceTree = ""; }; + 22C9186411933FCF0083AC69 /* der_length_printable_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_printable_string.c; sourceTree = ""; }; + 22C9186511933FCF0083AC69 /* der_length_sequence.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_sequence.c; sourceTree = ""; }; + 22C9186611933FCF0083AC69 /* der_length_short_integer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_short_integer.c; sourceTree = ""; }; + 22C9186711933FCF0083AC69 /* der_length_utctime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_utctime.c; sourceTree = ""; }; + 22C9186811933FCF0083AC69 /* der_length_utf8_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_utf8_string.c; sourceTree = ""; }; + 22C9186911933FCF0083AC69 /* der_sequence_free.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_sequence_free.c; sourceTree = ""; }; + 22C9186B11933FCF0083AC69 /* ltc_ecc_map.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_map.c; sourceTree = ""; }; + 22C9186C11933FCF0083AC69 /* ltc_ecc_mul2add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_mul2add.c; sourceTree = ""; }; + 22C9186D11933FCF0083AC69 /* ltc_ecc_mulmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_mulmod.c; sourceTree = ""; }; + 22C9186E11933FCF0083AC69 /* ltc_ecc_points.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_points.c; sourceTree = ""; }; + 22C9186F11933FCF0083AC69 /* ltc_ecc_projective_add_point.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_projective_add_point.c; sourceTree = ""; }; + 22C9187011933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_projective_dbl_point.c; sourceTree = ""; }; + 22C9187211933FCF0083AC69 /* pkcs_1_mgf1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs_1_mgf1.c; sourceTree = ""; }; + 22C9187311933FCF0083AC69 /* pkcs_1_oaep_decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs_1_oaep_decode.c; sourceTree = ""; }; + 22C9187411933FCF0083AC69 /* pkcs_1_pss_decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs_1_pss_decode.c; sourceTree = ""; }; + 22C9187511933FCF0083AC69 /* pkcs_1_v1_5_decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs_1_v1_5_decode.c; sourceTree = ""; }; + 22C9187711933FCF0083AC69 /* rsa_exptmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_exptmod.c; sourceTree = ""; }; + 22C9187811933FCF0083AC69 /* rsa_free.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_free.c; sourceTree = ""; }; + 22C9187911933FCF0083AC69 /* rsa_import.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_import.c; sourceTree = ""; }; + 22C9187A11933FCF0083AC69 /* rsa_make_key.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_make_key.c; sourceTree = ""; }; + 22C9187B11933FCF0083AC69 /* rsa_verify_hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_verify_hash.c; sourceTree = ""; }; + 22C9187C11933FCF0083AC69 /* rsa_verify_simple.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_verify_simple.c; sourceTree = ""; }; + 22C919111193400A0083AC69 /* bn_fast_mp_invmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_mp_invmod.c; sourceTree = ""; }; + 22C919121193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_mp_montgomery_reduce.c; sourceTree = ""; }; + 22C919131193400A0083AC69 /* bn_fast_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_mul_digs.c; sourceTree = ""; }; + 22C919141193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_mul_high_digs.c; sourceTree = ""; }; + 22C919151193400A0083AC69 /* bn_fast_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_sqr.c; sourceTree = ""; }; + 22C919161193400A0083AC69 /* bn_mp_2expt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_2expt.c; sourceTree = ""; }; + 22C919171193400A0083AC69 /* bn_mp_abs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_abs.c; sourceTree = ""; }; + 22C919181193400A0083AC69 /* bn_mp_add_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add_d.c; sourceTree = ""; }; + 22C919191193400A0083AC69 /* bn_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add.c; sourceTree = ""; }; + 22C9191A1193400A0083AC69 /* bn_mp_addmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_addmod.c; sourceTree = ""; }; + 22C9191B1193400A0083AC69 /* bn_mp_and.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_and.c; sourceTree = ""; }; + 22C9191C1193400A0083AC69 /* bn_mp_clamp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clamp.c; sourceTree = ""; }; + 22C9191D1193400A0083AC69 /* bn_mp_clear_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear_multi.c; sourceTree = ""; }; + 22C9191E1193400A0083AC69 /* bn_mp_clear.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear.c; sourceTree = ""; }; + 22C9191F1193400A0083AC69 /* bn_mp_cmp_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_d.c; sourceTree = ""; }; + 22C919201193400A0083AC69 /* bn_mp_cmp_mag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_mag.c; sourceTree = ""; }; + 22C919211193400A0083AC69 /* bn_mp_cmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp.c; sourceTree = ""; }; + 22C919221193400A0083AC69 /* bn_mp_cnt_lsb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cnt_lsb.c; sourceTree = ""; }; + 22C919231193400A0083AC69 /* bn_mp_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_copy.c; sourceTree = ""; }; + 22C919241193400A0083AC69 /* bn_mp_count_bits.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_count_bits.c; sourceTree = ""; }; + 22C919251193400A0083AC69 /* bn_mp_div_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2.c; sourceTree = ""; }; + 22C919261193400A0083AC69 /* bn_mp_div_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2d.c; sourceTree = ""; }; + 22C919271193400A0083AC69 /* bn_mp_div_3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_3.c; sourceTree = ""; }; + 22C919281193400A0083AC69 /* bn_mp_div_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_d.c; sourceTree = ""; }; + 22C919291193400A0083AC69 /* bn_mp_div.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div.c; sourceTree = ""; }; + 22C9192A1193400A0083AC69 /* bn_mp_dr_is_modulus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_dr_is_modulus.c; sourceTree = ""; }; + 22C9192B1193400A0083AC69 /* bn_mp_dr_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_dr_reduce.c; sourceTree = ""; }; + 22C9192C1193400A0083AC69 /* bn_mp_dr_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_dr_setup.c; sourceTree = ""; }; + 22C9192D1193400A0083AC69 /* bn_mp_exch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exch.c; sourceTree = ""; }; + 22C9192E1193400A0083AC69 /* bn_mp_expt_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_expt_d.c; sourceTree = ""; }; + 22C9192F1193400A0083AC69 /* bn_mp_exptmod_fast.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exptmod_fast.c; sourceTree = ""; }; + 22C919301193400A0083AC69 /* bn_mp_exptmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exptmod.c; sourceTree = ""; }; + 22C919311193400A0083AC69 /* bn_mp_exteuclid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exteuclid.c; sourceTree = ""; }; + 22C919321193400A0083AC69 /* bn_mp_fread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_fread.c; sourceTree = ""; }; + 22C919331193400A0083AC69 /* bn_mp_fwrite.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_fwrite.c; sourceTree = ""; }; + 22C919341193400A0083AC69 /* bn_mp_gcd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_gcd.c; sourceTree = ""; }; + 22C919351193400A0083AC69 /* bn_mp_get_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_get_int.c; sourceTree = ""; }; + 22C919361193400A0083AC69 /* bn_mp_grow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_grow.c; sourceTree = ""; }; + 22C919371193400A0083AC69 /* bn_mp_init_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_copy.c; sourceTree = ""; }; + 22C919381193400A0083AC69 /* bn_mp_init_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_multi.c; sourceTree = ""; }; + 22C919391193400A0083AC69 /* bn_mp_init_set_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_set_int.c; sourceTree = ""; }; + 22C9193A1193400A0083AC69 /* bn_mp_init_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_set.c; sourceTree = ""; }; + 22C9193B1193400A0083AC69 /* bn_mp_init_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_size.c; sourceTree = ""; }; + 22C9193C1193400A0083AC69 /* bn_mp_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init.c; sourceTree = ""; }; + 22C9193D1193400A0083AC69 /* bn_mp_invmod_slow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_invmod_slow.c; sourceTree = ""; }; + 22C9193E1193400A0083AC69 /* bn_mp_invmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_invmod.c; sourceTree = ""; }; + 22C9193F1193400A0083AC69 /* bn_mp_is_square.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_is_square.c; sourceTree = ""; }; + 22C919401193400A0083AC69 /* bn_mp_jacobi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_jacobi.c; sourceTree = ""; }; + 22C919411193400A0083AC69 /* bn_mp_karatsuba_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_mul.c; sourceTree = ""; }; + 22C919421193400A0083AC69 /* bn_mp_karatsuba_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_sqr.c; sourceTree = ""; }; + 22C919431193400A0083AC69 /* bn_mp_lcm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_lcm.c; sourceTree = ""; }; + 22C919441193400A0083AC69 /* bn_mp_lshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_lshd.c; sourceTree = ""; }; + 22C919451193400A0083AC69 /* bn_mp_mod_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod_2d.c; sourceTree = ""; }; + 22C919461193400A0083AC69 /* bn_mp_mod_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod_d.c; sourceTree = ""; }; + 22C919471193400A0083AC69 /* bn_mp_mod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod.c; sourceTree = ""; }; + 22C919481193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_montgomery_calc_normalization.c; sourceTree = ""; }; + 22C919491193400A0083AC69 /* bn_mp_montgomery_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_montgomery_reduce.c; sourceTree = ""; }; + 22C9194A1193400A0083AC69 /* bn_mp_montgomery_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_montgomery_setup.c; sourceTree = ""; }; + 22C9194B1193400A0083AC69 /* bn_mp_mul_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2.c; sourceTree = ""; }; + 22C9194C1193400A0083AC69 /* bn_mp_mul_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2d.c; sourceTree = ""; }; + 22C9194D1193400A0083AC69 /* bn_mp_mul_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_d.c; sourceTree = ""; }; + 22C9194E1193400A0083AC69 /* bn_mp_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul.c; sourceTree = ""; }; + 22C9194F1193400A0083AC69 /* bn_mp_mulmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mulmod.c; sourceTree = ""; }; + 22C919501193400A0083AC69 /* bn_mp_n_root.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_n_root.c; sourceTree = ""; }; + 22C919511193400A0083AC69 /* bn_mp_neg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_neg.c; sourceTree = ""; }; + 22C919521193400A0083AC69 /* bn_mp_or.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_or.c; sourceTree = ""; }; + 22C919531193400A0083AC69 /* bn_mp_prime_fermat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_fermat.c; sourceTree = ""; }; + 22C919541193400A0083AC69 /* bn_mp_prime_is_divisible.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_is_divisible.c; sourceTree = ""; }; + 22C919551193400A0083AC69 /* bn_mp_prime_is_prime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_is_prime.c; sourceTree = ""; }; + 22C919561193400A0083AC69 /* bn_mp_prime_miller_rabin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_miller_rabin.c; sourceTree = ""; }; + 22C919571193400A0083AC69 /* bn_mp_prime_next_prime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_next_prime.c; sourceTree = ""; }; + 22C919581193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_rabin_miller_trials.c; sourceTree = ""; }; + 22C919591193400A0083AC69 /* bn_mp_prime_random_ex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_random_ex.c; sourceTree = ""; }; + 22C9195A1193400A0083AC69 /* bn_mp_radix_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_size.c; sourceTree = ""; }; + 22C9195B1193400A0083AC69 /* bn_mp_radix_smap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_smap.c; sourceTree = ""; }; + 22C9195C1193400A0083AC69 /* bn_mp_rand.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_rand.c; sourceTree = ""; }; + 22C9195D1193400A0083AC69 /* bn_mp_read_radix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_radix.c; sourceTree = ""; }; + 22C9195E1193400A0083AC69 /* bn_mp_read_signed_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_signed_bin.c; sourceTree = ""; }; + 22C9195F1193400A0083AC69 /* bn_mp_read_unsigned_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_unsigned_bin.c; sourceTree = ""; }; + 22C919601193400A0083AC69 /* bn_mp_reduce_2k_l.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k_l.c; sourceTree = ""; }; + 22C919611193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k_setup_l.c; sourceTree = ""; }; + 22C919621193400A0083AC69 /* bn_mp_reduce_2k_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k_setup.c; sourceTree = ""; }; + 22C919631193400A0083AC69 /* bn_mp_reduce_2k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k.c; sourceTree = ""; }; + 22C919641193400A0083AC69 /* bn_mp_reduce_is_2k_l.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_is_2k_l.c; sourceTree = ""; }; + 22C919651193400A0083AC69 /* bn_mp_reduce_is_2k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_is_2k.c; sourceTree = ""; }; + 22C919661193400A0083AC69 /* bn_mp_reduce_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_setup.c; sourceTree = ""; }; + 22C919671193400A0083AC69 /* bn_mp_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce.c; sourceTree = ""; }; + 22C919681193400A0083AC69 /* bn_mp_rshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_rshd.c; sourceTree = ""; }; + 22C919691193400A0083AC69 /* bn_mp_set_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_set_int.c; sourceTree = ""; }; + 22C9196A1193400A0083AC69 /* bn_mp_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_set.c; sourceTree = ""; }; + 22C9196B1193400A0083AC69 /* bn_mp_shrink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_shrink.c; sourceTree = ""; }; + 22C9196C1193400A0083AC69 /* bn_mp_signed_bin_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_signed_bin_size.c; sourceTree = ""; }; + 22C9196D1193400A0083AC69 /* bn_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqr.c; sourceTree = ""; }; + 22C9196E1193400A0083AC69 /* bn_mp_sqrmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqrmod.c; sourceTree = ""; }; + 22C9196F1193400A0083AC69 /* bn_mp_sqrt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqrt.c; sourceTree = ""; }; + 22C919701193400A0083AC69 /* bn_mp_sub_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub_d.c; sourceTree = ""; }; + 22C919711193400A0083AC69 /* bn_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub.c; sourceTree = ""; }; + 22C919721193400A0083AC69 /* bn_mp_submod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_submod.c; sourceTree = ""; }; + 22C919731193400A0083AC69 /* bn_mp_to_signed_bin_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_signed_bin_n.c; sourceTree = ""; }; + 22C919741193400A0083AC69 /* bn_mp_to_signed_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_signed_bin.c; sourceTree = ""; }; + 22C919751193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin_n.c; sourceTree = ""; }; + 22C919761193400A0083AC69 /* bn_mp_to_unsigned_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin.c; sourceTree = ""; }; + 22C919771193400A0083AC69 /* bn_mp_toom_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_mul.c; sourceTree = ""; }; + 22C919781193400A0083AC69 /* bn_mp_toom_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_sqr.c; sourceTree = ""; }; + 22C919791193400A0083AC69 /* bn_mp_toradix_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toradix_n.c; sourceTree = ""; }; + 22C9197A1193400A0083AC69 /* bn_mp_toradix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toradix.c; sourceTree = ""; }; + 22C9197B1193400A0083AC69 /* bn_mp_unsigned_bin_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_unsigned_bin_size.c; sourceTree = ""; }; + 22C9197C1193400A0083AC69 /* bn_mp_xor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_xor.c; sourceTree = ""; }; + 22C9197D1193400A0083AC69 /* bn_mp_zero.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_zero.c; sourceTree = ""; }; + 22C9197E1193400A0083AC69 /* bn_prime_tab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_prime_tab.c; sourceTree = ""; }; + 22C9197F1193400A0083AC69 /* bn_reverse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_reverse.c; sourceTree = ""; }; + 22C919801193400A0083AC69 /* bn_s_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_add.c; sourceTree = ""; }; + 22C919811193400A0083AC69 /* bn_s_mp_exptmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_exptmod.c; sourceTree = ""; }; + 22C919821193400A0083AC69 /* bn_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_mul_digs.c; sourceTree = ""; }; + 22C919831193400A0083AC69 /* bn_s_mp_mul_high_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_mul_high_digs.c; sourceTree = ""; }; + 22C919841193400A0083AC69 /* bn_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sqr.c; sourceTree = ""; }; + 22C919851193400A0083AC69 /* bn_s_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sub.c; sourceTree = ""; }; + 22C919861193400A0083AC69 /* bncore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bncore.c; sourceTree = ""; }; + 22C919871193400A0083AC69 /* tommath_class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_class.h; sourceTree = ""; }; + 22C919881193400A0083AC69 /* tommath_superclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_superclass.h; sourceTree = ""; }; + 22C919891193400A0083AC69 /* tommath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath.h; sourceTree = ""; }; + 22EC6043154B28A000679228 /* FileStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FileStream.h; path = src/FileStream.h; sourceTree = ""; }; + 22F5A9C41193DFBA00F8B121 /* SFileVerify.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileVerify.cpp; path = src/SFileVerify.cpp; sourceTree = ""; }; + 32D20A8A0CF3902D00230E7A /* libbz2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbz2.dylib; path = /usr/lib/libbz2.dylib; sourceTree = ""; }; + 32D20A8B0CF3902D00230E7A /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = ""; }; + 32ED009C0D03542A00AB0B4E /* huff.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = huff.cpp; sourceTree = ""; }; + 32ED009D0D03542A00AB0B4E /* huff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = huff.h; sourceTree = ""; }; + 32ED00A60D03542A00AB0B4E /* explode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = explode.c; sourceTree = ""; }; + 32ED00A70D03542A00AB0B4E /* implode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = implode.c; sourceTree = ""; }; + 32ED00A80D03542A00AB0B4E /* pklib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pklib.h; sourceTree = ""; }; + 32ED00A90D03542A00AB0B4E /* SFileAttributes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileAttributes.cpp; path = src/SFileAttributes.cpp; sourceTree = ""; }; + 32ED00AA0D03542A00AB0B4E /* SBaseCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBaseCommon.cpp; path = src/SBaseCommon.cpp; sourceTree = ""; }; + 32ED00AB0D03542A00AB0B4E /* StormCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StormCommon.h; path = src/StormCommon.h; sourceTree = ""; }; + 32ED00AC0D03542A00AB0B4E /* SCompression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SCompression.cpp; path = src/SCompression.cpp; sourceTree = ""; }; + 32ED00AD0D03542A00AB0B4E /* SFileCompactArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileCompactArchive.cpp; path = src/SFileCompactArchive.cpp; sourceTree = ""; }; + 32ED00AE0D03542A00AB0B4E /* SFileCreateArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileCreateArchive.cpp; path = src/SFileCreateArchive.cpp; sourceTree = ""; }; + 32ED00AF0D03542A00AB0B4E /* SFileExtractFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileExtractFile.cpp; path = src/SFileExtractFile.cpp; sourceTree = ""; }; + 32ED00B00D03542A00AB0B4E /* SFileFindFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileFindFile.cpp; path = src/SFileFindFile.cpp; sourceTree = ""; }; + 32ED00B10D03542A00AB0B4E /* SFileOpenArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileOpenArchive.cpp; path = src/SFileOpenArchive.cpp; sourceTree = ""; }; + 32ED00B20D03542A00AB0B4E /* SFileOpenFileEx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileOpenFileEx.cpp; path = src/SFileOpenFileEx.cpp; sourceTree = ""; }; + 32ED00B30D03542A00AB0B4E /* SFileReadFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileReadFile.cpp; path = src/SFileReadFile.cpp; sourceTree = ""; }; + 32ED00B40D03542A00AB0B4E /* SFileListFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileListFile.cpp; path = src/SFileListFile.cpp; sourceTree = ""; }; + 32ED00B60D03542A00AB0B4E /* StormLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StormLib.h; path = src/StormLib.h; sourceTree = ""; }; + 32ED00B70D03542A00AB0B4E /* StormPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StormPort.h; path = src/StormPort.h; sourceTree = ""; }; + E60816D51B707A9000B283F7 /* rsa_sign_hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_sign_hash.c; sourceTree = ""; }; + E60816D81B707B1800B283F7 /* pkcs_1_pss_encode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs_1_pss_encode.c; sourceTree = ""; }; + E60816DB1B707B2700B283F7 /* pkcs_1_v1_5_encode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs_1_v1_5_encode.c; sourceTree = ""; }; + E60816DE1B707B5700B283F7 /* der_encode_sequence_ex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_sequence_ex.c; sourceTree = ""; }; + E60816E11B707B7200B283F7 /* der_encode_bit_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_bit_string.c; sourceTree = ""; }; + E60816E21B707B7200B283F7 /* der_encode_boolean.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_boolean.c; sourceTree = ""; }; + E60816E31B707B7200B283F7 /* der_encode_ia5_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_ia5_string.c; sourceTree = ""; }; + E60816E41B707B7200B283F7 /* der_encode_integer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_integer.c; sourceTree = ""; }; + E60816E51B707B7200B283F7 /* der_encode_object_identifier.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_object_identifier.c; sourceTree = ""; }; + E60816E61B707B7200B283F7 /* der_encode_octet_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_octet_string.c; sourceTree = ""; }; + E60816E71B707B7200B283F7 /* der_encode_printable_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_printable_string.c; sourceTree = ""; }; + E60816E81B707B7200B283F7 /* der_encode_sequence_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_sequence_multi.c; sourceTree = ""; }; + E60816E91B707B7200B283F7 /* der_encode_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_set.c; sourceTree = ""; }; + E60816EA1B707B7200B283F7 /* der_encode_setof.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_setof.c; sourceTree = ""; }; + E60816EB1B707B7200B283F7 /* der_encode_short_integer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_short_integer.c; sourceTree = ""; }; + E60816EC1B707B7200B283F7 /* der_encode_utctime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_utctime.c; sourceTree = ""; }; + E60816ED1B707B7200B283F7 /* der_encode_utf8_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_encode_utf8_string.c; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 225530D21056BAC800FA646A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 225FAC920E53B7F800DA2CAE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 225FADD40E53C06600DA2CAE /* libbz2.dylib in Frameworks */, + 225FADD50E53C06600DA2CAE /* libz.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 22954ACC11D463A30064B264 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 22954AD611D463BE0064B264 /* libbz2.dylib in Frameworks */, + 22954AD711D463BE0064B264 /* libz.dylib in Frameworks */, + 22954AD311D463B50064B264 /* libStormLib.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 034768DDFF38A45A11DB9C8B /* Products */ = { + isa = PBXGroup; + children = ( + 225FAC940E53B7F800DA2CAE /* StormLib.framework */, + 225530D41056BAC800FA646A /* libStormLib.a */, + 22954ACE11D463A30064B264 /* StormLib_Test */, + ); + name = Products; + sourceTree = ""; + }; + 0867D691FE84028FC02AAC07 /* stormlib */ = { + isa = PBXGroup; + children = ( + 32DBEE830D00E58F00DB1E81 /* Source */, + 2295488711D45A520064B264 /* Test */, + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, + 22B54B321054B287001D6436 /* Resources */, + 034768DDFF38A45A11DB9C8B /* Products */, + 2253A19F10568A83001909F9 /* StormLib.exp */, + ); + name = stormlib; + sourceTree = ""; + }; + 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 32D20A8A0CF3902D00230E7A /* libbz2.dylib */, + 32D20A8B0CF3902D00230E7A /* libz.dylib */, + ); + name = "External Frameworks and Libraries"; + sourceTree = ""; + }; + 221F652D116851D70026C852 /* lzma */ = { + isa = PBXGroup; + children = ( + 221F6AB31168545B0026C852 /* LzFind.c */, + 221F6AB41168545B0026C852 /* LzFind.h */, + 221F6AB9116854730026C852 /* LzHash.h */, + 221F6A7D116852B20026C852 /* LzmaDec.c */, + 221F6A721168529C0026C852 /* LzmaDec.h */, + 221F6A7A116852AA0026C852 /* LzmaEnc.c */, + 221F6A731168529C0026C852 /* LzmaEnc.h */, + 221F6ABC116854870026C852 /* Types.h */, + ); + name = lzma; + path = src/lzma; + sourceTree = ""; + }; + 225C734A1257CCC70009E8DA /* jenkins */ = { + isa = PBXGroup; + children = ( + 225C734B1257CCC70009E8DA /* lookup.h */, + 225C734C1257CCC70009E8DA /* lookup3.c */, + ); + name = jenkins; + path = src/jenkins; + sourceTree = ""; + }; + 2295488711D45A520064B264 /* Test */ = { + isa = PBXGroup; + children = ( + 2295488911D45A820064B264 /* Test.cpp */, + ); + name = Test; + sourceTree = ""; + }; + 2299D9D41167EFA8005C19BF /* adpcm */ = { + isa = PBXGroup; + children = ( + 2299D9D51167EFA8005C19BF /* adpcm.cpp */, + 2299D9D61167EFA8005C19BF /* adpcm.h */, + ); + name = adpcm; + path = src/adpcm; + sourceTree = ""; + }; + 2299D9DB1167EFC6005C19BF /* sparse */ = { + isa = PBXGroup; + children = ( + 2299D9DC1167EFC6005C19BF /* sparse.cpp */, + 2299D9DD1167EFC6005C19BF /* sparse.h */, + ); + name = sparse; + path = src/sparse; + sourceTree = ""; + }; + 22B54B321054B287001D6436 /* Resources */ = { + isa = PBXGroup; + children = ( + 225FAC950E53B7F800DA2CAE /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 22C9181D11933E3A0083AC69 /* libtomcrypt */ = { + isa = PBXGroup; + children = ( + 22C9182A11933FCF0083AC69 /* hashes */, + 22C9182E11933FCF0083AC69 /* headers */, + 22C9183C11933FCF0083AC69 /* math */, + 22C9184011933FCF0083AC69 /* misc */, + 22C9184E11933FCF0083AC69 /* pk */, + ); + name = libtomcrypt; + path = src/libtomcrypt; + sourceTree = ""; + }; + 22C9181E11933E470083AC69 /* libtommath */ = { + isa = PBXGroup; + children = ( + 22C919111193400A0083AC69 /* bn_fast_mp_invmod.c */, + 22C919121193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c */, + 22C919131193400A0083AC69 /* bn_fast_s_mp_mul_digs.c */, + 22C919141193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c */, + 22C919151193400A0083AC69 /* bn_fast_s_mp_sqr.c */, + 22C919161193400A0083AC69 /* bn_mp_2expt.c */, + 22C919171193400A0083AC69 /* bn_mp_abs.c */, + 22C919181193400A0083AC69 /* bn_mp_add_d.c */, + 22C919191193400A0083AC69 /* bn_mp_add.c */, + 22C9191A1193400A0083AC69 /* bn_mp_addmod.c */, + 22C9191B1193400A0083AC69 /* bn_mp_and.c */, + 22C9191C1193400A0083AC69 /* bn_mp_clamp.c */, + 22C9191D1193400A0083AC69 /* bn_mp_clear_multi.c */, + 22C9191E1193400A0083AC69 /* bn_mp_clear.c */, + 22C9191F1193400A0083AC69 /* bn_mp_cmp_d.c */, + 22C919201193400A0083AC69 /* bn_mp_cmp_mag.c */, + 22C919211193400A0083AC69 /* bn_mp_cmp.c */, + 22C919221193400A0083AC69 /* bn_mp_cnt_lsb.c */, + 22C919231193400A0083AC69 /* bn_mp_copy.c */, + 22C919241193400A0083AC69 /* bn_mp_count_bits.c */, + 22C919251193400A0083AC69 /* bn_mp_div_2.c */, + 22C919261193400A0083AC69 /* bn_mp_div_2d.c */, + 22C919271193400A0083AC69 /* bn_mp_div_3.c */, + 22C919281193400A0083AC69 /* bn_mp_div_d.c */, + 22C919291193400A0083AC69 /* bn_mp_div.c */, + 22C9192A1193400A0083AC69 /* bn_mp_dr_is_modulus.c */, + 22C9192B1193400A0083AC69 /* bn_mp_dr_reduce.c */, + 22C9192C1193400A0083AC69 /* bn_mp_dr_setup.c */, + 22C9192D1193400A0083AC69 /* bn_mp_exch.c */, + 22C9192E1193400A0083AC69 /* bn_mp_expt_d.c */, + 22C9192F1193400A0083AC69 /* bn_mp_exptmod_fast.c */, + 22C919301193400A0083AC69 /* bn_mp_exptmod.c */, + 22C919311193400A0083AC69 /* bn_mp_exteuclid.c */, + 22C919321193400A0083AC69 /* bn_mp_fread.c */, + 22C919331193400A0083AC69 /* bn_mp_fwrite.c */, + 22C919341193400A0083AC69 /* bn_mp_gcd.c */, + 22C919351193400A0083AC69 /* bn_mp_get_int.c */, + 22C919361193400A0083AC69 /* bn_mp_grow.c */, + 22C919371193400A0083AC69 /* bn_mp_init_copy.c */, + 22C919381193400A0083AC69 /* bn_mp_init_multi.c */, + 22C919391193400A0083AC69 /* bn_mp_init_set_int.c */, + 22C9193A1193400A0083AC69 /* bn_mp_init_set.c */, + 22C9193B1193400A0083AC69 /* bn_mp_init_size.c */, + 22C9193C1193400A0083AC69 /* bn_mp_init.c */, + 22C9193D1193400A0083AC69 /* bn_mp_invmod_slow.c */, + 22C9193E1193400A0083AC69 /* bn_mp_invmod.c */, + 22C9193F1193400A0083AC69 /* bn_mp_is_square.c */, + 22C919401193400A0083AC69 /* bn_mp_jacobi.c */, + 22C919411193400A0083AC69 /* bn_mp_karatsuba_mul.c */, + 22C919421193400A0083AC69 /* bn_mp_karatsuba_sqr.c */, + 22C919431193400A0083AC69 /* bn_mp_lcm.c */, + 22C919441193400A0083AC69 /* bn_mp_lshd.c */, + 22C919451193400A0083AC69 /* bn_mp_mod_2d.c */, + 22C919461193400A0083AC69 /* bn_mp_mod_d.c */, + 22C919471193400A0083AC69 /* bn_mp_mod.c */, + 22C919481193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c */, + 22C919491193400A0083AC69 /* bn_mp_montgomery_reduce.c */, + 22C9194A1193400A0083AC69 /* bn_mp_montgomery_setup.c */, + 22C9194B1193400A0083AC69 /* bn_mp_mul_2.c */, + 22C9194C1193400A0083AC69 /* bn_mp_mul_2d.c */, + 22C9194D1193400A0083AC69 /* bn_mp_mul_d.c */, + 22C9194E1193400A0083AC69 /* bn_mp_mul.c */, + 22C9194F1193400A0083AC69 /* bn_mp_mulmod.c */, + 22C919501193400A0083AC69 /* bn_mp_n_root.c */, + 22C919511193400A0083AC69 /* bn_mp_neg.c */, + 22C919521193400A0083AC69 /* bn_mp_or.c */, + 22C919531193400A0083AC69 /* bn_mp_prime_fermat.c */, + 22C919541193400A0083AC69 /* bn_mp_prime_is_divisible.c */, + 22C919551193400A0083AC69 /* bn_mp_prime_is_prime.c */, + 22C919561193400A0083AC69 /* bn_mp_prime_miller_rabin.c */, + 22C919571193400A0083AC69 /* bn_mp_prime_next_prime.c */, + 22C919581193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c */, + 22C919591193400A0083AC69 /* bn_mp_prime_random_ex.c */, + 22C9195A1193400A0083AC69 /* bn_mp_radix_size.c */, + 22C9195B1193400A0083AC69 /* bn_mp_radix_smap.c */, + 22C9195C1193400A0083AC69 /* bn_mp_rand.c */, + 22C9195D1193400A0083AC69 /* bn_mp_read_radix.c */, + 22C9195E1193400A0083AC69 /* bn_mp_read_signed_bin.c */, + 22C9195F1193400A0083AC69 /* bn_mp_read_unsigned_bin.c */, + 22C919601193400A0083AC69 /* bn_mp_reduce_2k_l.c */, + 22C919611193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c */, + 22C919621193400A0083AC69 /* bn_mp_reduce_2k_setup.c */, + 22C919631193400A0083AC69 /* bn_mp_reduce_2k.c */, + 22C919641193400A0083AC69 /* bn_mp_reduce_is_2k_l.c */, + 22C919651193400A0083AC69 /* bn_mp_reduce_is_2k.c */, + 22C919661193400A0083AC69 /* bn_mp_reduce_setup.c */, + 22C919671193400A0083AC69 /* bn_mp_reduce.c */, + 22C919681193400A0083AC69 /* bn_mp_rshd.c */, + 22C919691193400A0083AC69 /* bn_mp_set_int.c */, + 22C9196A1193400A0083AC69 /* bn_mp_set.c */, + 22C9196B1193400A0083AC69 /* bn_mp_shrink.c */, + 22C9196C1193400A0083AC69 /* bn_mp_signed_bin_size.c */, + 22C9196D1193400A0083AC69 /* bn_mp_sqr.c */, + 22C9196E1193400A0083AC69 /* bn_mp_sqrmod.c */, + 22C9196F1193400A0083AC69 /* bn_mp_sqrt.c */, + 22C919701193400A0083AC69 /* bn_mp_sub_d.c */, + 22C919711193400A0083AC69 /* bn_mp_sub.c */, + 22C919721193400A0083AC69 /* bn_mp_submod.c */, + 22C919731193400A0083AC69 /* bn_mp_to_signed_bin_n.c */, + 22C919741193400A0083AC69 /* bn_mp_to_signed_bin.c */, + 22C919751193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c */, + 22C919761193400A0083AC69 /* bn_mp_to_unsigned_bin.c */, + 22C919771193400A0083AC69 /* bn_mp_toom_mul.c */, + 22C919781193400A0083AC69 /* bn_mp_toom_sqr.c */, + 22C919791193400A0083AC69 /* bn_mp_toradix_n.c */, + 22C9197A1193400A0083AC69 /* bn_mp_toradix.c */, + 22C9197B1193400A0083AC69 /* bn_mp_unsigned_bin_size.c */, + 22C9197C1193400A0083AC69 /* bn_mp_xor.c */, + 22C9197D1193400A0083AC69 /* bn_mp_zero.c */, + 22C9197E1193400A0083AC69 /* bn_prime_tab.c */, + 22C9197F1193400A0083AC69 /* bn_reverse.c */, + 22C919801193400A0083AC69 /* bn_s_mp_add.c */, + 22C919811193400A0083AC69 /* bn_s_mp_exptmod.c */, + 22C919821193400A0083AC69 /* bn_s_mp_mul_digs.c */, + 22C919831193400A0083AC69 /* bn_s_mp_mul_high_digs.c */, + 22C919841193400A0083AC69 /* bn_s_mp_sqr.c */, + 22C919851193400A0083AC69 /* bn_s_mp_sub.c */, + 22C919861193400A0083AC69 /* bncore.c */, + 22C919871193400A0083AC69 /* tommath_class.h */, + 22C919881193400A0083AC69 /* tommath_superclass.h */, + 22C919891193400A0083AC69 /* tommath.h */, + ); + name = libtommath; + path = src/libtommath; + sourceTree = ""; + }; + 22C9182A11933FCF0083AC69 /* hashes */ = { + isa = PBXGroup; + children = ( + 22C9182B11933FCF0083AC69 /* hash_memory.c */, + 22C9182C11933FCF0083AC69 /* md5.c */, + 22C9182D11933FCF0083AC69 /* sha1.c */, + ); + name = hashes; + path = src/hashes; + sourceTree = ""; + }; + 22C9182E11933FCF0083AC69 /* headers */ = { + isa = PBXGroup; + children = ( + 22C9182F11933FCF0083AC69 /* tomcrypt.h */, + 22C9183011933FCF0083AC69 /* tomcrypt_argchk.h */, + 22C9183111933FCF0083AC69 /* tomcrypt_cfg.h */, + 22C9183211933FCF0083AC69 /* tomcrypt_cipher.h */, + 22C9183311933FCF0083AC69 /* tomcrypt_custom.h */, + 22C9183411933FCF0083AC69 /* tomcrypt_hash.h */, + 22C9183511933FCF0083AC69 /* tomcrypt_mac.h */, + 22C9183611933FCF0083AC69 /* tomcrypt_macros.h */, + 22C9183711933FCF0083AC69 /* tomcrypt_math.h */, + 22C9183811933FCF0083AC69 /* tomcrypt_misc.h */, + 22C9183911933FCF0083AC69 /* tomcrypt_pk.h */, + 22C9183A11933FCF0083AC69 /* tomcrypt_pkcs.h */, + 22C9183B11933FCF0083AC69 /* tomcrypt_prng.h */, + ); + name = headers; + path = src/headers; + sourceTree = ""; + }; + 22C9183C11933FCF0083AC69 /* math */ = { + isa = PBXGroup; + children = ( + 22C9183D11933FCF0083AC69 /* ltm_desc.c */, + 22C9183E11933FCF0083AC69 /* multi.c */, + 22C9183F11933FCF0083AC69 /* rand_prime.c */, + ); + name = math; + path = src/math; + sourceTree = ""; + }; + 22C9184011933FCF0083AC69 /* misc */ = { + isa = PBXGroup; + children = ( + 22C9184111933FCF0083AC69 /* base64_decode.c */, + 22C9184211933FCF0083AC69 /* crypt_argchk.c */, + 22C9184311933FCF0083AC69 /* crypt_find_hash.c */, + 22C9184411933FCF0083AC69 /* crypt_find_prng.c */, + 22C9184511933FCF0083AC69 /* crypt_hash_descriptor.c */, + 22C9184611933FCF0083AC69 /* crypt_hash_is_valid.c */, + 22C9184711933FCF0083AC69 /* crypt_libc.c */, + 22C9184811933FCF0083AC69 /* crypt_ltc_mp_descriptor.c */, + 22C9184911933FCF0083AC69 /* crypt_prng_descriptor.c */, + 22C9184A11933FCF0083AC69 /* crypt_prng_is_valid.c */, + 22C9184B11933FCF0083AC69 /* crypt_register_hash.c */, + 22C9184C11933FCF0083AC69 /* crypt_register_prng.c */, + 22C9184D11933FCF0083AC69 /* zeromem.c */, + ); + name = misc; + path = src/misc; + sourceTree = ""; + }; + 22C9184E11933FCF0083AC69 /* pk */ = { + isa = PBXGroup; + children = ( + 22C9184F11933FCF0083AC69 /* asn1 */, + 22C9186A11933FCF0083AC69 /* ecc */, + 22C9187111933FCF0083AC69 /* pkcs1 */, + 22C9187611933FCF0083AC69 /* rsa */, + ); + name = pk; + path = src/pk; + sourceTree = ""; + }; + 22C9184F11933FCF0083AC69 /* asn1 */ = { + isa = PBXGroup; + children = ( + E60816E11B707B7200B283F7 /* der_encode_bit_string.c */, + E60816E21B707B7200B283F7 /* der_encode_boolean.c */, + E60816E31B707B7200B283F7 /* der_encode_ia5_string.c */, + E60816E41B707B7200B283F7 /* der_encode_integer.c */, + E60816E51B707B7200B283F7 /* der_encode_object_identifier.c */, + E60816E61B707B7200B283F7 /* der_encode_octet_string.c */, + E60816E71B707B7200B283F7 /* der_encode_printable_string.c */, + E60816E81B707B7200B283F7 /* der_encode_sequence_multi.c */, + E60816E91B707B7200B283F7 /* der_encode_set.c */, + E60816EA1B707B7200B283F7 /* der_encode_setof.c */, + E60816EB1B707B7200B283F7 /* der_encode_short_integer.c */, + E60816EC1B707B7200B283F7 /* der_encode_utctime.c */, + E60816ED1B707B7200B283F7 /* der_encode_utf8_string.c */, + E60816DE1B707B5700B283F7 /* der_encode_sequence_ex.c */, + 22C9185011933FCF0083AC69 /* der_decode_bit_string.c */, + 22C9185111933FCF0083AC69 /* der_decode_boolean.c */, + 22C9185211933FCF0083AC69 /* der_decode_choice.c */, + 22C9185311933FCF0083AC69 /* der_decode_ia5_string.c */, + 22C9185411933FCF0083AC69 /* der_decode_integer.c */, + 22C9185511933FCF0083AC69 /* der_decode_object_identifier.c */, + 22C9185611933FCF0083AC69 /* der_decode_octet_string.c */, + 22C9185711933FCF0083AC69 /* der_decode_printable_string.c */, + 22C9185811933FCF0083AC69 /* der_decode_sequence_ex.c */, + 22C9185911933FCF0083AC69 /* der_decode_sequence_flexi.c */, + 22C9185A11933FCF0083AC69 /* der_decode_sequence_multi.c */, + 22C9185B11933FCF0083AC69 /* der_decode_short_integer.c */, + 22C9185C11933FCF0083AC69 /* der_decode_utctime.c */, + 22C9185D11933FCF0083AC69 /* der_decode_utf8_string.c */, + 22C9185E11933FCF0083AC69 /* der_length_bit_string.c */, + 22C9185F11933FCF0083AC69 /* der_length_boolean.c */, + 22C9186011933FCF0083AC69 /* der_length_ia5_string.c */, + 22C9186111933FCF0083AC69 /* der_length_integer.c */, + 22C9186211933FCF0083AC69 /* der_length_object_identifier.c */, + 22C9186311933FCF0083AC69 /* der_length_octet_string.c */, + 22C9186411933FCF0083AC69 /* der_length_printable_string.c */, + 22C9186511933FCF0083AC69 /* der_length_sequence.c */, + 22C9186611933FCF0083AC69 /* der_length_short_integer.c */, + 22C9186711933FCF0083AC69 /* der_length_utctime.c */, + 22C9186811933FCF0083AC69 /* der_length_utf8_string.c */, + 22C9186911933FCF0083AC69 /* der_sequence_free.c */, + ); + path = asn1; + sourceTree = ""; + }; + 22C9186A11933FCF0083AC69 /* ecc */ = { + isa = PBXGroup; + children = ( + 22C9186B11933FCF0083AC69 /* ltc_ecc_map.c */, + 22C9186C11933FCF0083AC69 /* ltc_ecc_mul2add.c */, + 22C9186D11933FCF0083AC69 /* ltc_ecc_mulmod.c */, + 22C9186E11933FCF0083AC69 /* ltc_ecc_points.c */, + 22C9186F11933FCF0083AC69 /* ltc_ecc_projective_add_point.c */, + 22C9187011933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c */, + ); + path = ecc; + sourceTree = ""; + }; + 22C9187111933FCF0083AC69 /* pkcs1 */ = { + isa = PBXGroup; + children = ( + E60816DB1B707B2700B283F7 /* pkcs_1_v1_5_encode.c */, + E60816D81B707B1800B283F7 /* pkcs_1_pss_encode.c */, + 22C9187211933FCF0083AC69 /* pkcs_1_mgf1.c */, + 22C9187311933FCF0083AC69 /* pkcs_1_oaep_decode.c */, + 22C9187411933FCF0083AC69 /* pkcs_1_pss_decode.c */, + 22C9187511933FCF0083AC69 /* pkcs_1_v1_5_decode.c */, + ); + path = pkcs1; + sourceTree = ""; + }; + 22C9187611933FCF0083AC69 /* rsa */ = { + isa = PBXGroup; + children = ( + E60816D51B707A9000B283F7 /* rsa_sign_hash.c */, + 22C9187711933FCF0083AC69 /* rsa_exptmod.c */, + 22C9187811933FCF0083AC69 /* rsa_free.c */, + 22C9187911933FCF0083AC69 /* rsa_import.c */, + 22C9187A11933FCF0083AC69 /* rsa_make_key.c */, + 22C9187B11933FCF0083AC69 /* rsa_verify_hash.c */, + 22C9187C11933FCF0083AC69 /* rsa_verify_simple.c */, + ); + path = rsa; + sourceTree = ""; + }; + 32DBEE830D00E58F00DB1E81 /* Source */ = { + isa = PBXGroup; + children = ( + 2299D9D41167EFA8005C19BF /* adpcm */, + 32ED009B0D03542A00AB0B4E /* huffman */, + 225C734A1257CCC70009E8DA /* jenkins */, + 22C9181D11933E3A0083AC69 /* libtomcrypt */, + 22C9181E11933E470083AC69 /* libtommath */, + 221F652D116851D70026C852 /* lzma */, + 32ED00A40D03542A00AB0B4E /* pklib */, + 2299D9DB1167EFC6005C19BF /* sparse */, + 228B538311BF7D0D001A58DA /* FileStream.cpp */, + 22EC6043154B28A000679228 /* FileStream.h */, + 32ED00AA0D03542A00AB0B4E /* SBaseCommon.cpp */, + 226C7CA61857DE9400AB689C /* SBaseDumpData.cpp */, + 225C73531257CD0C0009E8DA /* SBaseFileTable.cpp */, + 226C7CA91857DEAC00AB689C /* SBaseSubTypes.cpp */, + 32ED00AC0D03542A00AB0B4E /* SCompression.cpp */, + 2299DA4D1167FD16005C19BF /* SFileAddFile.cpp */, + 32ED00A90D03542A00AB0B4E /* SFileAttributes.cpp */, + 32ED00AD0D03542A00AB0B4E /* SFileCompactArchive.cpp */, + 32ED00AE0D03542A00AB0B4E /* SFileCreateArchive.cpp */, + 32ED00AF0D03542A00AB0B4E /* SFileExtractFile.cpp */, + 32ED00B00D03542A00AB0B4E /* SFileFindFile.cpp */, + 226C7CAC1857DEEB00AB689C /* SFileGetFileInfo.cpp */, + 32ED00B40D03542A00AB0B4E /* SFileListFile.cpp */, + 32ED00B10D03542A00AB0B4E /* SFileOpenArchive.cpp */, + 32ED00B20D03542A00AB0B4E /* SFileOpenFileEx.cpp */, + 22AEA121123125D800359B16 /* SFilePatchArchives.cpp */, + 32ED00B30D03542A00AB0B4E /* SFileReadFile.cpp */, + 22F5A9C41193DFBA00F8B121 /* SFileVerify.cpp */, + 32ED00AB0D03542A00AB0B4E /* StormCommon.h */, + 32ED00B60D03542A00AB0B4E /* StormLib.h */, + 32ED00B70D03542A00AB0B4E /* StormPort.h */, + ); + name = Source; + sourceTree = ""; + }; + 32ED009B0D03542A00AB0B4E /* huffman */ = { + isa = PBXGroup; + children = ( + 32ED009C0D03542A00AB0B4E /* huff.cpp */, + 32ED009D0D03542A00AB0B4E /* huff.h */, + ); + name = huffman; + path = src/huffman; + sourceTree = ""; + }; + 32ED00A40D03542A00AB0B4E /* pklib */ = { + isa = PBXGroup; + children = ( + 32ED00A60D03542A00AB0B4E /* explode.c */, + 32ED00A70D03542A00AB0B4E /* implode.c */, + 32ED00A80D03542A00AB0B4E /* pklib.h */, + ); + name = pklib; + path = src/pklib; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 225530D01056BAC800FA646A /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 225530DB1056BC7900FA646A /* huff.h in Headers */, + 225530DE1056BC7900FA646A /* pklib.h in Headers */, + 225530DF1056BC7900FA646A /* StormCommon.h in Headers */, + 225530E01056BC7900FA646A /* StormLib.h in Headers */, + 225530E11056BC7900FA646A /* StormPort.h in Headers */, + 2299D9DA1167EFA8005C19BF /* adpcm.h in Headers */, + 2299D9E11167EFC6005C19BF /* sparse.h in Headers */, + 221F6A761168529C0026C852 /* LzmaDec.h in Headers */, + 221F6A771168529C0026C852 /* LzmaEnc.h in Headers */, + 221F6AB81168545B0026C852 /* LzFind.h in Headers */, + 221F6ABB116854730026C852 /* LzHash.h in Headers */, + 221F6ABE116854870026C852 /* Types.h in Headers */, + 22C9188011933FCF0083AC69 /* tomcrypt.h in Headers */, + 22C9188111933FCF0083AC69 /* tomcrypt_argchk.h in Headers */, + 22C9188211933FCF0083AC69 /* tomcrypt_cfg.h in Headers */, + 22C9188311933FCF0083AC69 /* tomcrypt_cipher.h in Headers */, + 22C9188411933FCF0083AC69 /* tomcrypt_custom.h in Headers */, + 22C9188511933FCF0083AC69 /* tomcrypt_hash.h in Headers */, + 22C9188611933FCF0083AC69 /* tomcrypt_mac.h in Headers */, + 22C9188711933FCF0083AC69 /* tomcrypt_macros.h in Headers */, + 22C9188811933FCF0083AC69 /* tomcrypt_math.h in Headers */, + 22C9188911933FCF0083AC69 /* tomcrypt_misc.h in Headers */, + 22C9188A11933FCF0083AC69 /* tomcrypt_pk.h in Headers */, + 22C9188B11933FCF0083AC69 /* tomcrypt_pkcs.h in Headers */, + 22C9188C11933FCF0083AC69 /* tomcrypt_prng.h in Headers */, + 22C91A001193400A0083AC69 /* tommath_class.h in Headers */, + 22C91A011193400A0083AC69 /* tommath_superclass.h in Headers */, + 22C91A021193400A0083AC69 /* tommath.h in Headers */, + 225C734F1257CCC70009E8DA /* lookup.h in Headers */, + 22EC6044154B28A000679228 /* FileStream.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 225FAC8F0E53B7F800DA2CAE /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 225FAC9C0E53BAA100DA2CAE /* huff.h in Headers */, + 225FAC9F0E53BAA100DA2CAE /* pklib.h in Headers */, + 225FACA00E53BAA100DA2CAE /* StormCommon.h in Headers */, + 225FACA10E53BAA100DA2CAE /* StormLib.h in Headers */, + 225FACA20E53BAA100DA2CAE /* StormPort.h in Headers */, + 2299D9D81167EFA8005C19BF /* adpcm.h in Headers */, + 2299D9DF1167EFC6005C19BF /* sparse.h in Headers */, + 221F6A741168529C0026C852 /* LzmaDec.h in Headers */, + 221F6A751168529C0026C852 /* LzmaEnc.h in Headers */, + 221F6AB61168545B0026C852 /* LzFind.h in Headers */, + 221F6ABA116854730026C852 /* LzHash.h in Headers */, + 221F6ABD116854870026C852 /* Types.h in Headers */, + 22C918CA11933FCF0083AC69 /* tomcrypt.h in Headers */, + 22C918CB11933FCF0083AC69 /* tomcrypt_argchk.h in Headers */, + 22C918CC11933FCF0083AC69 /* tomcrypt_cfg.h in Headers */, + 22C918CD11933FCF0083AC69 /* tomcrypt_cipher.h in Headers */, + 22C918CE11933FCF0083AC69 /* tomcrypt_custom.h in Headers */, + 22C918CF11933FCF0083AC69 /* tomcrypt_hash.h in Headers */, + 22C918D011933FCF0083AC69 /* tomcrypt_mac.h in Headers */, + 22C918D111933FCF0083AC69 /* tomcrypt_macros.h in Headers */, + 22C918D211933FCF0083AC69 /* tomcrypt_math.h in Headers */, + 22C918D311933FCF0083AC69 /* tomcrypt_misc.h in Headers */, + 22C918D411933FCF0083AC69 /* tomcrypt_pk.h in Headers */, + 22C918D511933FCF0083AC69 /* tomcrypt_pkcs.h in Headers */, + 22C918D611933FCF0083AC69 /* tomcrypt_prng.h in Headers */, + 22C91A791193400A0083AC69 /* tommath_class.h in Headers */, + 22C91A7A1193400A0083AC69 /* tommath_superclass.h in Headers */, + 22C91A7B1193400A0083AC69 /* tommath.h in Headers */, + 225C734D1257CCC70009E8DA /* lookup.h in Headers */, + 22EC6045154B28A000679228 /* FileStream.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 225530D31056BAC800FA646A /* StormLib */ = { + isa = PBXNativeTarget; + buildConfigurationList = 225530D71056BB1600FA646A /* Build configuration list for PBXNativeTarget "StormLib" */; + buildPhases = ( + 225530D01056BAC800FA646A /* Headers */, + 225530D11056BAC800FA646A /* Sources */, + 225530D21056BAC800FA646A /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = StormLib; + productName = StormLib; + productReference = 225530D41056BAC800FA646A /* libStormLib.a */; + productType = "com.apple.product-type.library.static"; + }; + 225FAC930E53B7F800DA2CAE /* StormLibFramework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 225FAC980E53B7F900DA2CAE /* Build configuration list for PBXNativeTarget "StormLibFramework" */; + buildPhases = ( + 225FAC8F0E53B7F800DA2CAE /* Headers */, + 225FAC900E53B7F800DA2CAE /* Resources */, + 225FAC910E53B7F800DA2CAE /* Sources */, + 225FAC920E53B7F800DA2CAE /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = StormLibFramework; + productName = StormLib; + productReference = 225FAC940E53B7F800DA2CAE /* StormLib.framework */; + productType = "com.apple.product-type.framework"; + }; + 22954ACD11D463A30064B264 /* StormLib_Test */ = { + isa = PBXNativeTarget; + buildConfigurationList = 22954AD911D463E00064B264 /* Build configuration list for PBXNativeTarget "StormLib_Test" */; + buildPhases = ( + 22954ACB11D463A30064B264 /* Sources */, + 22954ACC11D463A30064B264 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 2229F62F11D4653600118914 /* PBXTargetDependency */, + ); + name = StormLib_Test; + productName = StormLib_Test; + productReference = 22954ACE11D463A30064B264 /* StormLib_Test */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0867D690FE84028FC02AAC07 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0500; + }; + buildConfigurationList = 1DEB916408733D950010E9CD /* Build configuration list for PBXProject "StormLib" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + en, + ); + mainGroup = 0867D691FE84028FC02AAC07 /* stormlib */; + productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 225530D31056BAC800FA646A /* StormLib */, + 225FAC930E53B7F800DA2CAE /* StormLibFramework */, + 22954ACD11D463A30064B264 /* StormLib_Test */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 225FAC900E53B7F800DA2CAE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 225530D11056BAC800FA646A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 225530E31056BC8700FA646A /* huff.cpp in Sources */, + 225530E61056BC8700FA646A /* explode.c in Sources */, + 226C7CA71857DE9400AB689C /* SBaseDumpData.cpp in Sources */, + 225530E71056BC8700FA646A /* implode.c in Sources */, + 225530E81056BC8700FA646A /* SFileAttributes.cpp in Sources */, + 226C7CAA1857DEAC00AB689C /* SBaseSubTypes.cpp in Sources */, + 225530E91056BC8700FA646A /* SBaseCommon.cpp in Sources */, + 225530EA1056BC8700FA646A /* SCompression.cpp in Sources */, + 225530EB1056BC8700FA646A /* SFileCompactArchive.cpp in Sources */, + 225530EC1056BC8700FA646A /* SFileCreateArchive.cpp in Sources */, + 225530ED1056BC8700FA646A /* SFileExtractFile.cpp in Sources */, + E60816F81B707B7200B283F7 /* der_encode_octet_string.c in Sources */, + 225530EE1056BC8700FA646A /* SFileFindFile.cpp in Sources */, + 225530EF1056BC8700FA646A /* SFileOpenArchive.cpp in Sources */, + 226C7CAD1857DEEB00AB689C /* SFileGetFileInfo.cpp in Sources */, + 225530F01056BC8700FA646A /* SFileOpenFileEx.cpp in Sources */, + 225530F11056BC8700FA646A /* SFileReadFile.cpp in Sources */, + 225530F21056BC8700FA646A /* SFileListFile.cpp in Sources */, + 2299D9D91167EFA8005C19BF /* adpcm.cpp in Sources */, + 2299D9E01167EFC6005C19BF /* sparse.cpp in Sources */, + 2299DA4F1167FD16005C19BF /* SFileAddFile.cpp in Sources */, + 221F6A7C116852AA0026C852 /* LzmaEnc.c in Sources */, + 221F6A7F116852B20026C852 /* LzmaDec.c in Sources */, + 221F6AB71168545B0026C852 /* LzFind.c in Sources */, + 22C9187D11933FCF0083AC69 /* hash_memory.c in Sources */, + 22C9187E11933FCF0083AC69 /* md5.c in Sources */, + 22C9187F11933FCF0083AC69 /* sha1.c in Sources */, + 22C9188D11933FCF0083AC69 /* ltm_desc.c in Sources */, + 22C9188E11933FCF0083AC69 /* multi.c in Sources */, + 22C9188F11933FCF0083AC69 /* rand_prime.c in Sources */, + 22C9189011933FCF0083AC69 /* base64_decode.c in Sources */, + 22C9189111933FCF0083AC69 /* crypt_argchk.c in Sources */, + 22C9189211933FCF0083AC69 /* crypt_find_hash.c in Sources */, + 22C9189311933FCF0083AC69 /* crypt_find_prng.c in Sources */, + 22C9189411933FCF0083AC69 /* crypt_hash_descriptor.c in Sources */, + 22C9189511933FCF0083AC69 /* crypt_hash_is_valid.c in Sources */, + 22C9189611933FCF0083AC69 /* crypt_libc.c in Sources */, + 2254917B11948CE70044424D /* crypt_ltc_mp_descriptor.c in Sources */, + 22C9189811933FCF0083AC69 /* crypt_prng_descriptor.c in Sources */, + 22C9189911933FCF0083AC69 /* crypt_prng_is_valid.c in Sources */, + 22C9189A11933FCF0083AC69 /* crypt_register_hash.c in Sources */, + 22C9189B11933FCF0083AC69 /* crypt_register_prng.c in Sources */, + 22C9189C11933FCF0083AC69 /* zeromem.c in Sources */, + 22C9189D11933FCF0083AC69 /* der_decode_bit_string.c in Sources */, + 22C9189E11933FCF0083AC69 /* der_decode_boolean.c in Sources */, + 22C9189F11933FCF0083AC69 /* der_decode_choice.c in Sources */, + 22C918A011933FCF0083AC69 /* der_decode_ia5_string.c in Sources */, + 22C918A111933FCF0083AC69 /* der_decode_integer.c in Sources */, + 22C918A211933FCF0083AC69 /* der_decode_object_identifier.c in Sources */, + 22C918A311933FCF0083AC69 /* der_decode_octet_string.c in Sources */, + 22C918A411933FCF0083AC69 /* der_decode_printable_string.c in Sources */, + 22C918A511933FCF0083AC69 /* der_decode_sequence_ex.c in Sources */, + 22C918A611933FCF0083AC69 /* der_decode_sequence_flexi.c in Sources */, + 22C918A711933FCF0083AC69 /* der_decode_sequence_multi.c in Sources */, + 22C918A811933FCF0083AC69 /* der_decode_short_integer.c in Sources */, + 22C918A911933FCF0083AC69 /* der_decode_utctime.c in Sources */, + 22C918AA11933FCF0083AC69 /* der_decode_utf8_string.c in Sources */, + E60816F01B707B7200B283F7 /* der_encode_boolean.c in Sources */, + 22C918AB11933FCF0083AC69 /* der_length_bit_string.c in Sources */, + 22C918AC11933FCF0083AC69 /* der_length_boolean.c in Sources */, + 22C918AD11933FCF0083AC69 /* der_length_ia5_string.c in Sources */, + 22C918AE11933FCF0083AC69 /* der_length_integer.c in Sources */, + 22C918AF11933FCF0083AC69 /* der_length_object_identifier.c in Sources */, + 22C918B011933FCF0083AC69 /* der_length_octet_string.c in Sources */, + 22C918B111933FCF0083AC69 /* der_length_printable_string.c in Sources */, + 22C918B211933FCF0083AC69 /* der_length_sequence.c in Sources */, + 22C918B311933FCF0083AC69 /* der_length_short_integer.c in Sources */, + 22C918B411933FCF0083AC69 /* der_length_utctime.c in Sources */, + 22C918B511933FCF0083AC69 /* der_length_utf8_string.c in Sources */, + 22C918B611933FCF0083AC69 /* der_sequence_free.c in Sources */, + 22C918B711933FCF0083AC69 /* ltc_ecc_map.c in Sources */, + 22C918B811933FCF0083AC69 /* ltc_ecc_mul2add.c in Sources */, + 22C918B911933FCF0083AC69 /* ltc_ecc_mulmod.c in Sources */, + 22C918BA11933FCF0083AC69 /* ltc_ecc_points.c in Sources */, + 22C918BB11933FCF0083AC69 /* ltc_ecc_projective_add_point.c in Sources */, + 22C918BC11933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c in Sources */, + 22C918BD11933FCF0083AC69 /* pkcs_1_mgf1.c in Sources */, + 22C918BE11933FCF0083AC69 /* pkcs_1_oaep_decode.c in Sources */, + 22C918BF11933FCF0083AC69 /* pkcs_1_pss_decode.c in Sources */, + 22C918C011933FCF0083AC69 /* pkcs_1_v1_5_decode.c in Sources */, + 22C918C111933FCF0083AC69 /* rsa_exptmod.c in Sources */, + 22C918C211933FCF0083AC69 /* rsa_free.c in Sources */, + 22C918C311933FCF0083AC69 /* rsa_import.c in Sources */, + 22C918C411933FCF0083AC69 /* rsa_make_key.c in Sources */, + 22C918C511933FCF0083AC69 /* rsa_verify_hash.c in Sources */, + 22C918C611933FCF0083AC69 /* rsa_verify_simple.c in Sources */, + 22C9198A1193400A0083AC69 /* bn_fast_mp_invmod.c in Sources */, + 22C9198B1193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c in Sources */, + E60816F61B707B7200B283F7 /* der_encode_object_identifier.c in Sources */, + 22C9198C1193400A0083AC69 /* bn_fast_s_mp_mul_digs.c in Sources */, + E60816FA1B707B7200B283F7 /* der_encode_printable_string.c in Sources */, + 22C9198D1193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c in Sources */, + 22C9198E1193400A0083AC69 /* bn_fast_s_mp_sqr.c in Sources */, + 22C9198F1193400A0083AC69 /* bn_mp_2expt.c in Sources */, + 22C919901193400A0083AC69 /* bn_mp_abs.c in Sources */, + 22C919911193400A0083AC69 /* bn_mp_add_d.c in Sources */, + 22C919921193400A0083AC69 /* bn_mp_add.c in Sources */, + 22C919931193400A0083AC69 /* bn_mp_addmod.c in Sources */, + 22C919941193400A0083AC69 /* bn_mp_and.c in Sources */, + 22C919951193400A0083AC69 /* bn_mp_clamp.c in Sources */, + 22C919961193400A0083AC69 /* bn_mp_clear_multi.c in Sources */, + 22C919971193400A0083AC69 /* bn_mp_clear.c in Sources */, + 22C919981193400A0083AC69 /* bn_mp_cmp_d.c in Sources */, + 22C919991193400A0083AC69 /* bn_mp_cmp_mag.c in Sources */, + 22C9199A1193400A0083AC69 /* bn_mp_cmp.c in Sources */, + 22C9199B1193400A0083AC69 /* bn_mp_cnt_lsb.c in Sources */, + 22C9199C1193400A0083AC69 /* bn_mp_copy.c in Sources */, + 22C9199D1193400A0083AC69 /* bn_mp_count_bits.c in Sources */, + E60816F41B707B7200B283F7 /* der_encode_integer.c in Sources */, + E60817061B707B7200B283F7 /* der_encode_utf8_string.c in Sources */, + 22C9199E1193400A0083AC69 /* bn_mp_div_2.c in Sources */, + 22C9199F1193400A0083AC69 /* bn_mp_div_2d.c in Sources */, + 22C919A01193400A0083AC69 /* bn_mp_div_3.c in Sources */, + 22C919A11193400A0083AC69 /* bn_mp_div_d.c in Sources */, + 22C919A21193400A0083AC69 /* bn_mp_div.c in Sources */, + 22C919A31193400A0083AC69 /* bn_mp_dr_is_modulus.c in Sources */, + 22C919A41193400A0083AC69 /* bn_mp_dr_reduce.c in Sources */, + 22C919A51193400A0083AC69 /* bn_mp_dr_setup.c in Sources */, + 22C919A61193400A0083AC69 /* bn_mp_exch.c in Sources */, + 22C919A71193400A0083AC69 /* bn_mp_expt_d.c in Sources */, + 22C919A81193400A0083AC69 /* bn_mp_exptmod_fast.c in Sources */, + 22C919A91193400A0083AC69 /* bn_mp_exptmod.c in Sources */, + 22C919AA1193400A0083AC69 /* bn_mp_exteuclid.c in Sources */, + 22C919AB1193400A0083AC69 /* bn_mp_fread.c in Sources */, + 22C919AC1193400A0083AC69 /* bn_mp_fwrite.c in Sources */, + 22C919AD1193400A0083AC69 /* bn_mp_gcd.c in Sources */, + 22C919AE1193400A0083AC69 /* bn_mp_get_int.c in Sources */, + 22C919AF1193400A0083AC69 /* bn_mp_grow.c in Sources */, + 22C919B01193400A0083AC69 /* bn_mp_init_copy.c in Sources */, + 22C919B11193400A0083AC69 /* bn_mp_init_multi.c in Sources */, + 22C919B21193400A0083AC69 /* bn_mp_init_set_int.c in Sources */, + 22C919B31193400A0083AC69 /* bn_mp_init_set.c in Sources */, + 22C919B41193400A0083AC69 /* bn_mp_init_size.c in Sources */, + 22C919B51193400A0083AC69 /* bn_mp_init.c in Sources */, + E60816D91B707B1800B283F7 /* pkcs_1_pss_encode.c in Sources */, + 22C919B61193400A0083AC69 /* bn_mp_invmod_slow.c in Sources */, + 22C919B71193400A0083AC69 /* bn_mp_invmod.c in Sources */, + 22C919B81193400A0083AC69 /* bn_mp_is_square.c in Sources */, + 22C919B91193400A0083AC69 /* bn_mp_jacobi.c in Sources */, + 22C919BA1193400A0083AC69 /* bn_mp_karatsuba_mul.c in Sources */, + 22C919BB1193400A0083AC69 /* bn_mp_karatsuba_sqr.c in Sources */, + 22C919BC1193400A0083AC69 /* bn_mp_lcm.c in Sources */, + 22C919BD1193400A0083AC69 /* bn_mp_lshd.c in Sources */, + 22C919BE1193400A0083AC69 /* bn_mp_mod_2d.c in Sources */, + 22C919BF1193400A0083AC69 /* bn_mp_mod_d.c in Sources */, + 22C919C01193400A0083AC69 /* bn_mp_mod.c in Sources */, + 22C919C11193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c in Sources */, + 22C919C21193400A0083AC69 /* bn_mp_montgomery_reduce.c in Sources */, + E60817021B707B7200B283F7 /* der_encode_short_integer.c in Sources */, + 22C919C31193400A0083AC69 /* bn_mp_montgomery_setup.c in Sources */, + E60816DC1B707B2700B283F7 /* pkcs_1_v1_5_encode.c in Sources */, + 22C919C41193400A0083AC69 /* bn_mp_mul_2.c in Sources */, + E60816FC1B707B7200B283F7 /* der_encode_sequence_multi.c in Sources */, + 22C919C51193400A0083AC69 /* bn_mp_mul_2d.c in Sources */, + 22C919C61193400A0083AC69 /* bn_mp_mul_d.c in Sources */, + 22C919C71193400A0083AC69 /* bn_mp_mul.c in Sources */, + E60816EE1B707B7200B283F7 /* der_encode_bit_string.c in Sources */, + 22C919C81193400A0083AC69 /* bn_mp_mulmod.c in Sources */, + 22C919C91193400A0083AC69 /* bn_mp_n_root.c in Sources */, + 22C919CA1193400A0083AC69 /* bn_mp_neg.c in Sources */, + 22C919CB1193400A0083AC69 /* bn_mp_or.c in Sources */, + 22C919CC1193400A0083AC69 /* bn_mp_prime_fermat.c in Sources */, + 22C919CD1193400A0083AC69 /* bn_mp_prime_is_divisible.c in Sources */, + 22C919CE1193400A0083AC69 /* bn_mp_prime_is_prime.c in Sources */, + E60816D61B707A9000B283F7 /* rsa_sign_hash.c in Sources */, + 22C919CF1193400A0083AC69 /* bn_mp_prime_miller_rabin.c in Sources */, + 22C919D01193400A0083AC69 /* bn_mp_prime_next_prime.c in Sources */, + 22C919D11193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c in Sources */, + 22C919D21193400A0083AC69 /* bn_mp_prime_random_ex.c in Sources */, + 22C919D31193400A0083AC69 /* bn_mp_radix_size.c in Sources */, + 22C919D41193400A0083AC69 /* bn_mp_radix_smap.c in Sources */, + 22C919D51193400A0083AC69 /* bn_mp_rand.c in Sources */, + 22C919D61193400A0083AC69 /* bn_mp_read_radix.c in Sources */, + 22C919D71193400A0083AC69 /* bn_mp_read_signed_bin.c in Sources */, + 22C919D81193400A0083AC69 /* bn_mp_read_unsigned_bin.c in Sources */, + 22C919D91193400A0083AC69 /* bn_mp_reduce_2k_l.c in Sources */, + 22C919DA1193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c in Sources */, + 22C919DB1193400A0083AC69 /* bn_mp_reduce_2k_setup.c in Sources */, + E60816FE1B707B7200B283F7 /* der_encode_set.c in Sources */, + E60817001B707B7200B283F7 /* der_encode_setof.c in Sources */, + 22C919DC1193400A0083AC69 /* bn_mp_reduce_2k.c in Sources */, + 22C919DD1193400A0083AC69 /* bn_mp_reduce_is_2k_l.c in Sources */, + E60817041B707B7200B283F7 /* der_encode_utctime.c in Sources */, + 22C919DE1193400A0083AC69 /* bn_mp_reduce_is_2k.c in Sources */, + 22C919DF1193400A0083AC69 /* bn_mp_reduce_setup.c in Sources */, + 22C919E01193400A0083AC69 /* bn_mp_reduce.c in Sources */, + 22C919E11193400A0083AC69 /* bn_mp_rshd.c in Sources */, + 22C919E21193400A0083AC69 /* bn_mp_set_int.c in Sources */, + 22C919E31193400A0083AC69 /* bn_mp_set.c in Sources */, + 22C919E41193400A0083AC69 /* bn_mp_shrink.c in Sources */, + 22C919E51193400A0083AC69 /* bn_mp_signed_bin_size.c in Sources */, + 22C919E61193400A0083AC69 /* bn_mp_sqr.c in Sources */, + 22C919E71193400A0083AC69 /* bn_mp_sqrmod.c in Sources */, + 22C919E81193400A0083AC69 /* bn_mp_sqrt.c in Sources */, + 22C919E91193400A0083AC69 /* bn_mp_sub_d.c in Sources */, + 22C919EA1193400A0083AC69 /* bn_mp_sub.c in Sources */, + 22C919EB1193400A0083AC69 /* bn_mp_submod.c in Sources */, + 22C919EC1193400A0083AC69 /* bn_mp_to_signed_bin_n.c in Sources */, + 22C919ED1193400A0083AC69 /* bn_mp_to_signed_bin.c in Sources */, + 22C919EE1193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c in Sources */, + 22C919EF1193400A0083AC69 /* bn_mp_to_unsigned_bin.c in Sources */, + 22C919F01193400A0083AC69 /* bn_mp_toom_mul.c in Sources */, + 22C919F11193400A0083AC69 /* bn_mp_toom_sqr.c in Sources */, + 22C919F21193400A0083AC69 /* bn_mp_toradix_n.c in Sources */, + 22C919F31193400A0083AC69 /* bn_mp_toradix.c in Sources */, + 22C919F41193400A0083AC69 /* bn_mp_unsigned_bin_size.c in Sources */, + E60816F21B707B7200B283F7 /* der_encode_ia5_string.c in Sources */, + E60816DF1B707B5700B283F7 /* der_encode_sequence_ex.c in Sources */, + 22C919F51193400A0083AC69 /* bn_mp_xor.c in Sources */, + 22C919F61193400A0083AC69 /* bn_mp_zero.c in Sources */, + 22C919F71193400A0083AC69 /* bn_prime_tab.c in Sources */, + 22C919F81193400A0083AC69 /* bn_reverse.c in Sources */, + 22C919F91193400A0083AC69 /* bn_s_mp_add.c in Sources */, + 22C919FA1193400A0083AC69 /* bn_s_mp_exptmod.c in Sources */, + 22C919FB1193400A0083AC69 /* bn_s_mp_mul_digs.c in Sources */, + 22C919FC1193400A0083AC69 /* bn_s_mp_mul_high_digs.c in Sources */, + 22C919FD1193400A0083AC69 /* bn_s_mp_sqr.c in Sources */, + 22C919FE1193400A0083AC69 /* bn_s_mp_sub.c in Sources */, + 22C919FF1193400A0083AC69 /* bncore.c in Sources */, + 22F5A9C51193DFBA00F8B121 /* SFileVerify.cpp in Sources */, + 228B538511BF7D0D001A58DA /* FileStream.cpp in Sources */, + 22AEA123123125D800359B16 /* SFilePatchArchives.cpp in Sources */, + 225C73501257CCC70009E8DA /* lookup3.c in Sources */, + 225C73551257CD0C0009E8DA /* SBaseFileTable.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 225FAC910E53B7F800DA2CAE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 225FACA50E53BAB400DA2CAE /* huff.cpp in Sources */, + 225FACA90E53BAB400DA2CAE /* explode.c in Sources */, + 226C7CA81857DE9400AB689C /* SBaseDumpData.cpp in Sources */, + 225FACAA0E53BAB400DA2CAE /* implode.c in Sources */, + 225FACAB0E53BAB400DA2CAE /* SFileAttributes.cpp in Sources */, + 226C7CAB1857DEAC00AB689C /* SBaseSubTypes.cpp in Sources */, + 225FACAC0E53BAB400DA2CAE /* SBaseCommon.cpp in Sources */, + 225FACAD0E53BAB400DA2CAE /* SCompression.cpp in Sources */, + 225FACAE0E53BAB400DA2CAE /* SFileCompactArchive.cpp in Sources */, + 225FACAF0E53BAB400DA2CAE /* SFileCreateArchive.cpp in Sources */, + 225FACB00E53BAB400DA2CAE /* SFileExtractFile.cpp in Sources */, + E60816F91B707B7200B283F7 /* der_encode_octet_string.c in Sources */, + 225FACB10E53BAB400DA2CAE /* SFileFindFile.cpp in Sources */, + 225FACB20E53BAB400DA2CAE /* SFileOpenArchive.cpp in Sources */, + 226C7CAE1857DEEB00AB689C /* SFileGetFileInfo.cpp in Sources */, + 225FACB30E53BAB400DA2CAE /* SFileOpenFileEx.cpp in Sources */, + 225FACB40E53BAB400DA2CAE /* SFileReadFile.cpp in Sources */, + 225FACB50E53BAB400DA2CAE /* SFileListFile.cpp in Sources */, + 2299D9D71167EFA8005C19BF /* adpcm.cpp in Sources */, + 2299D9DE1167EFC6005C19BF /* sparse.cpp in Sources */, + 2299DA4E1167FD16005C19BF /* SFileAddFile.cpp in Sources */, + 221F6A7B116852AA0026C852 /* LzmaEnc.c in Sources */, + 221F6A7E116852B20026C852 /* LzmaDec.c in Sources */, + 221F6AB51168545B0026C852 /* LzFind.c in Sources */, + 22C918C711933FCF0083AC69 /* hash_memory.c in Sources */, + 22C918C811933FCF0083AC69 /* md5.c in Sources */, + 22C918C911933FCF0083AC69 /* sha1.c in Sources */, + 22C918D711933FCF0083AC69 /* ltm_desc.c in Sources */, + 22C918D811933FCF0083AC69 /* multi.c in Sources */, + 22C918D911933FCF0083AC69 /* rand_prime.c in Sources */, + 22C918DA11933FCF0083AC69 /* base64_decode.c in Sources */, + 22C918DB11933FCF0083AC69 /* crypt_argchk.c in Sources */, + 22C918DC11933FCF0083AC69 /* crypt_find_hash.c in Sources */, + 22C918DD11933FCF0083AC69 /* crypt_find_prng.c in Sources */, + 22C918DE11933FCF0083AC69 /* crypt_hash_descriptor.c in Sources */, + 22C918DF11933FCF0083AC69 /* crypt_hash_is_valid.c in Sources */, + 22C918E011933FCF0083AC69 /* crypt_libc.c in Sources */, + 22C918E111933FCF0083AC69 /* crypt_ltc_mp_descriptor.c in Sources */, + 22C918E211933FCF0083AC69 /* crypt_prng_descriptor.c in Sources */, + 22C918E311933FCF0083AC69 /* crypt_prng_is_valid.c in Sources */, + 22C918E411933FCF0083AC69 /* crypt_register_hash.c in Sources */, + 22C918E511933FCF0083AC69 /* crypt_register_prng.c in Sources */, + 22C918E611933FCF0083AC69 /* zeromem.c in Sources */, + 22C918E711933FCF0083AC69 /* der_decode_bit_string.c in Sources */, + 22C918E811933FCF0083AC69 /* der_decode_boolean.c in Sources */, + 22C918E911933FCF0083AC69 /* der_decode_choice.c in Sources */, + 22C918EA11933FCF0083AC69 /* der_decode_ia5_string.c in Sources */, + 22C918EB11933FCF0083AC69 /* der_decode_integer.c in Sources */, + 22C918EC11933FCF0083AC69 /* der_decode_object_identifier.c in Sources */, + 22C918ED11933FCF0083AC69 /* der_decode_octet_string.c in Sources */, + 22C918EE11933FCF0083AC69 /* der_decode_printable_string.c in Sources */, + 22C918EF11933FCF0083AC69 /* der_decode_sequence_ex.c in Sources */, + 22C918F011933FCF0083AC69 /* der_decode_sequence_flexi.c in Sources */, + 22C918F111933FCF0083AC69 /* der_decode_sequence_multi.c in Sources */, + 22C918F211933FCF0083AC69 /* der_decode_short_integer.c in Sources */, + 22C918F311933FCF0083AC69 /* der_decode_utctime.c in Sources */, + 22C918F411933FCF0083AC69 /* der_decode_utf8_string.c in Sources */, + E60816F11B707B7200B283F7 /* der_encode_boolean.c in Sources */, + 22C918F511933FCF0083AC69 /* der_length_bit_string.c in Sources */, + 22C918F611933FCF0083AC69 /* der_length_boolean.c in Sources */, + 22C918F711933FCF0083AC69 /* der_length_ia5_string.c in Sources */, + 22C918F811933FCF0083AC69 /* der_length_integer.c in Sources */, + 22C918F911933FCF0083AC69 /* der_length_object_identifier.c in Sources */, + 22C918FA11933FCF0083AC69 /* der_length_octet_string.c in Sources */, + 22C918FB11933FCF0083AC69 /* der_length_printable_string.c in Sources */, + 22C918FC11933FCF0083AC69 /* der_length_sequence.c in Sources */, + 22C918FD11933FCF0083AC69 /* der_length_short_integer.c in Sources */, + 22C918FE11933FCF0083AC69 /* der_length_utctime.c in Sources */, + 22C918FF11933FCF0083AC69 /* der_length_utf8_string.c in Sources */, + 22C9190011933FCF0083AC69 /* der_sequence_free.c in Sources */, + 22C9190111933FCF0083AC69 /* ltc_ecc_map.c in Sources */, + 22C9190211933FCF0083AC69 /* ltc_ecc_mul2add.c in Sources */, + 22C9190311933FCF0083AC69 /* ltc_ecc_mulmod.c in Sources */, + 22C9190411933FCF0083AC69 /* ltc_ecc_points.c in Sources */, + 22C9190511933FCF0083AC69 /* ltc_ecc_projective_add_point.c in Sources */, + 22C9190611933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c in Sources */, + 22C9190711933FCF0083AC69 /* pkcs_1_mgf1.c in Sources */, + 22C9190811933FCF0083AC69 /* pkcs_1_oaep_decode.c in Sources */, + 22C9190911933FCF0083AC69 /* pkcs_1_pss_decode.c in Sources */, + 22C9190A11933FCF0083AC69 /* pkcs_1_v1_5_decode.c in Sources */, + 22C9190B11933FCF0083AC69 /* rsa_exptmod.c in Sources */, + 22C9190C11933FCF0083AC69 /* rsa_free.c in Sources */, + 22C9190D11933FCF0083AC69 /* rsa_import.c in Sources */, + 22C9190E11933FCF0083AC69 /* rsa_make_key.c in Sources */, + 22C9190F11933FCF0083AC69 /* rsa_verify_hash.c in Sources */, + 22C9191011933FCF0083AC69 /* rsa_verify_simple.c in Sources */, + 22C91A031193400A0083AC69 /* bn_fast_mp_invmod.c in Sources */, + 22C91A041193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c in Sources */, + E60816F71B707B7200B283F7 /* der_encode_object_identifier.c in Sources */, + 22C91A051193400A0083AC69 /* bn_fast_s_mp_mul_digs.c in Sources */, + E60816FB1B707B7200B283F7 /* der_encode_printable_string.c in Sources */, + 22C91A061193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c in Sources */, + 22C91A071193400A0083AC69 /* bn_fast_s_mp_sqr.c in Sources */, + 22C91A081193400A0083AC69 /* bn_mp_2expt.c in Sources */, + 22C91A091193400A0083AC69 /* bn_mp_abs.c in Sources */, + 22C91A0A1193400A0083AC69 /* bn_mp_add_d.c in Sources */, + 22C91A0B1193400A0083AC69 /* bn_mp_add.c in Sources */, + 22C91A0C1193400A0083AC69 /* bn_mp_addmod.c in Sources */, + 22C91A0D1193400A0083AC69 /* bn_mp_and.c in Sources */, + 22C91A0E1193400A0083AC69 /* bn_mp_clamp.c in Sources */, + 22C91A0F1193400A0083AC69 /* bn_mp_clear_multi.c in Sources */, + 22C91A101193400A0083AC69 /* bn_mp_clear.c in Sources */, + 22C91A111193400A0083AC69 /* bn_mp_cmp_d.c in Sources */, + 22C91A121193400A0083AC69 /* bn_mp_cmp_mag.c in Sources */, + 22C91A131193400A0083AC69 /* bn_mp_cmp.c in Sources */, + 22C91A141193400A0083AC69 /* bn_mp_cnt_lsb.c in Sources */, + 22C91A151193400A0083AC69 /* bn_mp_copy.c in Sources */, + 22C91A161193400A0083AC69 /* bn_mp_count_bits.c in Sources */, + E60816F51B707B7200B283F7 /* der_encode_integer.c in Sources */, + E60817071B707B7200B283F7 /* der_encode_utf8_string.c in Sources */, + 22C91A171193400A0083AC69 /* bn_mp_div_2.c in Sources */, + 22C91A181193400A0083AC69 /* bn_mp_div_2d.c in Sources */, + 22C91A191193400A0083AC69 /* bn_mp_div_3.c in Sources */, + 22C91A1A1193400A0083AC69 /* bn_mp_div_d.c in Sources */, + 22C91A1B1193400A0083AC69 /* bn_mp_div.c in Sources */, + 22C91A1C1193400A0083AC69 /* bn_mp_dr_is_modulus.c in Sources */, + 22C91A1D1193400A0083AC69 /* bn_mp_dr_reduce.c in Sources */, + 22C91A1E1193400A0083AC69 /* bn_mp_dr_setup.c in Sources */, + 22C91A1F1193400A0083AC69 /* bn_mp_exch.c in Sources */, + 22C91A201193400A0083AC69 /* bn_mp_expt_d.c in Sources */, + 22C91A211193400A0083AC69 /* bn_mp_exptmod_fast.c in Sources */, + 22C91A221193400A0083AC69 /* bn_mp_exptmod.c in Sources */, + 22C91A231193400A0083AC69 /* bn_mp_exteuclid.c in Sources */, + 22C91A241193400A0083AC69 /* bn_mp_fread.c in Sources */, + 22C91A251193400A0083AC69 /* bn_mp_fwrite.c in Sources */, + 22C91A261193400A0083AC69 /* bn_mp_gcd.c in Sources */, + 22C91A271193400A0083AC69 /* bn_mp_get_int.c in Sources */, + 22C91A281193400A0083AC69 /* bn_mp_grow.c in Sources */, + 22C91A291193400A0083AC69 /* bn_mp_init_copy.c in Sources */, + 22C91A2A1193400A0083AC69 /* bn_mp_init_multi.c in Sources */, + 22C91A2B1193400A0083AC69 /* bn_mp_init_set_int.c in Sources */, + 22C91A2C1193400A0083AC69 /* bn_mp_init_set.c in Sources */, + 22C91A2D1193400A0083AC69 /* bn_mp_init_size.c in Sources */, + 22C91A2E1193400A0083AC69 /* bn_mp_init.c in Sources */, + E60816DA1B707B1800B283F7 /* pkcs_1_pss_encode.c in Sources */, + 22C91A2F1193400A0083AC69 /* bn_mp_invmod_slow.c in Sources */, + 22C91A301193400A0083AC69 /* bn_mp_invmod.c in Sources */, + 22C91A311193400A0083AC69 /* bn_mp_is_square.c in Sources */, + 22C91A321193400A0083AC69 /* bn_mp_jacobi.c in Sources */, + 22C91A331193400A0083AC69 /* bn_mp_karatsuba_mul.c in Sources */, + 22C91A341193400A0083AC69 /* bn_mp_karatsuba_sqr.c in Sources */, + 22C91A351193400A0083AC69 /* bn_mp_lcm.c in Sources */, + 22C91A361193400A0083AC69 /* bn_mp_lshd.c in Sources */, + 22C91A371193400A0083AC69 /* bn_mp_mod_2d.c in Sources */, + 22C91A381193400A0083AC69 /* bn_mp_mod_d.c in Sources */, + 22C91A391193400A0083AC69 /* bn_mp_mod.c in Sources */, + 22C91A3A1193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c in Sources */, + 22C91A3B1193400A0083AC69 /* bn_mp_montgomery_reduce.c in Sources */, + E60817031B707B7200B283F7 /* der_encode_short_integer.c in Sources */, + 22C91A3C1193400A0083AC69 /* bn_mp_montgomery_setup.c in Sources */, + E60816DD1B707B2700B283F7 /* pkcs_1_v1_5_encode.c in Sources */, + 22C91A3D1193400A0083AC69 /* bn_mp_mul_2.c in Sources */, + E60816FD1B707B7200B283F7 /* der_encode_sequence_multi.c in Sources */, + 22C91A3E1193400A0083AC69 /* bn_mp_mul_2d.c in Sources */, + 22C91A3F1193400A0083AC69 /* bn_mp_mul_d.c in Sources */, + 22C91A401193400A0083AC69 /* bn_mp_mul.c in Sources */, + E60816EF1B707B7200B283F7 /* der_encode_bit_string.c in Sources */, + 22C91A411193400A0083AC69 /* bn_mp_mulmod.c in Sources */, + 22C91A421193400A0083AC69 /* bn_mp_n_root.c in Sources */, + 22C91A431193400A0083AC69 /* bn_mp_neg.c in Sources */, + 22C91A441193400A0083AC69 /* bn_mp_or.c in Sources */, + 22C91A451193400A0083AC69 /* bn_mp_prime_fermat.c in Sources */, + 22C91A461193400A0083AC69 /* bn_mp_prime_is_divisible.c in Sources */, + 22C91A471193400A0083AC69 /* bn_mp_prime_is_prime.c in Sources */, + E60816D71B707A9B00B283F7 /* rsa_sign_hash.c in Sources */, + 22C91A481193400A0083AC69 /* bn_mp_prime_miller_rabin.c in Sources */, + 22C91A491193400A0083AC69 /* bn_mp_prime_next_prime.c in Sources */, + 22C91A4A1193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c in Sources */, + 22C91A4B1193400A0083AC69 /* bn_mp_prime_random_ex.c in Sources */, + 22C91A4C1193400A0083AC69 /* bn_mp_radix_size.c in Sources */, + 22C91A4D1193400A0083AC69 /* bn_mp_radix_smap.c in Sources */, + 22C91A4E1193400A0083AC69 /* bn_mp_rand.c in Sources */, + 22C91A4F1193400A0083AC69 /* bn_mp_read_radix.c in Sources */, + 22C91A501193400A0083AC69 /* bn_mp_read_signed_bin.c in Sources */, + 22C91A511193400A0083AC69 /* bn_mp_read_unsigned_bin.c in Sources */, + 22C91A521193400A0083AC69 /* bn_mp_reduce_2k_l.c in Sources */, + 22C91A531193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c in Sources */, + 22C91A541193400A0083AC69 /* bn_mp_reduce_2k_setup.c in Sources */, + E60816FF1B707B7200B283F7 /* der_encode_set.c in Sources */, + E60817011B707B7200B283F7 /* der_encode_setof.c in Sources */, + 22C91A551193400A0083AC69 /* bn_mp_reduce_2k.c in Sources */, + 22C91A561193400A0083AC69 /* bn_mp_reduce_is_2k_l.c in Sources */, + E60817051B707B7200B283F7 /* der_encode_utctime.c in Sources */, + 22C91A571193400A0083AC69 /* bn_mp_reduce_is_2k.c in Sources */, + 22C91A581193400A0083AC69 /* bn_mp_reduce_setup.c in Sources */, + 22C91A591193400A0083AC69 /* bn_mp_reduce.c in Sources */, + 22C91A5A1193400A0083AC69 /* bn_mp_rshd.c in Sources */, + 22C91A5B1193400A0083AC69 /* bn_mp_set_int.c in Sources */, + 22C91A5C1193400A0083AC69 /* bn_mp_set.c in Sources */, + 22C91A5D1193400A0083AC69 /* bn_mp_shrink.c in Sources */, + 22C91A5E1193400A0083AC69 /* bn_mp_signed_bin_size.c in Sources */, + 22C91A5F1193400A0083AC69 /* bn_mp_sqr.c in Sources */, + 22C91A601193400A0083AC69 /* bn_mp_sqrmod.c in Sources */, + 22C91A611193400A0083AC69 /* bn_mp_sqrt.c in Sources */, + 22C91A621193400A0083AC69 /* bn_mp_sub_d.c in Sources */, + 22C91A631193400A0083AC69 /* bn_mp_sub.c in Sources */, + 22C91A641193400A0083AC69 /* bn_mp_submod.c in Sources */, + 22C91A651193400A0083AC69 /* bn_mp_to_signed_bin_n.c in Sources */, + 22C91A661193400A0083AC69 /* bn_mp_to_signed_bin.c in Sources */, + 22C91A671193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c in Sources */, + 22C91A681193400A0083AC69 /* bn_mp_to_unsigned_bin.c in Sources */, + 22C91A691193400A0083AC69 /* bn_mp_toom_mul.c in Sources */, + 22C91A6A1193400A0083AC69 /* bn_mp_toom_sqr.c in Sources */, + 22C91A6B1193400A0083AC69 /* bn_mp_toradix_n.c in Sources */, + 22C91A6C1193400A0083AC69 /* bn_mp_toradix.c in Sources */, + 22C91A6D1193400A0083AC69 /* bn_mp_unsigned_bin_size.c in Sources */, + E60816F31B707B7200B283F7 /* der_encode_ia5_string.c in Sources */, + E60816E01B707B5700B283F7 /* der_encode_sequence_ex.c in Sources */, + 22C91A6E1193400A0083AC69 /* bn_mp_xor.c in Sources */, + 22C91A6F1193400A0083AC69 /* bn_mp_zero.c in Sources */, + 22C91A701193400A0083AC69 /* bn_prime_tab.c in Sources */, + 22C91A711193400A0083AC69 /* bn_reverse.c in Sources */, + 22C91A721193400A0083AC69 /* bn_s_mp_add.c in Sources */, + 22C91A731193400A0083AC69 /* bn_s_mp_exptmod.c in Sources */, + 22C91A741193400A0083AC69 /* bn_s_mp_mul_digs.c in Sources */, + 22C91A751193400A0083AC69 /* bn_s_mp_mul_high_digs.c in Sources */, + 22C91A761193400A0083AC69 /* bn_s_mp_sqr.c in Sources */, + 22C91A771193400A0083AC69 /* bn_s_mp_sub.c in Sources */, + 22C91A781193400A0083AC69 /* bncore.c in Sources */, + 22F5A9C61193DFBA00F8B121 /* SFileVerify.cpp in Sources */, + 228B538411BF7D0D001A58DA /* FileStream.cpp in Sources */, + 22AEA122123125D800359B16 /* SFilePatchArchives.cpp in Sources */, + 225C73541257CD0C0009E8DA /* SBaseFileTable.cpp in Sources */, + 225C735A1257CD1F0009E8DA /* lookup3.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 22954ACB11D463A30064B264 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 22954AD211D463AB0064B264 /* Test.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 2229F62F11D4653600118914 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 225530D31056BAC800FA646A /* StormLib */; + targetProxy = 2229F62E11D4653600118914 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1DEB916508733D950010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = c89; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = ( + _7ZIP_ST, + _DEBUG, + ); + GCC_VERSION = ""; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.6; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + STRIP_INSTALLED_PRODUCT = NO; + }; + name = Debug; + }; + 1DEB916608733D950010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = c89; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = _7ZIP_ST; + GCC_VERSION = ""; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.6; + SDKROOT = macosx; + STRIP_INSTALLED_PRODUCT = YES; + }; + name = Release; + }; + 225530D51056BAC900FA646A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_VERSION = ""; + INSTALL_PATH = /usr/local/lib; + PRODUCT_NAME = StormLib; + }; + name = Debug; + }; + 225530D61056BAC900FA646A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_VERSION = ""; + INSTALL_PATH = /usr/local/lib; + PRODUCT_NAME = StormLib; + }; + name = Release; + }; + 225FAC960E53B7F900DA2CAE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + EXPORTED_SYMBOLS_FILE = "$(PROJECT_DIR)/stormlib_dll/StormLib.exp"; + FRAMEWORK_VERSION = A; + GCC_DYNAMIC_NO_PIC = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + PRODUCT_NAME = StormLib; + }; + name = Debug; + }; + 225FAC970E53B7F900DA2CAE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + EXPORTED_SYMBOLS_FILE = "$(PROJECT_DIR)/stormlib_dll/StormLib.exp"; + FRAMEWORK_VERSION = A; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + PRODUCT_NAME = StormLib; + }; + name = Release; + }; + 22954AD011D463A40064B264 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = ( + _7ZIP_ST, + _DEBUG, + __STORMLIB_TEST__, + ); + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INSTALL_PATH = /usr/local/bin; + PRODUCT_NAME = StormLib_Test; + }; + name = Debug; + }; + 22954AD111D463A40064B264 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INSTALL_PATH = /usr/local/bin; + PRODUCT_NAME = StormLib_Test; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB916408733D950010E9CD /* Build configuration list for PBXProject "StormLib" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB916508733D950010E9CD /* Debug */, + 1DEB916608733D950010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + 225530D71056BB1600FA646A /* Build configuration list for PBXNativeTarget "StormLib" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 225530D51056BAC900FA646A /* Debug */, + 225530D61056BAC900FA646A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + 225FAC980E53B7F900DA2CAE /* Build configuration list for PBXNativeTarget "StormLibFramework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 225FAC960E53B7F900DA2CAE /* Debug */, + 225FAC970E53B7F900DA2CAE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + 22954AD911D463E00064B264 /* Build configuration list for PBXNativeTarget "StormLib_Test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 22954AD011D463A40064B264 /* Debug */, + 22954AD111D463A40064B264 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0867D690FE84028FC02AAC07 /* Project object */; +} diff --git a/StormLib/StormLib_vs08.sln b/StormLib/StormLib_vs08.sln new file mode 100644 index 000000000..005e29f1c --- /dev/null +++ b/StormLib/StormLib_vs08.sln @@ -0,0 +1,139 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib", "StormLib_vs08.vcproj", "{78424708-1F6E-4D4B-920C-FB6D26847055}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib_dll", "StormLib_vs08_dll.vcproj", "{CB385198-50B1-4CF4-883B-11F042DED6AA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib_test", "StormLib_vs08_test.vcproj", "{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + DebugAD|Win32 = DebugAD|Win32 + DebugAD|x64 = DebugAD|x64 + DebugAS|Win32 = DebugAS|Win32 + DebugAS|x64 = DebugAS|x64 + DebugUD|Win32 = DebugUD|Win32 + DebugUD|x64 = DebugUD|x64 + DebugUS|Win32 = DebugUS|Win32 + DebugUS|x64 = DebugUS|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseAD|Win32 = ReleaseAD|Win32 + ReleaseAD|x64 = ReleaseAD|x64 + ReleaseAS|Win32 = ReleaseAS|Win32 + ReleaseAS|x64 = ReleaseAS|x64 + ReleaseUD|Win32 = ReleaseUD|Win32 + ReleaseUD|x64 = ReleaseUD|x64 + ReleaseUS|Win32 = ReleaseUS|Win32 + ReleaseUS|x64 = ReleaseUS|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|Win32.ActiveCfg = DebugUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.ActiveCfg = DebugUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.Build.0 = DebugUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAD|Win32.ActiveCfg = DebugAD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAD|Win32.Build.0 = DebugAD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAD|x64.ActiveCfg = DebugAD|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAD|x64.Build.0 = DebugAD|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAS|Win32.ActiveCfg = DebugAS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAS|Win32.Build.0 = DebugAS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAS|x64.ActiveCfg = DebugAS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAS|x64.Build.0 = DebugAS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUD|Win32.ActiveCfg = DebugUD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUD|Win32.Build.0 = DebugUD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUD|x64.ActiveCfg = DebugUD|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUD|x64.Build.0 = DebugUD|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUS|Win32.ActiveCfg = DebugUS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUS|Win32.Build.0 = DebugUS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUS|x64.ActiveCfg = DebugUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUS|x64.Build.0 = DebugUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Release|Win32.ActiveCfg = ReleaseUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.ActiveCfg = ReleaseUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.Build.0 = ReleaseUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAD|Win32.ActiveCfg = ReleaseAD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAD|Win32.Build.0 = ReleaseAD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAD|x64.ActiveCfg = ReleaseAD|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAD|x64.Build.0 = ReleaseAD|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAS|Win32.ActiveCfg = ReleaseAS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAS|Win32.Build.0 = ReleaseAS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAS|x64.ActiveCfg = ReleaseAS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAS|x64.Build.0 = ReleaseAS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUD|Win32.ActiveCfg = ReleaseUD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUD|Win32.Build.0 = ReleaseUD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUD|x64.ActiveCfg = ReleaseUD|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUD|x64.Build.0 = ReleaseUD|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUS|Win32.ActiveCfg = ReleaseUS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUS|Win32.Build.0 = ReleaseUS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUS|x64.ActiveCfg = ReleaseUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUS|x64.Build.0 = ReleaseUS|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.Debug|Win32.ActiveCfg = Debug|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.Debug|Win32.Build.0 = Debug|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.Debug|x64.ActiveCfg = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.Debug|x64.Build.0 = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAD|Win32.ActiveCfg = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAD|x64.ActiveCfg = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAD|x64.Build.0 = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAS|Win32.ActiveCfg = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAS|x64.ActiveCfg = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAS|x64.Build.0 = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUD|Win32.ActiveCfg = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUD|x64.ActiveCfg = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUD|x64.Build.0 = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUS|Win32.ActiveCfg = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUS|x64.ActiveCfg = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUS|x64.Build.0 = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.Release|Win32.ActiveCfg = Release|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.Release|Win32.Build.0 = Release|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.Release|x64.ActiveCfg = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.Release|x64.Build.0 = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAD|Win32.ActiveCfg = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAD|x64.ActiveCfg = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAD|x64.Build.0 = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAS|Win32.ActiveCfg = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAS|x64.ActiveCfg = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAS|x64.Build.0 = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUD|Win32.ActiveCfg = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUD|x64.ActiveCfg = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUD|x64.Build.0 = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUS|Win32.ActiveCfg = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUS|x64.ActiveCfg = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUS|x64.Build.0 = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Debug|Win32.ActiveCfg = Debug|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Debug|Win32.Build.0 = Debug|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Debug|x64.ActiveCfg = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Debug|x64.Build.0 = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAD|Win32.ActiveCfg = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAD|x64.ActiveCfg = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAD|x64.Build.0 = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAS|Win32.ActiveCfg = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAS|x64.ActiveCfg = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAS|x64.Build.0 = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUD|Win32.ActiveCfg = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUD|x64.ActiveCfg = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUD|x64.Build.0 = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUS|Win32.ActiveCfg = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUS|x64.ActiveCfg = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUS|x64.Build.0 = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Release|Win32.ActiveCfg = Release|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Release|Win32.Build.0 = Release|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Release|x64.ActiveCfg = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Release|x64.Build.0 = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAD|Win32.ActiveCfg = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAD|x64.ActiveCfg = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAD|x64.Build.0 = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAS|Win32.ActiveCfg = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAS|x64.ActiveCfg = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAS|x64.Build.0 = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUD|Win32.ActiveCfg = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUD|x64.ActiveCfg = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUD|x64.Build.0 = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUS|Win32.ActiveCfg = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUS|x64.ActiveCfg = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUS|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/StormLib/StormLib_vs08.vcproj b/StormLib/StormLib_vs08.vcproj new file mode 100644 index 000000000..0c02e133b --- /dev/null +++ b/StormLib/StormLib_vs08.vcproj @@ -0,0 +1,5017 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/StormLib/StormLib_vs08_dll.vcproj b/StormLib/StormLib_vs08_dll.vcproj new file mode 100644 index 000000000..8658887f5 --- /dev/null +++ b/StormLib/StormLib_vs08_dll.vcproj @@ -0,0 +1,2663 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/StormLib/StormLib_vs08_test.vcproj b/StormLib/StormLib_vs08_test.vcproj new file mode 100644 index 000000000..2f03a0b30 --- /dev/null +++ b/StormLib/StormLib_vs08_test.vcproj @@ -0,0 +1,2101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/StormLib/StormLib_vs19.sln b/StormLib/StormLib_vs19.sln new file mode 100644 index 000000000..586dd6ba0 --- /dev/null +++ b/StormLib/StormLib_vs19.sln @@ -0,0 +1,162 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28010.2050 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib", "StormLib_vs19.vcxproj", "{78424708-1F6E-4D4B-920C-FB6D26847055}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib_dll", "StormLib_vs19_dll.vcxproj", "{CB385198-50B1-4CF4-883B-11F042DED6AA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib_test", "StormLib_vs19_test.vcxproj", "{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + DebugAD|Win32 = DebugAD|Win32 + DebugAD|x64 = DebugAD|x64 + DebugAS|Win32 = DebugAS|Win32 + DebugAS|x64 = DebugAS|x64 + DebugUD|Win32 = DebugUD|Win32 + DebugUD|x64 = DebugUD|x64 + DebugUS|Win32 = DebugUS|Win32 + DebugUS|x64 = DebugUS|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseAD|Win32 = ReleaseAD|Win32 + ReleaseAD|x64 = ReleaseAD|x64 + ReleaseAS|Win32 = ReleaseAS|Win32 + ReleaseAS|x64 = ReleaseAS|x64 + ReleaseUD|Win32 = ReleaseUD|Win32 + ReleaseUD|x64 = ReleaseUD|x64 + ReleaseUS|Win32 = ReleaseUS|Win32 + ReleaseUS|x64 = ReleaseUS|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|Win32.ActiveCfg = DebugUS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|Win32.Build.0 = DebugUS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.ActiveCfg = DebugUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.Build.0 = DebugUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAD|Win32.ActiveCfg = DebugAD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAD|Win32.Build.0 = DebugAD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAD|x64.ActiveCfg = DebugAD|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAD|x64.Build.0 = DebugAD|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAS|Win32.ActiveCfg = DebugAS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAS|Win32.Build.0 = DebugAS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAS|x64.ActiveCfg = DebugAS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugAS|x64.Build.0 = DebugAS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUD|Win32.ActiveCfg = DebugUD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUD|Win32.Build.0 = DebugUD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUD|x64.ActiveCfg = DebugUD|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUD|x64.Build.0 = DebugUD|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUS|Win32.ActiveCfg = DebugUS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUS|Win32.Build.0 = DebugUS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUS|x64.ActiveCfg = DebugUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.DebugUS|x64.Build.0 = DebugUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Release|Win32.ActiveCfg = ReleaseUS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Release|Win32.Build.0 = ReleaseUS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.ActiveCfg = ReleaseUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.Build.0 = ReleaseUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAD|Win32.ActiveCfg = ReleaseAD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAD|Win32.Build.0 = ReleaseAD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAD|x64.ActiveCfg = ReleaseAD|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAD|x64.Build.0 = ReleaseAD|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAS|Win32.ActiveCfg = ReleaseAS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAS|Win32.Build.0 = ReleaseAS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAS|x64.ActiveCfg = ReleaseAS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseAS|x64.Build.0 = ReleaseAS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUD|Win32.ActiveCfg = ReleaseUD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUD|Win32.Build.0 = ReleaseUD|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUD|x64.ActiveCfg = ReleaseUD|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUD|x64.Build.0 = ReleaseUD|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUS|Win32.ActiveCfg = ReleaseUS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUS|Win32.Build.0 = ReleaseUS|Win32 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUS|x64.ActiveCfg = ReleaseUS|x64 + {78424708-1F6E-4D4B-920C-FB6D26847055}.ReleaseUS|x64.Build.0 = ReleaseUS|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.Debug|Win32.ActiveCfg = Debug|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.Debug|Win32.Build.0 = Debug|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.Debug|x64.ActiveCfg = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.Debug|x64.Build.0 = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAD|Win32.ActiveCfg = Debug|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAD|Win32.Build.0 = Debug|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAD|x64.ActiveCfg = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAD|x64.Build.0 = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAS|Win32.ActiveCfg = Debug|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAS|Win32.Build.0 = Debug|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAS|x64.ActiveCfg = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugAS|x64.Build.0 = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUD|Win32.ActiveCfg = Debug|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUD|Win32.Build.0 = Debug|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUD|x64.ActiveCfg = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUD|x64.Build.0 = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUS|Win32.ActiveCfg = Debug|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUS|Win32.Build.0 = Debug|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUS|x64.ActiveCfg = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.DebugUS|x64.Build.0 = Debug|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.Release|Win32.ActiveCfg = Release|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.Release|Win32.Build.0 = Release|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.Release|x64.ActiveCfg = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.Release|x64.Build.0 = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAD|Win32.ActiveCfg = Release|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAD|Win32.Build.0 = Release|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAD|x64.ActiveCfg = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAD|x64.Build.0 = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAS|Win32.ActiveCfg = Release|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAS|Win32.Build.0 = Release|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAS|x64.ActiveCfg = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseAS|x64.Build.0 = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUD|Win32.ActiveCfg = Release|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUD|Win32.Build.0 = Release|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUD|x64.ActiveCfg = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUD|x64.Build.0 = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUS|Win32.ActiveCfg = Release|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUS|Win32.Build.0 = Release|Win32 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUS|x64.ActiveCfg = Release|x64 + {CB385198-50B1-4CF4-883B-11F042DED6AA}.ReleaseUS|x64.Build.0 = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Debug|Win32.ActiveCfg = Debug|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Debug|Win32.Build.0 = Debug|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Debug|x64.ActiveCfg = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Debug|x64.Build.0 = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAD|Win32.ActiveCfg = Debug|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAD|Win32.Build.0 = Debug|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAD|x64.ActiveCfg = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAD|x64.Build.0 = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAS|Win32.ActiveCfg = Debug|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAS|Win32.Build.0 = Debug|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAS|x64.ActiveCfg = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugAS|x64.Build.0 = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUD|Win32.ActiveCfg = Debug|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUD|Win32.Build.0 = Debug|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUD|x64.ActiveCfg = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUD|x64.Build.0 = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUS|Win32.ActiveCfg = Debug|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUS|Win32.Build.0 = Debug|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUS|x64.ActiveCfg = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.DebugUS|x64.Build.0 = Debug|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Release|Win32.ActiveCfg = Release|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Release|Win32.Build.0 = Release|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Release|x64.ActiveCfg = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.Release|x64.Build.0 = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAD|Win32.ActiveCfg = Release|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAD|Win32.Build.0 = Release|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAD|x64.ActiveCfg = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAD|x64.Build.0 = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAS|Win32.ActiveCfg = Release|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAS|Win32.Build.0 = Release|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAS|x64.ActiveCfg = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseAS|x64.Build.0 = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUD|Win32.ActiveCfg = Release|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUD|Win32.Build.0 = Release|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUD|x64.ActiveCfg = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUD|x64.Build.0 = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUS|Win32.ActiveCfg = Release|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUS|Win32.Build.0 = Release|Win32 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUS|x64.ActiveCfg = Release|x64 + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D}.ReleaseUS|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {04583FA5-D423-4B0D-A42B-F7D44C70991C} + EndGlobalSection +EndGlobal diff --git a/StormLib/StormLib_vs19.vcxproj b/StormLib/StormLib_vs19.vcxproj new file mode 100644 index 000000000..e66423cda --- /dev/null +++ b/StormLib/StormLib_vs19.vcxproj @@ -0,0 +1,1187 @@ + + + + + DebugAD + Win32 + + + DebugAD + x64 + + + DebugAS + Win32 + + + DebugAS + x64 + + + DebugUD + Win32 + + + DebugUD + x64 + + + DebugUS + Win32 + + + DebugUS + x64 + + + ReleaseAD + Win32 + + + ReleaseAD + x64 + + + ReleaseAS + Win32 + + + ReleaseAS + x64 + + + ReleaseUD + Win32 + + + ReleaseUD + x64 + + + ReleaseUS + Win32 + + + ReleaseUS + x64 + + + + StormLib + {78424708-1F6E-4D4B-920C-FB6D26847055} + StormLib + false + 10.0 + StaticLibrary + v142 + false + + + + MultiByte + + + MultiByte + + + MultiByte + + + MultiByte + + + MultiByte + + + MultiByte + + + MultiByte + + + MultiByte + + + Unicode + + + Unicode + + + Unicode + + + Unicode + + + Unicode + + + Unicode + + + Unicode + + + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.50727.1 + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + $(ProjectName)DAD + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + $(ProjectName)DAD + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + $(ProjectName)DAS + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + $(ProjectName)DAS + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + $(ProjectName)RAD + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + $(ProjectName)RAD + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + $(ProjectName)RAS + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + $(ProjectName)RAS + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + $(ProjectName)DUD + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + $(ProjectName)DUD + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + $(ProjectName)DUS + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + $(ProjectName)DUS + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + $(ProjectName)RUD + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + $(ProjectName)RUD + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + $(ProjectName)RUS + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + $(ProjectName)RUS + + + + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + + Level1 + ProgramDatabase + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)/$(TargetName).lib + + + PostBuild.bat $(ProjectName) $(Platform) $(Configuration) + + + + + X64 + + + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + + Level1 + ProgramDatabase + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)/$(TargetName).lib + + + PostBuild.bat $(ProjectName) $(Platform) $(Configuration) + + + + + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + Level1 + ProgramDatabase + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)/$(TargetName).lib + + + PostBuild.bat $(ProjectName) $(Platform) $(Configuration) + + + + + X64 + + + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + Level1 + ProgramDatabase + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)/$(TargetName).lib + + + PostBuild.bat $(ProjectName) $(Platform) $(Configuration) + + + + + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreadedDLL + + Level1 + ProgramDatabase + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)/$(TargetName).lib + + + PostBuild.bat $(ProjectName) $(Platform) $(Configuration) + + + + + X64 + + + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreadedDLL + + Level1 + ProgramDatabase + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)/$(TargetName).lib + + + PostBuild.bat $(ProjectName) $(Platform) $(Configuration) + + + + + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + + Level1 + ProgramDatabase + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)/$(TargetName).lib + + + PostBuild.bat $(ProjectName) $(Platform) $(Configuration) + + + + + X64 + + + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + + Level1 + ProgramDatabase + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)/$(TargetName).lib + + + PostBuild.bat $(ProjectName) $(Platform) $(Configuration) + + + + + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + + Level1 + ProgramDatabase + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)/$(TargetName).lib + + + PostBuild.bat $(ProjectName) $(Platform) $(Configuration) + + + + + X64 + + + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + + Level1 + ProgramDatabase + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)/$(TargetName).lib + + + PostBuild.bat $(ProjectName) $(Platform) $(Configuration) + + + + + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + Level1 + ProgramDatabase + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)/$(TargetName).lib + + + PostBuild.bat $(ProjectName) $(Platform) $(Configuration) + + + + + X64 + + + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + Level1 + ProgramDatabase + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)/$(TargetName).lib + + + PostBuild.bat $(ProjectName) $(Platform) $(Configuration) + + + + + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreadedDLL + + Level1 + ProgramDatabase + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)/$(TargetName).lib + + + PostBuild.bat $(ProjectName) $(Platform) $(Configuration) + + + + + X64 + + + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreadedDLL + + Level1 + ProgramDatabase + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)/$(TargetName).lib + + + PostBuild.bat $(ProjectName) $(Platform) $(Configuration) + + + + + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + + Level1 + ProgramDatabase + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)/$(TargetName).lib + + + PostBuild.bat $(ProjectName) $(Platform) $(Configuration) + + + + + X64 + + + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + + Level1 + ProgramDatabase + false + StreamingSIMDExtensions + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)/$(TargetName).lib + + + PostBuild.bat $(ProjectName) $(Platform) $(Configuration) + + + + + + + + + + + + + + + + + + + + Create + StormCommon.h + Level4 + + + + + + + + + + + + + + + + + + + + Create + StormCommon.h + Level4 + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + + + Create + StormCommon.h + Level4 + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + + + Use + StormCommon.h + Use + StormCommon.h + Use + StormCommon.h + Use + StormCommon.h + Use + StormCommon.h + Use + StormCommon.h + Use + StormCommon.h + Use + StormCommon.h + Use + StormCommon.h + Use + StormCommon.h + Use + StormCommon.h + Use + StormCommon.h + Use + StormCommon.h + Use + StormCommon.h + Use + StormCommon.h + Use + StormCommon.h + Level4 + Level4 + Level4 + Level4 + Level4 + Level4 + Level4 + Level4 + Level4 + Level4 + Level4 + Level4 + Level4 + Level4 + Level4 + Level4 + + + Create + StormCommon.h + Level4 + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + + + Create + StormCommon.h + Level4 + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + + + Create + StormCommon.h + Level4 + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + + + Create + StormCommon.h + Level4 + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + + + Create + StormCommon.h + Level4 + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + + + Create + StormCommon.h + Level4 + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + + + Create + StormCommon.h + Level4 + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + + + Create + StormCommon.h + Level4 + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + + + Create + StormCommon.h + Level4 + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + + + Create + StormCommon.h + Level4 + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + + + Create + StormCommon.h + Level4 + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + + + Create + StormCommon.h + Level4 + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + + + Create + StormCommon.h + Level4 + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + + + Create + StormCommon.h + Level4 + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + Use + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/StormLib/StormLib_vs19.vcxproj.filters b/StormLib/StormLib_vs19.vcxproj.filters new file mode 100644 index 000000000..37915d2af --- /dev/null +++ b/StormLib/StormLib_vs19.vcxproj.filters @@ -0,0 +1,830 @@ + + + + + {595d6bc1-89d0-4fb8-98f6-be35e73727c4} + + + {721663d8-8692-476f-b0fd-71fdadf69929} + + + {9cc24144-d198-4bd1-b941-b946bd61b982} + + + {be0080d3-fc04-4442-9e28-b4cc2641177d} + + + {adb84a97-8a0c-4988-9473-452326110dff} + + + {87256d6a-e658-4f60-8759-6bff32a35eb2} + + + {d730d7c1-2960-49d2-ba0d-d1a91dd08964} + + + {13e5ccb1-06f1-4d10-bdc1-825b51c64dbf} + + + {73f7f025-7366-4d76-8d60-4327e00b9d18} + + + {be21c641-7727-4d7b-919e-c895d801db17} + + + {694a7758-f909-4b8e-aa13-4d06a8c70eff} + + + {3f01cae6-5676-4f33-bb38-215341eedfc4} + + + {63d75851-c430-4c76-aa08-3398523aab4a} + + + {11175e9e-e9f1-405c-961b-933e72503cdd} + + + {e30512f4-bdf8-4460-823d-475bd8f08d28} + + + {d2889ef6-3f12-4a9b-8624-8d061748ff03} + + + {02c6dfb8-4a58-46c5-bb35-69ba6215a3a6} + + + {563829a0-aaa3-4af2-88a2-8c6445d2754b} + + + {e82b0d03-77ff-46dc-b5a4-5b469224222a} + + + {cb92df18-9435-4db9-997a-e0e7d532cd26} + + + {2920175c-439c-4fd5-b94e-8cf1d3aaadd3} + + + + + Doc Files + + + Doc Files + + + Doc Files + + + + + Header Files + + + Source Files\adpcm + + + Source Files\huffman + + + Source Files\pklib + + + Source Files\sparse + + + Source Files\jenkins + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files\adpcm + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\huffman + + + Source Files\libtomcrypt\hashes + + + Source Files\libtomcrypt\hashes + + + Source Files\libtomcrypt\hashes + + + Source Files\libtomcrypt\math + + + Source Files\libtomcrypt\math + + + Source Files\libtomcrypt\math + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\lzma + + + Source Files\lzma + + + Source Files\lzma + + + Source Files\lzma + + + Source Files\lzma + + + Source Files\pklib + + + Source Files\pklib + + + Source Files\sparse + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\jenkins + + + Source Files\zlib + + + Source Files + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\rsa + + + \ No newline at end of file diff --git a/StormLib/StormLib_vs19_dll.vcxproj b/StormLib/StormLib_vs19_dll.vcxproj new file mode 100644 index 000000000..a4dbc19a5 --- /dev/null +++ b/StormLib/StormLib_vs19_dll.vcxproj @@ -0,0 +1,537 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + StormLib_dll + {CB385198-50B1-4CF4-883B-11F042DED6AA} + StormLib_dll + Win32Proj + 10.0 + + + + DynamicLibrary + v142 + Unicode + true + + + DynamicLibrary + v142 + Unicode + + + DynamicLibrary + v142 + Unicode + true + + + DynamicLibrary + v142 + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>14.0.25431.1 + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + true + StormLib + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + true + StormLib + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + false + StormLib + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + false + StormLib + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + Level1 + ProgramDatabase + + + $(OutDir)StormLib.dll + .\src\DllMain.def + true + Windows + false + + MachineX86 + + + + + X64 + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + Level1 + ProgramDatabase + + + $(OutDir)StormLib.dll + .\src\DllMain.def + true + Windows + false + + MachineX64 + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + MultiThreaded + + Level1 + ProgramDatabase + + + $(OutDir)StormLib.dll + .\src\DllMain.def + true + Windows + true + true + false + + MachineX86 + + + + + X64 + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + MultiThreaded + + Level1 + ProgramDatabase + + + $(OutDir)StormLib.dll + .\src\DllMain.def + true + Windows + true + true + false + + MachineX64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + Level4 + Level4 + Level4 + Level4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + + + + + + + + + + + Level4 + Level4 + Level4 + Level4 + + + + + + + + + \ No newline at end of file diff --git a/StormLib/StormLib_vs19_dll.vcxproj.filters b/StormLib/StormLib_vs19_dll.vcxproj.filters new file mode 100644 index 000000000..644488f51 --- /dev/null +++ b/StormLib/StormLib_vs19_dll.vcxproj.filters @@ -0,0 +1,838 @@ + + + + + {b352ea2c-4169-4b60-85bc-82eadd5a9d2e} + + + {9171b211-949a-4dc1-a028-edf0a2ed4605} + + + {712a20a0-c7a8-4e56-947b-2cf030bbb287} + + + {83502600-f49c-43b1-afe6-038d3560a859} + + + {ea8b08a3-5c21-48e0-b75f-78eaa2adbc22} + + + {593ac5e7-fe06-42b8-8025-e3bd725f95d8} + + + {9887a885-78fa-4164-80b9-9db6b0c11f86} + + + {7db62947-d38d-48e9-8b52-4cad226394a6} + + + {b435fecf-9a65-4f2e-8d64-7dfc70de3137} + + + {d8ad7878-9e42-427a-b5b6-ae51d92b92cf} + + + {07806629-c061-49ed-8212-0585d25fae23} + + + {ca554d9f-b602-452a-971e-86b537ee2ad1} + + + {46e1697c-e6c2-4a8c-b4d2-0142311bb48b} + + + {99279e07-2e33-44c9-8f37-0b810ee4ba25} + + + {04fbcfe0-3023-4fa0-8e36-26ab024a4abf} + + + {4720c7a0-f4aa-4737-978c-9efe8b429906} + + + {856c9964-4d85-40e9-8cbd-f4c672c07780} + + + {7ad3c876-768a-45bc-85b1-38cd492814ea} + + + {22e86a97-80e9-45a0-ac8e-70d7ea848f35} + + + {7b2ea923-8454-4073-bb9c-85de0f66caa1} + + + {5404ec38-706a-47f8-97b7-941c2574ddf2} + + + + + Doc Files + + + Doc Files + + + Doc Files + + + + + Header Files + + + Header Files + + + Header Files + + + Source Files\adpcm + + + Source Files\huffman + + + Source Files\pklib + + + Source Files\sparse + + + Source Files\jenkins + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files\adpcm + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\huffman + + + Source Files\libtomcrypt\hashes + + + Source Files\libtomcrypt\hashes + + + Source Files\libtomcrypt\hashes + + + Source Files\libtomcrypt\math + + + Source Files\libtomcrypt\math + + + Source Files\libtomcrypt\math + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\lzma + + + Source Files\lzma + + + Source Files\lzma + + + Source Files\lzma + + + Source Files\lzma + + + Source Files\pklib + + + Source Files\pklib + + + Source Files\sparse + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\jenkins + + + Source Files + + + + + Source Files + + + \ No newline at end of file diff --git a/StormLib/StormLib_vs19_test.vcxproj b/StormLib/StormLib_vs19_test.vcxproj new file mode 100644 index 000000000..21dd2402c --- /dev/null +++ b/StormLib/StormLib_vs19_test.vcxproj @@ -0,0 +1,549 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + StormLib_test + {AA561A7B-26EA-49AF-90E8-C53C1FA2965D} + StormLib_test + Win32Proj + 10.0 + + + + Application + v142 + Unicode + true + + + Application + v142 + Unicode + + + Application + v142 + Unicode + true + + + Application + v142 + Unicode + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>14.0.25431.1 + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + true + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + true + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + false + + + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + ./bin/$(ProjectName)/$(Platform)/$(Configuration)\ + false + + + + Disabled + WIN32;_DEBUG;_CONSOLE;__STORMLIB_TEST__;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + Level1 + EditAndContinue + Default + + + true + Console + false + + MachineX86 + false + + + + + X64 + + + Disabled + WIN32;_DEBUG;_CONSOLE;__STORMLIB_TEST__;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + Level1 + ProgramDatabase + Default + + + true + Console + false + + MachineX64 + false + + + + + WIN32;NDEBUG;_CONSOLE;__STORMLIB_TEST__;%(PreprocessorDefinitions) + MultiThreaded + + Level1 + ProgramDatabase + + + true + Console + true + true + false + + MachineX86 + false + + + + + X64 + + + WIN32;NDEBUG;_CONSOLE;__STORMLIB_TEST__;%(PreprocessorDefinitions) + MultiThreaded + + Level1 + ProgramDatabase + + + true + Console + true + true + false + + MachineX64 + false + + + + + + + + + + + + + + + + + + + + + Level4 + Level4 + + + + + + + + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + + + Level1 + Level1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + Level4 + Level4 + Level4 + Level4 + + + + + + + + + + + + + Level4 + Level4 + Level4 + Level4 + + + + + + + \ No newline at end of file diff --git a/StormLib/StormLib_vs19_test.vcxproj.filters b/StormLib/StormLib_vs19_test.vcxproj.filters new file mode 100644 index 000000000..18f619aa8 --- /dev/null +++ b/StormLib/StormLib_vs19_test.vcxproj.filters @@ -0,0 +1,839 @@ + + + + + {1dbbb48c-9db9-4fdb-a903-223ed233cc21} + + + {ab878eef-1074-4594-bac5-272c05774bd8} + + + {640f063a-5028-4ba1-9007-96d98a634561} + + + {6e8cfdab-fca3-4737-8905-6154bc657e15} + + + {a810fdb6-0d21-4279-8e39-b2de644170c0} + + + {7861b4fb-1471-4573-92ea-08c06dc14b93} + + + {8ba6c5c7-3ad0-44e6-8829-5020fce13d49} + + + {92cb0c1d-86f0-4735-9e4e-b07df664c359} + + + {f7fb3d55-94af-4a6e-be7b-76cb909e7325} + + + {337159fe-94a7-45a8-a91b-fa8b9d06b2ae} + + + {359bb3d3-71d5-47e7-967a-1fada7882e4d} + + + {775dbb7e-ef06-4660-9d84-50ff2557ef54} + + + {2e5d39cc-482c-4775-8830-79f8314e72e4} + + + {1e0ef267-228e-4c59-8d88-e3b33aeaff49} + + + {98330deb-0b92-4f02-8016-8a33dc5f5d29} + + + {fa78c716-784a-43a0-a548-db413431973b} + + + {5308566b-d3fd-4561-a7fb-982a63662793} + + + {d5371a5f-1630-4e79-9e7e-1ef654a2ddec} + + + {c2971fba-aff1-42ab-9f4f-71707edabf77} + + + {4f4fe3d6-6f2b-4c83-9cf9-f1d108ecd854} + + + {5aaea51e-4b7c-4a35-b35c-96c2fc7750f1} + + + + + Doc Files + + + Doc Files + + + Doc Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Source Files\adpcm + + + Source Files\huffman + + + Source Files\pklib + + + Source Files\sparse + + + Source Files\jenkins + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files\adpcm + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\bzip2 + + + Source Files\huffman + + + Source Files\libtomcrypt\hashes + + + Source Files\libtomcrypt\hashes + + + Source Files\libtomcrypt\hashes + + + Source Files\libtomcrypt\math + + + Source Files\libtomcrypt\math + + + Source Files\libtomcrypt\math + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\misc + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\asn1 + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\ecc + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\pkcs1 + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtomcrypt\pk\rsa + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\libtommath + + + Source Files\lzma + + + Source Files\lzma + + + Source Files\lzma + + + Source Files\lzma + + + Source Files\lzma + + + Source Files\pklib + + + Source Files\pklib + + + Source Files\sparse + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\zlib + + + Source Files\jenkins + + + \ No newline at end of file diff --git a/StormLib/doc/History.txt b/StormLib/doc/History.txt new file mode 100644 index 000000000..b6a098c4d --- /dev/null +++ b/StormLib/doc/History.txt @@ -0,0 +1,78 @@ + + StormLib history + ================ + + Version 9.11 + + - Fixed bug in processing HET table. + + Version 9.10 + + - Support for weak-signing + - Anti-protector: New Spazzler + + Version 9.00 + + - Support for streaming (master-mirror) + - Support for multi-file MPQs used by some WoW versions + - Opening maps protected by Spazzler protector + - Opening maps protected by BOBA protector + + Version 8.02 + + - Support for UNICODE encoding for on-disk files + - Optimized file deleting + + Version 8.01 + + - SFileFindFirstFile and SFileFindNextFile no longer find files that have + patch file in the oldest MPQ in the patch chain + - Write support for MPQs version 4 + + Version 8.00 + + - Updated support for protected maps from Warcraft III + + Version 7.11 + + - Support for MPQs v 3.0 (WOW-Cataclysm BETA) + - StormLib now deals properly with files that have MPQ_SECTOR_CHECKSUM missing, + but have sector checksum entry present in the sector offset table + + Version 7.10 + + - Support for partial MPQs ("interface.MPQ.part") + - The only operation that is externally allowed to do with internal files + ("(listfile)", "(attributes)" and "(signature)") is reading. Attempt to modify any of the file + fails and GetLastError returns ERROR_INTERNAL_FILE + - Fixed memory leak that has occured when writing more than one sector to the file at once + + Version 7.01 + + - Support for adding files from memory + - Fixed improper validation of handles to MPQ file and MPQ archive + - Fixed bug where StormLib didn't save CRC32 of the file when added to archive + + Version 7.00 + + - Properly deals with MPQs protected by w3xMaster + - Major rewrite + - Fixed support for (attributes) + - Added file verification + - Added MPQ signature verification + + Version 6.22 + + - Properly deals with MPQs protected by w3xMaster + + Version 6.21 + + - SFileRenameFile now properly re-crypts the file if necessary. + - SFileFindFirstFile correctly deals with deleted files + + Version 6.20 + + - Fixed lots of bugs when processing files with same names but different locales + - Fixed bugs when repeately extracts the same file with MPQ_FILE_SINGLE_UNIT flag + - Added SFileFlushArchive + - Fixed issue opening AVI files renamed to MPQ using SFileCreateArchiveEx diff --git a/StormLib/doc/The MoPaQ File Format 0.9.txt b/StormLib/doc/The MoPaQ File Format 0.9.txt new file mode 100644 index 000000000..ce8d8f701 --- /dev/null +++ b/StormLib/doc/The MoPaQ File Format 0.9.txt @@ -0,0 +1,318 @@ +THE MOPAQ ARCHIVE FORMAT +v0.9 (Thursday, June 30, 2005) +by Justin Olbrantz(Quantam) + +Distribution and reproduction of this specification are allowed without limitation, as long as it is not altered. Quoting +in other works is freely allowed, as long as the source and author of the quote is stated. + +TABLE OF CONTENTS +1. Introduction to the MoPaQ Format +2. The MoPaQ Format + 2.1 General Archive Layout + 2.2 Archive Header + 2.3 Block Table + 2.4 Hash Table + 2.5 File Data + 2.6 Listfile + 2.7 Extended Attributes + 2.8 Weak (Old) Digital Signature + 2.9 Strong (New) Digital Signature +3. Algorithm Source Code + 3.1 Encryption/Decryption + 3.2 Hashing + 3.3 Conversion of FILETIME and time_t + +1. INTRODUCTION TO THE MOPAQ FORMAT +The MoPaQ (or MPQ) format is an archive file format designed by Mike O'Brien (hence the name Mike O'brien PaCK) at Blizzard +Entertainment. The format has been used in all Blizzard games since (and including) Diablo. It is heavily optimized to be +a read-only game archive format, and excels at this role. + +The Blizzard MoPaQ-reading functions are contained in the Storm module, which my be either statically or dynamically linked. +The Blizzard MoPaQ-writing functions are contained in the MPQAPI module, which is always statically linked. + +2. THE MOPAQ FORMAT +All numbers in the MoPaQ format are in little endian. Data types are listed either as int (integer, the number of bits specified), +byte (8 bits), and char (bytes which contain ASCII characters). All sizes and offsets are in bytes, unless specified otherwise. +Structure members are listed in the following general form: +offset from the beginning of the structure: data type(array size) member name : member description + +2.1 GENERAL ARCHIVE LAYOUT +- Archive Header +- File Data +- File Data - Special Files +- Hash Table +- Block Table +- Strong Digital signature + +This is the usual archive format, and is not absolutely essential. Some archives have been observed placing the hash table +and file table after the archive header, and before the file data. + +2.2 ARCHIVE HEADER +00h: char(4) Magic : Indicates that the file is a MoPaQ archive. Must be ASCII "MPQ" 1Ah. +04h: int32 HeaderSize : Size of the archive header. Should be 32. +08h: int32 ArchiveSize : Size of the whole archive, including the header. Does not include the strong digital signature, if present. +This size is used, among other things, for determining the region to hash in computing the digital signature. +0Ch: int16 Unknown : Unknown +0Eh: int8 SectorSizeShift : Power of two exponent specifying the number of 512-byte disk sectors in each logical sector +in the archive. The size of each logical sector the archive is 512 * 2^SectorSizeShift. Bugs in the Storm library dictate +that this should always be 3 (4096 byte sectors). +10h: int32 HashTableOffset : Offset to the beginning of the hash table, relative to the beginning of the archive. +14h: int32 BlockTableOffset : Offset to the beginning of the block table, relative to the beginning of the archive. +18h: int32 HashTableEntries : Number of entries in the hash table. Must be a power of two, and must be less than 2^16. +1Ch: int32 BlockTableEntries : Number of entries in the block table. + +The archive header is the first structure in the archive, at archive offset 0, but the archive does not need to be at offset +0 of the containing file. The offset of the archive in the file is referred to here as ArchiveOffset. If the archive is not +at the beginning of the file, it must begin at a disk sector boundary (512 bytes). Early versions of Storm require that the +archive be at the end of the containing file (ArchiveOffset + ArchiveSize = file size), but this is not required in newer +versions (due to the strong digital signature not being considered a part of the archive). + +2.3 BLOCK TABLE +The block table contains entries for each region in the archive. Regions may be either files or empty space, which may be +overwritten by new files (typically this space is from deleted file data). The block table is encrypted, using the hash +of "(block table)" as the key. Each entry is structured as follows: + +00h: int32 BlockOffset : Offset of the beginning of the block, relative to the beginning of the archive. Meaningless if the block size is 0. +04h: int32 BlockSize : Size of the block in the archive. +08h: int32 FileSize : Size of the file data stored in the block. Only valid if the block is a file, otherwise meaningless, and should be 0. If the file is compressed, this is the size of the uncompressed file data. +0Ch: int32 Flags : Bit mask of the flags for the block. The following values are conclusively identified: + 80000000h: Block is a file, and follows the file data format; otherwise, block is free space, and may be overwritten. If the block is not a file, all other flags should be cleared. + 01000000h: File is stored as a single unit, rather than split into sectors. + 00020000h: The file's encryption key is adjusted by the block offset and file size (explained in detail in the File Data section). File must be encrypted. + 00010000h: File is encrypted. + 00000200h: File is compressed. Mutually exclusive to file imploded. + 00000100h: File is imploded. Mutually exclusive to file compressed. + +2.4 HASH TABLE +Instead of storing file names, for quick access MoPaQs use a fixed, power of two-size hash table of files in the archive. A file is uniquely identified by its file path, its language, and its platform. The home entry for a file in the hash table is computed as a hash of the file path. In the event of a collision (the home entry is occupied by another file), progressive overflow is used, and the file is placed in the next available hash table entry. Searches for a desired file in the hash table proceed from the home entry for the file until either the file is found, the entire hash table is searched, or an empty hash table entry (FileBlockIndex of FFFFFFFFh) is encountered. The hash table is encrypted using the hash of "(hash table)" as the key. Each entry is structured as follows: + +00h: int32 FilePathHashA : The hash of the file path, using method A. +04h: int32 FilePathHashB : The hash of the file path, using method B. +08h: int16 Language : The language of the file. This is a Windows LANGID data type, and uses the same values. 0 indicates the default language (American English), or that the file is language-neutral. +0Ah: int8 Platform : The platform the file is used for. 0 indicates the default platform. No other values have been observed. +0Ch: int32 FileBlockIndex : If the hash table entry is valid, this is the index into the block table of the file. Otherwise, one of the following two values: + FFFFFFFFh: Hash table entry is empty, and has always been empty. Terminates searches for a given file. + FFFFFFFEh: Hash table entry is empty, but was valid at some point (in other words, the file was deleted). Does not terminate searches for a given file. + +2.5 FILE DATA +00h: int32(SectorsInFile + 1) SectorOffsetTable : Offsets to the start of each sector's data, relative to the beginning of the file data. Not present if this information is calculatable (see details below). +immediately following SectorOffsetTable: SectorData : Data of each sector in the file, packed end to end (see details below). + +Normally, file data is split up into sectors, for simple streaming. All sectors, save for the last, will contain as many bytes of file data as specified in the archive header's SectorSizeShift; the last sector may be smaller than this, depending on the size of the file data. This sector size is the size of the raw file data; if the file is compressed, the compressed sector will be smaller or the same size as the uncompressed sector size. Individual sectors in a compressed file may be stored uncompressed; this occurs if and only if the sector could not be compressed by the algorithm used (if the compressed sector size was greater than or equal to the size of the raw data), and is indicated by the sector's compressed size in SectorOffsetTable being equal to the uncompressed size of the sector (which may be calculated from the FileSize). + +If the sector is compressed (but not imploded), a bit mask byte of the compression algorithm(s) used to compress the sector is appended to the beginning of the compressed sector data. This additional byte counts towards the total size of the sector; if the size of the sector (including this byte) exceeds or matches the uncompressed size of the sector data, the sector will be stored uncompressed, and this byte omitted. Multiple compression algorithms may be used on the same sector; in this case, successive compression occurs in the order the algorithms are listed below, and decompression occurs in the opposite order. For implimentations of all of these algorithms, see StormLib. + 40h: IMA ADPCM mono + 80h: IMA ADPCM stereo + 01h: Huffman encoded + 02h: Deflated (see ZLib) + 08h: Imploded (see PKWare Data Compression Library) + 10h: BZip2 compressed (see BZip2) + +If the file is stored as a single unit (indicated in the file's Flags), there is effectively only a single sector, which +contains the entire file. + +If the file is encrypted, each sector (after compression and appendage of the compression type byte, if applicable) +is encrypted with the file's key. The base key for a file is determined by a hash of the file name stripped of the +directory (i.e. the key for a file named "directory\file" would be computed as the hash of "file"). If this key is +adjusted, as indicated in the file's Flags, the final key is calculated as ((base key + BlockOffset - ArchiveOffset) +XOR FileSize) (StormLib - an open-source implementation of the MoPaQ reading and writing functions, +by Ladislav Zezula - incorrectly uses an AND in place of the XOR). Each sector is encrypted using the key + the +0-based index of the sector in the file. The SectorOffsetTable, if present, is encrypted using the key - 1. + +The SectorOffsetTable is omitted when the sizes and offsets of all sectors in the file are calculatable from the FileSize. +This can happen in several circumstances. If the file is not compressed/imploded, then the size and offset of all sectors +is known, based on the archive's SectorSizeShift. If the file is stored as a single unit compressed/imploded, then the +SectorOffsetTable is omitted, as the single file "sector" corresponds to BlockSize and FileSize, as mentioned previously. +Note that the SectorOffsetTable will always be present if the file is compressed/imploded and the file is not stored as +a single unit, even if there is only a single sector in the file (the size of the file is less than or equal to the +archive's sector size). + +2.6 LISTFILE +The listfile is a very simple extension to the MoPaQ format that contains the file paths of (most) files in the archive. +The languages and platforms of the files are not stored in the listfile. The listfile is contained in the file "(listfile)", +and is simply a non-Unix-style text file with one file path on each line, lines terminated with the bytes 0Dh 0Ah. The file +"(listfile)" may not be listed in the listfile. + +2.7 EXTENDED ATTRIBUTES +The extended attributes are optional file attributes for files in the block table. These attributes were added at times after +the MoPaQ format was already finalized, and it is not necessary for every archive to have all (or any) of the extended attributes. +If an archive contains a given attribute, there will be an instance of that attribute for every block in the block table, although +the attribute will be meaningless if the block is not a file. The order of the attributes for blocks correspond to the order of the +blocks in the block table, and are of the same number. The attributes are stored in parallel arrays in the "(attributes)" file, +in the archive. The attributes corresponding to this file need not be valid (and logically cannot be). Unlike all the other +structures in the MoPaQ format, entries in the extended attributes are NOT guaranteed to be aligned. Also note that in some +archives, malicious zeroing of the attributes has been observed, perhaps with the intent of breaking archive viewers. This +file is structured as follows: + +00h: int32 Version : Specifies the extended attributes format version. For now, must be 100. +04h: int32 AttributesPresent : Bit mask of the extended attributes present in the archive: + 00000001h: File CRC32s. + 00000002h: File timestamps. + 00000004h: File MD5s. +08h: int32(BlockTableEntries) CRC32s : CRC32s of the (uncompressed) file data for each block in the archive. Omitted if the +archive does not have CRC32s. immediately after CRC32s: FILETIME(BlockTableEntries) Timestamps : Timestamps for each block +in the archive. The format is that of the Windows FILETIME structure. Omitted if the archive does not have timestamps. +immediately after Timestamps: MD5(BlockTableEntries) MD5s : MD5s of the (uncompressed) file data for each block in the archive. +Omitted if the archive does not have MD5s. + +2.8 WEAK DIGITAL SIGNATURE +The weak digital signature is a digital signature using Microsoft CryptoAPI. It is an implimentation of the RSASSA-PKCS1-v1_5 +digital signature protocol, using the MD5 hashing algorithm and a 512-bit (weak) RSA key (for more information about this +protocol, see the RSA Labs PKCS1 specification). The public key and exponent are stored in a resource in Storm. The signature +is stored uncompressed, unencrypted in the file "(signature)" in the archive. The archive is hashed from the beginning of the +archive (ArchiveOffset in the containing file) to the end of the archive (the length indicated by ArchiveSize); the signature +file is added to the archive before signing, and the space occupied by the file is considered to be all binary 0s during +signing/verification. This file is structured as follows: + +00h: int32 Unknown : Must be 0. +04h: int32 Unknown : must be 0. +08h: int512 Signature : The digital signature. Like all other numbers in the MoPaQ format, this is stored in little-endian order. + +2.9 STRONG DIGITAL SIGNATURE +The strong digital signature uses a simple proprietary implementation of RSA signing, using the SHA-1 hashing algorithm and +a 2048-bit (strong) RSA key. The default public key and exponent are stored in Storm, but other keys may be used as well. +The strong digital signature is stored immediately after the archive, in the containing file; the entire archive (ArchiveSize +bytes, starting at ArchiveOffset in the containing file) is hashed as a single block. The signature has the following format: + +00h: char(4) Magic : Indicates the presence of a digital signature. Must be "NGIS" ("SIGN" backwards). +04h: int2048 Signature : The digital signature, stored in little-endian format. + +When the Signature field is decrypted with the public key and exponent, and the result stored in little-endian order, it is structured as follows: + +00h: byte Padding : Must be 0Bh. +01h: byte(235) Padding : Must be BBh. +ECh: byte(20) SHA-1 : SHA-1 hash of the archive, in standard SHA-1 format. + +3. ALGORITHM SOURCE CODE +3.1 ENCRYPTION/DECRYPTION +I believe this was derived at some point from code in StormLib. Assumes the long type to be 32 bits, and the machine to be little endian order. + +unsigned long dwCryptTable[0x500]; + +void InitializeCryptTable() +{ + unsigned long seed = 0x00100001; + unsigned long index1 = 0; + unsigned long index2 = 0; + int i; + + for (index1 = 0; index1 < 0x100; index1++) + { + for (index2 = index1, i = 0; i < 5; i++, index2 += 0x100) + { + unsigned long temp1, temp2; + + seed = (seed * 125 + 3) % 0x2AAAAB; + temp1 = (seed & 0xFFFF) << 0x10; + + seed = (seed * 125 + 3) % 0x2AAAAB; + temp2 = (seed & 0xFFFF); + + dwCryptTable[index2] = (temp1 | temp2); + } + } +} + +void EncryptData(void *lpbyBuffer, unsigned long dwLength, unsigned long dwKey) +{ + unsigned long *lpdwBuffer = (unsigned long *)lpbyBuffer; + unsigned long seed = 0xEEEEEEEE; + unsigned long ch; + + assert(lpbyBuffer); + + dwLength /= sizeof(unsigned long); + + while(dwLength-- > 0) + { + seed += dwCryptTable[0x400 + (dwKey & 0xFF)]; + ch = *lpdwBuffer ^ (dwKey + seed); + + dwKey = ((~dwKey << 0x15) + 0x11111111) | (dwKey >> 0x0B); + seed = *lpdwBuffer + seed + (seed << 5) + 3; + + *lpdwBuffer++ = ch; + } +} + +void DecryptData(void *lpbyBuffer, unsigned long dwLength, unsigned long dwKey) +{ + unsigned long *lpdwBuffer = (unsigned long *)lpbyBuffer; + unsigned long seed = 0xEEEEEEEE; + unsigned long ch; + + assert(lpbyBuffer); + + dwLength /= sizeof(unsigned long); + + while(dwLength-- > 0) + { + seed += dwCryptTable[0x400 + (dwKey & 0xFF)]; + ch = *lpdwBuffer ^ (dwKey + seed); + + dwKey = ((~dwKey << 0x15) + 0x11111111) | (dwKey >> 0x0B); + seed = ch + seed + (seed << 5) + 3; + + *lpdwBuffer++ = ch; + } +} + +3.2 HASHING +Based on code from StormLib. + +// Different types of hashes to make with HashString +#define MPQ_HASH_TABLE_OFFSET 0 +#define MPQ_HASH_NAME_A 1 +#define MPQ_HASH_NAME_B 2 +#define MPQ_HASH_FILE_KEY 3 + +unsigned long HashString(const char *lpszString, unsigned long dwHashType) +{ + unsigned long seed1 = 0x7FED7FED; + unsigned long seed2 = 0xEEEEEEEE; + int ch; + + while (*lpszString != 0) + { + ch = toupper(*lpszString++); + + seed1 = dwCryptTable[(dwHashType * 0xFF) + ch] ^ (seed1 + seed2); + seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; + } + return seed1; +} + +3.3 CONVERSION OF FILETIME AND time_t + +#define EPOCH_OFFSET 116444736000000000ULL // Number of 100 ns units between 01/01/1601 and 01/01/1970 + +bool GetTimeFromFileTime(FILETIME &fileTime, time_t &time) +{ + // The FILETIME represents a 64-bit integer: the number of 100 ns units since January 1, 1601 + unsigned long long nTime = ((unsigned long long)fileTime.dwHighDateTime << 32) + fileTime.dwLowDateTime; + + if (nTime < EPOCH_OFFSET) + return false; + + nTime -= EPOCH_OFFSET; // Convert the time base from 01/01/1601 to 01/01/1970 + nTime /= 10000000ULL; // Convert 100 ns to sec + + time = (time_t)nTime; + + // Test for overflow (FILETIME is 64 bits, time_t is 32 bits) + if ((nTime - (unsigned long long)time) > 0) + return false; + + return true; +} + +void GetFileTimeFromTime(time_t &time, FILETIME &fileTime) +{ + unsigned long long nTime = (unsigned long long)time; + + nTime *= 10000000ULL; + nTime += EPOCH_OFFSET; + + fileTime.dwLowDateTime = (DWORD)nTime; + fileTime.dwHighDateTime = (DWORD)(nTime >> 32); +} diff --git a/StormLib/doc/The MoPaQ File Format 1.0.txt b/StormLib/doc/The MoPaQ File Format 1.0.txt new file mode 100644 index 000000000..2f139453e --- /dev/null +++ b/StormLib/doc/The MoPaQ File Format 1.0.txt @@ -0,0 +1,433 @@ +THE MOPAQ ARCHIVE FORMAT +v1.0 (Friday, September 1, 2006) +by Justin Olbrantz(Quantam) + +Distribution and reproduction of this specification are allowed without limitation, as long as it is not altered. Quotation in other works is freely allowed, as long as the source and author of the quote are stated. + +TABLE OF CONTENTS +1. Introduction to the MoPaQ Format +2. The MoPaQ Format + 2.1 General Archive Layout + 2.2 Archive Header + 2.3 Block Table + 2.4 Extended Block Table + 2.5 Hash Table + 2.6 File Data + 2.7 Listfile + 2.8 Extended Attributes + 2.9 Weak (Old) Digital Signature + 2.10 Strong (New) Digital Signature +3. Algorithm Source Code + 3.1 Encryption/Decryption + 3.2 Hashing and File Key Computation + 3.3 Finding Files + 3.4 Deleting Files + 3.5 Conversion of FILETIME and time_t + 3.6 Forming a 64-bit Large Archive Offset from 32-bit and 16-bit Components +4. Revision History + +1. INTRODUCTION TO THE MOPAQ FORMAT +The MoPaQ (or MPQ) format is an archive file format designed by Mike O'Brien (hence the name Mike O'brien PaCK) at Blizzard Entertainment. The format has been used in all Blizzard games since (and including) Diablo. It is heavily optimized to be a read-only game archive format, and excels at this role. + +The Blizzard MoPaQ-reading functions are contained in the Storm module, which my be either statically or dynamically linked. The Blizzard MoPaQ-writing functions are contained in the MPQAPI module, which is always statically linked. + +StormLib - mentioned several times in this specification - is an open-source MoPaQ reading and writing library written by Ladislav Zezula (no affiliation with Blizzard Entertainment). While it's a bit dated, and does not support all of the newer MoPaQ features, it contains source code to the more exotic compression methods used by MoPaQ, such as the PKWare implode algorithm, MoPaQ's huffman compression algorithm, and the IMA ADPCM compression used by MoPaQ. + +2. THE MOPAQ FORMAT +All numbers in the MoPaQ format are in little endian byte order; signed numbers use the two's complement system. Data types are listed either as int (integer, the number of bits specified), byte (8 bits), or char (bytes which contain ASCII characters). All sizes and offsets are in bytes, unless specified otherwise. Structure members are listed in the following general form: +offset from the beginning of the structure: data type(array size) member name : member description + +2.1 GENERAL ARCHIVE LAYOUT +- Archive Header +- File Data +- File Data - Special Files +- Hash Table +- Block Table +- Extended Block Table +- Strong Digital signature + +This is the usual archive format, but it is not mandatory. Some archives have been observed placing the hash table and file table after the archive header, and before the file data. + +2.2 ARCHIVE HEADER +00h: char(4) Magic : Indicates that the file is a MoPaQ archive. Must be ASCII "MPQ" 1Ah. +04h: int32 HeaderSize : Size of the archive header. +08h: int32 ArchiveSize : Size of the whole archive, including the header. Does not include the strong digital signature, if present. This size is used, among other things, for determining the region to hash in computing the digital signature. This field is deprecated in the Burning Crusade MoPaQ format, and the size of the archive is calculated as the size from the beginning of the archive to the end of the hash table, block table, or extended block table (whichever is largest). +0Ch: int16 FormatVersion : MoPaQ format version. MPQAPI will not open archives where this is negative. Known versions: + 0000h: Original format. HeaderSize should be 20h, and large archives are not supported. + 0001h: Burning Crusade format. Header size should be 2Ch, and large archives are supported. +0Eh: int8 SectorSizeShift : Power of two exponent specifying the number of 512-byte disk sectors in each logical sector in the archive. The size of each logical sector in the archive is 512 * 2^SectorSizeShift. Bugs in the Storm library dictate that this should always be 3 (4096 byte sectors). +10h: int32 HashTableOffset : Offset to the beginning of the hash table, relative to the beginning of the archive. +14h: int32 BlockTableOffset : Offset to the beginning of the block table, relative to the beginning of the archive. +18h: int32 HashTableEntries : Number of entries in the hash table. Must be a power of two, and must be less than 2^16 for the original MoPaQ format, or less than 2^20 for the Burning Crusade format. +1Ch: int32 BlockTableEntries : Number of entries in the block table. +Fields only present in the Burning Crusade format and later: +20h: int64 ExtendedBlockTableOffset : Offset to the beginning of the extended block table, relative to the beginning of the archive. +28h: int16 HashTableOffsetHigh : High 16 bits of the hash table offset for large archives. +2Ah: int16 BlockTableOffsetHigh : High 16 bits of the block table offset for large archives. + +The archive header is the first structure in the archive, at archive offset 0; however, the archive does not need to be at offset 0 of the containing file. The offset of the archive in the file is referred to here as ArchiveOffset. If the archive is not at the beginning of the file, it must begin at a disk sector boundary (512 bytes). Early versions of Storm require that the archive be at the end of the containing file (ArchiveOffset + ArchiveSize = file size), but this is not required in newer versions (due to the strong digital signature not being considered a part of the archive). + +2.3 BLOCK TABLE +The block table contains entries for each region in the archive. Regions may be either files, empty space, which may be overwritten by new files (typically this space is from deleted file data), or unused block table entries. Empty space entries should have BlockOffset and BlockSize nonzero, and FileSize and Flags zero; unused block table entries should have BlockSize, FileSize, and Flags zero. The block table is encrypted, using the hash of "(block table)" as the key. Each entry is structured as follows: + +00h: int32 BlockOffset : Offset of the beginning of the block, relative to the beginning of the archive. +04h: int32 BlockSize : Size of the block in the archive. +08h: int32 FileSize : Size of the file data stored in the block. Only valid if the block is a file; otherwise meaningless, and should be 0. If the file is compressed, this is the size of the uncompressed file data. +0Ch: int32 Flags : Bit mask of the flags for the block. The following values are conclusively identified: + 80000000h: Block is a file, and follows the file data format; otherwise, block is free space or unused. If the block is not a file, all other flags should be cleared, and FileSize should be 0. + 01000000h: File is stored as a single unit, rather than split into sectors. + 00020000h: The file's encryption key is adjusted by the block offset and file size (explained in detail in the File Data section). File must be encrypted. + 00010000h: File is encrypted. + 00000200h: File is compressed. File cannot be imploded. + 00000100h: File is imploded. File cannot be compressed. + +2.4 EXTENDED BLOCK TABLE +The extended block table was added to support archives larger than 4 gigabytes (2^32 bytes). The table contains the upper bits of the archive offsets for each block in the block table. It is simply an array of int16s, which become bits 32-47 of the archive offsets for each block, with bits 48-63 being zero. Individual blocks in the archive are still limited to 4 gigabytes in size. This table is only present in Burning Crusade format archives that exceed 4 gigabytes size. + +As of the Burning Crusade Friends and Family beta, this table is not encrypted. + +2.5 HASH TABLE +Instead of storing file names, for quick access MoPaQs use a fixed, power of two-size hash table of files in the archive. A file is uniquely identified by its file path, its language, and its platform. The home entry for a file in the hash table is computed as a hash of the file path. In the event of a collision (the home entry is occupied by another file), progressive overflow is used, and the file is placed in the next available hash table entry. Searches for a desired file in the hash table proceed from the home entry for the file until either the file is found, the entire hash table is searched, or an empty hash table entry (FileBlockIndex of FFFFFFFFh) is encountered. The hash table is encrypted using the hash of "(hash table)" as the key. Each entry is structured as follows: + +00h: int32 FilePathHashA : The hash of the file path, using method A. +04h: int32 FilePathHashB : The hash of the file path, using method B. +08h: int16 Language : The language of the file. This is a Windows LANGID data type, and uses the same values. 0 indicates the default language (American English), or that the file is language-neutral. +0Ah: int8 Platform : The platform the file is used for. 0 indicates the default platform. No other values have been observed. +0Ch: int32 FileBlockIndex : If the hash table entry is valid, this is the index into the block table of the file. Otherwise, one of the following two values: + FFFFFFFFh: Hash table entry is empty, and has always been empty. Terminates searches for a given file. + FFFFFFFEh: Hash table entry is empty, but was valid at some point (in other words, the file was deleted). Does not terminate searches for a given file. + +2.6 FILE DATA +The data for each file is composed of the following structure: +00h: int32(SectorsInFile + 1) SectorOffsetTable : Offsets to the start of each sector, relative to the beginning of the file data. The last entry contains the file size, making it possible to easily calculate the size of any given sector. This table is not present if this information can be calculated (see details below). +immediately following SectorOffsetTable: SECTOR Sectors(SectorsInFile) : Data of each sector in the file, packed end to end (see details below). + +Normally, file data is split up into sectors, for simple streaming. All sectors, save for the last, will contain as many bytes of file data as specified in the archive header's SectorSizeShift; the last sector may contain less than this, depending on the size of the entire file's data. If the file is compressed or imploded, the sector will be smaller or the same size as the file data it contains. Individual sectors in a compressed or imploded file may be stored uncompressed; this occurs if and only if the file data the sector contains could not be compressed by the algorithm(s) used (if the compressed sector size was greater than or equal to the size of the file data), and is indicated by the sector's size in SectorOffsetTable being equal to the size of the file data in the sector (which may be calculated from the FileSize). + +The format of each sector depends on the kind of sector it is. Uncompressed sectors are simply the the raw file data contained in the sector. Imploded sectors are the raw compressed data following compression with the implode algorithm (these sectors can only be in imploded files). Compressed sectors (only found in compressed - not imploded - files) are compressed with one or more compression algorithms, and have the following structure: +00h: byte CompressionMask : Mask of the compression types applied to this sector. If multiple compression types are used, they are applied in the order listed below, and decompression is performed in the opposite order. This byte counts towards the total sector size, meaning that the sector will be stored uncompressed if the data cannot be compressed by at least two bytes; as well, this byte is encrypted with the sector data, if applicable. The following compression types are defined (for implementations of these algorithms, see StormLib): + 40h: IMA ADPCM mono + 80h: IMA ADPCM stereo + 01h: Huffman encoded + 02h: Deflated (see ZLib) + 08h: Imploded (see PKWare Data Compression Library) + 10h: BZip2 compressed (see BZip2) +01h: byte(SectorSize - 1) SectorData : The compressed data for the sector. + +If the file is stored as a single unit (indicated in the file's Flags), there is effectively only a single sector, which contains the entire file data. + +If the file is encrypted, each sector (after compression/implosion, if applicable) is encrypted with the file's key. The base key for a file is determined by a hash of the file name stripped of the directory (i.e. the key for a file named "directory\file" would be computed as the hash of "file"). If this key is adjusted, as indicated in the file's Flags, the final key is calculated as ((base key + BlockOffset - ArchiveOffset) XOR FileSize) (StormLib incorrectly uses an AND in place of the XOR). Each sector is encrypted using the key + the 0-based index of the sector in the file. The SectorOffsetTable, if present, is encrypted using the key - 1. + +The SectorOffsetTable is omitted when the sizes and offsets of all sectors in the file are calculatable from the FileSize. This can happen in several circumstances. If the file is not compressed/imploded, then the size and offset of all sectors is known, based on the archive's SectorSizeShift. If the file is stored as a single unit compressed/imploded, then the SectorOffsetTable is omitted, as the single file "sector" corresponds to BlockSize and FileSize, as mentioned previously. However, the SectorOffsetTable will be present if the file is compressed/imploded and the file is not stored as a single unit, even if there is only a single sector in the file (the size of the file is less than or equal to the archive's sector size). + +2.7 LISTFILE +The listfile is a very simple extension to the MoPaQ format that contains the file paths of (most) files in the archive. The languages and platforms of the files are not stored in the listfile. The listfile is contained in the file "(listfile)" (default language and platform), and is simply a text file with file paths separated by ';', 0Dh, 0Ah, or some combination of these. The file "(listfile)" may not be listed in the listfile. + +2.8 EXTENDED ATTRIBUTES +The extended attributes are optional file attributes for files in the block table. These attributes were added at times after the MoPaQ format was already finalized, and it is not necessary for every archive to have all (or any) of the extended attributes. If an archive contains a given attribute, there will be an instance of that attribute for every block in the block table, although the attribute will be meaningless if the block is not a file. The order of the attributes for blocks correspond to the order of the blocks in the block table, and are of the same number. The attributes are stored in parallel arrays in the "(attributes)" file (default language and platform), in the archive. The attributes corresponding to this file need not be valid (and logically cannot be). Unlike all the other structures in the MoPaQ format, entries in the extended attributes are NOT guaranteed to be aligned. Also note that in some archives, malicious zeroing of the attributes has been observed, perhaps with the intent of breaking archive viewers. This file is structured as follows: + +00h: int32 Version : Specifies the extended attributes format version. For now, must be 100. +04h: int32 AttributesPresent : Bit mask of the extended attributes present in the archive: + 00000001h: File CRC32s. + 00000002h: File timestamps. + 00000004h: File MD5s. +08h: int32(BlockTableEntries) CRC32s : CRC32s of the (uncompressed) file data for each block in the archive. Omitted if the archive does not have CRC32s. +immediately after CRC32s: FILETIME(BlockTableEntries) Timestamps : Timestamps for each block in the archive. The format is that of the Windows FILETIME structure. Omitted if the archive does not have timestamps. +immediately after Timestamps: MD5(BlockTableEntries) MD5s : MD5s of the (uncompressed) file data for each block in the archive. Omitted if the archive does not have MD5s. + +2.9 WEAK DIGITAL SIGNATURE +The weak digital signature is a digital signature using Microsoft CryptoAPI. It is an implimentation +of the RSASSA-PKCS1-v1_5 digital signature protocol, using the MD5 hashing algorithm and a 512-bit (weak) +RSA key (for more information about this protocol, see the RSA Labs PKCS1 specification). The public key +and exponent are stored in a resource in Storm, the private key is stored in a separate file, whose filename +is passed to MPQAPI (the private key is not stored in MPQAPI). The signature is stored uncompressed, +unencrypted in the file "(signature)" (default language and platform) in the archive. The archive +is hashed from the beginning of the archive (ArchiveOffset in the containing file) to the end of +the archive (the length indicated by ArchiveSize, or calculated in the Burning Crusade MoPaQ format); +the signature file is added to the archive before signing, and the space occupied by the file is considered +to be all binary 0s during signing/verification. This file is structured as follows: + +00h: int32 Unknown : Must be 0. +04h: int32 Unknown : Must be 0. +08h: int512 Signature : The digital signature. Like all other numbers in the MoPaQ format, this is stored +in little-endian order. The structure of this, when decrypted, follows the RSASSA-PKCS1-v1_5 specification; +this format is rather icky to work with (I wrote a program to verify this signature using nothing but an MD5 +function and huge integer functions; it wasn't pleasant), and best left to an encryption library such as Cryto++. + +2.10 STRONG DIGITAL SIGNATURE +The strong digital signature uses a simple proprietary implementation of RSA signing, using the SHA-1 hashing algorithm and a 2048-bit (strong) RSA key. The default public key and exponent are stored in Storm, but other keys may be used as well. The strong digital signature is stored immediately after the archive, in the containing file; the entire archive (ArchiveSize bytes, starting at ArchiveOffset in the containing file) is hashed as a single block. The signature has the following format: + +00h: char(4) Magic : Indicates the presence of a digital signature. Must be "NGIS" ("SIGN" backwards). +04h: int2048 Signature : The digital signature, stored in little-endian format. + +When the Signature field is decrypted with the public key and exponent, and the resulting large integer is stored in little-endian order, it is structured as follows: + +00h: byte Padding : Must be 0Bh. +01h: byte(235) Padding : Must be BBh. +ECh: byte(20) SHA-1 : SHA-1 hash of the archive, in standard SHA-1 byte order. + +3. ALGORITHM SOURCE CODE +All of the sample code here assumes little endian machine byte order, that the short type is 16 bits, that the long type is 32 bits, and that the long long type is 64 bits. Adjustments must be made if these assumptions are not correct on a given platform. All code not credited otherwise was written by myself in the writing of this specification. + +3.1 ENCRYPTION/DECRYPTION +Based on code from StormLib. + +unsigned long dwCryptTable[0x500]; + +// The encryption and hashing functions use a number table in their procedures. This table must be initialized before the functions are called the first time. +void InitializeCryptTable() +{ + unsigned long seed = 0x00100001; + unsigned long index1 = 0; + unsigned long index2 = 0; + int i; + + for (index1 = 0; index1 < 0x100; index1++) + { + for (index2 = index1, i = 0; i < 5; i++, index2 += 0x100) + { + unsigned long temp1, temp2; + + seed = (seed * 125 + 3) % 0x2AAAAB; + temp1 = (seed & 0xFFFF) << 0x10; + + seed = (seed * 125 + 3) % 0x2AAAAB; + temp2 = (seed & 0xFFFF); + + dwCryptTable[index2] = (temp1 | temp2); + } + } +} + +void EncryptData(void *lpbyBuffer, unsigned long dwLength, unsigned long dwKey) +{ + assert(lpbyBuffer); + + unsigned long *lpdwBuffer = (unsigned long *)lpbyBuffer; + unsigned long seed = 0xEEEEEEEE; + unsigned long ch; + + dwLength /= sizeof(unsigned long); + + while(dwLength-- > 0) + { + seed += dwCryptTable[0x400 + (dwKey & 0xFF)]; + ch = *lpdwBuffer ^ (dwKey + seed); + + dwKey = ((~dwKey << 0x15) + 0x11111111) | (dwKey >> 0x0B); + seed = *lpdwBuffer + seed + (seed << 5) + 3; + + *lpdwBuffer++ = ch; + } +} + +void DecryptData(void *lpbyBuffer, unsigned long dwLength, unsigned long dwKey) +{ + assert(lpbyBuffer); + + unsigned long *lpdwBuffer = (unsigned long *)lpbyBuffer; + unsigned long seed = 0xEEEEEEEEL; + unsigned long ch; + + dwLength /= sizeof(unsigned long); + + while(dwLength-- > 0) + { + seed += dwCryptTable[0x400 + (dwKey & 0xFF)]; + ch = *lpdwBuffer ^ (dwKey + seed); + + dwKey = ((~dwKey << 0x15) + 0x11111111L) | (dwKey >> 0x0B); + seed = ch + seed + (seed << 5) + 3; + + *lpdwBuffer++ = ch; + } +} + +3.2 HASHING AND FILE KEY COMPUTATION +These functions may have been derived from StormLib code at some point in the very distant past. It was so long ago that I don't remember for certain. + +// Different types of hashes to make with HashString +#define MPQ_HASH_TABLE_OFFSET 0 +#define MPQ_HASH_NAME_A 1 +#define MPQ_HASH_NAME_B 2 +#define MPQ_HASH_FILE_KEY 3 + +// Based on code from StormLib. +unsigned long HashString(const char *lpszString, unsigned long dwHashType) +{ + assert(lpszString); + assert(dwHashType <= MPQ_HASH_FILE_KEY); + + unsigned long seed1 = 0x7FED7FEDL; + unsigned long seed2 = 0xEEEEEEEEL; + int ch; + + while (*lpszString != 0) + { + ch = toupper(*lpszString++); + + seed1 = dwCryptTable[(dwHashType * 0x100) + ch] ^ (seed1 + seed2); + seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; + } + return seed1; +} + +#define BLOCK_OFFSET_ADJUSTED_KEY 0x00020000L + +unsigned long ComputeFileKey(const char *lpszFilePath, const BlockTableEntry &blockEntry, unsigned long nArchiveOffset) +{ + assert(lpszFilePath); + + // Find the file name part of the path + const char *lpszFileName = strrchr(lpszFilePath, '\\'); + if (lpszFileName) + lpszFileName++; // Skip the \ + else + lpszFileName = lpszFilePath; + + // Hash the name to get the base key + unsigned long nFileKey = HashString(lpszFileName, MPQ_HASH_FILE_KEY); + + // Offset-adjust the key if necessary + if (blockEntry.Flags & BLOCK_OFFSET_ADJUSTED_KEY) + nFileKey = (nFileKey + blockEntry.BlockOffset) ^ blockEntry.FileSize; + + return nFileKey; +} + +3.3 FINDING FILES + +#define MPQ_HASH_ENTRY_EMPTY 0xFFFFFFFFL +#define MPQ_HASH_ENTRY_DELETED 0xFFFFFFFEL + +bool FindFileInHashTable(const HashTableEntry *lpHashTable, unsigned long nHashTableSize, const char *lpszFilePath, unsigned short nLang, unsigned char nPlatform, unsigned long &iFileHashEntry) +{ + assert(lpHashTable); + assert(nHashTableSize); + assert(lpszFilePath); + + // Find the home entry in the hash table for the file + unsigned long iInitEntry = HashString(lpszFilePath, MPQ_HASH_TABLE_OFFSET) & (nHashTableSize - 1); + + // Is there anything there at all? + if (lpHashTable[iInitEntry].FileBlockIndex == MPQ_HASH_ENTRY_EMPTY) + return false; + + // Compute the hashes to compare the hash table entry against + unsigned long nNameHashA = HashString(lpszFilePath, MPQ_HASH_NAME_A), + nNameHashB = HashString(lpszFilePath, MPQ_HASH_NAME_B), + iCurEntry = iInitEntry; + + // Check each entry in the hash table till a termination point is reached + do + { + if (lpHashTable[iCurEntry].FileBlockIndex != MPQ_HASH_ENTRY_DELETED) + { + if (lpHashTable[iCurEntry].FilePathHashA == nNameHashA + && lpHashTable[iCurEntry].FilePathHashB == nNameHashB + && lpHashTable[iCurEntry].Language == nLang + && lpHashTable[iCurEntry].Platform == nPlatform) + { + iFileHashEntry = iCurEntry; + + return true; + } + } + + iCurEntry = (iCurEntry + 1) & (nHashTableSize - 1); + } while (iCurEntry != iInitEntry && lpHashTable[iCurEntry].FileBlockIndex != MPQ_HASH_ENTRY_EMPTY); + + return false; +} + +3.4 DELETING FILES + +bool DeleteFile(HashTableEntry *lpHashTable, unsigned long nHashTableSize, BlockTableEntry *lpBlockTable, const char *lpszFilePath, unsigned short nLang, unsigned char nPlatform) +{ + assert(lpHashTable); + assert(nHashTableSize); + assert(lpBlockTable); + + // Find the file in the hash table + unsigned long iFileHashEntry; + + if (!FindFileInHashTable(lpHashTable, nHashTableSize, lpszFilePath, nLang, nPlatform, iFileHashEntry)) + return false; + + // Get the block table index before we nuke the hash table entry + unsigned long iFileBlockEntry = lpHashTable[iFileHashEntry].FileBlockIndex; + + // Delete the file's entry in the hash table + memset(&lpHashTable[iFileHashEntry], 0xFF, sizeof(HashTableEntry)); + + // If the next entry is empty, mark this one as empty; otherwise, mark this as deleted. + if (lpHashTable[(iFileHashEntry + 1) & (nHashTableSize - 1)].FileBlockIndex == MPQ_HASH_ENTRY_EMPTY) + lpHashTable[iFileHashEntry].FileBlockIndex = MPQ_HASH_ENTRY_EMPTY; + else + lpHashTable[iFileHashEntry].FileBlockIndex = MPQ_HASH_ENTRY_DELETED; + + // If the block occupies space, mark the block as free space; otherwise, clear the block table entry. + if (lpBlockTable[iFileBlockEntry].BlockSize > 0) + { + lpBlockTable[iFileBlockEntry].FileSize = 0; + lpBlockTable[iFileBlockEntry].Flags = 0; + } + else + memset(&lpBlockTable[iFileBlockEntry], 0, sizeof(BlockTableEntry); + + return true; +} + +3.5 CONVERSION OF FILETIME AND time_t +This code assumes that the base ("zero") date for time_t is 01/01/1970. This is true on Windows, Unix System V systems, and Mac OS X. It is unknown whether this is true on all other platforms. You'll need to research this yourself, if you plan on porting it somewhere else. + +#define EPOCH_OFFSET 116444736000000000ULL // Number of 100 ns units between 01/01/1601 and 01/01/1970 + +bool GetTimeFromFileTime(const FILETIME &fileTime, time_t &time) +{ + // The FILETIME represents a 64-bit integer: the number of 100 ns units since January 1, 1601 + unsigned long long nTime = ((unsigned long long)fileTime.dwHighDateTime << 32) + fileTime.dwLowDateTime; + + if (nTime < EPOCH_OFFSET) + return false; + + nTime -= EPOCH_OFFSET; // Convert the time base from 01/01/1601 to 01/01/1970 + nTime /= 10000000ULL; // Convert 100 ns to sec + + time = (time_t)nTime; + + // Test for overflow (FILETIME is 64 bits, time_t is 32 bits) + if ((nTime - (unsigned long long)time) > 0) + return false; + + return true; +} + +void GetFileTimeFromTime(const time_t &time, FILETIME &fileTime) +{ + unsigned long long nTime = (unsigned long long)time; + + nTime *= 10000000ULL; + nTime += EPOCH_OFFSET; + + fileTime.dwLowDateTime = (DWORD)nTime; + fileTime.dwHighDateTime = (DWORD)(nTime >> 32); +} + +3.6 FORMING A 64-BIT LARGE ARCHIVE OFFSET FROM 32-BIT AND 16-BIT COMPONENTS +unsigned long long MakeLargeArchiveOffset(unsigned long nOffsetLow, unsigned short nOffsetHigh) +{ + return ((unsigned long long)nOffsetHigh << 32) + (unsigned long long)nOffsetLow; +} + +4. REVISION HISTORY +1.0 + - Updated to include most of the changes found in the Burning Crusade Friends and Family beta + +0.91. + - Updated several structure member descriptions + - Listed the full set of characters that can separate list file entries + - Noted that (attributes), (listfile), and (signature) use the default language and platform codes + - Redid part of the file data specs to clarify the format of sectors + - Enhanced descriptions of the different kinds of block table entries + - Added ComputeFileKey, FindFileInHashTable, and DeleteFile source \ No newline at end of file diff --git a/StormLib/doc/d3-authenticationcode/d3-authenticationcode-deDE.txt b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-deDE.txt new file mode 100644 index 000000000..cac66712a --- /dev/null +++ b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-deDE.txt @@ -0,0 +1 @@ +UCMXF6EJY352EFH4XFRXCFH2XC9MQRZK \ No newline at end of file diff --git a/StormLib/doc/d3-authenticationcode/d3-authenticationcode-enGB.txt b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-enGB.txt new file mode 100644 index 000000000..2bc9c8385 --- /dev/null +++ b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-enGB.txt @@ -0,0 +1 @@ +MMKVHY48RP7WXP4GHYBQ7SL9J9UNPHBP \ No newline at end of file diff --git a/StormLib/doc/d3-authenticationcode/d3-authenticationcode-enSG.txt b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-enSG.txt new file mode 100644 index 000000000..e6f1ec296 --- /dev/null +++ b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-enSG.txt @@ -0,0 +1 @@ +8MXLWHQ7VGGLTZ9MQZQSFDCLJYET3CPP \ No newline at end of file diff --git a/StormLib/doc/d3-authenticationcode/d3-authenticationcode-enUS.txt b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-enUS.txt new file mode 100644 index 000000000..8d73e61de --- /dev/null +++ b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-enUS.txt @@ -0,0 +1 @@ +EJ2R5TM6XFE2GUNG5QDGHKQ9UAKPWZSZ \ No newline at end of file diff --git a/StormLib/doc/d3-authenticationcode/d3-authenticationcode-esES.txt b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-esES.txt new file mode 100644 index 000000000..6b1b0a1b8 --- /dev/null +++ b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-esES.txt @@ -0,0 +1 @@ +PBGFBE42Z6LNK65UGJQ3WZVMCLP4HQQT \ No newline at end of file diff --git a/StormLib/doc/d3-authenticationcode/d3-authenticationcode-esMX.txt b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-esMX.txt new file mode 100644 index 000000000..504759e8d --- /dev/null +++ b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-esMX.txt @@ -0,0 +1 @@ +X7SEJJS9TSGCW5P28EBSC47AJPEY8VU2 \ No newline at end of file diff --git a/StormLib/doc/d3-authenticationcode/d3-authenticationcode-frFR.txt b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-frFR.txt new file mode 100644 index 000000000..bb35a2bfd --- /dev/null +++ b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-frFR.txt @@ -0,0 +1 @@ +5KVBQA8VYE6XRY3DLGC5ZDE4XS4P7YA2 \ No newline at end of file diff --git a/StormLib/doc/d3-authenticationcode/d3-authenticationcode-itIT.txt b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-itIT.txt new file mode 100644 index 000000000..a62031d38 --- /dev/null +++ b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-itIT.txt @@ -0,0 +1 @@ +478JD2K56EVNVVY4XX8TDWYT5B8KB254 \ No newline at end of file diff --git a/StormLib/doc/d3-authenticationcode/d3-authenticationcode-koKR.txt b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-koKR.txt new file mode 100644 index 000000000..296ffcc94 --- /dev/null +++ b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-koKR.txt @@ -0,0 +1 @@ +8TS4VNFQRZTN6YWHE9CHVDH9NVWD474A \ No newline at end of file diff --git a/StormLib/doc/d3-authenticationcode/d3-authenticationcode-plPL.txt b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-plPL.txt new file mode 100644 index 000000000..a92563c18 --- /dev/null +++ b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-plPL.txt @@ -0,0 +1 @@ +LJ52Z32DF4LZ4ZJJXVKK3AZQA6GABLJB \ No newline at end of file diff --git a/StormLib/doc/d3-authenticationcode/d3-authenticationcode-ptBR.txt b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-ptBR.txt new file mode 100644 index 000000000..e6e5c3568 --- /dev/null +++ b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-ptBR.txt @@ -0,0 +1 @@ +K6BDHY2ECUE2545YKNLBJPVYWHE7XYAG \ No newline at end of file diff --git a/StormLib/doc/d3-authenticationcode/d3-authenticationcode-zhTW.txt b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-zhTW.txt new file mode 100644 index 000000000..138a5449c --- /dev/null +++ b/StormLib/doc/d3-authenticationcode/d3-authenticationcode-zhTW.txt @@ -0,0 +1 @@ +6VWCQTN8V3ZZMRUCZXV8A8CGUX2TAA8H \ No newline at end of file diff --git a/StormLib/doc/hots-authenticationcode/hots-authenticationcode-bgdl.txt b/StormLib/doc/hots-authenticationcode/hots-authenticationcode-bgdl.txt new file mode 100644 index 000000000..6dfe0ee60 --- /dev/null +++ b/StormLib/doc/hots-authenticationcode/hots-authenticationcode-bgdl.txt @@ -0,0 +1 @@ +S48B6CDTN5XEQAKQDJNDLJBJ73FDFM3U \ No newline at end of file diff --git a/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-deDE.txt b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-deDE.txt new file mode 100644 index 000000000..029d733ea --- /dev/null +++ b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-deDE.txt @@ -0,0 +1 @@ +Y45MD3CAK4KXSSXHYD9VY64Z8EKJ4XFX \ No newline at end of file diff --git a/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-enGB.txt b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-enGB.txt new file mode 100644 index 000000000..7f66f8bba --- /dev/null +++ b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-enGB.txt @@ -0,0 +1 @@ +G8MN8UDG6NA2ANGY6A3DNY82HRGF29ZH \ No newline at end of file diff --git a/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-enUS.txt b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-enUS.txt new file mode 100644 index 000000000..0a4f5b8f6 --- /dev/null +++ b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-enUS.txt @@ -0,0 +1 @@ +3DH5RE5NVM5GTFD85LXGWT6FK859ETR5 \ No newline at end of file diff --git a/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-esES.txt b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-esES.txt new file mode 100644 index 000000000..fba8c8dc8 --- /dev/null +++ b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-esES.txt @@ -0,0 +1 @@ +8WLKUAXE94PFQU4Y249PAZ24N4R4XKTQ \ No newline at end of file diff --git a/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-esMX.txt b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-esMX.txt new file mode 100644 index 000000000..bb020c65e --- /dev/null +++ b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-esMX.txt @@ -0,0 +1 @@ +A34DXX3VHGGXSQBRFE5UFFDXMF9G4G54 \ No newline at end of file diff --git a/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-frFR.txt b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-frFR.txt new file mode 100644 index 000000000..37bcc4a41 --- /dev/null +++ b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-frFR.txt @@ -0,0 +1 @@ +ZG7J9K938HJEFWPQUA768MA2PFER6EAJ \ No newline at end of file diff --git a/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-itIT.txt b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-itIT.txt new file mode 100644 index 000000000..a665f6913 --- /dev/null +++ b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-itIT.txt @@ -0,0 +1 @@ +NE7CUNNNTVAPXV7E3G2BSVBWGVMW8BL2 \ No newline at end of file diff --git a/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-koKR.txt b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-koKR.txt new file mode 100644 index 000000000..e6346df30 --- /dev/null +++ b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-koKR.txt @@ -0,0 +1 @@ +3V9E2FTMBM9QQWK7U6MAMWAZWQDB838F \ No newline at end of file diff --git a/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-plPL.txt b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-plPL.txt new file mode 100644 index 000000000..564efc489 --- /dev/null +++ b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-plPL.txt @@ -0,0 +1 @@ +2NSFB8MELULJ83U6YHA3UP6K4MQD48L6 \ No newline at end of file diff --git a/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-ptBR.txt b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-ptBR.txt new file mode 100644 index 000000000..e8f8172d1 --- /dev/null +++ b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-ptBR.txt @@ -0,0 +1 @@ +QA2TZ9EWZ4CUU8BMB5WXCTY65F9CSW4E \ No newline at end of file diff --git a/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-ruRU.txt b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-ruRU.txt new file mode 100644 index 000000000..1b93b5be2 --- /dev/null +++ b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-ruRU.txt @@ -0,0 +1 @@ +VHB378W64BAT9SH7D68VV9NLQDK9YEGT \ No newline at end of file diff --git a/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-zhTW.txt b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-zhTW.txt new file mode 100644 index 000000000..409a8c142 --- /dev/null +++ b/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-zhTW.txt @@ -0,0 +1 @@ +U3NFQJV4M6GC7KBN9XQJ3BRDN3PLD9NE \ No newline at end of file diff --git a/StormLib/make-msvc.bat b/StormLib/make-msvc.bat new file mode 100644 index 000000000..9a2ea8e2f --- /dev/null +++ b/StormLib/make-msvc.bat @@ -0,0 +1,60 @@ +:: Build file for Visual Studio 2008 and 2017 +@echo off + +:: Save the values of INCLUDE, LIB and PATH +set SAVE_INCLUDE=%INCLUDE% +set SAVE_LIB=%LIB% +set SAVE_PATH=%PATH% +set LIB_NAME=StormLib + +:: Determine where the program files are, both for 64-bit and 32-bit Windows +if exist "%ProgramFiles%" set PROGRAM_FILES_DIR=%ProgramFiles% +if exist "%ProgramFiles(x86)%" set PROGRAM_FILES_DIR=%ProgramFiles(x86)% + +:: Determine the installed version of Visual Studio (Prioritize Enterprise over Professional) +if exist "%PROGRAM_FILES_DIR%\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" set VCVARS_2008=%PROGRAM_FILES_DIR%\Microsoft Visual Studio 9.0\VC\vcvarsall.bat +if exist "%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" set VCVARS_2017=%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat +if exist "%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvarsall.bat" set VCVARS_2017=%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvarsall.bat +if exist "%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" set VCVARS_2017=%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvarsall.bat +if exist "%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" set VCVARS_2019=%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat +if exist "%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvarsall.bat" set VCVARS_2019=%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvarsall.bat +if exist "%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" set VCVARS_2019=%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat + +::Build all libraries using Visual Studio 2008 and 2017 +call :BuildLibs "%VCVARS_2008%" x86 %LIB_NAME%_vs08.sln +call :BuildLibs "%VCVARS_2008%" x64 %LIB_NAME%_vs08.sln +call :BuildLibs "%VCVARS_2019%" x86 %LIB_NAME%_vs19.sln +call :BuildLibs "%VCVARS_2019%" x64 %LIB_NAME%_vs19.sln +goto:eof + +::----------------------------------------------------------------------------- +:: Build all 8 configurations of the library +:: +:: Parameters: +:: +:: %1 Full path to the VCVARS.BAT file +:: %2 Target build platform (x86 or x64) +:: %3 Plain name of the /sln solution file +:: + +:BuildLibs +::set VSCMD_DEBUG=1 +call %1 %2 +if "%2" == "x86" set SLN_TRG=Win32 +if "%2" == "x64" set SLN_TRG=x64 +devenv.com %3 /project "%LIB_NAME%" /rebuild "DebugAD|%SLN_TRG%" +devenv.com %3 /project "%LIB_NAME%" /rebuild "DebugAS|%SLN_TRG%" +devenv.com %3 /project "%LIB_NAME%" /rebuild "DebugUD|%SLN_TRG%" +devenv.com %3 /project "%LIB_NAME%" /rebuild "DebugUS|%SLN_TRG%" +devenv.com %3 /project "%LIB_NAME%" /rebuild "ReleaseAD|%SLN_TRG%" +devenv.com %3 /project "%LIB_NAME%" /rebuild "ReleaseAS|%SLN_TRG%" +devenv.com %3 /project "%LIB_NAME%" /rebuild "ReleaseUD|%SLN_TRG%" +devenv.com %3 /project "%LIB_NAME%" /rebuild "ReleaseUS|%SLN_TRG%" + +:: Restore environment variables to the old level +set INCLUDE=%SAVE_INCLUDE% +set LIB=%SAVE_LIB% +set PATH=%SAVE_PATH% +set VSINSTALLDIR= +set VCINSTALLDIR= +set DevEnvDir= diff --git a/StormLib/make.bat b/StormLib/make.bat new file mode 100644 index 000000000..8765eb597 --- /dev/null +++ b/StormLib/make.bat @@ -0,0 +1,46 @@ +@echo off +if not "x%WDKDIR%" == "x" goto SELECT_LIB +echo The WDKDIR environment variable is not set +echo Set this variable to your WDK directory (without ending backslash) +echo Example: set WDKDIR C:\WinDDK\6001 +pause +goto:eof + +:SELECT_LIB +set PROJECT_DIR=%~dp0 +set LIBRARY_NAME=StormLibWDK + +:PREPARE_SOURCES +echo Preparing sources ... +copy .\src\wdk\sources-cpp.cpp . >nul +copy .\src\wdk\sources-wdk-* . >nul +echo. + +:BUILD_LIB_32 +echo Building %LIBRARY_NAME%.lib (32-bit) ... +set DDKBUILDENV= +call %WDKDIR%\bin\setenv.bat %WDKDIR%\ fre w2k +cd %PROJECT_DIR% +build.exe -czgw +del buildfre_w2k_x86.log +echo. + +:BUILD_LIB_64 +echo Building %LIBRARY_NAME%.lib (64-bit) ... +set DDKBUILDENV= +call %WDKDIR%\bin\setenv.bat %WDKDIR%\ fre x64 WLH +cd %PROJECT_DIR% +build.exe -czgw +del buildfre_wlh_amd64.log +echo. + +:COPY_LIBS +copy /Y .\objfre_wlh_amd64\amd64\%LIBRARY_NAME%.lib ..\aaa\lib64\%LIBRARY_NAME%.lib >nul +copy /Y .\objfre_w2k_x86\i386\%LIBRARY_NAME%.lib ..\aaa\lib32\%LIBRARY_NAME%.lib >nul +copy /Y .\src\StormPort.h ..\aaa\inc >nul +copy /Y .\src\StormLib.h ..\aaa\inc >nul + +:CLEANUP +if exist sources-cpp.cpp del sources-cpp.cpp +if exist sources-wdk-* del sources-wdk-* +if exist build.bat del build.bat diff --git a/StormLib/sources b/StormLib/sources new file mode 100644 index 000000000..eaa49ad79 --- /dev/null +++ b/StormLib/sources @@ -0,0 +1,14 @@ +TARGETNAME=StormLibWDK +TARGETTYPE=LIBRARY +USE_MSVCRT=1 + +C_DEFINES=$(C_DEFINES) -DUNICODE -D_UNICODE -DWDK_BUILD + +SOURCES=sources-cpp.cpp \ + sources-wdk-bzip2.c \ + sources-wdk-ltc.c \ + sources-wdk-lzma.c \ + sources-wdk-misc.c \ + sources-wdk-tomcrypt.c \ + sources-wdk-tommath.c \ + sources-wdk-zlib.c diff --git a/StormLib/src/DllMain.c b/StormLib/src/DllMain.c new file mode 100644 index 000000000..98eb0038a --- /dev/null +++ b/StormLib/src/DllMain.c @@ -0,0 +1,24 @@ +/*****************************************************************************/ +/* DllMain.c Copyright (c) Ladislav Zezula 2006 */ +/*---------------------------------------------------------------------------*/ +/* Description: DllMain for the StormLib.dll library */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 23.11.06 1.00 Lad The first version of DllMain.c */ +/*****************************************************************************/ + +#define WIN32_LEAN_AND_MEAN +#include + +//----------------------------------------------------------------------------- +// DllMain + +BOOL WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved) +{ + UNREFERENCED_PARAMETER(hInst); + UNREFERENCED_PARAMETER(dwReason); + UNREFERENCED_PARAMETER(lpReserved); + + return TRUE; +} diff --git a/StormLib/src/DllMain.def b/StormLib/src/DllMain.def new file mode 100644 index 000000000..bce2877a3 --- /dev/null +++ b/StormLib/src/DllMain.def @@ -0,0 +1,79 @@ +; +; Export file for Windows +; Copyright (c) 2007-2010 Ladislav Zezula +; ladik@zezula.net +; + +LIBRARY StormLib.dll + +EXPORTS + + SFileSetLocale + SFileGetLocale + + SFileOpenArchive + SFileCreateArchive + SFileCreateArchive2 + SFileFlushArchive + SFileCloseArchive + + SFileAddListFile + + SFileSetCompactCallback + SFileCompactArchive + + SFileGetMaxFileCount + SFileSetMaxFileCount + + SFileGetAttributes + SFileSetAttributes + SFileUpdateFileAttributes + + SFileOpenPatchArchive + SFileIsPatchedArchive + + SFileOpenFileEx + SFileGetFileSize + SFileSetFilePointer + SFileReadFile + SFileCloseFile + + SFileHasFile + SFileGetFileName + SFileGetFileInfo + + SFileExtractFile + + SFileVerifyFile + SFileVerifyRawData + SFileVerifyArchive + + SFileFindFirstFile + SFileFindNextFile + SFileFindClose + + SListFileFindFirstFile + SListFileFindNextFile + SListFileFindClose + + SFileEnumLocales + + SFileCreateFile + SFileWriteFile + SFileFinishFile + SFileAddFileEx + SFileAddFile + SFileAddWave + SFileRemoveFile + SFileRenameFile + SFileSetFileLocale + SFileSetDataCompression + SFileSetAddFileCallback + + SCompImplode + SCompExplode + SCompCompress + SCompDecompress + + GetLastError=Kernel32.GetLastError + SetLastError=Kernel32.SetLastError diff --git a/StormLib/src/DllMain.rc b/StormLib/src/DllMain.rc new file mode 100644 index 000000000..27f43e252 --- /dev/null +++ b/StormLib/src/DllMain.rc @@ -0,0 +1,114 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1250) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 9,22,0,3 + PRODUCTVERSION 9,22,0,3 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040504b0" + BEGIN + VALUE "Comments", "http://www.zezula.net/mpq.html" + VALUE "FileDescription", "StormLib library for reading Blizzard MPQ archives" + VALUE "FileVersion", "9, 22, 0, 3\0" + VALUE "InternalName", "StormLib" + VALUE "LegalCopyright", "Copyright (c) 2014 - 2020 Ladislav Zezula" + VALUE "OriginalFilename", "StormLib.dll" + VALUE "ProductName", "StormLib" + VALUE "ProductVersion", "9, 22, 0, 3\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x405, 1200 + END +END + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// Czech resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY) +#ifdef _WIN32 +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT +#pragma code_page(1250) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Czech resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/StormLib/src/FileStream.cpp b/StormLib/src/FileStream.cpp new file mode 100644 index 000000000..da1d0438d --- /dev/null +++ b/StormLib/src/FileStream.cpp @@ -0,0 +1,2923 @@ +/*****************************************************************************/ +/* FileStream.cpp Copyright (c) Ladislav Zezula 2010 */ +/*---------------------------------------------------------------------------*/ +/* File stream support for StormLib */ +/* */ +/* Windows support: Written by Ladislav Zezula */ +/* Mac support: Written by Sam Wilkins */ +/* Linux support: Written by Sam Wilkins and Ivan Komissarov */ +/* Big-endian: Written & debugged by Sam Wilkins */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 11.06.10 1.00 Lad Derived from StormPortMac.cpp and StormPortLinux.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" +#include "FileStream.h" + +#ifdef _MSC_VER +#pragma comment(lib, "wininet.lib") // Internet functions for HTTP stream +#pragma warning(disable: 4800) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning) +#endif + +//----------------------------------------------------------------------------- +// Local defines + +#ifndef INVALID_HANDLE_VALUE +#define INVALID_HANDLE_VALUE ((HANDLE)-1) +#endif + +//----------------------------------------------------------------------------- +// Local functions - platform-specific functions + +#ifndef STORMLIB_WINDOWS +static thread_local DWORD dwLastError = ERROR_SUCCESS; + +DWORD GetLastError() +{ + return dwLastError; +} + +void SetLastError(DWORD dwErrCode) +{ + dwLastError = dwErrCode; +} +#endif + +static DWORD StringToInt(const char * szString) +{ + DWORD dwValue = 0; + + while('0' <= szString[0] && szString[0] <= '9') + { + dwValue = (dwValue * 10) + (szString[0] - '0'); + szString++; + } + + return dwValue; +} + +static void CreateNameWithSuffix(LPTSTR szBuffer, size_t cchMaxChars, LPCTSTR szName, unsigned int nValue) +{ + LPTSTR szBufferEnd = szBuffer + cchMaxChars - 1; + + // Copy the name + while(szBuffer < szBufferEnd && szName[0] != 0) + *szBuffer++ = *szName++; + + // Append "." + if(szBuffer < szBufferEnd) + *szBuffer++ = '.'; + + // Append the number + IntToString(szBuffer, szBufferEnd - szBuffer + 1, nValue); +} + +//----------------------------------------------------------------------------- +// Dummy init function + +static void BaseNone_Init(TFileStream *) +{ + // Nothing here +} + +//----------------------------------------------------------------------------- +// Local functions - base file support + +static bool BaseFile_Create(TFileStream * pStream) +{ +#ifdef STORMLIB_WINDOWS + { + DWORD dwWriteShare = (pStream->dwFlags & STREAM_FLAG_WRITE_SHARE) ? FILE_SHARE_WRITE : 0; + + pStream->Base.File.hFile = CreateFile(pStream->szFileName, + GENERIC_READ | GENERIC_WRITE, + dwWriteShare | FILE_SHARE_READ, + NULL, + CREATE_ALWAYS, + 0, + NULL); + if(pStream->Base.File.hFile == INVALID_HANDLE_VALUE) + return false; + } +#endif + +#if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX) + { + intptr_t handle; + + handle = open(pStream->szFileName, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if(handle == -1) + { + pStream->Base.File.hFile = INVALID_HANDLE_VALUE; + dwLastError = errno; + return false; + } + + pStream->Base.File.hFile = (HANDLE)handle; + } +#endif + + // Reset the file size and position + pStream->Base.File.FileSize = 0; + pStream->Base.File.FilePos = 0; + return true; +} + +static bool BaseFile_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD dwStreamFlags) +{ +#ifdef STORMLIB_WINDOWS + { + ULARGE_INTEGER FileSize; + DWORD dwWriteAccess = (dwStreamFlags & STREAM_FLAG_READ_ONLY) ? 0 : FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES; + DWORD dwWriteShare = (dwStreamFlags & STREAM_FLAG_WRITE_SHARE) ? FILE_SHARE_WRITE : 0; + + // Open the file + pStream->Base.File.hFile = CreateFile(szFileName, + FILE_READ_DATA | FILE_READ_ATTRIBUTES | dwWriteAccess, + FILE_SHARE_READ | dwWriteShare, + NULL, + OPEN_EXISTING, + 0, + NULL); + if(pStream->Base.File.hFile == INVALID_HANDLE_VALUE) + return false; + + // Query the file size + FileSize.LowPart = GetFileSize(pStream->Base.File.hFile, &FileSize.HighPart); + pStream->Base.File.FileSize = FileSize.QuadPart; + + // Query last write time + GetFileTime(pStream->Base.File.hFile, NULL, NULL, (LPFILETIME)&pStream->Base.File.FileTime); + } +#endif + +#if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX) + { + struct stat64 fileinfo; + int oflag = (dwStreamFlags & STREAM_FLAG_READ_ONLY) ? O_RDONLY : O_RDWR; + intptr_t handle; + + // Open the file + handle = open(szFileName, oflag | O_LARGEFILE); + if(handle == -1) + { + pStream->Base.File.hFile = INVALID_HANDLE_VALUE; + dwLastError = errno; + return false; + } + + // Get the file size + if(fstat64(handle, &fileinfo) == -1) + { + pStream->Base.File.hFile = INVALID_HANDLE_VALUE; + dwLastError = errno; + close(handle); + return false; + } + + // time_t is number of seconds since 1.1.1970, UTC. + // 1 second = 10000000 (decimal) in FILETIME + // Set the start to 1.1.1970 00:00:00 + pStream->Base.File.FileTime = 0x019DB1DED53E8000ULL + (10000000 * fileinfo.st_mtime); + pStream->Base.File.FileSize = (ULONGLONG)fileinfo.st_size; + pStream->Base.File.hFile = (HANDLE)handle; + } +#endif + + // Reset the file position + pStream->Base.File.FilePos = 0; + return true; +} + +static bool BaseFile_Read( + TFileStream * pStream, // Pointer to an open stream + ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position + void * pvBuffer, // Pointer to data to be read + DWORD dwBytesToRead) // Number of bytes to read from the file +{ + ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos; + DWORD dwBytesRead = 0; // Must be set by platform-specific code + +#ifdef STORMLIB_WINDOWS + { + // Note: StormLib no longer supports Windows 9x. + // Thus, we can use the OVERLAPPED structure to specify + // file offset to read from file. This allows us to skip + // one system call to SetFilePointer + + // Update the byte offset + pStream->Base.File.FilePos = ByteOffset; + + // Read the data + if(dwBytesToRead != 0) + { + OVERLAPPED Overlapped; + + Overlapped.OffsetHigh = (DWORD)(ByteOffset >> 32); + Overlapped.Offset = (DWORD)ByteOffset; + Overlapped.hEvent = NULL; + if(!ReadFile(pStream->Base.File.hFile, pvBuffer, dwBytesToRead, &dwBytesRead, &Overlapped)) + return false; + } + } +#endif + +#if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX) + { + ssize_t bytes_read; + + // If the byte offset is different from the current file position, + // we have to update the file position xxx + if(ByteOffset != pStream->Base.File.FilePos) + { + lseek64((intptr_t)pStream->Base.File.hFile, (off64_t)(ByteOffset), SEEK_SET); + pStream->Base.File.FilePos = ByteOffset; + } + + // Perform the read operation + if(dwBytesToRead != 0) + { + bytes_read = read((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToRead); + if(bytes_read == -1) + { + dwLastError = errno; + return false; + } + + dwBytesRead = (DWORD)(size_t)bytes_read; + } + } +#endif + + // Increment the current file position by number of bytes read + // If the number of bytes read doesn't match to required amount, return false + pStream->Base.File.FilePos = ByteOffset + dwBytesRead; + if(dwBytesRead != dwBytesToRead) + SetLastError(ERROR_HANDLE_EOF); + return (dwBytesRead == dwBytesToRead); +} + +/** + * \a pStream Pointer to an open stream + * \a pByteOffset Pointer to file byte offset. If NULL, writes to current position + * \a pvBuffer Pointer to data to be written + * \a dwBytesToWrite Number of bytes to write to the file + */ + +static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite) +{ + ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos; + DWORD dwBytesWritten = 0; // Must be set by platform-specific code + +#ifdef STORMLIB_WINDOWS + { + // Note: StormLib no longer supports Windows 9x. + // Thus, we can use the OVERLAPPED structure to specify + // file offset to read from file. This allows us to skip + // one system call to SetFilePointer + + // Update the byte offset + pStream->Base.File.FilePos = ByteOffset; + + // Read the data + if(dwBytesToWrite != 0) + { + OVERLAPPED Overlapped; + + Overlapped.OffsetHigh = (DWORD)(ByteOffset >> 32); + Overlapped.Offset = (DWORD)ByteOffset; + Overlapped.hEvent = NULL; + if(!WriteFile(pStream->Base.File.hFile, pvBuffer, dwBytesToWrite, &dwBytesWritten, &Overlapped)) + return false; + } + } +#endif + +#if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX) + { + ssize_t bytes_written; + + // If the byte offset is different from the current file position, + // we have to update the file position + if(ByteOffset != pStream->Base.File.FilePos) + { + lseek64((intptr_t)pStream->Base.File.hFile, (off64_t)(ByteOffset), SEEK_SET); + pStream->Base.File.FilePos = ByteOffset; + } + + // Perform the read operation + bytes_written = write((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToWrite); + if(bytes_written == -1) + { + dwLastError = errno; + return false; + } + + dwBytesWritten = (DWORD)(size_t)bytes_written; + } +#endif + + // Increment the current file position by number of bytes read + pStream->Base.File.FilePos = ByteOffset + dwBytesWritten; + + // Also modify the file size, if needed + if(pStream->Base.File.FilePos > pStream->Base.File.FileSize) + pStream->Base.File.FileSize = pStream->Base.File.FilePos; + + if(dwBytesWritten != dwBytesToWrite) + SetLastError(ERROR_DISK_FULL); + return (dwBytesWritten == dwBytesToWrite); +} + +/** + * \a pStream Pointer to an open stream + * \a NewFileSize New size of the file + */ +static bool BaseFile_Resize(TFileStream * pStream, ULONGLONG NewFileSize) +{ +#ifdef STORMLIB_WINDOWS + { + LONG FileSizeHi = (LONG)(NewFileSize >> 32); + LONG FileSizeLo; + DWORD dwNewPos; + bool bResult; + + // Set the position at the new file size + dwNewPos = SetFilePointer(pStream->Base.File.hFile, (LONG)NewFileSize, &FileSizeHi, FILE_BEGIN); + if(dwNewPos == INVALID_SET_FILE_POINTER && GetLastError() != ERROR_SUCCESS) + return false; + + // Set the current file pointer as the end of the file + bResult = (bool)SetEndOfFile(pStream->Base.File.hFile); + if(bResult) + pStream->Base.File.FileSize = NewFileSize; + + // Restore the file position + FileSizeHi = (LONG)(pStream->Base.File.FilePos >> 32); + FileSizeLo = (LONG)(pStream->Base.File.FilePos); + SetFilePointer(pStream->Base.File.hFile, FileSizeLo, &FileSizeHi, FILE_BEGIN); + return bResult; + } +#endif + +#if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX) + { + if(ftruncate64((intptr_t)pStream->Base.File.hFile, (off64_t)NewFileSize) == -1) + { + dwLastError = errno; + return false; + } + + pStream->Base.File.FileSize = NewFileSize; + return true; + } +#endif +} + +// Gives the current file size +static bool BaseFile_GetSize(TFileStream * pStream, ULONGLONG * pFileSize) +{ + // Note: Used by all thre base providers. + // Requires the TBaseData union to have the same layout for all three base providers + *pFileSize = pStream->Base.File.FileSize; + return true; +} + +// Gives the current file position +static bool BaseFile_GetPos(TFileStream * pStream, ULONGLONG * pByteOffset) +{ + // Note: Used by all thre base providers. + // Requires the TBaseData union to have the same layout for all three base providers + *pByteOffset = pStream->Base.File.FilePos; + return true; +} + +// Renames the file pointed by pStream so that it contains data from pNewStream +static bool BaseFile_Replace(TFileStream * pStream, TFileStream * pNewStream) +{ +#ifdef STORMLIB_WINDOWS + // Delete the original stream file. Don't check the result value, + // because if the file doesn't exist, it would fail + DeleteFile(pStream->szFileName); + + // Rename the new file to the old stream's file + return (bool)MoveFile(pNewStream->szFileName, pStream->szFileName); +#endif + +#if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX) + // "rename" on Linux also works if the target file exists + if(rename(pNewStream->szFileName, pStream->szFileName) == -1) + { + dwLastError = errno; + return false; + } + + return true; +#endif +} + +static void BaseFile_Close(TFileStream * pStream) +{ + if(pStream->Base.File.hFile != INVALID_HANDLE_VALUE) + { +#ifdef STORMLIB_WINDOWS + CloseHandle(pStream->Base.File.hFile); +#endif + +#if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX) + close((intptr_t)pStream->Base.File.hFile); +#endif + } + + // Also invalidate the handle + pStream->Base.File.hFile = INVALID_HANDLE_VALUE; +} + +// Initializes base functions for the disk file +static void BaseFile_Init(TFileStream * pStream) +{ + pStream->BaseCreate = BaseFile_Create; + pStream->BaseOpen = BaseFile_Open; + pStream->BaseRead = BaseFile_Read; + pStream->BaseWrite = BaseFile_Write; + pStream->BaseResize = BaseFile_Resize; + pStream->BaseGetSize = BaseFile_GetSize; + pStream->BaseGetPos = BaseFile_GetPos; + pStream->BaseClose = BaseFile_Close; +} + +//----------------------------------------------------------------------------- +// Local functions - base memory-mapped file support + +#ifdef STORMLIB_WINDOWS + +typedef struct _SECTION_BASIC_INFORMATION +{ + PVOID BaseAddress; + ULONG Attributes; + LARGE_INTEGER Size; +} SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION; + +typedef ULONG (WINAPI * NTQUERYSECTION)( + IN HANDLE SectionHandle, + IN ULONG SectionInformationClass, + OUT PVOID SectionInformation, + IN SIZE_T Length, + OUT PSIZE_T ResultLength); + +static bool RetrieveFileMappingSize(HANDLE hSection, ULARGE_INTEGER & RefFileSize) +{ + SECTION_BASIC_INFORMATION BasicInfo = {0}; + NTQUERYSECTION PfnQuerySection; + HMODULE hNtdll; + SIZE_T ReturnLength = 0; + + if((hNtdll = GetModuleHandle(_T("ntdll.dll"))) != NULL) + { + PfnQuerySection = (NTQUERYSECTION)GetProcAddress(hNtdll, "NtQuerySection"); + if(PfnQuerySection != NULL) + { + if(PfnQuerySection(hSection, 0, &BasicInfo, sizeof(SECTION_BASIC_INFORMATION), &ReturnLength) == 0) + { + RefFileSize.HighPart = BasicInfo.Size.HighPart; + RefFileSize.LowPart = BasicInfo.Size.LowPart; + return true; + } + } + } + + return false; +} +#endif + +static bool BaseMap_Open(TFileStream * pStream, LPCTSTR szFileName, DWORD dwStreamFlags) +{ +#ifdef STORMLIB_WINDOWS + + ULARGE_INTEGER FileSize = {0}; + HANDLE hFile = INVALID_HANDLE_VALUE; + HANDLE hMap = NULL; + bool bResult = false; + + // Keep compiler happy + dwStreamFlags = dwStreamFlags; + + // 1) Try to treat "szFileName" as a section name + hMap = OpenFileMapping(SECTION_QUERY | FILE_MAP_READ, FALSE, szFileName); + if(hMap != NULL) + { + // Try to retrieve the size of the mapping + if(!RetrieveFileMappingSize(hMap, FileSize)) + { + CloseHandle(hMap); + hMap = NULL; + } + } + + // 2) Treat the name as file name + else + { + hFile = CreateFile(szFileName, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if(hFile != INVALID_HANDLE_VALUE) + { + // Retrieve file size. Don't allow mapping file of a zero size. + FileSize.LowPart = GetFileSize(hFile, &FileSize.HighPart); + if(FileSize.QuadPart != 0) + { + // Now create file mapping over the file + hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); + } + } + } + + // Did it succeed? + if(hMap != NULL) + { + // Map the entire view into memory + // Note that this operation will fail if the file can't fit + // into usermode address space + pStream->Base.Map.pbFile = (LPBYTE)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0); + if(pStream->Base.Map.pbFile != NULL) + { + // Retrieve file time. If it's named section, put 0 + if(hFile != INVALID_HANDLE_VALUE) + GetFileTime(hFile, NULL, NULL, (LPFILETIME)&pStream->Base.Map.FileTime); + + // Retrieve file size and position + pStream->Base.Map.FileSize = FileSize.QuadPart; + pStream->Base.Map.FilePos = 0; + bResult = true; + } + + // Close the map handle + CloseHandle(hMap); + } + + // Close the file handle + if(hFile != INVALID_HANDLE_VALUE) + CloseHandle(hFile); + + // Return the result of the operation + return bResult; + +#elif defined(STORMLIB_HAS_MMAP) + + struct stat64 fileinfo; + intptr_t handle; + bool bResult = false; + + // Open the file + handle = open(szFileName, O_RDONLY); + if(handle != -1) + { + // Get the file size + if(fstat64(handle, &fileinfo) != -1) + { + pStream->Base.Map.pbFile = (LPBYTE)mmap(NULL, (size_t)fileinfo.st_size, PROT_READ, MAP_PRIVATE, handle, 0); + if(pStream->Base.Map.pbFile != NULL) + { + // time_t is number of seconds since 1.1.1970, UTC. + // 1 second = 10000000 (decimal) in FILETIME + // Set the start to 1.1.1970 00:00:00 + pStream->Base.Map.FileTime = 0x019DB1DED53E8000ULL + (10000000 * fileinfo.st_mtime); + pStream->Base.Map.FileSize = (ULONGLONG)fileinfo.st_size; + pStream->Base.Map.FilePos = 0; + bResult = true; + } + } + close(handle); + } + + // Did the mapping fail? + if(bResult == false) + dwLastError = errno; + return bResult; + +#else + + // File mapping is not supported + return false; + +#endif +} + +static bool BaseMap_Read( + TFileStream * pStream, // Pointer to an open stream + ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position + void * pvBuffer, // Pointer to data to be read + DWORD dwBytesToRead) // Number of bytes to read from the file +{ + ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.Map.FilePos; + + // Do we have to read anything at all? + if(dwBytesToRead != 0) + { + // Don't allow reading past file size + if((ByteOffset + dwBytesToRead) > pStream->Base.Map.FileSize) + return false; + + // Copy the required data + memcpy(pvBuffer, pStream->Base.Map.pbFile + (size_t)ByteOffset, dwBytesToRead); + } + + // Move the current file position + pStream->Base.Map.FilePos += dwBytesToRead; + return true; +} + +static void BaseMap_Close(TFileStream * pStream) +{ + +#ifdef STORMLIB_WINDOWS + + if(pStream->Base.Map.pbFile != NULL) + UnmapViewOfFile(pStream->Base.Map.pbFile); + +#elif defined(STORMLIB_HAS_MMAP) + + if(pStream->Base.Map.pbFile != NULL) + munmap(pStream->Base.Map.pbFile, (size_t )pStream->Base.Map.FileSize); + +#endif + + pStream->Base.Map.pbFile = NULL; +} + +// Initializes base functions for the mapped file +static void BaseMap_Init(TFileStream * pStream) +{ + // Supply the file stream functions + pStream->BaseOpen = BaseMap_Open; + pStream->BaseRead = BaseMap_Read; + pStream->BaseGetSize = BaseFile_GetSize; // Reuse BaseFile function + pStream->BaseGetPos = BaseFile_GetPos; // Reuse BaseFile function + pStream->BaseClose = BaseMap_Close; + + // Mapped files are read-only + pStream->dwFlags |= STREAM_FLAG_READ_ONLY; +} + +//----------------------------------------------------------------------------- +// Local functions - base HTTP file support + +static const TCHAR * BaseHttp_ExtractServerName(const TCHAR * szFileName, TCHAR * szServerName) +{ + // Check for HTTP + if(!_tcsnicmp(szFileName, _T("http://"), 7)) + szFileName += 7; + + // Cut off the server name + if(szServerName != NULL) + { + while(szFileName[0] != 0 && szFileName[0] != _T('/')) + *szServerName++ = *szFileName++; + *szServerName = 0; + } + else + { + while(szFileName[0] != 0 && szFileName[0] != _T('/')) + szFileName++; + } + + // Return the remainder + return szFileName; +} + +static bool BaseHttp_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD dwStreamFlags) +{ +#ifdef STORMLIB_WINDOWS + + HINTERNET hRequest; + DWORD dwTemp = 0; + + // Keep compiler happy + dwStreamFlags = dwStreamFlags; + + // Don't connect to the internet + if(!InternetGetConnectedState(&dwTemp, 0)) + return false; + + // Initiate the connection to the internet + pStream->Base.Http.hInternet = InternetOpen(_T("StormLib HTTP MPQ reader"), + INTERNET_OPEN_TYPE_PRECONFIG, + NULL, + NULL, + 0); + if(pStream->Base.Http.hInternet != NULL) + { + TCHAR szServerName[MAX_PATH]; + DWORD dwFlags = INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_UI | INTERNET_FLAG_NO_CACHE_WRITE; + + // Initiate connection with the server + szFileName = BaseHttp_ExtractServerName(szFileName, szServerName); + pStream->Base.Http.hConnect = InternetConnect(pStream->Base.Http.hInternet, + szServerName, + INTERNET_DEFAULT_HTTP_PORT, + NULL, + NULL, + INTERNET_SERVICE_HTTP, + dwFlags, + 0); + if(pStream->Base.Http.hConnect != NULL) + { + // Open HTTP request to the file + hRequest = HttpOpenRequest(pStream->Base.Http.hConnect, _T("GET"), szFileName, NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0); + if(hRequest != NULL) + { + if(HttpSendRequest(hRequest, NULL, 0, NULL, 0)) + { + ULONGLONG FileTime = 0; + DWORD dwFileSize = 0; + DWORD dwDataSize; + DWORD dwIndex = 0; + TCHAR StatusCode[0x08]; + + // Check if the file succeeded to open + dwDataSize = sizeof(StatusCode); + if(HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE, StatusCode, &dwDataSize, &dwIndex)) + { + if(_tcscmp(StatusCode, _T("200"))) + { + InternetCloseHandle(hRequest); + SetLastError(ERROR_FILE_NOT_FOUND); + return false; + } + } + + // Check if the MPQ has Last Modified field + dwDataSize = sizeof(ULONGLONG); + if(HttpQueryInfo(hRequest, HTTP_QUERY_LAST_MODIFIED | HTTP_QUERY_FLAG_SYSTEMTIME, &FileTime, &dwDataSize, &dwIndex)) + pStream->Base.Http.FileTime = FileTime; + + // Verify if the server supports random access + dwDataSize = sizeof(DWORD); + if(HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &dwFileSize, &dwDataSize, &dwIndex)) + { + if(dwFileSize != 0) + { + InternetCloseHandle(hRequest); + pStream->Base.Http.FileSize = dwFileSize; + pStream->Base.Http.FilePos = 0; + return true; + } + } + } + + // Close the request + InternetCloseHandle(hRequest); + } + + // Close the connection handle + InternetCloseHandle(pStream->Base.Http.hConnect); + pStream->Base.Http.hConnect = NULL; + } + + // Close the internet handle + InternetCloseHandle(pStream->Base.Http.hInternet); + pStream->Base.Http.hInternet = NULL; + } + + // If the file is not there or is not available for random access, report error + pStream->BaseClose(pStream); + return false; + +#else + + // Not supported + SetLastError(ERROR_NOT_SUPPORTED); + pStream = pStream; + return false; + +#endif +} + +static bool BaseHttp_Read( + TFileStream * pStream, // Pointer to an open stream + ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position + void * pvBuffer, // Pointer to data to be read + DWORD dwBytesToRead) // Number of bytes to read from the file +{ +#ifdef STORMLIB_WINDOWS + ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.Http.FilePos; + DWORD dwTotalBytesRead = 0; + + // Do we have to read anything at all? + if(dwBytesToRead != 0) + { + HINTERNET hRequest; + LPCTSTR szFileName; + LPBYTE pbBuffer = (LPBYTE)pvBuffer; + TCHAR szRangeRequest[0x80]; + DWORD dwStartOffset = (DWORD)ByteOffset; + DWORD dwEndOffset = dwStartOffset + dwBytesToRead; + + // Open HTTP request to the file + szFileName = BaseHttp_ExtractServerName(pStream->szFileName, NULL); + hRequest = HttpOpenRequest(pStream->Base.Http.hConnect, _T("GET"), szFileName, NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0); + if(hRequest != NULL) + { + // Add range request to the HTTP headers + // http://www.clevercomponents.com/articles/article015/resuming.asp + wsprintf(szRangeRequest, _T("Range: bytes=%u-%u"), (unsigned int)dwStartOffset, (unsigned int)dwEndOffset); + HttpAddRequestHeaders(hRequest, szRangeRequest, 0xFFFFFFFF, HTTP_ADDREQ_FLAG_ADD_IF_NEW); + + // Send the request to the server + if(HttpSendRequest(hRequest, NULL, 0, NULL, 0)) + { + while(dwTotalBytesRead < dwBytesToRead) + { + DWORD dwBlockBytesToRead = dwBytesToRead - dwTotalBytesRead; + DWORD dwBlockBytesRead = 0; + + // Read the block from the file + if(dwBlockBytesToRead > 0x200) + dwBlockBytesToRead = 0x200; + InternetReadFile(hRequest, pbBuffer, dwBlockBytesToRead, &dwBlockBytesRead); + + // Check for end + if(dwBlockBytesRead == 0) + break; + + // Move buffers + dwTotalBytesRead += dwBlockBytesRead; + pbBuffer += dwBlockBytesRead; + } + } + InternetCloseHandle(hRequest); + } + } + + // Increment the current file position by number of bytes read + pStream->Base.Http.FilePos = ByteOffset + dwTotalBytesRead; + + // If the number of bytes read doesn't match the required amount, return false + if(dwTotalBytesRead != dwBytesToRead) + SetLastError(ERROR_HANDLE_EOF); + return (dwTotalBytesRead == dwBytesToRead); + +#else + + // Not supported + pStream = pStream; + pByteOffset = pByteOffset; + pvBuffer = pvBuffer; + dwBytesToRead = dwBytesToRead; + SetLastError(ERROR_NOT_SUPPORTED); + return false; + +#endif +} + +static void BaseHttp_Close(TFileStream * pStream) +{ +#ifdef STORMLIB_WINDOWS + if(pStream->Base.Http.hConnect != NULL) + InternetCloseHandle(pStream->Base.Http.hConnect); + pStream->Base.Http.hConnect = NULL; + + if(pStream->Base.Http.hInternet != NULL) + InternetCloseHandle(pStream->Base.Http.hInternet); + pStream->Base.Http.hInternet = NULL; +#else + pStream = pStream; +#endif +} + +// Initializes base functions for the mapped file +static void BaseHttp_Init(TFileStream * pStream) +{ + // Supply the stream functions + pStream->BaseOpen = BaseHttp_Open; + pStream->BaseRead = BaseHttp_Read; + pStream->BaseGetSize = BaseFile_GetSize; // Reuse BaseFile function + pStream->BaseGetPos = BaseFile_GetPos; // Reuse BaseFile function + pStream->BaseClose = BaseHttp_Close; + + // HTTP files are read-only + pStream->dwFlags |= STREAM_FLAG_READ_ONLY; +} + +//----------------------------------------------------------------------------- +// Local functions - base block-based support + +// Generic function that loads blocks from the file +// The function groups the block with the same availability, +// so the called BlockRead can finish the request in a single system call +static bool BlockStream_Read( + TBlockStream * pStream, // Pointer to an open stream + ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position + void * pvBuffer, // Pointer to data to be read + DWORD dwBytesToRead) // Number of bytes to read from the file +{ + ULONGLONG BlockOffset0; + ULONGLONG BlockOffset; + ULONGLONG ByteOffset; + ULONGLONG EndOffset; + LPBYTE TransferBuffer; + LPBYTE BlockBuffer; + DWORD BlockBufferOffset; // Offset of the desired data in the block buffer + DWORD BytesNeeded; // Number of bytes that really need to be read + DWORD BlockSize = pStream->BlockSize; + DWORD BlockCount; + bool bPrevBlockAvailable; + bool bCallbackCalled = false; + bool bBlockAvailable; + bool bResult = true; + + // The base block read function must be present + assert(pStream->BlockRead != NULL); + + // NOP reading of zero bytes + if(dwBytesToRead == 0) + return true; + + // Get the current position in the stream + ByteOffset = (pByteOffset != NULL) ? pByteOffset[0] : pStream->StreamPos; + EndOffset = ByteOffset + dwBytesToRead; + if(EndOffset > pStream->StreamSize) + { + SetLastError(ERROR_HANDLE_EOF); + return false; + } + + // Calculate the block parameters + BlockOffset0 = BlockOffset = ByteOffset & ~((ULONGLONG)BlockSize - 1); + BlockCount = (DWORD)(((EndOffset - BlockOffset) + (BlockSize - 1)) / BlockSize); + BytesNeeded = (DWORD)(EndOffset - BlockOffset); + + // Remember where we have our data + assert((BlockSize & (BlockSize - 1)) == 0); + BlockBufferOffset = (DWORD)(ByteOffset & (BlockSize - 1)); + + // Allocate buffer for reading blocks + TransferBuffer = BlockBuffer = STORM_ALLOC(BYTE, (BlockCount * BlockSize)); + if(TransferBuffer == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return false; + } + + // If all blocks are available, just read all blocks at once + if(pStream->IsComplete == 0) + { + // Now parse the blocks and send the block read request + // to all blocks with the same availability + assert(pStream->BlockCheck != NULL); + bPrevBlockAvailable = pStream->BlockCheck(pStream, BlockOffset); + + // Loop as long as we have something to read + while(BlockOffset < EndOffset) + { + // Determine availability of the next block + bBlockAvailable = pStream->BlockCheck(pStream, BlockOffset); + + // If the availability has changed, read all blocks up to this one + if(bBlockAvailable != bPrevBlockAvailable) + { + // Call the file stream callback, if the block is not available + if(pStream->pMaster && pStream->pfnCallback && bPrevBlockAvailable == false) + { + pStream->pfnCallback(pStream->UserData, BlockOffset0, (DWORD)(BlockOffset - BlockOffset0)); + bCallbackCalled = true; + } + + // Load the continuous blocks with the same availability + assert(BlockOffset > BlockOffset0); + bResult = pStream->BlockRead(pStream, BlockOffset0, BlockOffset, BlockBuffer, BytesNeeded, bPrevBlockAvailable); + if(!bResult) + break; + + // Move the block offset + BlockBuffer += (DWORD)(BlockOffset - BlockOffset0); + BytesNeeded -= (DWORD)(BlockOffset - BlockOffset0); + bPrevBlockAvailable = bBlockAvailable; + BlockOffset0 = BlockOffset; + } + + // Move to the block offset in the stream + BlockOffset += BlockSize; + } + + // If there is a block(s) remaining to be read, do it + if(BlockOffset > BlockOffset0) + { + // Call the file stream callback, if the block is not available + if(pStream->pMaster && pStream->pfnCallback && bPrevBlockAvailable == false) + { + pStream->pfnCallback(pStream->UserData, BlockOffset0, (DWORD)(BlockOffset - BlockOffset0)); + bCallbackCalled = true; + } + + // Read the complete blocks from the file + if(BlockOffset > pStream->StreamSize) + BlockOffset = pStream->StreamSize; + bResult = pStream->BlockRead(pStream, BlockOffset0, BlockOffset, BlockBuffer, BytesNeeded, bPrevBlockAvailable); + } + } + else + { + // Read the complete blocks from the file + if(EndOffset > pStream->StreamSize) + EndOffset = pStream->StreamSize; + bResult = pStream->BlockRead(pStream, BlockOffset, EndOffset, BlockBuffer, BytesNeeded, true); + } + + // Now copy the data to the user buffer + if(bResult) + { + memcpy(pvBuffer, TransferBuffer + BlockBufferOffset, dwBytesToRead); + pStream->StreamPos = ByteOffset + dwBytesToRead; + } + else + { + // If the block read failed, set the last error + SetLastError(ERROR_FILE_INCOMPLETE); + } + + // Call the callback to indicate we are done + if(bCallbackCalled) + pStream->pfnCallback(pStream->UserData, 0, 0); + + // Free the block buffer and return + STORM_FREE(TransferBuffer); + return bResult; +} + +static bool BlockStream_GetSize(TFileStream * pStream, ULONGLONG * pFileSize) +{ + *pFileSize = pStream->StreamSize; + return true; +} + +static bool BlockStream_GetPos(TFileStream * pStream, ULONGLONG * pByteOffset) +{ + *pByteOffset = pStream->StreamPos; + return true; +} + +static void BlockStream_Close(TBlockStream * pStream) +{ + // Free the data map, if any + if(pStream->FileBitmap != NULL) + STORM_FREE(pStream->FileBitmap); + pStream->FileBitmap = NULL; + + // Call the base class for closing the stream + pStream->BaseClose(pStream); +} + +//----------------------------------------------------------------------------- +// File stream allocation function + +static STREAM_INIT StreamBaseInit[4] = +{ + BaseFile_Init, + BaseMap_Init, + BaseHttp_Init, + BaseNone_Init +}; + +// This function allocates an empty structure for the file stream +// The stream structure is created as flat block, variable length +// The file name is placed after the end of the stream structure data +static TFileStream * AllocateFileStream( + const TCHAR * szFileName, + size_t StreamSize, + DWORD dwStreamFlags) +{ + TFileStream * pMaster = NULL; + TFileStream * pStream; + const TCHAR * szNextFile = szFileName; + size_t FileNameSize; + + // Sanity check + assert(StreamSize != 0); + + // The caller can specify chain of files in the following form: + // C:\archive.MPQ*http://www.server.com/MPQs/archive-server.MPQ + // In that case, we use the part after "*" as master file name + while(szNextFile[0] != 0 && szNextFile[0] != _T('*')) + szNextFile++; + FileNameSize = (size_t)((szNextFile - szFileName) * sizeof(TCHAR)); + + // If we have a next file, we need to open it as master stream + // Note that we don't care if the master stream exists or not, + // If it doesn't, later attempts to read missing file block will fail + if(szNextFile[0] == _T('*')) + { + // Don't allow another master file in the string + if(_tcschr(szNextFile + 1, _T('*')) != NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + // Open the master file + pMaster = FileStream_OpenFile(szNextFile + 1, STREAM_FLAG_READ_ONLY); + } + + // Allocate the stream structure for the given stream type + pStream = (TFileStream *)STORM_ALLOC(BYTE, StreamSize + FileNameSize + sizeof(TCHAR)); + if(pStream != NULL) + { + // Zero the entire structure + memset(pStream, 0, StreamSize); + pStream->pMaster = pMaster; + pStream->dwFlags = dwStreamFlags; + + // Initialize the file name + pStream->szFileName = (TCHAR *)((BYTE *)pStream + StreamSize); + memcpy(pStream->szFileName, szFileName, FileNameSize); + pStream->szFileName[FileNameSize / sizeof(TCHAR)] = 0; + + // Initialize the stream functions + StreamBaseInit[dwStreamFlags & 0x03](pStream); + } + + return pStream; +} + +//----------------------------------------------------------------------------- +// Local functions - flat stream support + +static DWORD FlatStream_CheckFile(TBlockStream * pStream) +{ + LPBYTE FileBitmap = (LPBYTE)pStream->FileBitmap; + DWORD WholeByteCount = (pStream->BlockCount / 8); + DWORD ExtraBitsCount = (pStream->BlockCount & 7); + BYTE ExpectedValue; + + // Verify the whole bytes - their value must be 0xFF + for(DWORD i = 0; i < WholeByteCount; i++) + { + if(FileBitmap[i] != 0xFF) + return 0; + } + + // If there are extra bits, calculate the mask + if(ExtraBitsCount != 0) + { + ExpectedValue = (BYTE)((1 << ExtraBitsCount) - 1); + if(FileBitmap[WholeByteCount] != ExpectedValue) + return 0; + } + + // Yes, the file is complete + return 1; +} + +static bool FlatStream_LoadBitmap(TBlockStream * pStream) +{ + FILE_BITMAP_FOOTER Footer; + ULONGLONG ByteOffset; + LPBYTE FileBitmap; + DWORD BlockCount; + DWORD BitmapSize; + + // Do not load the bitmap if we should not have to + if(!(pStream->dwFlags & STREAM_FLAG_USE_BITMAP)) + return false; + + // Only if the size is greater than size of bitmap footer + if(pStream->Base.File.FileSize > sizeof(FILE_BITMAP_FOOTER)) + { + // Load the bitmap footer + ByteOffset = pStream->Base.File.FileSize - sizeof(FILE_BITMAP_FOOTER); + if(pStream->BaseRead(pStream, &ByteOffset, &Footer, sizeof(FILE_BITMAP_FOOTER))) + { + // Make sure that the array is properly BSWAP-ed + BSWAP_ARRAY32_UNSIGNED((LPDWORD)(&Footer), sizeof(FILE_BITMAP_FOOTER)); + + // Verify if there is actually a footer + if(Footer.Signature == ID_FILE_BITMAP_FOOTER && Footer.Version == 0x03) + { + // Get the offset of the bitmap, number of blocks and size of the bitmap + ByteOffset = MAKE_OFFSET64(Footer.MapOffsetHi, Footer.MapOffsetLo); + BlockCount = (DWORD)(((ByteOffset - 1) / Footer.BlockSize) + 1); + BitmapSize = ((BlockCount + 7) / 8); + + // Check if the sizes match + if(ByteOffset + BitmapSize + sizeof(FILE_BITMAP_FOOTER) == pStream->Base.File.FileSize) + { + // Allocate space for the bitmap + FileBitmap = STORM_ALLOC(BYTE, BitmapSize); + if(FileBitmap != NULL) + { + // Load the bitmap bits + if(!pStream->BaseRead(pStream, &ByteOffset, FileBitmap, BitmapSize)) + { + STORM_FREE(FileBitmap); + return false; + } + + // Update the stream size + pStream->BuildNumber = Footer.BuildNumber; + pStream->StreamSize = ByteOffset; + + // Fill the bitmap information + pStream->FileBitmap = FileBitmap; + pStream->BitmapSize = BitmapSize; + pStream->BlockSize = Footer.BlockSize; + pStream->BlockCount = BlockCount; + pStream->IsComplete = FlatStream_CheckFile(pStream); + return true; + } + } + } + } + } + + return false; +} + +static void FlatStream_UpdateBitmap( + TBlockStream * pStream, // Pointer to an open stream + ULONGLONG StartOffset, + ULONGLONG EndOffset) +{ + LPBYTE FileBitmap = (LPBYTE)pStream->FileBitmap; + DWORD BlockIndex; + DWORD BlockSize = pStream->BlockSize; + DWORD ByteIndex; + BYTE BitMask; + + // Sanity checks + assert((StartOffset & (BlockSize - 1)) == 0); + assert(FileBitmap != NULL); + + // Calculate the index of the block + BlockIndex = (DWORD)(StartOffset / BlockSize); + ByteIndex = (BlockIndex / 0x08); + BitMask = (BYTE)(1 << (BlockIndex & 0x07)); + + // Set all bits for the specified range + while(StartOffset < EndOffset) + { + // Set the bit + FileBitmap[ByteIndex] |= BitMask; + + // Move all + StartOffset += BlockSize; + ByteIndex += (BitMask >> 0x07); + BitMask = (BitMask >> 0x07) | (BitMask << 0x01); + } + + // Increment the bitmap update count + pStream->IsModified = 1; +} + +static bool FlatStream_BlockCheck( + TBlockStream * pStream, // Pointer to an open stream + ULONGLONG BlockOffset) +{ + LPBYTE FileBitmap = (LPBYTE)pStream->FileBitmap; + DWORD BlockIndex; + BYTE BitMask; + + // Sanity checks + assert((BlockOffset & (pStream->BlockSize - 1)) == 0); + assert(FileBitmap != NULL); + + // Calculate the index of the block + BlockIndex = (DWORD)(BlockOffset / pStream->BlockSize); + BitMask = (BYTE)(1 << (BlockIndex & 0x07)); + + // Check if the bit is present + return (FileBitmap[BlockIndex / 0x08] & BitMask) ? true : false; +} + +static bool FlatStream_BlockRead( + TBlockStream * pStream, // Pointer to an open stream + ULONGLONG StartOffset, + ULONGLONG EndOffset, + LPBYTE BlockBuffer, + DWORD BytesNeeded, + bool bAvailable) +{ + DWORD BytesToRead = (DWORD)(EndOffset - StartOffset); + + // The starting offset must be aligned to size of the block + assert(pStream->FileBitmap != NULL); + assert((StartOffset & (pStream->BlockSize - 1)) == 0); + assert(StartOffset < EndOffset); + + // If the blocks are not available, we need to load them from the master + // and then save to the mirror + if(bAvailable == false) + { + // If we have no master, we cannot satisfy read request + if(pStream->pMaster == NULL) + return false; + + // Load the blocks from the master stream + // Note that we always have to read complete blocks + // so they get properly stored to the mirror stream + if(!FileStream_Read(pStream->pMaster, &StartOffset, BlockBuffer, BytesToRead)) + return false; + + // Store the loaded blocks to the mirror file. + // Note that this operation is not required to succeed + if(pStream->BaseWrite(pStream, &StartOffset, BlockBuffer, BytesToRead)) + FlatStream_UpdateBitmap(pStream, StartOffset, EndOffset); + + return true; + } + else + { + if(BytesToRead > BytesNeeded) + BytesToRead = BytesNeeded; + return pStream->BaseRead(pStream, &StartOffset, BlockBuffer, BytesToRead); + } +} + +static void FlatStream_Close(TBlockStream * pStream) +{ + FILE_BITMAP_FOOTER Footer; + + if(pStream->FileBitmap && pStream->IsModified) + { + // Write the file bitmap + pStream->BaseWrite(pStream, &pStream->StreamSize, pStream->FileBitmap, pStream->BitmapSize); + + // Prepare and write the file footer + Footer.Signature = ID_FILE_BITMAP_FOOTER; + Footer.Version = 3; + Footer.BuildNumber = pStream->BuildNumber; + Footer.MapOffsetLo = (DWORD)(pStream->StreamSize & 0xFFFFFFFF); + Footer.MapOffsetHi = (DWORD)(pStream->StreamSize >> 0x20); + Footer.BlockSize = pStream->BlockSize; + BSWAP_ARRAY32_UNSIGNED(&Footer, sizeof(FILE_BITMAP_FOOTER)); + pStream->BaseWrite(pStream, NULL, &Footer, sizeof(FILE_BITMAP_FOOTER)); + } + + // Close the base class + BlockStream_Close(pStream); +} + +static bool FlatStream_CreateMirror(TBlockStream * pStream) +{ + ULONGLONG MasterSize = 0; + ULONGLONG MirrorSize = 0; + LPBYTE FileBitmap = NULL; + DWORD dwBitmapSize; + DWORD dwBlockCount; + bool bNeedCreateMirrorStream = true; + bool bNeedResizeMirrorStream = true; + + // Do we have master function and base creation function? + if(pStream->pMaster == NULL || pStream->BaseCreate == NULL) + return false; + + // Retrieve the master file size, block count and bitmap size + FileStream_GetSize(pStream->pMaster, &MasterSize); + dwBlockCount = (DWORD)((MasterSize + DEFAULT_BLOCK_SIZE - 1) / DEFAULT_BLOCK_SIZE); + dwBitmapSize = (DWORD)((dwBlockCount + 7) / 8); + + // Setup stream size and position + pStream->BuildNumber = DEFAULT_BUILD_NUMBER; // BUGBUG: Really??? + pStream->StreamSize = MasterSize; + pStream->StreamPos = 0; + + // Open the base stream for write access + if(pStream->BaseOpen(pStream, pStream->szFileName, 0)) + { + // If the file open succeeded, check if the file size matches required size + pStream->BaseGetSize(pStream, &MirrorSize); + if(MirrorSize == MasterSize + dwBitmapSize + sizeof(FILE_BITMAP_FOOTER)) + { + // Attempt to load an existing file bitmap + if(FlatStream_LoadBitmap(pStream)) + return true; + + // We need to create new file bitmap + bNeedResizeMirrorStream = false; + } + + // We need to create mirror stream + bNeedCreateMirrorStream = false; + } + + // Create a new stream, if needed + if(bNeedCreateMirrorStream) + { + if(!pStream->BaseCreate(pStream)) + return false; + } + + // If we need to, then resize the mirror stream + if(bNeedResizeMirrorStream) + { + if(!pStream->BaseResize(pStream, MasterSize + dwBitmapSize + sizeof(FILE_BITMAP_FOOTER))) + return false; + } + + // Allocate the bitmap array + FileBitmap = STORM_ALLOC(BYTE, dwBitmapSize); + if(FileBitmap == NULL) + return false; + + // Initialize the bitmap + memset(FileBitmap, 0, dwBitmapSize); + pStream->FileBitmap = FileBitmap; + pStream->BitmapSize = dwBitmapSize; + pStream->BlockSize = DEFAULT_BLOCK_SIZE; + pStream->BlockCount = dwBlockCount; + pStream->IsComplete = 0; + pStream->IsModified = 1; + + // Note: Don't write the stream bitmap right away. + // Doing so would cause sparse file resize on NTFS, + // which would take long time on larger files. + return true; +} + +static TFileStream * FlatStream_Open(const TCHAR * szFileName, DWORD dwStreamFlags) +{ + TBlockStream * pStream; + ULONGLONG ByteOffset = 0; + + // Create new empty stream + pStream = (TBlockStream *)AllocateFileStream(szFileName, sizeof(TBlockStream), dwStreamFlags); + if(pStream == NULL) + return NULL; + + // Do we have a master stream? + if(pStream->pMaster != NULL) + { + if(!FlatStream_CreateMirror(pStream)) + { + FileStream_Close(pStream); + SetLastError(ERROR_FILE_NOT_FOUND); + return NULL; + } + } + else + { + // Attempt to open the base stream + if(!pStream->BaseOpen(pStream, pStream->szFileName, dwStreamFlags)) + { + FileStream_Close(pStream); + return NULL; + } + + // Load the bitmap, if required to + if(dwStreamFlags & STREAM_FLAG_USE_BITMAP) + FlatStream_LoadBitmap(pStream); + } + + // If we have a stream bitmap, set the reading functions + // which check presence of each file block + if(pStream->FileBitmap != NULL) + { + // Set the stream position to zero. Stream size is already set + assert(pStream->StreamSize != 0); + pStream->StreamPos = 0; + pStream->dwFlags |= STREAM_FLAG_READ_ONLY; + + // Supply the stream functions + pStream->StreamRead = (STREAM_READ)BlockStream_Read; + pStream->StreamGetSize = BlockStream_GetSize; + pStream->StreamGetPos = BlockStream_GetPos; + pStream->StreamClose = (STREAM_CLOSE)FlatStream_Close; + + // Supply the block functions + pStream->BlockCheck = (BLOCK_CHECK)FlatStream_BlockCheck; + pStream->BlockRead = (BLOCK_READ)FlatStream_BlockRead; + } + else + { + // Reset the base position to zero + pStream->BaseRead(pStream, &ByteOffset, NULL, 0); + + // Setup stream size and position + pStream->StreamSize = pStream->Base.File.FileSize; + pStream->StreamPos = 0; + + // Set the base functions + pStream->StreamRead = pStream->BaseRead; + pStream->StreamWrite = pStream->BaseWrite; + pStream->StreamResize = pStream->BaseResize; + pStream->StreamGetSize = pStream->BaseGetSize; + pStream->StreamGetPos = pStream->BaseGetPos; + pStream->StreamClose = pStream->BaseClose; + } + + return pStream; +} + +//----------------------------------------------------------------------------- +// Local functions - partial stream support + +static bool IsPartHeader(PPART_FILE_HEADER pPartHdr) +{ + // Version number must be 2 + if(pPartHdr->PartialVersion == 2) + { + // GameBuildNumber must be an ASCII number + if(isdigit(pPartHdr->GameBuildNumber[0]) && isdigit(pPartHdr->GameBuildNumber[1]) && isdigit(pPartHdr->GameBuildNumber[2])) + { + // Block size must be power of 2 + if((pPartHdr->BlockSize & (pPartHdr->BlockSize - 1)) == 0) + return true; + } + } + + return false; +} + +static DWORD PartStream_CheckFile(TBlockStream * pStream) +{ + PPART_FILE_MAP_ENTRY FileBitmap = (PPART_FILE_MAP_ENTRY)pStream->FileBitmap; + DWORD dwBlockCount; + + // Get the number of blocks + dwBlockCount = (DWORD)((pStream->StreamSize + pStream->BlockSize - 1) / pStream->BlockSize); + + // Check all blocks + for(DWORD i = 0; i < dwBlockCount; i++, FileBitmap++) + { + // Few sanity checks + assert(FileBitmap->LargeValueHi == 0); + assert(FileBitmap->LargeValueLo == 0); + assert(FileBitmap->Flags == 0 || FileBitmap->Flags == 3); + + // Check if this block is present + if(FileBitmap->Flags != 3) + return 0; + } + + // Yes, the file is complete + return 1; +} + +static bool PartStream_LoadBitmap(TBlockStream * pStream) +{ + PPART_FILE_MAP_ENTRY FileBitmap; + PART_FILE_HEADER PartHdr; + ULONGLONG ByteOffset = 0; + ULONGLONG StreamSize = 0; + DWORD BlockCount; + DWORD BitmapSize; + + // Only if the size is greater than size of the bitmap header + if(pStream->Base.File.FileSize > sizeof(PART_FILE_HEADER)) + { + // Attempt to read PART file header + if(pStream->BaseRead(pStream, &ByteOffset, &PartHdr, sizeof(PART_FILE_HEADER))) + { + // We need to swap PART file header on big-endian platforms + BSWAP_ARRAY32_UNSIGNED(&PartHdr, sizeof(PART_FILE_HEADER)); + + // Verify the PART file header + if(IsPartHeader(&PartHdr)) + { + // Get the number of blocks and size of one block + StreamSize = MAKE_OFFSET64(PartHdr.FileSizeHi, PartHdr.FileSizeLo); + ByteOffset = sizeof(PART_FILE_HEADER); + BlockCount = (DWORD)((StreamSize + PartHdr.BlockSize - 1) / PartHdr.BlockSize); + BitmapSize = BlockCount * sizeof(PART_FILE_MAP_ENTRY); + + // Check if sizes match + if((ByteOffset + BitmapSize) < pStream->Base.File.FileSize) + { + // Allocate space for the array of PART_FILE_MAP_ENTRY + FileBitmap = STORM_ALLOC(PART_FILE_MAP_ENTRY, BlockCount); + if(FileBitmap != NULL) + { + // Load the block map + if(!pStream->BaseRead(pStream, &ByteOffset, FileBitmap, BitmapSize)) + { + STORM_FREE(FileBitmap); + return false; + } + + // Make sure that the byte order is correct + BSWAP_ARRAY32_UNSIGNED(FileBitmap, BitmapSize); + + // Update the stream size + pStream->BuildNumber = StringToInt(PartHdr.GameBuildNumber); + pStream->StreamSize = StreamSize; + + // Fill the bitmap information + pStream->FileBitmap = FileBitmap; + pStream->BitmapSize = BitmapSize; + pStream->BlockSize = PartHdr.BlockSize; + pStream->BlockCount = BlockCount; + pStream->IsComplete = PartStream_CheckFile(pStream); + return true; + } + } + } + } + } + + return false; +} + +static void PartStream_UpdateBitmap( + TBlockStream * pStream, // Pointer to an open stream + ULONGLONG StartOffset, + ULONGLONG EndOffset, + ULONGLONG RealOffset) +{ + PPART_FILE_MAP_ENTRY FileBitmap; + DWORD BlockSize = pStream->BlockSize; + + // Sanity checks + assert((StartOffset & (BlockSize - 1)) == 0); + assert(pStream->FileBitmap != NULL); + + // Calculate the first entry in the block map + FileBitmap = (PPART_FILE_MAP_ENTRY)pStream->FileBitmap + (StartOffset / BlockSize); + + // Set all bits for the specified range + while(StartOffset < EndOffset) + { + // Set the bit + FileBitmap->BlockOffsHi = (DWORD)(RealOffset >> 0x20); + FileBitmap->BlockOffsLo = (DWORD)(RealOffset & 0xFFFFFFFF); + FileBitmap->Flags = 3; + + // Move all + StartOffset += BlockSize; + RealOffset += BlockSize; + FileBitmap++; + } + + // Increment the bitmap update count + pStream->IsModified = 1; +} + +static bool PartStream_BlockCheck( + TBlockStream * pStream, // Pointer to an open stream + ULONGLONG BlockOffset) +{ + PPART_FILE_MAP_ENTRY FileBitmap; + + // Sanity checks + assert((BlockOffset & (pStream->BlockSize - 1)) == 0); + assert(pStream->FileBitmap != NULL); + + // Calculate the block map entry + FileBitmap = (PPART_FILE_MAP_ENTRY)pStream->FileBitmap + (BlockOffset / pStream->BlockSize); + + // Check if the flags are present + return (FileBitmap->Flags & 0x03) ? true : false; +} + +static bool PartStream_BlockRead( + TBlockStream * pStream, + ULONGLONG StartOffset, + ULONGLONG EndOffset, + LPBYTE BlockBuffer, + DWORD BytesNeeded, + bool bAvailable) +{ + PPART_FILE_MAP_ENTRY FileBitmap; + ULONGLONG ByteOffset; + DWORD BytesToRead; + DWORD BlockIndex = (DWORD)(StartOffset / pStream->BlockSize); + + // The starting offset must be aligned to size of the block + assert(pStream->FileBitmap != NULL); + assert((StartOffset & (pStream->BlockSize - 1)) == 0); + assert(StartOffset < EndOffset); + + // If the blocks are not available, we need to load them from the master + // and then save to the mirror + if(bAvailable == false) + { + // If we have no master, we cannot satisfy read request + if(pStream->pMaster == NULL) + return false; + + // Load the blocks from the master stream + // Note that we always have to read complete blocks + // so they get properly stored to the mirror stream + BytesToRead = (DWORD)(EndOffset - StartOffset); + if(!FileStream_Read(pStream->pMaster, &StartOffset, BlockBuffer, BytesToRead)) + return false; + + // The loaded blocks are going to be stored to the end of the file + // Note that this operation is not required to succeed + if(pStream->BaseGetSize(pStream, &ByteOffset)) + { + // Store the loaded blocks to the mirror file. + if(pStream->BaseWrite(pStream, &ByteOffset, BlockBuffer, BytesToRead)) + { + PartStream_UpdateBitmap(pStream, StartOffset, EndOffset, ByteOffset); + } + } + } + else + { + // Get the file map entry + FileBitmap = (PPART_FILE_MAP_ENTRY)pStream->FileBitmap + BlockIndex; + + // Read all blocks + while(StartOffset < EndOffset) + { + // Get the number of bytes to be read + BytesToRead = (DWORD)(EndOffset - StartOffset); + if(BytesToRead > pStream->BlockSize) + BytesToRead = pStream->BlockSize; + if(BytesToRead > BytesNeeded) + BytesToRead = BytesNeeded; + + // Read the block + ByteOffset = MAKE_OFFSET64(FileBitmap->BlockOffsHi, FileBitmap->BlockOffsLo); + if(!pStream->BaseRead(pStream, &ByteOffset, BlockBuffer, BytesToRead)) + return false; + + // Move the pointers + StartOffset += pStream->BlockSize; + BlockBuffer += pStream->BlockSize; + BytesNeeded -= pStream->BlockSize; + FileBitmap++; + } + } + + return true; +} + +static void PartStream_Close(TBlockStream * pStream) +{ + PART_FILE_HEADER PartHeader; + ULONGLONG ByteOffset = 0; + + if(pStream->FileBitmap && pStream->IsModified) + { + // Prepare the part file header + memset(&PartHeader, 0, sizeof(PART_FILE_HEADER)); + PartHeader.PartialVersion = 2; + PartHeader.FileSizeHi = (DWORD)(pStream->StreamSize >> 0x20); + PartHeader.FileSizeLo = (DWORD)(pStream->StreamSize & 0xFFFFFFFF); + PartHeader.BlockSize = pStream->BlockSize; + + // Make sure that the header is properly BSWAPed + BSWAP_ARRAY32_UNSIGNED(&PartHeader, sizeof(PART_FILE_HEADER)); + IntToString(PartHeader.GameBuildNumber, _countof(PartHeader.GameBuildNumber), pStream->BuildNumber); + + // Write the part header + pStream->BaseWrite(pStream, &ByteOffset, &PartHeader, sizeof(PART_FILE_HEADER)); + + // Write the block bitmap + BSWAP_ARRAY32_UNSIGNED(pStream->FileBitmap, pStream->BitmapSize); + pStream->BaseWrite(pStream, NULL, pStream->FileBitmap, pStream->BitmapSize); + } + + // Close the base class + BlockStream_Close(pStream); +} + +static bool PartStream_CreateMirror(TBlockStream * pStream) +{ + ULONGLONG RemainingSize; + ULONGLONG MasterSize = 0; + ULONGLONG MirrorSize = 0; + LPBYTE FileBitmap = NULL; + DWORD dwBitmapSize; + DWORD dwBlockCount; + bool bNeedCreateMirrorStream = true; + bool bNeedResizeMirrorStream = true; + + // Do we have master function and base creation function? + if(pStream->pMaster == NULL || pStream->BaseCreate == NULL) + return false; + + // Retrieve the master file size, block count and bitmap size + FileStream_GetSize(pStream->pMaster, &MasterSize); + dwBlockCount = (DWORD)((MasterSize + DEFAULT_BLOCK_SIZE - 1) / DEFAULT_BLOCK_SIZE); + dwBitmapSize = (DWORD)(dwBlockCount * sizeof(PART_FILE_MAP_ENTRY)); + + // Setup stream size and position + pStream->BuildNumber = DEFAULT_BUILD_NUMBER; // BUGBUG: Really??? + pStream->StreamSize = MasterSize; + pStream->StreamPos = 0; + + // Open the base stream for write access + if(pStream->BaseOpen(pStream, pStream->szFileName, 0)) + { + // If the file open succeeded, check if the file size matches required size + pStream->BaseGetSize(pStream, &MirrorSize); + if(MirrorSize >= sizeof(PART_FILE_HEADER) + dwBitmapSize) + { + // Check if the remaining size is aligned to block + RemainingSize = MirrorSize - sizeof(PART_FILE_HEADER) - dwBitmapSize; + if((RemainingSize & (DEFAULT_BLOCK_SIZE - 1)) == 0 || RemainingSize == MasterSize) + { + // Attempt to load an existing file bitmap + if(PartStream_LoadBitmap(pStream)) + return true; + } + } + + // We need to create mirror stream + bNeedCreateMirrorStream = false; + } + + // Create a new stream, if needed + if(bNeedCreateMirrorStream) + { + if(!pStream->BaseCreate(pStream)) + return false; + } + + // If we need to, then resize the mirror stream + if(bNeedResizeMirrorStream) + { + if(!pStream->BaseResize(pStream, sizeof(PART_FILE_HEADER) + dwBitmapSize)) + return false; + } + + // Allocate the bitmap array + FileBitmap = STORM_ALLOC(BYTE, dwBitmapSize); + if(FileBitmap == NULL) + return false; + + // Initialize the bitmap + memset(FileBitmap, 0, dwBitmapSize); + pStream->FileBitmap = FileBitmap; + pStream->BitmapSize = dwBitmapSize; + pStream->BlockSize = DEFAULT_BLOCK_SIZE; + pStream->BlockCount = dwBlockCount; + pStream->IsComplete = 0; + pStream->IsModified = 1; + + // Note: Don't write the stream bitmap right away. + // Doing so would cause sparse file resize on NTFS, + // which would take long time on larger files. + return true; +} + + +static TFileStream * PartStream_Open(const TCHAR * szFileName, DWORD dwStreamFlags) +{ + TBlockStream * pStream; + + // Create new empty stream + pStream = (TBlockStream *)AllocateFileStream(szFileName, sizeof(TBlockStream), dwStreamFlags); + if(pStream == NULL) + return NULL; + + // Do we have a master stream? + if(pStream->pMaster != NULL) + { + if(!PartStream_CreateMirror(pStream)) + { + FileStream_Close(pStream); + SetLastError(ERROR_FILE_NOT_FOUND); + return NULL; + } + } + else + { + // Attempt to open the base stream + if(!pStream->BaseOpen(pStream, pStream->szFileName, dwStreamFlags)) + { + FileStream_Close(pStream); + return NULL; + } + + // Load the part stream block map + if(!PartStream_LoadBitmap(pStream)) + { + FileStream_Close(pStream); + SetLastError(ERROR_BAD_FORMAT); + return NULL; + } + } + + // Set the stream position to zero. Stream size is already set + assert(pStream->StreamSize != 0); + pStream->StreamPos = 0; + pStream->dwFlags |= STREAM_FLAG_READ_ONLY; + + // Set new function pointers + pStream->StreamRead = (STREAM_READ)BlockStream_Read; + pStream->StreamGetPos = BlockStream_GetPos; + pStream->StreamGetSize = BlockStream_GetSize; + pStream->StreamClose = (STREAM_CLOSE)PartStream_Close; + + // Supply the block functions + pStream->BlockCheck = (BLOCK_CHECK)PartStream_BlockCheck; + pStream->BlockRead = (BLOCK_READ)PartStream_BlockRead; + return pStream; +} + +//----------------------------------------------------------------------------- +// Local functions - MPQE stream support + +static const char * szKeyTemplate = "expand 32-byte k000000000000000000000000000000000000000000000000"; + +static const char * AuthCodeArray[] = +{ + // Starcraft II (Heart of the Swarm) + // Authentication code URL: http://dist.blizzard.com/mediakey/hots-authenticationcode-bgdl.txt + // -0C- -1C--08- -18--04- -14--00- -10- + "S48B6CDTN5XEQAKQDJNDLJBJ73FDFM3U", // SC2 Heart of the Swarm-all : "expand 32-byte kQAKQ0000FM3UN5XE000073FD6CDT0000LJBJS48B0000DJND" + + // Diablo III: Agent.exe (1.0.0.954) + // Address of decryption routine: 00502b00 + // Pointer to decryptor object: ECX + // Pointer to key: ECX+0x5C + // Authentication code URL: http://dist.blizzard.com/mediakey/d3-authenticationcode-enGB.txt + // -0C- -1C--08- -18--04- -14--00- -10- + "UCMXF6EJY352EFH4XFRXCFH2XC9MQRZK", // Diablo III Installer (deDE): "expand 32-byte kEFH40000QRZKY3520000XC9MF6EJ0000CFH2UCMX0000XFRX" + "MMKVHY48RP7WXP4GHYBQ7SL9J9UNPHBP", // Diablo III Installer (enGB): "expand 32-byte kXP4G0000PHBPRP7W0000J9UNHY4800007SL9MMKV0000HYBQ" + "8MXLWHQ7VGGLTZ9MQZQSFDCLJYET3CPP", // Diablo III Installer (enSG): "expand 32-byte kTZ9M00003CPPVGGL0000JYETWHQ70000FDCL8MXL0000QZQS" + "EJ2R5TM6XFE2GUNG5QDGHKQ9UAKPWZSZ", // Diablo III Installer (enUS): "expand 32-byte kGUNG0000WZSZXFE20000UAKP5TM60000HKQ9EJ2R00005QDG" + "PBGFBE42Z6LNK65UGJQ3WZVMCLP4HQQT", // Diablo III Installer (esES): "expand 32-byte kK65U0000HQQTZ6LN0000CLP4BE420000WZVMPBGF0000GJQ3" + "X7SEJJS9TSGCW5P28EBSC47AJPEY8VU2", // Diablo III Installer (esMX): "expand 32-byte kW5P200008VU2TSGC0000JPEYJJS90000C47AX7SE00008EBS" + "5KVBQA8VYE6XRY3DLGC5ZDE4XS4P7YA2", // Diablo III Installer (frFR): "expand 32-byte kRY3D00007YA2YE6X0000XS4PQA8V0000ZDE45KVB0000LGC5" + "478JD2K56EVNVVY4XX8TDWYT5B8KB254", // Diablo III Installer (itIT): "expand 32-byte kVVY40000B2546EVN00005B8KD2K50000DWYT478J0000XX8T" + "8TS4VNFQRZTN6YWHE9CHVDH9NVWD474A", // Diablo III Installer (koKR): "expand 32-byte k6YWH0000474ARZTN0000NVWDVNFQ0000VDH98TS40000E9CH" + "LJ52Z32DF4LZ4ZJJXVKK3AZQA6GABLJB", // Diablo III Installer (plPL): "expand 32-byte k4ZJJ0000BLJBF4LZ0000A6GAZ32D00003AZQLJ520000XVKK" + "K6BDHY2ECUE2545YKNLBJPVYWHE7XYAG", // Diablo III Installer (ptBR): "expand 32-byte k545Y0000XYAGCUE20000WHE7HY2E0000JPVYK6BD0000KNLB" + "NDVW8GWLAYCRPGRNY8RT7ZZUQU63VLPR", // Diablo III Installer (ruRU): "expand 32-byte kXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + "6VWCQTN8V3ZZMRUCZXV8A8CGUX2TAA8H", // Diablo III Installer (zhTW): "expand 32-byte kMRUC0000AA8HV3ZZ0000UX2TQTN80000A8CG6VWC0000ZXV8" +// "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", // Diablo III Installer (zhCN): "expand 32-byte kXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + + // Starcraft II (Wings of Liberty): Installer.exe (4.1.1.4219) + // Address of decryption routine: 0053A3D0 + // Pointer to decryptor object: ECX + // Pointer to key: ECX+0x5C + // Authentication code URL: http://dist.blizzard.com/mediakey/sc2-authenticationcode-enUS.txt + // -0C- -1C--08- -18--04- -14--00- -10- + "Y45MD3CAK4KXSSXHYD9VY64Z8EKJ4XFX", // SC2 Wings of Liberty (deDE): "expand 32-byte kSSXH00004XFXK4KX00008EKJD3CA0000Y64ZY45M0000YD9V" + "G8MN8UDG6NA2ANGY6A3DNY82HRGF29ZH", // SC2 Wings of Liberty (enGB): "expand 32-byte kANGY000029ZH6NA20000HRGF8UDG0000NY82G8MN00006A3D" + "W9RRHLB2FDU9WW5B3ECEBLRSFWZSF7HW", // SC2 Wings of Liberty (enSG): "expand 32-byte kWW5B0000F7HWFDU90000FWZSHLB20000BLRSW9RR00003ECE" + "3DH5RE5NVM5GTFD85LXGWT6FK859ETR5", // SC2 Wings of Liberty (enUS): "expand 32-byte kTFD80000ETR5VM5G0000K859RE5N0000WT6F3DH500005LXG" + "8WLKUAXE94PFQU4Y249PAZ24N4R4XKTQ", // SC2 Wings of Liberty (esES): "expand 32-byte kQU4Y0000XKTQ94PF0000N4R4UAXE0000AZ248WLK0000249P" + "A34DXX3VHGGXSQBRFE5UFFDXMF9G4G54", // SC2 Wings of Liberty (esMX): "expand 32-byte kSQBR00004G54HGGX0000MF9GXX3V0000FFDXA34D0000FE5U" + "ZG7J9K938HJEFWPQUA768MA2PFER6EAJ", // SC2 Wings of Liberty (frFR): "expand 32-byte kFWPQ00006EAJ8HJE0000PFER9K9300008MA2ZG7J0000UA76" + "NE7CUNNNTVAPXV7E3G2BSVBWGVMW8BL2", // SC2 Wings of Liberty (itIT): "expand 32-byte kXV7E00008BL2TVAP0000GVMWUNNN0000SVBWNE7C00003G2B" + "3V9E2FTMBM9QQWK7U6MAMWAZWQDB838F", // SC2 Wings of Liberty (koKR): "expand 32-byte kQWK70000838FBM9Q0000WQDB2FTM0000MWAZ3V9E0000U6MA" + "2NSFB8MELULJ83U6YHA3UP6K4MQD48L6", // SC2 Wings of Liberty (plPL): "expand 32-byte k83U6000048L6LULJ00004MQDB8ME0000UP6K2NSF0000YHA3" + "QA2TZ9EWZ4CUU8BMB5WXCTY65F9CSW4E", // SC2 Wings of Liberty (ptBR): "expand 32-byte kU8BM0000SW4EZ4CU00005F9CZ9EW0000CTY6QA2T0000B5WX" + "VHB378W64BAT9SH7D68VV9NLQDK9YEGT", // SC2 Wings of Liberty (ruRU): "expand 32-byte k9SH70000YEGT4BAT0000QDK978W60000V9NLVHB30000D68V" + "U3NFQJV4M6GC7KBN9XQJ3BRDN3PLD9NE", // SC2 Wings of Liberty (zhTW): "expand 32-byte k7KBN0000D9NEM6GC0000N3PLQJV400003BRDU3NF00009XQJ" + + NULL +}; + +static DWORD Rol32(DWORD dwValue, DWORD dwRolCount) +{ + DWORD dwShiftRight = 32 - dwRolCount; + + return (dwValue << dwRolCount) | (dwValue >> dwShiftRight); +} + +static void CreateKeyFromAuthCode( + LPBYTE pbKeyBuffer, + const char * szAuthCode) +{ + LPDWORD KeyPosition = (LPDWORD)(pbKeyBuffer + 0x10); + LPDWORD AuthCode32 = (LPDWORD)szAuthCode; + + memcpy(pbKeyBuffer, szKeyTemplate, MPQE_CHUNK_SIZE); + KeyPosition[0x00] = AuthCode32[0x03]; + KeyPosition[0x02] = AuthCode32[0x07]; + KeyPosition[0x03] = AuthCode32[0x02]; + KeyPosition[0x05] = AuthCode32[0x06]; + KeyPosition[0x06] = AuthCode32[0x01]; + KeyPosition[0x08] = AuthCode32[0x05]; + KeyPosition[0x09] = AuthCode32[0x00]; + KeyPosition[0x0B] = AuthCode32[0x04]; + BSWAP_ARRAY32_UNSIGNED(pbKeyBuffer, MPQE_CHUNK_SIZE); +} + +static void DecryptFileChunk( + DWORD * MpqData, + LPBYTE pbKey, + ULONGLONG ByteOffset, + DWORD dwLength) +{ + ULONGLONG ChunkOffset; + DWORD KeyShuffled[0x10]; + DWORD KeyMirror[0x10]; + DWORD RoundCount = 0x14; + + // Prepare the key + ChunkOffset = ByteOffset / MPQE_CHUNK_SIZE; + memcpy(KeyMirror, pbKey, MPQE_CHUNK_SIZE); + BSWAP_ARRAY32_UNSIGNED(KeyMirror, MPQE_CHUNK_SIZE); + KeyMirror[0x05] = (DWORD)(ChunkOffset >> 32); + KeyMirror[0x08] = (DWORD)(ChunkOffset); + + while(dwLength >= MPQE_CHUNK_SIZE) + { + // Shuffle the key - part 1 + KeyShuffled[0x0E] = KeyMirror[0x00]; + KeyShuffled[0x0C] = KeyMirror[0x01]; + KeyShuffled[0x05] = KeyMirror[0x02]; + KeyShuffled[0x0F] = KeyMirror[0x03]; + KeyShuffled[0x0A] = KeyMirror[0x04]; + KeyShuffled[0x07] = KeyMirror[0x05]; + KeyShuffled[0x0B] = KeyMirror[0x06]; + KeyShuffled[0x09] = KeyMirror[0x07]; + KeyShuffled[0x03] = KeyMirror[0x08]; + KeyShuffled[0x06] = KeyMirror[0x09]; + KeyShuffled[0x08] = KeyMirror[0x0A]; + KeyShuffled[0x0D] = KeyMirror[0x0B]; + KeyShuffled[0x02] = KeyMirror[0x0C]; + KeyShuffled[0x04] = KeyMirror[0x0D]; + KeyShuffled[0x01] = KeyMirror[0x0E]; + KeyShuffled[0x00] = KeyMirror[0x0F]; + + // Shuffle the key - part 2 + for(DWORD i = 0; i < RoundCount; i += 2) + { + KeyShuffled[0x0A] = KeyShuffled[0x0A] ^ Rol32((KeyShuffled[0x0E] + KeyShuffled[0x02]), 0x07); + KeyShuffled[0x03] = KeyShuffled[0x03] ^ Rol32((KeyShuffled[0x0A] + KeyShuffled[0x0E]), 0x09); + KeyShuffled[0x02] = KeyShuffled[0x02] ^ Rol32((KeyShuffled[0x03] + KeyShuffled[0x0A]), 0x0D); + KeyShuffled[0x0E] = KeyShuffled[0x0E] ^ Rol32((KeyShuffled[0x02] + KeyShuffled[0x03]), 0x12); + + KeyShuffled[0x07] = KeyShuffled[0x07] ^ Rol32((KeyShuffled[0x0C] + KeyShuffled[0x04]), 0x07); + KeyShuffled[0x06] = KeyShuffled[0x06] ^ Rol32((KeyShuffled[0x07] + KeyShuffled[0x0C]), 0x09); + KeyShuffled[0x04] = KeyShuffled[0x04] ^ Rol32((KeyShuffled[0x06] + KeyShuffled[0x07]), 0x0D); + KeyShuffled[0x0C] = KeyShuffled[0x0C] ^ Rol32((KeyShuffled[0x04] + KeyShuffled[0x06]), 0x12); + + KeyShuffled[0x0B] = KeyShuffled[0x0B] ^ Rol32((KeyShuffled[0x05] + KeyShuffled[0x01]), 0x07); + KeyShuffled[0x08] = KeyShuffled[0x08] ^ Rol32((KeyShuffled[0x0B] + KeyShuffled[0x05]), 0x09); + KeyShuffled[0x01] = KeyShuffled[0x01] ^ Rol32((KeyShuffled[0x08] + KeyShuffled[0x0B]), 0x0D); + KeyShuffled[0x05] = KeyShuffled[0x05] ^ Rol32((KeyShuffled[0x01] + KeyShuffled[0x08]), 0x12); + + KeyShuffled[0x09] = KeyShuffled[0x09] ^ Rol32((KeyShuffled[0x0F] + KeyShuffled[0x00]), 0x07); + KeyShuffled[0x0D] = KeyShuffled[0x0D] ^ Rol32((KeyShuffled[0x09] + KeyShuffled[0x0F]), 0x09); + KeyShuffled[0x00] = KeyShuffled[0x00] ^ Rol32((KeyShuffled[0x0D] + KeyShuffled[0x09]), 0x0D); + KeyShuffled[0x0F] = KeyShuffled[0x0F] ^ Rol32((KeyShuffled[0x00] + KeyShuffled[0x0D]), 0x12); + + KeyShuffled[0x04] = KeyShuffled[0x04] ^ Rol32((KeyShuffled[0x0E] + KeyShuffled[0x09]), 0x07); + KeyShuffled[0x08] = KeyShuffled[0x08] ^ Rol32((KeyShuffled[0x04] + KeyShuffled[0x0E]), 0x09); + KeyShuffled[0x09] = KeyShuffled[0x09] ^ Rol32((KeyShuffled[0x08] + KeyShuffled[0x04]), 0x0D); + KeyShuffled[0x0E] = KeyShuffled[0x0E] ^ Rol32((KeyShuffled[0x09] + KeyShuffled[0x08]), 0x12); + + KeyShuffled[0x01] = KeyShuffled[0x01] ^ Rol32((KeyShuffled[0x0C] + KeyShuffled[0x0A]), 0x07); + KeyShuffled[0x0D] = KeyShuffled[0x0D] ^ Rol32((KeyShuffled[0x01] + KeyShuffled[0x0C]), 0x09); + KeyShuffled[0x0A] = KeyShuffled[0x0A] ^ Rol32((KeyShuffled[0x0D] + KeyShuffled[0x01]), 0x0D); + KeyShuffled[0x0C] = KeyShuffled[0x0C] ^ Rol32((KeyShuffled[0x0A] + KeyShuffled[0x0D]), 0x12); + + KeyShuffled[0x00] = KeyShuffled[0x00] ^ Rol32((KeyShuffled[0x05] + KeyShuffled[0x07]), 0x07); + KeyShuffled[0x03] = KeyShuffled[0x03] ^ Rol32((KeyShuffled[0x00] + KeyShuffled[0x05]), 0x09); + KeyShuffled[0x07] = KeyShuffled[0x07] ^ Rol32((KeyShuffled[0x03] + KeyShuffled[0x00]), 0x0D); + KeyShuffled[0x05] = KeyShuffled[0x05] ^ Rol32((KeyShuffled[0x07] + KeyShuffled[0x03]), 0x12); + + KeyShuffled[0x02] = KeyShuffled[0x02] ^ Rol32((KeyShuffled[0x0F] + KeyShuffled[0x0B]), 0x07); + KeyShuffled[0x06] = KeyShuffled[0x06] ^ Rol32((KeyShuffled[0x02] + KeyShuffled[0x0F]), 0x09); + KeyShuffled[0x0B] = KeyShuffled[0x0B] ^ Rol32((KeyShuffled[0x06] + KeyShuffled[0x02]), 0x0D); + KeyShuffled[0x0F] = KeyShuffled[0x0F] ^ Rol32((KeyShuffled[0x0B] + KeyShuffled[0x06]), 0x12); + } + + // Decrypt one data chunk + BSWAP_ARRAY32_UNSIGNED(MpqData, MPQE_CHUNK_SIZE); + MpqData[0x00] = MpqData[0x00] ^ (KeyShuffled[0x0E] + KeyMirror[0x00]); + MpqData[0x01] = MpqData[0x01] ^ (KeyShuffled[0x04] + KeyMirror[0x0D]); + MpqData[0x02] = MpqData[0x02] ^ (KeyShuffled[0x08] + KeyMirror[0x0A]); + MpqData[0x03] = MpqData[0x03] ^ (KeyShuffled[0x09] + KeyMirror[0x07]); + MpqData[0x04] = MpqData[0x04] ^ (KeyShuffled[0x0A] + KeyMirror[0x04]); + MpqData[0x05] = MpqData[0x05] ^ (KeyShuffled[0x0C] + KeyMirror[0x01]); + MpqData[0x06] = MpqData[0x06] ^ (KeyShuffled[0x01] + KeyMirror[0x0E]); + MpqData[0x07] = MpqData[0x07] ^ (KeyShuffled[0x0D] + KeyMirror[0x0B]); + MpqData[0x08] = MpqData[0x08] ^ (KeyShuffled[0x03] + KeyMirror[0x08]); + MpqData[0x09] = MpqData[0x09] ^ (KeyShuffled[0x07] + KeyMirror[0x05]); + MpqData[0x0A] = MpqData[0x0A] ^ (KeyShuffled[0x05] + KeyMirror[0x02]); + MpqData[0x0B] = MpqData[0x0B] ^ (KeyShuffled[0x00] + KeyMirror[0x0F]); + MpqData[0x0C] = MpqData[0x0C] ^ (KeyShuffled[0x02] + KeyMirror[0x0C]); + MpqData[0x0D] = MpqData[0x0D] ^ (KeyShuffled[0x06] + KeyMirror[0x09]); + MpqData[0x0E] = MpqData[0x0E] ^ (KeyShuffled[0x0B] + KeyMirror[0x06]); + MpqData[0x0F] = MpqData[0x0F] ^ (KeyShuffled[0x0F] + KeyMirror[0x03]); + BSWAP_ARRAY32_UNSIGNED(MpqData, MPQE_CHUNK_SIZE); + + // Update byte offset in the key + KeyMirror[0x08]++; + if(KeyMirror[0x08] == 0) + KeyMirror[0x05]++; + + // Move pointers and decrease number of bytes to decrypt + MpqData += (MPQE_CHUNK_SIZE / sizeof(DWORD)); + dwLength -= MPQE_CHUNK_SIZE; + } +} + +static bool MpqeStream_DetectFileKey(TEncryptedStream * pStream) +{ + ULONGLONG ByteOffset = 0; + BYTE EncryptedHeader[MPQE_CHUNK_SIZE]; + BYTE FileHeader[MPQE_CHUNK_SIZE]; + + // Read the first file chunk + if(pStream->BaseRead(pStream, &ByteOffset, EncryptedHeader, sizeof(EncryptedHeader))) + { + // We just try all known keys one by one + for(int i = 0; AuthCodeArray[i] != NULL; i++) + { + // Prepare they decryption key from game serial number + CreateKeyFromAuthCode(pStream->Key, AuthCodeArray[i]); + + // Try to decrypt with the given key + memcpy(FileHeader, EncryptedHeader, MPQE_CHUNK_SIZE); + DecryptFileChunk((LPDWORD)FileHeader, pStream->Key, ByteOffset, MPQE_CHUNK_SIZE); + + // We check the decrypted data + // All known encrypted MPQs have header at the begin of the file, + // so we check for MPQ signature there. + if(FileHeader[0] == 'M' && FileHeader[1] == 'P' && FileHeader[2] == 'Q') + { + // Update the stream size + pStream->StreamSize = pStream->Base.File.FileSize; + + // Fill the block information + pStream->BlockSize = MPQE_CHUNK_SIZE; + pStream->BlockCount = (DWORD)(pStream->Base.File.FileSize + MPQE_CHUNK_SIZE - 1) / MPQE_CHUNK_SIZE; + pStream->IsComplete = 1; + return true; + } + } + } + + // Key not found, sorry + return false; +} + +static bool MpqeStream_BlockRead( + TEncryptedStream * pStream, + ULONGLONG StartOffset, + ULONGLONG EndOffset, + LPBYTE BlockBuffer, + DWORD BytesNeeded, + bool bAvailable) +{ + DWORD dwBytesToRead; + + assert((StartOffset & (pStream->BlockSize - 1)) == 0); + assert(StartOffset < EndOffset); + assert(bAvailable != false); + BytesNeeded = BytesNeeded; + bAvailable = bAvailable; + + // Read the file from the stream as-is + // Limit the reading to number of blocks really needed + dwBytesToRead = (DWORD)(EndOffset - StartOffset); + if(!pStream->BaseRead(pStream, &StartOffset, BlockBuffer, dwBytesToRead)) + return false; + + // Decrypt the data + dwBytesToRead = (dwBytesToRead + MPQE_CHUNK_SIZE - 1) & ~(MPQE_CHUNK_SIZE - 1); + DecryptFileChunk((LPDWORD)BlockBuffer, pStream->Key, StartOffset, dwBytesToRead); + return true; +} + +static TFileStream * MpqeStream_Open(const TCHAR * szFileName, DWORD dwStreamFlags) +{ + TEncryptedStream * pStream; + + // Create new empty stream + pStream = (TEncryptedStream *)AllocateFileStream(szFileName, sizeof(TEncryptedStream), dwStreamFlags); + if(pStream == NULL) + return NULL; + + // Attempt to open the base stream + assert(pStream->BaseOpen != NULL); + if(!pStream->BaseOpen(pStream, pStream->szFileName, dwStreamFlags)) + return NULL; + + // Determine the encryption key for the MPQ + if(MpqeStream_DetectFileKey(pStream)) + { + // Set the stream position and size + assert(pStream->StreamSize != 0); + pStream->StreamPos = 0; + pStream->dwFlags |= STREAM_FLAG_READ_ONLY; + + // Set new function pointers + pStream->StreamRead = (STREAM_READ)BlockStream_Read; + pStream->StreamGetPos = BlockStream_GetPos; + pStream->StreamGetSize = BlockStream_GetSize; + pStream->StreamClose = pStream->BaseClose; + + // Supply the block functions + pStream->BlockRead = (BLOCK_READ)MpqeStream_BlockRead; + return pStream; + } + + // Cleanup the stream and return + FileStream_Close(pStream); + SetLastError(ERROR_UNKNOWN_FILE_KEY); + return NULL; +} + +//----------------------------------------------------------------------------- +// Local functions - Block4 stream support + +#define BLOCK4_BLOCK_SIZE 0x4000 // Size of one block +#define BLOCK4_HASH_SIZE 0x20 // Size of MD5 hash that is after each block +#define BLOCK4_MAX_BLOCKS 0x00002000 // Maximum amount of blocks per file +#define BLOCK4_MAX_FSIZE 0x08040000 // Max size of one file + +static bool Block4Stream_BlockRead( + TBlockStream * pStream, // Pointer to an open stream + ULONGLONG StartOffset, + ULONGLONG EndOffset, + LPBYTE BlockBuffer, + DWORD BytesNeeded, + bool bAvailable) +{ + TBaseProviderData * BaseArray = (TBaseProviderData *)pStream->FileBitmap; + ULONGLONG ByteOffset; + DWORD BytesToRead; + DWORD StreamIndex; + DWORD BlockIndex; + bool bResult; + + // The starting offset must be aligned to size of the block + assert(pStream->FileBitmap != NULL); + assert((StartOffset & (pStream->BlockSize - 1)) == 0); + assert(StartOffset < EndOffset); + assert(bAvailable == true); + + // Keep compiler happy + bAvailable = bAvailable; + EndOffset = EndOffset; + + while(BytesNeeded != 0) + { + // Calculate the block index and the file index + StreamIndex = (DWORD)((StartOffset / pStream->BlockSize) / BLOCK4_MAX_BLOCKS); + BlockIndex = (DWORD)((StartOffset / pStream->BlockSize) % BLOCK4_MAX_BLOCKS); + if(StreamIndex > pStream->BitmapSize) + return false; + + // Calculate the block offset + ByteOffset = ((ULONGLONG)BlockIndex * (BLOCK4_BLOCK_SIZE + BLOCK4_HASH_SIZE)); + BytesToRead = STORMLIB_MIN(BytesNeeded, BLOCK4_BLOCK_SIZE); + + // Read from the base stream + pStream->Base = BaseArray[StreamIndex]; + bResult = pStream->BaseRead(pStream, &ByteOffset, BlockBuffer, BytesToRead); + BaseArray[StreamIndex] = pStream->Base; + + // Did the result succeed? + if(bResult == false) + return false; + + // Move pointers + StartOffset += BytesToRead; + BlockBuffer += BytesToRead; + BytesNeeded -= BytesToRead; + } + + return true; +} + + +static void Block4Stream_Close(TBlockStream * pStream) +{ + TBaseProviderData * BaseArray = (TBaseProviderData *)pStream->FileBitmap; + + // If we have a non-zero count of base streams, + // we have to close them all + if(BaseArray != NULL) + { + // Close all base streams + for(DWORD i = 0; i < pStream->BitmapSize; i++) + { + memcpy(&pStream->Base, BaseArray + i, sizeof(TBaseProviderData)); + pStream->BaseClose(pStream); + } + } + + // Free the data map, if any + if(pStream->FileBitmap != NULL) + STORM_FREE(pStream->FileBitmap); + pStream->FileBitmap = NULL; + + // Do not call the BaseClose function, + // we closed all handles already + return; +} + +static TFileStream * Block4Stream_Open(const TCHAR * szFileName, DWORD dwStreamFlags) +{ + TBaseProviderData * NewBaseArray = NULL; + ULONGLONG RemainderBlock; + ULONGLONG BlockCount; + ULONGLONG FileSize; + TBlockStream * pStream; + TCHAR * szNameBuff; + size_t nNameLength; + DWORD dwBaseFiles = 0; + DWORD dwBaseFlags; + + // Create new empty stream + pStream = (TBlockStream *)AllocateFileStream(szFileName, sizeof(TBlockStream), dwStreamFlags); + if(pStream == NULL) + return NULL; + + // Sanity check + assert(pStream->BaseOpen != NULL); + + // Get the length of the file name without numeric suffix + nNameLength = _tcslen(pStream->szFileName); + if(pStream->szFileName[nNameLength - 2] == '.' && pStream->szFileName[nNameLength - 1] == '0') + nNameLength -= 2; + pStream->szFileName[nNameLength] = 0; + + // Supply the stream functions + pStream->StreamRead = (STREAM_READ)BlockStream_Read; + pStream->StreamGetSize = BlockStream_GetSize; + pStream->StreamGetPos = BlockStream_GetPos; + pStream->StreamClose = (STREAM_CLOSE)Block4Stream_Close; + pStream->BlockRead = (BLOCK_READ)Block4Stream_BlockRead; + + // Allocate work space for numeric names + szNameBuff = STORM_ALLOC(TCHAR, nNameLength + 4); + if(szNameBuff != NULL) + { + // Set the base flags + dwBaseFlags = (dwStreamFlags & STREAM_PROVIDERS_MASK) | STREAM_FLAG_READ_ONLY; + + // Go all suffixes from 0 to 30 + for(int nSuffix = 0; nSuffix < 30; nSuffix++) + { + // Open the n-th file + CreateNameWithSuffix(szNameBuff, nNameLength + 4, pStream->szFileName, nSuffix); + if(!pStream->BaseOpen(pStream, szNameBuff, dwBaseFlags)) + break; + + // If the open succeeded, we re-allocate the base provider array + NewBaseArray = STORM_ALLOC(TBaseProviderData, dwBaseFiles + 1); + if(NewBaseArray == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + + // Copy the old base data array to the new base data array + if(pStream->FileBitmap != NULL) + { + memcpy(NewBaseArray, pStream->FileBitmap, sizeof(TBaseProviderData) * dwBaseFiles); + STORM_FREE(pStream->FileBitmap); + } + + // Also copy the opened base array + memcpy(NewBaseArray + dwBaseFiles, &pStream->Base, sizeof(TBaseProviderData)); + pStream->FileBitmap = NewBaseArray; + dwBaseFiles++; + + // Get the size of the base stream + pStream->BaseGetSize(pStream, &FileSize); + assert(FileSize <= BLOCK4_MAX_FSIZE); + RemainderBlock = FileSize % (BLOCK4_BLOCK_SIZE + BLOCK4_HASH_SIZE); + BlockCount = FileSize / (BLOCK4_BLOCK_SIZE + BLOCK4_HASH_SIZE); + + // Increment the stream size and number of blocks + pStream->StreamSize += (BlockCount * BLOCK4_BLOCK_SIZE); + pStream->BlockCount += (DWORD)BlockCount; + + // Is this the last file? + if(FileSize < BLOCK4_MAX_FSIZE) + { + if(RemainderBlock) + { + pStream->StreamSize += (RemainderBlock - BLOCK4_HASH_SIZE); + pStream->BlockCount++; + } + break; + } + } + + // Fill the remainining block stream variables + pStream->BitmapSize = dwBaseFiles; + pStream->BlockSize = BLOCK4_BLOCK_SIZE; + pStream->IsComplete = 1; + pStream->IsModified = 0; + + // Fill the remaining stream variables + pStream->StreamPos = 0; + pStream->dwFlags |= STREAM_FLAG_READ_ONLY; + + STORM_FREE(szNameBuff); + } + + // If we opened something, return success + if(dwBaseFiles == 0) + { + FileStream_Close(pStream); + SetLastError(ERROR_FILE_NOT_FOUND); + pStream = NULL; + } + + return pStream; +} + +//----------------------------------------------------------------------------- +// Public functions + +/** + * This function creates a new file for read-write access + * + * - If the current platform supports file sharing, + * the file must be created for read sharing (i.e. another application + * can open the file for read, but not for write) + * - If the file does not exist, the function must create new one + * - If the file exists, the function must rewrite it and set to zero size + * - The parameters of the function must be validate by the caller + * - The function must initialize all stream function pointers in TFileStream + * - If the function fails from any reason, it must close all handles + * and free all memory that has been allocated in the process of stream creation, + * including the TFileStream structure itself + * + * \a szFileName Name of the file to create + */ + +TFileStream * FileStream_CreateFile( + const TCHAR * szFileName, + DWORD dwStreamFlags) +{ + TFileStream * pStream; + + // We only support creation of flat, local file + if((dwStreamFlags & (STREAM_PROVIDERS_MASK)) != (STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE)) + { + SetLastError(ERROR_NOT_SUPPORTED); + return NULL; + } + + // Allocate file stream structure for flat stream + pStream = AllocateFileStream(szFileName, sizeof(TBlockStream), dwStreamFlags); + if(pStream != NULL) + { + // Attempt to create the disk file + if(BaseFile_Create(pStream)) + { + // Fill the stream provider functions + pStream->StreamRead = pStream->BaseRead; + pStream->StreamWrite = pStream->BaseWrite; + pStream->StreamResize = pStream->BaseResize; + pStream->StreamGetSize = pStream->BaseGetSize; + pStream->StreamGetPos = pStream->BaseGetPos; + pStream->StreamClose = pStream->BaseClose; + return pStream; + } + + // File create failed, delete the stream + STORM_FREE(pStream); + pStream = NULL; + } + + // Return the stream + return pStream; +} + +/** + * This function opens an existing file for read or read-write access + * - If the current platform supports file sharing, + * the file must be open for read sharing (i.e. another application + * can open the file for read, but not for write) + * - If the file does not exist, the function must return NULL + * - If the file exists but cannot be open, then function must return NULL + * - The parameters of the function must be validate by the caller + * - The function must initialize all stream function pointers in TFileStream + * - If the function fails from any reason, it must close all handles + * and free all memory that has been allocated in the process of stream creation, + * including the TFileStream structure itself + * + * \a szFileName Name of the file to open + * \a dwStreamFlags specifies the provider and base storage type + */ + +TFileStream * FileStream_OpenFile( + const TCHAR * szFileName, + DWORD dwStreamFlags) +{ + DWORD dwProvider = dwStreamFlags & STREAM_PROVIDERS_MASK; + size_t nPrefixLength = FileStream_Prefix(szFileName, &dwProvider); + + // Re-assemble the stream flags + dwStreamFlags = (dwStreamFlags & STREAM_OPTIONS_MASK) | dwProvider; + szFileName += nPrefixLength; + + // Perform provider-specific open + switch(dwStreamFlags & STREAM_PROVIDER_MASK) + { + case STREAM_PROVIDER_FLAT: + return FlatStream_Open(szFileName, dwStreamFlags); + + case STREAM_PROVIDER_PARTIAL: + return PartStream_Open(szFileName, dwStreamFlags); + + case STREAM_PROVIDER_MPQE: + return MpqeStream_Open(szFileName, dwStreamFlags); + + case STREAM_PROVIDER_BLOCK4: + return Block4Stream_Open(szFileName, dwStreamFlags); + + default: + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } +} + +/** + * Returns the file name of the stream + * + * \a pStream Pointer to an open stream + */ +const TCHAR * FileStream_GetFileName(TFileStream * pStream) +{ + assert(pStream != NULL); + return pStream->szFileName; +} + +/** + * Returns the length of the provider prefix. Returns zero if no prefix + * + * \a szFileName Pointer to a stream name (file, mapped file, URL) + * \a pdwStreamProvider Pointer to a DWORD variable that receives stream provider (STREAM_PROVIDER_XXX) + */ + +size_t FileStream_Prefix(const TCHAR * szFileName, DWORD * pdwProvider) +{ + size_t nPrefixLength1 = 0; + size_t nPrefixLength2 = 0; + DWORD dwProvider = 0; + + if(szFileName != NULL) + { + // + // Determine the stream provider + // + + if(!_tcsnicmp(szFileName, _T("flat-"), 5)) + { + dwProvider |= STREAM_PROVIDER_FLAT; + nPrefixLength1 = 5; + } + + else if(!_tcsnicmp(szFileName, _T("part-"), 5)) + { + dwProvider |= STREAM_PROVIDER_PARTIAL; + nPrefixLength1 = 5; + } + + else if(!_tcsnicmp(szFileName, _T("mpqe-"), 5)) + { + dwProvider |= STREAM_PROVIDER_MPQE; + nPrefixLength1 = 5; + } + + else if(!_tcsnicmp(szFileName, _T("blk4-"), 5)) + { + dwProvider |= STREAM_PROVIDER_BLOCK4; + nPrefixLength1 = 5; + } + + // + // Determine the base provider + // + + if(!_tcsnicmp(szFileName+nPrefixLength1, _T("file:"), 5)) + { + dwProvider |= BASE_PROVIDER_FILE; + nPrefixLength2 = 5; + } + + else if(!_tcsnicmp(szFileName+nPrefixLength1, _T("map:"), 4)) + { + dwProvider |= BASE_PROVIDER_MAP; + nPrefixLength2 = 4; + } + + else if(!_tcsnicmp(szFileName+nPrefixLength1, _T("http:"), 5)) + { + dwProvider |= BASE_PROVIDER_HTTP; + nPrefixLength2 = 5; + } + + // Only accept stream provider if we recognized the base provider + if(nPrefixLength2 != 0) + { + // It is also allowed to put "//" after the base provider, e.g. "file://", "http://" + if(szFileName[nPrefixLength1+nPrefixLength2] == '/' && szFileName[nPrefixLength1+nPrefixLength2+1] == '/') + nPrefixLength2 += 2; + + if(pdwProvider != NULL) + *pdwProvider = dwProvider; + return nPrefixLength1 + nPrefixLength2; + } + } + + return 0; +} + +/** + * Sets a download callback. Whenever the stream needs to download one or more blocks + * from the server, the callback is called + * + * \a pStream Pointer to an open stream + * \a pfnCallback Pointer to callback function + * \a pvUserData Arbitrary user pointer passed to the download callback + */ + +bool FileStream_SetCallback(TFileStream * pStream, SFILE_DOWNLOAD_CALLBACK pfnCallback, void * pvUserData) +{ + TBlockStream * pBlockStream = (TBlockStream *)pStream; + + if(pStream->BlockRead == NULL) + { + SetLastError(ERROR_NOT_SUPPORTED); + return false; + } + + pBlockStream->pfnCallback = pfnCallback; + pBlockStream->UserData = pvUserData; + return true; +} + +/** + * This function gives the block map. The 'pvBitmap' pointer must point to a buffer + * of at least sizeof(STREAM_BLOCK_MAP) size. It can also have size of the complete + * block map (i.e. sizeof(STREAM_BLOCK_MAP) + BitmapSize). In that case, the function + * also copies the bit-based block map. + * + * \a pStream Pointer to an open stream + * \a pvBitmap Pointer to buffer where the block map will be stored + * \a cbBitmap Length of the buffer, of the block map + * \a cbLengthNeeded Length of the bitmap, in bytes + */ + +bool FileStream_GetBitmap(TFileStream * pStream, void * pvBitmap, DWORD cbBitmap, DWORD * pcbLengthNeeded) +{ + TStreamBitmap * pBitmap = (TStreamBitmap *)pvBitmap; + TBlockStream * pBlockStream = (TBlockStream *)pStream; + ULONGLONG BlockOffset; + LPBYTE Bitmap = (LPBYTE)(pBitmap + 1); + DWORD BitmapSize; + DWORD BlockCount; + DWORD BlockSize; + bool bResult = false; + + // Retrieve the size of one block + if(pStream->BlockCheck != NULL) + { + BlockCount = pBlockStream->BlockCount; + BlockSize = pBlockStream->BlockSize; + } + else + { + BlockCount = (DWORD)((pStream->StreamSize + DEFAULT_BLOCK_SIZE - 1) / DEFAULT_BLOCK_SIZE); + BlockSize = DEFAULT_BLOCK_SIZE; + } + + // Fill-in the variables + BitmapSize = (BlockCount + 7) / 8; + + // Give the number of blocks + if(pcbLengthNeeded != NULL) + pcbLengthNeeded[0] = sizeof(TStreamBitmap) + BitmapSize; + + // If the length of the buffer is not enough + if(pvBitmap != NULL && cbBitmap != 0) + { + // Give the STREAM_BLOCK_MAP structure + if(cbBitmap >= sizeof(TStreamBitmap)) + { + pBitmap->StreamSize = pStream->StreamSize; + pBitmap->BitmapSize = BitmapSize; + pBitmap->BlockCount = BlockCount; + pBitmap->BlockSize = BlockSize; + pBitmap->IsComplete = (pStream->BlockCheck != NULL) ? pBlockStream->IsComplete : 1; + bResult = true; + } + + // Give the block bitmap, if enough space + if(cbBitmap >= sizeof(TStreamBitmap) + BitmapSize) + { + // Version with bitmap present + if(pStream->BlockCheck != NULL) + { + DWORD ByteIndex = 0; + BYTE BitMask = 0x01; + + // Initialize the map with zeros + memset(Bitmap, 0, BitmapSize); + + // Fill the map + for(BlockOffset = 0; BlockOffset < pStream->StreamSize; BlockOffset += BlockSize) + { + // Set the bit if the block is present + if(pBlockStream->BlockCheck(pStream, BlockOffset)) + Bitmap[ByteIndex] |= BitMask; + + // Move bit position + ByteIndex += (BitMask >> 0x07); + BitMask = (BitMask >> 0x07) | (BitMask << 0x01); + } + } + else + { + memset(Bitmap, 0xFF, BitmapSize); + } + } + } + + // Set last error value and return + if(bResult == false) + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return bResult; +} + +/** + * Reads data from the stream + * + * - Returns true if the read operation succeeded and all bytes have been read + * - Returns false if either read failed or not all bytes have been read + * - If the pByteOffset is NULL, the function must read the data from the current file position + * - The function can be called with dwBytesToRead = 0. In that case, pvBuffer is ignored + * and the function just adjusts file pointer. + * + * \a pStream Pointer to an open stream + * \a pByteOffset Pointer to file byte offset. If NULL, it reads from the current position + * \a pvBuffer Pointer to data to be read + * \a dwBytesToRead Number of bytes to read from the file + * + * \returns + * - If the function reads the required amount of bytes, it returns true. + * - If the function reads less than required bytes, it returns false and GetLastError() returns ERROR_HANDLE_EOF + * - If the function fails, it reads false and GetLastError() returns an error code different from ERROR_HANDLE_EOF + */ +bool FileStream_Read(TFileStream * pStream, ULONGLONG * pByteOffset, void * pvBuffer, DWORD dwBytesToRead) +{ + assert(pStream->StreamRead != NULL); + return pStream->StreamRead(pStream, pByteOffset, pvBuffer, dwBytesToRead); +} + +/** + * This function writes data to the stream + * + * - Returns true if the write operation succeeded and all bytes have been written + * - Returns false if either write failed or not all bytes have been written + * - If the pByteOffset is NULL, the function must write the data to the current file position + * + * \a pStream Pointer to an open stream + * \a pByteOffset Pointer to file byte offset. If NULL, it reads from the current position + * \a pvBuffer Pointer to data to be written + * \a dwBytesToWrite Number of bytes to write to the file + */ +bool FileStream_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite) +{ + if(pStream->dwFlags & STREAM_FLAG_READ_ONLY) + { + SetLastError(ERROR_ACCESS_DENIED); + return false; + } + + assert(pStream->StreamWrite != NULL); + return pStream->StreamWrite(pStream, pByteOffset, pvBuffer, dwBytesToWrite); +} + +/** + * Returns the size of a file + * + * \a pStream Pointer to an open stream + * \a FileSize Pointer where to store the file size + */ +bool FileStream_GetSize(TFileStream * pStream, ULONGLONG * pFileSize) +{ + assert(pStream->StreamGetSize != NULL); + return pStream->StreamGetSize(pStream, pFileSize); +} + +/** + * Sets the size of a file + * + * \a pStream Pointer to an open stream + * \a NewFileSize File size to set + */ +bool FileStream_SetSize(TFileStream * pStream, ULONGLONG NewFileSize) +{ + if(pStream->dwFlags & STREAM_FLAG_READ_ONLY) + { + SetLastError(ERROR_ACCESS_DENIED); + return false; + } + + assert(pStream->StreamResize != NULL); + return pStream->StreamResize(pStream, NewFileSize); +} + +/** + * This function returns the current file position + * \a pStream + * \a pByteOffset + */ +bool FileStream_GetPos(TFileStream * pStream, ULONGLONG * pByteOffset) +{ + assert(pStream->StreamGetPos != NULL); + return pStream->StreamGetPos(pStream, pByteOffset); +} + +/** + * Returns the last write time of a file + * + * \a pStream Pointer to an open stream + * \a pFileType Pointer where to store the file last write time + */ +bool FileStream_GetTime(TFileStream * pStream, ULONGLONG * pFileTime) +{ + // Just use the saved filetime value + *pFileTime = pStream->Base.File.FileTime; + return true; +} + +/** + * Returns the stream flags + * + * \a pStream Pointer to an open stream + * \a pdwStreamFlags Pointer where to store the stream flags + */ +bool FileStream_GetFlags(TFileStream * pStream, LPDWORD pdwStreamFlags) +{ + *pdwStreamFlags = pStream->dwFlags; + return true; +} + +/** + * Switches a stream with another. Used for final phase of archive compacting. + * Performs these steps: + * + * 1) Closes the handle to the existing MPQ + * 2) Renames the temporary MPQ to the original MPQ, overwrites existing one + * 3) Opens the MPQ stores the handle and stream position to the new stream structure + * + * \a pStream Pointer to an open stream + * \a pNewStream Temporary ("working") stream (created during archive compacting) + */ +bool FileStream_Replace(TFileStream * pStream, TFileStream * pNewStream) +{ + // Only supported on flat files + if((pStream->dwFlags & STREAM_PROVIDERS_MASK) != (STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE)) + { + SetLastError(ERROR_NOT_SUPPORTED); + return false; + } + + // Not supported on read-only streams + if(pStream->dwFlags & STREAM_FLAG_READ_ONLY) + { + SetLastError(ERROR_ACCESS_DENIED); + return false; + } + + // Close both stream's base providers + pNewStream->BaseClose(pNewStream); + pStream->BaseClose(pStream); + + // Now we have to delete the (now closed) old file and rename the new file + if(!BaseFile_Replace(pStream, pNewStream)) + return false; + + // Now open the base file again + if(!BaseFile_Open(pStream, pStream->szFileName, pStream->dwFlags)) + return false; + + // Cleanup the new stream + FileStream_Close(pNewStream); + return true; +} + +/** + * This function closes an archive file and frees any data buffers + * that have been allocated for stream management. The function must also + * support partially allocated structure, i.e. one or more buffers + * can be NULL, if there was an allocation failure during the process + * + * \a pStream Pointer to an open stream + */ +void FileStream_Close(TFileStream * pStream) +{ + // Check if the stream structure is allocated at all + if(pStream != NULL) + { + // Free the master stream, if any + if(pStream->pMaster != NULL) + FileStream_Close(pStream->pMaster); + pStream->pMaster = NULL; + + // Close the stream provider + if(pStream->StreamClose != NULL) + pStream->StreamClose(pStream); + + // ... or close base stream, if any + else if(pStream->BaseClose != NULL) + pStream->BaseClose(pStream); + + // Free the stream itself + STORM_FREE(pStream); + } +} diff --git a/StormLib/src/FileStream.h b/StormLib/src/FileStream.h new file mode 100644 index 000000000..2bc118b28 --- /dev/null +++ b/StormLib/src/FileStream.h @@ -0,0 +1,217 @@ +/*****************************************************************************/ +/* FileStream.h Copyright (c) Ladislav Zezula 2012 */ +/*---------------------------------------------------------------------------*/ +/* Description: Definitions for FileStream object */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 14.04.12 1.00 Lad The first version of FileStream.h */ +/*****************************************************************************/ + +#ifndef __FILESTREAM_H__ +#define __FILESTREAM_H__ + +//----------------------------------------------------------------------------- +// Function prototypes + +typedef void (*STREAM_INIT)( + struct TFileStream * pStream // Pointer to an unopened stream +); + +typedef bool (*STREAM_CREATE)( + struct TFileStream * pStream // Pointer to an unopened stream + ); + +typedef bool (*STREAM_OPEN)( + struct TFileStream * pStream, // Pointer to an unopened stream + const TCHAR * szFileName, // Pointer to file name to be open + DWORD dwStreamFlags // Stream flags + ); + +typedef bool (*STREAM_READ)( + struct TFileStream * pStream, // Pointer to an open stream + ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position + void * pvBuffer, // Pointer to data to be read + DWORD dwBytesToRead // Number of bytes to read from the file + ); + +typedef bool (*STREAM_WRITE)( + struct TFileStream * pStream, // Pointer to an open stream + ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it writes to the current position + const void * pvBuffer, // Pointer to data to be written + DWORD dwBytesToWrite // Number of bytes to read from the file + ); + +typedef bool (*STREAM_RESIZE)( + struct TFileStream * pStream, // Pointer to an open stream + ULONGLONG FileSize // New size for the file, in bytes + ); + +typedef bool (*STREAM_GETSIZE)( + struct TFileStream * pStream, // Pointer to an open stream + ULONGLONG * pFileSize // Receives the file size, in bytes + ); + +typedef bool (*STREAM_GETPOS)( + struct TFileStream * pStream, // Pointer to an open stream + ULONGLONG * pByteOffset // Pointer to store current file position + ); + +typedef void (*STREAM_CLOSE)( + struct TFileStream * pStream // Pointer to an open stream + ); + +typedef bool (*BLOCK_READ)( + struct TFileStream * pStream, // Pointer to a block-oriented stream + ULONGLONG StartOffset, // Byte offset of start of the block array + ULONGLONG EndOffset, // End offset (either end of the block or end of the file) + LPBYTE BlockBuffer, // Pointer to block-aligned buffer + DWORD BytesNeeded, // Number of bytes that are really needed + bool bAvailable // true if the block is available + ); + +typedef bool (*BLOCK_CHECK)( + struct TFileStream * pStream, // Pointer to a block-oriented stream + ULONGLONG BlockOffset // Offset of the file to check + ); + +typedef void (*BLOCK_SAVEMAP)( + struct TFileStream * pStream // Pointer to a block-oriented stream + ); + +//----------------------------------------------------------------------------- +// Local structures - partial file structure and bitmap footer + +#define ID_FILE_BITMAP_FOOTER 0x33767470 // Signature of the file bitmap footer ('ptv3') +#define DEFAULT_BLOCK_SIZE 0x00004000 // Default size of the stream block +#define DEFAULT_BUILD_NUMBER 10958 // Build number for newly created partial MPQs + +typedef struct _PART_FILE_HEADER +{ + DWORD PartialVersion; // Always set to 2 + char GameBuildNumber[0x20]; // Minimum build number of the game that can use this MPQ + DWORD Flags; // Flags (details unknown) + DWORD FileSizeLo; // Low 32 bits of the contained file size + DWORD FileSizeHi; // High 32 bits of the contained file size + DWORD BlockSize; // Size of one file block, in bytes + +} PART_FILE_HEADER, *PPART_FILE_HEADER; + +// Structure describing the block-to-file map entry +typedef struct _PART_FILE_MAP_ENTRY +{ + DWORD Flags; // 3 = the block is present in the file + DWORD BlockOffsLo; // Low 32 bits of the block position in the file + DWORD BlockOffsHi; // High 32 bits of the block position in the file + DWORD LargeValueLo; // 64-bit value, meaning is unknown + DWORD LargeValueHi; + +} PART_FILE_MAP_ENTRY, *PPART_FILE_MAP_ENTRY; + +typedef struct _FILE_BITMAP_FOOTER +{ + DWORD Signature; // 'ptv3' (ID_FILE_BITMAP_FOOTER) + DWORD Version; // Unknown, seems to always have value of 3 (version?) + DWORD BuildNumber; // Game build number for that MPQ + DWORD MapOffsetLo; // Low 32-bits of the offset of the bit map + DWORD MapOffsetHi; // High 32-bits of the offset of the bit map + DWORD BlockSize; // Size of one block (usually 0x4000 bytes) + +} FILE_BITMAP_FOOTER, *PFILE_BITMAP_FOOTER; + +//----------------------------------------------------------------------------- +// Structure for file stream + +union TBaseProviderData +{ + struct + { + ULONGLONG FileSize; // Size of the file + ULONGLONG FilePos; // Current file position + ULONGLONG FileTime; // Last write time + HANDLE hFile; // File handle + } File; + + struct + { + ULONGLONG FileSize; // Size of the file + ULONGLONG FilePos; // Current file position + ULONGLONG FileTime; // Last write time + LPBYTE pbFile; // Pointer to mapped view + } Map; + + struct + { + ULONGLONG FileSize; // Size of the file + ULONGLONG FilePos; // Current file position + ULONGLONG FileTime; // Last write time + HANDLE hInternet; // Internet handle + HANDLE hConnect; // Connection to the internet server + } Http; +}; + +struct TFileStream +{ + // Stream provider functions + STREAM_READ StreamRead; // Pointer to stream read function for this archive. Do not use directly. + STREAM_WRITE StreamWrite; // Pointer to stream write function for this archive. Do not use directly. + STREAM_RESIZE StreamResize; // Pointer to function changing file size + STREAM_GETSIZE StreamGetSize; // Pointer to function returning file size + STREAM_GETPOS StreamGetPos; // Pointer to function that returns current file position + STREAM_CLOSE StreamClose; // Pointer to function closing the stream + + // Block-oriented functions + BLOCK_READ BlockRead; // Pointer to function reading one or more blocks + BLOCK_CHECK BlockCheck; // Pointer to function checking whether the block is present + + // Base provider functions + STREAM_CREATE BaseCreate; // Pointer to base create function + STREAM_OPEN BaseOpen; // Pointer to base open function + STREAM_READ BaseRead; // Read from the stream + STREAM_WRITE BaseWrite; // Write to the stream + STREAM_RESIZE BaseResize; // Pointer to function changing file size + STREAM_GETSIZE BaseGetSize; // Pointer to function returning file size + STREAM_GETPOS BaseGetPos; // Pointer to function that returns current file position + STREAM_CLOSE BaseClose; // Pointer to function closing the stream + + // Base provider data (file size, file position) + TBaseProviderData Base; + + // Stream provider data + TFileStream * pMaster; // Master stream (e.g. MPQ on a web server) + TCHAR * szFileName; // File name (self-relative pointer) + + ULONGLONG StreamSize; // Stream size (can be less than file size) + ULONGLONG StreamPos; // Stream position + DWORD BuildNumber; // Game build number + DWORD dwFlags; // Stream flags + + // Followed by stream provider data, with variable length +}; + +//----------------------------------------------------------------------------- +// Structures for block-oriented stream + +struct TBlockStream : public TFileStream +{ + SFILE_DOWNLOAD_CALLBACK pfnCallback; // Callback for downloading + void * FileBitmap; // Array of bits for file blocks + void * UserData; // User data to be passed to the download callback + DWORD BitmapSize; // Size of the file bitmap (in bytes) + DWORD BlockSize; // Size of one block, in bytes + DWORD BlockCount; // Number of data blocks in the file + DWORD IsComplete; // If nonzero, no blocks are missing + DWORD IsModified; // nonzero if the bitmap has been modified +}; + +//----------------------------------------------------------------------------- +// Structure for encrypted stream + +#define MPQE_CHUNK_SIZE 0x40 // Size of one chunk to be decrypted + +struct TEncryptedStream : public TBlockStream +{ + BYTE Key[MPQE_CHUNK_SIZE]; // File key +}; + +#endif // __FILESTREAM_H__ diff --git a/StormLib/src/SBaseCommon.cpp b/StormLib/src/SBaseCommon.cpp new file mode 100644 index 000000000..fcb50a927 --- /dev/null +++ b/StormLib/src/SBaseCommon.cpp @@ -0,0 +1,1967 @@ +/*****************************************************************************/ +/* SBaseCommon.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Common functions for StormLib, used by all SFile*** modules */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 24.03.03 1.00 Lad The first version of SFileCommon.cpp */ +/* 19.11.03 1.01 Dan Big endian handling */ +/* 12.06.04 1.01 Lad Renamed to SCommon.cpp */ +/* 06.09.10 1.01 Lad Renamed to SBaseCommon.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" + +char StormLibCopyright[] = "StormLib v " STORMLIB_VERSION_STRING " Copyright Ladislav Zezula 1998-2014"; + +//----------------------------------------------------------------------------- +// Local variables + +DWORD g_dwMpqSignature = ID_MPQ; // Marker for MPQ header +DWORD g_dwHashTableKey = MPQ_KEY_HASH_TABLE; // Key for hash table +DWORD g_dwBlockTableKey = MPQ_KEY_BLOCK_TABLE; // Key for block table +LCID g_lcFileLocale = LANG_NEUTRAL; // File locale +USHORT wPlatform = 0; // File platform + +//----------------------------------------------------------------------------- +// Conversion to uppercase/lowercase + +// Converts ASCII characters to lowercase +// Converts slash (0x2F) to backslash (0x5C) +unsigned char AsciiToLowerTable[256] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x5C, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF +}; + +// Converts ASCII characters to uppercase +// Converts backslash (0x5C) to backslash (0x2F) +unsigned char AsciiToUpperTable[256] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x5C, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF +}; + +// Converts ASCII characters to uppercase +// Does NOT convert slash (0x2F) to backslash (0x5C) +unsigned char AsciiToUpperTable_Slash[256] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF +}; + +//----------------------------------------------------------------------------- +// Safe string functions (for ANSI builds) + +char * StringCopy(char * szTarget, size_t cchTarget, const char * szSource) +{ + size_t cchSource = 0; + + if(cchTarget > 0) + { + cchSource = strlen(szSource); + + if(cchSource >= cchTarget) + cchSource = cchTarget - 1; + + memcpy(szTarget, szSource, cchSource); + szTarget[cchSource] = 0; + } + + return szTarget + cchSource; +} + +void StringCat(char * szTarget, size_t cchTargetMax, const char * szSource) +{ + // Get the current length of the target + size_t cchTarget = strlen(szTarget); + + // Copy the string to the target + if(cchTarget < cchTargetMax) + { + StringCopy(szTarget + cchTarget, (cchTargetMax - cchTarget), szSource); + } +} + +void StringCreatePseudoFileName(char * szBuffer, size_t cchMaxChars, unsigned int nIndex, const char * szExtension) +{ + char * szBufferEnd = szBuffer + cchMaxChars; + + // "File" + szBuffer = StringCopy(szBuffer, (szBufferEnd - szBuffer), "File"); + + // Number + szBuffer = IntToString(szBuffer, szBufferEnd - szBuffer + 1, nIndex, 8); + + // Dot + if(szBuffer < szBufferEnd) + *szBuffer++ = '.'; + + // Extension + while(szExtension[0] == '.') + szExtension++; + StringCopy(szBuffer, (szBufferEnd - szBuffer), szExtension); +} + +//----------------------------------------------------------------------------- +// Utility functions (UNICODE) only exist in the ANSI version of the library +// In ANSI builds, TCHAR = char, so we don't need these functions implemented + +#ifdef _UNICODE +void StringCopy(TCHAR * szTarget, size_t cchTarget, const char * szSource) +{ + if(cchTarget > 0) + { + size_t cchSource = strlen(szSource); + + if(cchSource >= cchTarget) + cchSource = cchTarget - 1; + + mbstowcs(szTarget, szSource, cchSource); + szTarget[cchSource] = 0; + } +} + +void StringCopy(char * szTarget, size_t cchTarget, const TCHAR * szSource) +{ + if(cchTarget > 0) + { + size_t cchSource = _tcslen(szSource); + + if(cchSource >= cchTarget) + cchSource = cchTarget - 1; + + wcstombs(szTarget, szSource, cchSource); + szTarget[cchSource] = 0; + } +} + +void StringCopy(TCHAR * szTarget, size_t cchTarget, const TCHAR * szSource) +{ + if(cchTarget > 0) + { + size_t cchSource = _tcslen(szSource); + + if(cchSource >= cchTarget) + cchSource = cchTarget - 1; + + memcpy(szTarget, szSource, cchSource * sizeof(TCHAR)); + szTarget[cchSource] = 0; + } +} + +void StringCat(TCHAR * szTarget, size_t cchTargetMax, const TCHAR * szSource) +{ + // Get the current length of the target + size_t cchTarget = _tcslen(szTarget); + + // Copy the string to the target + if(cchTarget < cchTargetMax) + { + StringCopy(szTarget + cchTarget, (cchTargetMax - cchTarget), szSource); + } +} +#endif + +//----------------------------------------------------------------------------- +// Storm hashing functions + +#define STORM_BUFFER_SIZE 0x500 +#define HASH_INDEX_MASK(ha) (ha->pHeader->dwHashTableSize ? (ha->pHeader->dwHashTableSize - 1) : 0) + +static DWORD StormBuffer[STORM_BUFFER_SIZE]; // Buffer for the decryption engine +static bool bMpqCryptographyInitialized = false; + +void InitializeMpqCryptography() +{ + DWORD dwSeed = 0x00100001; + DWORD index1 = 0; + DWORD index2 = 0; + int i; + + // Initialize the decryption buffer. + // Do nothing if already done. + if(bMpqCryptographyInitialized == false) + { + for(index1 = 0; index1 < 0x100; index1++) + { + for(index2 = index1, i = 0; i < 5; i++, index2 += 0x100) + { + DWORD temp1, temp2; + + dwSeed = (dwSeed * 125 + 3) % 0x2AAAAB; + temp1 = (dwSeed & 0xFFFF) << 0x10; + + dwSeed = (dwSeed * 125 + 3) % 0x2AAAAB; + temp2 = (dwSeed & 0xFFFF); + + StormBuffer[index2] = (temp1 | temp2); + } + } + + // Also register both MD5 and SHA1 hash algorithms + register_hash(&md5_desc); + register_hash(&sha1_desc); + + // Use LibTomMath as support math library for LibTomCrypt + ltc_mp = ltm_desc; + + // Don't do that again + bMpqCryptographyInitialized = true; + } +} + +// +// Note: Implementation of this function in WorldEdit.exe and storm.dll +// incorrectly treats the character as signed, which leads to the +// a buffer underflow if the character in the file name >= 0x80: +// The following steps happen when *pbKey == 0xBF and dwHashType == 0x0000 +// (calculating hash index) +// +// 1) Result of AsciiToUpperTable_Slash[*pbKey++] is sign-extended to 0xffffffbf +// 2) The "ch" is added to dwHashType (0xffffffbf + 0x0000 => 0xffffffbf) +// 3) The result is used as index to the StormBuffer table, +// thus dereferences a random value BEFORE the begin of StormBuffer. +// +// As result, MPQs containing files with non-ANSI characters will not work between +// various game versions and localizations. Even WorldEdit, after importing a file +// with Korean characters in the name, cannot open the file back. +// +DWORD HashString(const char * szFileName, DWORD dwHashType) +{ + LPBYTE pbKey = (BYTE *)szFileName; + DWORD dwSeed1 = 0x7FED7FED; + DWORD dwSeed2 = 0xEEEEEEEE; + DWORD ch; + + while(*pbKey != 0) + { + // Convert the input character to uppercase + // Convert slash (0x2F) to backslash (0x5C) + ch = AsciiToUpperTable[*pbKey++]; + + dwSeed1 = StormBuffer[dwHashType + ch] ^ (dwSeed1 + dwSeed2); + dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3; + } + + return dwSeed1; +} + +DWORD HashStringSlash(const char * szFileName, DWORD dwHashType) +{ + LPBYTE pbKey = (BYTE *)szFileName; + DWORD dwSeed1 = 0x7FED7FED; + DWORD dwSeed2 = 0xEEEEEEEE; + DWORD ch; + + while(*pbKey != 0) + { + // Convert the input character to uppercase + // DON'T convert slash (0x2F) to backslash (0x5C) + //ch = AsciiToUpperTable_Slash[*pbKey++]; + ch = AsciiToUpperTable[*pbKey++]; + + dwSeed1 = StormBuffer[dwHashType + ch] ^ (dwSeed1 + dwSeed2); + dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3; + } + + return dwSeed1; +} + +DWORD HashStringLower(const char * szFileName, DWORD dwHashType) +{ + LPBYTE pbKey = (BYTE *)szFileName; + DWORD dwSeed1 = 0x7FED7FED; + DWORD dwSeed2 = 0xEEEEEEEE; + DWORD ch; + + while(*pbKey != 0) + { + // Convert the input character to lower + // DON'T convert slash (0x2F) to backslash (0x5C) + ch = AsciiToLowerTable[*pbKey++]; + + dwSeed1 = StormBuffer[dwHashType + ch] ^ (dwSeed1 + dwSeed2); + dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3; + } + + return dwSeed1; +} + +//----------------------------------------------------------------------------- +// Calculates the hash table size for a given amount of files + +// Returns the nearest higher power of two. +// If the value is already a power of two, returns the same value +DWORD GetNearestPowerOfTwo(DWORD dwFileCount) +{ + dwFileCount --; + + dwFileCount |= dwFileCount >> 1; + dwFileCount |= dwFileCount >> 2; + dwFileCount |= dwFileCount >> 4; + dwFileCount |= dwFileCount >> 8; + dwFileCount |= dwFileCount >> 16; + + return dwFileCount + 1; +} +/* +DWORD GetNearestPowerOfTwo(DWORD dwFileCount) +{ + DWORD dwPowerOfTwo = HASH_TABLE_SIZE_MIN; + + // For zero files, there is no hash table needed + if(dwFileCount == 0) + return 0; + + // Round the hash table size up to the nearest power of two + // Don't allow the hash table size go over allowed maximum + while(dwPowerOfTwo < HASH_TABLE_SIZE_MAX && dwPowerOfTwo < dwFileCount) + dwPowerOfTwo <<= 1; + return dwPowerOfTwo; +} +*/ +//----------------------------------------------------------------------------- +// Calculates a Jenkin's Encrypting and decrypting MPQ file data + +ULONGLONG HashStringJenkins(const char * szFileName) +{ + LPBYTE pbFileName = (LPBYTE)szFileName; + char szNameBuff[0x108]; + size_t nLength = 0; + unsigned int primary_hash = 1; + unsigned int secondary_hash = 2; + + // Normalize the file name - convert to uppercase, and convert "/" to "\\". + if(pbFileName != NULL) + { + char * szNamePtr = szNameBuff; + char * szNameEnd = szNamePtr + sizeof(szNameBuff); + + // Normalize the file name. Doesn't have to be zero terminated for hashing + while(szNamePtr < szNameEnd && pbFileName[0] != 0) + *szNamePtr++ = (char)AsciiToLowerTable[*pbFileName++]; + nLength = szNamePtr - szNameBuff; + } + + // Thanks Quantam for finding out what the algorithm is. + // I am really getting old for reversing large chunks of assembly + // that does hashing :-) + hashlittle2(szNameBuff, nLength, &secondary_hash, &primary_hash); + + // Combine those 2 together + return ((ULONGLONG)primary_hash << 0x20) | (ULONGLONG)secondary_hash; +} + +//----------------------------------------------------------------------------- +// Default flags for (attributes) and (listfile) + +DWORD GetDefaultSpecialFileFlags(DWORD dwFileSize, USHORT wFormatVersion) +{ + // Fixed for format 1.0 + if(wFormatVersion == MPQ_FORMAT_VERSION_1) + return MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY; + + // Size-dependent for formats 2.0-4.0 + return (dwFileSize > 0x4000) ? (MPQ_FILE_COMPRESS | MPQ_FILE_SECTOR_CRC) : (MPQ_FILE_COMPRESS | MPQ_FILE_SINGLE_UNIT); +} + + +//----------------------------------------------------------------------------- +// Encrypting/Decrypting MPQ data block + +static DWORD EncryptUInt32Unaligned(LPDWORD DataPointer, DWORD i, DWORD dwXorKey) +{ + LPBYTE pbDataPointer = (LPBYTE)(DataPointer + i); + LPBYTE pbXorKey = (LPBYTE)(&dwXorKey); + DWORD dwValue32; + + // Retrieve the value + dwValue32 = ((DWORD)pbDataPointer[0] << 0x00) | + ((DWORD)pbDataPointer[1] << 0x08) | + ((DWORD)pbDataPointer[2] << 0x10) | + ((DWORD)pbDataPointer[3] << 0x18); + + // Perform unaligned XOR + pbDataPointer[0] = (pbDataPointer[0] ^ pbXorKey[0]); + pbDataPointer[1] = (pbDataPointer[1] ^ pbXorKey[1]); + pbDataPointer[2] = (pbDataPointer[2] ^ pbXorKey[2]); + pbDataPointer[3] = (pbDataPointer[3] ^ pbXorKey[3]); + return dwValue32; +} + +void EncryptMpqBlock(void * pvDataBlock, DWORD dwLength, DWORD dwKey1) +{ + LPDWORD DataPointer = (LPDWORD)pvDataBlock; + DWORD dwValue32; + DWORD dwKey2 = 0xEEEEEEEE; + + // Round to DWORDs + dwLength >>= 2; + + // We need different approach on non-aligned buffers + if(STORMLIB_DWORD_ALIGNED(DataPointer)) + { + for(DWORD i = 0; i < dwLength; i++) + { + // Modify the second key + dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)]; + + // We can use 32-bit approach, when the buffer is aligned + DataPointer[i] = (dwValue32 = DataPointer[i]) ^ (dwKey1 + dwKey2); + + dwKey1 = ((~dwKey1 << 0x15) + 0x11111111) | (dwKey1 >> 0x0B); + dwKey2 = dwValue32 + dwKey2 + (dwKey2 << 5) + 3; + } + } + else + { + for(DWORD i = 0; i < dwLength; i++) + { + // Modify the second key + dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)]; + + // The data are unaligned. Make sure we don't cause data misalignment error + dwValue32 = EncryptUInt32Unaligned(DataPointer, i, (dwKey1 + dwKey2)); + + dwKey1 = ((~dwKey1 << 0x15) + 0x11111111) | (dwKey1 >> 0x0B); + dwKey2 = dwValue32 + dwKey2 + (dwKey2 << 5) + 3; + } + } +} + +static DWORD DecryptUInt32Unaligned(LPDWORD DataPointer, DWORD i, DWORD dwXorKey) +{ + LPBYTE pbDataPointer = (LPBYTE)(DataPointer + i); + LPBYTE pbXorKey = (LPBYTE)(&dwXorKey); + + // Perform unaligned XOR + pbDataPointer[0] = (pbDataPointer[0] ^ pbXorKey[0]); + pbDataPointer[1] = (pbDataPointer[1] ^ pbXorKey[1]); + pbDataPointer[2] = (pbDataPointer[2] ^ pbXorKey[2]); + pbDataPointer[3] = (pbDataPointer[3] ^ pbXorKey[3]); + + // Retrieve the value + return ((DWORD)pbDataPointer[0] << 0x00) | + ((DWORD)pbDataPointer[1] << 0x08) | + ((DWORD)pbDataPointer[2] << 0x10) | + ((DWORD)pbDataPointer[3] << 0x18); +} + +void DecryptMpqBlock(void * pvDataBlock, DWORD dwLength, DWORD dwKey1) +{ + LPDWORD DataPointer = (LPDWORD)pvDataBlock; + DWORD dwValue32; + DWORD dwKey2 = 0xEEEEEEEE; + + // Round to DWORDs + dwLength >>= 2; + + // We need different approach on non-aligned buffers + if(STORMLIB_DWORD_ALIGNED(DataPointer)) + { + for(DWORD i = 0; i < dwLength; i++) + { + // Modify the second key + dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)]; + + // We can use 32-bit approach, when the buffer is aligned + DataPointer[i] = dwValue32 = DataPointer[i] ^ (dwKey1 + dwKey2); + + dwKey1 = ((~dwKey1 << 0x15) + 0x11111111) | (dwKey1 >> 0x0B); + dwKey2 = dwValue32 + dwKey2 + (dwKey2 << 5) + 3; + } + } + else + { + for(DWORD i = 0; i < dwLength; i++) + { + // Modify the second key + dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)]; + + // The data are unaligned. Make sure we don't cause data misalignment error + dwValue32 = DecryptUInt32Unaligned(DataPointer, i, (dwKey1 + dwKey2)); + + dwKey1 = ((~dwKey1 << 0x15) + 0x11111111) | (dwKey1 >> 0x0B); + dwKey2 = dwValue32 + dwKey2 + (dwKey2 << 5) + 3; + } + } +} + +/** + * Functions tries to get file decryption key. This comes from these facts + * + * - We know the decrypted value of the first DWORD in the encrypted data + * - We know the decrypted value of the second DWORD (at least aproximately) + * - There is only 256 variants of how the second key is modified + * + * The first iteration of dwKey1 and dwKey2 is this: + * + * dwKey2 = 0xEEEEEEEE + StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)] + * dwDecrypted0 = DataBlock[0] ^ (dwKey1 + dwKey2); + * + * This means: + * + * (dwKey1 + dwKey2) = DataBlock[0] ^ dwDecrypted0; + * + */ + +DWORD DetectFileKeyBySectorSize(LPDWORD EncryptedData, DWORD dwSectorSize, DWORD dwDecrypted0) +{ + DWORD dwDecrypted1Max = dwSectorSize + dwDecrypted0; + DWORD dwKey1PlusKey2; + DWORD DataBlock[2]; + + // We must have at least 2 DWORDs there to be able to decrypt something + if(dwSectorSize < 0x08) + return 0; + + // Get the value of the combined encryption key + dwKey1PlusKey2 = (EncryptedData[0] ^ dwDecrypted0) - 0xEEEEEEEE; + + // Try all 256 combinations of dwKey1 + for(DWORD i = 0; i < 0x100; i++) + { + DWORD dwSaveKey1; + DWORD dwKey1 = dwKey1PlusKey2 - StormBuffer[MPQ_HASH_KEY2_MIX + i]; + DWORD dwKey2 = 0xEEEEEEEE; + + // Modify the second key and decrypt the first DWORD + dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)]; + DataBlock[0] = EncryptedData[0] ^ (dwKey1 + dwKey2); + + // Did we obtain the same value like dwDecrypted0? + if(DataBlock[0] == dwDecrypted0) + { + // Save this key value. Increment by one because + // we are decrypting sector offset table + dwSaveKey1 = dwKey1 + 1; + + // Rotate both keys + dwKey1 = ((~dwKey1 << 0x15) + 0x11111111) | (dwKey1 >> 0x0B); + dwKey2 = DataBlock[0] + dwKey2 + (dwKey2 << 5) + 3; + + // Modify the second key again and decrypt the second DWORD + dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)]; + DataBlock[1] = EncryptedData[1] ^ (dwKey1 + dwKey2); + + // Now compare the results + if(DataBlock[1] <= dwDecrypted1Max) + return dwSaveKey1; + } + } + + // Key not found + return 0; +} + +// Function tries to detect file encryption key based on expected file content +// It is the same function like before, except that we know the value of the second DWORD +DWORD DetectFileKeyByKnownContent(void * pvEncryptedData, DWORD dwDecrypted0, DWORD dwDecrypted1) +{ + LPDWORD EncryptedData = (LPDWORD)pvEncryptedData; + DWORD dwKey1PlusKey2; + DWORD DataBlock[2]; + + // Get the value of the combined encryption key + dwKey1PlusKey2 = (EncryptedData[0] ^ dwDecrypted0) - 0xEEEEEEEE; + + // Try all 256 combinations of dwKey1 + for(DWORD i = 0; i < 0x100; i++) + { + DWORD dwSaveKey1; + DWORD dwKey1 = dwKey1PlusKey2 - StormBuffer[MPQ_HASH_KEY2_MIX + i]; + DWORD dwKey2 = 0xEEEEEEEE; + + // Modify the second key and decrypt the first DWORD + dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)]; + DataBlock[0] = EncryptedData[0] ^ (dwKey1 + dwKey2); + + // Did we obtain the same value like dwDecrypted0? + if(DataBlock[0] == dwDecrypted0) + { + // Save this key value + dwSaveKey1 = dwKey1; + + // Rotate both keys + dwKey1 = ((~dwKey1 << 0x15) + 0x11111111) | (dwKey1 >> 0x0B); + dwKey2 = DataBlock[0] + dwKey2 + (dwKey2 << 5) + 3; + + // Modify the second key again and decrypt the second DWORD + dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)]; + DataBlock[1] = EncryptedData[1] ^ (dwKey1 + dwKey2); + + // Now compare the results + if(DataBlock[1] == dwDecrypted1) + return dwSaveKey1; + } + } + + // Key not found + return 0; +} + +DWORD DetectFileKeyByContent(void * pvEncryptedData, DWORD dwSectorSize, DWORD dwFileSize) +{ + DWORD dwFileKey; + + // Try to break the file encryption key as if it was a WAVE file + if(dwSectorSize >= 0x0C) + { + dwFileKey = DetectFileKeyByKnownContent(pvEncryptedData, 0x46464952, dwFileSize - 8); + if(dwFileKey != 0) + return dwFileKey; + } + + // Try to break the encryption key as if it was an EXE file + if(dwSectorSize > 0x40) + { + dwFileKey = DetectFileKeyByKnownContent(pvEncryptedData, 0x00905A4D, 0x00000003); + if(dwFileKey != 0) + return dwFileKey; + } + + // Try to break the encryption key as if it was a XML file + if(dwSectorSize > 0x04) + { + dwFileKey = DetectFileKeyByKnownContent(pvEncryptedData, 0x6D783F3C, 0x6576206C); + if(dwFileKey != 0) + return dwFileKey; + } + + // Not detected, sorry + return 0; +} + +DWORD DecryptFileKey( + const char * szFileName, + ULONGLONG MpqPos, + DWORD dwFileSize, + DWORD dwFlags) +{ + DWORD dwFileKey; + DWORD dwMpqPos = (DWORD)MpqPos; + + // File key is calculated from plain name + szFileName = GetPlainFileName(szFileName); + dwFileKey = HashString(szFileName, MPQ_HASH_FILE_KEY); + + // Fix the key, if needed + if(dwFlags & MPQ_FILE_FIX_KEY) + dwFileKey = (dwFileKey + dwMpqPos) ^ dwFileSize; + + // Return the key + return dwFileKey; +} + +//----------------------------------------------------------------------------- +// Handle validation functions + +TMPQArchive * IsValidMpqHandle(HANDLE hMpq) +{ + TMPQArchive * ha = (TMPQArchive *)hMpq; + + return (ha != NULL && ha->pHeader != NULL && ha->pHeader->dwID == g_dwMpqSignature) ? ha : NULL; +} + +TMPQFile * IsValidFileHandle(HANDLE hFile) +{ + TMPQFile * hf = (TMPQFile *)hFile; + + // Must not be NULL + if(hf != NULL && hf->dwMagic == ID_MPQ_FILE) + { + // Local file handle? + if(hf->pStream != NULL) + return hf; + + // Also verify the MPQ handle within the file handle + if(IsValidMpqHandle(hf->ha)) + return hf; + } + + return NULL; +} + +//----------------------------------------------------------------------------- +// Hash table and block table manipulation + +// Attempts to search a free hash entry, or an entry whose names and locale matches +TMPQHash * FindFreeHashEntry(TMPQArchive * ha, DWORD dwStartIndex, DWORD dwName1, DWORD dwName2, LCID lcLocale) +{ + TMPQHash * pDeletedEntry = NULL; // If a deleted entry was found in the continuous hash range + TMPQHash * pFreeEntry = NULL; // If a free entry was found in the continuous hash range + DWORD dwHashIndexMask = HASH_INDEX_MASK(ha); + DWORD dwIndex; + + // Set the initial index + dwStartIndex = dwIndex = (dwStartIndex & dwHashIndexMask); + + // Search the hash table and return the found entries in the following priority: + // 1) + // 2) + // 3) + // 4) NULL + for(;;) + { + TMPQHash * pHash = ha->pHashTable + dwIndex; + + // If we found a matching entry, return that one + if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && pHash->lcLocale == lcLocale) + return pHash; + + // If we found a deleted entry, remember it but keep searching + if(pHash->dwBlockIndex == HASH_ENTRY_DELETED && pDeletedEntry == NULL) + pDeletedEntry = pHash; + + // If we found a free entry, we need to stop searching + if(pHash->dwBlockIndex == HASH_ENTRY_FREE) + { + pFreeEntry = pHash; + break; + } + + // Move to the next hash entry. + // If we reached the starting entry, it's failure. + dwIndex = (dwIndex + 1) & dwHashIndexMask; + if(dwIndex == dwStartIndex) + break; + } + + // If we found a deleted entry, return that one preferentially + return (pDeletedEntry != NULL) ? pDeletedEntry : pFreeEntry; +} + +// Retrieves the first hash entry for the given file. +// Every locale version of a file has its own hash entry +TMPQHash * GetFirstHashEntry(TMPQArchive * ha, const char * szFileName) +{ + DWORD dwHashIndexMask = HASH_INDEX_MASK(ha); + DWORD dwStartIndex = ha->pfnHashString(szFileName, MPQ_HASH_TABLE_INDEX); + DWORD dwName1 = ha->pfnHashString(szFileName, MPQ_HASH_NAME_A); + DWORD dwName2 = ha->pfnHashString(szFileName, MPQ_HASH_NAME_B); + DWORD dwIndex; + + // Set the initial index + dwStartIndex = dwIndex = (dwStartIndex & dwHashIndexMask); + + // Search the hash table + for(;;) + { + TMPQHash * pHash = ha->pHashTable + dwIndex; + + // If the entry matches, we found it. + if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize) + return pHash; + + // If that hash entry is a free entry, it means we haven't found the file + if(pHash->dwBlockIndex == HASH_ENTRY_FREE) + return NULL; + + // Move to the next hash entry. Stop searching + // if we got reached the original hash entry + dwIndex = (dwIndex + 1) & dwHashIndexMask; + if(dwIndex == dwStartIndex) + return NULL; + } +} + +TMPQHash * GetNextHashEntry(TMPQArchive * ha, TMPQHash * pFirstHash, TMPQHash * pHash) +{ + DWORD dwHashIndexMask = HASH_INDEX_MASK(ha); + DWORD dwStartIndex = (DWORD)(pFirstHash - ha->pHashTable); + DWORD dwName1 = pHash->dwName1; + DWORD dwName2 = pHash->dwName2; + DWORD dwIndex = (DWORD)(pHash - ha->pHashTable); + + // Now go for any next entry that follows the pHash, + // until either free hash entry was found, or the start entry was reached + for(;;) + { + // Move to the next hash entry. Stop searching + // if we got reached the original hash entry + dwIndex = (dwIndex + 1) & dwHashIndexMask; + if(dwIndex == dwStartIndex) + return NULL; + pHash = ha->pHashTable + dwIndex; + + // If the entry matches, we found it. + if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize) + return pHash; + + // If that hash entry is a free entry, it means we haven't found the file + if(pHash->dwBlockIndex == HASH_ENTRY_FREE) + return NULL; + } +} + +// Allocates an entry in the hash table +TMPQHash * AllocateHashEntry( + TMPQArchive * ha, + TFileEntry * pFileEntry, + LCID lcLocale) +{ + TMPQHash * pHash; + DWORD dwStartIndex = ha->pfnHashString(pFileEntry->szFileName, MPQ_HASH_TABLE_INDEX); + DWORD dwName1 = ha->pfnHashString(pFileEntry->szFileName, MPQ_HASH_NAME_A); + DWORD dwName2 = ha->pfnHashString(pFileEntry->szFileName, MPQ_HASH_NAME_B); + + // Attempt to find a free hash entry + pHash = FindFreeHashEntry(ha, dwStartIndex, dwName1, dwName2, lcLocale); + if(pHash != NULL) + { + // Fill the free hash entry + pHash->dwName1 = dwName1; + pHash->dwName2 = dwName2; + pHash->lcLocale = (USHORT)lcLocale; + pHash->Platform = 0; + pHash->dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable); + } + + return pHash; +} + + +// Finds a free space in the MPQ where to store next data +// The free space begins beyond the file that is stored at the fuhrtest +// position in the MPQ. (listfile), (attributes) and (signature) are ignored, +// unless the MPQ is being flushed. +ULONGLONG FindFreeMpqSpace(TMPQArchive * ha) +{ + TMPQHeader * pHeader = ha->pHeader; + TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; + TFileEntry * pFileEntry; + ULONGLONG FreeSpacePos = ha->pHeader->dwHeaderSize; + DWORD dwChunkCount; + + //static TFileEntry* furthestFile = nullptr; + //TFileEntry* startEntry = furthestFile == nullptr ? ha->pFileTable : furthestFile; + + TFileEntry* startEntry = (ha->useFreeSpaceOptimization && ha->lastFreeSpaceEntry != nullptr) ? ha->lastFreeSpaceEntry : ha->pFileTable; + + // Parse the entire block table + for(pFileEntry = startEntry; pFileEntry < pFileTableEnd; pFileEntry++) + { + // Only take existing files with nonzero size + if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) && (pFileEntry->dwCmpSize != 0)) + { + // If we are not saving MPQ tables, ignore internal MPQ files + if((ha->dwFlags & MPQ_FLAG_SAVING_TABLES) == 0 && IsInternalMpqFileName(pFileEntry->szFileName)) + continue; + + // If the end of the file is bigger than current MPQ table pos, update it + if((pFileEntry->ByteOffset + pFileEntry->dwCmpSize) > FreeSpacePos) + { + // Get the end of the file data + FreeSpacePos = pFileEntry->ByteOffset + pFileEntry->dwCmpSize; + + // Add the MD5 chunks, if present + if(pHeader->dwRawChunkSize != 0 && pFileEntry->dwCmpSize != 0) + { + dwChunkCount = ((pFileEntry->dwCmpSize - 1) / pHeader->dwRawChunkSize) + 1; + FreeSpacePos += dwChunkCount * MD5_DIGEST_SIZE; + } + + ha->lastFreeSpaceEntry = pFileEntry; + + //if (ha->useFreeSpaceOptimization) + //break; + } + } + } + + // Give the free space position to the caller + return FreeSpacePos; +} + +//----------------------------------------------------------------------------- +// Common functions - MPQ File + +TMPQFile * CreateFileHandle(TMPQArchive * ha, TFileEntry * pFileEntry) +{ + TMPQFile * hf; + + // Allocate space for TMPQFile + hf = STORM_ALLOC(TMPQFile, 1); + if(hf != NULL) + { + // Fill the file structure + memset(hf, 0, sizeof(TMPQFile)); + hf->dwMagic = ID_MPQ_FILE; + hf->pStream = NULL; + hf->ha = ha; + + // If the called entered a file entry, we also copy informations from the file entry + if(ha != NULL && pFileEntry != NULL) + { + // Set the raw position and MPQ position + hf->RawFilePos = FileOffsetFromMpqOffset(ha, pFileEntry->ByteOffset); + hf->MpqFilePos = pFileEntry->ByteOffset; + + // Set the data size + hf->dwDataSize = pFileEntry->dwFileSize; + hf->pFileEntry = pFileEntry; + } + } + + return hf; +} + +TMPQFile * CreateWritableHandle(TMPQArchive * ha, DWORD dwFileSize) +{ + ULONGLONG FreeMpqSpace; + ULONGLONG TempPos; + TMPQFile * hf; + + // We need to find the position in the MPQ where we save the file data + FreeMpqSpace = FindFreeMpqSpace(ha); + + // When format V1, the size of the archive cannot exceed 4 GB + if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1) + { + TempPos = FreeMpqSpace + + dwFileSize + + (ha->pHeader->dwHashTableSize * sizeof(TMPQHash)) + + (ha->dwFileTableSize * sizeof(TMPQBlock)); + if((TempPos >> 32) != 0) + { + SetLastError(ERROR_DISK_FULL); + return NULL; + } + } + + // Allocate the file handle + hf = CreateFileHandle(ha, NULL); + if(hf == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + + // We need to find the position in the MPQ where we save the file data + hf->MpqFilePos = FreeMpqSpace; + hf->bIsWriteHandle = true; + return hf; +} + +// Loads a table from MPQ. +// Can be used for hash table, block table, sector offset table or sector checksum table +void * LoadMpqTable( + TMPQArchive * ha, + ULONGLONG ByteOffset, + LPBYTE pbTableHash, + DWORD dwCompressedSize, + DWORD dwTableSize, + DWORD dwKey, + bool * pbTableIsCut) +{ + ULONGLONG FileSize = 0; + LPBYTE pbCompressed = NULL; + LPBYTE pbMpqTable; + LPBYTE pbToRead; + DWORD dwBytesToRead = dwCompressedSize; + DWORD dwErrCode = ERROR_SUCCESS; + + // Allocate the MPQ table + pbMpqTable = pbToRead = STORM_ALLOC(BYTE, dwTableSize); + if(pbMpqTable != NULL) + { + // Check if the MPQ table is encrypted + if(dwCompressedSize < dwTableSize) + { + // Allocate temporary buffer for holding compressed data + pbCompressed = pbToRead = STORM_ALLOC(BYTE, dwCompressedSize); + if(pbCompressed == NULL) + { + STORM_FREE(pbMpqTable); + return NULL; + } + } + + // Get the file offset from which we will read the table + // Note: According to Storm.dll from Warcraft III (version 2002), + // if the hash table position is 0xFFFFFFFF, no SetFilePointer call is done + // and the table is loaded from the current file offset + if(ByteOffset == SFILE_INVALID_POS) + FileStream_GetPos(ha->pStream, &ByteOffset); + + // On archives v 1.0, hash table and block table can go beyond EOF. + // Storm.dll reads as much as possible, then fills the missing part with zeros. + // Abused by Spazzler map protector which sets hash table size to 0x00100000 + // Abused by NP_Protect in MPQs v4 as well + if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1) + { + // Cut the table size + FileStream_GetSize(ha->pStream, &FileSize); + if((ByteOffset + dwBytesToRead) > FileSize) + { + // Fill the extra data with zeros + dwBytesToRead = (DWORD)(FileSize - ByteOffset); + memset(pbMpqTable + dwBytesToRead, 0, (dwTableSize - dwBytesToRead)); + + // Give the caller information that the table was cut + if(pbTableIsCut != NULL) + pbTableIsCut[0] = true; + } + } + + // If everything succeeded, read the raw table from the MPQ + if(FileStream_Read(ha->pStream, &ByteOffset, pbToRead, dwBytesToRead)) + { + // Verify the MD5 of the table, if present + if(!VerifyDataBlockHash(pbToRead, dwBytesToRead, pbTableHash)) + { + dwErrCode = ERROR_FILE_CORRUPT; + } + } + else + { + dwErrCode = GetLastError(); + } + + if(dwErrCode == ERROR_SUCCESS) + { + // First of all, decrypt the table + if(dwKey != 0) + { + BSWAP_ARRAY32_UNSIGNED(pbToRead, dwCompressedSize); + DecryptMpqBlock(pbToRead, dwCompressedSize, dwKey); + BSWAP_ARRAY32_UNSIGNED(pbToRead, dwCompressedSize); + } + + // If the table is compressed, decompress it + if(dwCompressedSize < dwTableSize) + { + int cbOutBuffer = (int)dwTableSize; + int cbInBuffer = (int)dwCompressedSize; + + if(!SCompDecompress2(pbMpqTable, &cbOutBuffer, pbCompressed, cbInBuffer)) + dwErrCode = GetLastError(); + } + + // Make sure that the table is properly byte-swapped + BSWAP_ARRAY32_UNSIGNED(pbMpqTable, dwTableSize); + } + + // If read failed, free the table and return + if(dwErrCode != ERROR_SUCCESS) + { + STORM_FREE(pbMpqTable); + pbMpqTable = NULL; + } + + // Free the compression buffer, if any + if(pbCompressed != NULL) + STORM_FREE(pbCompressed); + } + + // Return the MPQ table + return pbMpqTable; +} + +unsigned char * AllocateMd5Buffer( + DWORD dwRawDataSize, + DWORD dwChunkSize, + LPDWORD pcbMd5Size) +{ + unsigned char * md5_array; + DWORD cbMd5Size; + + // Sanity check + assert(dwRawDataSize != 0); + assert(dwChunkSize != 0); + + // Calculate how many MD5's we will calculate + cbMd5Size = (((dwRawDataSize - 1) / dwChunkSize) + 1) * MD5_DIGEST_SIZE; + + // Allocate space for array or MD5s + md5_array = STORM_ALLOC(BYTE, cbMd5Size); + + // Give the size of the MD5 array + if(pcbMd5Size != NULL) + *pcbMd5Size = cbMd5Size; + return md5_array; +} + +// Allocates sector buffer and sector offset table +DWORD AllocateSectorBuffer(TMPQFile * hf) +{ + TMPQArchive * ha = hf->ha; + + // Caller of AllocateSectorBuffer must ensure these + assert(hf->pbFileSector == NULL); + assert(hf->pFileEntry != NULL); + assert(hf->ha != NULL); + + // Don't allocate anything if the file has zero size + if(hf->pFileEntry->dwFileSize == 0 || hf->dwDataSize == 0) + return ERROR_SUCCESS; + + // Determine the file sector size and allocate buffer for it + hf->dwSectorSize = (hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) ? hf->dwDataSize : ha->dwSectorSize; + hf->pbFileSector = STORM_ALLOC(BYTE, hf->dwSectorSize); + hf->dwSectorOffs = SFILE_INVALID_POS; + + // Return result + return (hf->pbFileSector != NULL) ? ERROR_SUCCESS : ERROR_NOT_ENOUGH_MEMORY; +} + +// Allocates sector offset table +DWORD AllocatePatchInfo(TMPQFile * hf, bool bLoadFromFile) +{ + TMPQArchive * ha = hf->ha; + DWORD dwLength = sizeof(TPatchInfo); + + // The following conditions must be true + assert(hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE); + assert(hf->pPatchInfo == NULL); + +__AllocateAndLoadPatchInfo: + + // Allocate space for patch header. Start with default size, + // and if its size if bigger, then we reload them + hf->pPatchInfo = STORM_ALLOC(TPatchInfo, 1); + if(hf->pPatchInfo == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // Do we have to load the patch header from the file ? + if(bLoadFromFile) + { + // Load the patch header + if(!FileStream_Read(ha->pStream, &hf->RawFilePos, hf->pPatchInfo, dwLength)) + { + // Free the patch info + STORM_FREE(hf->pPatchInfo); + hf->pPatchInfo = NULL; + return GetLastError(); + } + + // Perform necessary swapping + hf->pPatchInfo->dwLength = BSWAP_INT32_UNSIGNED(hf->pPatchInfo->dwLength); + hf->pPatchInfo->dwFlags = BSWAP_INT32_UNSIGNED(hf->pPatchInfo->dwFlags); + hf->pPatchInfo->dwDataSize = BSWAP_INT32_UNSIGNED(hf->pPatchInfo->dwDataSize); + + // Verify the size of the patch header + // If it's not default size, we have to reload them + if(hf->pPatchInfo->dwLength > dwLength) + { + // Free the patch info + dwLength = hf->pPatchInfo->dwLength; + STORM_FREE(hf->pPatchInfo); + hf->pPatchInfo = NULL; + + // If the length is out of all possible ranges, fail the operation + if(dwLength > 0x400) + return ERROR_FILE_CORRUPT; + goto __AllocateAndLoadPatchInfo; + } + + // Patch file data size according to the patch header + hf->dwDataSize = hf->pPatchInfo->dwDataSize; + } + else + { + memset(hf->pPatchInfo, 0, dwLength); + } + + // Save the final length to the patch header + hf->pPatchInfo->dwLength = dwLength; + hf->pPatchInfo->dwFlags = 0x80000000; + return ERROR_SUCCESS; +} + +// Allocates sector offset table +DWORD AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile) +{ + TMPQArchive * ha = hf->ha; + TFileEntry * pFileEntry = hf->pFileEntry; + DWORD dwSectorOffsLen; + bool bSectorOffsetTableCorrupt = false; + + // Caller of AllocateSectorOffsets must ensure these + assert(hf->SectorOffsets == NULL); + assert(hf->pFileEntry != NULL); + assert(hf->dwDataSize != 0); + assert(hf->ha != NULL); + + // If the file is stored as single unit, just set number of sectors to 1 + if(pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) + { + hf->dwSectorCount = 1; + return ERROR_SUCCESS; + } + + // Calculate the number of data sectors + // Note that this doesn't work if the file size is zero + hf->dwSectorCount = ((hf->dwDataSize - 1) / hf->dwSectorSize) + 1; + + // Calculate the number of file sectors + dwSectorOffsLen = (hf->dwSectorCount + 1) * sizeof(DWORD); + + // If MPQ_FILE_SECTOR_CRC flag is set, there will either be extra DWORD + // or an array of MD5's. Either way, we read at least 4 bytes more + // in order to save additional read from the file. + if(pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC) + dwSectorOffsLen += sizeof(DWORD); + + // Only allocate and load the table if the file is compressed + if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) + { + __LoadSectorOffsets: + + // Allocate the sector offset table + hf->SectorOffsets = STORM_ALLOC(DWORD, (dwSectorOffsLen / sizeof(DWORD))); + if(hf->SectorOffsets == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // Only read from the file if we are supposed to do so + if(bLoadFromFile) + { + ULONGLONG RawFilePos = hf->RawFilePos; + + // Append the length of the patch info, if any + if(hf->pPatchInfo != NULL) + { + if((RawFilePos + hf->pPatchInfo->dwLength) < RawFilePos) + return ERROR_FILE_CORRUPT; + RawFilePos += hf->pPatchInfo->dwLength; + } + + // Load the sector offsets from the file + if(!FileStream_Read(ha->pStream, &RawFilePos, hf->SectorOffsets, dwSectorOffsLen)) + { + // Free the sector offsets + STORM_FREE(hf->SectorOffsets); + hf->SectorOffsets = NULL; + return GetLastError(); + } + + // Swap the sector positions + BSWAP_ARRAY32_UNSIGNED(hf->SectorOffsets, dwSectorOffsLen); + + // Decrypt loaded sector positions if necessary + if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) + { + // If we don't know the file key, try to find it. + if(hf->dwFileKey == 0) + { + hf->dwFileKey = DetectFileKeyBySectorSize(hf->SectorOffsets, ha->dwSectorSize, dwSectorOffsLen); + if(hf->dwFileKey == 0) + { + STORM_FREE(hf->SectorOffsets); + hf->SectorOffsets = NULL; + return ERROR_UNKNOWN_FILE_KEY; + } + } + + // Decrypt sector positions + DecryptMpqBlock(hf->SectorOffsets, dwSectorOffsLen, hf->dwFileKey - 1); + } + + // + // Validate the sector offset table + // + // Note: Some MPQ protectors put the actual file data before the sector offset table. + // In this case, the sector offsets are negative (> 0x80000000). + // + + for(DWORD i = 0; i < hf->dwSectorCount; i++) + { + DWORD dwSectorOffset1 = hf->SectorOffsets[i+1]; + DWORD dwSectorOffset0 = hf->SectorOffsets[i]; + + // Every following sector offset must be bigger than the previous one + if(dwSectorOffset1 <= dwSectorOffset0) + { + bSectorOffsetTableCorrupt = true; + break; + } + + // The sector size must not be bigger than compressed file size + // Edit: Yes, but apparently, in original Storm.dll, the compressed + // size is not checked anywhere. However, we need to do this check + // in order to sector offset table malformed by MPQ protectors + if((dwSectorOffset1 - dwSectorOffset0) > ha->dwSectorSize) + { + bSectorOffsetTableCorrupt = true; + break; + } + } + + // If data corruption detected, free the sector offset table + if(bSectorOffsetTableCorrupt) + { + STORM_FREE(hf->SectorOffsets); + hf->SectorOffsets = NULL; + return ERROR_FILE_CORRUPT; + } + + // + // There may be various extra DWORDs loaded after the sector offset table. + // They are mostly empty on WoW release MPQs, but on MPQs from PTR, + // they contain random non-zero data. Their meaning is unknown. + // + // These extra values are, however, include in the dwCmpSize in the file + // table. We cannot ignore them, because compacting archive would fail + // + + if(hf->SectorOffsets[0] > dwSectorOffsLen) + { + // MPQ protectors put some ridiculous values there. We must limit the extra bytes + if(hf->SectorOffsets[0] > (dwSectorOffsLen + 0x400)) + return ERROR_FILE_CORRUPT; + + // Free the old sector offset table + dwSectorOffsLen = hf->SectorOffsets[0]; + STORM_FREE(hf->SectorOffsets); + goto __LoadSectorOffsets; + } + } + else + { + memset(hf->SectorOffsets, 0, dwSectorOffsLen); + hf->SectorOffsets[0] = dwSectorOffsLen; + } + } + + return ERROR_SUCCESS; +} + +DWORD AllocateSectorChecksums(TMPQFile * hf, bool bLoadFromFile) +{ + TMPQArchive * ha = hf->ha; + TFileEntry * pFileEntry = hf->pFileEntry; + ULONGLONG RawFilePos; + DWORD dwCompressedSize = 0; + DWORD dwExpectedSize; + DWORD dwCrcOffset; // Offset of the CRC table, relative to file offset in the MPQ + DWORD dwCrcSize; + + // Caller of AllocateSectorChecksums must ensure these + assert(hf->SectorChksums == NULL); + assert(hf->SectorOffsets != NULL); + assert(hf->pFileEntry != NULL); + assert(hf->ha != NULL); + + // Single unit files don't have sector checksums + if(pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) + return ERROR_SUCCESS; + + // Caller must ensure that we are only called when we have sector checksums + assert(pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC); + + // + // Older MPQs store an array of CRC32's after + // the raw file data in the MPQ. + // + // In newer MPQs, the (since Cataclysm BETA) the (attributes) file + // contains additional 32-bit values beyond the sector table. + // Their number depends on size of the (attributes), but their + // meaning is unknown. They are usually zeroed in retail game files, + // but contain some sort of checksum in BETA MPQs + // + + // Does the size of the file table match with the CRC32-based checksums? + dwExpectedSize = (hf->dwSectorCount + 2) * sizeof(DWORD); + if(hf->SectorOffsets[0] != 0 && hf->SectorOffsets[0] == dwExpectedSize) + { + // If we are not loading from the MPQ file, we just allocate the sector table + // In that case, do not check any sizes + if(bLoadFromFile == false) + { + hf->SectorChksums = STORM_ALLOC(DWORD, hf->dwSectorCount); + if(hf->SectorChksums == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // Fill the checksum table with zeros + memset(hf->SectorChksums, 0, hf->dwSectorCount * sizeof(DWORD)); + return ERROR_SUCCESS; + } + else + { + // Is there valid size of the sector checksums? + if(hf->SectorOffsets[hf->dwSectorCount + 1] >= hf->SectorOffsets[hf->dwSectorCount]) + dwCompressedSize = hf->SectorOffsets[hf->dwSectorCount + 1] - hf->SectorOffsets[hf->dwSectorCount]; + + // Ignore cases when the length is too small or too big. + if(dwCompressedSize < sizeof(DWORD) || dwCompressedSize > hf->dwSectorSize) + return ERROR_SUCCESS; + + // Calculate offset of the CRC table + dwCrcSize = hf->dwSectorCount * sizeof(DWORD); + dwCrcOffset = hf->SectorOffsets[hf->dwSectorCount]; + RawFilePos = CalculateRawSectorOffset(hf, dwCrcOffset); + + // Now read the table from the MPQ + hf->SectorChksums = (DWORD *)LoadMpqTable(ha, RawFilePos, NULL, dwCompressedSize, dwCrcSize, 0, NULL); + if(hf->SectorChksums == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + } + } + + // If the size doesn't match, we ignore sector checksums +// assert(false); + return ERROR_SUCCESS; +} + +DWORD WritePatchInfo(TMPQFile * hf) +{ + TMPQArchive * ha = hf->ha; + TPatchInfo * pPatchInfo = hf->pPatchInfo; + + // The caller must make sure that this function is only called + // when the following is true. + assert(hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE); + assert(pPatchInfo != NULL); + + BSWAP_ARRAY32_UNSIGNED(pPatchInfo, 3 * sizeof(DWORD)); + if(!FileStream_Write(ha->pStream, &hf->RawFilePos, pPatchInfo, sizeof(TPatchInfo))) + return GetLastError(); + + return ERROR_SUCCESS; +} + +DWORD WriteSectorOffsets(TMPQFile * hf) +{ + TMPQArchive * ha = hf->ha; + TFileEntry * pFileEntry = hf->pFileEntry; + ULONGLONG RawFilePos = hf->RawFilePos; + DWORD dwSectorOffsLen; + + // The caller must make sure that this function is only called + // when the following is true. + assert(hf->pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK); + assert(hf->SectorOffsets != NULL); + dwSectorOffsLen = hf->SectorOffsets[0]; + + // If file is encrypted, sector positions are also encrypted + if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) + EncryptMpqBlock(hf->SectorOffsets, dwSectorOffsLen, hf->dwFileKey - 1); + BSWAP_ARRAY32_UNSIGNED(hf->SectorOffsets, dwSectorOffsLen); + + // Adjust sector offset table position, if we also have patch info + if(hf->pPatchInfo != NULL) + RawFilePos += hf->pPatchInfo->dwLength; + + // Write sector offsets to the archive + if(!FileStream_Write(ha->pStream, &RawFilePos, hf->SectorOffsets, dwSectorOffsLen)) + return GetLastError(); + + // Not necessary, as the sector checksums + // are going to be freed when this is done. +// BSWAP_ARRAY32_UNSIGNED(hf->SectorOffsets, dwSectorOffsLen); + return ERROR_SUCCESS; +} + +DWORD WriteSectorChecksums(TMPQFile * hf) +{ + TMPQArchive * ha = hf->ha; + ULONGLONG RawFilePos; + TFileEntry * pFileEntry = hf->pFileEntry; + LPBYTE pbCompressed; + DWORD dwCompressedSize = 0; + DWORD dwErrCode = ERROR_SUCCESS; + DWORD dwCrcSize; + int nOutSize; + + // The caller must make sure that this function is only called + // when the following is true. + assert(hf->pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC); + assert(hf->SectorOffsets != NULL); + assert(hf->SectorChksums != NULL); + + // If the MPQ has MD5 of each raw data chunk, + // we leave sector offsets empty + if(ha->pHeader->dwRawChunkSize != 0) + { + hf->SectorOffsets[hf->dwSectorCount + 1] = hf->SectorOffsets[hf->dwSectorCount]; + return ERROR_SUCCESS; + } + + // Calculate size of the checksum array + dwCrcSize = hf->dwSectorCount * sizeof(DWORD); + + // Allocate buffer for compressed sector CRCs. + pbCompressed = STORM_ALLOC(BYTE, dwCrcSize); + if(pbCompressed == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // Perform the compression + BSWAP_ARRAY32_UNSIGNED(hf->SectorChksums, dwCrcSize); + + nOutSize = (int)dwCrcSize; + SCompCompress(pbCompressed, &nOutSize, hf->SectorChksums, (int)dwCrcSize, MPQ_COMPRESSION_ZLIB, 0, 0); + dwCompressedSize = (DWORD)nOutSize; + + // Write the sector CRCs to the archive + RawFilePos = hf->RawFilePos + hf->SectorOffsets[hf->dwSectorCount]; + if(hf->pPatchInfo != NULL) + RawFilePos += hf->pPatchInfo->dwLength; + if(!FileStream_Write(ha->pStream, &RawFilePos, pbCompressed, dwCompressedSize)) + dwErrCode = GetLastError(); + + // Not necessary, as the sector checksums + // are going to be freed when this is done. +// BSWAP_ARRAY32_UNSIGNED(hf->SectorChksums, dwCrcSize); + + // Store the sector CRCs + hf->SectorOffsets[hf->dwSectorCount + 1] = hf->SectorOffsets[hf->dwSectorCount] + dwCompressedSize; + pFileEntry->dwCmpSize += dwCompressedSize; + STORM_FREE(pbCompressed); + return dwErrCode; +} + +DWORD WriteMemDataMD5( + TFileStream * pStream, + ULONGLONG RawDataOffs, + void * pvRawData, + DWORD dwRawDataSize, + DWORD dwChunkSize, + LPDWORD pcbTotalSize) +{ + unsigned char * md5_array; + unsigned char * md5; + LPBYTE pbRawData = (LPBYTE)pvRawData; + DWORD dwBytesRemaining = dwRawDataSize; + DWORD dwMd5ArraySize = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Allocate buffer for array of MD5 + md5_array = md5 = AllocateMd5Buffer(dwRawDataSize, dwChunkSize, &dwMd5ArraySize); + if(md5_array == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // For every file chunk, calculate MD5 + while(dwBytesRemaining != 0) + { + // Get the remaining number of bytes to read + dwChunkSize = STORMLIB_MIN(dwBytesRemaining, dwChunkSize); + + // Calculate MD5 + CalculateDataBlockHash(pbRawData, dwChunkSize, md5); + md5 += MD5_DIGEST_SIZE; + + // Move offset and size + dwBytesRemaining -= dwChunkSize; + pbRawData += dwChunkSize; + } + + // Write the array od MD5's to the file + RawDataOffs += dwRawDataSize; + if(!FileStream_Write(pStream, &RawDataOffs, md5_array, dwMd5ArraySize)) + dwErrCode = GetLastError(); + + // Give the caller the size of the MD5 array + if(pcbTotalSize != NULL) + *pcbTotalSize = dwRawDataSize + dwMd5ArraySize; + + // Free buffers and exit + STORM_FREE(md5_array); + return dwErrCode; +} + + +// Writes the MD5 for each chunk of the raw file data +DWORD WriteMpqDataMD5( + TFileStream * pStream, + ULONGLONG RawDataOffs, + DWORD dwRawDataSize, + DWORD dwChunkSize) +{ + unsigned char * md5_array; + unsigned char * md5; + LPBYTE pbFileChunk; + DWORD dwMd5ArraySize = 0; + DWORD dwToRead = dwRawDataSize; + DWORD dwErrCode = ERROR_SUCCESS; + + // Allocate buffer for array of MD5 + md5_array = md5 = AllocateMd5Buffer(dwRawDataSize, dwChunkSize, &dwMd5ArraySize); + if(md5_array == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // Allocate space for file chunk + pbFileChunk = STORM_ALLOC(BYTE, dwChunkSize); + if(pbFileChunk == NULL) + { + STORM_FREE(md5_array); + return ERROR_NOT_ENOUGH_MEMORY; + } + + // For every file chunk, calculate MD5 + while(dwRawDataSize != 0) + { + // Get the remaining number of bytes to read + dwToRead = STORMLIB_MIN(dwRawDataSize, dwChunkSize); + + // Read the chunk + if(!FileStream_Read(pStream, &RawDataOffs, pbFileChunk, dwToRead)) + { + dwErrCode = GetLastError(); + break; + } + + // Calculate MD5 + CalculateDataBlockHash(pbFileChunk, dwToRead, md5); + md5 += MD5_DIGEST_SIZE; + + // Move offset and size + RawDataOffs += dwToRead; + dwRawDataSize -= dwToRead; + } + + // Write the array od MD5's to the file + if(dwErrCode == ERROR_SUCCESS) + { + if(!FileStream_Write(pStream, NULL, md5_array, dwMd5ArraySize)) + dwErrCode = GetLastError(); + } + + // Free buffers and exit + STORM_FREE(pbFileChunk); + STORM_FREE(md5_array); + return dwErrCode; +} + +// Frees the structure for MPQ file +void FreeFileHandle(TMPQFile *& hf) +{ + if(hf != NULL) + { + // If we have patch file attached to this one, free it first + if(hf->hfPatch != NULL) + FreeFileHandle(hf->hfPatch); + + // Then free all buffers allocated in the file structure + if(hf->pbFileData != NULL) + STORM_FREE(hf->pbFileData); + if(hf->pPatchInfo != NULL) + STORM_FREE(hf->pPatchInfo); + if(hf->SectorOffsets != NULL) + STORM_FREE(hf->SectorOffsets); + if(hf->SectorChksums != NULL) + STORM_FREE(hf->SectorChksums); + if(hf->pbFileSector != NULL) + STORM_FREE(hf->pbFileSector); + if(hf->pStream != NULL) + FileStream_Close(hf->pStream); + STORM_FREE(hf); + hf = NULL; + } +} + +// Frees the MPQ archive +void FreeArchiveHandle(TMPQArchive *& ha) +{ + if(ha != NULL) + { + // First of all, free the patch archive, if any + if(ha->haPatch != NULL) + FreeArchiveHandle(ha->haPatch); + + // Free the patch prefix, if any + if(ha->pPatchPrefix != NULL) + STORM_FREE(ha->pPatchPrefix); + + // Close the file stream + FileStream_Close(ha->pStream); + ha->pStream = NULL; + + // Free the file names from the file table + if(ha->pFileTable != NULL) + { + for(DWORD i = 0; i < ha->dwFileTableSize; i++) + { + if(ha->pFileTable[i].szFileName != NULL) + STORM_FREE(ha->pFileTable[i].szFileName); + ha->pFileTable[i].szFileName = NULL; + } + + // Then free all buffers allocated in the archive structure + STORM_FREE(ha->pFileTable); + } + + if(ha->pHashTable != NULL) + STORM_FREE(ha->pHashTable); + if(ha->pHetTable != NULL) + FreeHetTable(ha->pHetTable); + STORM_FREE(ha); + ha = NULL; + } +} + +bool IsInternalMpqFileName(const char * szFileName) +{ + if(szFileName != NULL && szFileName[0] == '(') + { + if(!_stricmp(szFileName, LISTFILE_NAME) || + !_stricmp(szFileName, ATTRIBUTES_NAME) || + !_stricmp(szFileName, SIGNATURE_NAME)) + { + return true; + } + } + + return false; +} + +// Verifies if the file name is a pseudo-name +bool IsPseudoFileName(const char * szFileName, DWORD * pdwFileIndex) +{ + DWORD dwFileIndex = 0; + + if(szFileName != NULL) + { + // Must be "File########.ext" + if(!_strnicmp(szFileName, "File", 4)) + { + // Check 8 digits + for(int i = 4; i < 4+8; i++) + { + if(szFileName[i] < '0' || szFileName[i] > '9') + return false; + dwFileIndex = (dwFileIndex * 10) + (szFileName[i] - '0'); + } + + // An extension must follow + if(szFileName[12] == '.') + { + if(pdwFileIndex != NULL) + *pdwFileIndex = dwFileIndex; + return true; + } + } + } + + // Not a pseudo-name + return false; +} + +//----------------------------------------------------------------------------- +// Functions calculating and verifying the MD5 signature + +bool IsValidMD5(LPBYTE pbMd5) +{ + LPDWORD Md5 = (LPDWORD)pbMd5; + + return ((Md5 != NULL) && (Md5[0] | Md5[1] | Md5[2] | Md5[3])) ? true : false; +} + +bool IsValidSignature(LPBYTE pbSignature) +{ + LPDWORD Signature = (LPDWORD)pbSignature; + DWORD SigValid = 0; + + for(int i = 0; i < MPQ_WEAK_SIGNATURE_SIZE / sizeof(DWORD); i++) + SigValid |= Signature[i]; + + return (SigValid != 0) ? true : false; +} + + +bool VerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5) +{ + hash_state md5_state; + BYTE md5_digest[MD5_DIGEST_SIZE]; + bool bResult = true; + + // Don't verify the block if the MD5 is not valid. + if(IsValidMD5(expected_md5)) + { + // Calculate the MD5 of the data block + md5_init(&md5_state); + md5_process(&md5_state, (unsigned char *)pvDataBlock, cbDataBlock); + md5_done(&md5_state, md5_digest); + + // Does the MD5's match? + bResult = (memcmp(md5_digest, expected_md5, MD5_DIGEST_SIZE) == 0); + } + + return bResult; +} + +void CalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_hash) +{ + hash_state md5_state; + + md5_init(&md5_state); + md5_process(&md5_state, (unsigned char *)pvDataBlock, cbDataBlock); + md5_done(&md5_state, md5_hash); +} + + +//----------------------------------------------------------------------------- +// Swapping functions + +#ifndef STORMLIB_LITTLE_ENDIAN + +// Swaps a signed 16-bit integer +int16_t SwapInt16(uint16_t val) +{ + return (val << 8) | ((val >> 8) & 0xFF); +} + +// Swaps an unsigned 16-bit integer +uint16_t SwapUInt16(uint16_t val) +{ + return (val << 8) | (val >> 8 ); +} + +// Swaps a signed 32-bit integer +int32_t SwapInt32(uint32_t val) +{ + val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF ); + return (val << 16) | ((val >> 16) & 0xFFFF); +} + +// Swaps an unsigned 32-bit integer +uint32_t SwapUInt32(uint32_t val) +{ + val = ((val << 8) & 0xFF00FF00 ) | ((val >> 8) & 0xFF00FF ); + return (val << 16) | (val >> 16); +} + +// Swaps a signed 64-bit integer +int64_t SwapInt64(uint64_t val) +{ + val = ((val << 8) & 0xFF00FF00FF00FF00ULL ) | ((val >> 8) & 0x00FF00FF00FF00FFULL ); + val = ((val << 16) & 0xFFFF0000FFFF0000ULL ) | ((val >> 16) & 0x0000FFFF0000FFFFULL ); + return (val << 32) | ((val >> 32) & 0xFFFFFFFFULL); +} + +// Swaps an unsigned 64-bit integer +uint64_t SwapUInt64(uint64_t val) +{ + val = ((val << 8) & 0xFF00FF00FF00FF00ULL ) | ((val >> 8) & 0x00FF00FF00FF00FFULL ); + val = ((val << 16) & 0xFFFF0000FFFF0000ULL ) | ((val >> 16) & 0x0000FFFF0000FFFFULL ); + return (val << 32) | (val >> 32); +} + +// Swaps array of unsigned 16-bit integers +void ConvertUInt16Buffer(void * ptr, size_t length) +{ + uint16_t * buffer = (uint16_t *)ptr; + uint32_t nElements = (uint32_t)(length / sizeof(uint16_t)); + + while(nElements-- > 0) + { + *buffer = SwapUInt16(*buffer); + buffer++; + } +} + +// Swaps array of unsigned 32-bit integers +void ConvertUInt32Buffer(void * ptr, size_t length) +{ + uint32_t * buffer = (uint32_t *)ptr; + uint32_t nElements = (uint32_t)(length / sizeof(uint32_t)); + + while(nElements-- > 0) + { + *buffer = SwapUInt32(*buffer); + buffer++; + } +} + +// Swaps array of unsigned 64-bit integers +void ConvertUInt64Buffer(void * ptr, size_t length) +{ + uint64_t * buffer = (uint64_t *)ptr; + uint32_t nElements = (uint32_t)(length / sizeof(uint64_t)); + + while(nElements-- > 0) + { + *buffer = SwapUInt64(*buffer); + buffer++; + } +} + +// Swaps the TMPQHeader structure +void ConvertTMPQHeader(void *header, uint16_t version) +{ + TMPQHeader * theHeader = (TMPQHeader *)header; + + // Swap header part version 1 + if(version == MPQ_FORMAT_VERSION_1) + { + theHeader->dwID = SwapUInt32(theHeader->dwID); + theHeader->dwHeaderSize = SwapUInt32(theHeader->dwHeaderSize); + theHeader->dwArchiveSize = SwapUInt32(theHeader->dwArchiveSize); + theHeader->wFormatVersion = SwapUInt16(theHeader->wFormatVersion); + theHeader->wSectorSize = SwapUInt16(theHeader->wSectorSize); + theHeader->dwHashTablePos = SwapUInt32(theHeader->dwHashTablePos); + theHeader->dwBlockTablePos = SwapUInt32(theHeader->dwBlockTablePos); + theHeader->dwHashTableSize = SwapUInt32(theHeader->dwHashTableSize); + theHeader->dwBlockTableSize = SwapUInt32(theHeader->dwBlockTableSize); + } + + if(version == MPQ_FORMAT_VERSION_2) + { + theHeader->HiBlockTablePos64 = SwapUInt64(theHeader->HiBlockTablePos64); + theHeader->wHashTablePosHi = SwapUInt16(theHeader->wHashTablePosHi); + theHeader->wBlockTablePosHi = SwapUInt16(theHeader->wBlockTablePosHi); + } + + if(version == MPQ_FORMAT_VERSION_3) + { + theHeader->ArchiveSize64 = SwapUInt64(theHeader->ArchiveSize64); + theHeader->BetTablePos64 = SwapUInt64(theHeader->BetTablePos64); + theHeader->HetTablePos64 = SwapUInt64(theHeader->HetTablePos64); + } + + if(version == MPQ_FORMAT_VERSION_4) + { + theHeader->HashTableSize64 = SwapUInt64(theHeader->HashTableSize64); + theHeader->BlockTableSize64 = SwapUInt64(theHeader->BlockTableSize64); + theHeader->HiBlockTableSize64 = SwapUInt64(theHeader->HiBlockTableSize64); + theHeader->HetTableSize64 = SwapUInt64(theHeader->HetTableSize64); + theHeader->BetTableSize64 = SwapUInt64(theHeader->BetTableSize64); + } +} + +#endif // STORMLIB_LITTLE_ENDIAN diff --git a/StormLib/src/SBaseDumpData.cpp b/StormLib/src/SBaseDumpData.cpp new file mode 100644 index 000000000..b08796a4a --- /dev/null +++ b/StormLib/src/SBaseDumpData.cpp @@ -0,0 +1,183 @@ +/*****************************************************************************/ +/* SBaseDumpData.cpp Copyright (c) Ladislav Zezula 2011 */ +/*---------------------------------------------------------------------------*/ +/* Description : */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 26.01.11 1.00 Lad The first version of SBaseDumpData.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" + +#ifdef __STORMLIB_DUMP_DATA__ + +void DumpMpqHeader(TMPQHeader * pHeader) +{ + printf("== MPQ Header =================================\n"); + printf("DWORD dwID = %08X\n", pHeader->dwID); + printf("DWORD dwHeaderSize = %08X\n", pHeader->dwHeaderSize); + printf("DWORD dwArchiveSize = %08X\n", pHeader->dwArchiveSize); + printf("USHORT wFormatVersion = %04X\n", pHeader->wFormatVersion); + printf("USHORT wSectorSize = %04X\n", pHeader->wSectorSize); + printf("DWORD dwHashTablePos = %08X\n", pHeader->dwHashTablePos); + printf("DWORD dwBlockTablePos = %08X\n", pHeader->dwBlockTablePos); + printf("DWORD dwHashTableSize = %08X\n", pHeader->dwHashTableSize); + printf("DWORD dwBlockTableSize = %08X\n", pHeader->dwBlockTableSize); + printf("ULONGLONG HiBlockTablePos64 = %016llX\n", pHeader->HiBlockTablePos64); + printf("USHORT wHashTablePosHi = %04X\n", pHeader->wHashTablePosHi); + printf("USHORT wBlockTablePosHi = %04X\n", pHeader->wBlockTablePosHi); + printf("ULONGLONG ArchiveSize64 = %016llX\n", pHeader->ArchiveSize64); + printf("ULONGLONG BetTablePos64 = %016llX\n", pHeader->BetTablePos64); + printf("ULONGLONG HetTablePos64 = %016llX\n", pHeader->HetTablePos64); + printf("ULONGLONG HashTableSize64 = %016llX\n", pHeader->HashTableSize64); + printf("ULONGLONG BlockTableSize64 = %016llX\n", pHeader->BlockTableSize64); + printf("ULONGLONG HiBlockTableSize64 = %016llX\n", pHeader->HiBlockTableSize64); + printf("ULONGLONG HetTableSize64 = %016llX\n", pHeader->HetTableSize64); + printf("ULONGLONG BetTableSize64 = %016llX\n", pHeader->BetTableSize64); + printf("DWORD dwRawChunkSize = %08X\n", pHeader->dwRawChunkSize); + printf("-----------------------------------------------\n\n"); +} + +void DumpHashTable(TMPQHash * pHashTable, DWORD dwHashTableSize) +{ + DWORD i; + + if(pHashTable == NULL || dwHashTableSize == 0) + return; + + printf("== Hash Table =================================\n"); + for(i = 0; i < dwHashTableSize; i++) + { + printf("[%08x] %08X %08X %04X %02X %08X\n", i, + pHashTable[i].dwName1, + pHashTable[i].dwName2, + pHashTable[i].lcLocale, + pHashTable[i].Platform, + pHashTable[i].dwBlockIndex); + } + printf("-----------------------------------------------\n\n"); +} + +void DumpHetAndBetTable(TMPQHetTable * pHetTable, TMPQBetTable * pBetTable) +{ + DWORD i; + + if(pHetTable == NULL || pBetTable == NULL) + return; + + printf("== HET Header =================================\n"); + printf("ULONGLONG AndMask64 = %016llX\n", pHetTable->AndMask64); + printf("ULONGLONG OrMask64 = %016llX\n", pHetTable->OrMask64); + printf("DWORD dwEntryCount = %08X\n", pHetTable->dwEntryCount); + printf("DWORD dwTotalCount = %08X\n", pHetTable->dwTotalCount); + printf("DWORD dwNameHashBitSize = %08X\n", pHetTable->dwNameHashBitSize); + printf("DWORD dwIndexSizeTotal = %08X\n", pHetTable->dwIndexSizeTotal); + printf("DWORD dwIndexSizeExtra = %08X\n", pHetTable->dwIndexSizeExtra); + printf("DWORD dwIndexSize = %08X\n", pHetTable->dwIndexSize); + printf("-----------------------------------------------\n\n"); + + printf("== BET Header =================================\n"); + printf("DWORD dwTableEntrySize = %08X\n", pBetTable->dwTableEntrySize); + printf("DWORD dwBitIndex_FilePos = %08X\n", pBetTable->dwBitIndex_FilePos); + printf("DWORD dwBitIndex_FileSize = %08X\n", pBetTable->dwBitIndex_FileSize); + printf("DWORD dwBitIndex_CmpSize = %08X\n", pBetTable->dwBitIndex_CmpSize); + printf("DWORD dwBitIndex_FlagIndex = %08X\n", pBetTable->dwBitIndex_FlagIndex); + printf("DWORD dwBitIndex_Unknown = %08X\n", pBetTable->dwBitIndex_Unknown); + printf("DWORD dwBitCount_FilePos = %08X\n", pBetTable->dwBitCount_FilePos); + printf("DWORD dwBitCount_FileSize = %08X\n", pBetTable->dwBitCount_FileSize); + printf("DWORD dwBitCount_CmpSize = %08X\n", pBetTable->dwBitCount_CmpSize); + printf("DWORD dwBitCount_FlagIndex = %08X\n", pBetTable->dwBitCount_FlagIndex); + printf("DWORD dwBitCount_Unknown = %08X\n", pBetTable->dwBitCount_Unknown); + printf("DWORD dwBitTotal_NameHash2 = %08X\n", pBetTable->dwBitTotal_NameHash2); + printf("DWORD dwBitExtra_NameHash2 = %08X\n", pBetTable->dwBitExtra_NameHash2); + printf("DWORD dwBitCount_NameHash2 = %08X\n", pBetTable->dwBitCount_NameHash2); + printf("DWORD dwEntryCount = %08X\n", pBetTable->dwEntryCount); + printf("DWORD dwFlagCount = %08X\n", pBetTable->dwFlagCount); + printf("-----------------------------------------------\n\n"); + + printf("== HET & Bet Table ======================================================================\n\n"); + printf("HetIdx HetHash BetIdx BetHash ByteOffset FileSize CmpSize FlgIdx Flags \n"); + printf("------ ------- ------ ---------------- ---------------- -------- -------- ------ --------\n"); + for(i = 0; i < pHetTable->dwTotalCount; i++) + { + ULONGLONG ByteOffset = 0; + ULONGLONG BetHash = 0; + DWORD dwFileSize = 0; + DWORD dwCmpSize = 0; + DWORD dwFlagIndex = 0; + DWORD dwFlags = 0; + DWORD dwBetIndex = 0; + + GetMPQBits(pHetTable->pBetIndexes, i * pHetTable->dwIndexSizeTotal, + pHetTable->dwIndexSize, + &dwBetIndex, 4); + + if(dwBetIndex < pHetTable->dwTotalCount) + { + DWORD dwEntryIndex = pBetTable->dwTableEntrySize * dwBetIndex; + + GetMPQBits(pBetTable->pNameHashes, dwBetIndex * pBetTable->dwBitTotal_NameHash2, + pBetTable->dwBitCount_NameHash2, + &BetHash, 8); + + GetMPQBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FilePos, + pBetTable->dwBitCount_FilePos, + &ByteOffset, 8); + + GetMPQBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FileSize, + pBetTable->dwBitCount_FileSize, + &dwFileSize, 4); + + GetMPQBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_CmpSize, + pBetTable->dwBitCount_CmpSize, + &dwCmpSize, 4); + + GetMPQBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FlagIndex, + pBetTable->dwBitCount_FlagIndex, + &dwFlagIndex, 4); + + dwFlags = pBetTable->pFileFlags[dwFlagIndex]; + } + + printf(" %04X %02lX %04X %016llX %016llX %08X %08X %04X %08X\n", i, + pHetTable->pNameHashes[i], + dwBetIndex, + BetHash, + ByteOffset, + dwFileSize, + dwCmpSize, + dwFlagIndex, + dwFlags); + } + printf("-----------------------------------------------------------------------------------------\n"); +} + +void DumpFileTable(TFileEntry * pFileTable, DWORD dwFileTableSize) +{ + DWORD i; + + if(pFileTable == NULL || dwFileTableSize == 0) + return; + + printf("== File Table =================================\n"); + for(i = 0; i < dwFileTableSize; i++, pFileTable++) + { + printf("[%04u] %08X-%08X %08X-%08X %08X-%08X 0x%08X 0x%08X 0x%08X %s\n", i, + (DWORD)(pFileTable->FileNameHash >> 0x20), + (DWORD)(pFileTable->FileNameHash & 0xFFFFFFFF), + (DWORD)(pFileTable->ByteOffset >> 0x20), + (DWORD)(pFileTable->ByteOffset & 0xFFFFFFFF), + (DWORD)(pFileTable->FileTime >> 0x20), + (DWORD)(pFileTable->FileTime & 0xFFFFFFFF), + pFileTable->dwFileSize, + pFileTable->dwCmpSize, + pFileTable->dwFlags, + pFileTable->szFileName != NULL ? pFileTable->szFileName : ""); + } + printf("-----------------------------------------------\n\n"); +} + +#endif // __STORMLIB_DUMP_DATA__ diff --git a/StormLib/src/SBaseFileTable.cpp b/StormLib/src/SBaseFileTable.cpp new file mode 100644 index 000000000..58a993d72 --- /dev/null +++ b/StormLib/src/SBaseFileTable.cpp @@ -0,0 +1,3101 @@ +/*****************************************************************************/ +/* SBaseFileTable.cpp Copyright (c) Ladislav Zezula 2010 */ +/*---------------------------------------------------------------------------*/ +/* Description: Common handler for classic and new hash&block tables */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 06.09.10 1.00 Lad The first version of SBaseFileTable.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" + +//----------------------------------------------------------------------------- +// Local defines + +#define INVALID_FLAG_VALUE 0xCCCCCCCC +#define MAX_FLAG_INDEX 512 + +//----------------------------------------------------------------------------- +// Support for calculating bit sizes + +static void InitFileFlagArray(LPDWORD FlagArray) +{ + memset(FlagArray, 0xCC, MAX_FLAG_INDEX * sizeof(DWORD)); +} + +static DWORD GetFileFlagIndex(LPDWORD FlagArray, DWORD dwFlags) +{ + // Find free or equal entry in the flag array + for(DWORD dwFlagIndex = 0; dwFlagIndex < MAX_FLAG_INDEX; dwFlagIndex++) + { + if(FlagArray[dwFlagIndex] == INVALID_FLAG_VALUE || FlagArray[dwFlagIndex] == dwFlags) + { + FlagArray[dwFlagIndex] = dwFlags; + return dwFlagIndex; + } + } + + // This should never happen + assert(false); + return 0xFFFFFFFF; +} + +static DWORD GetNecessaryBitCount(ULONGLONG MaxValue) +{ + DWORD dwBitCount = 0; + + while(MaxValue > 0) + { + MaxValue >>= 1; + dwBitCount++; + } + + return dwBitCount; +} + +//----------------------------------------------------------------------------- +// Implementation of the TMPQBits struct + +struct TMPQBits +{ + static TMPQBits * Create(DWORD NumberOfBits, BYTE FillValue); + + void GetBits(unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultSize); + void SetBits(unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultSize); + + static const USHORT SetBitsMask[]; // Bit mask for each number of bits (0-8) + + DWORD NumberOfBytes; // Total number of bytes in "Elements" + DWORD NumberOfBits; // Total number of bits that are available + BYTE Elements[1]; // Array of elements (variable length) +}; + +const USHORT TMPQBits::SetBitsMask[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF}; + +TMPQBits * TMPQBits::Create( + DWORD NumberOfBits, + BYTE FillValue) +{ + TMPQBits * pBitArray; + size_t nSize = sizeof(TMPQBits) + (NumberOfBits + 7) / 8; + + // Allocate the bit array + pBitArray = (TMPQBits *)STORM_ALLOC(BYTE, nSize); + if(pBitArray != NULL) + { + memset(pBitArray, FillValue, nSize); + pBitArray->NumberOfBytes = (NumberOfBits + 7) / 8; + pBitArray->NumberOfBits = NumberOfBits; + } + + return pBitArray; +} + +void TMPQBits::GetBits( + unsigned int nBitPosition, + unsigned int nBitLength, + void * pvBuffer, + int nResultByteSize) +{ + unsigned char * pbBuffer = (unsigned char *)pvBuffer; + unsigned int nBytePosition0 = (nBitPosition / 8); + unsigned int nBytePosition1 = nBytePosition0 + 1; + unsigned int nByteLength = (nBitLength / 8); + unsigned int nBitOffset = (nBitPosition & 0x07); + unsigned char BitBuffer; + + // Keep compiler happy for platforms where nResultByteSize is not used + nResultByteSize = nResultByteSize; + +#ifdef _DEBUG + // Check if the target is properly zeroed + for(int i = 0; i < nResultByteSize; i++) + assert(pbBuffer[i] == 0); +#endif + +#ifndef STORMLIB_LITTLE_ENDIAN + // Adjust the buffer pointer for big endian platforms + pbBuffer += (nResultByteSize - 1); +#endif + + // Copy whole bytes, if any + while(nByteLength > 0) + { + // Is the current position in the Elements byte-aligned? + if(nBitOffset != 0) + { + BitBuffer = (unsigned char)((Elements[nBytePosition0] >> nBitOffset) | (Elements[nBytePosition1] << (0x08 - nBitOffset))); + } + else + { + BitBuffer = Elements[nBytePosition0]; + } + +#ifdef STORMLIB_LITTLE_ENDIAN + *pbBuffer++ = BitBuffer; +#else + *pbBuffer-- = BitBuffer; +#endif + + // Move byte positions and lengths + nBytePosition1++; + nBytePosition0++; + nByteLength--; + } + + // Get the rest of the bits + nBitLength = (nBitLength & 0x07); + if(nBitLength != 0) + { + *pbBuffer = (unsigned char)(Elements[nBytePosition0] >> nBitOffset); + + if(nBitLength > (8 - nBitOffset)) + *pbBuffer = (unsigned char)((Elements[nBytePosition1] << (8 - nBitOffset)) | (Elements[nBytePosition0] >> nBitOffset)); + + *pbBuffer &= (0x01 << nBitLength) - 1; + } +} + +void TMPQBits::SetBits( + unsigned int nBitPosition, + unsigned int nBitLength, + void * pvBuffer, + int nResultByteSize) +{ + unsigned char * pbBuffer = (unsigned char *)pvBuffer; + unsigned int nBytePosition = (nBitPosition / 8); + unsigned int nBitOffset = (nBitPosition & 0x07); + unsigned short BitBuffer = 0; + unsigned short AndMask = 0; + unsigned short OneByte = 0; + + // Keep compiler happy for platforms where nResultByteSize is not used + nResultByteSize = nResultByteSize; + +#ifndef STORMLIB_LITTLE_ENDIAN + // Adjust the buffer pointer for big endian platforms + pbBuffer += (nResultByteSize - 1); +#endif + + // Copy whole bytes, if any + while(nBitLength > 8) + { + // Reload the bit buffer +#ifdef STORMLIB_LITTLE_ENDIAN + OneByte = *pbBuffer++; +#else + OneByte = *pbBuffer--; +#endif + // Update the BitBuffer and AndMask for the bit array + BitBuffer = (BitBuffer >> 0x08) | (OneByte << nBitOffset); + AndMask = (AndMask >> 0x08) | (0x00FF << nBitOffset); + + // Update the byte in the array + Elements[nBytePosition] = (BYTE)((Elements[nBytePosition] & ~AndMask) | BitBuffer); + + // Move byte positions and lengths + nBytePosition++; + nBitLength -= 0x08; + } + + if(nBitLength != 0) + { + // Reload the bit buffer + OneByte = *pbBuffer; + + // Update the AND mask for the last bit + BitBuffer = (BitBuffer >> 0x08) | (OneByte << nBitOffset); + AndMask = (AndMask >> 0x08) | (SetBitsMask[nBitLength] << nBitOffset); + + // Update the byte in the array + Elements[nBytePosition] = (BYTE)((Elements[nBytePosition] & ~AndMask) | BitBuffer); + + // Update the next byte, if needed + if(AndMask & 0xFF00) + { + nBytePosition++; + BitBuffer >>= 0x08; + AndMask >>= 0x08; + + Elements[nBytePosition] = (BYTE)((Elements[nBytePosition] & ~AndMask) | BitBuffer); + } + } +} + +void GetMPQBits(TMPQBits * pBits, unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultByteSize) +{ + pBits->GetBits(nBitPosition, nBitLength, pvBuffer, nResultByteSize); +} + +//----------------------------------------------------------------------------- +// Support for MPQ header + +static bool VerifyTablePosition64( + ULONGLONG MpqOffset, // Position of the MPQ header + ULONGLONG TableOffset, // Position of the MPQ table, relative to MPQ header + ULONGLONG TableSize, // Size of the MPQ table, in bytes + ULONGLONG FileSize) // Size of the entire file, in bytes +{ + if(TableOffset != 0) + { + // Verify overflows + if((MpqOffset + TableOffset) < MpqOffset) + return false; + if((MpqOffset + TableOffset + TableSize) < MpqOffset) + return false; + + // Verify sizes + if(TableOffset >= FileSize || TableSize >= FileSize) + return false; + if((MpqOffset + TableOffset) >= FileSize) + return false; + if((MpqOffset + TableOffset + TableSize) >= FileSize) + return false; + } + return true; +} + +static bool VerifyTableTandemPositions( + ULONGLONG MpqOffset, // Position of the MPQ header + ULONGLONG TableOffset1, // 1st table: Position, relative to MPQ header + ULONGLONG TableSize1, // 1st table: Size in bytes + ULONGLONG TableOffset2, // 2nd table: Position, relative to MPQ header + ULONGLONG TableSize2, // 2nd table: Size in bytes + ULONGLONG FileSize) // Size of the entire file, in bytes +{ + return VerifyTablePosition64(MpqOffset, TableOffset1, TableSize1, FileSize) && + VerifyTablePosition64(MpqOffset, TableOffset2, TableSize2, FileSize); +} + +static ULONGLONG DetermineArchiveSize_V1( + TMPQArchive * ha, + TMPQHeader * pHeader, + ULONGLONG MpqOffset, + ULONGLONG FileSize) +{ + ULONGLONG ByteOffset; + ULONGLONG EndOfMpq = FileSize; + DWORD SignatureHeader = 0; + DWORD dwArchiveSize32; + + // This could only be called for MPQs version 1.0 + assert(pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1); + + // Check if we can rely on the archive size in the header + if(pHeader->dwBlockTablePos < pHeader->dwArchiveSize) + { + // The block table cannot be compressed, so the sizes must match + if((pHeader->dwArchiveSize - pHeader->dwBlockTablePos) == (pHeader->dwBlockTableSize * sizeof(TMPQBlock))) + return pHeader->dwArchiveSize; + + // If the archive size in the header is less than real file size + dwArchiveSize32 = (DWORD)(FileSize - MpqOffset); + if(pHeader->dwArchiveSize == dwArchiveSize32) + return pHeader->dwArchiveSize; + } + + // Check if there is a signature header + if((EndOfMpq - MpqOffset) > (MPQ_STRONG_SIGNATURE_SIZE + 4)) + { + ByteOffset = EndOfMpq - MPQ_STRONG_SIGNATURE_SIZE - 4; + if(FileStream_Read(ha->pStream, &ByteOffset, &SignatureHeader, sizeof(DWORD))) + { + if(BSWAP_INT32_UNSIGNED(SignatureHeader) == MPQ_STRONG_SIGNATURE_ID) + EndOfMpq = EndOfMpq - MPQ_STRONG_SIGNATURE_SIZE - 4; + } + } + + // Return the returned archive size + return (EndOfMpq - MpqOffset); +} + +static ULONGLONG DetermineArchiveSize_V2( + TMPQHeader * pHeader, + ULONGLONG MpqOffset, + ULONGLONG FileSize) +{ + ULONGLONG EndOfMpq = FileSize; + DWORD dwArchiveSize32; + + // This could only be called for MPQs version 2.0 + assert(pHeader->wFormatVersion == MPQ_FORMAT_VERSION_2); + + // Check if we can rely on the archive size in the header + if((FileSize >> 0x20) == 0) + { + if(pHeader->dwBlockTablePos < pHeader->dwArchiveSize) + { + if((pHeader->dwArchiveSize - pHeader->dwBlockTablePos) <= (pHeader->dwBlockTableSize * sizeof(TMPQBlock))) + return pHeader->dwArchiveSize; + + // If the archive size in the header is less than real file size + dwArchiveSize32 = (DWORD)(FileSize - MpqOffset); + if(pHeader->dwArchiveSize <= dwArchiveSize32) + return pHeader->dwArchiveSize; + } + } + + // Return the calculated archive size + return (EndOfMpq - MpqOffset); +} + +static ULONGLONG DetermineArchiveSize_V4( + TMPQHeader * pHeader, + ULONGLONG /* MpqOffset */, + ULONGLONG /* FileSize */) +{ + ULONGLONG ArchiveSize = 0; + ULONGLONG EndOfTable; + + // This could only be called for MPQs version 4 + assert(pHeader->wFormatVersion == MPQ_FORMAT_VERSION_4); + + // Check position of BET table, if correct + if((pHeader->BetTablePos64 >> 0x20) == 0 && (pHeader->BetTableSize64 >> 0x20) == 0) + { + EndOfTable = pHeader->BetTablePos64 + pHeader->BetTableSize64; + if(EndOfTable > ArchiveSize) + ArchiveSize = EndOfTable; + } + + // Check position of HET table, if correct + if((pHeader->HetTablePos64 >> 0x20) == 0 && (pHeader->HetTableSize64 >> 0x20) == 0) + { + EndOfTable = pHeader->HetTablePos64 + pHeader->HetTableSize64; + if(EndOfTable > ArchiveSize) + ArchiveSize = EndOfTable; + } + + EndOfTable = pHeader->dwHashTablePos + pHeader->dwHashTableSize * sizeof(TMPQHash); + if(EndOfTable > ArchiveSize) + ArchiveSize = EndOfTable; + + EndOfTable = pHeader->dwBlockTablePos + pHeader->dwBlockTableSize * sizeof(TMPQBlock); + if(EndOfTable > ArchiveSize) + ArchiveSize = EndOfTable; + + // Return the calculated archive size + return ArchiveSize; +} + +ULONGLONG FileOffsetFromMpqOffset(TMPQArchive * ha, ULONGLONG MpqOffset) +{ + if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1) + { + // For MPQ archive v1, any file offset is only 32-bit + return (ULONGLONG)((DWORD)ha->MpqPos + (DWORD)MpqOffset); + } + else + { + // For MPQ archive v2+, file offsets are full 64-bit + return ha->MpqPos + MpqOffset; + } +} + +ULONGLONG CalculateRawSectorOffset( + TMPQFile * hf, + DWORD dwSectorOffset) +{ + ULONGLONG RawFilePos; + + // Must be used for files within a MPQ + assert(hf->ha != NULL); + assert(hf->ha->pHeader != NULL); + + // + // Some MPQ protectors place the sector offset table after the actual file data. + // Sector offsets in the sector offset table are negative. When added + // to MPQ file offset from the block table entry, the result is a correct + // position of the file data in the MPQ. + // + // For MPQs version 1.0, the offset is purely 32-bit + // + + RawFilePos = hf->RawFilePos + dwSectorOffset; + if(hf->ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1) + RawFilePos = (DWORD)hf->ha->MpqPos + (DWORD)hf->pFileEntry->ByteOffset + dwSectorOffset; + + // We also have to add patch header size, if patch header is present + if(hf->pPatchInfo != NULL) + RawFilePos += hf->pPatchInfo->dwLength; + + // Return the result offset + return RawFilePos; +} + +// This function converts the MPQ header so it always looks like version 4 +DWORD ConvertMpqHeaderToFormat4( + TMPQArchive * ha, + ULONGLONG ByteOffset, + ULONGLONG FileSize, + DWORD dwFlags, + MTYPE MapType) +{ + TMPQHeader * pHeader = (TMPQHeader *)ha->HeaderData; + ULONGLONG BlockTablePos64 = 0; + ULONGLONG HashTablePos64 = 0; + ULONGLONG BlockTableMask = (ULONGLONG)-1; + ULONGLONG MaxOffset; + USHORT wFormatVersion = BSWAP_INT16_UNSIGNED(pHeader->wFormatVersion); + bool bHashBlockOffsetOK = false; + bool bHetBetOffsetOK = false; + DWORD dwErrCode = ERROR_SUCCESS; + + // If version 1.0 is forced, then the format version is forced to be 1.0 + // Reason: Storm.dll in Warcraft III ignores format version value + if((MapType == MapTypeWarcraft3) || (dwFlags & MPQ_OPEN_FORCE_MPQ_V1)) + wFormatVersion = MPQ_FORMAT_VERSION_1; + + // Don't accept format 3 for Starcraft II maps + if((MapType == MapTypeStarcraft2) && (pHeader->wFormatVersion > MPQ_FORMAT_VERSION_2)) + wFormatVersion = MPQ_FORMAT_VERSION_4; + + // Format-specific fixes + switch(wFormatVersion) + { + case MPQ_FORMAT_VERSION_1: + + // Check for malformed MPQ header version 1.0 + BSWAP_TMPQHEADER(pHeader, MPQ_FORMAT_VERSION_1); + if(pHeader->wFormatVersion != MPQ_FORMAT_VERSION_1 || pHeader->dwHeaderSize != MPQ_HEADER_SIZE_V1) + { + pHeader->wFormatVersion = MPQ_FORMAT_VERSION_1; + pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V1; + ha->dwFlags |= MPQ_FLAG_MALFORMED; + } + + // + // Note: The value of "dwArchiveSize" member in the MPQ header + // is ignored by Storm.dll and can contain garbage value + // ("w3xmaster" protector). + // + + Label_ArchiveVersion1: + if(pHeader->dwBlockTableSize > 1) // Prevent empty MPQs being marked as malformed + { + if(pHeader->dwHashTablePos <= pHeader->dwHeaderSize || (pHeader->dwHashTablePos & 0x80000000)) + ha->dwFlags |= MPQ_FLAG_MALFORMED; + if(pHeader->dwBlockTablePos <= pHeader->dwHeaderSize || (pHeader->dwBlockTablePos & 0x80000000)) + ha->dwFlags |= MPQ_FLAG_MALFORMED; + } + + // Only low byte of sector size is really used + if(pHeader->wSectorSize & 0xFF00) + ha->dwFlags |= MPQ_FLAG_MALFORMED; + pHeader->wSectorSize = pHeader->wSectorSize & 0xFF; + + // Fill the rest of the header + memset((LPBYTE)pHeader + MPQ_HEADER_SIZE_V1, 0, sizeof(TMPQHeader) - MPQ_HEADER_SIZE_V1); + pHeader->BlockTableSize64 = pHeader->dwBlockTableSize * sizeof(TMPQBlock); + pHeader->HashTableSize64 = pHeader->dwHashTableSize * sizeof(TMPQHash); + pHeader->ArchiveSize64 = pHeader->dwArchiveSize; + + // Block table position must be calculated as 32-bit value + // Note: BOBA protector puts block table before the MPQ header, so it is negative + BlockTablePos64 = (ULONGLONG)((DWORD)ByteOffset + pHeader->dwBlockTablePos); + BlockTableMask = 0xFFFFFFF0; + + // Determine the archive size on malformed MPQs + if(ha->dwFlags & MPQ_FLAG_MALFORMED) + { + // Calculate the archive size + pHeader->ArchiveSize64 = DetermineArchiveSize_V1(ha, pHeader, ByteOffset, FileSize); + pHeader->dwArchiveSize = (DWORD)pHeader->ArchiveSize64; + } + + // EWIX_v8_7.w3x: TMPQHeader::dwBlockTableSize = 0x00319601 + // Size of TFileTable goes to ~200MB, so we artificially cut it + if(BlockTablePos64 + (pHeader->dwBlockTableSize * sizeof(TMPQBlock)) > FileSize) + { + pHeader->dwBlockTableSize = (DWORD)((FileSize - BlockTablePos64) / sizeof(TMPQBlock)); + pHeader->BlockTableSize64 = pHeader->dwBlockTableSize * sizeof(TMPQBlock); + } + break; + + case MPQ_FORMAT_VERSION_2: + + // Check for malformed MPQ header version 1.0 + BSWAP_TMPQHEADER(pHeader, MPQ_FORMAT_VERSION_2); + if(pHeader->wFormatVersion != MPQ_FORMAT_VERSION_2 || pHeader->dwHeaderSize != MPQ_HEADER_SIZE_V2) + { + pHeader->wFormatVersion = MPQ_FORMAT_VERSION_1; + pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V1; + ha->dwFlags |= MPQ_FLAG_MALFORMED; + goto Label_ArchiveVersion1; + } + + // Fill the rest of the header with zeros + memset((LPBYTE)pHeader + MPQ_HEADER_SIZE_V2, 0, sizeof(TMPQHeader) - MPQ_HEADER_SIZE_V2); + + // Calculate the expected hash table size + pHeader->HashTableSize64 = (pHeader->dwHashTableSize * sizeof(TMPQHash)); + HashTablePos64 = MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos); + + // Calculate the expected block table size + pHeader->BlockTableSize64 = (pHeader->dwBlockTableSize * sizeof(TMPQBlock)); + BlockTablePos64 = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos); + + // We require the block table to follow hash table + if(BlockTablePos64 >= HashTablePos64) + { + // HashTableSize64 may be less than TblSize * sizeof(TMPQHash). + // That means that the hash table is compressed. + pHeader->HashTableSize64 = BlockTablePos64 - HashTablePos64; + + // Calculate the compressed block table size + if(pHeader->HiBlockTablePos64 != 0) + { + // BlockTableSize64 may be less than TblSize * sizeof(TMPQBlock). + // That means that the block table is compressed. + pHeader->BlockTableSize64 = pHeader->HiBlockTablePos64 - BlockTablePos64; + assert(pHeader->BlockTableSize64 <= (pHeader->dwBlockTableSize * sizeof(TMPQBlock))); + + // Determine real archive size + pHeader->ArchiveSize64 = DetermineArchiveSize_V2(pHeader, ByteOffset, FileSize); + + // Calculate the size of the hi-block table + pHeader->HiBlockTableSize64 = pHeader->ArchiveSize64 - pHeader->HiBlockTablePos64; + assert(pHeader->HiBlockTableSize64 == (pHeader->dwBlockTableSize * sizeof(USHORT))); + } + else + { + // Determine real archive size + pHeader->ArchiveSize64 = DetermineArchiveSize_V2(pHeader, ByteOffset, FileSize); + + // Calculate size of the block table + pHeader->BlockTableSize64 = pHeader->ArchiveSize64 - BlockTablePos64; + assert(pHeader->BlockTableSize64 <= (pHeader->dwBlockTableSize * sizeof(TMPQBlock))); + } + } + else + { + pHeader->ArchiveSize64 = pHeader->dwArchiveSize; + ha->dwFlags |= MPQ_FLAG_MALFORMED; + } + + // Add the MPQ Offset + BlockTablePos64 += ByteOffset; + break; + + case MPQ_FORMAT_VERSION_3: + + // In MPQ format 3.0, the entire header is optional + // and the size of the header can actually be identical + // to size of header 2.0 + BSWAP_TMPQHEADER(pHeader, MPQ_FORMAT_VERSION_3); + if(pHeader->dwHeaderSize < MPQ_HEADER_SIZE_V3) + { + pHeader->ArchiveSize64 = pHeader->dwArchiveSize; + pHeader->HetTablePos64 = 0; + pHeader->BetTablePos64 = 0; + } + + // + // We need to calculate the compressed size of each table. We assume the following order: + // 1) HET table + // 2) BET table + // 3) Classic hash table + // 4) Classic block table + // 5) Hi-block table + // + + // Fill the rest of the header with zeros + memset((LPBYTE)pHeader + MPQ_HEADER_SIZE_V3, 0, sizeof(TMPQHeader) - MPQ_HEADER_SIZE_V3); + BlockTablePos64 = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos); + HashTablePos64 = MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos); + MaxOffset = pHeader->ArchiveSize64; + + // Size of the hi-block table + if(pHeader->HiBlockTablePos64) + { + pHeader->HiBlockTableSize64 = MaxOffset - pHeader->HiBlockTablePos64; + MaxOffset = pHeader->HiBlockTablePos64; + } + + // Size of the block table + if(BlockTablePos64) + { + pHeader->BlockTableSize64 = MaxOffset - BlockTablePos64; + MaxOffset = BlockTablePos64; + } + + // Size of the hash table + if(HashTablePos64) + { + pHeader->HashTableSize64 = MaxOffset - HashTablePos64; + MaxOffset = HashTablePos64; + } + + // Size of the BET table + if(pHeader->BetTablePos64) + { + pHeader->BetTableSize64 = MaxOffset - pHeader->BetTablePos64; + MaxOffset = pHeader->BetTablePos64; + } + + // Size of the HET table + if(pHeader->HetTablePos64) + { + pHeader->HetTableSize64 = MaxOffset - pHeader->HetTablePos64; +// MaxOffset = pHeader->HetTablePos64; + } + + // Add the MPQ Offset + BlockTablePos64 += ByteOffset; + break; + + case MPQ_FORMAT_VERSION_4: + + // Verify header MD5. Header MD5 is calculated from the MPQ header since the 'MPQ\x1A' + // signature until the position of header MD5 at offset 0xC0 + BSWAP_TMPQHEADER(pHeader, MPQ_FORMAT_VERSION_4); + + // Apparently, Starcraft II only accepts MPQ headers where the MPQ header hash matches + // If MD5 doesn't match, we ignore this offset. We also ignore it if there's no MD5 at all + if(!IsValidMD5(pHeader->MD5_MpqHeader)) + return ERROR_FAKE_MPQ_HEADER; + if(!VerifyDataBlockHash(pHeader, MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE, pHeader->MD5_MpqHeader)) + return ERROR_FAKE_MPQ_HEADER; + + // HiBlockTable must be 0 for archives under 4GB + if((pHeader->ArchiveSize64 >> 0x20) == 0 && pHeader->HiBlockTablePos64 != 0) + return ERROR_FAKE_MPQ_HEADER; + + // Is the "HET&BET" table tandem OK? + bHetBetOffsetOK = VerifyTableTandemPositions(ByteOffset, + pHeader->HetTablePos64, pHeader->HetTableSize64, + pHeader->BetTablePos64, pHeader->BetTableSize64, + FileSize); + + // Is the "Hash&Block" table tandem OK? + bHashBlockOffsetOK = VerifyTableTandemPositions(ByteOffset, + pHeader->dwHashTablePos, pHeader->HashTableSize64, + pHeader->dwBlockTablePos, pHeader->BlockTableSize64, + FileSize); + + // At least one pair must be OK + if(bHetBetOffsetOK == false && bHashBlockOffsetOK == false) + return ERROR_FAKE_MPQ_HEADER; + + // Check for malformed MPQs + if(pHeader->wFormatVersion != MPQ_FORMAT_VERSION_4 || (ByteOffset + pHeader->ArchiveSize64) != FileSize || (ByteOffset + pHeader->HiBlockTablePos64) >= FileSize) + { + pHeader->wFormatVersion = MPQ_FORMAT_VERSION_4; + pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V4; + ha->dwFlags |= MPQ_FLAG_MALFORMED; + } + + // Recalculate archive size + if(ha->dwFlags & MPQ_FLAG_MALFORMED) + { + // Calculate the archive size + pHeader->ArchiveSize64 = DetermineArchiveSize_V4(pHeader, ByteOffset, FileSize); + pHeader->dwArchiveSize = (DWORD)pHeader->ArchiveSize64; + } + + // Calculate the block table position + BlockTablePos64 = ByteOffset + MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos); + break; + + default: + + // Check if it's a War of the Immortal data file (SQP) + // If not, we treat it as malformed MPQ version 1.0 + if(ConvertSqpHeaderToFormat4(ha, FileSize, dwFlags) != ERROR_SUCCESS) + { + pHeader->wFormatVersion = MPQ_FORMAT_VERSION_1; + pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V1; + ha->dwFlags |= MPQ_FLAG_MALFORMED; + goto Label_ArchiveVersion1; + } + + // Calculate the block table position + BlockTablePos64 = ByteOffset + MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos); + break; + } + + // Handle case when block table is placed before the MPQ header + // Used by BOBA protector + if(BlockTablePos64 < ByteOffset) + ha->dwFlags |= MPQ_FLAG_MALFORMED; + return dwErrCode; +} + +//----------------------------------------------------------------------------- +// Support for hash table + +// Hash entry verification when the file table does not exist yet +bool IsValidHashEntry(TMPQArchive * ha, TMPQHash * pHash) +{ + TFileEntry * pFileEntry = ha->pFileTable + MPQ_BLOCK_INDEX(pHash); + + return ((MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize) && (pFileEntry->dwFlags & MPQ_FILE_EXISTS)) ? true : false; +} + +// Hash entry verification when the file table does not exist yet +static bool IsValidHashEntry1(TMPQArchive * ha, TMPQHash * pHash, TMPQBlock * pBlockTable) +{ + ULONGLONG ByteOffset; + TMPQBlock * pBlock; + + // The block index is considered valid if it's less than block table size + if(MPQ_BLOCK_INDEX(pHash) < ha->pHeader->dwBlockTableSize) + { + // Calculate the block table position + pBlock = pBlockTable + MPQ_BLOCK_INDEX(pHash); + + // Check whether this is an existing file + // Also we do not allow to be file size greater than 2GB + if((pBlock->dwFlags & MPQ_FILE_EXISTS) && (pBlock->dwFSize & 0x80000000) == 0) + { + // The begin of the file must be within the archive + ByteOffset = FileOffsetFromMpqOffset(ha, pBlock->dwFilePos); + return (ByteOffset < ha->FileSize); + } + } + + return false; +} + +// Returns a hash table entry in the following order: +// 1) A hash table entry with the preferred locale and platform +// 2) A hash table entry with the neutral|matching locale and neutral|matching platform +// 3) NULL +// Storm_2016.dll: 15020940 +static TMPQHash * GetHashEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale, BYTE Platform) +{ + TMPQHash * pFirstHash = GetFirstHashEntry(ha, szFileName); + TMPQHash * pBestEntry = NULL; + TMPQHash * pHash = pFirstHash; + + // Parse the found hashes + while(pHash != NULL) + { + // Storm_2016.dll: 150209CB + // If the hash entry matches both locale and platform, return it immediately + // Note: We only succeed this check if the locale is non-neutral, because + // some Warcraft III maps have several items with neutral locale&platform, which leads + // to wrong item being returned + if((lcLocale || Platform) && pHash->lcLocale == lcLocale && pHash->Platform == Platform) + return pHash; + + // Storm_2016.dll: 150209D9 + // If (locale matches or is neutral) OR (platform matches or is neutral) + // remember this as the best entry + if(pHash->lcLocale == 0 || pHash->lcLocale == lcLocale) + { + if(pHash->Platform == 0 || pHash->Platform == Platform) + pBestEntry = pHash; + } + + // Get the next hash entry for that file + pHash = GetNextHashEntry(ha, pFirstHash, pHash); + } + + // At the end, return neutral hash (if found), otherwise NULL + return pBestEntry; +} + +// Returns a hash table entry in the following order: +// 1) A hash table entry with the preferred locale +// 2) NULL +static TMPQHash * GetHashEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcLocale) +{ + TMPQHash * pFirstHash = GetFirstHashEntry(ha, szFileName); + TMPQHash * pHash = pFirstHash; + + // Parse the found hashes + while(pHash != NULL) + { + // If the locales match, return it + if(pHash->lcLocale == lcLocale) + return pHash; + + // Get the next hash entry for that file + pHash = GetNextHashEntry(ha, pFirstHash, pHash); + } + + // Not found + return NULL; +} + +// Defragment the file table so it does not contain any gaps +// Note: As long as all values of all TMPQHash::dwBlockIndex +// are not HASH_ENTRY_FREE, the startup search index does not matter. +// Hash table is circular, so as long as there is no terminator, +// all entries will be found. +static TMPQHash * DefragmentHashTable( + TMPQArchive * ha, + TMPQHash * pHashTable, + TMPQBlock * pBlockTable) +{ + TMPQHeader * pHeader = ha->pHeader; + TMPQHash * pHashTableEnd = pHashTable + pHeader->dwHashTableSize; + TMPQHash * pSource = pHashTable; + TMPQHash * pTarget = pHashTable; + DWORD dwFirstFreeEntry; + DWORD dwNewTableSize; + + // Sanity checks + assert(pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1); + assert(pHeader->HiBlockTablePos64 == 0); + + // Parse the hash table and move the entries to the begin of it + for(pSource = pHashTable; pSource < pHashTableEnd; pSource++) + { + // Check whether this is a valid hash table entry + if(IsValidHashEntry1(ha, pSource, pBlockTable)) + { + // Copy the hash table entry back + if(pSource > pTarget) + pTarget[0] = pSource[0]; + + // Move the target + pTarget++; + } + } + + // Calculate how many entries in the hash table we really need + dwFirstFreeEntry = (DWORD)(pTarget - pHashTable); + dwNewTableSize = GetNearestPowerOfTwo(dwFirstFreeEntry); + + // Fill the rest with entries that look like deleted + pHashTableEnd = pHashTable + dwNewTableSize; + pSource = pHashTable + dwFirstFreeEntry; + memset(pSource, 0xFF, (dwNewTableSize - dwFirstFreeEntry) * sizeof(TMPQHash)); + + // Mark the block indexes as deleted + for(; pSource < pHashTableEnd; pSource++) + pSource->dwBlockIndex = HASH_ENTRY_DELETED; + + // Free some of the space occupied by the hash table + if(dwNewTableSize < pHeader->dwHashTableSize) + { + pHashTable = STORM_REALLOC(TMPQHash, pHashTable, dwNewTableSize); + ha->pHeader->BlockTableSize64 = dwNewTableSize * sizeof(TMPQHash); + ha->pHeader->dwHashTableSize = dwNewTableSize; + } + + return pHashTable; +} + +static DWORD BuildFileTableFromBlockTable( + TMPQArchive * ha, + TMPQBlock * pBlockTable) +{ + TFileEntry * pFileEntry; + TMPQHeader * pHeader = ha->pHeader; + TMPQBlock * pBlock; + TMPQHash * pHashTableEnd; + TMPQHash * pHash; + LPDWORD DefragmentTable = NULL; + DWORD dwItemCount = 0; + DWORD dwFlagMask; + + // Sanity checks + assert(ha->pFileTable != NULL); + assert(ha->dwFileTableSize >= ha->dwMaxFileCount); + + // MPQs for Warcraft III doesn't know some flags, namely MPQ_FILE_SINGLE_UNIT and MPQ_FILE_PATCH_FILE + dwFlagMask = (ha->dwFlags & MPQ_FLAG_WAR3_MAP) ? MPQ_FILE_VALID_FLAGS_W3X : MPQ_FILE_VALID_FLAGS; + + // Defragment the hash table, if needed + if(ha->dwFlags & MPQ_FLAG_HASH_TABLE_CUT) + { + ha->pHashTable = DefragmentHashTable(ha, ha->pHashTable, pBlockTable); + ha->dwMaxFileCount = pHeader->dwHashTableSize; + } + + // If the hash table or block table is cut, + // we will defragment the block table + if(ha->dwFlags & (MPQ_FLAG_HASH_TABLE_CUT | MPQ_FLAG_BLOCK_TABLE_CUT)) + { + // Sanity checks + assert(pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1); + assert(pHeader->HiBlockTablePos64 == 0); + + // Allocate the translation table + DefragmentTable = STORM_ALLOC(DWORD, pHeader->dwBlockTableSize); + if(DefragmentTable == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // Fill the translation table + memset(DefragmentTable, 0xFF, pHeader->dwBlockTableSize * sizeof(DWORD)); + } + + // Parse the entire hash table + pHashTableEnd = ha->pHashTable + pHeader->dwHashTableSize; + for(pHash = ha->pHashTable; pHash < pHashTableEnd; pHash++) + { + // + // We need to properly handle these cases: + // - Multiple hash entries (same file name) point to the same block entry + // - Multiple hash entries (different file name) point to the same block entry + // + // Ignore all hash table entries where: + // - Block Index >= BlockTableSize + // - Flags of the appropriate block table entry + // + + if(IsValidHashEntry1(ha, pHash, pBlockTable)) + { + DWORD dwOldIndex = MPQ_BLOCK_INDEX(pHash); + DWORD dwNewIndex = MPQ_BLOCK_INDEX(pHash); + + // Determine the new block index + if(DefragmentTable != NULL) + { + // Need to handle case when multiple hash + // entries point to the same block entry + if(DefragmentTable[dwOldIndex] == HASH_ENTRY_FREE) + { + DefragmentTable[dwOldIndex] = dwItemCount; + dwNewIndex = dwItemCount++; + } + else + { + dwNewIndex = DefragmentTable[dwOldIndex]; + } + + // Fix the pointer in the hash entry + pHash->dwBlockIndex = dwNewIndex; + + // Dump the relocation entry +// printf("Relocating hash entry %08X-%08X: %08X -> %08X\n", pHash->dwName1, pHash->dwName2, dwBlockIndex, dwNewIndex); + } + + // Get the pointer to the file entry and the block entry + pFileEntry = ha->pFileTable + dwNewIndex; + pBlock = pBlockTable + dwOldIndex; + + // ByteOffset is only valid if file size is not zero + pFileEntry->ByteOffset = pBlock->dwFilePos; + if(pFileEntry->ByteOffset == 0 && pBlock->dwFSize == 0) + pFileEntry->ByteOffset = ha->pHeader->dwHeaderSize; + + // Fill the rest of the file entry + pFileEntry->dwFileSize = pBlock->dwFSize; + pFileEntry->dwCmpSize = pBlock->dwCSize; + pFileEntry->dwFlags = pBlock->dwFlags & dwFlagMask; + } + } + + // Free the translation table + if(DefragmentTable != NULL) + { + // If we defragmented the block table in the process, + // free some memory by shrinking the file table + if(ha->dwFileTableSize > ha->dwMaxFileCount) + { + ha->pFileTable = STORM_REALLOC(TFileEntry, ha->pFileTable, ha->dwMaxFileCount); + ha->pHeader->BlockTableSize64 = ha->dwMaxFileCount * sizeof(TMPQBlock); + ha->pHeader->dwBlockTableSize = ha->dwMaxFileCount; + ha->dwFileTableSize = ha->dwMaxFileCount; + } + +// DumpFileTable(ha->pFileTable, ha->dwFileTableSize); + + // Free the translation table + STORM_FREE(DefragmentTable); + } + + return ERROR_SUCCESS; +} + +static TMPQHash * TranslateHashTable( + TMPQArchive * ha, + ULONGLONG * pcbTableSize) +{ + TMPQHash * pHashTable; + size_t HashTableSize; + + // Allocate copy of the hash table + pHashTable = STORM_ALLOC(TMPQHash, ha->pHeader->dwHashTableSize); + if(pHashTable != NULL) + { + // Copy the hash table + HashTableSize = sizeof(TMPQHash) * ha->pHeader->dwHashTableSize; + memcpy(pHashTable, ha->pHashTable, HashTableSize); + + // Give the size to the caller + if(pcbTableSize != NULL) + { + *pcbTableSize = (ULONGLONG)HashTableSize; + } + } + + return pHashTable; +} + +// Also used in SFileGetFileInfo +TMPQBlock * TranslateBlockTable( + TMPQArchive * ha, + ULONGLONG * pcbTableSize, + bool * pbNeedHiBlockTable) +{ + TFileEntry * pFileEntry = ha->pFileTable; + TMPQBlock * pBlockTable; + TMPQBlock * pBlock; + DWORD NeedHiBlockTable = 0; + DWORD dwBlockTableSize = ha->pHeader->dwBlockTableSize; + + // Allocate copy of the hash table + pBlockTable = pBlock = STORM_ALLOC(TMPQBlock, dwBlockTableSize); + if(pBlockTable != NULL) + { + // Convert the block table + for(DWORD i = 0; i < dwBlockTableSize; i++) + { + NeedHiBlockTable |= (DWORD)(pFileEntry->ByteOffset >> 32); + pBlock->dwFilePos = (DWORD)pFileEntry->ByteOffset; + pBlock->dwFSize = pFileEntry->dwFileSize; + pBlock->dwCSize = pFileEntry->dwCmpSize; + pBlock->dwFlags = pFileEntry->dwFlags; + + pFileEntry++; + pBlock++; + } + + // Give the size to the caller + if(pcbTableSize != NULL) + *pcbTableSize = (ULONGLONG)dwBlockTableSize * sizeof(TMPQBlock); + + if(pbNeedHiBlockTable != NULL) + *pbNeedHiBlockTable = NeedHiBlockTable ? true : false; + } + + return pBlockTable; +} + +static USHORT * TranslateHiBlockTable( + TMPQArchive * ha, + ULONGLONG * pcbTableSize) +{ + TFileEntry * pFileEntry = ha->pFileTable; + USHORT * pHiBlockTable; + USHORT * pHiBlock; + DWORD dwBlockTableSize = ha->pHeader->dwBlockTableSize; + + // Allocate copy of the hash table + pHiBlockTable = pHiBlock = STORM_ALLOC(USHORT, dwBlockTableSize); + if(pHiBlockTable != NULL) + { + // Copy the block table + for(DWORD i = 0; i < dwBlockTableSize; i++) + pHiBlock[i] = (USHORT)(pFileEntry[i].ByteOffset >> 0x20); + + // Give the size to the caller + if(pcbTableSize != NULL) + *pcbTableSize = (ULONGLONG)dwBlockTableSize * sizeof(USHORT); + } + + return pHiBlockTable; +} + +//----------------------------------------------------------------------------- +// General EXT table functions + +TMPQExtHeader * LoadExtTable( + TMPQArchive * ha, + ULONGLONG ByteOffset, + size_t Size, + DWORD dwSignature, + DWORD dwKey) +{ + TMPQExtHeader * pCompressed = NULL; // Compressed table + TMPQExtHeader * pExtTable = NULL; // Uncompressed table + + // Do nothing if the size is zero + if(ByteOffset != 0 && Size != 0) + { + // Allocate size for the compressed table + pExtTable = (TMPQExtHeader *)STORM_ALLOC(BYTE, Size); + if(pExtTable != NULL) + { + // Load the table from the MPQ + ByteOffset += ha->MpqPos; + if(!FileStream_Read(ha->pStream, &ByteOffset, pExtTable, (DWORD)Size)) + { + STORM_FREE(pExtTable); + return NULL; + } + + // Swap the ext table header + BSWAP_ARRAY32_UNSIGNED(pExtTable, sizeof(TMPQExtHeader)); + if(pExtTable->dwSignature != dwSignature) + { + STORM_FREE(pExtTable); + return NULL; + } + + // Decrypt the block + BSWAP_ARRAY32_UNSIGNED(pExtTable + 1, pExtTable->dwDataSize); + DecryptMpqBlock(pExtTable + 1, (DWORD)(Size - sizeof(TMPQExtHeader)), dwKey); + BSWAP_ARRAY32_UNSIGNED(pExtTable + 1, pExtTable->dwDataSize); + + // If the table is compressed, decompress it + if((pExtTable->dwDataSize + sizeof(TMPQExtHeader)) > Size) + { + pCompressed = pExtTable; + pExtTable = (TMPQExtHeader *)STORM_ALLOC(BYTE, sizeof(TMPQExtHeader) + pCompressed->dwDataSize); + if(pExtTable != NULL) + { + int cbOutBuffer = (int)pCompressed->dwDataSize; + int cbInBuffer = (int)Size; + + // Decompress the extended table + pExtTable->dwSignature = pCompressed->dwSignature; + pExtTable->dwVersion = pCompressed->dwVersion; + pExtTable->dwDataSize = pCompressed->dwDataSize; + if(!SCompDecompress2(pExtTable + 1, &cbOutBuffer, pCompressed + 1, cbInBuffer)) + { + STORM_FREE(pExtTable); + pExtTable = NULL; + } + } + + // Free the compressed block + STORM_FREE(pCompressed); + } + } + } + + // Return the decompressed table to the caller + return pExtTable; +} + +static DWORD SaveMpqTable( + TMPQArchive * ha, + void * pMpqTable, + ULONGLONG ByteOffset, + size_t Size, + unsigned char * md5, + DWORD dwKey, + bool bCompress) +{ + ULONGLONG FileOffset; + void * pCompressed = NULL; + DWORD dwErrCode = ERROR_SUCCESS; + + // Do we have to compress the table? + if(bCompress) + { + int cbOutBuffer = (int)Size; + int cbInBuffer = (int)Size; + + // Allocate extra space for compressed table + pCompressed = STORM_ALLOC(BYTE, Size); + if(pCompressed == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // Compress the table + SCompCompress(pCompressed, &cbOutBuffer, pMpqTable, cbInBuffer, MPQ_COMPRESSION_ZLIB, 0, 0); + + // If the compression failed, revert it. Otherwise, swap the tables + if(cbOutBuffer >= cbInBuffer) + { + STORM_FREE(pCompressed); + pCompressed = NULL; + } + else + { + pMpqTable = pCompressed; + } + } + + // Encrypt the table + if(dwKey != 0) + { + BSWAP_ARRAY32_UNSIGNED(pMpqTable, Size); + EncryptMpqBlock(pMpqTable, (DWORD)Size, dwKey); + BSWAP_ARRAY32_UNSIGNED(pMpqTable, Size); + } + + // Calculate the MD5 + if(md5 != NULL) + { + CalculateDataBlockHash(pMpqTable, (DWORD)Size, md5); + } + + // Save the table to the MPQ + BSWAP_ARRAY32_UNSIGNED(pMpqTable, Size); + FileOffset = ha->MpqPos + ByteOffset; + if(!FileStream_Write(ha->pStream, &FileOffset, pMpqTable, (DWORD)Size)) + dwErrCode = GetLastError(); + + // Free the compressed table, if any + if(pCompressed != NULL) + STORM_FREE(pCompressed); + return dwErrCode; +} + +static DWORD SaveExtTable( + TMPQArchive * ha, + TMPQExtHeader * pExtTable, + ULONGLONG ByteOffset, + DWORD dwTableSize, + unsigned char * md5, + DWORD dwKey, + bool bCompress, + LPDWORD pcbTotalSize) +{ + ULONGLONG FileOffset; + TMPQExtHeader * pCompressed = NULL; + DWORD cbTotalSize = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Do we have to compress the table? + if(bCompress) + { + int cbOutBuffer = (int)dwTableSize; + int cbInBuffer = (int)dwTableSize; + + // Allocate extra space for compressed table + pCompressed = (TMPQExtHeader *)STORM_ALLOC(BYTE, dwTableSize); + if(pCompressed == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // Compress the table + pCompressed->dwSignature = pExtTable->dwSignature; + pCompressed->dwVersion = pExtTable->dwVersion; + pCompressed->dwDataSize = pExtTable->dwDataSize; + SCompCompress((pCompressed + 1), &cbOutBuffer, (pExtTable + 1), cbInBuffer, MPQ_COMPRESSION_ZLIB, 0, 0); + + // If the compression failed, revert it. Otherwise, swap the tables + if(cbOutBuffer >= cbInBuffer) + { + STORM_FREE(pCompressed); + pCompressed = NULL; + } + else + { + pExtTable = pCompressed; + } + } + + // Encrypt the table + if(dwKey != 0) + { + BSWAP_ARRAY32_UNSIGNED(pExtTable + 1, pExtTable->dwDataSize); + EncryptMpqBlock(pExtTable + 1, (DWORD)(dwTableSize - sizeof(TMPQExtHeader)), dwKey); + BSWAP_ARRAY32_UNSIGNED(pExtTable + 1, pExtTable->dwDataSize); + } + + // Calculate the MD5 of the table after + if(md5 != NULL) + { + CalculateDataBlockHash(pExtTable, dwTableSize, md5); + } + + // Save the table to the MPQ + FileOffset = ha->MpqPos + ByteOffset; + if(FileStream_Write(ha->pStream, &FileOffset, pExtTable, dwTableSize)) + cbTotalSize += dwTableSize; + else + dwErrCode = GetLastError(); + + // We have to write raw data MD5 + if(dwErrCode == ERROR_SUCCESS && ha->pHeader->dwRawChunkSize != 0) + { + dwErrCode = WriteMemDataMD5(ha->pStream, + FileOffset, + pExtTable, + dwTableSize, + ha->pHeader->dwRawChunkSize, + &cbTotalSize); + } + + // Give the total written size, if needed + if(pcbTotalSize != NULL) + *pcbTotalSize = cbTotalSize; + + // Free the compressed table, if any + if(pCompressed != NULL) + STORM_FREE(pCompressed); + return dwErrCode; +} + +//----------------------------------------------------------------------------- +// Support for HET table + +static void CreateHetHeader( + TMPQHetTable * pHetTable, + TMPQHetHeader * pHetHeader) +{ + // Fill the common header + pHetHeader->ExtHdr.dwSignature = HET_TABLE_SIGNATURE; + pHetHeader->ExtHdr.dwVersion = 1; + pHetHeader->ExtHdr.dwDataSize = 0; + + // Fill the HET header + pHetHeader->dwEntryCount = pHetTable->dwEntryCount; + pHetHeader->dwTotalCount = pHetTable->dwTotalCount; + pHetHeader->dwNameHashBitSize = pHetTable->dwNameHashBitSize; + pHetHeader->dwIndexSizeTotal = pHetTable->dwIndexSizeTotal; + pHetHeader->dwIndexSizeExtra = pHetTable->dwIndexSizeExtra; + pHetHeader->dwIndexSize = pHetTable->dwIndexSize; + pHetHeader->dwIndexTableSize = ((pHetHeader->dwIndexSizeTotal * pHetTable->dwTotalCount) + 7) / 8; + + // Calculate the total size needed for holding HET table + pHetHeader->ExtHdr.dwDataSize = + pHetHeader->dwTableSize = sizeof(TMPQHetHeader) - sizeof(TMPQExtHeader) + + pHetHeader->dwTotalCount + + pHetHeader->dwIndexTableSize; +} + +TMPQHetTable * CreateHetTable(DWORD dwEntryCount, DWORD dwTotalCount, DWORD dwNameHashBitSize, LPBYTE pbSrcData) +{ + TMPQHetTable * pHetTable; + + pHetTable = STORM_ALLOC(TMPQHetTable, 1); + if(pHetTable != NULL) + { + // Zero the HET table + memset(pHetTable, 0, sizeof(TMPQHetTable)); + + // Hash sizes less than 0x40 bits are not tested + assert(dwNameHashBitSize == 0x40); + + // Calculate masks + pHetTable->AndMask64 = ((dwNameHashBitSize != 0x40) ? ((ULONGLONG)1 << dwNameHashBitSize) : 0) - 1; + pHetTable->OrMask64 = (ULONGLONG)1 << (dwNameHashBitSize - 1); + + // If the total count is not entered, use default + if(dwTotalCount == 0) + dwTotalCount = (dwEntryCount * 4) / 3; + + // Store the HET table parameters + pHetTable->dwEntryCount = dwEntryCount; + pHetTable->dwTotalCount = dwTotalCount; + pHetTable->dwNameHashBitSize = dwNameHashBitSize; + pHetTable->dwIndexSizeTotal = GetNecessaryBitCount(dwEntryCount); + pHetTable->dwIndexSizeExtra = 0; + pHetTable->dwIndexSize = pHetTable->dwIndexSizeTotal; + + // Allocate array of hashes + pHetTable->pNameHashes = STORM_ALLOC(BYTE, dwTotalCount); + if(pHetTable->pNameHashes != NULL) + { + // Make sure the data are initialized + memset(pHetTable->pNameHashes, 0, dwTotalCount); + + // Allocate the bit array for file indexes + pHetTable->pBetIndexes = TMPQBits::Create(dwTotalCount * pHetTable->dwIndexSizeTotal, 0xFF); + if(pHetTable->pBetIndexes != NULL) + { + // Initialize the HET table from the source data (if given) + if(pbSrcData != NULL) + { + // Copy the name hashes + memcpy(pHetTable->pNameHashes, pbSrcData, dwTotalCount); + + // Copy the file indexes + memcpy(pHetTable->pBetIndexes->Elements, pbSrcData + dwTotalCount, pHetTable->pBetIndexes->NumberOfBytes); + } + + // Return the result HET table + return pHetTable; + } + + // Free the name hashes + STORM_FREE(pHetTable->pNameHashes); + } + + STORM_FREE(pHetTable); + } + + // Failed + return NULL; +} + +static DWORD InsertHetEntry(TMPQHetTable * pHetTable, ULONGLONG FileNameHash, DWORD dwFileIndex) +{ + DWORD StartIndex; + DWORD Index; + BYTE NameHash1; + + // Get the start index and the high 8 bits of the name hash + StartIndex = Index = (DWORD)(FileNameHash % pHetTable->dwTotalCount); + NameHash1 = (BYTE)(FileNameHash >> (pHetTable->dwNameHashBitSize - 8)); + + // Find a place where to put it + for(;;) + { + // Did we find a free HET entry? + if(pHetTable->pNameHashes[Index] == HET_ENTRY_FREE) + { + // Set the entry in the name hash table + pHetTable->pNameHashes[Index] = NameHash1; + + // Set the entry in the file index table + pHetTable->pBetIndexes->SetBits(pHetTable->dwIndexSizeTotal * Index, + pHetTable->dwIndexSize, + &dwFileIndex, + 4); + return ERROR_SUCCESS; + } + + // Move to the next entry in the HET table + // If we came to the start index again, we are done + Index = (Index + 1) % pHetTable->dwTotalCount; + if(Index == StartIndex) + break; + } + + // No space in the HET table. Should never happen, + // because the HET table is created according to the number of files + assert(false); + return ERROR_DISK_FULL; +} + +static TMPQHetTable * TranslateHetTable(TMPQHetHeader * pHetHeader) +{ + TMPQHetTable * pHetTable = NULL; + LPBYTE pbSrcData = (LPBYTE)(pHetHeader + 1); + + // Sanity check + assert(pHetHeader->ExtHdr.dwSignature == HET_TABLE_SIGNATURE); + assert(pHetHeader->ExtHdr.dwVersion == 1); + + // Verify size of the HET table + if(pHetHeader->ExtHdr.dwDataSize >= (sizeof(TMPQHetHeader) - sizeof(TMPQExtHeader))) + { + // Verify the size of the table in the header + if(pHetHeader->ExtHdr.dwDataSize >= pHetHeader->dwTableSize) + { + // The size of the HET table must be sum of header, hash and index table size + assert((sizeof(TMPQHetHeader) - sizeof(TMPQExtHeader) + pHetHeader->dwTotalCount + pHetHeader->dwIndexTableSize) == pHetHeader->dwTableSize); + + // So far, all MPQs with HET Table have had total number of entries equal to 4/3 of file count + // Exception: "2010 - Starcraft II\!maps\Tya's Zerg Defense (unprotected).SC2Map" +// assert(((pHetHeader->dwEntryCount * 4) / 3) == pHetHeader->dwTotalCount); + + // The size of one index is predictable as well + assert(GetNecessaryBitCount(pHetHeader->dwEntryCount) == pHetHeader->dwIndexSizeTotal); + + // The size of index table (in entries) is expected + // to be the same like the hash table size (in bytes) + assert(((pHetHeader->dwTotalCount * pHetHeader->dwIndexSizeTotal) + 7) / 8 == pHetHeader->dwIndexTableSize); + + // Create translated table + pHetTable = CreateHetTable(pHetHeader->dwEntryCount, pHetHeader->dwTotalCount, pHetHeader->dwNameHashBitSize, pbSrcData); + if(pHetTable != NULL) + { + // Now the sizes in the hash table should be already set + assert(pHetTable->dwEntryCount == pHetHeader->dwEntryCount); + assert(pHetTable->dwTotalCount == pHetHeader->dwTotalCount); + assert(pHetTable->dwIndexSizeTotal == pHetHeader->dwIndexSizeTotal); + + // Copy the missing variables + pHetTable->dwIndexSizeExtra = pHetHeader->dwIndexSizeExtra; + pHetTable->dwIndexSize = pHetHeader->dwIndexSize; + } + } + } + + return pHetTable; +} + +static TMPQExtHeader * TranslateHetTable(TMPQHetTable * pHetTable, ULONGLONG * pcbHetTable) +{ + TMPQHetHeader * pHetHeader = NULL; + TMPQHetHeader HetHeader; + LPBYTE pbLinearTable = NULL; + LPBYTE pbTrgData; + + // Prepare header of the HET table + CreateHetHeader(pHetTable, &HetHeader); + + // Allocate space for the linear table + pbLinearTable = STORM_ALLOC(BYTE, sizeof(TMPQExtHeader) + HetHeader.dwTableSize); + if(pbLinearTable != NULL) + { + // Copy the table header + pHetHeader = (TMPQHetHeader *)pbLinearTable; + memcpy(pHetHeader, &HetHeader, sizeof(TMPQHetHeader)); + pbTrgData = (LPBYTE)(pHetHeader + 1); + + // Copy the array of name hashes + memcpy(pbTrgData, pHetTable->pNameHashes, pHetTable->dwTotalCount); + pbTrgData += pHetTable->dwTotalCount; + + // Copy the bit array of BET indexes + memcpy(pbTrgData, pHetTable->pBetIndexes->Elements, HetHeader.dwIndexTableSize); + + // Calculate the total size of the table, including the TMPQExtHeader + if(pcbHetTable != NULL) + { + *pcbHetTable = (ULONGLONG)(sizeof(TMPQExtHeader) + HetHeader.dwTableSize); + } + } + + // Keep Coverity happy + assert((TMPQExtHeader *)&pHetHeader->ExtHdr == (TMPQExtHeader *)pbLinearTable); + return (TMPQExtHeader *)pbLinearTable; +} + +static DWORD GetFileIndex_Het(TMPQArchive * ha, const char * szFileName) +{ + TMPQHetTable * pHetTable = ha->pHetTable; + ULONGLONG FileNameHash; + DWORD StartIndex; + DWORD Index; + BYTE NameHash1; // Upper 8 bits of the masked file name hash + + // If there are no entries in the HET table, do nothing + if(pHetTable->dwEntryCount == 0) + return HASH_ENTRY_FREE; + + // Do nothing if the MPQ has no HET table + assert(ha->pHetTable != NULL); + + // Calculate 64-bit hash of the file name + FileNameHash = (HashStringJenkins(szFileName) & pHetTable->AndMask64) | pHetTable->OrMask64; + + // Split the file name hash into two parts: + // NameHash1: The highest 8 bits of the name hash + // NameHash2: File name hash limited to hash size + // Note: Our file table contains full name hash, no need to cut the high 8 bits before comparison + NameHash1 = (BYTE)(FileNameHash >> (pHetTable->dwNameHashBitSize - 8)); + + // Calculate the starting index to the hash table + StartIndex = Index = (DWORD)(FileNameHash % pHetTable->dwTotalCount); + + // Go through HET table until we find a terminator + while(pHetTable->pNameHashes[Index] != HET_ENTRY_FREE) + { + // Did we find a match ? + if(pHetTable->pNameHashes[Index] == NameHash1) + { + DWORD dwFileIndex = 0; + + // Get the file index + pHetTable->pBetIndexes->GetBits(pHetTable->dwIndexSizeTotal * Index, + pHetTable->dwIndexSize, + &dwFileIndex, + sizeof(DWORD)); + + // Verify the FileNameHash against the entry in the table of name hashes + if(dwFileIndex <= ha->dwFileTableSize && ha->pFileTable[dwFileIndex].FileNameHash == FileNameHash) + { + return dwFileIndex; + } + } + + // Move to the next entry in the HET table + // If we came to the start index again, we are done + Index = (Index + 1) % pHetTable->dwTotalCount; + if(Index == StartIndex) + break; + } + + // File not found + return HASH_ENTRY_FREE; +} + +void FreeHetTable(TMPQHetTable * pHetTable) +{ + if(pHetTable != NULL) + { + if(pHetTable->pNameHashes != NULL) + STORM_FREE(pHetTable->pNameHashes); + if(pHetTable->pBetIndexes != NULL) + STORM_FREE(pHetTable->pBetIndexes); + + STORM_FREE(pHetTable); + } +} + +//----------------------------------------------------------------------------- +// Support for BET table + +static void CreateBetHeader( + TMPQArchive * ha, + TMPQBetHeader * pBetHeader) +{ + TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; + TFileEntry * pFileEntry; + ULONGLONG MaxByteOffset = 0; + DWORD FlagArray[MAX_FLAG_INDEX]; + DWORD dwMaxFlagIndex = 0; + DWORD dwMaxFileSize = 0; + DWORD dwMaxCmpSize = 0; + DWORD dwFlagIndex; + + // Initialize array of flag combinations + InitFileFlagArray(FlagArray); + + // Fill the common header + pBetHeader->ExtHdr.dwSignature = BET_TABLE_SIGNATURE; + pBetHeader->ExtHdr.dwVersion = 1; + pBetHeader->ExtHdr.dwDataSize = 0; + + // Get the maximum values for the BET table + pFileTableEnd = ha->pFileTable + ha->pHeader->dwBlockTableSize; + for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) + { + // + // Note: Deleted files must be counted as well + // + + // Highest file position in the MPQ + if(pFileEntry->ByteOffset > MaxByteOffset) + MaxByteOffset = pFileEntry->ByteOffset; + + // Biggest file size + if(pFileEntry->dwFileSize > dwMaxFileSize) + dwMaxFileSize = pFileEntry->dwFileSize; + + // Biggest compressed size + if(pFileEntry->dwCmpSize > dwMaxCmpSize) + dwMaxCmpSize = pFileEntry->dwCmpSize; + + // Check if this flag was there before + dwFlagIndex = GetFileFlagIndex(FlagArray, pFileEntry->dwFlags); + if(dwFlagIndex > dwMaxFlagIndex) + dwMaxFlagIndex = dwFlagIndex; + } + + // Now save bit count for every piece of file information + pBetHeader->dwBitIndex_FilePos = 0; + pBetHeader->dwBitCount_FilePos = GetNecessaryBitCount(MaxByteOffset); + + pBetHeader->dwBitIndex_FileSize = pBetHeader->dwBitIndex_FilePos + pBetHeader->dwBitCount_FilePos; + pBetHeader->dwBitCount_FileSize = GetNecessaryBitCount(dwMaxFileSize); + + pBetHeader->dwBitIndex_CmpSize = pBetHeader->dwBitIndex_FileSize + pBetHeader->dwBitCount_FileSize; + pBetHeader->dwBitCount_CmpSize = GetNecessaryBitCount(dwMaxCmpSize); + + pBetHeader->dwBitIndex_FlagIndex = pBetHeader->dwBitIndex_CmpSize + pBetHeader->dwBitCount_CmpSize; + pBetHeader->dwBitCount_FlagIndex = GetNecessaryBitCount(dwMaxFlagIndex + 1); + + pBetHeader->dwBitIndex_Unknown = pBetHeader->dwBitIndex_FlagIndex + pBetHeader->dwBitCount_FlagIndex; + pBetHeader->dwBitCount_Unknown = 0; + + // Calculate the total size of one entry + pBetHeader->dwTableEntrySize = pBetHeader->dwBitCount_FilePos + + pBetHeader->dwBitCount_FileSize + + pBetHeader->dwBitCount_CmpSize + + pBetHeader->dwBitCount_FlagIndex + + pBetHeader->dwBitCount_Unknown; + + // Save the file count and flag count + pBetHeader->dwEntryCount = ha->pHeader->dwBlockTableSize; + pBetHeader->dwFlagCount = dwMaxFlagIndex + 1; + pBetHeader->dwUnknown08 = 0x10; + + // Save the total size of the BET hash + pBetHeader->dwBitTotal_NameHash2 = ha->pHetTable->dwNameHashBitSize - 0x08; + pBetHeader->dwBitExtra_NameHash2 = 0; + pBetHeader->dwBitCount_NameHash2 = pBetHeader->dwBitTotal_NameHash2; + pBetHeader->dwNameHashArraySize = ((pBetHeader->dwBitTotal_NameHash2 * pBetHeader->dwEntryCount) + 7) / 8; + + // Save the total table size + pBetHeader->ExtHdr.dwDataSize = + pBetHeader->dwTableSize = sizeof(TMPQBetHeader) - sizeof(TMPQExtHeader) + + pBetHeader->dwFlagCount * sizeof(DWORD) + + ((pBetHeader->dwTableEntrySize * pBetHeader->dwEntryCount) + 7) / 8 + + pBetHeader->dwNameHashArraySize; +} + +TMPQBetTable * CreateBetTable(DWORD dwEntryCount) +{ + TMPQBetTable * pBetTable; + + // Allocate BET table + pBetTable = STORM_ALLOC(TMPQBetTable, 1); + if(pBetTable != NULL) + { + memset(pBetTable, 0, sizeof(TMPQBetTable)); + pBetTable->dwEntryCount = dwEntryCount; + } + + return pBetTable; +} + +static TMPQBetTable * TranslateBetTable( + TMPQArchive * ha, + TMPQBetHeader * pBetHeader) +{ + TMPQBetTable * pBetTable = NULL; + LPBYTE pbSrcData = (LPBYTE)(pBetHeader + 1); + DWORD LengthInBytes = 0; + + // Sanity check + assert(pBetHeader->ExtHdr.dwSignature == BET_TABLE_SIGNATURE); + assert(pBetHeader->ExtHdr.dwVersion == 1); + assert(ha->pHetTable != NULL); + ha = ha; + + // Verify size of the HET table + if(pBetHeader->ExtHdr.dwDataSize >= (sizeof(TMPQBetHeader) - sizeof(TMPQExtHeader))) + { + // Verify the size of the table in the header + if(pBetHeader->ExtHdr.dwDataSize >= pBetHeader->dwTableSize) + { + // The number of entries in the BET table must be the same like number of entries in the block table + // Note: Ignored if there is no block table + //assert(pBetHeader->dwEntryCount == ha->pHeader->dwBlockTableSize); + assert(pBetHeader->dwEntryCount <= ha->dwMaxFileCount); + + // The number of entries in the BET table must be the same like number of entries in the HET table + // Note that if it's not, it is not a problem + //assert(pBetHeader->dwEntryCount == ha->pHetTable->dwEntryCount); + + // Create translated table + pBetTable = CreateBetTable(pBetHeader->dwEntryCount); + if(pBetTable != NULL) + { + // Copy the variables from the header to the BetTable + pBetTable->dwTableEntrySize = pBetHeader->dwTableEntrySize; + pBetTable->dwBitIndex_FilePos = pBetHeader->dwBitIndex_FilePos; + pBetTable->dwBitIndex_FileSize = pBetHeader->dwBitIndex_FileSize; + pBetTable->dwBitIndex_CmpSize = pBetHeader->dwBitIndex_CmpSize; + pBetTable->dwBitIndex_FlagIndex = pBetHeader->dwBitIndex_FlagIndex; + pBetTable->dwBitIndex_Unknown = pBetHeader->dwBitIndex_Unknown; + pBetTable->dwBitCount_FilePos = pBetHeader->dwBitCount_FilePos; + pBetTable->dwBitCount_FileSize = pBetHeader->dwBitCount_FileSize; + pBetTable->dwBitCount_CmpSize = pBetHeader->dwBitCount_CmpSize; + pBetTable->dwBitCount_FlagIndex = pBetHeader->dwBitCount_FlagIndex; + pBetTable->dwBitCount_Unknown = pBetHeader->dwBitCount_Unknown; + + // Since we don't know what the "unknown" is, we'll assert when it's zero + assert(pBetTable->dwBitCount_Unknown == 0); + + // Allocate array for flags + if(pBetHeader->dwFlagCount != 0) + { + // Allocate array for file flags and load it + pBetTable->pFileFlags = STORM_ALLOC(DWORD, pBetHeader->dwFlagCount); + if(pBetTable->pFileFlags != NULL) + { + LengthInBytes = pBetHeader->dwFlagCount * sizeof(DWORD); + memcpy(pBetTable->pFileFlags, pbSrcData, LengthInBytes); + BSWAP_ARRAY32_UNSIGNED(pBetTable->pFileFlags, LengthInBytes); + pbSrcData += LengthInBytes; + } + + // Save the number of flags + pBetTable->dwFlagCount = pBetHeader->dwFlagCount; + } + + // Load the bit-based file table + pBetTable->pFileTable = TMPQBits::Create(pBetTable->dwTableEntrySize * pBetHeader->dwEntryCount, 0); + if(pBetTable->pFileTable != NULL) + { + LengthInBytes = (pBetTable->pFileTable->NumberOfBits + 7) / 8; + memcpy(pBetTable->pFileTable->Elements, pbSrcData, LengthInBytes); + pbSrcData += LengthInBytes; + } + + // Fill the sizes of BET hash + pBetTable->dwBitTotal_NameHash2 = pBetHeader->dwBitTotal_NameHash2; + pBetTable->dwBitExtra_NameHash2 = pBetHeader->dwBitExtra_NameHash2; + pBetTable->dwBitCount_NameHash2 = pBetHeader->dwBitCount_NameHash2; + + // Create and load the array of BET hashes + pBetTable->pNameHashes = TMPQBits::Create(pBetTable->dwBitTotal_NameHash2 * pBetHeader->dwEntryCount, 0); + if(pBetTable->pNameHashes != NULL) + { + LengthInBytes = (pBetTable->pNameHashes->NumberOfBits + 7) / 8; + memcpy(pBetTable->pNameHashes->Elements, pbSrcData, LengthInBytes); +// pbSrcData += LengthInBytes; + } + + // Dump both tables +// DumpHetAndBetTable(ha->pHetTable, pBetTable); + } + } + } + + return pBetTable; +} + +TMPQExtHeader * TranslateBetTable( + TMPQArchive * ha, + ULONGLONG * pcbBetTable) +{ + TMPQBetHeader * pBetHeader = NULL; + TMPQBetHeader BetHeader; + TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; + TFileEntry * pFileEntry; + TMPQBits * pBitArray = NULL; + LPBYTE pbLinearTable = NULL; + LPBYTE pbTrgData; + DWORD LengthInBytes; + DWORD FlagArray[MAX_FLAG_INDEX]; + + // Calculate the bit sizes of various entries + InitFileFlagArray(FlagArray); + CreateBetHeader(ha, &BetHeader); + + // Allocate space + pbLinearTable = STORM_ALLOC(BYTE, sizeof(TMPQExtHeader) + BetHeader.dwTableSize); + if(pbLinearTable != NULL) + { + // Copy the BET header to the linear buffer + pBetHeader = (TMPQBetHeader *)pbLinearTable; + memcpy(pBetHeader, &BetHeader, sizeof(TMPQBetHeader)); + pbTrgData = (LPBYTE)(pBetHeader + 1); + + // Save the bit-based block table + pBitArray = TMPQBits::Create(BetHeader.dwEntryCount * BetHeader.dwTableEntrySize, 0); + if(pBitArray != NULL) + { + DWORD dwFlagIndex = 0; + DWORD nBitOffset = 0; + + // Construct the bit-based file table + pFileTableEnd = ha->pFileTable + BetHeader.dwEntryCount; + for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) + { + // + // Note: Missing files must be included as well + // + + // Save the byte offset + pBitArray->SetBits(nBitOffset + BetHeader.dwBitIndex_FilePos, + BetHeader.dwBitCount_FilePos, + &pFileEntry->ByteOffset, + 8); + pBitArray->SetBits(nBitOffset + BetHeader.dwBitIndex_FileSize, + BetHeader.dwBitCount_FileSize, + &pFileEntry->dwFileSize, + 4); + pBitArray->SetBits(nBitOffset + BetHeader.dwBitIndex_CmpSize, + BetHeader.dwBitCount_CmpSize, + &pFileEntry->dwCmpSize, + 4); + + // Save the flag index + dwFlagIndex = GetFileFlagIndex(FlagArray, pFileEntry->dwFlags); + pBitArray->SetBits(nBitOffset + BetHeader.dwBitIndex_FlagIndex, + BetHeader.dwBitCount_FlagIndex, + &dwFlagIndex, + 4); + + // Move the bit offset + nBitOffset += BetHeader.dwTableEntrySize; + } + + // Write the array of flags + LengthInBytes = BetHeader.dwFlagCount * sizeof(DWORD); + memcpy(pbTrgData, FlagArray, LengthInBytes); + BSWAP_ARRAY32_UNSIGNED(pbTrgData, LengthInBytes); + pbTrgData += LengthInBytes; + + // Write the bit-based block table + LengthInBytes = (pBitArray->NumberOfBits + 7) / 8; + memcpy(pbTrgData, pBitArray->Elements, LengthInBytes); + pbTrgData += LengthInBytes; + + // Free the bit array + STORM_FREE(pBitArray); + } + + // Create bit array for name hashes + pBitArray = TMPQBits::Create(BetHeader.dwBitTotal_NameHash2 * BetHeader.dwEntryCount, 0); + if(pBitArray != NULL) + { + DWORD dwFileIndex = 0; + + for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) + { + // Insert the name hash to the bit array + pBitArray->SetBits(BetHeader.dwBitTotal_NameHash2 * dwFileIndex, + BetHeader.dwBitCount_NameHash2, + &pFileEntry->FileNameHash, + 8); + + assert(dwFileIndex < BetHeader.dwEntryCount); + dwFileIndex++; + } + + // Write the array of BET hashes + LengthInBytes = (pBitArray->NumberOfBits + 7) / 8; + memcpy(pbTrgData, pBitArray->Elements, LengthInBytes); +// pbTrgData += LengthInBytes; + + // Free the bit array + STORM_FREE(pBitArray); + } + + // Write the size of the BET table in the MPQ + if(pcbBetTable != NULL) + { + *pcbBetTable = (ULONGLONG)(sizeof(TMPQExtHeader) + BetHeader.dwTableSize); + } + } + + // Keep Coverity happy + assert((TMPQExtHeader *)&pBetHeader->ExtHdr == (TMPQExtHeader *)pbLinearTable); + return (TMPQExtHeader *)pbLinearTable; +} + +void FreeBetTable(TMPQBetTable * pBetTable) +{ + if(pBetTable != NULL) + { + if(pBetTable->pFileTable != NULL) + STORM_FREE(pBetTable->pFileTable); + if(pBetTable->pFileFlags != NULL) + STORM_FREE(pBetTable->pFileFlags); + if(pBetTable->pNameHashes != NULL) + STORM_FREE(pBetTable->pNameHashes); + + STORM_FREE(pBetTable); + } +} + +//----------------------------------------------------------------------------- +// Support for file table + +TFileEntry * GetFileEntryLocale2(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex) +{ + TMPQHash * pHash; + DWORD dwFileIndex; + + // First, we have to search the classic hash table + // This is because on renaming, deleting, or changing locale, + // we will need the pointer to hash table entry + if(ha->pHashTable != NULL) + { + pHash = GetHashEntryLocale(ha, szFileName, lcLocale, 0); + if(pHash != NULL && MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize) + { + if(PtrHashIndex != NULL) + PtrHashIndex[0] = (DWORD)(pHash - ha->pHashTable); + return ha->pFileTable + MPQ_BLOCK_INDEX(pHash); + } + } + + // If we have HET table in the MPQ, try to find the file in HET table + if(ha->pHetTable != NULL) + { + dwFileIndex = GetFileIndex_Het(ha, szFileName); + if(dwFileIndex != HASH_ENTRY_FREE) + return ha->pFileTable + dwFileIndex; + } + + // Not found + return NULL; +} + +TFileEntry * GetFileEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale) +{ + return GetFileEntryLocale2(ha, szFileName, lcLocale, NULL); +} + +TFileEntry * GetFileEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex) +{ + TMPQHash * pHash; + DWORD dwFileIndex; + + // If the hash table is present, find the entry from hash table + if(ha->pHashTable != NULL) + { + pHash = GetHashEntryExact(ha, szFileName, lcLocale); + if(pHash != NULL && MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize) + { + if(PtrHashIndex != NULL) + PtrHashIndex[0] = (DWORD)(pHash - ha->pHashTable); + return ha->pFileTable + MPQ_BLOCK_INDEX(pHash); + } + } + + // If we have HET table in the MPQ, try to find the file in HET table + if(ha->pHetTable != NULL) + { + dwFileIndex = GetFileIndex_Het(ha, szFileName); + if(dwFileIndex != HASH_ENTRY_FREE) + { + if(PtrHashIndex != NULL) + PtrHashIndex[0] = HASH_ENTRY_FREE; + return ha->pFileTable + dwFileIndex; + } + } + + // Not found + return NULL; +} + +void AllocateFileName(TMPQArchive * ha, TFileEntry * pFileEntry, const char * szFileName) +{ + // Sanity check + assert(pFileEntry != NULL); + + // If the file name is pseudo file name, free it at this point + if(IsPseudoFileName(pFileEntry->szFileName, NULL)) + { + if(pFileEntry->szFileName != NULL) + STORM_FREE(pFileEntry->szFileName); + pFileEntry->szFileName = NULL; + } + + // Only allocate new file name if it's not there yet + if(pFileEntry->szFileName == NULL) + { + pFileEntry->szFileName = STORM_ALLOC(char, strlen(szFileName) + 1); + if(pFileEntry->szFileName != NULL) + strcpy(pFileEntry->szFileName, szFileName); + } + + // We also need to create the file name hash + if(ha->pHetTable != NULL) + { + ULONGLONG AndMask64 = ha->pHetTable->AndMask64; + ULONGLONG OrMask64 = ha->pHetTable->OrMask64; + + pFileEntry->FileNameHash = (HashStringJenkins(szFileName) & AndMask64) | OrMask64; + } +} + +TFileEntry * AllocateFileEntry(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex) +{ + TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; + TFileEntry * pFreeEntry = NULL; + TFileEntry * pFileEntry; + TMPQHash * pHash = NULL; + DWORD dwReservedFiles = ha->dwReservedFiles; + DWORD dwFreeCount = 0; + + // Sanity check: File table size must be greater or equal to max file count + assert(ha->dwFileTableSize >= ha->dwMaxFileCount); + + // If we are saving MPQ tables, we don't tale number of reserved files into account + dwReservedFiles = (ha->dwFlags & MPQ_FLAG_SAVING_TABLES) ? 0 : ha->dwReservedFiles; + + // Now find a free entry in the file table. + // Note that in the case when free entries are in the middle, + // we need to use these + for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) + { + if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0) + { + // Remember the first free entry + if(pFreeEntry == NULL) + pFreeEntry = pFileEntry; + dwFreeCount++; + + // If the number of free items is greater than number + // of reserved items, We can add the file + if(dwFreeCount > dwReservedFiles) + break; + } + } + + // If the total number of free entries is less than number of reserved files, + // we cannot add the file to the archive + if(pFreeEntry == NULL || dwFreeCount <= dwReservedFiles) + return NULL; + + // Initialize the file entry and set its file name + memset(pFreeEntry, 0, sizeof(TFileEntry)); + AllocateFileName(ha, pFreeEntry, szFileName); + + // If the archive has a hash table, we need to first free entry there + if(ha->pHashTable != NULL) + { + // Make sure that the entry is not there yet + assert(GetHashEntryExact(ha, szFileName, lcLocale) == NULL); + + // Find a free hash table entry for the name + pHash = AllocateHashEntry(ha, pFreeEntry, lcLocale); + if(pHash == NULL) + return NULL; + + // Set the file index to the hash table + pHash->dwBlockIndex = (DWORD)(pFreeEntry - ha->pFileTable); + PtrHashIndex[0] = (DWORD)(pHash - ha->pHashTable); + } + + // If the archive has a HET table, just do some checks + // Note: Don't bother modifying the HET table. It will be rebuilt from scratch after, anyway + if(ha->pHetTable != NULL) + { + assert(GetFileIndex_Het(ha, szFileName) == HASH_ENTRY_FREE); + } + + // Return the free table entry + return pFreeEntry; +} + +DWORD RenameFileEntry( + TMPQArchive * ha, + TMPQFile * hf, + const char * szNewFileName) +{ + TFileEntry * pFileEntry = hf->pFileEntry; + TMPQHash * pHashEntry = hf->pHashEntry; + LCID lcLocale = 0; + + // If the archive hash hash table, we need to free the hash table entry + if(ha->pHashTable != NULL) + { + // The file must have hash table entry assigned + // Will exit if there are multiple HASH entries pointing to the same file entry + if(pHashEntry == NULL) + return ERROR_NOT_SUPPORTED; + + // Save the locale + lcLocale = pHashEntry->lcLocale; + + // Mark the hash table entry as deleted + pHashEntry->dwName1 = 0xFFFFFFFF; + pHashEntry->dwName2 = 0xFFFFFFFF; + pHashEntry->lcLocale = 0xFFFF; + pHashEntry->Platform = 0xFF; + pHashEntry->Reserved = 0xFF; + pHashEntry->dwBlockIndex = HASH_ENTRY_DELETED; + } + + // Free the old file name + if(pFileEntry->szFileName != NULL) + STORM_FREE(pFileEntry->szFileName); + pFileEntry->szFileName = NULL; + + // Allocate new file name + AllocateFileName(ha, pFileEntry, szNewFileName); + + // Allocate new hash entry + if(ha->pHashTable != NULL) + { + // Since we freed one hash entry before, this must succeed + hf->pHashEntry = AllocateHashEntry(ha, pFileEntry, lcLocale); + assert(hf->pHashEntry != NULL); + } + + return ERROR_SUCCESS; +} + +DWORD DeleteFileEntry(TMPQArchive * ha, TMPQFile * hf) +{ + TFileEntry * pFileEntry = hf->pFileEntry; + TMPQHash * pHashEntry = hf->pHashEntry; + + // If the archive hash hash table, we need to free the hash table entry + if(ha->pHashTable != NULL) + { + // The file must have hash table entry assigned + // Will exit if there are multiple HASH entries pointing to the same file entry + if(pHashEntry == NULL) + return ERROR_NOT_SUPPORTED; + + // Mark the hash table entry as deleted + pHashEntry->dwName1 = 0xFFFFFFFF; + pHashEntry->dwName2 = 0xFFFFFFFF; + pHashEntry->lcLocale = 0xFFFF; + pHashEntry->Platform = 0xFF; + pHashEntry->Reserved = 0xFF; + pHashEntry->dwBlockIndex = HASH_ENTRY_DELETED; + } + + // Free the file name, and set the file entry as deleted + if(pFileEntry->szFileName != NULL) + STORM_FREE(pFileEntry->szFileName); + pFileEntry->szFileName = NULL; + + // + // Don't modify the HET table, because it gets recreated by the caller + // Don't decrement the number of entries in the file table + // Keep Byte Offset, file size, compressed size, CRC32 and MD5 + // Clear the file name hash and the MPQ_FILE_EXISTS bit + // + + pFileEntry->dwFlags &= ~MPQ_FILE_EXISTS; + pFileEntry->FileNameHash = 0; + return ERROR_SUCCESS; +} + +DWORD InvalidateInternalFile(TMPQArchive * ha, const char * szFileName, DWORD dwFlagNone, DWORD dwFlagNew, DWORD dwForceAddTheFile = 0) +{ + TMPQFile * hf = NULL; + DWORD dwFileFlags = MPQ_FILE_DEFAULT_INTERNAL; + DWORD dwErrCode = ERROR_FILE_NOT_FOUND; + + // Open the file from the MPQ + if(SFileOpenFileEx((HANDLE)ha, szFileName, SFILE_OPEN_BASE_FILE, (HANDLE *)&hf)) + { + // Remember the file flags + dwFileFlags = hf->pFileEntry->dwFlags; + + // Delete the file entry + dwErrCode = DeleteFileEntry(ha, hf); + if(dwErrCode == ERROR_SUCCESS) + dwForceAddTheFile = 1; + + // Close the file + FreeFileHandle(hf); + } + + // Are we going to add the file? + if(dwForceAddTheFile) + { + ha->dwFlags |= dwFlagNew; + ha->dwReservedFiles++; + } + else + { + ha->dwFlags |= dwFlagNone; + dwFileFlags = 0; + } + + // Return the intended file flags + return dwFileFlags; +} + +void InvalidateInternalFiles(TMPQArchive * ha) +{ + // Do nothing if we are in the middle of saving internal files + if(!(ha->dwFlags & MPQ_FLAG_SAVING_TABLES)) + { + // + // We clear the file entries for (listfile), (attributes) and (signature) + // For each internal file cleared, we increment the number + // of reserved entries in the file table. + // + + // Invalidate the (listfile), if not done yet + if((ha->dwFlags & (MPQ_FLAG_LISTFILE_NONE | MPQ_FLAG_LISTFILE_NEW)) == 0) + { + ha->dwFileFlags1 = InvalidateInternalFile(ha, LISTFILE_NAME, MPQ_FLAG_LISTFILE_NONE, MPQ_FLAG_LISTFILE_NEW, (ha->dwFlags & MPQ_FLAG_LISTFILE_FORCE)); + } + + // Invalidate the (attributes), if not done yet + if((ha->dwFlags & (MPQ_FLAG_ATTRIBUTES_NONE | MPQ_FLAG_ATTRIBUTES_NEW)) == 0) + { + ha->dwFileFlags2 = InvalidateInternalFile(ha, ATTRIBUTES_NAME, MPQ_FLAG_ATTRIBUTES_NONE, MPQ_FLAG_ATTRIBUTES_NEW); + } + + // Invalidate the (signature), if not done yet + if((ha->dwFlags & (MPQ_FLAG_SIGNATURE_NONE | MPQ_FLAG_SIGNATURE_NEW)) == 0) + { + ha->dwFileFlags3 = InvalidateInternalFile(ha, SIGNATURE_NAME, MPQ_FLAG_SIGNATURE_NONE, MPQ_FLAG_SIGNATURE_NEW); + } + + // Remember that the MPQ has been changed + ha->dwFlags |= MPQ_FLAG_CHANGED; + } +} + +//----------------------------------------------------------------------------- +// Support for file tables - hash table, block table, hi-block table + +DWORD CreateHashTable(TMPQArchive * ha, DWORD dwHashTableSize) +{ + TMPQHash * pHashTable; + + // Sanity checks + assert((dwHashTableSize & (dwHashTableSize - 1)) == 0); + assert(ha->pHashTable == NULL); + + // If the required hash table size is zero, don't create anything + if(dwHashTableSize == 0) + dwHashTableSize = HASH_TABLE_SIZE_DEFAULT; + + // Create the hash table + pHashTable = STORM_ALLOC(TMPQHash, dwHashTableSize); + if(pHashTable == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // Fill it + memset(pHashTable, 0xFF, dwHashTableSize * sizeof(TMPQHash)); + ha->pHeader->dwHashTableSize = dwHashTableSize; + ha->dwMaxFileCount = dwHashTableSize; + ha->pHashTable = pHashTable; + return ERROR_SUCCESS; +} + +static TMPQHash * LoadHashTable(TMPQArchive * ha) +{ + TMPQHeader * pHeader = ha->pHeader; + ULONGLONG ByteOffset; + TMPQHash * pHashTable = NULL; + DWORD dwTableSize; + DWORD dwCmpSize; + bool bHashTableIsCut = false; + + // Note: It is allowed to load hash table if it is at offset 0. + // Example: MPQ_2016_v1_ProtectedMap_HashOffsIsZero.w3x +// if(pHeader->dwHashTablePos == 0 && pHeader->wHashTablePosHi == 0) +// return NULL; + + // If the hash table size is zero, do nothing + if(pHeader->dwHashTableSize == 0) + return NULL; + + // Load the hash table for MPQ variations + switch(ha->dwSubType) + { + case MPQ_SUBTYPE_MPQ: + + // Calculate the position and size of the hash table + ByteOffset = FileOffsetFromMpqOffset(ha, MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos)); + dwTableSize = pHeader->dwHashTableSize * sizeof(TMPQHash); + dwCmpSize = (DWORD)pHeader->HashTableSize64; + + // Read, decrypt and uncompress the hash table + pHashTable = (TMPQHash *)LoadMpqTable(ha, ByteOffset, pHeader->MD5_HashTable, dwCmpSize, dwTableSize, g_dwHashTableKey, &bHashTableIsCut); +// DumpHashTable(pHashTable, pHeader->dwHashTableSize); + + // If the hash table was cut, we can/have to defragment it + if(pHashTable != NULL && bHashTableIsCut) + ha->dwFlags |= (MPQ_FLAG_MALFORMED | MPQ_FLAG_HASH_TABLE_CUT); + break; + + case MPQ_SUBTYPE_SQP: + pHashTable = LoadSqpHashTable(ha); + break; + + case MPQ_SUBTYPE_MPK: + pHashTable = LoadMpkHashTable(ha); + break; + } + + // Return the loaded hash table + return pHashTable; +} + +DWORD CreateFileTable(TMPQArchive * ha, DWORD dwFileTableSize) +{ + ha->pFileTable = STORM_ALLOC(TFileEntry, dwFileTableSize); + if(ha->pFileTable == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + memset(ha->pFileTable, 0x00, sizeof(TFileEntry) * dwFileTableSize); + ha->dwFileTableSize = dwFileTableSize; + return ERROR_SUCCESS; +} + +TMPQBlock * LoadBlockTable(TMPQArchive * ha, bool /* bDontFixEntries */) +{ + TMPQHeader * pHeader = ha->pHeader; + TMPQBlock * pBlockTable = NULL; + ULONGLONG ByteOffset; + DWORD dwTableSize; + DWORD dwCmpSize; + bool bBlockTableIsCut = false; + + // Note: It is possible that the block table starts at offset 0 + // Example: MPQ_2016_v1_ProtectedMap_HashOffsIsZero.w3x +// if(pHeader->dwBlockTablePos == 0 && pHeader->wBlockTablePosHi == 0) +// return NULL; + + // Do nothing if the block table size is zero + if(pHeader->dwBlockTableSize == 0) + return NULL; + + // Load the block table for MPQ variations + switch(ha->dwSubType) + { + case MPQ_SUBTYPE_MPQ: + + // Calculate byte position of the block table + ByteOffset = FileOffsetFromMpqOffset(ha, MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos)); + dwTableSize = pHeader->dwBlockTableSize * sizeof(TMPQBlock); + dwCmpSize = (DWORD)pHeader->BlockTableSize64; + + // Read, decrypt and uncompress the block table + pBlockTable = (TMPQBlock * )LoadMpqTable(ha, ByteOffset, NULL, dwCmpSize, dwTableSize, g_dwBlockTableKey, &bBlockTableIsCut); + + // If the block table was cut, we need to remember it + if(pBlockTable != NULL && bBlockTableIsCut) + ha->dwFlags |= (MPQ_FLAG_MALFORMED | MPQ_FLAG_BLOCK_TABLE_CUT); + break; + + case MPQ_SUBTYPE_SQP: + + pBlockTable = LoadSqpBlockTable(ha); + break; + + case MPQ_SUBTYPE_MPK: + + pBlockTable = LoadMpkBlockTable(ha); + break; + } + + return pBlockTable; +} + +TMPQHetTable * LoadHetTable(TMPQArchive * ha) +{ + TMPQExtHeader * pExtTable; + TMPQHetTable * pHetTable = NULL; + TMPQHeader * pHeader = ha->pHeader; + + // If the HET table position is not 0, we expect the table to be present + if(pHeader->HetTablePos64 && pHeader->HetTableSize64) + { + // Attempt to load the HET table (Hash Extended Table) + pExtTable = LoadExtTable(ha, pHeader->HetTablePos64, (size_t)pHeader->HetTableSize64, HET_TABLE_SIGNATURE, MPQ_KEY_HASH_TABLE); + if(pExtTable != NULL) + { + // If loading HET table fails, we ignore the result. + pHetTable = TranslateHetTable((TMPQHetHeader *)pExtTable); + STORM_FREE(pExtTable); + } + } + + return pHetTable; +} + +TMPQBetTable * LoadBetTable(TMPQArchive * ha) +{ + TMPQExtHeader * pExtTable; + TMPQBetTable * pBetTable = NULL; + TMPQHeader * pHeader = ha->pHeader; + + // If the BET table position is not 0, we expect the table to be present + if(pHeader->BetTablePos64 && pHeader->BetTableSize64) + { + // Attempt to load the HET table (Hash Extended Table) + pExtTable = LoadExtTable(ha, pHeader->BetTablePos64, (size_t)pHeader->BetTableSize64, BET_TABLE_SIGNATURE, MPQ_KEY_BLOCK_TABLE); + if(pExtTable != NULL) + { + // If succeeded, we translate the BET table + // to more readable form + pBetTable = TranslateBetTable(ha, (TMPQBetHeader *)pExtTable); + STORM_FREE(pExtTable); + } + } + + return pBetTable; +} + +DWORD LoadAnyHashTable(TMPQArchive * ha) +{ + TMPQHeader * pHeader = ha->pHeader; + + // If the MPQ archive is empty, don't bother trying to load anything + if(pHeader->dwHashTableSize == 0 && pHeader->HetTableSize64 == 0) + return CreateHashTable(ha, HASH_TABLE_SIZE_DEFAULT); + + // Try to load HET table + if(pHeader->HetTablePos64 != 0) + ha->pHetTable = LoadHetTable(ha); + + // Try to load classic hash table + // Note that we load the classic hash table even when HET table exists, + // because if the MPQ gets modified and saved, hash table must be there + if(pHeader->dwHashTableSize) + ha->pHashTable = LoadHashTable(ha); + + // At least one of the tables must be present + if(ha->pHetTable == NULL && ha->pHashTable == NULL) + return ERROR_FILE_CORRUPT; + + // Set the maximum file count to the size of the hash table. + // Note: We don't care about HET table limits, because HET table is rebuilt + // after each file add/rename/delete. + ha->dwMaxFileCount = (ha->pHashTable != NULL) ? pHeader->dwHashTableSize : HASH_TABLE_SIZE_MAX; + return ERROR_SUCCESS; +} + +static DWORD BuildFileTable_Classic(TMPQArchive * ha) +{ + TMPQHeader * pHeader = ha->pHeader; + TMPQBlock * pBlockTable; + DWORD dwErrCode = ERROR_SUCCESS; + + // Sanity checks + assert(ha->pHashTable != NULL); + assert(ha->pFileTable != NULL); + + // If the MPQ has no block table, do nothing + if(pHeader->dwBlockTableSize == 0) + return ERROR_SUCCESS; + assert(ha->dwFileTableSize >= pHeader->dwBlockTableSize); + + // Load the block table + // WARNING! ha->pFileTable can change in the process!! + pBlockTable = (TMPQBlock *)LoadBlockTable(ha); + if(pBlockTable != NULL) + { + dwErrCode = BuildFileTableFromBlockTable(ha, pBlockTable); + STORM_FREE(pBlockTable); + } + else + { + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + + // Load the hi-block table + if(dwErrCode == ERROR_SUCCESS && pHeader->HiBlockTablePos64 != 0) + { + ULONGLONG ByteOffset; + USHORT * pHiBlockTable = NULL; + DWORD dwTableSize = pHeader->dwBlockTableSize * sizeof(USHORT); + + // Allocate space for the hi-block table + // Note: pHeader->dwBlockTableSize can be zero !!! + pHiBlockTable = STORM_ALLOC(USHORT, pHeader->dwBlockTableSize + 1); + if(pHiBlockTable != NULL) + { + // Load the hi-block table. It is not encrypted, nor compressed + ByteOffset = ha->MpqPos + pHeader->HiBlockTablePos64; + if(!FileStream_Read(ha->pStream, &ByteOffset, pHiBlockTable, dwTableSize)) + dwErrCode = GetLastError(); + + // Now merge the hi-block table to the file table + if(dwErrCode == ERROR_SUCCESS) + { + TFileEntry * pFileEntry = ha->pFileTable; + + // Swap the hi-block table + BSWAP_ARRAY16_UNSIGNED(pHiBlockTable, dwTableSize); + + // Add the high file offset to the base file offset. + for(DWORD i = 0; i < pHeader->dwBlockTableSize; i++, pFileEntry++) + pFileEntry->ByteOffset = MAKE_OFFSET64(pHiBlockTable[i], pFileEntry->ByteOffset); + } + + // Free the hi-block table + STORM_FREE(pHiBlockTable); + } + else + { + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + } + + return dwErrCode; +} + +static DWORD BuildFileTable_HetBet(TMPQArchive * ha) +{ + TMPQHetTable * pHetTable = ha->pHetTable; + TMPQBetTable * pBetTable; + TFileEntry * pFileEntry = ha->pFileTable; + TMPQBits * pBitArray; + DWORD dwBitPosition = 0; + DWORD i; + DWORD dwErrCode = ERROR_FILE_CORRUPT; + + // Load the BET table from the MPQ + pBetTable = LoadBetTable(ha); + if(pBetTable != NULL) + { + // Verify the size of NameHash2 in the BET table. + // It has to be 8 bits less than the information in HET table + if((pBetTable->dwBitCount_NameHash2 + 8) != pHetTable->dwNameHashBitSize) + { + FreeBetTable(pBetTable); + return ERROR_FILE_CORRUPT; + } + + // Step one: Fill the name indexes + for(i = 0; i < pHetTable->dwTotalCount; i++) + { + DWORD dwFileIndex = 0; + + // Is the entry in the HET table occupied? + if(pHetTable->pNameHashes[i] != HET_ENTRY_FREE) + { + // Load the index to the BET table + pHetTable->pBetIndexes->GetBits(pHetTable->dwIndexSizeTotal * i, + pHetTable->dwIndexSize, + &dwFileIndex, + 4); + // Overflow test + if(dwFileIndex < pBetTable->dwEntryCount) + { + ULONGLONG NameHash1 = pHetTable->pNameHashes[i]; + ULONGLONG NameHash2 = 0; + + // Load the BET hash + pBetTable->pNameHashes->GetBits(pBetTable->dwBitTotal_NameHash2 * dwFileIndex, + pBetTable->dwBitCount_NameHash2, + &NameHash2, + 8); + + // Combine both part of the name hash and put it to the file table + pFileEntry = ha->pFileTable + dwFileIndex; + pFileEntry->FileNameHash = (NameHash1 << pBetTable->dwBitCount_NameHash2) | NameHash2; + } + } + } + + // Go through the entire BET table and convert it to the file table. + pFileEntry = ha->pFileTable; + pBitArray = pBetTable->pFileTable; + for(i = 0; i < pBetTable->dwEntryCount; i++) + { + DWORD dwFlagIndex = 0; + + // Read the file position + pBitArray->GetBits(dwBitPosition + pBetTable->dwBitIndex_FilePos, + pBetTable->dwBitCount_FilePos, + &pFileEntry->ByteOffset, + 8); + + // Read the file size + pBitArray->GetBits(dwBitPosition + pBetTable->dwBitIndex_FileSize, + pBetTable->dwBitCount_FileSize, + &pFileEntry->dwFileSize, + 4); + + // Read the compressed size + pBitArray->GetBits(dwBitPosition + pBetTable->dwBitIndex_CmpSize, + pBetTable->dwBitCount_CmpSize, + &pFileEntry->dwCmpSize, + 4); + + + // Read the flag index + if(pBetTable->dwFlagCount != 0) + { + pBitArray->GetBits(dwBitPosition + pBetTable->dwBitIndex_FlagIndex, + pBetTable->dwBitCount_FlagIndex, + &dwFlagIndex, + 4); + pFileEntry->dwFlags = pBetTable->pFileFlags[dwFlagIndex]; + } + + // + // TODO: Locale (?) + // + + // Move the current bit position + dwBitPosition += pBetTable->dwTableEntrySize; + pFileEntry++; + } + + // Set the current size of the file table + FreeBetTable(pBetTable); + dwErrCode = ERROR_SUCCESS; + } + else + { + dwErrCode = ERROR_FILE_CORRUPT; + } + + return dwErrCode; +} + +DWORD BuildFileTable(TMPQArchive * ha) +{ + DWORD dwFileTableSize; + bool bFileTableCreated = false; + + // Sanity checks + assert(ha->pFileTable == NULL); + assert(ha->dwFileTableSize == 0); + assert(ha->dwMaxFileCount != 0); + + // Determine the allocation size for the file table + dwFileTableSize = STORMLIB_MAX(ha->pHeader->dwBlockTableSize, ha->dwMaxFileCount); + + // Allocate the file table with size determined before + ha->pFileTable = STORM_ALLOC(TFileEntry, dwFileTableSize); + if(ha->pFileTable == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // Fill the table with zeros + memset(ha->pFileTable, 0, dwFileTableSize * sizeof(TFileEntry)); + ha->dwFileTableSize = dwFileTableSize; + + // If we have HET table, we load file table from the BET table + // Note: If BET table is corrupt or missing, we set the archive as read only + if(ha->pHetTable != NULL) + { + if(BuildFileTable_HetBet(ha) != ERROR_SUCCESS) + ha->dwFlags |= MPQ_FLAG_READ_ONLY; + else + bFileTableCreated = true; + } + + // If we have hash table, we load the file table from the block table + // Note: If block table is corrupt or missing, we set the archive as read only + if(ha->pHashTable != NULL) + { + if(BuildFileTable_Classic(ha) != ERROR_SUCCESS) + ha->dwFlags |= MPQ_FLAG_READ_ONLY; + else + bFileTableCreated = true; + } + + // Return result + return bFileTableCreated ? ERROR_SUCCESS : ERROR_FILE_CORRUPT; +} + +/* +void UpdateBlockTableSize(TMPQArchive * ha) +{ + TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; + TFileEntry * pFileEntry; + DWORD dwBlockTableSize = 0; + + // Calculate the number of files + for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) + { + // If the source table entry is valid, + if(pFileEntry->dwFlags & MPQ_FILE_EXISTS) + dwBlockTableSize = (DWORD)(pFileEntry - ha->pFileTable) + 1; + } + + // Save the block table size to the MPQ header + ha->pHeader->dwBlockTableSize = ha->dwReservedFiles + dwBlockTableSize; +} +*/ + +// Defragment the file table so it does not contain any gaps +DWORD DefragmentFileTable(TMPQArchive * ha) +{ + TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; + TFileEntry * pSource = ha->pFileTable; + TFileEntry * pTarget = ha->pFileTable; + LPDWORD DefragmentTable; + DWORD dwBlockTableSize = 0; + DWORD dwSrcIndex; + DWORD dwTrgIndex; + + // Allocate brand new file table + DefragmentTable = STORM_ALLOC(DWORD, ha->dwFileTableSize); + if(DefragmentTable != NULL) + { + // Clear the file table + memset(DefragmentTable, 0xFF, sizeof(DWORD) * ha->dwFileTableSize); + + // Parse the entire file table and defragment it + for(; pSource < pFileTableEnd; pSource++) + { + // If the source table entry is valid, + if(pSource->dwFlags & MPQ_FILE_EXISTS) + { + // Remember the index conversion + dwSrcIndex = (DWORD)(pSource - ha->pFileTable); + dwTrgIndex = (DWORD)(pTarget - ha->pFileTable); + DefragmentTable[dwSrcIndex] = dwTrgIndex; + + // Move the entry, if needed + if(pTarget != pSource) + pTarget[0] = pSource[0]; + pTarget++; + + // Update the block table size + dwBlockTableSize = (DWORD)(pTarget - ha->pFileTable); + } + else + { + // If there is file name left, free it + if(pSource->szFileName != NULL) + STORM_FREE(pSource->szFileName); + pSource->szFileName = NULL; + } + } + + // Did we defragment something? + if(pTarget < pFileTableEnd) + { + // Clear the remaining file entries + memset(pTarget, 0, (pFileTableEnd - pTarget) * sizeof(TFileEntry)); + + // Go through the hash table and relocate the block indexes + if(ha->pHashTable != NULL) + { + TMPQHash * pHashTableEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; + TMPQHash * pHash; + DWORD dwNewBlockIndex; + + for(pHash = ha->pHashTable; pHash < pHashTableEnd; pHash++) + { + if(MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize) + { + // If that block entry is there, set it to the hash entry + // If not, set it as DELETED + dwNewBlockIndex = DefragmentTable[MPQ_BLOCK_INDEX(pHash)]; + pHash->dwBlockIndex = (dwNewBlockIndex != HASH_ENTRY_FREE) ? dwNewBlockIndex : HASH_ENTRY_DELETED; + } + } + } + } + + // Save the block table size + ha->pHeader->dwBlockTableSize = ha->dwReservedFiles + dwBlockTableSize; + + // Free the defragment table + STORM_FREE(DefragmentTable); + } + + return ERROR_SUCCESS; +} + +// Rebuilds the HET table from scratch based on the file table +// Used after a modifying operation (add, rename, delete) +DWORD RebuildHetTable(TMPQArchive * ha) +{ + TMPQHetTable * pOldHetTable = ha->pHetTable; + TFileEntry * pFileTableEnd; + TFileEntry * pFileEntry; + DWORD dwBlockTableSize = ha->dwFileTableSize; + DWORD dwErrCode = ERROR_SUCCESS; + + // If we are in the state of saving MPQ tables, the real size of block table + // must already have been calculated. Use that value instead + if(ha->dwFlags & MPQ_FLAG_SAVING_TABLES) + { + assert(ha->pHeader->dwBlockTableSize != 0); + dwBlockTableSize = ha->pHeader->dwBlockTableSize; + } + + // Create new HET table based on the total number of entries in the file table + // Note that if we fail to create it, we just stop using HET table + ha->pHetTable = CreateHetTable(dwBlockTableSize, 0, 0x40, NULL); + if(ha->pHetTable != NULL) + { + // Go through the file table again and insert all existing files + pFileTableEnd = ha->pFileTable + dwBlockTableSize; + for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) + { + if(pFileEntry->dwFlags & MPQ_FILE_EXISTS) + { + // Get the high + dwErrCode = InsertHetEntry(ha->pHetTable, pFileEntry->FileNameHash, (DWORD)(pFileEntry - ha->pFileTable)); + if(dwErrCode != ERROR_SUCCESS) + break; + } + } + } + + // Free the old HET table + FreeHetTable(pOldHetTable); + return dwErrCode; +} + +// Rebuilds the file table, removing all deleted file entries. +// Used when compacting the archive +DWORD RebuildFileTable(TMPQArchive * ha, DWORD dwNewHashTableSize) +{ + TFileEntry * pFileEntry; + TMPQHash * pHashTableEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; + TMPQHash * pOldHashTable = ha->pHashTable; + TMPQHash * pHashTable = NULL; + TMPQHash * pHash; + DWORD dwErrCode = ERROR_SUCCESS; + + // The new hash table size must be greater or equal to the current hash table size + assert(dwNewHashTableSize >= ha->pHeader->dwHashTableSize); + assert(dwNewHashTableSize >= ha->dwMaxFileCount); + assert((dwNewHashTableSize & (dwNewHashTableSize - 1)) == 0); + assert(ha->pHashTable != NULL); + + // Reallocate the new file table, if needed + if(dwNewHashTableSize > ha->dwFileTableSize) + { + ha->pFileTable = STORM_REALLOC(TFileEntry, ha->pFileTable, dwNewHashTableSize); + if(ha->pFileTable == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + memset(ha->pFileTable + ha->dwFileTableSize, 0, (dwNewHashTableSize - ha->dwFileTableSize) * sizeof(TFileEntry)); + } + + // Allocate new hash table + if(dwErrCode == ERROR_SUCCESS) + { + pHashTable = STORM_ALLOC(TMPQHash, dwNewHashTableSize); + if(pHashTable == NULL) + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + + // If both succeeded, we need to rebuild the file table + if(dwErrCode == ERROR_SUCCESS) + { + // Make sure that the hash table is properly filled + memset(pHashTable, 0xFF, sizeof(TMPQHash) * dwNewHashTableSize); + ha->pHashTable = pHashTable; + + // Set the new limits to the MPQ archive + ha->pHeader->dwHashTableSize = dwNewHashTableSize; + + // Parse the old hash table and copy all entries to the new table + for(pHash = pOldHashTable; pHash < pHashTableEnd; pHash++) + { + if(IsValidHashEntry(ha, pHash)) + { + pFileEntry = ha->pFileTable + MPQ_BLOCK_INDEX(pHash); + AllocateHashEntry(ha, pFileEntry, pHash->lcLocale); + } + } + + // Increment the max file count for the file + ha->dwFileTableSize = dwNewHashTableSize; + ha->dwMaxFileCount = dwNewHashTableSize; + ha->dwFlags |= MPQ_FLAG_CHANGED; + } + + // Now free the remaining entries + if(pOldHashTable != NULL) + STORM_FREE(pOldHashTable); + return dwErrCode; +} + +// Saves MPQ header, hash table, block table and hi-block table. +DWORD SaveMPQTables(TMPQArchive * ha) +{ + TMPQExtHeader * pHetTable = NULL; + TMPQExtHeader * pBetTable = NULL; + TMPQHeader * pHeader = ha->pHeader; + TMPQBlock * pBlockTable = NULL; + TMPQHash * pHashTable = NULL; + ULONGLONG HetTableSize64 = 0; + ULONGLONG BetTableSize64 = 0; + ULONGLONG HashTableSize64 = 0; + ULONGLONG BlockTableSize64 = 0; + ULONGLONG HiBlockTableSize64 = 0; + ULONGLONG TablePos = 0; // A table position, relative to the begin of the MPQ + USHORT * pHiBlockTable = NULL; + DWORD cbTotalSize; + bool bNeedHiBlockTable = false; + DWORD dwErrCode = ERROR_SUCCESS; + + // We expect this function to be called only when tables have been changed + assert(ha->dwFlags & MPQ_FLAG_CHANGED); + + // Find the space where the MPQ tables will be saved + TablePos = FindFreeMpqSpace(ha); + + // If the MPQ has HET table, we prepare a ready-to-save version + if(dwErrCode == ERROR_SUCCESS && ha->pHetTable != NULL) + { + pHetTable = TranslateHetTable(ha->pHetTable, &HetTableSize64); + if(pHetTable == NULL) + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + + // If the MPQ has HET table, we also must create BET table to be saved + if(dwErrCode == ERROR_SUCCESS && ha->pHetTable != NULL) + { + pBetTable = TranslateBetTable(ha, &BetTableSize64); + if(pBetTable == NULL) + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + + // Now create hash table + if(dwErrCode == ERROR_SUCCESS && ha->pHashTable != NULL) + { + pHashTable = TranslateHashTable(ha, &HashTableSize64); + if(pHashTable == NULL) + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + + // Create block table + if(dwErrCode == ERROR_SUCCESS && ha->pFileTable != NULL) + { + pBlockTable = TranslateBlockTable(ha, &BlockTableSize64, &bNeedHiBlockTable); + if(pBlockTable == NULL) + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + + // Create hi-block table, if needed + if(dwErrCode == ERROR_SUCCESS && bNeedHiBlockTable) + { + pHiBlockTable = TranslateHiBlockTable(ha, &HiBlockTableSize64); + if(pHiBlockTable == NULL) + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + + // Write the HET table, if any + if(dwErrCode == ERROR_SUCCESS && pHetTable != NULL) + { + pHeader->HetTableSize64 = HetTableSize64; + pHeader->HetTablePos64 = TablePos; + dwErrCode = SaveExtTable(ha, pHetTable, TablePos, (DWORD)HetTableSize64, pHeader->MD5_HetTable, MPQ_KEY_HASH_TABLE, false, &cbTotalSize); + TablePos += cbTotalSize; + } + + // Write the BET table, if any + if(dwErrCode == ERROR_SUCCESS && pBetTable != NULL) + { + pHeader->BetTableSize64 = BetTableSize64; + pHeader->BetTablePos64 = TablePos; + dwErrCode = SaveExtTable(ha, pBetTable, TablePos, (DWORD)BetTableSize64, pHeader->MD5_BetTable, MPQ_KEY_BLOCK_TABLE, false, &cbTotalSize); + TablePos += cbTotalSize; + } + + // Write the hash table, if we have any + if(dwErrCode == ERROR_SUCCESS && pHashTable != NULL) + { + pHeader->HashTableSize64 = HashTableSize64; + pHeader->wHashTablePosHi = (USHORT)(TablePos >> 32); + pHeader->dwHashTableSize = (DWORD)(HashTableSize64 / sizeof(TMPQHash)); + pHeader->dwHashTablePos = (DWORD)TablePos; + dwErrCode = SaveMpqTable(ha, pHashTable, TablePos, (size_t)HashTableSize64, pHeader->MD5_HashTable, MPQ_KEY_HASH_TABLE, false); + TablePos += HashTableSize64; + } + + // Write the block table, if we have any + if(dwErrCode == ERROR_SUCCESS && pBlockTable != NULL) + { + pHeader->BlockTableSize64 = BlockTableSize64; + pHeader->wBlockTablePosHi = (USHORT)(TablePos >> 32); + pHeader->dwBlockTableSize = (DWORD)(BlockTableSize64 / sizeof(TMPQBlock)); + pHeader->dwBlockTablePos = (DWORD)TablePos; + dwErrCode = SaveMpqTable(ha, pBlockTable, TablePos, (size_t)BlockTableSize64, pHeader->MD5_BlockTable, MPQ_KEY_BLOCK_TABLE, false); + TablePos += BlockTableSize64; + } + + // Write the hi-block table, if we have any + if(dwErrCode == ERROR_SUCCESS && pHiBlockTable != NULL) + { + ULONGLONG ByteOffset = ha->MpqPos + TablePos; + + pHeader->HiBlockTableSize64 = HiBlockTableSize64; + pHeader->HiBlockTablePos64 = TablePos; + BSWAP_ARRAY16_UNSIGNED(pHiBlockTable, HiBlockTableSize64); + + if(!FileStream_Write(ha->pStream, &ByteOffset, pHiBlockTable, (DWORD)HiBlockTableSize64)) + dwErrCode = GetLastError(); + TablePos += HiBlockTableSize64; + } + + // Cut the MPQ + if(dwErrCode == ERROR_SUCCESS) + { + ULONGLONG FileSize = ha->MpqPos + TablePos; + + if(!FileStream_SetSize(ha->pStream, FileSize)) + dwErrCode = GetLastError(); + } + + // Write the MPQ header + if(dwErrCode == ERROR_SUCCESS) + { + TMPQHeader SaveMpqHeader; + + // Update the size of the archive + pHeader->ArchiveSize64 = TablePos; + pHeader->dwArchiveSize = (DWORD)TablePos; + + // Update the MD5 of the archive header + CalculateDataBlockHash(pHeader, MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE, pHeader->MD5_MpqHeader); + + // Write the MPQ header to the file + memcpy(&SaveMpqHeader, pHeader, pHeader->dwHeaderSize); + BSWAP_TMPQHEADER(&SaveMpqHeader, MPQ_FORMAT_VERSION_1); + BSWAP_TMPQHEADER(&SaveMpqHeader, MPQ_FORMAT_VERSION_2); + BSWAP_TMPQHEADER(&SaveMpqHeader, MPQ_FORMAT_VERSION_3); + BSWAP_TMPQHEADER(&SaveMpqHeader, MPQ_FORMAT_VERSION_4); + if(!FileStream_Write(ha->pStream, &ha->MpqPos, &SaveMpqHeader, pHeader->dwHeaderSize)) + dwErrCode = GetLastError(); + } + + // Clear the changed flag + if(dwErrCode == ERROR_SUCCESS) + ha->dwFlags &= ~MPQ_FLAG_CHANGED; + + // Cleanup and exit + if(pHetTable != NULL) + STORM_FREE(pHetTable); + if(pBetTable != NULL) + STORM_FREE(pBetTable); + if(pHashTable != NULL) + STORM_FREE(pHashTable); + if(pBlockTable != NULL) + STORM_FREE(pBlockTable); + if(pHiBlockTable != NULL) + STORM_FREE(pHiBlockTable); + return dwErrCode; +} diff --git a/StormLib/src/SBaseSubTypes.cpp b/StormLib/src/SBaseSubTypes.cpp new file mode 100644 index 000000000..6ab4a99c8 --- /dev/null +++ b/StormLib/src/SBaseSubTypes.cpp @@ -0,0 +1,618 @@ +/*****************************************************************************/ +/* SBaseSubTypes.cpp Copyright (c) Ladislav Zezula 2013 */ +/*---------------------------------------------------------------------------*/ +/* Conversion routines for archive formats that are similar to MPQ format */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 02.11.11 1.00 Lad The first version of SBaseSubTypes.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" + +/*****************************************************************************/ +/* */ +/* Support for SQP file format (War of the Immortals) */ +/* */ +/*****************************************************************************/ + +typedef struct _TSQPHeader +{ + // The ID_MPQ ('MPQ\x1A') signature + DWORD dwID; + + // Size of the archive header + DWORD dwHeaderSize; + + // 32-bit size of MPQ archive + DWORD dwArchiveSize; + + // Offset to the beginning of the hash table, relative to the beginning of the archive. + DWORD dwHashTablePos; + + // Offset to the beginning of the block table, relative to the beginning of the archive. + DWORD dwBlockTablePos; + + // Number of entries in the hash table. Must be a power of two, and must be less than 2^16 for + // the original MoPaQ format, or less than 2^20 for the Burning Crusade format. + DWORD dwHashTableSize; + + // Number of entries in the block table + DWORD dwBlockTableSize; + + // Must be zero for SQP files + USHORT wFormatVersion; + + // Power of two exponent specifying the number of 512-byte disk sectors in each file sector + // in the archive. The size of each file sector in the archive is 512 * 2 ^ wSectorSize. + USHORT wSectorSize; + +} TSQPHeader; + +typedef struct _TSQPHash +{ + // Most likely the lcLocale+wPlatform. + DWORD dwAlwaysZero; + + // If the hash table entry is valid, this is the index into the block table of the file. + // Otherwise, one of the following two values: + // - FFFFFFFFh: Hash table entry is empty, and has always been empty. + // Terminates searches for a given file. + // - FFFFFFFEh: Hash table entry is empty, but was valid at some point (a deleted file). + // Does not terminate searches for a given file. + DWORD dwBlockIndex; + + // The hash of the file path, using method A. + DWORD dwName1; + + // The hash of the file path, using method B. + DWORD dwName2; + +} TSQPHash; + +typedef struct _TSQPBlock +{ + // Offset of the beginning of the file, relative to the beginning of the archive. + DWORD dwFilePos; + + // Flags for the file. See MPQ_FILE_XXXX constants + DWORD dwFlags; + + // Compressed file size + DWORD dwCSize; + + // Uncompressed file size + DWORD dwFSize; + +} TSQPBlock; + +//----------------------------------------------------------------------------- +// Functions - SQP file format + +// This function converts SQP file header into MPQ file header +DWORD ConvertSqpHeaderToFormat4( + TMPQArchive * ha, + ULONGLONG FileSize, + DWORD dwFlags) +{ + TSQPHeader * pSqpHeader = (TSQPHeader *)ha->HeaderData; + TMPQHeader Header; + + // SQP files from War of the Immortal use MPQ file format with slightly + // modified structure. These fields have different position: + // + // Offset TMPQHeader TSQPHeader + // ------ ---------- ----------- + // 000C wFormatVersion dwHashTablePos (lo) + // 000E wSectorSize dwHashTablePos (hi) + // 001C dwBlockTableSize (lo) wBlockSize + // 001E dwHashTableSize (hi) wFormatVersion + + // Can't open the archive with certain flags + if(dwFlags & MPQ_OPEN_FORCE_MPQ_V1) + return ERROR_FILE_CORRUPT; + + // The file must not be greater than 4 GB + if((FileSize >> 0x20) != 0) + return ERROR_FILE_CORRUPT; + + // Translate the SQP header into a MPQ header + memset(&Header, 0, sizeof(TMPQHeader)); + Header.dwID = BSWAP_INT32_UNSIGNED(pSqpHeader->dwID); + Header.dwHeaderSize = BSWAP_INT32_UNSIGNED(pSqpHeader->dwHeaderSize); + Header.dwArchiveSize = BSWAP_INT32_UNSIGNED(pSqpHeader->dwArchiveSize); + Header.dwHashTablePos = BSWAP_INT32_UNSIGNED(pSqpHeader->dwHashTablePos); + Header.dwBlockTablePos = BSWAP_INT32_UNSIGNED(pSqpHeader->dwBlockTablePos); + Header.dwHashTableSize = BSWAP_INT32_UNSIGNED(pSqpHeader->dwHashTableSize); + Header.dwBlockTableSize = BSWAP_INT32_UNSIGNED(pSqpHeader->dwBlockTableSize); + Header.wFormatVersion = BSWAP_INT16_UNSIGNED(pSqpHeader->wFormatVersion); + Header.wSectorSize = BSWAP_INT16_UNSIGNED(pSqpHeader->wSectorSize); + + // Verify the SQP header + if(Header.dwID == g_dwMpqSignature && Header.dwHeaderSize == sizeof(TSQPHeader) && Header.dwArchiveSize == FileSize) + { + // Check for fixed values of version and sector size + if(Header.wFormatVersion == MPQ_FORMAT_VERSION_1 && Header.wSectorSize == 3) + { + // Initialize the fields of 3.0 header + Header.ArchiveSize64 = Header.dwArchiveSize; + Header.HashTableSize64 = Header.dwHashTableSize * sizeof(TMPQHash); + Header.BlockTableSize64 = Header.dwBlockTableSize * sizeof(TMPQBlock); + + // Copy the converted MPQ header back + memcpy(ha->HeaderData, &Header, sizeof(TMPQHeader)); + + // Mark this file as SQP file + ha->pfnHashString = HashStringSlash; + ha->dwFlags |= MPQ_FLAG_READ_ONLY; + ha->dwSubType = MPQ_SUBTYPE_SQP; + return ERROR_SUCCESS; + } + } + + return ERROR_FILE_CORRUPT; +} + +void * LoadSqpTable(TMPQArchive * ha, DWORD dwByteOffset, DWORD cbTableSize, DWORD dwKey) +{ + ULONGLONG ByteOffset; + LPBYTE pbSqpTable; + + // Allocate buffer for the table + pbSqpTable = STORM_ALLOC(BYTE, cbTableSize); + if(pbSqpTable != NULL) + { + // Load the table + ByteOffset = ha->MpqPos + dwByteOffset; + if(FileStream_Read(ha->pStream, &ByteOffset, pbSqpTable, cbTableSize)) + { + // Decrypt the SQP table + DecryptMpqBlock(pbSqpTable, cbTableSize, dwKey); + return pbSqpTable; + } + + // Free the table + STORM_FREE(pbSqpTable); + } + + return NULL; +} + +TMPQHash * LoadSqpHashTable(TMPQArchive * ha) +{ + TMPQHeader * pHeader = ha->pHeader; + TSQPHash * pSqpHashTable; + TSQPHash * pSqpHashEnd; + TSQPHash * pSqpHash; + TMPQHash * pMpqHash; + DWORD dwErrCode = ERROR_SUCCESS; + + // Load the hash table + pSqpHashTable = (TSQPHash *)LoadSqpTable(ha, pHeader->dwHashTablePos, pHeader->dwHashTableSize * sizeof(TSQPHash), MPQ_KEY_HASH_TABLE); + if(pSqpHashTable != NULL) + { + // Parse the entire hash table and convert it to MPQ hash table + pSqpHashEnd = pSqpHashTable + pHeader->dwHashTableSize; + pMpqHash = (TMPQHash *)pSqpHashTable; + for(pSqpHash = pSqpHashTable; pSqpHash < pSqpHashEnd; pSqpHash++, pMpqHash++) + { + // Ignore free entries + if(pSqpHash->dwBlockIndex != HASH_ENTRY_FREE) + { + // Check block index against the size of the block table + if(pHeader->dwBlockTableSize <= MPQ_BLOCK_INDEX(pSqpHash) && pSqpHash->dwBlockIndex < HASH_ENTRY_DELETED) + dwErrCode = ERROR_FILE_CORRUPT; + + // We do not support nonzero locale and platform ID + if(pSqpHash->dwAlwaysZero != 0 && pSqpHash->dwAlwaysZero != HASH_ENTRY_FREE) + dwErrCode = ERROR_FILE_CORRUPT; + + // Store the file name hash + pMpqHash->dwName1 = pSqpHash->dwName1; + pMpqHash->dwName2 = pSqpHash->dwName2; + + // Store the rest. Note that this must be done last, + // because block index corresponds to pMpqHash->dwName2 + pMpqHash->dwBlockIndex = MPQ_BLOCK_INDEX(pSqpHash); + pMpqHash->Platform = 0; + pMpqHash->lcLocale = 0; + } + } + + // If an error occured, we need to free the hash table + if(dwErrCode != ERROR_SUCCESS) + { + STORM_FREE(pSqpHashTable); + pSqpHashTable = NULL; + } + } + + // Return the converted hash table (or NULL on failure) + return (TMPQHash *)pSqpHashTable; +} + +// Loads the SQP Block table and converts it to a MPQ block table +TMPQBlock * LoadSqpBlockTable(TMPQArchive * ha) +{ + TMPQHeader * pHeader = ha->pHeader; + TSQPBlock * pSqpBlockTable; + TSQPBlock * pSqpBlockEnd; + TSQPBlock * pSqpBlock; + TMPQBlock * pMpqBlock; + DWORD dwFlags; + DWORD dwErrCode = ERROR_SUCCESS; + + // Load the hash table + pSqpBlockTable = (TSQPBlock *)LoadSqpTable(ha, pHeader->dwBlockTablePos, pHeader->dwBlockTableSize * sizeof(TSQPBlock), MPQ_KEY_BLOCK_TABLE); + if(pSqpBlockTable != NULL) + { + // Parse the entire hash table and convert it to MPQ hash table + pSqpBlockEnd = pSqpBlockTable + pHeader->dwBlockTableSize; + pMpqBlock = (TMPQBlock *)pSqpBlockTable; + for(pSqpBlock = pSqpBlockTable; pSqpBlock < pSqpBlockEnd; pSqpBlock++, pMpqBlock++) + { + // Check for valid flags + if(pSqpBlock->dwFlags & ~MPQ_FILE_VALID_FLAGS) + dwErrCode = ERROR_FILE_CORRUPT; + + // Convert SQP block table entry to MPQ block table entry + dwFlags = pSqpBlock->dwFlags; + pMpqBlock->dwCSize = pSqpBlock->dwCSize; + pMpqBlock->dwFSize = pSqpBlock->dwFSize; + pMpqBlock->dwFlags = dwFlags; + } + + // If an error occured, we need to free the hash table + if(dwErrCode != ERROR_SUCCESS) + { + STORM_FREE(pSqpBlockTable); + pSqpBlockTable = NULL; + } + } + + // Return the converted hash table (or NULL on failure) + return (TMPQBlock *)pSqpBlockTable; +} + +/*****************************************************************************/ +/* */ +/* Support for MPK file format (Longwu Online) */ +/* */ +/*****************************************************************************/ + +#define MPK_FILE_UNKNOWN_0001 0x00000001 // Seems to be always present +#define MPK_FILE_UNKNOWN_0010 0x00000010 // Seems to be always present +#define MPK_FILE_COMPRESSED 0x00000100 // Indicates a compressed file +#define MPK_FILE_UNKNOWN_2000 0x00002000 // Seems to be always present +#define MPK_FILE_EXISTS 0x01000000 // Seems to be always present + +typedef struct _TMPKHeader +{ + // The ID_MPK ('MPK\x1A') signature + DWORD dwID; + + // Contains '2000' + DWORD dwVersion; + + // 32-bit size of the archive + DWORD dwArchiveSize; + + // Size of the archive header + DWORD dwHeaderSize; + + DWORD dwHashTablePos; + DWORD dwHashTableSize; + DWORD dwBlockTablePos; + DWORD dwBlockTableSize; + DWORD dwUnknownPos; + DWORD dwUnknownSize; +} TMPKHeader; + + +typedef struct _TMPKHash +{ + // The hash of the file path, using method A. + DWORD dwName1; + + // The hash of the file path, using method B. + DWORD dwName2; + + // The hash of the file path, using method C. + DWORD dwName3; + + // If the hash table entry is valid, this is the index into the block table of the file. + // Otherwise, one of the following two values: + // - FFFFFFFFh: Hash table entry is empty, and has always been empty. + // Terminates searches for a given file. + // - FFFFFFFEh: Hash table entry is empty, but was valid at some point (a deleted file). + // Does not terminate searches for a given file. + DWORD dwBlockIndex; + +} TMPKHash; + +typedef struct _TMPKBlock +{ + DWORD dwFlags; // 0x1121 - Compressed , 0x1120 - Not compressed + DWORD dwFilePos; // Offset of the beginning of the file, relative to the beginning of the archive. + DWORD dwFSize; // Uncompressed file size + DWORD dwCSize; // Compressed file size + DWORD dwUnknown; // 0x86364E6D +} TMPKBlock; + +//----------------------------------------------------------------------------- +// Local variables - MPK file format + +static const unsigned char MpkDecryptionKey[512] = +{ + 0x60, 0x20, 0x29, 0xE1, 0x01, 0xCE, 0xAA, 0xFE, 0xA3, 0xAB, 0x8E, 0x30, 0xAF, 0x02, 0xD1, 0x7D, + 0x41, 0x24, 0x06, 0xBD, 0xAE, 0xBE, 0x43, 0xC3, 0xBA, 0xB7, 0x08, 0x13, 0x51, 0xCF, 0xF8, 0xF7, + 0x25, 0x42, 0xA5, 0x4A, 0xDA, 0x0F, 0x52, 0x1C, 0x90, 0x3B, 0x63, 0x49, 0x36, 0xF6, 0xDD, 0x1B, + 0xEA, 0x58, 0xD4, 0x40, 0x70, 0x61, 0x55, 0x09, 0xCD, 0x0B, 0xA2, 0x4B, 0x68, 0x2C, 0x8A, 0xF1, + 0x3C, 0x3A, 0x65, 0xBB, 0xA1, 0xA8, 0x23, 0x97, 0xFD, 0x15, 0x00, 0x94, 0x88, 0x33, 0x59, 0xE9, + 0xFB, 0x69, 0x21, 0xEF, 0x85, 0x5B, 0x57, 0x6C, 0xFA, 0xB5, 0xEE, 0xB8, 0x71, 0xDC, 0xB1, 0x38, + 0x0C, 0x0A, 0x5C, 0x56, 0xC9, 0xB4, 0x84, 0x17, 0x1E, 0xE5, 0xD3, 0x5A, 0xCC, 0xFC, 0x11, 0x86, + 0x7F, 0x45, 0x4F, 0x54, 0xC8, 0x8D, 0x73, 0x89, 0x79, 0x5D, 0xB3, 0xBF, 0xB9, 0xE3, 0x93, 0xE4, + 0x6F, 0x35, 0x2D, 0x46, 0xF2, 0x76, 0xC5, 0x7E, 0xE2, 0xA4, 0xE6, 0xD9, 0x6E, 0x48, 0x34, 0x2B, + 0xC6, 0x5F, 0xBC, 0xA0, 0x6D, 0x0D, 0x47, 0x6B, 0x95, 0x96, 0x92, 0x91, 0xB2, 0x27, 0xEB, 0x9E, + 0xEC, 0x8F, 0xDF, 0x9C, 0x74, 0x99, 0x64, 0xF5, 0xFF, 0x28, 0xB6, 0x37, 0xF3, 0x7C, 0x81, 0x03, + 0x44, 0x62, 0x1F, 0xDB, 0x04, 0x7B, 0xB0, 0x9B, 0x31, 0xA7, 0xDE, 0x78, 0x9F, 0xAD, 0x0E, 0x3F, + 0x3E, 0x4D, 0xC7, 0xD7, 0x39, 0x19, 0x5E, 0xC2, 0xD0, 0xAC, 0xE8, 0x1A, 0x87, 0x8B, 0x07, 0x05, + 0x22, 0xED, 0x72, 0x2E, 0x1D, 0xC1, 0xA9, 0xD6, 0xE0, 0x83, 0xD5, 0xD8, 0xCB, 0x80, 0xF0, 0x66, + 0x7A, 0x9D, 0x50, 0xF9, 0x10, 0x4E, 0x16, 0x14, 0x77, 0x75, 0x6A, 0x67, 0xD2, 0xC0, 0xA6, 0xC4, + 0x53, 0x8C, 0x32, 0xCA, 0x82, 0x2A, 0x18, 0x9A, 0xF4, 0x4C, 0x3D, 0x26, 0x12, 0xE7, 0x98, 0x2F, + 0x4A, 0x04, 0x0D, 0xAF, 0xB4, 0xCF, 0x12, 0xCE, 0x1A, 0x37, 0x61, 0x39, 0x60, 0x95, 0xBE, 0x25, + 0xE4, 0x6E, 0xFC, 0x1B, 0xE7, 0x49, 0xE6, 0x67, 0xF6, 0xC5, 0xCB, 0x2F, 0x27, 0xD4, 0x68, 0xB2, + 0x01, 0x52, 0xD0, 0x46, 0x11, 0x20, 0xFB, 0x9D, 0xA9, 0x02, 0xF5, 0x8F, 0x3D, 0x82, 0xD3, 0xFF, + 0x0B, 0xB8, 0xF2, 0x4D, 0x8E, 0x81, 0x2C, 0xAB, 0x5F, 0xC4, 0x41, 0x29, 0x40, 0xFA, 0xC0, 0xBF, + 0x33, 0x10, 0x21, 0x16, 0xB0, 0x71, 0x83, 0x96, 0x8D, 0x2B, 0x23, 0x3B, 0xF9, 0xC1, 0xE5, 0x72, + 0xE2, 0x1C, 0x26, 0xF0, 0x73, 0x36, 0x63, 0x56, 0x31, 0x4E, 0x6B, 0x55, 0x62, 0x79, 0xC6, 0x91, + 0x00, 0x35, 0xB1, 0x2A, 0xA6, 0x42, 0xDF, 0xEB, 0x3C, 0x51, 0xEA, 0x97, 0x57, 0x94, 0x8C, 0x80, + 0x34, 0x5C, 0xD2, 0x76, 0xA4, 0xE9, 0x85, 0xE8, 0xBB, 0x78, 0xE0, 0xB5, 0xAD, 0x0F, 0x87, 0x70, + 0xDD, 0xAE, 0xF4, 0xD9, 0x66, 0x54, 0x6F, 0xCC, 0x4C, 0x77, 0x3E, 0xCD, 0xF1, 0x75, 0x0A, 0xA1, + 0x28, 0x9B, 0x9A, 0x7E, 0x4B, 0x98, 0x99, 0x47, 0xFE, 0xA5, 0xF7, 0xB7, 0xA3, 0xE1, 0x9F, 0xBC, + 0x93, 0x44, 0x3A, 0x08, 0x89, 0x22, 0xEE, 0xB9, 0x45, 0xD6, 0x06, 0x09, 0xC9, 0xBD, 0x14, 0x0C, + 0xB6, 0x5E, 0x9C, 0x7A, 0x65, 0x59, 0xAA, 0x19, 0x5B, 0x7C, 0x18, 0x43, 0x92, 0x13, 0x15, 0x7B, + 0xED, 0xD5, 0xC7, 0x17, 0xEF, 0x86, 0x90, 0xC2, 0x74, 0x64, 0xF3, 0xDC, 0x6C, 0x38, 0x05, 0x1D, + 0xC8, 0x0E, 0xEC, 0x6A, 0x32, 0xDA, 0xD7, 0xC3, 0xDB, 0x8B, 0x24, 0xB3, 0x5D, 0x2E, 0xBA, 0xA2, + 0xD8, 0x03, 0x88, 0x7D, 0x7F, 0x69, 0x8A, 0xFD, 0xCA, 0x4F, 0x30, 0x9E, 0xA0, 0xD1, 0x5A, 0x53, + 0xDE, 0x3F, 0x84, 0xAC, 0xF8, 0xA7, 0x2D, 0x1F, 0x1E, 0xE3, 0x58, 0x50, 0x6D, 0x48, 0x07, 0xA8 +}; + +//----------------------------------------------------------------------------- +// Functions - MPK file format + +// This function converts MPK file header into MPQ file header +DWORD ConvertMpkHeaderToFormat4( + TMPQArchive * ha, + ULONGLONG FileSize, + DWORD dwFlags) +{ + TMPKHeader * pMpkHeader = (TMPKHeader *)ha->HeaderData; + TMPQHeader Header; + + // Can't open the archive with certain flags + if(dwFlags & MPQ_OPEN_FORCE_MPQ_V1) + return ERROR_FILE_CORRUPT; + + // Translate the MPK header into a MPQ header + // Note: Hash table size and block table size are in bytes, not in entries + memset(&Header, 0, sizeof(TMPQHeader)); + Header.dwID = BSWAP_INT32_UNSIGNED(pMpkHeader->dwID); + Header.dwArchiveSize = BSWAP_INT32_UNSIGNED(pMpkHeader->dwArchiveSize); + Header.dwHeaderSize = BSWAP_INT32_UNSIGNED(pMpkHeader->dwHeaderSize); + Header.dwHashTablePos = BSWAP_INT32_UNSIGNED(pMpkHeader->dwHashTablePos); + Header.dwHashTableSize = BSWAP_INT32_UNSIGNED(pMpkHeader->dwHashTableSize) / sizeof(TMPKHash); + Header.dwBlockTablePos = BSWAP_INT32_UNSIGNED(pMpkHeader->dwBlockTablePos); + Header.dwBlockTableSize = BSWAP_INT32_UNSIGNED(pMpkHeader->dwBlockTableSize) / sizeof(TMPKBlock); +// Header.dwUnknownPos = BSWAP_INT32_UNSIGNED(pMpkHeader->dwUnknownPos); +// Header.dwUnknownSize = BSWAP_INT32_UNSIGNED(pMpkHeader->dwUnknownSize); + assert(Header.dwHeaderSize == sizeof(TMPKHeader)); + + // Verify the MPK header + if(Header.dwID == ID_MPK && Header.dwHeaderSize == sizeof(TMPKHeader) && Header.dwArchiveSize == (DWORD)FileSize) + { + // The header ID must be ID_MPQ + Header.dwID = g_dwMpqSignature; + Header.wFormatVersion = MPQ_FORMAT_VERSION_1; + Header.wSectorSize = 3; + + // Initialize the fields of 3.0 header + Header.ArchiveSize64 = Header.dwArchiveSize; + Header.HashTableSize64 = Header.dwHashTableSize * sizeof(TMPQHash); + Header.BlockTableSize64 = Header.dwBlockTableSize * sizeof(TMPQBlock); + + // Copy the converted MPQ header back + memcpy(ha->HeaderData, &Header, sizeof(TMPQHeader)); + + // Mark this file as MPK file + ha->pfnHashString = HashStringLower; + ha->dwFlags |= MPQ_FLAG_READ_ONLY; + ha->dwSubType = MPQ_SUBTYPE_MPK; + return ERROR_SUCCESS; + } + return ERROR_FILE_CORRUPT; +} + +// Attempts to search a free hash entry in the hash table being converted. +// The created hash table must always be of nonzero size, +// should have no duplicated items and no deleted entries +TMPQHash * FindFreeHashEntry(TMPQHash * pHashTable, DWORD dwHashTableSize, DWORD dwStartIndex) +{ + TMPQHash * pHash; + DWORD dwIndex; + + // Set the initial index + dwStartIndex = dwIndex = (dwStartIndex & (dwHashTableSize - 1)); + assert(dwHashTableSize != 0); + + // Search the hash table and return the found entries in the following priority: + for(;;) + { + // We are not expecting to find matching entry in the hash table being built + // We are not expecting to find deleted entry either + pHash = pHashTable + dwIndex; + + // If we found a free entry, we need to stop searching + if(pHash->dwBlockIndex == HASH_ENTRY_FREE) + return pHash; + + // Move to the next hash entry. + // If we reached the starting entry, it's failure. + dwIndex = (dwIndex + 1) & (dwHashTableSize - 1); + if(dwIndex == dwStartIndex) + break; + } + + // We haven't found anything + assert(false); + return NULL; +} + +void DecryptMpkTable(void * pvMpkTable, size_t cbSize) +{ + LPBYTE pbMpkTable = (LPBYTE)pvMpkTable; + + for(size_t i = 0; i < cbSize; i++) + pbMpkTable[i] = MpkDecryptionKey[pbMpkTable[i]]; +} + +void * LoadMpkTable(TMPQArchive * ha, DWORD dwByteOffset, DWORD cbTableSize) +{ + ULONGLONG ByteOffset; + LPBYTE pbMpkTable = NULL; + + // Allocate space for the table + pbMpkTable = STORM_ALLOC(BYTE, cbTableSize); + if(pbMpkTable != NULL) + { + // Load and the MPK hash table + ByteOffset = ha->MpqPos + dwByteOffset; + if(FileStream_Read(ha->pStream, &ByteOffset, pbMpkTable, cbTableSize)) + { + // Decrypt the table + DecryptMpkTable(pbMpkTable, cbTableSize); + return pbMpkTable; + } + + // Free the MPK table + STORM_FREE(pbMpkTable); + pbMpkTable = NULL; + } + + // Return the table + return pbMpkTable; +} + +TMPQHash * LoadMpkHashTable(TMPQArchive * ha) +{ + TMPQHeader * pHeader = ha->pHeader; + TMPQHash * pHashTable = NULL; + TMPKHash * pMpkHash; + TMPQHash * pHash = NULL; + DWORD dwHashTableSize = pHeader->dwHashTableSize; + + // MPKs use different hash table searching. + // Instead of using MPQ_HASH_TABLE_INDEX hash as index, + // they store the value directly in the hash table. + // Also for faster searching, the hash table is sorted ascending by the value + + // Load and decrypt the MPK hash table. + pMpkHash = (TMPKHash *)LoadMpkTable(ha, pHeader->dwHashTablePos, pHeader->dwHashTableSize * sizeof(TMPKHash)); + if(pMpkHash != NULL) + { + // Calculate the hash table size as if it was real MPQ hash table + pHeader->dwHashTableSize = GetNearestPowerOfTwo(pHeader->dwHashTableSize); + pHeader->HashTableSize64 = pHeader->dwHashTableSize * sizeof(TMPQHash); + + // Now allocate table that will serve like a true MPQ hash table, + // so we translate the MPK hash table to MPQ hash table + pHashTable = STORM_ALLOC(TMPQHash, pHeader->dwHashTableSize); + if(pHashTable != NULL) + { + // Set the entire hash table to free + memset(pHashTable, 0xFF, (size_t)pHeader->HashTableSize64); + + // Copy the MPK hash table into MPQ hash table + for(DWORD i = 0; i < dwHashTableSize; i++) + { + // Finds the free hash entry in the hash table + // We don't expect any errors here, because we are putting files to empty hash table + pHash = FindFreeHashEntry(pHashTable, pHeader->dwHashTableSize, pMpkHash[i].dwName1); + assert(pHash->dwBlockIndex == HASH_ENTRY_FREE); + + // Copy the MPK hash entry to the hash table + pHash->dwBlockIndex = pMpkHash[i].dwBlockIndex; + pHash->Platform = 0; + pHash->lcLocale = 0; + pHash->dwName1 = pMpkHash[i].dwName2; + pHash->dwName2 = pMpkHash[i].dwName3; + } + } + + // Free the temporary hash table + STORM_FREE(pMpkHash); + } + + return pHashTable; +} + +static DWORD ConvertMpkFlagsToMpqFlags(DWORD dwMpkFlags) +{ + DWORD dwMpqFlags = MPQ_FILE_EXISTS; + + // Check for flags that are always present + assert((dwMpkFlags & MPK_FILE_UNKNOWN_0001) != 0); + assert((dwMpkFlags & MPK_FILE_UNKNOWN_0010) != 0); + assert((dwMpkFlags & MPK_FILE_UNKNOWN_2000) != 0); + assert((dwMpkFlags & MPK_FILE_EXISTS) != 0); + + // Append the compressed flag + dwMpqFlags |= (dwMpkFlags & MPK_FILE_COMPRESSED) ? MPQ_FILE_COMPRESS : 0; + + // All files in the MPQ seem to be single unit files + dwMpqFlags |= MPQ_FILE_ENCRYPTED | MPQ_FILE_SINGLE_UNIT; + + return dwMpqFlags; +} + +TMPQBlock * LoadMpkBlockTable(TMPQArchive * ha) +{ + TMPQHeader * pHeader = ha->pHeader; + TMPKBlock * pMpkBlockTable; + TMPKBlock * pMpkBlockEnd; + TMPQBlock * pBlockTable = NULL; + TMPKBlock * pMpkBlock; + TMPQBlock * pMpqBlock; + + // Load and decrypt the MPK block table + pMpkBlockTable = pMpkBlock = (TMPKBlock *)LoadMpkTable(ha, pHeader->dwBlockTablePos, pHeader->dwBlockTableSize * sizeof(TMPKBlock)); + if(pMpkBlockTable != NULL) + { + // Allocate buffer for MPQ-like block table + pBlockTable = pMpqBlock = STORM_ALLOC(TMPQBlock, pHeader->dwBlockTableSize); + if(pBlockTable != NULL) + { + // Convert the MPK block table to MPQ block table + pMpkBlockEnd = pMpkBlockTable + pHeader->dwBlockTableSize; + while(pMpkBlock < pMpkBlockEnd) + { + // Translate the MPK block table entry to MPQ block table entry + pMpqBlock->dwFilePos = pMpkBlock->dwFilePos; + pMpqBlock->dwCSize = pMpkBlock->dwCSize; + pMpqBlock->dwFSize = pMpkBlock->dwFSize; + pMpqBlock->dwFlags = ConvertMpkFlagsToMpqFlags(pMpkBlock->dwFlags); + + // Move both + pMpkBlock++; + pMpqBlock++; + } + } + + // Free the MPK block table + STORM_FREE(pMpkBlockTable); + } + + return pBlockTable; +} diff --git a/StormLib/src/SCompression.cpp b/StormLib/src/SCompression.cpp new file mode 100644 index 000000000..1d0f67979 --- /dev/null +++ b/StormLib/src/SCompression.cpp @@ -0,0 +1,1124 @@ +/*****************************************************************************/ +/* SCompression.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* This module serves as a bridge between StormLib code and (de)compression */ +/* functions. All (de)compression calls go (and should only go) through this */ +/* module. No system headers should be included in this module to prevent */ +/* compile-time problems. */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 01.04.03 1.00 Lad The first version of SCompression.cpp */ +/* 19.11.03 1.01 Dan Big endian handling */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" + +//----------------------------------------------------------------------------- +// Local structures + +// Information about the input and output buffers for pklib +typedef struct +{ + unsigned char * pbInBuff; // Pointer to input data buffer + unsigned char * pbInBuffEnd; // End of the input buffer + unsigned char * pbOutBuff; // Pointer to output data buffer + unsigned char * pbOutBuffEnd; // Pointer to output data buffer +} TDataInfo; + +// Prototype of the compression function +// Function doesn't return an error. A success means that the size of compressed buffer +// is lower than size of uncompressed buffer. +typedef void (*COMPRESS)( + void * pvOutBuffer, // [out] Pointer to the buffer where the compressed data will be stored + int * pcbOutBuffer, // [in] Pointer to length of the buffer pointed by pvOutBuffer + void * pvInBuffer, // [in] Pointer to the buffer with data to compress + int cbInBuffer, // [in] Length of the buffer pointer by pvInBuffer + int * pCmpType, // [in] Compression-method specific value. ADPCM Setups this for the following Huffman compression + int nCmpLevel); // [in] Compression specific value. ADPCM uses this. Should be set to zero. + +// Prototype of the decompression function +// Returns 1 if success, 0 if failure +typedef int (*DECOMPRESS)( + void * pvOutBuffer, // [out] Pointer to the buffer where to store decompressed data + int * pcbOutBuffer, // [in] Pointer to total size of the buffer pointed by pvOutBuffer + // [out] Contains length of the decompressed data + void * pvInBuffer, // [in] Pointer to data to be decompressed + int cbInBuffer); // [in] Length of the data to be decompressed + +// Table of compression functions +typedef struct +{ + unsigned long uMask; // Compression mask + COMPRESS Compress; // Compression function +} TCompressTable; + +// Table of decompression functions +typedef struct +{ + unsigned long uMask; // Decompression bit + DECOMPRESS Decompress; // Decompression function +} TDecompressTable; + + +/*****************************************************************************/ +/* */ +/* Support for Huffman compression (0x01) */ +/* */ +/*****************************************************************************/ + +void Compress_huff(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, int * pCmpType, int nCmpLevel) +{ + THuffmannTree ht(true); + TOutputStream os(pvOutBuffer, *pcbOutBuffer); + + STORMLIB_UNUSED(nCmpLevel); + *pcbOutBuffer = ht.Compress(&os, pvInBuffer, cbInBuffer, *pCmpType); +} + +int Decompress_huff(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + THuffmannTree ht(false); + TInputStream is(pvInBuffer, cbInBuffer); + + *pcbOutBuffer = ht.Decompress(pvOutBuffer, *pcbOutBuffer, &is); + return (*pcbOutBuffer == 0) ? 0 : 1; +} + +/******************************************************************************/ +/* */ +/* Support for ZLIB compression (0x02) */ +/* */ +/******************************************************************************/ + +void Compress_ZLIB(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, int * pCmpType, int nCmpLevel) +{ + z_stream z; // Stream information for zlib + int windowBits; + int nResult; + + // Keep compilers happy + STORMLIB_UNUSED(pCmpType); + STORMLIB_UNUSED(nCmpLevel); + + // Fill the stream structure for zlib + z.next_in = (Bytef *)pvInBuffer; + z.avail_in = (uInt)cbInBuffer; + z.total_in = cbInBuffer; + z.next_out = (Bytef *)pvOutBuffer; + z.avail_out = *pcbOutBuffer; + z.total_out = 0; + z.zalloc = NULL; + z.zfree = NULL; + + // Determine the proper window bits (WoW.exe build 12694) + if(cbInBuffer <= 0x100) + windowBits = 8; + else if(cbInBuffer <= 0x200) + windowBits = 9; + else if(cbInBuffer <= 0x400) + windowBits = 10; + else if(cbInBuffer <= 0x800) + windowBits = 11; + else if(cbInBuffer <= 0x1000) + windowBits = 12; + else if(cbInBuffer <= 0x2000) + windowBits = 13; + else if(cbInBuffer <= 0x4000) + windowBits = 14; + else + windowBits = 15; + + // Initialize the compression. + // Storm.dll uses zlib version 1.1.3 + // Wow.exe uses zlib version 1.2.3 + nResult = deflateInit2(&z, + 6, // Compression level used by WoW MPQs + Z_DEFLATED, + windowBits, + 8, + Z_DEFAULT_STRATEGY); + if(nResult == Z_OK) + { + // Call zlib to compress the data + nResult = deflate(&z, Z_FINISH); + + if(nResult == Z_OK || nResult == Z_STREAM_END) + *pcbOutBuffer = z.total_out; + + deflateEnd(&z); + } +} + +int Decompress_ZLIB(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + z_stream z; // Stream information for zlib + int nResult; + + // Fill the stream structure for zlib + z.next_in = (Bytef *)pvInBuffer; + z.avail_in = (uInt)cbInBuffer; + z.total_in = cbInBuffer; + z.next_out = (Bytef *)pvOutBuffer; + z.avail_out = *pcbOutBuffer; + z.total_out = 0; + z.zalloc = NULL; + z.zfree = NULL; + + // Initialize the decompression structure. Storm.dll uses zlib version 1.1.3 + if((nResult = inflateInit(&z)) == Z_OK) + { + // Call zlib to decompress the data + nResult = inflate(&z, Z_FINISH); + *pcbOutBuffer = z.total_out; + inflateEnd(&z); + } + + return (nResult >= Z_OK); +} + +/******************************************************************************/ +/* */ +/* Support functions for PKWARE Data Compression Library compression (0x08) */ +/* */ +/******************************************************************************/ + +// Function loads data from the input buffer. Used by Pklib's "implode" +// and "explode" function as user-defined callback +// Returns number of bytes loaded +// +// char * buf - Pointer to a buffer where to store loaded data +// unsigned int * size - Max. number of bytes to read +// void * param - Custom pointer, parameter of implode/explode + +static unsigned int ReadInputData(char * buf, unsigned int * size, void * param) +{ + TDataInfo * pInfo = (TDataInfo *)param; + unsigned int nMaxAvail = (unsigned int)(pInfo->pbInBuffEnd - pInfo->pbInBuff); + unsigned int nToRead = *size; + + // Check the case when not enough data available + if(nToRead > nMaxAvail) + nToRead = nMaxAvail; + + // Load data and increment offsets + memcpy(buf, pInfo->pbInBuff, nToRead); + pInfo->pbInBuff += nToRead; + assert(pInfo->pbInBuff <= pInfo->pbInBuffEnd); + return nToRead; +} + +// Function for store output data. Used by Pklib's "implode" and "explode" +// as user-defined callback +// +// char * buf - Pointer to data to be written +// unsigned int * size - Number of bytes to write +// void * param - Custom pointer, parameter of implode/explode + +static void WriteOutputData(char * buf, unsigned int * size, void * param) +{ + TDataInfo * pInfo = (TDataInfo *)param; + unsigned int nMaxWrite = (unsigned int)(pInfo->pbOutBuffEnd - pInfo->pbOutBuff); + unsigned int nToWrite = *size; + + // Check the case when not enough space in the output buffer + if(nToWrite > nMaxWrite) + nToWrite = nMaxWrite; + + // Write output data and increments offsets + memcpy(pInfo->pbOutBuff, buf, nToWrite); + pInfo->pbOutBuff += nToWrite; + assert(pInfo->pbOutBuff <= pInfo->pbOutBuffEnd); +} + +static void Compress_PKLIB(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, int * pCmpType, int nCmpLevel) +{ + TDataInfo Info; // Data information + char * work_buf = STORM_ALLOC(char, CMP_BUFFER_SIZE);// Pklib's work buffer + unsigned int dict_size; // Dictionary size + unsigned int ctype = CMP_BINARY; // Compression type + + // Keep compilers happy + STORMLIB_UNUSED(pCmpType); + STORMLIB_UNUSED(nCmpLevel); + + // Handle no-memory condition + if(work_buf != NULL) + { + // Fill data information structure + memset(work_buf, 0, CMP_BUFFER_SIZE); + Info.pbInBuff = (unsigned char *)pvInBuffer; + Info.pbInBuffEnd = (unsigned char *)pvInBuffer + cbInBuffer; + Info.pbOutBuff = (unsigned char *)pvOutBuffer; + Info.pbOutBuffEnd = (unsigned char *)pvOutBuffer + *pcbOutBuffer; + + // + // Set the dictionary size + // + // Diablo I uses fixed dictionary size of CMP_IMPLODE_DICT_SIZE3 + // Starcraft I uses the variable dictionary size based on algorithm below + // + + if (cbInBuffer < 0x600) + dict_size = CMP_IMPLODE_DICT_SIZE1; + else if(0x600 <= cbInBuffer && cbInBuffer < 0xC00) + dict_size = CMP_IMPLODE_DICT_SIZE2; + else + dict_size = CMP_IMPLODE_DICT_SIZE3; + + // Do the compression + if(implode(ReadInputData, WriteOutputData, work_buf, &Info, &ctype, &dict_size) == CMP_NO_ERROR) + *pcbOutBuffer = (int)(Info.pbOutBuff - (unsigned char *)pvOutBuffer); + + STORM_FREE(work_buf); + } +} + +static int Decompress_PKLIB(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + TDataInfo Info; // Data information + char * work_buf; + int nResult = 0; + + // Allocate Pklib's work buffer + if((work_buf = STORM_ALLOC(char, EXP_BUFFER_SIZE)) != NULL) + { + // Fill data information structure + memset(work_buf, 0, EXP_BUFFER_SIZE); + Info.pbInBuff = (unsigned char *)pvInBuffer; + Info.pbInBuffEnd = (unsigned char *)pvInBuffer + cbInBuffer; + Info.pbOutBuff = (unsigned char *)pvOutBuffer; + Info.pbOutBuffEnd = (unsigned char *)pvOutBuffer + *pcbOutBuffer; + + // Do the decompression + if(explode(ReadInputData, WriteOutputData, work_buf, &Info) == CMP_NO_ERROR) + nResult = 1; + + // Give away the number of decompressed bytes + *pcbOutBuffer = (int)(Info.pbOutBuff - (unsigned char *)pvOutBuffer); + STORM_FREE(work_buf); + } + + return nResult; +} + +/******************************************************************************/ +/* */ +/* Support for Bzip2 compression (0x10) */ +/* */ +/******************************************************************************/ + +static void Compress_BZIP2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, int * pCmpType, int nCmpLevel) +{ + bz_stream strm; + int blockSize100k = 9; + int workFactor = 30; + int bzError; + + // Keep compilers happy + STORMLIB_UNUSED(pCmpType); + STORMLIB_UNUSED(nCmpLevel); + + // Initialize the BZIP2 compression + strm.bzalloc = NULL; + strm.bzfree = NULL; + strm.opaque = NULL; + + // Blizzard uses 9 as blockSize100k, (0x30 as workFactor) + // Last checked on Starcraft II + if(BZ2_bzCompressInit(&strm, blockSize100k, 0, workFactor) == BZ_OK) + { + strm.next_in = (char *)pvInBuffer; + strm.avail_in = cbInBuffer; + strm.next_out = (char *)pvOutBuffer; + strm.avail_out = *pcbOutBuffer; + + // Perform the compression + for(;;) + { + bzError = BZ2_bzCompress(&strm, (strm.avail_in != 0) ? BZ_RUN : BZ_FINISH); + if(bzError == BZ_STREAM_END || bzError < 0) + break; + } + + // Put the stream into idle state + BZ2_bzCompressEnd(&strm); + + if(bzError > 0) + *pcbOutBuffer = strm.total_out_lo32; + } +} + +static int Decompress_BZIP2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + bz_stream strm; + int nResult; + + // Initialize the BZIP2 decompression + strm.next_in = (char *)pvInBuffer; + strm.avail_in = cbInBuffer; + strm.next_out = (char *)pvOutBuffer; + strm.avail_out = *pcbOutBuffer; + strm.bzalloc = NULL; + strm.bzfree = NULL; + strm.opaque = NULL; + + // Initialize decompression + if((nResult = BZ2_bzDecompressInit(&strm, 0, 0)) == BZ_OK) + { + // Perform the decompression + nResult = BZ2_bzDecompress(&strm); + *pcbOutBuffer = strm.total_out_lo32; + BZ2_bzDecompressEnd(&strm); + } + + return (nResult >= BZ_OK); +} + +/******************************************************************************/ +/* */ +/* Support functions for LZMA compression (0x12) */ +/* */ +/******************************************************************************/ + +#define LZMA_HEADER_SIZE (1 + LZMA_PROPS_SIZE + 8) + +static SRes LZMA_Callback_Progress(void * /* p */, UInt64 /* inSize */, UInt64 /* outSize */) +{ + return SZ_OK; +} + +static void * LZMA_Callback_Alloc(void *p, size_t size) +{ + p = p; + return STORM_ALLOC(BYTE, size); +} + +/* address can be 0 */ +static void LZMA_Callback_Free(void *p, void *address) +{ + p = p; + if(address != NULL) + STORM_FREE(address); +} + +// +// Note: So far, I haven't seen any files compressed by LZMA. +// This code haven't been verified against code ripped from Starcraft II Beta, +// but we know that Starcraft LZMA decompression code is able to decompress +// the data compressed by StormLib. +// + +static void Compress_LZMA(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, int * pCmpType, int nCmpLevel) +{ + ICompressProgress Progress; + CLzmaEncProps props; + ISzAlloc SzAlloc; + Byte * pbOutBuffer = (Byte *)pvOutBuffer; + Byte * destBuffer; + SizeT destLen = *pcbOutBuffer; + SizeT srcLen = cbInBuffer; + Byte encodedProps[LZMA_PROPS_SIZE]; + size_t encodedPropsSize = LZMA_PROPS_SIZE; + SRes nResult; + + // Keep compilers happy + STORMLIB_UNUSED(pCmpType); + STORMLIB_UNUSED(nCmpLevel); + + // Fill the callbacks in structures + Progress.Progress = LZMA_Callback_Progress; + SzAlloc.Alloc = LZMA_Callback_Alloc; + SzAlloc.Free = LZMA_Callback_Free; + + // Initialize properties + LzmaEncProps_Init(&props); + + // Perform compression + destBuffer = (Byte *)pvOutBuffer + LZMA_HEADER_SIZE; + destLen = *pcbOutBuffer - LZMA_HEADER_SIZE; + nResult = LzmaEncode(destBuffer, + &destLen, + (Byte *)pvInBuffer, + srcLen, + &props, + encodedProps, + &encodedPropsSize, + 0, + &Progress, + &SzAlloc, + &SzAlloc); + if(nResult != SZ_OK) + return; + + // If we failed to compress the data + if(destLen >= (SizeT)(*pcbOutBuffer - LZMA_HEADER_SIZE)) + return; + + // Write "useFilter" variable. Blizzard MPQ must not use filter. + *pbOutBuffer++ = 0; + + // Copy the encoded properties to the output buffer + memcpy(pvOutBuffer, encodedProps, encodedPropsSize); + pbOutBuffer += encodedPropsSize; + + // Copy the size of the data + *pbOutBuffer++ = (unsigned char)(srcLen >> 0x00); + *pbOutBuffer++ = (unsigned char)(srcLen >> 0x08); + *pbOutBuffer++ = (unsigned char)(srcLen >> 0x10); + *pbOutBuffer++ = (unsigned char)(srcLen >> 0x18); + *pbOutBuffer++ = 0; + *pbOutBuffer++ = 0; + *pbOutBuffer++ = 0; + *pbOutBuffer++ = 0; + + // Give the size of the data to the caller + *pcbOutBuffer = (unsigned int)(destLen + LZMA_HEADER_SIZE); +} + +static int Decompress_LZMA(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + ELzmaStatus LzmaStatus; + ISzAlloc SzAlloc; + Byte * destBuffer = (Byte *)pvOutBuffer; + Byte * srcBuffer = (Byte *)pvInBuffer; + SizeT destLen = *pcbOutBuffer; + SizeT srcLen = cbInBuffer; + SRes nResult; + + // There must be at least 0x0E bytes in the buffer + if(srcLen <= LZMA_HEADER_SIZE) + return 0; + + // We only accept blocks that have no filter used + if(*srcBuffer != 0) + return 0; + + // Fill the callbacks in structures + SzAlloc.Alloc = LZMA_Callback_Alloc; + SzAlloc.Free = LZMA_Callback_Free; + + // Perform compression + srcLen = cbInBuffer - LZMA_HEADER_SIZE; + nResult = LzmaDecode(destBuffer, + &destLen, + srcBuffer + LZMA_HEADER_SIZE, + &srcLen, + srcBuffer + 1, + LZMA_PROPS_SIZE, + LZMA_FINISH_END, + &LzmaStatus, + &SzAlloc); + if(nResult != SZ_OK) + return 0; + + *pcbOutBuffer = (unsigned int)destLen; + return 1; +} + +static int Decompress_LZMA_MPK(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + ELzmaStatus LzmaStatus; + ISzAlloc SzAlloc; + Byte * destBuffer = (Byte *)pvOutBuffer; + Byte * srcBuffer = (Byte *)pvInBuffer; + SizeT destLen = *pcbOutBuffer; + SizeT srcLen = cbInBuffer; + SRes nResult; + BYTE LZMA_Props[] = {0x5D, 0x00, 0x00, 0x00, 0x01}; + + // There must be at least 0x0E bytes in the buffer + if(srcLen <= sizeof(LZMA_Props)) + return 0; + + // Verify the props header + if(memcmp(pvInBuffer, LZMA_Props, sizeof(LZMA_Props))) + return 0; + + // Fill the callbacks in structures + SzAlloc.Alloc = LZMA_Callback_Alloc; + SzAlloc.Free = LZMA_Callback_Free; + + // Perform compression + srcLen = cbInBuffer - sizeof(LZMA_Props); + nResult = LzmaDecode(destBuffer, + &destLen, + srcBuffer + sizeof(LZMA_Props), + &srcLen, + srcBuffer, + sizeof(LZMA_Props), + LZMA_FINISH_END, + &LzmaStatus, + &SzAlloc); + if(nResult != SZ_OK) + return 0; + + *pcbOutBuffer = (unsigned int)destLen; + return 1; +} + +/******************************************************************************/ +/* */ +/* Support functions for SPARSE compression (0x20) */ +/* */ +/******************************************************************************/ + +void Compress_SPARSE(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, int * pCmpType, int nCmpLevel) +{ + // Keep compilers happy + STORMLIB_UNUSED(pCmpType); + STORMLIB_UNUSED(nCmpLevel); + + CompressSparse(pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer); +} + +int Decompress_SPARSE(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + return DecompressSparse(pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer); +} + +/******************************************************************************/ +/* */ +/* Support for ADPCM mono compression (0x40) */ +/* */ +/******************************************************************************/ + +static void Compress_ADPCM_mono(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, int * pCmpType, int nCmpLevel) +{ + // Prepare the compression level for Huffmann compression, + // which will be called as next step + if(0 < nCmpLevel && nCmpLevel <= 2) + { + nCmpLevel = 4; + *pCmpType = 6; + } + else if(nCmpLevel == 3) + { + nCmpLevel = 6; + *pCmpType = 8; + } + else + { + nCmpLevel = 5; + *pCmpType = 7; + } + *pcbOutBuffer = CompressADPCM(pvOutBuffer, *pcbOutBuffer, pvInBuffer, cbInBuffer, 1, nCmpLevel); +} + +static int Decompress_ADPCM_mono(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + *pcbOutBuffer = DecompressADPCM(pvOutBuffer, *pcbOutBuffer, pvInBuffer, cbInBuffer, 1); + return 1; +} + +/******************************************************************************/ +/* */ +/* Support for ADPCM stereo compression (0x80) */ +/* */ +/******************************************************************************/ + +static void Compress_ADPCM_stereo(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, int * pCmpType, int nCmpLevel) +{ + // Prepare the compression level for Huffmann compression, + // which will be called as next step + if(0 < nCmpLevel && nCmpLevel <= 2) + { + nCmpLevel = 4; + *pCmpType = 6; + } + else if(nCmpLevel == 3) + { + nCmpLevel = 6; + *pCmpType = 8; + } + else + { + nCmpLevel = 5; + *pCmpType = 7; + } + *pcbOutBuffer = CompressADPCM(pvOutBuffer, *pcbOutBuffer, pvInBuffer, cbInBuffer, 2, nCmpLevel); +} + +static int Decompress_ADPCM_stereo(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + *pcbOutBuffer = DecompressADPCM(pvOutBuffer, *pcbOutBuffer, pvInBuffer, cbInBuffer, 2); + return 1; +} + +/*****************************************************************************/ +/* */ +/* SCompImplode */ +/* */ +/*****************************************************************************/ + +int WINAPI SCompImplode(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + int cbOutBuffer; + + // Check for valid parameters + if(!pcbOutBuffer || *pcbOutBuffer < cbInBuffer || !pvOutBuffer || !pvInBuffer) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + // Perform the compression + cbOutBuffer = *pcbOutBuffer; + Compress_PKLIB(pvOutBuffer, &cbOutBuffer, pvInBuffer, cbInBuffer, NULL, 0); + + // If the compression was unsuccessful, copy the data as-is + if(cbOutBuffer >= *pcbOutBuffer) + { + memcpy(pvOutBuffer, pvInBuffer, cbInBuffer); + cbOutBuffer = *pcbOutBuffer; + } + + *pcbOutBuffer = cbOutBuffer; + return 1; +} + +/*****************************************************************************/ +/* */ +/* SCompExplode */ +/* */ +/*****************************************************************************/ + +int WINAPI SCompExplode(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + int cbOutBuffer; + + // Check for valid parameters + if(!pcbOutBuffer || *pcbOutBuffer < cbInBuffer || !pvOutBuffer || !pvInBuffer) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + // If the input length is the same as output length, do nothing. + cbOutBuffer = *pcbOutBuffer; + if(cbInBuffer == cbOutBuffer) + { + // If the buffers are equal, don't copy anything. + if(pvInBuffer == pvOutBuffer) + return 1; + + memcpy(pvOutBuffer, pvInBuffer, cbInBuffer); + return 1; + } + + // Perform decompression + if(!Decompress_PKLIB(pvOutBuffer, &cbOutBuffer, pvInBuffer, cbInBuffer)) + { + SetLastError(ERROR_FILE_CORRUPT); + return 0; + } + + *pcbOutBuffer = cbOutBuffer; + return 1; +} + +/*****************************************************************************/ +/* */ +/* SCompCompress */ +/* */ +/*****************************************************************************/ + +// This table contains compress functions which can be applied to +// uncompressed data. Each bit means the corresponding +// compression method/function must be applied. +// +// WAVes compression Data compression +// ------------------ ------------------- +// 1st sector - 0x08 0x08 (D, HF, W2, SC, D2) +// Next sectors - 0x81 0x02 (W3) + +static TCompressTable cmp_table[] = +{ + {MPQ_COMPRESSION_SPARSE, Compress_SPARSE}, // Sparse compression + {MPQ_COMPRESSION_ADPCM_MONO, Compress_ADPCM_mono}, // IMA ADPCM mono compression + {MPQ_COMPRESSION_ADPCM_STEREO, Compress_ADPCM_stereo}, // IMA ADPCM stereo compression + {MPQ_COMPRESSION_HUFFMANN, Compress_huff}, // Huffmann compression + {MPQ_COMPRESSION_ZLIB, Compress_ZLIB}, // Compression with the "zlib" library + {MPQ_COMPRESSION_PKWARE, Compress_PKLIB}, // Compression with Pkware DCL + {MPQ_COMPRESSION_BZIP2, Compress_BZIP2} // Compression Bzip2 library +}; + +int WINAPI SCompCompress(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, unsigned uCompressionMask, int nCmpType, int nCmpLevel) +{ + COMPRESS CompressFuncArray[0x10]; // Array of compression functions, applied sequentially + unsigned char CompressByte[0x10]; // CompressByte for each method in the CompressFuncArray array + unsigned char * pbWorkBuffer = NULL; // Temporary storage for decompressed data + unsigned char * pbOutBuffer = (unsigned char *)pvOutBuffer; + unsigned char * pbOutput = (unsigned char *)pvOutBuffer;// Current output buffer + unsigned char * pbInput = (unsigned char *)pvInBuffer; // Current input buffer + int nCompressCount = 0; + int nCompressIndex = 0; + int nAtLeastOneCompressionDone = 0; + int cbOutBuffer = 0; + int cbInLength = cbInBuffer; + int nResult = 1; + + // Check for valid parameters + if(!pcbOutBuffer || *pcbOutBuffer < cbInBuffer || !pvOutBuffer || !pvInBuffer) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + // Zero input length brings zero output length + if(cbInBuffer == 0) + { + *pcbOutBuffer = 0; + return true; + } + + // Setup the compression function array + if(uCompressionMask == MPQ_COMPRESSION_LZMA) + { + CompressFuncArray[0] = Compress_LZMA; + CompressByte[0] = (char)uCompressionMask; + nCompressCount = 1; + } + else + { + // Fill the compressions array + for(size_t i = 0; i < (sizeof(cmp_table) / sizeof(TCompressTable)); i++) + { + // If the mask agrees, insert the compression function to the array + if(uCompressionMask & cmp_table[i].uMask) + { + CompressFuncArray[nCompressCount] = cmp_table[i].Compress; + CompressByte[nCompressCount] = (unsigned char)cmp_table[i].uMask; + uCompressionMask &= ~cmp_table[i].uMask; + nCompressCount++; + } + } + + // If at least one of the compressions remaing unknown, return an error + if(uCompressionMask != 0) + { + SetLastError(ERROR_NOT_SUPPORTED); + return 0; + } + } + + // If there is at least one compression, do it + if(nCompressCount > 0) + { + // If we need to do more than 1 compression, allocate intermediate buffer + if(nCompressCount > 1) + { + pbWorkBuffer = STORM_ALLOC(unsigned char, *pcbOutBuffer); + if(pbWorkBuffer == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + } + + // Get the current compression index + nCompressIndex = nCompressCount - 1; + + // Perform all compressions in the array + for(int i = 0; i < nCompressCount; i++) + { + // Choose the proper output buffer + pbOutput = (nCompressIndex & 1) ? pbWorkBuffer : pbOutBuffer; + nCompressIndex--; + + // Perform the (next) compression + // Note that if the compression method is unable to compress the input data block + // by at least 2 bytes, we consider it as failure and will use source data instead + cbOutBuffer = *pcbOutBuffer - 1; + CompressFuncArray[i](pbOutput + 1, &cbOutBuffer, pbInput, cbInLength, &nCmpType, nCmpLevel); + + // If the compression failed, we copy the input buffer as-is. + // Note that there is one extra byte at the end of the intermediate buffer, so it should be OK + if(cbOutBuffer > (cbInLength - 2)) + { + memcpy(pbOutput + nAtLeastOneCompressionDone, pbInput, cbInLength); + cbOutBuffer = cbInLength; + } + else + { + // Remember that we have done at least one compression + nAtLeastOneCompressionDone = 1; + uCompressionMask |= CompressByte[i]; + } + + // Now point input buffer to the output buffer + pbInput = pbOutput + nAtLeastOneCompressionDone; + cbInLength = cbOutBuffer; + } + + // If at least one compression succeeded, put the compression + // mask to the begin of the output buffer + if(nAtLeastOneCompressionDone) + *pbOutBuffer = (unsigned char)uCompressionMask; + *pcbOutBuffer = cbOutBuffer + nAtLeastOneCompressionDone; + } + else + { + memcpy(pvOutBuffer, pvInBuffer, cbInBuffer); + *pcbOutBuffer = cbInBuffer; + } + + // Cleanup and return + if(pbWorkBuffer != NULL) + STORM_FREE(pbWorkBuffer); + return nResult; +} + +/*****************************************************************************/ +/* */ +/* SCompDecompress */ +/* */ +/*****************************************************************************/ + +// This table contains decompress functions which can be applied to +// uncompressed data. The compression mask is stored in the first byte +// of compressed data +static TDecompressTable dcmp_table[] = +{ + {MPQ_COMPRESSION_BZIP2, Decompress_BZIP2}, // Decompression with Bzip2 library + {MPQ_COMPRESSION_PKWARE, Decompress_PKLIB}, // Decompression with Pkware Data Compression Library + {MPQ_COMPRESSION_ZLIB, Decompress_ZLIB}, // Decompression with the "zlib" library + {MPQ_COMPRESSION_HUFFMANN, Decompress_huff}, // Huffmann decompression + {MPQ_COMPRESSION_ADPCM_STEREO, Decompress_ADPCM_stereo}, // IMA ADPCM stereo decompression + {MPQ_COMPRESSION_ADPCM_MONO, Decompress_ADPCM_mono}, // IMA ADPCM mono decompression + {MPQ_COMPRESSION_SPARSE, Decompress_SPARSE} // Sparse decompression +}; + +int WINAPI SCompDecompress(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + unsigned char * pbWorkBuffer = NULL; + unsigned char * pbOutBuffer = (unsigned char *)pvOutBuffer; + unsigned char * pbInBuffer = (unsigned char *)pvInBuffer; + unsigned char * pbOutput = (unsigned char *)pvOutBuffer; + unsigned char * pbInput; + unsigned uCompressionMask; // Decompressions applied to the data + unsigned uCompressionCopy; // Decompressions applied to the data + int cbOutBuffer = *pcbOutBuffer; // Current size of the output buffer + int cbInLength; // Current size of the input buffer + int nCompressCount = 0; // Number of compressions to be applied + int nCompressIndex = 0; + int nResult = 1; + + // Verify buffer sizes + if(cbOutBuffer < cbInBuffer || cbInBuffer < 1) + return 0; + + // If the input length is the same as output length, do nothing. + if(cbOutBuffer == cbInBuffer) + { + // If the buffers are equal, don't copy anything. + if(pvInBuffer != pvOutBuffer) + memcpy(pvOutBuffer, pvInBuffer, cbInBuffer); + return 1; + } + + // Get applied compression types and decrement data length + uCompressionMask = uCompressionCopy = (unsigned char)*pbInBuffer++; + cbInBuffer--; + + // Get current compressed data and length of it + pbInput = pbInBuffer; + cbInLength = cbInBuffer; + + // This compression function doesn't support LZMA + assert(uCompressionMask != MPQ_COMPRESSION_LZMA); + + // Parse the compression mask + for(size_t i = 0; i < (sizeof(dcmp_table) / sizeof(TDecompressTable)); i++) + { + // If the mask agrees, insert the compression function to the array + if(uCompressionMask & dcmp_table[i].uMask) + { + uCompressionCopy &= ~dcmp_table[i].uMask; + nCompressCount++; + } + } + + // If at least one of the compressions remaing unknown, return an error + if(nCompressCount == 0 || uCompressionCopy != 0) + { + SetLastError(ERROR_NOT_SUPPORTED); + return 0; + } + + // If there is more than one compression, we have to allocate extra buffer + if(nCompressCount > 1) + { + pbWorkBuffer = STORM_ALLOC(unsigned char, cbOutBuffer); + if(pbWorkBuffer == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + } + + // Get the current compression index + nCompressIndex = nCompressCount - 1; + + // Apply all decompressions + for(size_t i = 0; i < (sizeof(dcmp_table) / sizeof(TDecompressTable)); i++) + { + // Perform the (next) decompression + if(uCompressionMask & dcmp_table[i].uMask) + { + // Get the correct output buffer + pbOutput = (nCompressIndex & 1) ? pbWorkBuffer : pbOutBuffer; + nCompressIndex--; + + // Perform the decompression + cbOutBuffer = *pcbOutBuffer; + nResult = dcmp_table[i].Decompress(pbOutput, &cbOutBuffer, pbInput, cbInLength); + if(nResult == 0 || cbOutBuffer == 0) + { + SetLastError(ERROR_FILE_CORRUPT); + nResult = 0; + break; + } + + // Switch buffers + cbInLength = cbOutBuffer; + pbInput = pbOutput; + } + } + + // Put the length of the decompressed data to the output buffer + *pcbOutBuffer = cbOutBuffer; + + // Cleanup and return + if(pbWorkBuffer != NULL) + STORM_FREE(pbWorkBuffer); + return nResult; +} + +int WINAPI SCompDecompress2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + DECOMPRESS pfnDecompress1 = NULL; + DECOMPRESS pfnDecompress2 = NULL; + unsigned char * pbWorkBuffer = (unsigned char *)pvOutBuffer; + unsigned char * pbInBuffer = (unsigned char *)pvInBuffer; + int cbWorkBuffer = *pcbOutBuffer; + int nResult; + char CompressionMethod; + + // Verify buffer sizes + if(*pcbOutBuffer < cbInBuffer || cbInBuffer < 1) + return 0; + + // If the outputbuffer is as big as input buffer, just copy the block + if(*pcbOutBuffer == cbInBuffer) + { + if(pvOutBuffer != pvInBuffer) + memcpy(pvOutBuffer, pvInBuffer, cbInBuffer); + return 1; + } + + // Get the compression methods + CompressionMethod = *pbInBuffer++; + cbInBuffer--; + + // We only recognize a fixed set of compression methods + switch((unsigned char)CompressionMethod) + { + case MPQ_COMPRESSION_ZLIB: + pfnDecompress1 = Decompress_ZLIB; + break; + + case MPQ_COMPRESSION_PKWARE: + pfnDecompress1 = Decompress_PKLIB; + break; + + case MPQ_COMPRESSION_BZIP2: + pfnDecompress1 = Decompress_BZIP2; + break; + + case MPQ_COMPRESSION_LZMA: + pfnDecompress1 = Decompress_LZMA; + break; + + case MPQ_COMPRESSION_SPARSE: + pfnDecompress1 = Decompress_SPARSE; + break; + + case (MPQ_COMPRESSION_SPARSE | MPQ_COMPRESSION_ZLIB): + pfnDecompress1 = Decompress_ZLIB; + pfnDecompress2 = Decompress_SPARSE; + break; + + case (MPQ_COMPRESSION_SPARSE | MPQ_COMPRESSION_BZIP2): + pfnDecompress1 = Decompress_BZIP2; + pfnDecompress2 = Decompress_SPARSE; + break; + + // + // Note: Any combination including MPQ_COMPRESSION_ADPCM_MONO, + // MPQ_COMPRESSION_ADPCM_STEREO or MPQ_COMPRESSION_HUFFMANN + // is not supported by newer MPQs. + // + + case (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_HUFFMANN): + pfnDecompress1 = Decompress_huff; + pfnDecompress2 = Decompress_ADPCM_mono; + break; + + case (MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN): + pfnDecompress1 = Decompress_huff; + pfnDecompress2 = Decompress_ADPCM_stereo; + break; + + default: + SetLastError(ERROR_FILE_CORRUPT); + return 0; + } + + // If we have to use two decompressions, allocate temporary buffer + if(pfnDecompress2 != NULL) + { + pbWorkBuffer = STORM_ALLOC(unsigned char, *pcbOutBuffer); + if(pbWorkBuffer == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + } + + // Apply the first decompression method + nResult = pfnDecompress1(pbWorkBuffer, &cbWorkBuffer, pbInBuffer, cbInBuffer); + + // Apply the second decompression method, if any + if(pfnDecompress2 != NULL && nResult != 0) + { + cbInBuffer = cbWorkBuffer; + cbWorkBuffer = *pcbOutBuffer; + nResult = pfnDecompress2(pvOutBuffer, &cbWorkBuffer, pbWorkBuffer, cbInBuffer); + } + + // Supply the output buffer size + *pcbOutBuffer = cbWorkBuffer; + + // Free temporary buffer + if(pbWorkBuffer != pvOutBuffer) + STORM_FREE(pbWorkBuffer); + + if(nResult == 0) + SetLastError(ERROR_FILE_CORRUPT); + return nResult; +} + +/*****************************************************************************/ +/* */ +/* File decompression for MPK archives */ +/* */ +/*****************************************************************************/ + +int SCompDecompressMpk(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + return Decompress_LZMA_MPK(pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer); +} + diff --git a/StormLib/src/SFileAddFile.cpp b/StormLib/src/SFileAddFile.cpp new file mode 100644 index 000000000..1f7156e99 --- /dev/null +++ b/StormLib/src/SFileAddFile.cpp @@ -0,0 +1,1316 @@ +/*****************************************************************************/ +/* SFileAddFile.cpp Copyright (c) Ladislav Zezula 2010 */ +/*---------------------------------------------------------------------------*/ +/* MPQ Editing functions */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 27.03.10 1.00 Lad Splitted from SFileCreateArchiveEx.cpp */ +/* 21.04.13 1.01 Dea AddFile callback now part of TMPQArchive */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" + +//----------------------------------------------------------------------------- +// Local variables + +// Mask for lossy compressions +#define MPQ_LOSSY_COMPRESSION_MASK (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN) + +// Data compression for SFileAddFile +// Kept here for compatibility with code that was created with StormLib version < 6.50 +static DWORD DefaultDataCompression = MPQ_COMPRESSION_PKWARE; + +//----------------------------------------------------------------------------- +// WAVE verification + +#define FILE_SIGNATURE_RIFF 0x46464952 +#define FILE_SIGNATURE_WAVE 0x45564157 +#define FILE_SIGNATURE_FMT 0x20746D66 +#define AUDIO_FORMAT_PCM 1 + +typedef struct _WAVE_FILE_HEADER +{ + DWORD dwChunkId; // 0x52494646 ("RIFF") + DWORD dwChunkSize; // Size of that chunk, in bytes + DWORD dwFormat; // Must be 0x57415645 ("WAVE") + + // Format sub-chunk + DWORD dwSubChunk1Id; // 0x666d7420 ("fmt ") + DWORD dwSubChunk1Size; // 0x16 for PCM + USHORT wAudioFormat; // 1 = PCM. Other value means some sort of compression + USHORT wChannels; // Number of channels + DWORD dwSampleRate; // 8000, 44100, etc. + DWORD dwBytesRate; // SampleRate * NumChannels * BitsPerSample/8 + USHORT wBlockAlign; // NumChannels * BitsPerSample/8 + USHORT wBitsPerSample; // 8 bits = 8, 16 bits = 16, etc. + + // Followed by "data" sub-chunk (we don't care) +} WAVE_FILE_HEADER, *PWAVE_FILE_HEADER; + +static bool IsWaveFile_16BitsPerAdpcmSample( + LPBYTE pbFileData, + DWORD cbFileData, + LPDWORD pdwChannels) +{ + PWAVE_FILE_HEADER pWaveHdr = (PWAVE_FILE_HEADER)pbFileData; + + // The amount of file data must be at least size of WAVE header + if(cbFileData > sizeof(WAVE_FILE_HEADER)) + { + // Check for the RIFF header + if(pWaveHdr->dwChunkId == FILE_SIGNATURE_RIFF && pWaveHdr->dwFormat == FILE_SIGNATURE_WAVE) + { + // Check for ADPCM format + if(pWaveHdr->dwSubChunk1Id == FILE_SIGNATURE_FMT && pWaveHdr->wAudioFormat == AUDIO_FORMAT_PCM) + { + // Now the number of bits per sample must be at least 16. + // If not, the WAVE file gets corrupted by the ADPCM compression + if(pWaveHdr->wBitsPerSample >= 0x10) + { + *pdwChannels = pWaveHdr->wChannels; + return true; + } + } + } + } + + return false; +} + +static int FillWritableHandle( + TMPQArchive * ha, + TMPQFile * hf, + ULONGLONG FileTime, + DWORD dwFileSize, + DWORD dwFlags) +{ + TFileEntry * pFileEntry = hf->pFileEntry; + + // Initialize the hash entry for the file + hf->RawFilePos = ha->MpqPos + hf->MpqFilePos; + hf->dwDataSize = dwFileSize; + + // Initialize the block table entry for the file + pFileEntry->ByteOffset = hf->MpqFilePos; + pFileEntry->dwFileSize = dwFileSize; + pFileEntry->dwCmpSize = 0; + pFileEntry->dwFlags = dwFlags | MPQ_FILE_EXISTS; + + // Initialize the file time, CRC32 and MD5 + assert(sizeof(hf->hctx) >= sizeof(hash_state)); + memset(pFileEntry->md5, 0, MD5_DIGEST_SIZE); + md5_init((hash_state *)hf->hctx); + pFileEntry->dwCrc32 = crc32(0, Z_NULL, 0); + + // If the caller gave us a file time, use it. + pFileEntry->FileTime = FileTime; + + // Mark the archive as modified + ha->dwFlags |= MPQ_FLAG_CHANGED; + + // Call the callback, if needed + if(ha->pfnAddFileCB != NULL) + ha->pfnAddFileCB(ha->pvAddFileUserData, 0, hf->dwDataSize, false); + hf->dwAddFileError = ERROR_SUCCESS; + + return ERROR_SUCCESS; +} + +//----------------------------------------------------------------------------- +// MPQ write data functions + +static DWORD WriteDataToMpqFile( + TMPQArchive * ha, + TMPQFile * hf, + LPBYTE pbFileData, + DWORD dwDataSize, + DWORD dwCompression) +{ + TFileEntry * pFileEntry = hf->pFileEntry; + ULONGLONG ByteOffset; + LPBYTE pbCompressed = NULL; // Compressed (target) data + LPBYTE pbToWrite = hf->pbFileSector; // Data to write to the file + DWORD dwErrCode = ERROR_SUCCESS; + int nCompressionLevel; // ADPCM compression level (only used for wave files) + + // Make sure that the caller won't overrun the previously initiated file size + assert(hf->dwFilePos + dwDataSize <= pFileEntry->dwFileSize); + assert(hf->dwSectorCount != 0); + assert(hf->pbFileSector != NULL); + if((hf->dwFilePos + dwDataSize) > pFileEntry->dwFileSize) + return ERROR_DISK_FULL; + + // Now write all data to the file sector buffer + if(dwErrCode == ERROR_SUCCESS) + { + DWORD dwBytesInSector = hf->dwFilePos % hf->dwSectorSize; + DWORD dwSectorIndex = hf->dwFilePos / hf->dwSectorSize; + DWORD dwBytesToCopy; + + // Process all data. + while(dwDataSize != 0) + { + dwBytesToCopy = dwDataSize; + + // Check for sector overflow + if(dwBytesToCopy > (hf->dwSectorSize - dwBytesInSector)) + dwBytesToCopy = (hf->dwSectorSize - dwBytesInSector); + + // Copy the data to the file sector + memcpy(hf->pbFileSector + dwBytesInSector, pbFileData, dwBytesToCopy); + dwBytesInSector += dwBytesToCopy; + pbFileData += dwBytesToCopy; + dwDataSize -= dwBytesToCopy; + + // Update the file position + hf->dwFilePos += dwBytesToCopy; + + // If the current sector is full, or if the file is already full, + // then write the data to the MPQ + if(dwBytesInSector >= hf->dwSectorSize || hf->dwFilePos >= pFileEntry->dwFileSize) + { + // Set the position in the file + ByteOffset = hf->RawFilePos + pFileEntry->dwCmpSize; + + // Update CRC32 and MD5 of the file + md5_process((hash_state *)hf->hctx, hf->pbFileSector, dwBytesInSector); + hf->dwCrc32 = crc32(hf->dwCrc32, hf->pbFileSector, dwBytesInSector); + + // Compress the file sector, if needed + if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) + { + int nOutBuffer = (int)dwBytesInSector; + int nInBuffer = (int)dwBytesInSector; + + // If the file is compressed, allocate buffer for the compressed data. + // Note that we allocate buffer that is a bit longer than sector size, + // for case if the compression method performs a buffer overrun + if(pbCompressed == NULL) + { + pbToWrite = pbCompressed = STORM_ALLOC(BYTE, hf->dwSectorSize + 0x100); + if(pbCompressed == NULL) + { + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + break; + } + } + + // + // Note that both SCompImplode and SCompCompress copy data as-is, + // if they are unable to compress the data. + // + + if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE) + { + SCompImplode(pbCompressed, &nOutBuffer, hf->pbFileSector, nInBuffer); + } + + if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS) + { + // If this is the first sector, we need to override the given compression + // by the first sector compression. This is because the entire sector must + // be compressed by the same compression. + // + // Test case: + // + // WRITE_FILE(hFile, pvBuffer, 0x10, MPQ_COMPRESSION_PKWARE) // Write 0x10 bytes (sector 0) + // WRITE_FILE(hFile, pvBuffer, 0x10, MPQ_COMPRESSION_ADPCM_MONO) // Write 0x10 bytes (still sector 0) + // WRITE_FILE(hFile, pvBuffer, 0x10, MPQ_COMPRESSION_ADPCM_MONO) // Write 0x10 bytes (still sector 0) + // WRITE_FILE(hFile, pvBuffer, 0x10, MPQ_COMPRESSION_ADPCM_MONO) // Write 0x10 bytes (still sector 0) + dwCompression = (dwSectorIndex == 0) ? hf->dwCompression0 : dwCompression; + + // If the caller wants ADPCM compression, we will set wave compression level to 4, + // which corresponds to medium quality + nCompressionLevel = (dwCompression & MPQ_LOSSY_COMPRESSION_MASK) ? 4 : -1; + SCompCompress(pbCompressed, &nOutBuffer, hf->pbFileSector, nInBuffer, (unsigned)dwCompression, 0, nCompressionLevel); + } + + // Update sector positions + dwBytesInSector = nOutBuffer; + if(hf->SectorOffsets != NULL) + hf->SectorOffsets[dwSectorIndex+1] = hf->SectorOffsets[dwSectorIndex] + dwBytesInSector; + + // We have to calculate sector CRC, if enabled + if(hf->SectorChksums != NULL) + hf->SectorChksums[dwSectorIndex] = adler32(0, pbCompressed, nOutBuffer); + } + + // Encrypt the sector, if necessary + if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) + { + BSWAP_ARRAY32_UNSIGNED(pbToWrite, dwBytesInSector); + EncryptMpqBlock(pbToWrite, dwBytesInSector, hf->dwFileKey + dwSectorIndex); + BSWAP_ARRAY32_UNSIGNED(pbToWrite, dwBytesInSector); + } + + // Write the file sector + if(!FileStream_Write(ha->pStream, &ByteOffset, pbToWrite, dwBytesInSector)) + { + dwErrCode = GetLastError(); + break; + } + + // Call the compact callback, if any + if(ha->pfnAddFileCB != NULL) + ha->pfnAddFileCB(ha->pvAddFileUserData, hf->dwFilePos, hf->dwDataSize, false); + + // Update the compressed file size + pFileEntry->dwCmpSize += dwBytesInSector; + dwBytesInSector = 0; + dwSectorIndex++; + } + } + } + + // Cleanup + if(pbCompressed != NULL) + STORM_FREE(pbCompressed); + return dwErrCode; +} + +//----------------------------------------------------------------------------- +// Recrypts file data for file renaming + +static DWORD RecryptFileData( + TMPQArchive * ha, + TMPQFile * hf, + const char * szFileName, + const char * szNewFileName) +{ + ULONGLONG RawFilePos; + TFileEntry * pFileEntry = hf->pFileEntry; + DWORD dwBytesToRecrypt = pFileEntry->dwCmpSize; + DWORD dwOldKey; + DWORD dwNewKey; + DWORD dwErrCode = ERROR_SUCCESS; + + // The file must be encrypted + assert(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED); + + // File decryption key is calculated from the plain name + szNewFileName = GetPlainFileName(szNewFileName); + szFileName = GetPlainFileName(szFileName); + + // Calculate both file keys + dwOldKey = DecryptFileKey(szFileName, pFileEntry->ByteOffset, pFileEntry->dwFileSize, pFileEntry->dwFlags); + dwNewKey = DecryptFileKey(szNewFileName, pFileEntry->ByteOffset, pFileEntry->dwFileSize, pFileEntry->dwFlags); + + // Incase the keys are equal, don't recrypt the file + if(dwNewKey == dwOldKey) + return ERROR_SUCCESS; + hf->dwFileKey = dwOldKey; + + // Calculate the raw position of the file in the archive + hf->MpqFilePos = pFileEntry->ByteOffset; + hf->RawFilePos = ha->MpqPos + hf->MpqFilePos; + + // Allocate buffer for file transfer + dwErrCode = AllocateSectorBuffer(hf); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + // Also allocate buffer for sector offsets + // Note: Don't load sector checksums, we don't need to recrypt them + dwErrCode = AllocateSectorOffsets(hf, true); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + // If we have sector offsets, recrypt these as well + if(hf->SectorOffsets != NULL) + { + // Allocate secondary buffer for sectors copy + DWORD * SectorOffsetsCopy = STORM_ALLOC(DWORD, hf->SectorOffsets[0] / sizeof(DWORD)); + DWORD dwSectorOffsLen = hf->SectorOffsets[0]; + + if(SectorOffsetsCopy == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // Recrypt the array of sector offsets + memcpy(SectorOffsetsCopy, hf->SectorOffsets, dwSectorOffsLen); + EncryptMpqBlock(SectorOffsetsCopy, dwSectorOffsLen, dwNewKey - 1); + BSWAP_ARRAY32_UNSIGNED(SectorOffsetsCopy, dwSectorOffsLen); + + // Write the recrypted array back + if(!FileStream_Write(ha->pStream, &hf->RawFilePos, SectorOffsetsCopy, dwSectorOffsLen)) + dwErrCode = GetLastError(); + STORM_FREE(SectorOffsetsCopy); + } + + // Now we have to recrypt all file sectors. We do it without + // recompression, because recompression is not necessary in this case + if(dwErrCode == ERROR_SUCCESS) + { + for(DWORD dwSector = 0; dwSector < hf->dwSectorCount; dwSector++) + { + DWORD dwRawDataInSector = hf->dwSectorSize; + DWORD dwRawByteOffset = dwSector * hf->dwSectorSize; + + // Last sector: If there is not enough bytes remaining in the file, cut the raw size + if(dwRawDataInSector > dwBytesToRecrypt) + dwRawDataInSector = dwBytesToRecrypt; + + // Fix the raw data length if the file is compressed + if(hf->SectorOffsets != NULL) + { + dwRawDataInSector = hf->SectorOffsets[dwSector+1] - hf->SectorOffsets[dwSector]; + dwRawByteOffset = hf->SectorOffsets[dwSector]; + } + + // Calculate the raw file offset of the file sector + RawFilePos = CalculateRawSectorOffset(hf, dwRawByteOffset); + + // Read the file sector + if(!FileStream_Read(ha->pStream, &RawFilePos, hf->pbFileSector, dwRawDataInSector)) + { + dwErrCode = GetLastError(); + break; + } + + // If necessary, re-encrypt the sector + // Note: Recompression is not necessary here. Unlike encryption, + // the compression does not depend on the position of the file in MPQ. + BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector); + DecryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwOldKey + dwSector); + EncryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwNewKey + dwSector); + BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector); + + // Write the sector back + if(!FileStream_Write(ha->pStream, &RawFilePos, hf->pbFileSector, dwRawDataInSector)) + { + dwErrCode = GetLastError(); + break; + } + + // Decrement number of bytes remaining + dwBytesToRecrypt -= hf->dwSectorSize; + } + } + + return dwErrCode; +} + +//----------------------------------------------------------------------------- +// Internal support for MPQ modifications + +DWORD SFileAddFile_Init( + TMPQArchive * ha, + const char * szFileName, + ULONGLONG FileTime, + DWORD dwFileSize, + LCID lcLocale, + DWORD dwFlags, + TMPQFile ** phf) +{ + TFileEntry * pFileEntry = NULL; + TMPQFile * hf = NULL; // File structure for newly added file + DWORD dwHashIndex = HASH_ENTRY_FREE; + DWORD dwErrCode = ERROR_SUCCESS; + + // + // Note: This is an internal function so no validity checks are done. + // It is the caller's responsibility to make sure that no invalid + // flags get to this point + // + + // Sestor CRC is not allowed with single unit files + if(dwFlags & MPQ_FILE_SINGLE_UNIT) + dwFlags &= ~MPQ_FILE_SECTOR_CRC; + + // Sector CRC is not allowed if the file is not compressed + if(!(dwFlags & MPQ_FILE_COMPRESS_MASK)) + dwFlags &= ~MPQ_FILE_SECTOR_CRC; + + // Fix Key is not allowed if the file is not enrypted + if(!(dwFlags & MPQ_FILE_ENCRYPTED)) + dwFlags &= ~MPQ_FILE_FIX_KEY; + + // If the MPQ is of version 3.0 or higher, we ignore file locale. + // This is because HET and BET tables have no known support for it + if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_3) + lcLocale = 0; + + // Allocate the TMPQFile entry for newly added file + hf = CreateWritableHandle(ha, dwFileSize); + if(hf == NULL) + return false; + + // Allocate file entry in the MPQ + if(dwErrCode == ERROR_SUCCESS) + { + // Check if the file already exists in the archive + pFileEntry = GetFileEntryExact(ha, szFileName, lcLocale, &dwHashIndex); + if(pFileEntry != NULL) + { + if(dwFlags & MPQ_FILE_REPLACEEXISTING) + InvalidateInternalFiles(ha); + else + dwErrCode = ERROR_ALREADY_EXISTS; + } + else + { + // Attempt to allocate new file entry + pFileEntry = AllocateFileEntry(ha, szFileName, lcLocale, &dwHashIndex); + if(pFileEntry != NULL) + InvalidateInternalFiles(ha); + else + dwErrCode = ERROR_DISK_FULL; + } + + // Set the file entry to the file structure + hf->pFileEntry = pFileEntry; + } + + // Prepare the pointer to hash table entry + if(dwErrCode == ERROR_SUCCESS && ha->pHashTable != NULL && dwHashIndex < ha->pHeader->dwHashTableSize) + { + hf->pHashEntry = ha->pHashTable + dwHashIndex; + hf->pHashEntry->lcLocale = (USHORT)lcLocale; + } + + // Prepare the file key + if(dwErrCode == ERROR_SUCCESS && (dwFlags & MPQ_FILE_ENCRYPTED)) + { + hf->dwFileKey = DecryptFileKey(szFileName, hf->MpqFilePos, dwFileSize, dwFlags); + if(hf->dwFileKey == 0) + dwErrCode = ERROR_UNKNOWN_FILE_KEY; + } + + // Fill the file entry and TMPQFile structure + if(dwErrCode == ERROR_SUCCESS) + { + // At this point, the file name in the file entry must be set + assert(pFileEntry->szFileName != NULL); + assert(_stricmp(pFileEntry->szFileName, szFileName) == 0); + + dwErrCode = FillWritableHandle(ha, hf, FileTime, dwFileSize, dwFlags); + } + + // Free the file handle if failed + if(dwErrCode != ERROR_SUCCESS && hf != NULL) + FreeFileHandle(hf); + + // Give the handle to the caller + *phf = hf; + return dwErrCode; +} + +DWORD SFileAddFile_Init( + TMPQArchive * ha, + TMPQFile * hfSrc, + TMPQFile ** phf) +{ + TFileEntry * pFileEntry = NULL; + TMPQFile * hf = NULL; // File structure for newly added file + ULONGLONG FileTime = hfSrc->pFileEntry->FileTime; + DWORD dwFileSize = hfSrc->pFileEntry->dwFileSize; + DWORD dwFlags = hfSrc->pFileEntry->dwFlags; + DWORD dwErrCode = ERROR_SUCCESS; + + // Allocate the TMPQFile entry for newly added file + hf = CreateWritableHandle(ha, dwFileSize); + if(hf == NULL) + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + + // We need to keep the file entry index the same like in the source archive + // This is because multiple hash table entries can point to the same file entry + if(dwErrCode == ERROR_SUCCESS) + { + // Retrieve the file entry for the target file + pFileEntry = ha->pFileTable + (hfSrc->pFileEntry - hfSrc->ha->pFileTable); + + // Copy all variables except file name + if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0) + { + pFileEntry[0] = hfSrc->pFileEntry[0]; + pFileEntry->szFileName = NULL; + } + else + dwErrCode = ERROR_ALREADY_EXISTS; + + // Set the file entry to the file structure + hf->pFileEntry = pFileEntry; + } + + // Prepare the pointer to hash table entry + if(dwErrCode == ERROR_SUCCESS && ha->pHashTable != NULL && hfSrc->pHashEntry != NULL) + { + hf->dwHashIndex = (DWORD)(hfSrc->pHashEntry - hfSrc->ha->pHashTable); + hf->pHashEntry = ha->pHashTable + hf->dwHashIndex; + } + + // Prepare the file key (copy from source file) + if(dwErrCode == ERROR_SUCCESS && (dwFlags & MPQ_FILE_ENCRYPTED)) + { + hf->dwFileKey = hfSrc->dwFileKey; + if(hf->dwFileKey == 0) + dwErrCode = ERROR_UNKNOWN_FILE_KEY; + } + + // Fill the file entry and TMPQFile structure + if(dwErrCode == ERROR_SUCCESS) + { + dwErrCode = FillWritableHandle(ha, hf, FileTime, dwFileSize, dwFlags); + } + + // Free the file handle if failed + if(dwErrCode != ERROR_SUCCESS && hf != NULL) + FreeFileHandle(hf); + + // Give the handle to the caller + *phf = hf; + return dwErrCode; +} + +DWORD SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD dwCompression) +{ + TMPQArchive * ha; + TFileEntry * pFileEntry; + DWORD dwErrCode = ERROR_SUCCESS; + + // Don't bother if the caller gave us zero size + if(pvData == NULL || dwSize == 0) + return ERROR_SUCCESS; + + // Get pointer to the MPQ archive + pFileEntry = hf->pFileEntry; + ha = hf->ha; + + // Allocate file buffers + if(hf->pbFileSector == NULL) + { + ULONGLONG RawFilePos = hf->RawFilePos; + + // Allocate buffer for file sector + hf->dwAddFileError = dwErrCode = AllocateSectorBuffer(hf); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + // Allocate patch info, if the data is patch + if(hf->pPatchInfo == NULL && IsIncrementalPatchFile(pvData, dwSize, &hf->dwPatchedFileSize)) + { + // Set the MPQ_FILE_PATCH_FILE flag + pFileEntry->dwFlags |= MPQ_FILE_PATCH_FILE; + + // Allocate the patch info + hf->dwAddFileError = dwErrCode = AllocatePatchInfo(hf, false); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + } + + // Allocate sector offsets + if(hf->SectorOffsets == NULL) + { + hf->dwAddFileError = dwErrCode = AllocateSectorOffsets(hf, false); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + } + + // Create array of sector checksums + if(hf->SectorChksums == NULL && (pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC)) + { + hf->dwAddFileError = dwErrCode = AllocateSectorChecksums(hf, false); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + } + + // Pre-save the patch info, if any + if(hf->pPatchInfo != NULL) + { + if(!FileStream_Write(ha->pStream, &RawFilePos, hf->pPatchInfo, hf->pPatchInfo->dwLength)) + dwErrCode = GetLastError(); + + pFileEntry->dwCmpSize += hf->pPatchInfo->dwLength; + RawFilePos += hf->pPatchInfo->dwLength; + } + + // Pre-save the sector offset table, just to reserve space in the file. + // Note that we dont need to swap the sector positions, nor encrypt the table + // at the moment, as it will be written again after writing all file sectors. + if(hf->SectorOffsets != NULL) + { + if(!FileStream_Write(ha->pStream, &RawFilePos, hf->SectorOffsets, hf->SectorOffsets[0])) + dwErrCode = GetLastError(); + + pFileEntry->dwCmpSize += hf->SectorOffsets[0]; + RawFilePos += hf->SectorOffsets[0]; + } + } + + // Write the MPQ data to the file + if(dwErrCode == ERROR_SUCCESS) + { + // Save the first sector compression to the file structure + // Note that the entire first file sector will be compressed + // by compression that was passed to the first call of SFileAddFile_Write + if(hf->dwFilePos == 0) + hf->dwCompression0 = dwCompression; + + // Write the data to the MPQ + dwErrCode = WriteDataToMpqFile(ha, hf, (LPBYTE)pvData, dwSize, dwCompression); + } + + // If it succeeded and we wrote all the file data, + // we need to re-save sector offset table + if(dwErrCode == ERROR_SUCCESS) + { + if(hf->dwFilePos >= pFileEntry->dwFileSize) + { + // Finish calculating CRC32 + pFileEntry->dwCrc32 = hf->dwCrc32; + + // Finish calculating MD5 + md5_done((hash_state *)hf->hctx, pFileEntry->md5); + + // If we also have sector checksums, write them to the file + if(hf->SectorChksums != NULL) + { + dwErrCode = WriteSectorChecksums(hf); + } + + // Now write patch info + if(hf->pPatchInfo != NULL) + { + memcpy(hf->pPatchInfo->md5, pFileEntry->md5, MD5_DIGEST_SIZE); + hf->pPatchInfo->dwDataSize = pFileEntry->dwFileSize; + pFileEntry->dwFileSize = hf->dwPatchedFileSize; + dwErrCode = WritePatchInfo(hf); + } + + // Now write sector offsets to the file + if(hf->SectorOffsets != NULL) + { + dwErrCode = WriteSectorOffsets(hf); + } + + // Write the MD5 hashes of each file chunk, if required + if(ha->pHeader->dwRawChunkSize != 0) + { + dwErrCode = WriteMpqDataMD5(ha->pStream, + ha->MpqPos + pFileEntry->ByteOffset, + hf->pFileEntry->dwCmpSize, + ha->pHeader->dwRawChunkSize); + } + } + } + + // Update the archive size + if((ha->MpqPos + pFileEntry->ByteOffset + pFileEntry->dwCmpSize) > ha->FileSize) + ha->FileSize = ha->MpqPos + pFileEntry->ByteOffset + pFileEntry->dwCmpSize; + + // Store the error code from the Write File operation + hf->dwAddFileError = dwErrCode; + return dwErrCode; +} + +DWORD SFileAddFile_Finish(TMPQFile * hf) +{ + TMPQArchive * ha = hf->ha; + TFileEntry * pFileEntry = hf->pFileEntry; + DWORD dwErrCode = hf->dwAddFileError; + + // If all previous operations succeeded, we can update the MPQ + if(dwErrCode == ERROR_SUCCESS) + { + // Verify if the caller wrote the file properly + if(hf->pPatchInfo == NULL) + { + assert(pFileEntry != NULL); + if(hf->dwFilePos != pFileEntry->dwFileSize) + dwErrCode = ERROR_CAN_NOT_COMPLETE; + } + else + { + if(hf->dwFilePos != hf->pPatchInfo->dwDataSize) + dwErrCode = ERROR_CAN_NOT_COMPLETE; + } + } + + // Now we need to recreate the HET table, if exists + if(dwErrCode == ERROR_SUCCESS && ha->pHetTable != NULL) + { + dwErrCode = RebuildHetTable(ha); + } + + // Update the block table size + if(dwErrCode == ERROR_SUCCESS) + { + // Call the user callback, if any + if(ha->pfnAddFileCB != NULL) + ha->pfnAddFileCB(ha->pvAddFileUserData, hf->dwDataSize, hf->dwDataSize, true); + } + else + { + // Free the file entry in MPQ tables + if(pFileEntry != NULL) + DeleteFileEntry(ha, hf); + } + + // Clear the add file callback + FreeFileHandle(hf); + return dwErrCode; +} + +//----------------------------------------------------------------------------- +// Adds data as file to the archive + +bool WINAPI SFileCreateFile( + HANDLE hMpq, + const char * szArchivedName, + ULONGLONG FileTime, + DWORD dwFileSize, + LCID lcLocale, + DWORD dwFlags, + HANDLE * phFile) +{ + TMPQArchive * ha = (TMPQArchive *)hMpq; + DWORD dwErrCode = ERROR_SUCCESS; + + // Check valid parameters + if(!IsValidMpqHandle(hMpq)) + dwErrCode = ERROR_INVALID_HANDLE; + if(szArchivedName == NULL || *szArchivedName == 0) + dwErrCode = ERROR_INVALID_PARAMETER; + if(phFile == NULL) + dwErrCode = ERROR_INVALID_PARAMETER; + + // Don't allow to add file if the MPQ is open for read only + if(dwErrCode == ERROR_SUCCESS) + { + if(ha->dwFlags & MPQ_FLAG_READ_ONLY) + dwErrCode = ERROR_ACCESS_DENIED; + + // Don't allow to add a file under pseudo-file name + if(IsPseudoFileName(szArchivedName, NULL)) + dwErrCode = ERROR_INVALID_PARAMETER; + + // Don't allow to add any of the internal files + if(IsInternalMpqFileName(szArchivedName)) + dwErrCode = ERROR_INTERNAL_FILE; + } + + // Perform validity check of the MPQ flags + if(dwErrCode == ERROR_SUCCESS) + { + // Mask all unsupported flags out + dwFlags &= (ha->dwFlags & MPQ_FLAG_WAR3_MAP) ? MPQ_FILE_VALID_FLAGS_W3X : MPQ_FILE_VALID_FLAGS; + + // Check for valid flag combinations + if((dwFlags & (MPQ_FILE_IMPLODE | MPQ_FILE_COMPRESS)) == (MPQ_FILE_IMPLODE | MPQ_FILE_COMPRESS)) + dwErrCode = ERROR_INVALID_PARAMETER; + } + + // Initiate the add file operation + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = SFileAddFile_Init(ha, szArchivedName, FileTime, dwFileSize, lcLocale, dwFlags, (TMPQFile **)phFile); + + // Deal with the errors + if(dwErrCode != ERROR_SUCCESS) + SetLastError(dwErrCode); + return (dwErrCode == ERROR_SUCCESS); +} + +bool WINAPI SFileWriteFile( + HANDLE hFile, + const void * pvData, + DWORD dwSize, + DWORD dwCompression) +{ + TMPQFile * hf = (TMPQFile *)hFile; + DWORD dwErrCode = ERROR_SUCCESS; + + // Check the proper parameters + if(!IsValidFileHandle(hFile)) + dwErrCode = ERROR_INVALID_HANDLE; + if(hf->bIsWriteHandle == false) + dwErrCode = ERROR_INVALID_HANDLE; + + // Special checks for single unit files + if(dwErrCode == ERROR_SUCCESS && (hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT)) + { + // + // Note: Blizzard doesn't support single unit files + // that are stored as encrypted or imploded. We will allow them here, + // the calling application must ensure that such flag combination doesn't get here + // + +// if(dwFlags & MPQ_FILE_IMPLODE) +// dwErrCode = ERROR_INVALID_PARAMETER; +// +// if(dwFlags & MPQ_FILE_ENCRYPTED) +// dwErrCode = ERROR_INVALID_PARAMETER; + + // Lossy compression is not allowed on single unit files + if(dwCompression & MPQ_LOSSY_COMPRESSION_MASK) + dwErrCode = ERROR_INVALID_PARAMETER; + } + + + // Write the data to the file + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = SFileAddFile_Write(hf, pvData, dwSize, dwCompression); + + // Deal with errors + if(dwErrCode != ERROR_SUCCESS) + SetLastError(dwErrCode); + return (dwErrCode == ERROR_SUCCESS); +} + +bool WINAPI SFileFinishFile(HANDLE hFile) +{ + TMPQFile * hf = (TMPQFile *)hFile; + DWORD dwErrCode = ERROR_SUCCESS; + + // Check the proper parameters + if(!IsValidFileHandle(hFile)) + dwErrCode = ERROR_INVALID_HANDLE; + if(hf->bIsWriteHandle == false) + dwErrCode = ERROR_INVALID_HANDLE; + + // Finish the file + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = SFileAddFile_Finish(hf); + + // Deal with errors + if(dwErrCode != ERROR_SUCCESS) + SetLastError(dwErrCode); + return (dwErrCode == ERROR_SUCCESS); +} + +//----------------------------------------------------------------------------- +// Adds a file to the archive + +bool WINAPI SFileAddFileEx( + HANDLE hMpq, + const TCHAR * szFileName, + const char * szArchivedName, + DWORD dwFlags, + DWORD dwCompression, // Compression of the first sector + DWORD dwCompressionNext) // Compression of next sectors +{ + ULONGLONG FileSize = 0; + ULONGLONG FileTime = 0; + TFileStream * pStream = NULL; + HANDLE hMpqFile = NULL; + LPBYTE pbFileData = NULL; + DWORD dwBytesRemaining = 0; + DWORD dwBytesToRead; + DWORD dwSectorSize = 0x1000; + DWORD dwChannels = 0; + bool bIsAdpcmCompression = false; + bool bIsFirstSector = true; + DWORD dwErrCode = ERROR_SUCCESS; + + // Check parameters + if(hMpq == NULL || szFileName == NULL || *szFileName == 0) + { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + // Open added file + pStream = FileStream_OpenFile(szFileName, STREAM_FLAG_READ_ONLY | STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE); + if(pStream == NULL) + return false; + + // Files bigger than 4GB cannot be added to MPQ + FileStream_GetTime(pStream, &FileTime); + FileStream_GetSize(pStream, &FileSize); + if(FileSize >> 32) + dwErrCode = ERROR_DISK_FULL; + + // Allocate data buffer for reading from the source file + if(dwErrCode == ERROR_SUCCESS) + { + dwBytesRemaining = (DWORD)FileSize; + pbFileData = STORM_ALLOC(BYTE, dwSectorSize); + if(pbFileData == NULL) + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + + // Deal with various combination of compressions + if(dwErrCode == ERROR_SUCCESS) + { + // When the compression for next blocks is set to default, + // we will copy the compression for the first sector + if(dwCompressionNext == MPQ_COMPRESSION_NEXT_SAME) + dwCompressionNext = dwCompression; + + // If the caller wants ADPCM compression, we make sure + // that the first sector is not compressed with lossy compression + if(dwCompressionNext & (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO)) + { + // The compression of the first file sector must not be ADPCM + // in order not to corrupt the headers + if(dwCompression & (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO)) + dwCompression = MPQ_COMPRESSION_PKWARE; + + // Remove both flag mono and stereo flags. + // They will be re-added according to WAVE type + dwCompressionNext &= ~(MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO); + bIsAdpcmCompression = true; + } + + // Initiate adding file to the MPQ + if(!SFileCreateFile(hMpq, szArchivedName, FileTime, (DWORD)FileSize, g_lcFileLocale, dwFlags, &hMpqFile)) + dwErrCode = GetLastError(); + } + + // Write the file data to the MPQ + while(dwErrCode == ERROR_SUCCESS && dwBytesRemaining != 0) + { + // Get the number of bytes remaining in the source file + dwBytesToRead = dwBytesRemaining; + if(dwBytesToRead > dwSectorSize) + dwBytesToRead = dwSectorSize; + + // Read data from the local file + if(!FileStream_Read(pStream, NULL, pbFileData, dwBytesToRead)) + { + dwErrCode = GetLastError(); + break; + } + + // If the file being added is a WAVE file, we check number of channels + if(bIsFirstSector && bIsAdpcmCompression) + { + // The file must really be a WAVE file with at least 16 bits per sample, + // otherwise the ADPCM compression will corrupt it + if(IsWaveFile_16BitsPerAdpcmSample(pbFileData, dwBytesToRead, &dwChannels)) + { + // Setup the compression of next sectors according to number of channels + dwCompressionNext |= (dwChannels == 1) ? MPQ_COMPRESSION_ADPCM_MONO : MPQ_COMPRESSION_ADPCM_STEREO; + } + else + { + // Setup the compression of next sectors to a lossless compression + dwCompressionNext = (dwCompression & MPQ_LOSSY_COMPRESSION_MASK) ? MPQ_COMPRESSION_PKWARE : dwCompression; + } + + bIsFirstSector = false; + } + + // Add the file sectors to the MPQ + if(!SFileWriteFile(hMpqFile, pbFileData, dwBytesToRead, dwCompression)) + { + dwErrCode = GetLastError(); + break; + } + + // Set the next data compression + dwBytesRemaining -= dwBytesToRead; + dwCompression = dwCompressionNext; + } + + // Finish the file writing + if(hMpqFile != NULL) + { + if(!SFileFinishFile(hMpqFile)) + dwErrCode = GetLastError(); + } + + // Cleanup and exit + if(pbFileData != NULL) + STORM_FREE(pbFileData); + if(pStream != NULL) + FileStream_Close(pStream); + if(dwErrCode != ERROR_SUCCESS) + SetLastError(dwErrCode); + return (dwErrCode == ERROR_SUCCESS); +} + +// Adds a data file into the archive +bool WINAPI SFileAddFile(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags) +{ + return SFileAddFileEx(hMpq, + szFileName, + szArchivedName, + dwFlags, + DefaultDataCompression, + DefaultDataCompression); +} + +// Adds a WAVE file into the archive +bool WINAPI SFileAddWave(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwQuality) +{ + DWORD dwCompression = 0; + + // + // Note to wave compression level: + // The following conversion table applied: + // High quality: WaveCompressionLevel = -1 + // Medium quality: WaveCompressionLevel = 4 + // Low quality: WaveCompressionLevel = 2 + // + // Starcraft files are packed as Mono (0x41) on medium quality. + // Because this compression is not used anymore, our compression functions + // will default to WaveCompressionLevel = 4 when using ADPCM compression + // + + // Convert quality to data compression + switch(dwQuality) + { + case MPQ_WAVE_QUALITY_HIGH: +// WaveCompressionLevel = -1; + dwCompression = MPQ_COMPRESSION_PKWARE; + break; + + case MPQ_WAVE_QUALITY_MEDIUM: +// WaveCompressionLevel = 4; + dwCompression = MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN; + break; + + case MPQ_WAVE_QUALITY_LOW: +// WaveCompressionLevel = 2; + dwCompression = MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN; + break; + } + + return SFileAddFileEx(hMpq, + szFileName, + szArchivedName, + dwFlags, + MPQ_COMPRESSION_PKWARE, // First sector should be compressed as data + dwCompression); // Next sectors should be compressed as WAVE +} + +//----------------------------------------------------------------------------- +// bool SFileRemoveFile(HANDLE hMpq, char * szFileName) +// +// This function removes a file from the archive. +// + +bool WINAPI SFileRemoveFile(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope) +{ + TMPQArchive * ha = IsValidMpqHandle(hMpq); + TMPQFile * hf = NULL; + DWORD dwErrCode = ERROR_SUCCESS; + + // Keep compiler happy + dwSearchScope = dwSearchScope; + + // Check the parameters + if(ha == NULL) + dwErrCode = ERROR_INVALID_HANDLE; + if(szFileName == NULL || *szFileName == 0) + dwErrCode = ERROR_INVALID_PARAMETER; + if(IsInternalMpqFileName(szFileName)) + dwErrCode = ERROR_INTERNAL_FILE; + + // Do not allow to remove files from read-only or patched MPQs + if(dwErrCode == ERROR_SUCCESS) + { + if((ha->dwFlags & MPQ_FLAG_READ_ONLY) || (ha->haPatch != NULL)) + dwErrCode = ERROR_ACCESS_DENIED; + } + + // If all checks have passed, we can delete the file from the MPQ + if(dwErrCode == ERROR_SUCCESS) + { + // Open the file from the MPQ + if(SFileOpenFileEx(hMpq, szFileName, SFILE_OPEN_BASE_FILE, (HANDLE *)&hf)) + { + // Delete the file entry + dwErrCode = DeleteFileEntry(ha, hf); + FreeFileHandle(hf); + } + else + dwErrCode = GetLastError(); + } + + // If the file has been deleted, we need to invalidate + // the internal files and recreate HET table + if(dwErrCode == ERROR_SUCCESS) + { + // Invalidate the entries for internal files + // After we are done with MPQ changes, we need to re-create them anyway + InvalidateInternalFiles(ha); + + // + // Don't rebuild HET table now; the file's flags indicate + // that it's been deleted, which is enough + // + } + + // Resolve error and exit + if(dwErrCode != ERROR_SUCCESS) + SetLastError(dwErrCode); + return (dwErrCode == ERROR_SUCCESS); +} + +// Renames the file within the archive. +bool WINAPI SFileRenameFile(HANDLE hMpq, const char * szFileName, const char * szNewFileName) +{ + TMPQArchive * ha = IsValidMpqHandle(hMpq); + TMPQFile * hf; + DWORD dwErrCode = ERROR_SUCCESS; + + // Test the valid parameters + if(ha == NULL) + dwErrCode = ERROR_INVALID_HANDLE; + if(szFileName == NULL || *szFileName == 0 || szNewFileName == NULL || *szNewFileName == 0) + dwErrCode = ERROR_INVALID_PARAMETER; + if(IsInternalMpqFileName(szFileName) || IsInternalMpqFileName(szNewFileName)) + dwErrCode = ERROR_INTERNAL_FILE; + + // Do not allow to rename files in MPQ open for read only + if(dwErrCode == ERROR_SUCCESS) + { + if(ha->dwFlags & MPQ_FLAG_READ_ONLY) + dwErrCode = ERROR_ACCESS_DENIED; + } + + // Open the new file. If exists, we don't allow rename operation + if(dwErrCode == ERROR_SUCCESS) + { + if(GetFileEntryLocale(ha, szNewFileName, g_lcFileLocale) != NULL) + dwErrCode = ERROR_ALREADY_EXISTS; + } + + // Open the file from the MPQ + if(dwErrCode == ERROR_SUCCESS) + { + // Attempt to open the file + if(SFileOpenFileEx(hMpq, szFileName, SFILE_OPEN_BASE_FILE, (HANDLE *)&hf)) + { + ULONGLONG RawDataOffs; + TFileEntry * pFileEntry = hf->pFileEntry; + + // Invalidate the entries for internal files + InvalidateInternalFiles(ha); + + // Rename the file entry in the table + dwErrCode = RenameFileEntry(ha, hf, szNewFileName); + + // If the file is encrypted, we have to re-crypt the file content + // with the new decryption key + if((dwErrCode == ERROR_SUCCESS) && (pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)) + { + // Recrypt the file data in the MPQ + dwErrCode = RecryptFileData(ha, hf, szFileName, szNewFileName); + + // Update the MD5 of the raw block + if(dwErrCode == ERROR_SUCCESS && ha->pHeader->dwRawChunkSize != 0) + { + RawDataOffs = ha->MpqPos + pFileEntry->ByteOffset; + WriteMpqDataMD5(ha->pStream, + RawDataOffs, + pFileEntry->dwCmpSize, + ha->pHeader->dwRawChunkSize); + } + } + + // Free the file handle + FreeFileHandle(hf); + } + else + { + dwErrCode = GetLastError(); + } + } + + // We also need to rebuild the HET table, if present + if(dwErrCode == ERROR_SUCCESS && ha->pHetTable != NULL) + dwErrCode = RebuildHetTable(ha); + + // Resolve error and exit + if(dwErrCode != ERROR_SUCCESS) + SetLastError(dwErrCode); + return (dwErrCode == ERROR_SUCCESS); +} + +//----------------------------------------------------------------------------- +// Sets default data compression for SFileAddFile + +bool WINAPI SFileSetDataCompression(DWORD DataCompression) +{ + unsigned int uValidMask = (MPQ_COMPRESSION_ZLIB | MPQ_COMPRESSION_PKWARE | MPQ_COMPRESSION_BZIP2 | MPQ_COMPRESSION_SPARSE); + + if((DataCompression & uValidMask) != DataCompression) + { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + DefaultDataCompression = DataCompression; + return true; +} + +//----------------------------------------------------------------------------- +// Changes locale ID of a file + +bool WINAPI SFileSetFileLocale(HANDLE hFile, LCID lcNewLocale) +{ + TMPQArchive * ha; + TFileEntry * pFileEntry; + TMPQFile * hf = IsValidFileHandle(hFile); + + // Invalid handle => do nothing + if(hf == NULL) + { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + // Do not allow to rename files in MPQ open for read only + ha = hf->ha; + if(ha->dwFlags & MPQ_FLAG_READ_ONLY) + { + SetLastError(ERROR_ACCESS_DENIED); + return false; + } + + // Do not allow unnamed access + if(hf->pFileEntry->szFileName == NULL) + { + SetLastError(ERROR_CAN_NOT_COMPLETE); + return false; + } + + // Do not allow to change locale of any internal file + if(IsInternalMpqFileName(hf->pFileEntry->szFileName)) + { + SetLastError(ERROR_INTERNAL_FILE); + return false; + } + + // Do not allow changing file locales if there is no hash table + if(hf->pHashEntry == NULL) + { + SetLastError(ERROR_NOT_SUPPORTED); + return false; + } + + // We have to check if the file+locale is not already there + pFileEntry = GetFileEntryExact(ha, hf->pFileEntry->szFileName, lcNewLocale, NULL); + if(pFileEntry != NULL) + { + SetLastError(ERROR_ALREADY_EXISTS); + return false; + } + + // Update the locale in the hash table entry + hf->pHashEntry->lcLocale = (USHORT)lcNewLocale; + ha->dwFlags |= MPQ_FLAG_CHANGED; + return true; +} + +//----------------------------------------------------------------------------- +// Sets add file callback + +bool WINAPI SFileSetAddFileCallback(HANDLE hMpq, SFILE_ADDFILE_CALLBACK AddFileCB, void * pvUserData) +{ + TMPQArchive * ha = (TMPQArchive *) hMpq; + + if(!IsValidMpqHandle(hMpq)) + { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + ha->pvAddFileUserData = pvUserData; + ha->pfnAddFileCB = AddFileCB; + return true; +} diff --git a/StormLib/src/SFileAttributes.cpp b/StormLib/src/SFileAttributes.cpp new file mode 100644 index 000000000..e43781324 --- /dev/null +++ b/StormLib/src/SFileAttributes.cpp @@ -0,0 +1,570 @@ +/*****************************************************************************/ +/* SAttrFile.cpp Copyright (c) Ladislav Zezula 2007 */ +/*---------------------------------------------------------------------------*/ +/* Description: */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 12.06.04 1.00 Lad The first version of SAttrFile.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" + +//----------------------------------------------------------------------------- +// Local structures + +typedef struct _MPQ_ATTRIBUTES_HEADER +{ + DWORD dwVersion; // Version of the (attributes) file. Must be 100 (0x64) + DWORD dwFlags; // See MPQ_ATTRIBUTE_XXXX + + // Followed by an array of CRC32 + // Followed by an array of file times + // Followed by an array of MD5 + // Followed by an array of patch bits + + // Note: The MD5 in (attributes), if present, is a hash of the entire file. + // In case the file is an incremental patch, it contains MD5 of the file + // after being patched. + +} MPQ_ATTRIBUTES_HEADER, *PMPQ_ATTRIBUTES_HEADER; + +//----------------------------------------------------------------------------- +// Local functions + +static DWORD GetSizeOfAttributesFile(DWORD dwAttrFlags, DWORD dwBlockTableSize) +{ + DWORD cbAttrFile = sizeof(MPQ_ATTRIBUTES_HEADER); + + // Calculate size of the (attributes) file + if(dwAttrFlags & MPQ_ATTRIBUTE_CRC32) + cbAttrFile += dwBlockTableSize * sizeof(DWORD); + if(dwAttrFlags & MPQ_ATTRIBUTE_FILETIME) + cbAttrFile += dwBlockTableSize * sizeof(ULONGLONG); + if(dwAttrFlags & MPQ_ATTRIBUTE_MD5) + cbAttrFile += dwBlockTableSize * MD5_DIGEST_SIZE; + + // The bit array has been created without the last bit belonging to (attributes) + // When the number of files is a multiplier of 8 plus one, then the size of (attributes) + // if 1 byte less than expected. + // Example: wow-update-13164.MPQ: BlockTableSize = 0x62E1, but there's only 0xC5C bytes + if(dwAttrFlags & MPQ_ATTRIBUTE_PATCH_BIT) + cbAttrFile += (dwBlockTableSize + 6) / 8; + + return cbAttrFile; +} + +static DWORD CheckSizeOfAttributesFile(DWORD cbAttrFile, DWORD dwAttrFlags, DWORD dwBlockTableSize) +{ + DWORD cbHeaderSize = sizeof(MPQ_ATTRIBUTES_HEADER); + DWORD cbChecksumSize1 = 0; + DWORD cbChecksumSize2 = 0; + DWORD cbFileTimeSize1 = 0; + DWORD cbFileTimeSize2 = 0; + DWORD cbFileHashSize1 = 0; + DWORD cbFileHashSize2 = 0; + DWORD cbPatchBitSize1 = 0; + DWORD cbPatchBitSize2 = 0; + DWORD cbPatchBitSize3 = 0; + + // + // Various variants with the patch bit + // + // interface.MPQ.part from WoW build 10958 has + // the MPQ_ATTRIBUTE_PATCH_BIT set, but there's an array of DWORDs instead. + // The array is filled with zeros, so we don't know what it should contain + // + // Zenith.SC2MAP has the MPQ_ATTRIBUTE_PATCH_BIT set, but the bit array is missing + // + // Elimination Tournament 2.w3x's (attributes) have one entry less + // + // There may be two variants: Either the (attributes) file has full + // number of entries, or has one entry less + // + + // Get the expected size of CRC32 array + if(dwAttrFlags & MPQ_ATTRIBUTE_CRC32) + { + cbChecksumSize1 += dwBlockTableSize * sizeof(DWORD); + cbChecksumSize2 += cbChecksumSize1 - sizeof(DWORD); + } + + // Get the expected size of FILETIME array + if(dwAttrFlags & MPQ_ATTRIBUTE_FILETIME) + { + cbFileTimeSize1 += dwBlockTableSize * sizeof(ULONGLONG); + cbFileTimeSize2 += cbFileTimeSize1 - sizeof(ULONGLONG); + } + + // Get the expected size of MD5 array + if(dwAttrFlags & MPQ_ATTRIBUTE_MD5) + { + cbFileHashSize1 += dwBlockTableSize * MD5_DIGEST_SIZE; + cbFileHashSize2 += cbFileHashSize1 - MD5_DIGEST_SIZE; + } + + // Get the expected size of patch bit array + if(dwAttrFlags & MPQ_ATTRIBUTE_PATCH_BIT) + { + cbPatchBitSize1 = + cbPatchBitSize2 = ((dwBlockTableSize + 6) / 8); + cbPatchBitSize3 = dwBlockTableSize * sizeof(DWORD); + } + + // Check if the (attributes) file entry count is equal to our file table size + if(cbAttrFile == (cbHeaderSize + cbChecksumSize1 + cbFileTimeSize1 + cbFileHashSize1 + cbPatchBitSize1)) + return dwBlockTableSize; + + // Check if the (attributes) file entry count is equal to our file table size minus one + if(cbAttrFile == (cbHeaderSize + cbChecksumSize2 + cbFileTimeSize2 + cbFileHashSize2 + cbPatchBitSize2)) + return dwBlockTableSize - 1; + + // Zenith.SC2MAP has the MPQ_ATTRIBUTE_PATCH_BIT set, but the bit array is missing + if(cbAttrFile == (cbHeaderSize + cbChecksumSize1 + cbFileTimeSize1 + cbFileHashSize1)) + return dwBlockTableSize; + + // interface.MPQ.part (WoW build 10958) has the MPQ_ATTRIBUTE_PATCH_BIT set + // but there's an array of DWORDs (filled with zeros) instead of array of bits + if(cbAttrFile == (cbHeaderSize + cbChecksumSize1 + cbFileTimeSize1 + cbFileHashSize1 + cbPatchBitSize3)) + return dwBlockTableSize; + +#ifdef __STORMLIB_TEST__ + // Invalid size of the (attributes) file + // Note that many MPQs, especially Warcraft III maps have the size of (attributes) invalid. + // We only perform this check if this is the STORMLIB testprogram itself +// assert(false); +#endif + + return 0; +} + +static DWORD LoadAttributesFile(TMPQArchive * ha, LPBYTE pbAttrFile, DWORD cbAttrFile) +{ + LPBYTE pbAttrFileEnd = pbAttrFile + cbAttrFile; + LPBYTE pbAttrPtr = pbAttrFile; + DWORD dwAttributesEntries = 0; + DWORD i; + + // Load and verify the header + if((pbAttrPtr + sizeof(MPQ_ATTRIBUTES_HEADER)) <= pbAttrFileEnd) + { + PMPQ_ATTRIBUTES_HEADER pAttrHeader = (PMPQ_ATTRIBUTES_HEADER)pbAttrPtr; + + // Verify the header version + BSWAP_ARRAY32_UNSIGNED(pAttrHeader, sizeof(MPQ_ATTRIBUTES_HEADER)); + if(pAttrHeader->dwVersion != MPQ_ATTRIBUTES_V1) + return ERROR_BAD_FORMAT; + + // Verify the flags + if(pAttrHeader->dwFlags & ~MPQ_ATTRIBUTE_ALL) + return ERROR_BAD_FORMAT; + + // Verify whether file size of (attributes) is expected + dwAttributesEntries = CheckSizeOfAttributesFile(cbAttrFile, pAttrHeader->dwFlags, ha->pHeader->dwBlockTableSize); + if(dwAttributesEntries == 0) + return ERROR_BAD_FORMAT; + + ha->dwAttrFlags = pAttrHeader->dwFlags; + pbAttrPtr = (LPBYTE)(pAttrHeader + 1); + } + + // Load the CRC32 (if present) + if(ha->dwAttrFlags & MPQ_ATTRIBUTE_CRC32) + { + LPDWORD ArrayCRC32 = (LPDWORD)pbAttrPtr; + DWORD cbArraySize = dwAttributesEntries * sizeof(DWORD); + + // Verify if there's enough data + if((pbAttrPtr + cbArraySize) > pbAttrFileEnd) + return ERROR_FILE_CORRUPT; + + BSWAP_ARRAY32_UNSIGNED(ArrayCRC32, cbCRC32Size); + for(i = 0; i < dwAttributesEntries; i++) + ha->pFileTable[i].dwCrc32 = ArrayCRC32[i]; + pbAttrPtr += cbArraySize; + } + + // Load the FILETIME (if present) + if(ha->dwAttrFlags & MPQ_ATTRIBUTE_FILETIME) + { + ULONGLONG * ArrayFileTime = (ULONGLONG *)pbAttrPtr; + DWORD cbArraySize = dwAttributesEntries * sizeof(ULONGLONG); + + // Verify if there's enough data + if((pbAttrPtr + cbArraySize) > pbAttrFileEnd) + return ERROR_FILE_CORRUPT; + + BSWAP_ARRAY64_UNSIGNED(ArrayFileTime, cbFileTimeSize); + for(i = 0; i < dwAttributesEntries; i++) + ha->pFileTable[i].FileTime = ArrayFileTime[i]; + pbAttrPtr += cbArraySize; + } + + // Load the MD5 (if present) + if(ha->dwAttrFlags & MPQ_ATTRIBUTE_MD5) + { + LPBYTE ArrayMd5 = pbAttrPtr; + DWORD cbArraySize = dwAttributesEntries * MD5_DIGEST_SIZE; + + // Verify if there's enough data + if((pbAttrPtr + cbArraySize) > pbAttrFileEnd) + return ERROR_FILE_CORRUPT; + + for(i = 0; i < dwAttributesEntries; i++) + { + memcpy(ha->pFileTable[i].md5, ArrayMd5, MD5_DIGEST_SIZE); + ArrayMd5 += MD5_DIGEST_SIZE; + } + pbAttrPtr += cbArraySize; + } + + // Read the patch bit for each file (if present) + if(ha->dwAttrFlags & MPQ_ATTRIBUTE_PATCH_BIT) + { + LPBYTE pbBitArray = pbAttrPtr; + DWORD cbArraySize = (dwAttributesEntries + 7) / 8; + DWORD dwByteIndex = 0; + DWORD dwBitMask = 0x80; + + // Verify if there's enough data + if((pbAttrPtr + cbArraySize) == pbAttrFileEnd) + { + for(i = 0; i < dwAttributesEntries; i++) + { + ha->pFileTable[i].dwFlags |= (pbBitArray[dwByteIndex] & dwBitMask) ? MPQ_FILE_PATCH_FILE : 0; + dwByteIndex += (dwBitMask & 0x01); + dwBitMask = (dwBitMask << 0x07) | (dwBitMask >> 0x01); + } + } + } + + return ERROR_SUCCESS; +} + +static LPBYTE CreateAttributesFile(TMPQArchive * ha, DWORD * pcbAttrFile) +{ + PMPQ_ATTRIBUTES_HEADER pAttrHeader; + TFileEntry * pFileTableEnd = ha->pFileTable + ha->pHeader->dwBlockTableSize; + TFileEntry * pFileEntry; + LPBYTE pbAttrFile; + LPBYTE pbAttrPtr; + size_t cbAttrFile; + + // Check if we need patch bits in the (attributes) file + for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) + { + if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) + { + ha->dwAttrFlags |= MPQ_ATTRIBUTE_PATCH_BIT; + break; + } + } + + // Allocate the buffer for holding the entire (attributes) + // Allocate 1 byte more (See GetSizeOfAttributesFile for more info) + cbAttrFile = GetSizeOfAttributesFile(ha->dwAttrFlags, ha->pHeader->dwBlockTableSize); + pbAttrFile = pbAttrPtr = STORM_ALLOC(BYTE, cbAttrFile + 1); + if(pbAttrFile != NULL) + { + // Make sure it's all zeroed + memset(pbAttrFile, 0, cbAttrFile + 1); + + // Write the header of the (attributes) file + pAttrHeader = (PMPQ_ATTRIBUTES_HEADER)pbAttrPtr; + pAttrHeader->dwVersion = BSWAP_INT32_UNSIGNED(100); + pAttrHeader->dwFlags = BSWAP_INT32_UNSIGNED((ha->dwAttrFlags & MPQ_ATTRIBUTE_ALL)); + pbAttrPtr = (LPBYTE)(pAttrHeader + 1); + + // Write the array of CRC32, if present + if(ha->dwAttrFlags & MPQ_ATTRIBUTE_CRC32) + { + LPDWORD pArrayCRC32 = (LPDWORD)pbAttrPtr; + + // Copy from file table + for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) + *pArrayCRC32++ = BSWAP_INT32_UNSIGNED(pFileEntry->dwCrc32); + + // Update pointer + pbAttrPtr = (LPBYTE)pArrayCRC32; + } + + // Write the array of file time + if(ha->dwAttrFlags & MPQ_ATTRIBUTE_FILETIME) + { + ULONGLONG * pArrayFileTime = (ULONGLONG *)pbAttrPtr; + + // Copy from file table + for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) + *pArrayFileTime++ = BSWAP_INT64_UNSIGNED(pFileEntry->FileTime); + + // Update pointer + pbAttrPtr = (LPBYTE)pArrayFileTime; + } + + // Write the array of MD5s + if(ha->dwAttrFlags & MPQ_ATTRIBUTE_MD5) + { + LPBYTE pbArrayMD5 = pbAttrPtr; + + // Copy from file table + for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) + { + memcpy(pbArrayMD5, pFileEntry->md5, MD5_DIGEST_SIZE); + pbArrayMD5 += MD5_DIGEST_SIZE; + } + + // Update pointer + pbAttrPtr = pbArrayMD5; + } + + // Write the array of patch bits + if(ha->dwAttrFlags & MPQ_ATTRIBUTE_PATCH_BIT) + { + LPBYTE pbBitArray = pbAttrPtr; + DWORD dwByteIndex = 0; + BYTE dwBitMask = 0x80; + + // Copy from file table + for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) + { + // Set the bit, if needed + if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) + pbBitArray[dwByteIndex] |= dwBitMask; + + // Update bit index and bit mask + dwByteIndex += (dwBitMask & 0x01); + dwBitMask = (dwBitMask << 0x07) | (dwBitMask >> 0x01); + } + + // Move past the bit array + pbAttrPtr += (ha->pHeader->dwBlockTableSize + 6) / 8; + } + + // Now we expect that current position matches the estimated size + // Note that if there is 1 extra bit above the byte size, + // the table is actually 1 byte shorter in Blizzard MPQs. See GetSizeOfAttributesFile + assert((size_t)(pbAttrPtr - pbAttrFile) == cbAttrFile); + } + + // Give away the attributes file + if(pcbAttrFile != NULL) + *pcbAttrFile = (DWORD)cbAttrFile; + return pbAttrFile; +} + +//----------------------------------------------------------------------------- +// Public functions (internal use by StormLib) + +DWORD SAttrLoadAttributes(TMPQArchive * ha) +{ + HANDLE hFile = NULL; + LPBYTE pbAttrFile; + DWORD dwBytesRead; + DWORD cbAttrFile = 0; + DWORD dwErrCode = ERROR_FILE_CORRUPT; + + // File table must be initialized + assert(ha->pFileTable != NULL); + assert((ha->dwFlags & MPQ_FLAG_BLOCK_TABLE_CUT) == 0); + + // Don't load the attributes file from malformed Warcraft III maps + if(ha->dwFlags & MPQ_FLAG_MALFORMED) + return ERROR_FILE_CORRUPT; + + // Attempt to open the "(attributes)" file. + if(SFileOpenFileEx((HANDLE)ha, ATTRIBUTES_NAME, SFILE_OPEN_ANY_LOCALE, &hFile)) + { + // Retrieve and check size of the (attributes) file + cbAttrFile = SFileGetFileSize(hFile, NULL); + + // Integer overflow check + if((cbAttrFile + 1) > cbAttrFile) + { + // Size of the (attributes) might be 1 byte less than expected + // See GetSizeOfAttributesFile for more info + pbAttrFile = STORM_ALLOC(BYTE, cbAttrFile + 1); + if(pbAttrFile != NULL) + { + // Set the last byte to 0 in case the size should be 1 byte greater + pbAttrFile[cbAttrFile] = 0; + + // Load the entire file to memory + SFileReadFile(hFile, pbAttrFile, cbAttrFile, &dwBytesRead, NULL); + if(dwBytesRead == cbAttrFile) + dwErrCode = LoadAttributesFile(ha, pbAttrFile, cbAttrFile); + + // Free the buffer + STORM_FREE(pbAttrFile); + } + } + + // Close the attributes file + SFileCloseFile(hFile); + } + + return dwErrCode; +} + +// Saves the (attributes) to the MPQ +DWORD SAttrFileSaveToMpq(TMPQArchive * ha) +{ + TMPQFile * hf = NULL; + LPBYTE pbAttrFile; + DWORD cbAttrFile = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Only save the attributes if we should do so + if(ha->dwFileFlags2 != 0) + { + // At this point, we expect to have at least one reserved entry in the file table + assert(ha->dwFlags & MPQ_FLAG_ATTRIBUTES_NEW); + assert(ha->dwReservedFiles > 0); + + // Create the raw data that is to be written to (attributes) + // Note: Blizzard MPQs have entries for (listfile) and (attributes), + // but they are filled empty + pbAttrFile = CreateAttributesFile(ha, &cbAttrFile); + if(pbAttrFile != NULL) + { + // Determine the real flags for (attributes) + if(ha->dwFileFlags2 == MPQ_FILE_DEFAULT_INTERNAL) + ha->dwFileFlags2 = GetDefaultSpecialFileFlags(cbAttrFile, ha->pHeader->wFormatVersion); + + // Create the attributes file in the MPQ + dwErrCode = SFileAddFile_Init(ha, ATTRIBUTES_NAME, + 0, + cbAttrFile, + LANG_NEUTRAL, + ha->dwFileFlags2 | MPQ_FILE_REPLACEEXISTING, + &hf); + + // Write the attributes file raw data to it + if(dwErrCode == ERROR_SUCCESS) + { + // Write the content of the attributes file to the MPQ + dwErrCode = SFileAddFile_Write(hf, pbAttrFile, cbAttrFile, MPQ_COMPRESSION_ZLIB); + SFileAddFile_Finish(hf); + } + + // Clear the number of reserved files + ha->dwFlags &= ~(MPQ_FLAG_ATTRIBUTES_NEW | MPQ_FLAG_ATTRIBUTES_NONE); + ha->dwReservedFiles--; + + // Free the attributes buffer + STORM_FREE(pbAttrFile); + } + else + { + // If the (attributes) file would be empty, its OK + dwErrCode = (cbAttrFile == 0) ? ERROR_SUCCESS : ERROR_NOT_ENOUGH_MEMORY; + } + } + + return dwErrCode; +} + +//----------------------------------------------------------------------------- +// Public functions + +DWORD WINAPI SFileGetAttributes(HANDLE hMpq) +{ + TMPQArchive * ha = (TMPQArchive *)hMpq; + + // Verify the parameters + if(!IsValidMpqHandle(hMpq)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return SFILE_INVALID_ATTRIBUTES; + } + + return ha->dwAttrFlags; +} + +bool WINAPI SFileSetAttributes(HANDLE hMpq, DWORD dwFlags) +{ + TMPQArchive * ha = (TMPQArchive *)hMpq; + + // Verify the parameters + if(!IsValidMpqHandle(hMpq)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + // Not allowed when the archive is read-only + if(ha->dwFlags & MPQ_FLAG_READ_ONLY) + { + SetLastError(ERROR_ACCESS_DENIED); + return false; + } + + // Set the attributes + InvalidateInternalFiles(ha); + ha->dwAttrFlags = (dwFlags & MPQ_ATTRIBUTE_ALL); + return true; +} + +bool WINAPI SFileUpdateFileAttributes(HANDLE hMpq, const char * szFileName) +{ + hash_state md5_state; + TMPQArchive * ha = (TMPQArchive *)hMpq; + TMPQFile * hf; + BYTE Buffer[0x1000]; + HANDLE hFile = NULL; + DWORD dwTotalBytes = 0; + DWORD dwBytesRead; + DWORD dwCrc32; + + // Verify the parameters + if(!IsValidMpqHandle(ha)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + // Not allowed when the archive is read-only + if(ha->dwFlags & MPQ_FLAG_READ_ONLY) + { + SetLastError(ERROR_ACCESS_DENIED); + return false; + } + + // Attempt to open the file + if(!SFileOpenFileEx(hMpq, szFileName, SFILE_OPEN_BASE_FILE, &hFile)) + return false; + + // Get the file size + hf = (TMPQFile *)hFile; + dwTotalBytes = hf->pFileEntry->dwFileSize; + + // Initialize the CRC32 and MD5 contexts + md5_init(&md5_state); + dwCrc32 = crc32(0, Z_NULL, 0); + + // Go through entire file and calculate both CRC32 and MD5 + while(dwTotalBytes != 0) + { + // Read data from file + SFileReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL); + if(dwBytesRead == 0) + break; + + // Update CRC32 and MD5 + dwCrc32 = crc32(dwCrc32, Buffer, dwBytesRead); + md5_process(&md5_state, Buffer, dwBytesRead); + + // Decrement the total size + dwTotalBytes -= dwBytesRead; + } + + // Update both CRC32 and MD5 + hf->pFileEntry->dwCrc32 = dwCrc32; + md5_done(&md5_state, hf->pFileEntry->md5); + + // Remember that we need to save the MPQ tables + InvalidateInternalFiles(ha); + SFileCloseFile(hFile); + return true; +} diff --git a/StormLib/src/SFileCompactArchive.cpp b/StormLib/src/SFileCompactArchive.cpp new file mode 100644 index 000000000..e6f96a8b4 --- /dev/null +++ b/StormLib/src/SFileCompactArchive.cpp @@ -0,0 +1,654 @@ +/*****************************************************************************/ +/* SFileCompactArchive.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Archive compacting function */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 14.04.03 1.00 Lad Splitted from SFileCreateArchiveEx.cpp */ +/* 19.11.03 1.01 Dan Big endian handling */ +/* 21.04.13 1.02 Dea Compact callback now part of TMPQArchive */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" + +/*****************************************************************************/ +/* Local functions */ +/*****************************************************************************/ + +static DWORD CheckIfAllFilesKnown(TMPQArchive * ha) +{ + TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; + TFileEntry * pFileEntry; + DWORD dwBlockIndex = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Verify the file table + if(dwErrCode == ERROR_SUCCESS) + { + for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++, dwBlockIndex++) + { + // If there is an existing entry in the file table, check its name + if(pFileEntry->dwFlags & MPQ_FILE_EXISTS) + { + // The name must be valid and must not be a pseudo-name + if(pFileEntry->szFileName == NULL || IsPseudoFileName(pFileEntry->szFileName, NULL)) + { + dwErrCode = ERROR_UNKNOWN_FILE_NAMES; + break; + } + } + } + } + + return dwErrCode; +} + +static DWORD CheckIfAllKeysKnown(TMPQArchive * ha, const TCHAR * szListFile, LPDWORD pFileKeys) +{ + TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; + TFileEntry * pFileEntry; + DWORD dwBlockIndex = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Add the listfile to the MPQ + if(szListFile != NULL) + { + // Notify the user + if(ha->pfnCompactCB != NULL) + ha->pfnCompactCB(ha->pvCompactUserData, CCB_CHECKING_FILES, ha->CompactBytesProcessed, ha->CompactTotalBytes); + + dwErrCode = SFileAddListFile((HANDLE)ha, szListFile); + } + + // Verify the file table + if(dwErrCode == ERROR_SUCCESS) + { + for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++, dwBlockIndex++) + { + // If the file exists and it's encrypted + if(pFileEntry->dwFlags & MPQ_FILE_EXISTS) + { + // If we know the name, we decrypt the file key from the file name + if(pFileEntry->szFileName != NULL && !IsPseudoFileName(pFileEntry->szFileName, NULL)) + { + // Give the key to the caller + pFileKeys[dwBlockIndex] = DecryptFileKey(pFileEntry->szFileName, + pFileEntry->ByteOffset, + pFileEntry->dwFileSize, + pFileEntry->dwFlags); + continue; + } + + // We don't know the encryption key of this file, + // thus we cannot compact the file + dwErrCode = ERROR_UNKNOWN_FILE_NAMES; + break; + } + } + } + + return dwErrCode; +} + +static DWORD CopyNonMpqData( + TMPQArchive * ha, + TFileStream * pSrcStream, + TFileStream * pTrgStream, + ULONGLONG & ByteOffset, + ULONGLONG & ByteCount) +{ + ULONGLONG DataSize = ByteCount; + DWORD dwToRead; + char DataBuffer[0x1000]; + DWORD dwErrCode = ERROR_SUCCESS; + + // Copy the data + while(DataSize > 0) + { + // Get the proper size of data + dwToRead = sizeof(DataBuffer); + if(DataSize < dwToRead) + dwToRead = (DWORD)DataSize; + + // Read from the source stream + if(!FileStream_Read(pSrcStream, &ByteOffset, DataBuffer, dwToRead)) + { + dwErrCode = GetLastError(); + break; + } + + // Write to the target stream + if(!FileStream_Write(pTrgStream, NULL, DataBuffer, dwToRead)) + { + dwErrCode = GetLastError(); + break; + } + + // Update the progress + if(ha->pfnCompactCB != NULL) + { + ha->CompactBytesProcessed += dwToRead; + ha->pfnCompactCB(ha->pvCompactUserData, CCB_COPYING_NON_MPQ_DATA, ha->CompactBytesProcessed, ha->CompactTotalBytes); + } + + // Decrement the number of data to be copied + ByteOffset += dwToRead; + DataSize -= dwToRead; + } + + return dwErrCode; +} + +// Copies all file sectors into another archive. +static DWORD CopyMpqFileSectors( + TMPQArchive * ha, + TMPQFile * hf, + TFileStream * pNewStream, + ULONGLONG MpqFilePos) // MPQ file position in the new archive +{ + TFileEntry * pFileEntry = hf->pFileEntry; + ULONGLONG RawFilePos; // Used for calculating sector offset in the old MPQ archive + DWORD dwBytesToCopy = pFileEntry->dwCmpSize; + DWORD dwPatchSize = 0; // Size of patch header + DWORD dwFileKey1 = 0; // File key used for decryption + DWORD dwFileKey2 = 0; // File key used for encryption + DWORD dwCmpSize = 0; // Compressed file size, including patch header + DWORD dwErrCode = ERROR_SUCCESS; + + // Resolve decryption keys. Note that the file key given + // in the TMPQFile structure also includes the key adjustment + if(dwErrCode == ERROR_SUCCESS && (pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)) + { + dwFileKey2 = dwFileKey1 = hf->dwFileKey; + if(pFileEntry->dwFlags & MPQ_FILE_FIX_KEY) + { + dwFileKey2 = (dwFileKey1 ^ pFileEntry->dwFileSize) - (DWORD)pFileEntry->ByteOffset; + dwFileKey2 = (dwFileKey2 + (DWORD)MpqFilePos) ^ pFileEntry->dwFileSize; + } + } + + // If we have to save patch header, do it + if(dwErrCode == ERROR_SUCCESS && hf->pPatchInfo != NULL) + { + BSWAP_ARRAY32_UNSIGNED(hf->pPatchInfo, sizeof(DWORD) * 3); + if(!FileStream_Write(pNewStream, NULL, hf->pPatchInfo, hf->pPatchInfo->dwLength)) + dwErrCode = GetLastError(); + + // Save the size of the patch info + dwPatchSize = hf->pPatchInfo->dwLength; + } + + // If we have to save sector offset table, do it. + if(dwErrCode == ERROR_SUCCESS && hf->SectorOffsets != NULL) + { + DWORD * SectorOffsetsCopy = STORM_ALLOC(DWORD, hf->SectorOffsets[0] / sizeof(DWORD)); + DWORD dwSectorOffsLen = hf->SectorOffsets[0]; + + assert((pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) == 0); + assert(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK); + + if(SectorOffsetsCopy == NULL) + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + + // Encrypt the secondary sector offset table and write it to the target file + if(dwErrCode == ERROR_SUCCESS) + { + memcpy(SectorOffsetsCopy, hf->SectorOffsets, dwSectorOffsLen); + if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) + EncryptMpqBlock(SectorOffsetsCopy, dwSectorOffsLen, dwFileKey2 - 1); + + BSWAP_ARRAY32_UNSIGNED(SectorOffsetsCopy, dwSectorOffsLen); + if(!FileStream_Write(pNewStream, NULL, SectorOffsetsCopy, dwSectorOffsLen)) + dwErrCode = GetLastError(); + + dwBytesToCopy -= dwSectorOffsLen; + dwCmpSize += dwSectorOffsLen; + } + + // Update compact progress + if(ha->pfnCompactCB != NULL) + { + ha->CompactBytesProcessed += dwSectorOffsLen; + ha->pfnCompactCB(ha->pvCompactUserData, CCB_COMPACTING_FILES, ha->CompactBytesProcessed, ha->CompactTotalBytes); + } + + STORM_FREE(SectorOffsetsCopy); + } + + // Now we have to copy all file sectors. We do it without + // recompression, because recompression is not necessary in this case + if(dwErrCode == ERROR_SUCCESS) + { + for(DWORD dwSector = 0; dwSector < hf->dwSectorCount; dwSector++) + { + DWORD dwRawDataInSector = hf->dwSectorSize; + DWORD dwRawByteOffset = dwSector * hf->dwSectorSize; + + // Fix the raw data length if the file is compressed + if(hf->SectorOffsets != NULL) + { + dwRawDataInSector = hf->SectorOffsets[dwSector+1] - hf->SectorOffsets[dwSector]; + dwRawByteOffset = hf->SectorOffsets[dwSector]; + } + + // Last sector: If there is not enough bytes remaining in the file, cut the raw size + if(dwRawDataInSector > dwBytesToCopy) + dwRawDataInSector = dwBytesToCopy; + + // Calculate the raw file offset of the file sector + RawFilePos = CalculateRawSectorOffset(hf, dwRawByteOffset); + + // Read the file sector + if(!FileStream_Read(ha->pStream, &RawFilePos, hf->pbFileSector, dwRawDataInSector)) + { + dwErrCode = GetLastError(); + break; + } + + // If necessary, re-encrypt the sector + // Note: Recompression is not necessary here. Unlike encryption, + // the compression does not depend on the position of the file in MPQ. + if((pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) && dwFileKey1 != dwFileKey2) + { + BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector); + DecryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwFileKey1 + dwSector); + EncryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwFileKey2 + dwSector); + BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector); + } + + // Now write the sector back to the file + if(!FileStream_Write(pNewStream, NULL, hf->pbFileSector, dwRawDataInSector)) + { + dwErrCode = GetLastError(); + break; + } + + // Update compact progress + if(ha->pfnCompactCB != NULL) + { + ha->CompactBytesProcessed += dwRawDataInSector; + ha->pfnCompactCB(ha->pvCompactUserData, CCB_COMPACTING_FILES, ha->CompactBytesProcessed, ha->CompactTotalBytes); + } + + // Adjust byte counts + dwBytesToCopy -= dwRawDataInSector; + dwCmpSize += dwRawDataInSector; + } + } + + // Copy the sector CRCs, if any + // Sector CRCs are always compressed (not imploded) and unencrypted + if(dwErrCode == ERROR_SUCCESS && hf->SectorOffsets != NULL && hf->SectorChksums != NULL) + { + DWORD dwCrcLength; + + dwCrcLength = hf->SectorOffsets[hf->dwSectorCount + 1] - hf->SectorOffsets[hf->dwSectorCount]; + if(dwCrcLength != 0) + { + if(!FileStream_Read(ha->pStream, NULL, hf->SectorChksums, dwCrcLength)) + dwErrCode = GetLastError(); + + if(!FileStream_Write(pNewStream, NULL, hf->SectorChksums, dwCrcLength)) + dwErrCode = GetLastError(); + + // Update compact progress + if(ha->pfnCompactCB != NULL) + { + ha->CompactBytesProcessed += dwCrcLength; + ha->pfnCompactCB(ha->pvCompactUserData, CCB_COMPACTING_FILES, ha->CompactBytesProcessed, ha->CompactTotalBytes); + } + + // Size of the CRC block is also included in the compressed file size + dwBytesToCopy -= dwCrcLength; + dwCmpSize += dwCrcLength; + } + } + + // There might be extra data beyond sector checksum table + // Sometimes, these data are even part of sector offset table + // Examples: + // 2012 - WoW\15354\locale-enGB.MPQ:DBFilesClient\SpellLevels.dbc + // 2012 - WoW\15354\locale-enGB.MPQ:Interface\AddOns\Blizzard_AuctionUI\Blizzard_AuctionUI.xml + if(dwErrCode == ERROR_SUCCESS && dwBytesToCopy != 0) + { + LPBYTE pbExtraData; + + // Allocate space for the extra data + pbExtraData = STORM_ALLOC(BYTE, dwBytesToCopy); + if(pbExtraData != NULL) + { + if(!FileStream_Read(ha->pStream, NULL, pbExtraData, dwBytesToCopy)) + dwErrCode = GetLastError(); + + if(!FileStream_Write(pNewStream, NULL, pbExtraData, dwBytesToCopy)) + dwErrCode = GetLastError(); + + // Include these extra data in the compressed size + dwCmpSize += dwBytesToCopy; + STORM_FREE(pbExtraData); + } + else + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + + // Write the MD5's of the raw file data, if needed + if(dwErrCode == ERROR_SUCCESS && ha->pHeader->dwRawChunkSize != 0) + { + dwErrCode = WriteMpqDataMD5(pNewStream, + ha->MpqPos + MpqFilePos, + pFileEntry->dwCmpSize, + ha->pHeader->dwRawChunkSize); + } + + // Verify the number of bytes written + if(dwErrCode == ERROR_SUCCESS) + { + // At this point, number of bytes written should be exactly + // the same like the compressed file size. If it isn't, + // there's something wrong (an unknown archive version, MPQ malformation, ...) + // + // Note: Diablo savegames have very weird layout, and the file "hero" + // seems to have improper compressed size. Instead of real compressed size, + // the "dwCmpSize" member of the block table entry contains + // uncompressed size of file data + size of the sector table. + // If we compact the archive, Diablo will refuse to load the game + // + // Note: Some patch files in WOW patches don't count the patch header + // into compressed size + // + + if(!(dwCmpSize <= pFileEntry->dwCmpSize && pFileEntry->dwCmpSize <= dwCmpSize + dwPatchSize)) + { + dwErrCode = ERROR_FILE_CORRUPT; + assert(false); + } + } + + return dwErrCode; +} + +static DWORD CopyMpqFiles(TMPQArchive * ha, LPDWORD pFileKeys, TFileStream * pNewStream) +{ + TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; + TFileEntry * pFileEntry; + TMPQFile * hf = NULL; + ULONGLONG MpqFilePos; + DWORD dwErrCode = ERROR_SUCCESS; + + // Walk through all files and write them to the destination MPQ archive + for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) + { + // Copy all the file sectors + // Only do that when the file has nonzero size + if((pFileEntry->dwFlags & MPQ_FILE_EXISTS)) + { + // Query the position where the destination file will be + FileStream_GetPos(pNewStream, &MpqFilePos); + MpqFilePos = MpqFilePos - ha->MpqPos; + + // Perform file copy ONLY if the file has nonzero size + if(pFileEntry->dwFileSize != 0) + { + // Allocate structure for the MPQ file + hf = CreateFileHandle(ha, pFileEntry); + if(hf == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // Set the file decryption key + hf->dwFileKey = pFileKeys[pFileEntry - ha->pFileTable]; + + // If the file is a patch file, load the patch header + if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) + { + dwErrCode = AllocatePatchInfo(hf, true); + if(dwErrCode != ERROR_SUCCESS) + break; + } + + // Allocate buffers for file sector and sector offset table + dwErrCode = AllocateSectorBuffer(hf); + if(dwErrCode != ERROR_SUCCESS) + break; + + // Also allocate sector offset table and sector checksum table + dwErrCode = AllocateSectorOffsets(hf, true); + if(dwErrCode != ERROR_SUCCESS) + break; + + // Also load sector checksums, if any + if(pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC) + { + dwErrCode = AllocateSectorChecksums(hf, false); + if(dwErrCode != ERROR_SUCCESS) + break; + } + + // Copy all file sectors + dwErrCode = CopyMpqFileSectors(ha, hf, pNewStream, MpqFilePos); + if(dwErrCode != ERROR_SUCCESS) + break; + + // Free buffers. This also sets "hf" to NULL. + FreeFileHandle(hf); + } + + // Note: DO NOT update the compressed size in the file entry, no matter how bad it is. + pFileEntry->ByteOffset = MpqFilePos; + } + } + + // Cleanup and exit + if(hf != NULL) + FreeFileHandle(hf); + return dwErrCode; +} + +/*****************************************************************************/ +/* Public functions */ +/*****************************************************************************/ + +//----------------------------------------------------------------------------- +// Changing hash table size + +DWORD WINAPI SFileGetMaxFileCount(HANDLE hMpq) +{ + TMPQArchive * ha = (TMPQArchive *)hMpq; + + return ha->dwMaxFileCount; +} + +bool WINAPI SFileSetMaxFileCount(HANDLE hMpq, DWORD dwMaxFileCount) +{ + TMPQArchive * ha = (TMPQArchive *)hMpq; + DWORD dwNewHashTableSize = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Test the valid parameters + if(!IsValidMpqHandle(hMpq)) + dwErrCode = ERROR_INVALID_HANDLE; + if(ha->dwFlags & MPQ_FLAG_READ_ONLY) + dwErrCode = ERROR_ACCESS_DENIED; + if(dwMaxFileCount < ha->dwFileTableSize) + dwErrCode = ERROR_DISK_FULL; + + // ALL file names must be known in order to be able to rebuild hash table + if(dwErrCode == ERROR_SUCCESS && ha->pHashTable != NULL) + { + dwErrCode = CheckIfAllFilesKnown(ha); + if(dwErrCode == ERROR_SUCCESS) + { + // Calculate the hash table size for the new file limit + dwNewHashTableSize = GetNearestPowerOfTwo(dwMaxFileCount); + + // Rebuild both file tables + dwErrCode = RebuildFileTable(ha, dwNewHashTableSize); + } + } + + // We always have to rebuild the (attributes) file due to file table change + if(dwErrCode == ERROR_SUCCESS) + { + // Invalidate (listfile) and (attributes) + InvalidateInternalFiles(ha); + + // Rebuild the HET table, if we have any + if(ha->pHetTable != NULL) + dwErrCode = RebuildHetTable(ha); + } + + // Return the error + if(dwErrCode != ERROR_SUCCESS) + SetLastError(dwErrCode); + return (dwErrCode == ERROR_SUCCESS); +} + +//----------------------------------------------------------------------------- +// Archive compacting + +bool WINAPI SFileSetCompactCallback(HANDLE hMpq, SFILE_COMPACT_CALLBACK pfnCompactCB, void * pvUserData) +{ + TMPQArchive * ha = (TMPQArchive *) hMpq; + + if (!IsValidMpqHandle(hMpq)) + { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + ha->pfnCompactCB = pfnCompactCB; + ha->pvCompactUserData = pvUserData; + return true; +} + +bool WINAPI SFileCompactArchive(HANDLE hMpq, const TCHAR * szListFile, bool /* bReserved */) +{ + TFileStream * pTempStream = NULL; + TMPQArchive * ha = (TMPQArchive *)hMpq; + ULONGLONG ByteOffset; + ULONGLONG ByteCount; + LPDWORD pFileKeys = NULL; + TCHAR szTempFile[MAX_PATH+1] = _T(""); + DWORD dwErrCode = ERROR_SUCCESS; + + // Test the valid parameters + if(!IsValidMpqHandle(hMpq)) + dwErrCode = ERROR_INVALID_HANDLE; + if(ha->dwFlags & MPQ_FLAG_READ_ONLY) + dwErrCode = ERROR_ACCESS_DENIED; + + // If the MPQ is changed at this moment, we have to flush the archive + if(dwErrCode == ERROR_SUCCESS && (ha->dwFlags & MPQ_FLAG_CHANGED)) + { + SFileFlushArchive(hMpq); + } + + // Create the table with file keys + if(dwErrCode == ERROR_SUCCESS) + { + if((pFileKeys = STORM_ALLOC(DWORD, ha->dwFileTableSize)) != NULL) + memset(pFileKeys, 0, sizeof(DWORD) * ha->dwFileTableSize); + else + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + + // First of all, we have to check of we are able to decrypt all files. + // If not, sorry, but the archive cannot be compacted. + if(dwErrCode == ERROR_SUCCESS) + { + // Initialize the progress variables for compact callback + FileStream_GetSize(ha->pStream, &(ha->CompactTotalBytes)); + ha->CompactBytesProcessed = 0; + dwErrCode = CheckIfAllKeysKnown(ha, szListFile, pFileKeys); + } + + // Get the temporary file name and create it + if(dwErrCode == ERROR_SUCCESS) + { + // Create temporary file name. Prevent buffer overflow + StringCopy(szTempFile, _countof(szTempFile), FileStream_GetFileName(ha->pStream)); + StringCat(szTempFile, _countof(szTempFile), _T(".tmp")); + + // Create temporary file + pTempStream = FileStream_CreateFile(szTempFile, STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE); + if(pTempStream == NULL) + dwErrCode = GetLastError(); + } + + // Write the data before MPQ user data (if any) + if(dwErrCode == ERROR_SUCCESS && ha->UserDataPos != 0) + { + // Inform the application about the progress + if(ha->pfnCompactCB != NULL) + ha->pfnCompactCB(ha->pvCompactUserData, CCB_COPYING_NON_MPQ_DATA, ha->CompactBytesProcessed, ha->CompactTotalBytes); + + ByteOffset = 0; + ByteCount = ha->UserDataPos; + dwErrCode = CopyNonMpqData(ha, ha->pStream, pTempStream, ByteOffset, ByteCount); + } + + // Write the MPQ user data (if any) + if(dwErrCode == ERROR_SUCCESS && ha->MpqPos > ha->UserDataPos) + { + // At this point, we assume that the user data size is equal + // to pUserData->dwHeaderOffs. + // If this assumption doesn't work, then we have an unknown version of MPQ + ByteOffset = ha->UserDataPos; + ByteCount = ha->MpqPos - ha->UserDataPos; + + assert(ha->pUserData != NULL); + assert(ha->pUserData->dwHeaderOffs == ByteCount); + dwErrCode = CopyNonMpqData(ha, ha->pStream, pTempStream, ByteOffset, ByteCount); + } + + // Write the MPQ header + if(dwErrCode == ERROR_SUCCESS) + { + TMPQHeader SaveMpqHeader; + + // Write the MPQ header to the file + memcpy(&SaveMpqHeader, ha->pHeader, ha->pHeader->dwHeaderSize); + BSWAP_TMPQHEADER(&SaveMpqHeader, MPQ_FORMAT_VERSION_1); + BSWAP_TMPQHEADER(&SaveMpqHeader, MPQ_FORMAT_VERSION_2); + BSWAP_TMPQHEADER(&SaveMpqHeader, MPQ_FORMAT_VERSION_3); + BSWAP_TMPQHEADER(&SaveMpqHeader, MPQ_FORMAT_VERSION_4); + if(!FileStream_Write(pTempStream, NULL, &SaveMpqHeader, ha->pHeader->dwHeaderSize)) + dwErrCode = GetLastError(); + + // Update the progress + ha->CompactBytesProcessed += ha->pHeader->dwHeaderSize; + } + + // Now copy all files + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = CopyMpqFiles(ha, pFileKeys, pTempStream); + + // If succeeded, switch the streams + if(dwErrCode == ERROR_SUCCESS) + { + ha->dwFlags |= MPQ_FLAG_CHANGED; + if(FileStream_Replace(ha->pStream, pTempStream)) + pTempStream = NULL; + else + dwErrCode = ERROR_CAN_NOT_COMPLETE; + } + + // Final user notification + if(dwErrCode == ERROR_SUCCESS && ha->pfnCompactCB != NULL) + { + ha->CompactBytesProcessed += (ha->pHeader->dwHashTableSize * sizeof(TMPQHash)); + ha->CompactBytesProcessed += (ha->dwFileTableSize * sizeof(TMPQBlock)); + ha->pfnCompactCB(ha->pvCompactUserData, CCB_CLOSING_ARCHIVE, ha->CompactBytesProcessed, ha->CompactTotalBytes); + } + + // Cleanup and return + if(pTempStream != NULL) + FileStream_Close(pTempStream); + if(pFileKeys != NULL) + STORM_FREE(pFileKeys); + if(dwErrCode != ERROR_SUCCESS) + SetLastError(dwErrCode); + return (dwErrCode == ERROR_SUCCESS); +} diff --git a/StormLib/src/SFileCreateArchive.cpp b/StormLib/src/SFileCreateArchive.cpp new file mode 100644 index 000000000..6f398add5 --- /dev/null +++ b/StormLib/src/SFileCreateArchive.cpp @@ -0,0 +1,276 @@ +/*****************************************************************************/ +/* SFileCreateArchive.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* MPQ Editing functions */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 24.03.03 1.00 Lad Splitted from SFileOpenArchive.cpp */ +/* 08.06.10 1.00 Lad Renamed to SFileCreateArchive.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" + +//----------------------------------------------------------------------------- +// Local variables + +static const DWORD MpqHeaderSizes[] = +{ + MPQ_HEADER_SIZE_V1, + MPQ_HEADER_SIZE_V2, + MPQ_HEADER_SIZE_V3, + MPQ_HEADER_SIZE_V4 +}; + +//----------------------------------------------------------------------------- +// Local functions + +static USHORT GetSectorSizeShift(DWORD dwSectorSize) +{ + USHORT wSectorSizeShift = 0; + + while(dwSectorSize > 0x200) + { + dwSectorSize >>= 1; + wSectorSizeShift++; + } + + return wSectorSizeShift; +} + +static DWORD WriteNakedMPQHeader(TMPQArchive * ha) +{ + TMPQHeader * pHeader = ha->pHeader; + TMPQHeader Header; + DWORD dwBytesToWrite = pHeader->dwHeaderSize; + DWORD dwErrCode = ERROR_SUCCESS; + + // Prepare the naked MPQ header + memset(&Header, 0, sizeof(TMPQHeader)); + Header.dwID = pHeader->dwID; + Header.dwHeaderSize = pHeader->dwHeaderSize; + Header.dwArchiveSize = pHeader->dwHeaderSize; + Header.wFormatVersion = pHeader->wFormatVersion; + Header.wSectorSize = pHeader->wSectorSize; + + // Write it to the file + BSWAP_TMPQHEADER(&Header, MPQ_FORMAT_VERSION_1); + BSWAP_TMPQHEADER(&Header, MPQ_FORMAT_VERSION_2); + BSWAP_TMPQHEADER(&Header, MPQ_FORMAT_VERSION_3); + BSWAP_TMPQHEADER(&Header, MPQ_FORMAT_VERSION_4); + if(!FileStream_Write(ha->pStream, &ha->MpqPos, &Header, dwBytesToWrite)) + dwErrCode = GetLastError(); + + return dwErrCode; +} + +//----------------------------------------------------------------------------- +// Creates a new MPQ archive. + +bool WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwCreateFlags, DWORD dwMaxFileCount, HANDLE * phMpq) +{ + SFILE_CREATE_MPQ CreateInfo; + + // Fill the create structure + memset(&CreateInfo, 0, sizeof(SFILE_CREATE_MPQ)); + CreateInfo.cbSize = sizeof(SFILE_CREATE_MPQ); + CreateInfo.dwMpqVersion = (dwCreateFlags & MPQ_CREATE_ARCHIVE_VMASK) >> FLAGS_TO_FORMAT_SHIFT; + CreateInfo.dwStreamFlags = STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE; + CreateInfo.dwFileFlags1 = (dwCreateFlags & MPQ_CREATE_LISTFILE) ? MPQ_FILE_DEFAULT_INTERNAL : 0; + CreateInfo.dwFileFlags2 = (dwCreateFlags & MPQ_CREATE_ATTRIBUTES) ? MPQ_FILE_DEFAULT_INTERNAL : 0; + CreateInfo.dwFileFlags3 = (dwCreateFlags & MPQ_CREATE_SIGNATURE) ? MPQ_FILE_DEFAULT_INTERNAL : 0; + CreateInfo.dwAttrFlags = (dwCreateFlags & MPQ_CREATE_ATTRIBUTES) ? (MPQ_ATTRIBUTE_CRC32 | MPQ_ATTRIBUTE_FILETIME | MPQ_ATTRIBUTE_MD5) : 0; + CreateInfo.dwSectorSize = (CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_3) ? 0x4000 : 0x1000; + CreateInfo.dwRawChunkSize = (CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_4) ? 0x4000 : 0; + CreateInfo.dwMaxFileCount = dwMaxFileCount; + + // Set the proper attribute parts + if((CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_3) && (dwCreateFlags & MPQ_CREATE_ATTRIBUTES)) + CreateInfo.dwAttrFlags |= MPQ_ATTRIBUTE_PATCH_BIT; + + // Backward compatibility: SFileCreateArchive always used to add (listfile) + // We would break loads of applications if we change that + CreateInfo.dwFileFlags1 = MPQ_FILE_DEFAULT_INTERNAL; + + // Let the main function create the archive + return SFileCreateArchive2(szMpqName, &CreateInfo, phMpq); +} + +bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCreateInfo, HANDLE * phMpq) +{ + TFileStream * pStream = NULL; // File stream + TMPQArchive * ha = NULL; // MPQ archive handle + TMPQHeader * pHeader; + ULONGLONG MpqPos = 0; // Position of MPQ header in the file + HANDLE hMpq = NULL; + DWORD dwBlockTableSize = 0; // Initial block table size + DWORD dwHashTableSize = 0; + DWORD dwReservedFiles = 0; // Number of reserved file entries + DWORD dwMpqFlags = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Check the parameters, if they are valid + if(szMpqName == NULL || *szMpqName == 0 || pCreateInfo == NULL || phMpq == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + // Verify if all variables in SFILE_CREATE_MPQ are correct + if((pCreateInfo->cbSize == 0 || pCreateInfo->cbSize > sizeof(SFILE_CREATE_MPQ)) || + (pCreateInfo->dwMpqVersion > MPQ_FORMAT_VERSION_4) || + (pCreateInfo->pvUserData != NULL || pCreateInfo->cbUserData != 0) || + (pCreateInfo->dwAttrFlags & ~MPQ_ATTRIBUTE_ALL) || + (pCreateInfo->dwSectorSize & (pCreateInfo->dwSectorSize - 1)) || + (pCreateInfo->dwRawChunkSize & (pCreateInfo->dwRawChunkSize - 1))) + { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + // One time initialization of MPQ cryptography + InitializeMpqCryptography(); + + // We verify if the file already exists and if it's a MPQ archive. + // If yes, we won't allow to overwrite it. + if(SFileOpenArchive(szMpqName, 0, STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE | MPQ_OPEN_NO_ATTRIBUTES | MPQ_OPEN_NO_LISTFILE, &hMpq)) + { + SFileCloseArchive(hMpq); + SetLastError(ERROR_ALREADY_EXISTS); + return false; + } + + // + // At this point, we have to create the archive. + // - If the file exists, convert it to MPQ archive. + // - If the file doesn't exist, create new empty file + // + + pStream = FileStream_OpenFile(szMpqName, pCreateInfo->dwStreamFlags); + if(pStream == NULL) + { + pStream = FileStream_CreateFile(szMpqName, pCreateInfo->dwStreamFlags); + if(pStream == NULL) + return false; + } + + // Increment the maximum amount of files to have space for (listfile) + if(pCreateInfo->dwMaxFileCount && pCreateInfo->dwFileFlags1) + { + dwMpqFlags |= MPQ_FLAG_LISTFILE_NEW; + dwReservedFiles++; + } + + // Increment the maximum amount of files to have space for (attributes) + if(pCreateInfo->dwMaxFileCount && pCreateInfo->dwFileFlags2 && pCreateInfo->dwAttrFlags) + { + dwMpqFlags |= MPQ_FLAG_ATTRIBUTES_NEW; + dwReservedFiles++; + } + + // Increment the maximum amount of files to have space for (signature) + if(pCreateInfo->dwMaxFileCount && pCreateInfo->dwFileFlags3) + { + dwMpqFlags |= MPQ_FLAG_SIGNATURE_NEW; + dwReservedFiles++; + } + + // If file count is not zero, initialize the hash table size + dwHashTableSize = GetNearestPowerOfTwo(pCreateInfo->dwMaxFileCount + dwReservedFiles); + + // Retrieve the file size and round it up to 0x200 bytes + FileStream_GetSize(pStream, &MpqPos); + MpqPos = (MpqPos + 0x1FF) & (ULONGLONG)0xFFFFFFFFFFFFFE00ULL; + if(!FileStream_SetSize(pStream, MpqPos)) + dwErrCode = GetLastError(); + +#ifdef _DEBUG + // Debug code, used for testing StormLib +// dwBlockTableSize = dwHashTableSize * 2; +#endif + + // Create the archive handle + if(dwErrCode == ERROR_SUCCESS) + { + if((ha = STORM_ALLOC(TMPQArchive, 1)) == NULL) + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + + // Fill the MPQ archive handle structure + if(dwErrCode == ERROR_SUCCESS) + { + memset(ha, 0, sizeof(TMPQArchive)); + ha->pfnHashString = HashStringSlash; + ha->pStream = pStream; + ha->dwSectorSize = pCreateInfo->dwSectorSize; + ha->UserDataPos = MpqPos; + ha->MpqPos = MpqPos; + ha->pHeader = pHeader = (TMPQHeader *)ha->HeaderData; + ha->dwMaxFileCount = dwHashTableSize; + ha->dwFileTableSize = 0; + ha->dwReservedFiles = dwReservedFiles; + ha->dwFileFlags1 = pCreateInfo->dwFileFlags1; + ha->dwFileFlags2 = pCreateInfo->dwFileFlags2; + ha->dwFileFlags3 = pCreateInfo->dwFileFlags3 ? MPQ_FILE_EXISTS : 0; + ha->dwAttrFlags = pCreateInfo->dwAttrFlags; + ha->dwFlags = dwMpqFlags | MPQ_FLAG_CHANGED; + ha->useFreeSpaceOptimization = true; + ha->lastFreeSpaceEntry = nullptr; + pStream = NULL; + + // Fill the MPQ header + memset(pHeader, 0, sizeof(ha->HeaderData)); + pHeader->dwID = g_dwMpqSignature; + pHeader->dwHeaderSize = MpqHeaderSizes[pCreateInfo->dwMpqVersion]; + pHeader->dwArchiveSize = pHeader->dwHeaderSize + dwHashTableSize * sizeof(TMPQHash); + pHeader->wFormatVersion = (USHORT)pCreateInfo->dwMpqVersion; + pHeader->wSectorSize = GetSectorSizeShift(ha->dwSectorSize); + pHeader->dwHashTablePos = pHeader->dwHeaderSize; + pHeader->dwHashTableSize = dwHashTableSize; + pHeader->dwBlockTablePos = pHeader->dwHashTablePos + dwHashTableSize * sizeof(TMPQHash); + pHeader->dwBlockTableSize = dwBlockTableSize; + + // For MPQs version 4 and higher, we set the size of raw data block + // for calculating MD5 + if(pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_4) + pHeader->dwRawChunkSize = pCreateInfo->dwRawChunkSize; + + // Write the naked MPQ header + dwErrCode = WriteNakedMPQHeader(ha); + } + + // Create initial HET table, if the caller required an MPQ format 3.0 or newer + if(dwErrCode == ERROR_SUCCESS && pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_3 && pCreateInfo->dwMaxFileCount != 0) + { + ha->pHetTable = CreateHetTable(ha->dwFileTableSize, 0, 0x40, NULL); + if(ha->pHetTable == NULL) + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + + // Create initial hash table + if(dwErrCode == ERROR_SUCCESS && dwHashTableSize != 0) + { + dwErrCode = CreateHashTable(ha, dwHashTableSize); + } + + // Create initial file table + if(dwErrCode == ERROR_SUCCESS && ha->dwMaxFileCount != 0) + { + dwErrCode = CreateFileTable(ha, ha->dwMaxFileCount); + } + + // Cleanup : If an error, delete all buffers and return + if(dwErrCode != ERROR_SUCCESS) + { + FileStream_Close(pStream); + FreeArchiveHandle(ha); + SetLastError(dwErrCode); + ha = NULL; + } + + // Return the values + *phMpq = (HANDLE)ha; + return (dwErrCode == ERROR_SUCCESS); +} diff --git a/StormLib/src/SFileExtractFile.cpp b/StormLib/src/SFileExtractFile.cpp new file mode 100644 index 000000000..6b3b76759 --- /dev/null +++ b/StormLib/src/SFileExtractFile.cpp @@ -0,0 +1,64 @@ +/*****************************************************************************/ +/* SFileExtractFile.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Simple extracting utility */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 20.06.03 1.00 Lad The first version of SFileExtractFile.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" + +bool WINAPI SFileExtractFile(HANDLE hMpq, const char * szToExtract, const TCHAR * szExtracted, DWORD dwSearchScope) +{ + TFileStream * pLocalFile = NULL; + HANDLE hMpqFile = NULL; + DWORD dwErrCode = ERROR_SUCCESS; + + // Open the MPQ file + if(dwErrCode == ERROR_SUCCESS) + { + if(!SFileOpenFileEx(hMpq, szToExtract, dwSearchScope, &hMpqFile)) + dwErrCode = GetLastError(); + } + + // Create the local file + if(dwErrCode == ERROR_SUCCESS) + { + pLocalFile = FileStream_CreateFile(szExtracted, 0); + if(pLocalFile == NULL) + dwErrCode = GetLastError(); + } + + // Copy the file's content + while(dwErrCode == ERROR_SUCCESS) + { + char szBuffer[0x1000]; + DWORD dwTransferred = 0; + + // dwTransferred is only set to nonzero if something has been read. + // dwErrCode can be ERROR_SUCCESS or ERROR_HANDLE_EOF + if(!SFileReadFile(hMpqFile, szBuffer, sizeof(szBuffer), &dwTransferred, NULL)) + dwErrCode = GetLastError(); + if(dwErrCode == ERROR_HANDLE_EOF) + dwErrCode = ERROR_SUCCESS; + if(dwTransferred == 0) + break; + + // If something has been actually read, write it + if(!FileStream_Write(pLocalFile, NULL, szBuffer, dwTransferred)) + dwErrCode = GetLastError(); + } + + // Close the files + if(hMpqFile != NULL) + SFileCloseFile(hMpqFile); + if(pLocalFile != NULL) + FileStream_Close(pLocalFile); + if(dwErrCode != ERROR_SUCCESS) + SetLastError(dwErrCode); + return (dwErrCode == ERROR_SUCCESS); +} diff --git a/StormLib/src/SFileFindFile.cpp b/StormLib/src/SFileFindFile.cpp new file mode 100644 index 000000000..856de443e --- /dev/null +++ b/StormLib/src/SFileFindFile.cpp @@ -0,0 +1,483 @@ +/*****************************************************************************/ +/* SFileFindFile.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* A module for file searching within MPQs */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 25.03.03 1.00 Lad The first version of SFileFindFile.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" + +//----------------------------------------------------------------------------- +// Private structure used for file search (search handle) + +// Used by searching in MPQ archives +struct TMPQSearch +{ + TMPQArchive * ha; // Handle to MPQ, where the search runs + TFileEntry ** pSearchTable; // Table for files that have been already found + DWORD dwSearchTableItems; // Number of items in the search table + DWORD dwNextIndex; // Next file index to be checked + DWORD dwFlagMask; // For checking flag mask + char szSearchMask[1]; // Search mask (variable length) +}; + +//----------------------------------------------------------------------------- +// Local functions + +static TMPQSearch * IsValidSearchHandle(HANDLE hFind) +{ + TMPQSearch * hs = (TMPQSearch *)hFind; + + if(hs != NULL && IsValidMpqHandle(hs->ha)) + return hs; + + return NULL; +} + +bool SFileCheckWildCard(const char * szString, const char * szWildCard) +{ + const char * szWildCardPtr; + + for(;;) + { + // If there is '?' in the wildcard, we skip one char + while(szWildCard[0] == '?') + { + if(szString[0] == 0) + return false; + + szWildCard++; + szString++; + } + + // Handle '*' + szWildCardPtr = szWildCard; + if(szWildCardPtr[0] != 0) + { + if(szWildCardPtr[0] == '*') + { + while(szWildCardPtr[0] == '*') + szWildCardPtr++; + + if(szWildCardPtr[0] == 0) + return true; + + if(AsciiToUpperTable[szWildCardPtr[0]] == AsciiToUpperTable[szString[0]]) + { + if(SFileCheckWildCard(szString, szWildCardPtr)) + return true; + } + } + else + { + if(AsciiToUpperTable[szWildCardPtr[0]] != AsciiToUpperTable[szString[0]]) + return false; + + szWildCard = szWildCardPtr + 1; + } + + if(szString[0] == 0) + return false; + szString++; + } + else + { + return (szString[0] == 0) ? true : false; + } + } +} + +static DWORD GetSearchTableItems(TMPQArchive * ha) +{ + DWORD dwMergeItems = 0; + + // Loop over all patches + while(ha != NULL) + { + // Append the number of files + dwMergeItems += (ha->pHetTable != NULL) ? ha->pHetTable->dwEntryCount + : ha->pHeader->dwBlockTableSize; + // Move to the patched archive + ha = ha->haPatch; + } + + // Return the double size of number of items + return (dwMergeItems | 1); +} + +static bool FileWasFoundBefore( + TMPQArchive * ha, + TMPQSearch * hs, + TFileEntry * pFileEntry) +{ + TFileEntry * pEntry; + char * szRealFileName = pFileEntry->szFileName; + DWORD dwStartIndex; + DWORD dwNameHash; + DWORD dwIndex; + + if(hs->pSearchTable != NULL && szRealFileName != NULL) + { + // If we are in patch MPQ, we check if patch prefix matches + // and then trim the patch prefix + if(ha->pPatchPrefix != NULL) + { + // If the patch prefix doesn't fit, we pretend that the file + // was there before and it will be skipped + if(_strnicmp(szRealFileName, ha->pPatchPrefix->szPatchPrefix, ha->pPatchPrefix->nLength)) + return true; + + szRealFileName += ha->pPatchPrefix->nLength; + } + + // Calculate the hash to the table + dwNameHash = ha->pfnHashString(szRealFileName, MPQ_HASH_NAME_A); + dwStartIndex = dwIndex = (dwNameHash % hs->dwSearchTableItems); + + // The file might have been found before + // only if this is not the first MPQ being searched + if(ha->haBase != NULL) + { + // Enumerate all entries in the search table + for(;;) + { + // Get the file entry at that position + pEntry = hs->pSearchTable[dwIndex]; + if(pEntry == NULL) + break; + + if(pEntry->szFileName != NULL) + { + // Does the name match? + if(!_stricmp(pEntry->szFileName, szRealFileName)) + return true; + } + + // Move to the next entry + dwIndex = (dwIndex + 1) % hs->dwSearchTableItems; + if(dwIndex == dwStartIndex) + break; + } + } + + // Put the entry to the table for later use + hs->pSearchTable[dwIndex] = pFileEntry; + } + return false; +} + +static TFileEntry * FindPatchEntry(TMPQArchive * ha, TFileEntry * pFileEntry) +{ + TFileEntry * pPatchEntry = pFileEntry; + TFileEntry * pTempEntry; + char szFileName[MAX_PATH+1]; + + // Can't find patch entry for a file that doesn't have name + if(pFileEntry->szFileName != NULL && pFileEntry->szFileName[0] != 0) + { + // Go while there are patches + while(ha->haPatch != NULL) + { + // Move to the patch archive + ha = ha->haPatch; + szFileName[0] = 0; + + // Prepare the prefix for the file name + if(ha->pPatchPrefix && ha->pPatchPrefix->nLength) + StringCopy(szFileName, _countof(szFileName), ha->pPatchPrefix->szPatchPrefix); + StringCat(szFileName, _countof(szFileName), pFileEntry->szFileName); + + // Try to find the file there + pTempEntry = GetFileEntryExact(ha, szFileName, 0, NULL); + if(pTempEntry != NULL) + pPatchEntry = pTempEntry; + } + } + + // Return the found patch entry + return pPatchEntry; +} + +static bool DoMPQSearch_FileEntry( + TMPQSearch * hs, + SFILE_FIND_DATA * lpFindFileData, + TMPQArchive * ha, + TMPQHash * pHashEntry, + TFileEntry * pFileEntry) +{ + TFileEntry * pPatchEntry; + HANDLE hFile = NULL; + const char * szFileName; + size_t nPrefixLength = (ha->pPatchPrefix != NULL) ? ha->pPatchPrefix->nLength : 0; + DWORD dwBlockIndex; + char szNameBuff[MAX_PATH]; + + // Is it a file but not a patch file? + if((pFileEntry->dwFlags & hs->dwFlagMask) == MPQ_FILE_EXISTS) + { + // Ignore fake files which are not compressed but have size higher than the archive + if ((pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) == 0 && (pFileEntry->dwFileSize > ha->FileSize)) + return false; + + // Now we have to check if this file was not enumerated before + if(!FileWasFoundBefore(ha, hs, pFileEntry)) + { +// if(pFileEntry != NULL && !_stricmp(pFileEntry->szFileName, "TriggerLibs\\NativeLib.galaxy")) +// DebugBreak(); + + // Find a patch to this file + // Note: This either succeeds or returns pFileEntry + pPatchEntry = FindPatchEntry(ha, pFileEntry); + + // Prepare the block index + dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable); + if(dwBlockIndex == 569) + szNameBuff[0] = 'F'; + + // Get the file name. If it's not known, we will create pseudo-name + szFileName = pFileEntry->szFileName; + if(szFileName == NULL) + { + // Open the file by its pseudo-name. + StringCreatePseudoFileName(szNameBuff, _countof(szNameBuff), dwBlockIndex, "xxx"); + if(SFileOpenFileEx((HANDLE)hs->ha, szNameBuff, SFILE_OPEN_BASE_FILE, &hFile)) + { + SFileGetFileName(hFile, szNameBuff); + szFileName = szNameBuff; + SFileCloseFile(hFile); + } + } + + // If the file name is still NULL, we cannot include the file to search results + if(szFileName != NULL) + { + // Check the file name against the wildcard + if(SFileCheckWildCard(szFileName + nPrefixLength, hs->szSearchMask)) + { + // Fill the found entry. hash entry and block index are taken from the base MPQ + lpFindFileData->dwHashIndex = HASH_ENTRY_FREE; + lpFindFileData->dwBlockIndex = dwBlockIndex; + lpFindFileData->dwFileSize = pPatchEntry->dwFileSize; + lpFindFileData->dwFileFlags = pPatchEntry->dwFlags; + lpFindFileData->dwCompSize = pPatchEntry->dwCmpSize; + lpFindFileData->lcLocale = 0; // pPatchEntry->lcLocale; + + // Fill the filetime + lpFindFileData->dwFileTimeHi = (DWORD)(pPatchEntry->FileTime >> 32); + lpFindFileData->dwFileTimeLo = (DWORD)(pPatchEntry->FileTime); + + // Fill-in the entries from hash table entry, if given + if(pHashEntry != NULL) + { + lpFindFileData->dwHashIndex = (DWORD)(pHashEntry - ha->pHashTable); + lpFindFileData->lcLocale = pHashEntry->lcLocale; + } + + // Fill the file name and plain file name + StringCopy(lpFindFileData->cFileName, _countof(lpFindFileData->cFileName), szFileName + nPrefixLength); + lpFindFileData->szPlainName = (char *)GetPlainFileName(lpFindFileData->cFileName); + return true; + } + } + } + } + + // Either not a valid item or was found before + return false; +} + +static DWORD DoMPQSearch_HashTable(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData, TMPQArchive * ha) +{ + TMPQHash * pHashTableEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; + TMPQHash * pHash; + + // Parse the file table + for(pHash = ha->pHashTable + hs->dwNextIndex; pHash < pHashTableEnd; pHash++) + { + // Increment the next index for subsequent search + hs->dwNextIndex++; + + // Does this hash table entry point to a proper block table entry? + if(IsValidHashEntry(ha, pHash)) + { + // Check if this file entry should be included in the search result + if(DoMPQSearch_FileEntry(hs, lpFindFileData, ha, pHash, ha->pFileTable + MPQ_BLOCK_INDEX(pHash))) + return ERROR_SUCCESS; + } + } + + // No more files + return ERROR_NO_MORE_FILES; +} + +static DWORD DoMPQSearch_FileTable(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData, TMPQArchive * ha) +{ + TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; + TFileEntry * pFileEntry; + + // Parse the file table + for(pFileEntry = ha->pFileTable + hs->dwNextIndex; pFileEntry < pFileTableEnd; pFileEntry++) + { + // Increment the next index for subsequent search + hs->dwNextIndex++; + + // Check if this file entry should be included in the search result + if(DoMPQSearch_FileEntry(hs, lpFindFileData, ha, NULL, pFileEntry)) + return ERROR_SUCCESS; + } + + // No more files + return ERROR_NO_MORE_FILES; +} + +// Performs one MPQ search +static DWORD DoMPQSearch(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData) +{ + TMPQArchive * ha = hs->ha; + DWORD dwErrCode; + + // Start searching with base MPQ + while(ha != NULL) + { + // If the archive has hash table, we need to use hash table + // in order to catch hash table index and file locale. + // Note: If multiple hash table entries, point to the same block entry, + // we need, to report them all + dwErrCode = (ha->pHashTable != NULL) ? DoMPQSearch_HashTable(hs, lpFindFileData, ha) + : DoMPQSearch_FileTable(hs, lpFindFileData, ha); + if(dwErrCode == ERROR_SUCCESS) + return dwErrCode; + + // If there is no more patches in the chain, stop it. + // This also keeps hs->ha non-NULL, which is required + // for freeing the handle later + if(ha->haPatch == NULL) + break; + + // Move to the next patch in the patch chain + hs->ha = ha = ha->haPatch; + hs->dwNextIndex = 0; + } + + // No more files found, return error + return ERROR_NO_MORE_FILES; +} + +static void FreeMPQSearch(TMPQSearch *& hs) +{ + if(hs != NULL) + { + if(hs->pSearchTable != NULL) + STORM_FREE(hs->pSearchTable); + STORM_FREE(hs); + hs = NULL; + } +} + +//----------------------------------------------------------------------------- +// Public functions + +HANDLE WINAPI SFileFindFirstFile(HANDLE hMpq, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const TCHAR * szListFile) +{ + TMPQArchive * ha = (TMPQArchive *)hMpq; + TMPQSearch * hs = NULL; + size_t nSize = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Check for the valid parameters + if(!IsValidMpqHandle(hMpq)) + dwErrCode = ERROR_INVALID_HANDLE; + if(szMask == NULL || lpFindFileData == NULL) + dwErrCode = ERROR_INVALID_PARAMETER; + + // Include the listfile into the MPQ's internal listfile + // Note that if the listfile name is NULL, do nothing because the + // internal listfile is always included. + if(dwErrCode == ERROR_SUCCESS && szListFile != NULL && *szListFile != 0) + dwErrCode = SFileAddListFile((HANDLE)ha, szListFile); + + // Allocate the structure for MPQ search + if(dwErrCode == ERROR_SUCCESS) + { + nSize = sizeof(TMPQSearch) + strlen(szMask) + 1; + if((hs = (TMPQSearch *)STORM_ALLOC(char, nSize)) == NULL) + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + + // Perform the first search + if(dwErrCode == ERROR_SUCCESS) + { + memset(hs, 0, sizeof(TMPQSearch)); + strcpy(hs->szSearchMask, szMask); + hs->dwFlagMask = MPQ_FILE_EXISTS; + hs->ha = ha; + + // If the archive is patched archive, we have to create a merge table + // to prevent files being repeated + if(ha->haPatch != NULL) + { + hs->dwSearchTableItems = GetSearchTableItems(ha); + hs->pSearchTable = STORM_ALLOC(TFileEntry *, hs->dwSearchTableItems); + hs->dwFlagMask = MPQ_FILE_EXISTS | MPQ_FILE_PATCH_FILE; + if(hs->pSearchTable != NULL) + memset(hs->pSearchTable, 0, hs->dwSearchTableItems * sizeof(TFileEntry *)); + else + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + } + + // Perform first item searching + if(dwErrCode == ERROR_SUCCESS) + { + dwErrCode = DoMPQSearch(hs, lpFindFileData); + } + + // Cleanup + if(dwErrCode != ERROR_SUCCESS) + { + FreeMPQSearch(hs); + SetLastError(dwErrCode); + } + + // Return the result value + return (HANDLE)hs; +} + +bool WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData) +{ + TMPQSearch * hs = IsValidSearchHandle(hFind); + DWORD dwErrCode = ERROR_SUCCESS; + + // Check the parameters + if(hs == NULL) + dwErrCode = ERROR_INVALID_HANDLE; + if(lpFindFileData == NULL) + dwErrCode = ERROR_INVALID_PARAMETER; + + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = DoMPQSearch(hs, lpFindFileData); + + if(dwErrCode != ERROR_SUCCESS) + SetLastError(dwErrCode); + return (dwErrCode == ERROR_SUCCESS); +} + +bool WINAPI SFileFindClose(HANDLE hFind) +{ + TMPQSearch * hs = IsValidSearchHandle(hFind); + + // Check the parameters + if(hs == NULL) + { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + FreeMPQSearch(hs); + return true; +} diff --git a/StormLib/src/SFileGetFileInfo.cpp b/StormLib/src/SFileGetFileInfo.cpp new file mode 100644 index 000000000..28edfe0bf --- /dev/null +++ b/StormLib/src/SFileGetFileInfo.cpp @@ -0,0 +1,607 @@ +/*****************************************************************************/ +/* SFileGetFileInfo.cpp Copyright (c) Ladislav Zezula 2013 */ +/*---------------------------------------------------------------------------*/ +/* Description: */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 30.11.13 1.00 Lad The first version of SFileGetFileInfo.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" + +//----------------------------------------------------------------------------- +// Local functions + +static DWORD GetMpqFileCount(TMPQArchive * ha) +{ + TFileEntry * pFileTableEnd; + TFileEntry * pFileEntry; + DWORD dwFileCount = 0; + + // Go through all open MPQs, including patches + while(ha != NULL) + { + // Only count files that are not patch files + pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; + for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) + { + // If the file is patch file and this is not primary archive, skip it + // BUGBUG: This errorneously counts non-patch files that are in both + // base MPQ and in patches, and increases the number of files by cca 50% + if((pFileEntry->dwFlags & (MPQ_FILE_EXISTS | MPQ_FILE_PATCH_FILE)) == MPQ_FILE_EXISTS) + dwFileCount++; + } + + // Move to the next patch archive + ha = ha->haPatch; + } + + return dwFileCount; +} + +static bool GetInfo_ReturdwErrCode(DWORD dwErrCode) +{ + SetLastError(dwErrCode); + return false; +} + +static bool GetInfo_BufferCheck(void * pvFileInfo, DWORD cbFileInfo, DWORD cbData, LPDWORD pcbLengthNeeded) +{ + // Give the length needed to store the info + if(pcbLengthNeeded != NULL) + pcbLengthNeeded[0] = cbData; + + // Check for sufficient buffer + if(cbData > cbFileInfo) + return GetInfo_ReturdwErrCode(ERROR_INSUFFICIENT_BUFFER); + + // If the buffer size is sufficient, check for valid user buffer + if(pvFileInfo == NULL) + return GetInfo_ReturdwErrCode(ERROR_INVALID_PARAMETER); + + // Buffers and sizes are OK, we are ready to proceed file copying + return true; +} + +static bool GetInfo(void * pvFileInfo, DWORD cbFileInfo, const void * pvData, DWORD cbData, LPDWORD pcbLengthNeeded) +{ + // Verify buffer pointer and buffer size + if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbData, pcbLengthNeeded)) + return false; + + // Copy the data to the caller-supplied buffer + memcpy(pvFileInfo, pvData, cbData); + return true; +} + +static bool GetInfo_Allocated(void * pvFileInfo, DWORD cbFileInfo, void * pvData, DWORD cbData, LPDWORD pcbLengthNeeded) +{ + bool bResult; + + // Verify buffer pointer and buffer size + if((bResult = GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbData, pcbLengthNeeded)) != false) + memcpy(pvFileInfo, pvData, cbData); + + // Copy the data to the user buffer + STORM_FREE(pvData); + return bResult; +} + +static bool GetInfo_TablePointer(void * pvFileInfo, DWORD cbFileInfo, void * pvTablePointer, SFileInfoClass InfoClass, LPDWORD pcbLengthNeeded) +{ + // Verify buffer pointer and buffer size + if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, sizeof(void *), pcbLengthNeeded)) + { + SFileFreeFileInfo(pvTablePointer, InfoClass); + return false; + } + + // The user buffer receives pointer to the table. + // When done, the caller needs to call SFileFreeFileInfo on it + *(void **)pvFileInfo = pvTablePointer; + return true; +} + +static bool GetInfo_ReadFromFile(void * pvFileInfo, DWORD cbFileInfo, TFileStream * pStream, ULONGLONG ByteOffset, DWORD cbData, LPDWORD pcbLengthNeeded) +{ + // Verify buffer pointer and buffer size + if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbData, pcbLengthNeeded)) + return false; + + return FileStream_Read(pStream, &ByteOffset, pvFileInfo, cbData); +} + +static bool GetInfo_FileEntry(void * pvFileInfo, DWORD cbFileInfo, TFileEntry * pFileEntry, LPDWORD pcbLengthNeeded) +{ + LPBYTE pbFileInfo = (LPBYTE)pvFileInfo; + DWORD cbSrcFileInfo = sizeof(TFileEntry); + DWORD cbFileName = 1; + + // The file name belongs to the file entry + if(pFileEntry->szFileName) + cbFileName = (DWORD)strlen(pFileEntry->szFileName) + 1; + cbSrcFileInfo += cbFileName; + + // Verify buffer pointer and buffer size + if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbSrcFileInfo, pcbLengthNeeded)) + return false; + + // Copy the file entry + memcpy(pbFileInfo, pFileEntry, sizeof(TFileEntry)); + pbFileInfo += sizeof(TFileEntry); + pbFileInfo[0] = 0; + + // Copy the file name + if(pFileEntry->szFileName) + memcpy(pbFileInfo, pFileEntry->szFileName, cbFileName); + return true; +} + +static bool GetInfo_PatchChain(TMPQFile * hf, void * pvFileInfo, DWORD cbFileInfo, LPDWORD pcbLengthNeeded) +{ + TMPQFile * hfTemp; + LPCTSTR szPatchName; + LPTSTR szFileInfo = (LPTSTR)pvFileInfo; + size_t cchCharsNeeded = 1; + size_t nLength; + + // Patch chain is only supported on MPQ files. Local files are not supported. + if(hf->pStream != NULL) + return GetInfo_ReturdwErrCode(ERROR_INVALID_PARAMETER); + + // Calculate the necessary length of the multi-string + for(hfTemp = hf; hfTemp != NULL; hfTemp = hfTemp->hfPatch) + cchCharsNeeded += _tcslen(FileStream_GetFileName(hfTemp->ha->pStream)) + 1; + + // Verify whether the caller gave us valid buffer with enough size + if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, (DWORD)(cchCharsNeeded * sizeof(TCHAR)), pcbLengthNeeded)) + return false; + + // Copy each patch name + for(hfTemp = hf; hfTemp != NULL; hfTemp = hfTemp->hfPatch) + { + // Get the file name and its length + szPatchName = FileStream_GetFileName(hfTemp->ha->pStream); + nLength = _tcslen(szPatchName) + 1; + + // Copy the file name + memcpy(szFileInfo, szPatchName, nLength * sizeof(TCHAR)); + szFileInfo += nLength; + } + + // Make it multi-string + szFileInfo[0] = 0; + return true; +} + +//----------------------------------------------------------------------------- +// Retrieves an information about an archive or about a file within the archive +// +// hMpqOrFile - Handle to an MPQ archive or to a file +// InfoClass - Information to obtain +// pvFileInfo - Pointer to buffer to store the information +// cbFileInfo - Size of the buffer pointed by pvFileInfo +// pcbLengthNeeded - Receives number of bytes necessary to store the information + +bool WINAPI SFileGetFileInfo( + HANDLE hMpqOrFile, + SFileInfoClass InfoClass, + void * pvFileInfo, + DWORD cbFileInfo, + LPDWORD pcbLengthNeeded) +{ + MPQ_SIGNATURE_INFO SignatureInfo; + const TCHAR * szSrcFileInfo; + TMPQArchive * ha = NULL; + TFileEntry * pFileEntry = NULL; + TMPQHeader * pHeader = NULL; + ULONGLONG Int64Value = 0; + TMPQFile * hf = NULL; + void * pvSrcFileInfo = NULL; + DWORD cbSrcFileInfo = 0; + DWORD dwInt32Value = 0; + + // Validate archive/file handle + if((int)InfoClass <= (int)SFileMpqFlags) + { + if((ha = IsValidMpqHandle(hMpqOrFile)) == NULL) + return GetInfo_ReturdwErrCode(ERROR_INVALID_HANDLE); + pHeader = ha->pHeader; + } + else + { + if((hf = IsValidFileHandle(hMpqOrFile)) == NULL) + return GetInfo_ReturdwErrCode(ERROR_INVALID_HANDLE); + pFileEntry = hf->pFileEntry; + } + + // Return info-class-specific data + switch(InfoClass) + { + case SFileMpqFileName: + szSrcFileInfo = FileStream_GetFileName(ha->pStream); + cbSrcFileInfo = (DWORD)((_tcslen(szSrcFileInfo) + 1) * sizeof(TCHAR)); + return GetInfo(pvFileInfo, cbFileInfo, szSrcFileInfo, cbSrcFileInfo, pcbLengthNeeded); + + case SFileMpqStreamBitmap: + return FileStream_GetBitmap(ha->pStream, pvFileInfo, cbFileInfo, pcbLengthNeeded); + + case SFileMpqUserDataOffset: + return GetInfo(pvFileInfo, cbFileInfo, &ha->UserDataPos, sizeof(ULONGLONG), pcbLengthNeeded); + + case SFileMpqUserDataHeader: + if(ha->pUserData == NULL) + return GetInfo_ReturdwErrCode(ERROR_INVALID_PARAMETER); + return GetInfo_ReadFromFile(pvFileInfo, cbFileInfo, ha->pStream, ha->UserDataPos, sizeof(TMPQUserData), pcbLengthNeeded); + + case SFileMpqUserData: + if(ha->pUserData == NULL) + return GetInfo_ReturdwErrCode(ERROR_INVALID_PARAMETER); + return GetInfo_ReadFromFile(pvFileInfo, cbFileInfo, ha->pStream, ha->UserDataPos + sizeof(TMPQUserData), ha->pUserData->dwHeaderOffs - sizeof(TMPQUserData), pcbLengthNeeded); + + case SFileMpqHeaderOffset: + return GetInfo(pvFileInfo, cbFileInfo, &ha->MpqPos, sizeof(ULONGLONG), pcbLengthNeeded); + + case SFileMpqHeaderSize: + return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwHeaderSize, sizeof(DWORD), pcbLengthNeeded); + + case SFileMpqHeader: + return GetInfo_ReadFromFile(pvFileInfo, cbFileInfo, ha->pStream, ha->MpqPos, pHeader->dwHeaderSize, pcbLengthNeeded); + + case SFileMpqHetTableOffset: + return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HetTablePos64, sizeof(ULONGLONG), pcbLengthNeeded); + + case SFileMpqHetTableSize: + return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HetTableSize64, sizeof(ULONGLONG), pcbLengthNeeded); + + case SFileMpqHetHeader: + pvSrcFileInfo = LoadExtTable(ha, pHeader->HetTablePos64, (size_t)pHeader->HetTableSize64, HET_TABLE_SIGNATURE, MPQ_KEY_HASH_TABLE); + if(pvSrcFileInfo == NULL) + return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + return GetInfo_Allocated(pvFileInfo, cbFileInfo, pvSrcFileInfo, sizeof(TMPQHetHeader), pcbLengthNeeded); + + case SFileMpqHetTable: + if((pvSrcFileInfo = LoadHetTable(ha)) == NULL) + return GetInfo_ReturdwErrCode(ERROR_NOT_ENOUGH_MEMORY); + return GetInfo_TablePointer(pvFileInfo, cbFileInfo, pvSrcFileInfo, InfoClass, pcbLengthNeeded); + + case SFileMpqBetTableOffset: + return GetInfo(pvFileInfo, cbFileInfo, &pHeader->BetTablePos64, sizeof(ULONGLONG), pcbLengthNeeded); + + case SFileMpqBetTableSize: + return GetInfo(pvFileInfo, cbFileInfo, &pHeader->BetTableSize64, sizeof(ULONGLONG), pcbLengthNeeded); + + case SFileMpqBetHeader: + + // Retrieve the table and its size + pvSrcFileInfo = LoadExtTable(ha, pHeader->BetTablePos64, (size_t)pHeader->BetTableSize64, BET_TABLE_SIGNATURE, MPQ_KEY_BLOCK_TABLE); + if(pvSrcFileInfo == NULL) + return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + cbSrcFileInfo = sizeof(TMPQBetHeader) + ((TMPQBetHeader *)pvSrcFileInfo)->dwFlagCount * sizeof(DWORD); + + // It is allowed for the caller to only require BET header + if(cbFileInfo == sizeof(TMPQBetHeader)) + cbSrcFileInfo = sizeof(TMPQBetHeader); + return GetInfo_Allocated(pvFileInfo, cbFileInfo, pvSrcFileInfo, cbSrcFileInfo, pcbLengthNeeded); + + case SFileMpqBetTable: + if((pvSrcFileInfo = LoadBetTable(ha)) == NULL) + return GetInfo_ReturdwErrCode(ERROR_NOT_ENOUGH_MEMORY); + return GetInfo_TablePointer(pvFileInfo, cbFileInfo, pvSrcFileInfo, InfoClass, pcbLengthNeeded); + + case SFileMpqHashTableOffset: + Int64Value = MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos); + return GetInfo(pvFileInfo, cbFileInfo, &Int64Value, sizeof(ULONGLONG), pcbLengthNeeded); + + case SFileMpqHashTableSize64: + return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HashTableSize64, sizeof(ULONGLONG), pcbLengthNeeded); + + case SFileMpqHashTableSize: + return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwHashTableSize, sizeof(DWORD), pcbLengthNeeded); + + case SFileMpqHashTable: + cbSrcFileInfo = pHeader->dwHashTableSize * sizeof(TMPQHash); + return GetInfo(pvFileInfo, cbFileInfo, ha->pHashTable, cbSrcFileInfo, pcbLengthNeeded); + + case SFileMpqBlockTableOffset: + Int64Value = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos); + return GetInfo(pvFileInfo, cbFileInfo, &Int64Value, sizeof(ULONGLONG), pcbLengthNeeded); + + case SFileMpqBlockTableSize64: + return GetInfo(pvFileInfo, cbFileInfo, &pHeader->BlockTableSize64, sizeof(ULONGLONG), pcbLengthNeeded); + + case SFileMpqBlockTableSize: + return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwBlockTableSize, sizeof(DWORD), pcbLengthNeeded); + + case SFileMpqBlockTable: + if(MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos) >= ha->FileSize) + return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + cbSrcFileInfo = pHeader->dwBlockTableSize * sizeof(TMPQBlock); + pvSrcFileInfo = LoadBlockTable(ha, true); + return GetInfo_Allocated(pvFileInfo, cbFileInfo, pvSrcFileInfo, cbSrcFileInfo, pcbLengthNeeded); + + case SFileMpqHiBlockTableOffset: + return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HiBlockTablePos64, sizeof(ULONGLONG), pcbLengthNeeded); + + case SFileMpqHiBlockTableSize64: + return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HiBlockTableSize64, sizeof(ULONGLONG), pcbLengthNeeded); + + case SFileMpqHiBlockTable: + return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + + case SFileMpqSignatures: + if(!QueryMpqSignatureInfo(ha, &SignatureInfo)) + return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + return GetInfo(pvFileInfo, cbFileInfo, &SignatureInfo.SignatureTypes, sizeof(DWORD), pcbLengthNeeded); + + case SFileMpqStrongSignatureOffset: + if(QueryMpqSignatureInfo(ha, &SignatureInfo) == false || (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG) == 0) + return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + return GetInfo(pvFileInfo, cbFileInfo, &SignatureInfo.EndMpqData, sizeof(ULONGLONG), pcbLengthNeeded); + + case SFileMpqStrongSignatureSize: + if(QueryMpqSignatureInfo(ha, &SignatureInfo) == false || (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG) == 0) + return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + dwInt32Value = MPQ_STRONG_SIGNATURE_SIZE + 4; + return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded); + + case SFileMpqStrongSignature: + if(QueryMpqSignatureInfo(ha, &SignatureInfo) == false || (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG) == 0) + return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + return GetInfo(pvFileInfo, cbFileInfo, SignatureInfo.Signature, MPQ_STRONG_SIGNATURE_SIZE + 4, pcbLengthNeeded); + + case SFileMpqArchiveSize64: + return GetInfo(pvFileInfo, cbFileInfo, &pHeader->ArchiveSize64, sizeof(ULONGLONG), pcbLengthNeeded); + + case SFileMpqArchiveSize: + return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwArchiveSize, sizeof(DWORD), pcbLengthNeeded); + + case SFileMpqMaxFileCount: + return GetInfo(pvFileInfo, cbFileInfo, &ha->dwMaxFileCount, sizeof(DWORD), pcbLengthNeeded); + + case SFileMpqFileTableSize: + return GetInfo(pvFileInfo, cbFileInfo, &ha->dwFileTableSize, sizeof(DWORD), pcbLengthNeeded); + + case SFileMpqSectorSize: + return GetInfo(pvFileInfo, cbFileInfo, &ha->dwSectorSize, sizeof(DWORD), pcbLengthNeeded); + + case SFileMpqNumberOfFiles: + dwInt32Value = GetMpqFileCount(ha); + return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded); + + case SFileMpqRawChunkSize: + if(pHeader->dwRawChunkSize == 0) + return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwRawChunkSize, sizeof(DWORD), pcbLengthNeeded); + + case SFileMpqStreamFlags: + FileStream_GetFlags(ha->pStream, &dwInt32Value); + return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded); + + case SFileMpqFlags: + return GetInfo(pvFileInfo, cbFileInfo, &ha->dwFlags, sizeof(DWORD), pcbLengthNeeded); + + case SFileInfoPatchChain: + return GetInfo_PatchChain(hf, pvFileInfo, cbFileInfo, pcbLengthNeeded); + + case SFileInfoFileEntry: + if(pFileEntry == NULL) + return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + return GetInfo_FileEntry(pvFileInfo, cbFileInfo, pFileEntry, pcbLengthNeeded); + + case SFileInfoHashEntry: + return GetInfo(pvFileInfo, cbFileInfo, hf->pHashEntry, sizeof(TMPQHash), pcbLengthNeeded); + + case SFileInfoHashIndex: + return GetInfo(pvFileInfo, cbFileInfo, &hf->dwHashIndex, sizeof(DWORD), pcbLengthNeeded); + + case SFileInfoNameHash1: + return GetInfo(pvFileInfo, cbFileInfo, &hf->pHashEntry->dwName1, sizeof(DWORD), pcbLengthNeeded); + + case SFileInfoNameHash2: + return GetInfo(pvFileInfo, cbFileInfo, &hf->pHashEntry->dwName2, sizeof(DWORD), pcbLengthNeeded); + + case SFileInfoNameHash3: + return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->FileNameHash, sizeof(ULONGLONG), pcbLengthNeeded); + + case SFileInfoLocale: + dwInt32Value = hf->pHashEntry->lcLocale; + return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded); + + case SFileInfoFileIndex: + dwInt32Value = (DWORD)(pFileEntry - hf->ha->pFileTable); + return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded); + + case SFileInfoByteOffset: + return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->ByteOffset, sizeof(ULONGLONG), pcbLengthNeeded); + + case SFileInfoFileTime: + return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->FileTime, sizeof(ULONGLONG), pcbLengthNeeded); + + case SFileInfoFileSize: + return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->dwFileSize, sizeof(DWORD), pcbLengthNeeded); + + case SFileInfoCompressedSize: + return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->dwCmpSize, sizeof(DWORD), pcbLengthNeeded); + + case SFileInfoFlags: + return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->dwFlags, sizeof(DWORD), pcbLengthNeeded); + + case SFileInfoEncryptionKey: + return GetInfo(pvFileInfo, cbFileInfo, &hf->dwFileKey, sizeof(DWORD), pcbLengthNeeded); + + case SFileInfoEncryptionKeyRaw: + dwInt32Value = hf->dwFileKey; + if(pFileEntry->dwFlags & MPQ_FILE_FIX_KEY) + dwInt32Value = (dwInt32Value ^ pFileEntry->dwFileSize) - (DWORD)hf->MpqFilePos; + return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded); + + case SFileInfoCRC32: + return GetInfo(pvFileInfo, cbFileInfo, &hf->pFileEntry->dwCrc32, sizeof(DWORD), pcbLengthNeeded); + } + + // Invalid info class + return GetInfo_ReturdwErrCode(ERROR_INVALID_PARAMETER); +} + +bool WINAPI SFileFreeFileInfo(void * pvFileInfo, SFileInfoClass InfoClass) +{ + switch(InfoClass) + { + case SFileMpqHetTable: + FreeHetTable((TMPQHetTable *)pvFileInfo); + return true; + + case SFileMpqBetTable: + FreeBetTable((TMPQBetTable *)pvFileInfo); + return true; + + default: + break; + } + + SetLastError(ERROR_INVALID_PARAMETER); + return false; +} + +//----------------------------------------------------------------------------- +// Tries to retrieve the file name + +struct TFileHeader2Ext +{ + DWORD dwOffset00Data; // Required data at offset 00 (32-bits) + DWORD dwOffset00Mask; // Mask for data at offset 00 (32 bits). 0 = data are ignored + DWORD dwOffset04Data; // Required data at offset 04 (32-bits) + DWORD dwOffset04Mask; // Mask for data at offset 04 (32 bits). 0 = data are ignored + const char * szExt; // Supplied extension, if the condition is true +}; + +static TFileHeader2Ext data2ext[] = +{ + {0x00005A4D, 0x0000FFFF, 0x00000000, 0x00000000, "exe"}, // EXE files + {0x00000006, 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, "dc6"}, // EXE files + {0x1A51504D, 0xFFFFFFFF, 0x00000000, 0x00000000, "mpq"}, // MPQ archive header ID ('MPQ\x1A') + {0x46464952, 0xFFFFFFFF, 0x00000000, 0x00000000, "wav"}, // WAVE header 'RIFF' + {0x324B4D53, 0xFFFFFFFF, 0x00000000, 0x00000000, "smk"}, // Old "Smacker Video" files 'SMK2' + {0x694B4942, 0xFFFFFFFF, 0x00000000, 0x00000000, "bik"}, // Bink video files (new) + {0x0801050A, 0xFFFFFFFF, 0x00000000, 0x00000000, "pcx"}, // PCX images used in Diablo I + {0x544E4F46, 0xFFFFFFFF, 0x00000000, 0x00000000, "fnt"}, // Font files used in Diablo II + {0x6D74683C, 0xFFFFFFFF, 0x00000000, 0x00000000, "html"}, // HTML 'ha->pFileTable), data2ext[i].szExt); + + // Save the pseudo-name in the file entry as well + AllocateFileName(hf->ha, pFileEntry, szPseudoName); + + // If the caller wants to copy the file name, do it + if(szFileName != NULL) + strcpy(szFileName, szPseudoName); + return ERROR_SUCCESS; + } + } + } + + return ERROR_CAN_NOT_COMPLETE; +} + +bool WINAPI SFileGetFileName(HANDLE hFile, char * szFileName) +{ + TMPQFile * hf = (TMPQFile *)hFile; // MPQ File handle + DWORD dwErrCode = ERROR_INVALID_HANDLE; + + // Check valid parameters + if(IsValidFileHandle(hFile)) + { + TFileEntry * pFileEntry = hf->pFileEntry; + + // For MPQ files, retrieve the file name from the file entry + if(hf->pStream == NULL) + { + if(pFileEntry != NULL) + { + // If the file name is not there yet, create a pseudo name + if(pFileEntry->szFileName == NULL) + dwErrCode = CreatePseudoFileName(hFile, pFileEntry, szFileName); + + // Copy the file name to the output buffer, if any + if(pFileEntry->szFileName && szFileName) + { + strcpy(szFileName, pFileEntry->szFileName); + dwErrCode = ERROR_SUCCESS; + } + } + } + + // For local files, copy the file name from the stream + else + { + if(szFileName != NULL) + { + const TCHAR * szStreamName = FileStream_GetFileName(hf->pStream); + StringCopy(szFileName, MAX_PATH, szStreamName); + } + dwErrCode = ERROR_SUCCESS; + } + } + + if(dwErrCode != ERROR_SUCCESS) + SetLastError(dwErrCode); + return (dwErrCode == ERROR_SUCCESS); +} + diff --git a/StormLib/src/SFileListFile.cpp b/StormLib/src/SFileListFile.cpp new file mode 100644 index 000000000..c36f1812c --- /dev/null +++ b/StormLib/src/SFileListFile.cpp @@ -0,0 +1,686 @@ +/*****************************************************************************/ +/* SListFile.cpp Copyright (c) Ladislav Zezula 2004 */ +/*---------------------------------------------------------------------------*/ +/* Description: */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 12.06.04 1.00 Lad The first version of SListFile.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" +#include + +//----------------------------------------------------------------------------- +// Listfile entry structure + +#define CACHE_BUFFER_SIZE 0x1000 // Size of the cache buffer +#define MAX_LISTFILE_SIZE 0x8000000 // Maximum accepted listfile size is 128 MB + +union TListFileHandle +{ + TFileStream * pStream; // Opened local file + HANDLE hFile; // Opened MPQ file +}; + +struct TListFileCache +{ + char * szWildCard; // Self-relative pointer to file mask + LPBYTE pBegin; // The begin of the listfile cache + LPBYTE pPos; // Current position in the cache + LPBYTE pEnd; // The last character in the file cache + DWORD dwFlags; // Flags from TMPQArchive + +// char szWildCard[wildcard_length]; // Followed by the name mask (if any) +// char szListFile[listfile_length]; // Followed by the listfile (if any) +}; + +typedef bool (*LOAD_LISTFILE)(TListFileHandle * pHandle, void * pvBuffer, DWORD cbBuffer, LPDWORD pdwBytesRead); + +//----------------------------------------------------------------------------- +// Local functions (cache) + +// In SFileFindFile.cll +bool SFileCheckWildCard(const char * szString, const char * szWildCard); + +static char * CopyListLine(char * szListLine, const char * szFileName) +{ + // Copy the string + while (szFileName[0] != 0) + { + *szListLine++ = *szFileName++; + } + // Append the end-of-line + *szListLine++ = 0x0D; + *szListLine++ = 0x0A; + return szListLine; +} + +static bool LoadListFile_Stream(TListFileHandle * pHandle, void * pvBuffer, DWORD cbBuffer, LPDWORD pdwBytesRead) +{ + ULONGLONG ByteOffset = 0; + bool bResult; + + bResult = FileStream_Read(pHandle->pStream, &ByteOffset, pvBuffer, cbBuffer); + if(bResult) + *pdwBytesRead = cbBuffer; + return bResult; +} + +static bool LoadListFile_MPQ(TListFileHandle * pHandle, void * pvBuffer, DWORD cbBuffer, LPDWORD pdwBytesRead) +{ + return SFileReadFile(pHandle->hFile, pvBuffer, cbBuffer, pdwBytesRead, NULL); +} + +static bool FreeListFileCache(TListFileCache * pCache) +{ + // Valid parameter check + if(pCache != NULL) + STORM_FREE(pCache); + return true; +} + +static TListFileCache * CreateListFileCache( + LOAD_LISTFILE PfnLoadFile, + TListFileHandle * pHandle, + const char * szWildCard, + DWORD dwFileSize, + DWORD dwMaxSize, + DWORD dwFlags) +{ + TListFileCache * pCache = NULL; + size_t cchWildCardAligned = 0; + size_t cchWildCard = 0; + DWORD dwBytesRead = 0; + + // Get the amount of bytes that need to be allocated + if(dwFileSize == 0 || dwFileSize > dwMaxSize) + return NULL; + + // Append buffer for name mask, if any + if(szWildCard != NULL) + { + cchWildCard = strlen(szWildCard) + 1; + cchWildCardAligned = (cchWildCard + 3) & 0xFFFFFFFC; + } + + // Allocate cache for one file block + pCache = (TListFileCache *)STORM_ALLOC(BYTE, sizeof(TListFileCache) + cchWildCardAligned + dwFileSize + 1); + if(pCache != NULL) + { + // Clear the entire structure + memset(pCache, 0, sizeof(TListFileCache) + cchWildCard); + pCache->dwFlags = dwFlags; + + // Shall we copy the mask? + if(cchWildCard != 0) + { + pCache->szWildCard = (char *)(pCache + 1); + memcpy(pCache->szWildCard, szWildCard, cchWildCard); + } + + // Fill-in the rest of the cache pointers + pCache->pBegin = (LPBYTE)(pCache + 1) + cchWildCardAligned; + + // Load the entire listfile to the cache + PfnLoadFile(pHandle, pCache->pBegin, dwFileSize, &dwBytesRead); + if(dwBytesRead != 0) + { + // Allocate pointers + pCache->pPos = pCache->pBegin; + pCache->pEnd = pCache->pBegin + dwBytesRead; + } + else + { + FreeListFileCache(pCache); + pCache = NULL; + } + } + + // Return the cache + return pCache; +} + +static TListFileCache * CreateListFileCache( + HANDLE hMpq, + const TCHAR * szListFile, + const char * szWildCard, + DWORD dwMaxSize, + DWORD dwFlags) +{ + TListFileCache * pCache = NULL; + TListFileHandle ListHandle = {NULL}; + + // Put default value to dwMaxSize + if(dwMaxSize == 0) + dwMaxSize = MAX_LISTFILE_SIZE; + + // Internal listfile: hMPQ must be non NULL and szListFile must be NULL. + // We load the MPQ::(listfile) file + if(hMpq != NULL && szListFile == NULL) + { + DWORD dwFileSize = 0; + + // Open the file from the MPQ + if(SFileOpenFileEx(hMpq, LISTFILE_NAME, 0, &ListHandle.hFile)) + { + // Get the file size and create the listfile cache + dwFileSize = SFileGetFileSize(ListHandle.hFile, NULL); + pCache = CreateListFileCache(LoadListFile_MPQ, &ListHandle, szWildCard, dwFileSize, dwMaxSize, dwFlags); + + // Close the MPQ file + SFileCloseFile(ListHandle.hFile); + } + + // Return the loaded cache + return pCache; + } + + // External listfile: hMpq must be NULL and szListFile must be non-NULL. + // We load the file using TFileStream + if(hMpq == NULL && szListFile != NULL) + { + ULONGLONG FileSize = 0; + + // Open the local file + ListHandle.pStream = FileStream_OpenFile(szListFile, STREAM_FLAG_READ_ONLY); + if(ListHandle.pStream != NULL) + { + // Verify the file size + FileStream_GetSize(ListHandle.pStream, &FileSize); + if(0 < FileSize && FileSize < dwMaxSize) + { + pCache = CreateListFileCache(LoadListFile_Stream, &ListHandle, szWildCard, (DWORD)FileSize, dwMaxSize, dwFlags); + } + + // Close the stream + FileStream_Close(ListHandle.pStream); + } + + // Return the loaded cache + return pCache; + } + + // This combination should never happen + SetLastError(ERROR_INVALID_PARAMETER); + assert(false); + return NULL; +} + +#ifdef _DEBUG +/* +TMPQNameCache * CreateNameCache(HANDLE hListFile, const char * szSearchMask) +{ + TMPQNameCache * pNameCache; + char * szCachePointer; + size_t cbToAllocate; + size_t nMaskLength = 1; + DWORD dwBytesRead = 0; + DWORD dwFileSize; + + // Get the size of the listfile. Ignore zero or too long ones + dwFileSize = SFileGetFileSize(hListFile, NULL); + if(dwFileSize == 0 || dwFileSize > MAX_LISTFILE_SIZE) + return NULL; + + // Get the length of the search mask + if(szSearchMask == NULL) + szSearchMask = "*"; + nMaskLength = strlen(szSearchMask) + 1; + + // Allocate the name cache + cbToAllocate = sizeof(TMPQNameCache) + nMaskLength + dwFileSize + 1; + pNameCache = (TMPQNameCache *)STORM_ALLOC(BYTE, cbToAllocate); + if(pNameCache != NULL) + { + // Initialize the name cache + memset(pNameCache, 0, sizeof(TMPQNameCache)); + pNameCache->TotalCacheSize = (DWORD)(nMaskLength + dwFileSize + 1); + szCachePointer = (char *)(pNameCache + 1); + + // Copy the search mask, if any + memcpy(szCachePointer, szSearchMask, nMaskLength); + pNameCache->FirstNameOffset = (DWORD)nMaskLength; + pNameCache->FreeSpaceOffset = (DWORD)nMaskLength; + + // Read the listfile itself + SFileSetFilePointer(hListFile, 0, NULL, FILE_BEGIN); + SFileReadFile(hListFile, szCachePointer + nMaskLength, dwFileSize, &dwBytesRead, NULL); + + // If nothing has been read from the listfile, clear the cache + if(dwBytesRead == 0) + { + STORM_FREE(pNameCache); + return NULL; + } + + // Move the free space offset + pNameCache->FreeSpaceOffset = pNameCache->FirstNameOffset + dwBytesRead + 1; + szCachePointer[nMaskLength + dwBytesRead] = 0; + } + + return pNameCache; +} + +static void FreeNameCache(TMPQNameCache * pNameCache) +{ + if(pNameCache != NULL) + STORM_FREE(pNameCache); + pNameCache = NULL; +} +*/ +#endif // _DEBUG + +static char * ReadListFileLine(TListFileCache * pCache, size_t * PtrLength) +{ + LPBYTE pbLineBegin; + LPBYTE pbLineEnd; + + // Skip newlines. Keep spaces and tabs, as they can be a legal part of the file name + while(pCache->pPos < pCache->pEnd && (pCache->pPos[0] == 0x0A || pCache->pPos[0] == 0x0D)) + pCache->pPos++; + + // Set the line begin and end + if(pCache->pPos >= pCache->pEnd) + return NULL; + pbLineBegin = pbLineEnd = pCache->pPos; + + // Find the end of the line + while(pCache->pPos < pCache->pEnd && pCache->pPos[0] != 0x0A && pCache->pPos[0] != 0x0D) + pCache->pPos++; + + // Remember the end of the line + pbLineEnd = pCache->pPos++; + pbLineEnd[0] = 0; + + // Give the line to the caller + if(PtrLength != NULL) + PtrLength[0] = (size_t)(pbLineEnd - pbLineBegin); + return (char *)pbLineBegin; +} + +static int STORMLIB_CDECL CompareFileNodes(const void * p1, const void * p2) +{ + char * szFileName1 = *(char **)p1; + char * szFileName2 = *(char **)p2; + + return _stricmp(szFileName1, szFileName2); +} + +static LPBYTE CreateListFile(TMPQArchive * ha, DWORD * pcbListFile) +{ + TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; + TFileEntry * pFileEntry; + char ** SortTable = NULL; + char * szListFile = NULL; + char * szListLine; + size_t nFileNodes = 0; + size_t cbListFile = 0; + size_t nIndex0; + size_t nIndex1; + + // Allocate the table for sorting listfile + SortTable = STORM_ALLOC(char*, ha->dwFileTableSize); + if(SortTable == NULL) + return NULL; + + // Construct the sort table + // Note: in MPQs with multiple locale versions of the same file, + // this code causes adding multiple listfile entries. + // They will get removed after the listfile sorting + for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) + { + // Only take existing items + if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) && pFileEntry->szFileName != NULL) + { + // Ignore pseudo-names and internal names + if(!IsPseudoFileName(pFileEntry->szFileName, NULL) && !IsInternalMpqFileName(pFileEntry->szFileName)) + { + for (int i = 0; i < strlen(pFileEntry->szFileName); i++) + { + if (pFileEntry->szFileName[i] == '/') + pFileEntry->szFileName[i] = '\\'; + } + + SortTable[nFileNodes++] = pFileEntry->szFileName; + } + } + } + + // Remove duplicities + if(nFileNodes > 0) + { + // Sort the table + qsort(SortTable, nFileNodes, sizeof(char *), CompareFileNodes); + + // Count the 0-th item + cbListFile += strlen(SortTable[0]) + 2; + + // Walk through the items and only use the ones that are not duplicated + for(nIndex0 = 0, nIndex1 = 1; nIndex1 < nFileNodes; nIndex1++) + { + // If the next file node is different, we will include it to the result listfile + if(_stricmp(SortTable[nIndex1], SortTable[nIndex0]) != 0) + { + cbListFile += strlen(SortTable[nIndex1]) + 2; + nIndex0 = nIndex1; + } + } + + // Now allocate buffer for the entire listfile + szListFile = szListLine = STORM_ALLOC(char, cbListFile + 1); + if(szListFile != NULL) + { + // Copy the 0-th item + szListLine = CopyListLine(szListLine, SortTable[0]); + + // Walk through the items and only use the ones that are not duplicated + for(nIndex0 = 0, nIndex1 = 1; nIndex1 < nFileNodes; nIndex1++) + { + // If the next file node is different, we will include it to the result listfile + if(_stricmp(SortTable[nIndex1], SortTable[nIndex0]) != 0) + { + // Copy the listfile line + szListLine = CopyListLine(szListLine, SortTable[nIndex1]); + nIndex0 = nIndex1; + } + } + + // Sanity check - does the size match? + assert((size_t)(szListLine - szListFile) == cbListFile); + } + } + else + { + szListFile = STORM_ALLOC(char, 1); + cbListFile = 0; + } + + // Free the sort table + STORM_FREE(SortTable); + + // Give away the listfile + if(pcbListFile != NULL) + *pcbListFile = (DWORD)cbListFile; + return (LPBYTE)szListFile; +} + +//----------------------------------------------------------------------------- +// Local functions (listfile nodes) + +// Adds a name into the list of all names. For each locale in the MPQ, +// one entry will be created +// If the file name is already there, does nothing. +static DWORD SListFileCreateNodeForAllLocales(TMPQArchive * ha, const char * szFileName) +{ + TFileEntry * pFileEntry; + TMPQHash * pFirstHash; + TMPQHash * pHash; + + // If we have HET table, use that one + if(ha->pHetTable != NULL) + { + pFileEntry = GetFileEntryLocale(ha, szFileName, 0); + if(pFileEntry != NULL) + { + // Allocate file name for the file entry + AllocateFileName(ha, pFileEntry, szFileName); + } + + return ERROR_SUCCESS; + } + + // If we have hash table, we use it + if(ha->pHashTable != NULL) + { + // Go while we found something + pFirstHash = pHash = GetFirstHashEntry(ha, szFileName); + while(pHash != NULL) + { + // Allocate file name for the file entry + AllocateFileName(ha, ha->pFileTable + MPQ_BLOCK_INDEX(pHash), szFileName); + + // Now find the next language version of the file + pHash = GetNextHashEntry(ha, pFirstHash, pHash); + } + + return ERROR_SUCCESS; + } + + return ERROR_CAN_NOT_COMPLETE; +} + +// Saves the whole listfile to the MPQ +DWORD SListFileSaveToMpq(TMPQArchive * ha) +{ + TMPQFile * hf = NULL; + LPBYTE pbListFile; + DWORD cbListFile = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Only save the listfile if we should do so + if(ha->dwFileFlags1 != 0) + { + // At this point, we expect to have at least one reserved entry in the file table + assert(ha->dwFlags & MPQ_FLAG_LISTFILE_NEW); + assert(ha->dwReservedFiles > 0); + + // Create the raw data that is to be written to (listfile) + // Note: Creating the raw data before the (listfile) has been created in the MPQ + // causes that the name of the listfile will not be included in the listfile itself. + // That is OK, because (listfile) in Blizzard MPQs does not contain it either. + pbListFile = CreateListFile(ha, &cbListFile); + if(pbListFile != NULL) + { + // Determine the real flags for (listfile) + if(ha->dwFileFlags1 == MPQ_FILE_DEFAULT_INTERNAL) + ha->dwFileFlags1 = GetDefaultSpecialFileFlags(cbListFile, ha->pHeader->wFormatVersion); + + // Create the listfile in the MPQ + dwErrCode = SFileAddFile_Init(ha, LISTFILE_NAME, + 0, + cbListFile, + LANG_NEUTRAL, + ha->dwFileFlags1 | MPQ_FILE_REPLACEEXISTING, + &hf); + + // Write the listfile raw data to it + if(dwErrCode == ERROR_SUCCESS) + { + // Write the content of the listfile to the MPQ + dwErrCode = SFileAddFile_Write(hf, pbListFile, cbListFile, MPQ_COMPRESSION_ZLIB); + SFileAddFile_Finish(hf); + } + + // Clear the listfile flags + ha->dwFlags &= ~(MPQ_FLAG_LISTFILE_NEW | MPQ_FLAG_LISTFILE_NONE); + ha->dwReservedFiles--; + + // Free the listfile buffer + STORM_FREE(pbListFile); + } + else + { + // If the (listfile) file would be empty, its OK + dwErrCode = (cbListFile == 0) ? ERROR_SUCCESS : ERROR_NOT_ENOUGH_MEMORY; + } + } + + return dwErrCode; +} + +static DWORD SFileAddArbitraryListFile( + TMPQArchive * ha, + HANDLE hMpq, + const TCHAR * szListFile, + DWORD dwMaxSize) +{ + TListFileCache * pCache = NULL; + + // Create the listfile cache for that file + pCache = CreateListFileCache(hMpq, szListFile, NULL, dwMaxSize, ha->dwFlags); + if(pCache != NULL) + { + char * szFileName; + size_t nLength = 0; + + // Get the next line + while((szFileName = ReadListFileLine(pCache, &nLength)) != NULL) + { + // Add the line to the MPQ + if(nLength != 0) + SListFileCreateNodeForAllLocales(ha, szFileName); + } + + // Delete the cache + FreeListFileCache(pCache); + } + + return (pCache != NULL) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT; +} + +static DWORD SFileAddInternalListFile( + TMPQArchive * ha, + HANDLE hMpq) +{ + TMPQHash * pFirstHash; + TMPQHash * pHash; + LCID lcSaveLocale = g_lcFileLocale; + DWORD dwMaxSize = MAX_LISTFILE_SIZE; + DWORD dwErrCode = ERROR_SUCCESS; + + // If there is hash table, we need to support multiple listfiles + // with different locales (BrooDat.mpq) + if(ha->pHashTable != NULL) + { + // If the archive is a malformed map, ignore too large listfiles + if(ha->dwFlags & MPQ_FLAG_MALFORMED) + dwMaxSize = 0x40000; + + pFirstHash = pHash = GetFirstHashEntry(ha, LISTFILE_NAME); + while(dwErrCode == ERROR_SUCCESS && pHash != NULL) + { + // Set the prefered locale to that from list file + SFileSetLocale(pHash->lcLocale); + + // Add that listfile + dwErrCode = SFileAddArbitraryListFile(ha, hMpq, NULL, dwMaxSize); + + // Move to the next hash + pHash = GetNextHashEntry(ha, pFirstHash, pHash); + } + + // Restore the original locale + SFileSetLocale(lcSaveLocale); + } + else + { + // Add the single listfile + dwErrCode = SFileAddArbitraryListFile(ha, hMpq, NULL, dwMaxSize); + } + + // Return the result of the operation + return dwErrCode; +} + +static bool DoListFileSearch(TListFileCache * pCache, SFILE_FIND_DATA * lpFindFileData) +{ + // Check for the valid search handle + if(pCache != NULL) + { + char * szFileName; + size_t nLength = 0; + + // Get the next line + while((szFileName = ReadListFileLine(pCache, &nLength)) != NULL) + { + // Check search mask + if(nLength != 0 && SFileCheckWildCard(szFileName, pCache->szWildCard)) + { + if(nLength >= sizeof(lpFindFileData->cFileName)) + nLength = sizeof(lpFindFileData->cFileName) - 1; + + memcpy(lpFindFileData->cFileName, szFileName, nLength); + lpFindFileData->cFileName[nLength] = 0; + return true; + } + } + } + + // No more files + memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA)); + SetLastError(ERROR_NO_MORE_FILES); + return false; +} + +//----------------------------------------------------------------------------- +// File functions + +// Adds a listfile into the MPQ archive. +DWORD WINAPI SFileAddListFile(HANDLE hMpq, const TCHAR * szListFile) +{ + TMPQArchive * ha = (TMPQArchive *)hMpq; + DWORD dwErrCode = ERROR_SUCCESS; + + // Add the listfile for each MPQ in the patch chain + while(ha != NULL) + { + if(szListFile != NULL) + dwErrCode = SFileAddArbitraryListFile(ha, NULL, szListFile, MAX_LISTFILE_SIZE); + else + dwErrCode = SFileAddInternalListFile(ha, hMpq); + + // Also, add three special files to the listfile: + // (listfile) itself, (attributes) and (signature) + SListFileCreateNodeForAllLocales(ha, LISTFILE_NAME); + SListFileCreateNodeForAllLocales(ha, SIGNATURE_NAME); + SListFileCreateNodeForAllLocales(ha, ATTRIBUTES_NAME); + + // Move to the next archive in the chain + ha = ha->haPatch; + } + + return dwErrCode; +} + +//----------------------------------------------------------------------------- +// Enumerating files in listfile + +HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const TCHAR * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData) +{ + TListFileCache * pCache = NULL; + + // Initialize the structure with zeros + memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA)); + + // Open the local/internal listfile + pCache = CreateListFileCache(hMpq, szListFile, szMask, 0, 0); + if(pCache != NULL) + { + if(!DoListFileSearch(pCache, lpFindFileData)) + { + memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA)); + SetLastError(ERROR_NO_MORE_FILES); + FreeListFileCache(pCache); + pCache = NULL; + } + } + + // Return the listfile cache as handle + return (HANDLE)pCache; +} + +bool WINAPI SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData) +{ + return DoListFileSearch((TListFileCache *)hFind, lpFindFileData); +} + +bool WINAPI SListFileFindClose(HANDLE hFind) +{ + TListFileCache * pCache = (TListFileCache *)hFind; + + return FreeListFileCache(pCache); +} + diff --git a/StormLib/src/SFileOpenArchive.cpp b/StormLib/src/SFileOpenArchive.cpp new file mode 100644 index 000000000..ea298500e --- /dev/null +++ b/StormLib/src/SFileOpenArchive.cpp @@ -0,0 +1,658 @@ +/*****************************************************************************/ +/* SFileOpenArchive.cpp Copyright Ladislav Zezula 1999 */ +/* */ +/* Author : Ladislav Zezula */ +/* E-mail : ladik@zezula.net */ +/* WWW : www.zezula.net */ +/*---------------------------------------------------------------------------*/ +/* Implementation of archive functions */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* xx.xx.xx 1.00 Lad Created */ +/* 19.11.03 1.01 Dan Big endian handling */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" + +#define HEADER_SEARCH_BUFFER_SIZE 0x1000 + +//----------------------------------------------------------------------------- +// Local functions + +static MTYPE CheckMapType(LPCTSTR szFileName, LPBYTE pbHeaderBuffer, size_t cbHeaderBuffer) +{ + LPDWORD HeaderInt32 = (LPDWORD)pbHeaderBuffer; + LPCTSTR szExtension; + + // Don't do any checks if there is not at least 16 bytes + if(cbHeaderBuffer > 0x10) + { + DWORD DwordValue0 = BSWAP_INT32_UNSIGNED(HeaderInt32[0]); + DWORD DwordValue1 = BSWAP_INT32_UNSIGNED(HeaderInt32[1]); + DWORD DwordValue2 = BSWAP_INT32_UNSIGNED(HeaderInt32[2]); + DWORD DwordValue3 = BSWAP_INT32_UNSIGNED(HeaderInt32[3]); + + // Test for AVI files (Warcraft III cinematics) - 'RIFF', 'AVI ' or 'LIST' + if(DwordValue0 == 0x46464952 && DwordValue2 == 0x20495641 && DwordValue3 == 0x5453494C) + return MapTypeAviFile; + + // Check for Starcraft II maps + if((szExtension = _tcsrchr(szFileName, _T('.'))) != NULL) + { + // The "NP_Protect" protector places fake Warcraft III header + // into the Starcraft II maps, whilst SC2 maps have no other header but MPQ v4 + if(!_tcsicmp(szExtension, _T(".s2ma")) || !_tcsicmp(szExtension, _T(".SC2Map")) || !_tcsicmp(szExtension, _T(".SC2Mod"))) + { + return MapTypeStarcraft2; + } + } + + // Check for Warcraft III maps + if(DwordValue0 == 0x57334D48 && DwordValue1 == 0x00000000) + return MapTypeWarcraft3; + } + + // MIX files are DLL files that contain MPQ in overlay. + // Only Warcraft III is able to load them, so we consider them Warcraft III maps + if(cbHeaderBuffer > 0x200 && pbHeaderBuffer[0] == 'M' && pbHeaderBuffer[1] == 'Z') + { + // Check the value of IMAGE_DOS_HEADER::e_lfanew at offset 0x3C + if(0 < HeaderInt32[0x0F] && HeaderInt32[0x0F] < 0x10000) + return MapTypeWarcraft3; + } + + // No special map type recognized + return MapTypeNotRecognized; +} + +static TMPQUserData * IsValidMpqUserData(ULONGLONG ByteOffset, ULONGLONG FileSize, void * pvUserData) +{ + TMPQUserData * pUserData; + + // BSWAP the source data and copy them to our buffer + BSWAP_ARRAY32_UNSIGNED(pvUserData, sizeof(TMPQUserData)); + pUserData = (TMPQUserData *)pvUserData; + + // Check the sizes + if(pUserData->cbUserDataHeader <= pUserData->cbUserDataSize && pUserData->cbUserDataSize <= pUserData->dwHeaderOffs) + { + // Move to the position given by the userdata + ByteOffset += pUserData->dwHeaderOffs; + + // The MPQ header should be within range of the file size + if((ByteOffset + MPQ_HEADER_SIZE_V1) < FileSize) + { + // Note: We should verify if there is the MPQ header. + // However, the header could be at any position below that + // that is multiplier of 0x200 + return (TMPQUserData *)pvUserData; + } + } + + return NULL; +} + +// This function gets the right positions of the hash table and the block table. +static DWORD VerifyMpqTablePositions(TMPQArchive * ha, ULONGLONG FileSize) +{ + TMPQHeader * pHeader = ha->pHeader; + ULONGLONG ByteOffset; + //bool bMalformed = (ha->dwFlags & MPQ_FLAG_MALFORMED) ? true : false; + + // Check the begin of HET table + if(pHeader->HetTablePos64) + { + ByteOffset = ha->MpqPos + pHeader->HetTablePos64; + if(ByteOffset > FileSize) + return ERROR_BAD_FORMAT; + } + + // Check the begin of BET table + if(pHeader->BetTablePos64) + { + ByteOffset = ha->MpqPos + pHeader->BetTablePos64; + if(ByteOffset > FileSize) + return ERROR_BAD_FORMAT; + } + + // Check the begin of hash table + if(pHeader->wHashTablePosHi || pHeader->dwHashTablePos) + { + ByteOffset = FileOffsetFromMpqOffset(ha, MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos)); + if(ByteOffset > FileSize) + return ERROR_BAD_FORMAT; + } + + // Check the begin of block table + if(pHeader->wBlockTablePosHi || pHeader->dwBlockTablePos) + { + ByteOffset = FileOffsetFromMpqOffset(ha, MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos)); + if(ByteOffset > FileSize) + return ERROR_BAD_FORMAT; + } + + // Check the begin of hi-block table + //if(pHeader->HiBlockTablePos64 != 0) + //{ + // ByteOffset = ha->MpqPos + pHeader->HiBlockTablePos64; + // if(ByteOffset > FileSize) + // return ERROR_BAD_FORMAT; + //} + + // All OK. + return ERROR_SUCCESS; +} + +//----------------------------------------------------------------------------- +// Support for alternate markers. Call before opening an archive + +#define SFILE_MARKERS_MIN_SIZE (sizeof(DWORD) + sizeof(DWORD) + sizeof(const char *) + sizeof(const char *)) + +bool WINAPI SFileSetArchiveMarkers(PSFILE_MARKERS pMarkers) +{ + // Check structure minimum size + if(pMarkers == NULL || pMarkers->dwSize < SFILE_MARKERS_MIN_SIZE) + { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + // Make sure that the MPQ cryptography is initialized at this time + InitializeMpqCryptography(); + + // Remember the marker for MPQ header + if(pMarkers->dwSignature != 0) + g_dwMpqSignature = pMarkers->dwSignature; + + // Remember the encryption key for hash table + if(pMarkers->szHashTableKey != NULL) + g_dwHashTableKey = HashString(pMarkers->szHashTableKey, MPQ_HASH_FILE_KEY); + + // Remember the encryption key for block table + if(pMarkers->szBlockTableKey != NULL) + g_dwBlockTableKey = HashString(pMarkers->szBlockTableKey, MPQ_HASH_FILE_KEY); + + // Succeeded + return true; +} + +//----------------------------------------------------------------------------- +// SFileGetLocale and SFileSetLocale +// Set the locale for all newly opened files + +LCID WINAPI SFileGetLocale() +{ + return g_lcFileLocale; +} + +LCID WINAPI SFileSetLocale(LCID lcNewLocale) +{ + g_lcFileLocale = lcNewLocale; + return g_lcFileLocale; +} + +//----------------------------------------------------------------------------- +// SFileOpenArchive +// +// szFileName - MPQ archive file name to open +// dwPriority - When SFileOpenFileEx called, this contains the search priority for searched archives +// dwFlags - See MPQ_OPEN_XXX in StormLib.h +// phMpq - Pointer to store open archive handle + +bool WINAPI SFileOpenArchive( + const TCHAR * szMpqName, + DWORD dwPriority, + DWORD dwFlags, + HANDLE * phMpq) +{ + TMPQUserData * pUserData; + TFileStream * pStream = NULL; // Open file stream + TMPQArchive * ha = NULL; // Archive handle + TFileEntry * pFileEntry; + ULONGLONG FileSize = 0; // Size of the file + LPBYTE pbHeaderBuffer = NULL; // Buffer for searching MPQ header + DWORD dwStreamFlags = (dwFlags & STREAM_FLAGS_MASK); + MTYPE MapType = MapTypeNotChecked; + DWORD dwErrCode = ERROR_SUCCESS; + + // Verify the parameters + if(szMpqName == NULL || *szMpqName == 0 || phMpq == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + // One time initialization of MPQ cryptography + InitializeMpqCryptography(); + dwPriority = dwPriority; + + // If not forcing MPQ v 1.0, also use file bitmap + dwStreamFlags |= (dwFlags & MPQ_OPEN_FORCE_MPQ_V1) ? 0 : STREAM_FLAG_USE_BITMAP; + + // Open the MPQ archive file + pStream = FileStream_OpenFile(szMpqName, dwStreamFlags); + if(pStream == NULL) + return false; + + // Check the file size. There must be at least 0x20 bytes + if(dwErrCode == ERROR_SUCCESS) + { + FileStream_GetSize(pStream, &FileSize); + if(FileSize < MPQ_HEADER_SIZE_V1) + dwErrCode = ERROR_BAD_FORMAT; + } + + // Allocate the MPQhandle + if(dwErrCode == ERROR_SUCCESS) + { + if((ha = STORM_ALLOC(TMPQArchive, 1)) == NULL) + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + + // Allocate buffer for searching MPQ header + if(dwErrCode == ERROR_SUCCESS) + { + pbHeaderBuffer = STORM_ALLOC(BYTE, HEADER_SEARCH_BUFFER_SIZE); + if(pbHeaderBuffer == NULL) + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + + // Find the position of MPQ header + if(dwErrCode == ERROR_SUCCESS) + { + ULONGLONG ByteOffset = 0; + ULONGLONG EndOfSearch = FileSize; + DWORD dwStrmFlags = 0; + DWORD dwHeaderSize; + DWORD dwHeaderID; + bool bSearchComplete = false; + + memset(ha, 0, sizeof(TMPQArchive)); + ha->pfnHashString = HashStringSlash; + ha->pStream = pStream; + pStream = NULL; + + // Set the archive read only if the stream is read-only + FileStream_GetFlags(ha->pStream, &dwStrmFlags); + ha->dwFlags |= (dwStrmFlags & STREAM_FLAG_READ_ONLY) ? MPQ_FLAG_READ_ONLY : 0; + + // Also remember if we shall check sector CRCs when reading file + ha->dwFlags |= (dwFlags & MPQ_OPEN_CHECK_SECTOR_CRC) ? MPQ_FLAG_CHECK_SECTOR_CRC : 0; + + // Also remember if this MPQ is a patch + ha->dwFlags |= (dwFlags & MPQ_OPEN_PATCH) ? MPQ_FLAG_PATCH : 0; + + // Limit the header searching to about 130 MB of data + if(EndOfSearch > 0x08000000) + EndOfSearch = 0x08000000; + + // Find the offset of MPQ header within the file + while(bSearchComplete == false && ByteOffset < EndOfSearch) + { + // Always read at least 0x1000 bytes for performance. + // This is what Storm.dll (2002) does. + DWORD dwBytesAvailable = HEADER_SEARCH_BUFFER_SIZE; + + // Cut the bytes available, if needed + if((FileSize - ByteOffset) < HEADER_SEARCH_BUFFER_SIZE) + dwBytesAvailable = (DWORD)(FileSize - ByteOffset); + + // Read the eventual MPQ header + if(!FileStream_Read(ha->pStream, &ByteOffset, pbHeaderBuffer, dwBytesAvailable)) + { + dwErrCode = GetLastError(); + break; + } + + // Check whether the file is AVI file or a Warcraft III/Starcraft II map + if(MapType == MapTypeNotChecked) + { + // Do nothing if the file is an AVI file + if((MapType = CheckMapType(szMpqName, pbHeaderBuffer, dwBytesAvailable)) == MapTypeAviFile) + { + dwErrCode = ERROR_AVI_FILE; + break; + } + } + + // Search the header buffer + for(DWORD dwInBufferOffset = 0; dwInBufferOffset < dwBytesAvailable; dwInBufferOffset += 0x200) + { + // Copy the data from the potential header buffer to the MPQ header + memcpy(ha->HeaderData, pbHeaderBuffer + dwInBufferOffset, sizeof(ha->HeaderData)); + + // If there is the MPQ user data, process it + // Note that Warcraft III does not check for user data, which is abused by many map protectors + dwHeaderID = BSWAP_INT32_UNSIGNED(ha->HeaderData[0]); + if(MapType != MapTypeWarcraft3 && (dwFlags & MPQ_OPEN_FORCE_MPQ_V1) == 0) + { + if(ha->pUserData == NULL && dwHeaderID == ID_MPQ_USERDATA) + { + // Verify if this looks like a valid user data + pUserData = IsValidMpqUserData(ByteOffset, FileSize, ha->HeaderData); + if(pUserData != NULL) + { + // Fill the user data header + ha->UserDataPos = ByteOffset; + ha->pUserData = &ha->UserData; + memcpy(ha->pUserData, pUserData, sizeof(TMPQUserData)); + + // Continue searching from that position + ByteOffset += ha->pUserData->dwHeaderOffs; + break; + } + } + } + + // There must be MPQ header signature. Note that STORM.dll from Warcraft III actually + // tests the MPQ header size. It must be at least 0x20 bytes in order to load it + // Abused by Spazzler Map protector. Note that the size check is not present + // in Storm.dll v 1.00, so Diablo I code would load the MPQ anyway. + dwHeaderSize = BSWAP_INT32_UNSIGNED(ha->HeaderData[1]); + if(dwHeaderID == g_dwMpqSignature && dwHeaderSize >= MPQ_HEADER_SIZE_V1) + { + // Now convert the header to version 4 + dwErrCode = ConvertMpqHeaderToFormat4(ha, ByteOffset, FileSize, dwFlags, MapType); + if(dwErrCode != ERROR_FAKE_MPQ_HEADER) + { + bSearchComplete = true; + break; + } + } + + // Check for MPK archives (Longwu Online - MPQ fork) + if(MapType == MapTypeNotRecognized && dwHeaderID == ID_MPK) + { + // Now convert the MPK header to MPQ Header version 4 + dwErrCode = ConvertMpkHeaderToFormat4(ha, FileSize, dwFlags); + bSearchComplete = true; + break; + } + + // If searching for the MPQ header is disabled, return an error + if(dwFlags & MPQ_OPEN_NO_HEADER_SEARCH) + { + dwErrCode = ERROR_NOT_SUPPORTED; + bSearchComplete = true; + break; + } + + // Move the pointers + ByteOffset += 0x200; + } + } + + // Did we identify one of the supported headers? + if(dwErrCode == ERROR_SUCCESS) + { + // Set the user data position to the MPQ header, if none + if(ha->pUserData == NULL) + ha->UserDataPos = ByteOffset; + + // Set the position of the MPQ header + ha->pHeader = (TMPQHeader *)ha->HeaderData; + ha->MpqPos = ByteOffset; + ha->FileSize = FileSize; + + // Sector size must be nonzero. + if(ByteOffset >= FileSize || ha->pHeader->wSectorSize == 0) + dwErrCode = ERROR_BAD_FORMAT; + } + } + + // Fix table positions according to format + if(dwErrCode == ERROR_SUCCESS) + { + // Dump the header +// DumpMpqHeader(ha->pHeader); + + // W3x Map Protectors use the fact that War3's Storm.dll ignores the MPQ user data, + // and ignores the MPQ format version as well. The trick is to + // fake MPQ format 2, with an improper hi-word position of hash table and block table + // We can overcome such protectors by forcing opening the archive as MPQ v 1.0 + if(dwFlags & MPQ_OPEN_FORCE_MPQ_V1) + { + ha->pHeader->wFormatVersion = MPQ_FORMAT_VERSION_1; + ha->pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V1; + ha->dwFlags |= MPQ_FLAG_READ_ONLY; + ha->pUserData = NULL; + } + + // Anti-overflow. If the hash table size in the header is + // higher than 0x10000000, it would overflow in 32-bit version + // Observed in the malformed Warcraft III maps + // Example map: MPQ_2016_v1_ProtectedMap_TableSizeOverflow.w3x + ha->pHeader->dwBlockTableSize = (ha->pHeader->dwBlockTableSize & BLOCK_INDEX_MASK); + ha->pHeader->dwHashTableSize = (ha->pHeader->dwHashTableSize & BLOCK_INDEX_MASK); + + // Both MPQ_OPEN_NO_LISTFILE or MPQ_OPEN_NO_ATTRIBUTES trigger read only mode + if(dwFlags & (MPQ_OPEN_NO_LISTFILE | MPQ_OPEN_NO_ATTRIBUTES)) + ha->dwFlags |= MPQ_FLAG_READ_ONLY; + + // Check if the caller wants to force adding listfile + if(dwFlags & MPQ_OPEN_FORCE_LISTFILE) + ha->dwFlags |= MPQ_FLAG_LISTFILE_FORCE; + + // Remember whether whis is a map for Warcraft III + if(MapType == MapTypeWarcraft3) + ha->dwFlags |= MPQ_FLAG_WAR3_MAP; + + // Set the size of file sector + ha->dwSectorSize = (0x200 << ha->pHeader->wSectorSize); + + // Verify if any of the tables doesn't start beyond the end of the file + dwErrCode = VerifyMpqTablePositions(ha, FileSize); + } + + // Read the hash table. Ignore the result, as hash table is no longer required + // Read HET table. Ignore the result, as HET table is no longer required + if(dwErrCode == ERROR_SUCCESS) + { + dwErrCode = LoadAnyHashTable(ha); + } + + // Now, build the file table. It will be built by combining + // the block table, BET table, hi-block table, (attributes) and (listfile). + if(dwErrCode == ERROR_SUCCESS) + { + dwErrCode = BuildFileTable(ha); + } + + // Load the internal listfile and include it to the file table + if(dwErrCode == ERROR_SUCCESS && (dwFlags & MPQ_OPEN_NO_LISTFILE) == 0) + { + // Quick check for (listfile) + pFileEntry = GetFileEntryLocale(ha, LISTFILE_NAME, LANG_NEUTRAL); + if(pFileEntry != NULL) + { + // Ignore result of the operation. (listfile) is optional. + SFileAddListFile((HANDLE)ha, NULL); + ha->dwFileFlags1 = pFileEntry->dwFlags; + } + } + + // Load the "(attributes)" file and merge it to the file table + if(dwErrCode == ERROR_SUCCESS && (dwFlags & MPQ_OPEN_NO_ATTRIBUTES) == 0 && (ha->dwFlags & MPQ_FLAG_BLOCK_TABLE_CUT) == 0) + { + // Quick check for (attributes) + pFileEntry = GetFileEntryLocale(ha, ATTRIBUTES_NAME, LANG_NEUTRAL); + if(pFileEntry != NULL) + { + // Ignore result of the operation. (attributes) is optional. + SAttrLoadAttributes(ha); + ha->dwFileFlags2 = pFileEntry->dwFlags; + } + } + + // Remember whether the archive has weak signature. Only for MPQs format 1.0. + if(dwErrCode == ERROR_SUCCESS) + { + // Quick check for (signature) + pFileEntry = GetFileEntryLocale(ha, SIGNATURE_NAME, LANG_NEUTRAL); + if(pFileEntry != NULL) + { + // Just remember that the archive is weak-signed + assert((pFileEntry->dwFlags & MPQ_FILE_EXISTS) != 0); + ha->dwFileFlags3 = pFileEntry->dwFlags; + } + + // Finally, set the MPQ_FLAG_READ_ONLY if the MPQ was found malformed + ha->dwFlags |= (ha->dwFlags & MPQ_FLAG_MALFORMED) ? MPQ_FLAG_READ_ONLY : 0; + } + + // Cleanup and exit + if(dwErrCode != ERROR_SUCCESS) + { + FileStream_Close(pStream); + FreeArchiveHandle(ha); + SetLastError(dwErrCode); + ha = NULL; + } + + // Free the header buffer + if(pbHeaderBuffer != NULL) + STORM_FREE(pbHeaderBuffer); + if(phMpq != NULL) + *phMpq = ha; + return (dwErrCode == ERROR_SUCCESS); +} + +//----------------------------------------------------------------------------- +// bool WINAPI SFileSetDownloadCallback(HANDLE, SFILE_DOWNLOAD_CALLBACK, void *); +// +// Sets a callback that is called when content is downloaded from the master MPQ +// + +bool WINAPI SFileSetDownloadCallback(HANDLE hMpq, SFILE_DOWNLOAD_CALLBACK DownloadCB, void * pvUserData) +{ + TMPQArchive * ha = (TMPQArchive *)hMpq; + + // Do nothing if 'hMpq' is bad parameter + if(!IsValidMpqHandle(hMpq)) + { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + return FileStream_SetCallback(ha->pStream, DownloadCB, pvUserData); +} + +//----------------------------------------------------------------------------- +// bool SFileFlushArchive(HANDLE hMpq) +// +// Saves all dirty data into MPQ archive. +// Has similar effect like SFileCloseArchive, but the archive is not closed. +// Use on clients who keep MPQ archive open even for write operations, +// and terminating without calling SFileCloseArchive might corrupt the archive. +// + +bool WINAPI SFileFlushArchive(HANDLE hMpq) +{ + TMPQArchive * ha; + DWORD dwResultError = ERROR_SUCCESS; + DWORD dwErrCode; + + // Do nothing if 'hMpq' is bad parameter + if((ha = IsValidMpqHandle(hMpq)) == NULL) + { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + // Only if the MPQ was changed + if(ha->dwFlags & MPQ_FLAG_CHANGED) + { + // Indicate that we are saving MPQ internal structures + ha->dwFlags |= MPQ_FLAG_SAVING_TABLES; + + // Defragment the file table. This will allow us to put the internal files to the end + DefragmentFileTable(ha); + + // + // Create each internal file + // Note that the (signature) file is usually before (listfile) in the file table + // + + if(ha->dwFlags & MPQ_FLAG_SIGNATURE_NEW) + { + dwErrCode = SSignFileCreate(ha); + if(dwErrCode != ERROR_SUCCESS) + dwResultError = dwErrCode; + } + + if(ha->dwFlags & (MPQ_FLAG_LISTFILE_NEW | MPQ_FLAG_LISTFILE_FORCE)) + { + dwErrCode = SListFileSaveToMpq(ha); + if(dwErrCode != ERROR_SUCCESS) + dwResultError = dwErrCode; + } + + if(ha->dwFlags & MPQ_FLAG_ATTRIBUTES_NEW) + { + dwErrCode = SAttrFileSaveToMpq(ha); + if(dwErrCode != ERROR_SUCCESS) + dwResultError = dwErrCode; + } + + // Save HET table, BET table, hash table, block table, hi-block table + if(ha->dwFlags & MPQ_FLAG_CHANGED) + { + // Rebuild the HET table + if(ha->pHetTable != NULL) + RebuildHetTable(ha); + + // Save all MPQ tables first + dwErrCode = SaveMPQTables(ha); + if(dwErrCode != ERROR_SUCCESS) + dwResultError = dwErrCode; + + // If the archive has weak signature, we need to finish it + if(ha->dwFileFlags3 != 0) + { + dwErrCode = SSignFileFinish(ha); + if(dwErrCode != ERROR_SUCCESS) + dwResultError = dwErrCode; + } + } + + // We are no longer saving internal MPQ structures + ha->dwFlags &= ~MPQ_FLAG_SAVING_TABLES; + } + + // Return the error + if(dwResultError != ERROR_SUCCESS) + SetLastError(dwResultError); + return (dwResultError == ERROR_SUCCESS); +} + +//----------------------------------------------------------------------------- +// bool SFileCloseArchive(HANDLE hMpq); +// + +bool WINAPI SFileCloseArchive(HANDLE hMpq) +{ + TMPQArchive * ha = IsValidMpqHandle(hMpq); + bool bResult = false; + + // Only if the handle is valid + if(ha == NULL) + { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + // Invalidate the add file callback so it won't be called + // when saving (listfile) and (attributes) + ha->pfnAddFileCB = NULL; + ha->pvAddFileUserData = NULL; + + // Flush all unsaved data to the storage + bResult = SFileFlushArchive(hMpq); + + // Free all memory used by MPQ archive + FreeArchiveHandle(ha); + return bResult; +} diff --git a/StormLib/src/SFileOpenFileEx.cpp b/StormLib/src/SFileOpenFileEx.cpp new file mode 100644 index 000000000..d77f25e35 --- /dev/null +++ b/StormLib/src/SFileOpenFileEx.cpp @@ -0,0 +1,418 @@ +/*****************************************************************************/ +/* SFileOpenFileEx.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Description : */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* xx.xx.99 1.00 Lad The first version of SFileOpenFileEx.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" + +/*****************************************************************************/ +/* Local functions */ +/*****************************************************************************/ + +static DWORD FindHashIndex(TMPQArchive * ha, DWORD dwFileIndex) +{ + TMPQHash * pHashTableEnd; + TMPQHash * pHash; + DWORD dwFirstIndex = HASH_ENTRY_FREE; + + // Should only be called if the archive has hash table + assert(ha->pHashTable != NULL); + + // Multiple hash table entries can point to the file table entry. + // We need to search all of them + pHashTableEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; + for(pHash = ha->pHashTable; pHash < pHashTableEnd; pHash++) + { + if(MPQ_BLOCK_INDEX(pHash) == dwFileIndex) + { + // Duplicate hash entry found + if(dwFirstIndex != HASH_ENTRY_FREE) + return HASH_ENTRY_FREE; + dwFirstIndex = (DWORD)(pHash - ha->pHashTable); + } + } + + // Return the hash table entry index + return dwFirstIndex; +} + +static const char * GetPatchFileName(TMPQArchive * ha, const char * szFileName, char * szBuffer) +{ + TMPQNamePrefix * pPrefix; + + // Are there patches in the current MPQ? + if(ha->dwFlags & MPQ_FLAG_PATCH) + { + // The patch prefix must be already known here + assert(ha->pPatchPrefix != NULL); + pPrefix = ha->pPatchPrefix; + + // The patch name for "OldWorld\\XXX\\YYY" is "Base\\XXX\YYY" + // We need to remove the "OldWorld\\" prefix + if(!_strnicmp(szFileName, "OldWorld\\", 9)) + szFileName += 9; + + // Create the file name from the known patch entry + memcpy(szBuffer, pPrefix->szPatchPrefix, pPrefix->nLength); + strcpy(szBuffer + pPrefix->nLength, szFileName); + szFileName = szBuffer; + } + + return szFileName; +} + +static bool OpenLocalFile(const char * szFileName, HANDLE * PtrFile) +{ + TFileStream * pStream; + TMPQFile * hf = NULL; + TCHAR szFileNameT[MAX_PATH]; + + // Convert the file name to UNICODE (if needed) + StringCopy(szFileNameT, _countof(szFileNameT), szFileName); + + // Open the file and create the TMPQFile structure + pStream = FileStream_OpenFile(szFileNameT, STREAM_FLAG_READ_ONLY); + if(pStream != NULL) + { + // Allocate and initialize file handle + hf = CreateFileHandle(NULL, NULL); + if(hf != NULL) + { + hf->pStream = pStream; + *PtrFile = hf; + return true; + } + else + { + FileStream_Close(pStream); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + } + } + *PtrFile = NULL; + return false; +} + +bool OpenPatchedFile(HANDLE hMpq, const char * szFileName, HANDLE * PtrFile) +{ + TMPQArchive * haBase = NULL; + TMPQArchive * ha = (TMPQArchive *)hMpq; + TFileEntry * pFileEntry; + TMPQFile * hfPatch; // Pointer to patch file + TMPQFile * hfBase = NULL; // Pointer to base open file + TMPQFile * hf = NULL; + HANDLE hPatchFile; + char szNameBuffer[MAX_PATH]; + + // First of all, find the latest archive where the file is in base version + // (i.e. where the original, unpatched version of the file exists) + while(ha != NULL) + { + // If the file is there, then we remember the archive + pFileEntry = GetFileEntryExact(ha, GetPatchFileName(ha, szFileName, szNameBuffer), 0, NULL); + if(pFileEntry != NULL && (pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0) + haBase = ha; + + // Move to the patch archive + ha = ha->haPatch; + } + + // If we couldn't find the base file in any of the patches, it doesn't exist + if((ha = haBase) != NULL) + { + // Now open the base file + if(SFileOpenFileEx((HANDLE)ha, GetPatchFileName(ha, szFileName, szNameBuffer), SFILE_OPEN_BASE_FILE, (HANDLE *)&hfBase)) + { + // The file must be a base file, i.e. without MPQ_FILE_PATCH_FILE + assert((hfBase->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0); + hf = hfBase; + + // Now open all patches and attach them on top of the base file + for(ha = ha->haPatch; ha != NULL; ha = ha->haPatch) + { + // Prepare the file name with a correct prefix + if(SFileOpenFileEx((HANDLE)ha, GetPatchFileName(ha, szFileName, szNameBuffer), SFILE_OPEN_BASE_FILE, &hPatchFile)) + { + // Remember the new version + hfPatch = (TMPQFile *)hPatchFile; + + // We should not find patch file + assert((hfPatch->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) != 0); + + // Attach the patch to the base file + hf->hfPatch = hfPatch; + hf = hfPatch; + } + } + } + } + else + { + SetLastError(ERROR_FILE_NOT_FOUND); + } + + // Give the updated base MPQ + if(PtrFile != NULL) + *PtrFile = (HANDLE)hfBase; + return (hfBase != NULL); +} + +/*****************************************************************************/ +/* Public functions */ +/*****************************************************************************/ + +//----------------------------------------------------------------------------- +// SFileEnumLocales enums all locale versions within MPQ. +// Functions fills all available language identifiers on a file into the buffer +// pointed by plcLocales. There must be enough entries to copy the localed, +// otherwise the function returns ERROR_INSUFFICIENT_BUFFER. + +DWORD WINAPI SFileEnumLocales( + HANDLE hMpq, + const char * szFileName, + LCID * PtrLocales, + LPDWORD PtrMaxLocales, + DWORD dwSearchScope) +{ + TMPQArchive * ha = (TMPQArchive *)hMpq; + TMPQHash * pFirstHash; + TMPQHash * pHash; + DWORD dwFileIndex = 0; + DWORD dwMaxLocales; + DWORD dwLocales = 0; + + // Test the parameters + if(!IsValidMpqHandle(hMpq)) + return ERROR_INVALID_HANDLE; + if(szFileName == NULL || *szFileName == 0) + return ERROR_INVALID_PARAMETER; + if(ha->pHashTable == NULL) + return ERROR_NOT_SUPPORTED; + if(PtrMaxLocales == NULL) + return ERROR_INVALID_PARAMETER; + if(IsPseudoFileName(szFileName, &dwFileIndex)) + return ERROR_INVALID_PARAMETER; + + // Keep compiler happy + dwMaxLocales = PtrMaxLocales[0]; + dwSearchScope = dwSearchScope; + + // Parse all files with that name + pFirstHash = pHash = GetFirstHashEntry(ha, szFileName); + while(pHash != NULL) + { + // Put the locales to the buffer + if(PtrLocales != NULL && dwLocales < dwMaxLocales) + *PtrLocales++ = pHash->lcLocale; + dwLocales++; + + // Get the next locale + pHash = GetNextHashEntry(ha, pFirstHash, pHash); + } + + // Give the caller the number of locales and return + PtrMaxLocales[0] = dwLocales; + return (dwLocales <= dwMaxLocales) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER; +} + +//----------------------------------------------------------------------------- +// SFileOpenFileEx +// +// hMpq - Handle of opened MPQ archive +// szFileName - Name of file to open +// dwSearchScope - Where to search +// PtrFile - Pointer to store opened file handle + +bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope, HANDLE * PtrFile) +{ + TMPQArchive * ha = IsValidMpqHandle(hMpq); + TFileEntry * pFileEntry = NULL; + TMPQFile * hf = NULL; + DWORD dwHashIndex = HASH_ENTRY_FREE; + DWORD dwFileIndex = 0; + DWORD dwErrCode = ERROR_SUCCESS; + bool bOpenByIndex = false; + + // Don't accept NULL pointer to file handle + if(szFileName == NULL || *szFileName == 0) + dwErrCode = ERROR_INVALID_PARAMETER; + + // When opening a file from MPQ, the handle must be valid + if(dwSearchScope != SFILE_OPEN_LOCAL_FILE && ha == NULL) + dwErrCode = ERROR_INVALID_HANDLE; + + // When not checking for existence, the pointer to file handle must be valid + if(dwSearchScope != SFILE_OPEN_CHECK_EXISTS && PtrFile == NULL) + dwErrCode = ERROR_INVALID_PARAMETER; + + // Prepare the file opening + if(dwErrCode == ERROR_SUCCESS) + { + switch(dwSearchScope) + { + case SFILE_OPEN_FROM_MPQ: + case SFILE_OPEN_BASE_FILE: + case SFILE_OPEN_CHECK_EXISTS: + + // If this MPQ has no patches, open the file from this MPQ directly + if(ha->haPatch == NULL || dwSearchScope == SFILE_OPEN_BASE_FILE) + { + pFileEntry = GetFileEntryLocale2(ha, szFileName, g_lcFileLocale, &dwHashIndex); + } + + // If this MPQ is a patched archive, open the file as patched + else + { + return OpenPatchedFile(hMpq, szFileName, PtrFile); + } + break; + + case SFILE_OPEN_ANY_LOCALE: + + // This open option is reserved for opening MPQ internal listfile. + // No argument validation. Tries to open file with neutral locale first, + // then any other available. + pFileEntry = GetFileEntryLocale2(ha, szFileName, 0, &dwHashIndex); + break; + + case SFILE_OPEN_LOCAL_FILE: + + // Open a local file + return OpenLocalFile(szFileName, PtrFile); + + default: + + // Don't accept any other value + dwErrCode = ERROR_INVALID_PARAMETER; + break; + } + } + + // Check whether the file really exists in the MPQ + if(dwErrCode == ERROR_SUCCESS) + { + // If we didn't find the file, try to open it using pseudo file name ("File + if (pFileEntry == NULL || (pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0) + { + // Check the pseudo-file name ("File00000001.ext") + if ((bOpenByIndex = IsPseudoFileName(szFileName, &dwFileIndex)) == true) + { + // Get the file entry for the file + if (dwFileIndex < ha->dwFileTableSize) + { + pFileEntry = ha->pFileTable + dwFileIndex; + } + } + + // Still not found? + if (pFileEntry == NULL) + { + dwErrCode = ERROR_FILE_NOT_FOUND; + } + } + + // Perform some checks of invalid files + if (pFileEntry != NULL) + { + // MPQ protectors use insanely amount of fake files, often with very high size. + // We won't open any files whose compressed size is bigger than archive size + // If the file is not compressed, its size cannot be bigger than archive size + if ((pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) == 0 && (pFileEntry->dwFileSize > ha->FileSize)) + { + dwErrCode = ERROR_FILE_CORRUPT; + pFileEntry = NULL; + } + + // Ignore unknown loading flags (example: MPQ_2016_v1_WME4_4.w3x) +// if(pFileEntry->dwFlags & ~MPQ_FILE_VALID_FLAGS) +// { +// dwErrCode = ERROR_NOT_SUPPORTED; +// pFileEntry = NULL; +// } + } + } + + // Did the caller just wanted to know if the file exists? + if(dwErrCode == ERROR_SUCCESS && dwSearchScope != SFILE_OPEN_CHECK_EXISTS) + { + // Allocate file handle + hf = CreateFileHandle(ha, pFileEntry); + if(hf != NULL) + { + // Get the hash index for the file + if(ha->pHashTable != NULL && dwHashIndex == HASH_ENTRY_FREE) + dwHashIndex = FindHashIndex(ha, dwFileIndex); + if(dwHashIndex != HASH_ENTRY_FREE) + hf->pHashEntry = ha->pHashTable + dwHashIndex; + hf->dwHashIndex = dwHashIndex; + + // If the MPQ has sector CRC enabled, enable if for the file + if(ha->dwFlags & MPQ_FLAG_CHECK_SECTOR_CRC) + hf->bCheckSectorCRCs = true; + + // If we know the real file name, copy it to the file entry + if(bOpenByIndex == false) + { + // If there is no file name yet, allocate it + AllocateFileName(ha, pFileEntry, szFileName); + + // If the file is encrypted, we should detect the file key + if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) + { + hf->dwFileKey = DecryptFileKey(szFileName, + pFileEntry->ByteOffset, + pFileEntry->dwFileSize, + pFileEntry->dwFlags); + } + } + } + else + { + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + } + + // Give the file entry + if(PtrFile != NULL) + PtrFile[0] = hf; + + // Return error code + if(dwErrCode != ERROR_SUCCESS) + SetLastError(dwErrCode); + return (dwErrCode == ERROR_SUCCESS); +} + +//----------------------------------------------------------------------------- +// SFileHasFile +// +// hMpq - Handle of opened MPQ archive +// szFileName - Name of file to look for + +bool WINAPI SFileHasFile(HANDLE hMpq, const char * szFileName) +{ + return SFileOpenFileEx(hMpq, szFileName, SFILE_OPEN_CHECK_EXISTS, NULL); +} + +//----------------------------------------------------------------------------- +// bool WINAPI SFileCloseFile(HANDLE hFile); + +bool WINAPI SFileCloseFile(HANDLE hFile) +{ + TMPQFile * hf = (TMPQFile *)hFile; + + if(!IsValidFileHandle(hFile)) + { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + // Free the structure + FreeFileHandle(hf); + return true; +} diff --git a/StormLib/src/SFilePatchArchives.cpp b/StormLib/src/SFilePatchArchives.cpp new file mode 100644 index 000000000..d8c104f7c --- /dev/null +++ b/StormLib/src/SFilePatchArchives.cpp @@ -0,0 +1,1175 @@ +/*****************************************************************************/ +/* SFilePatchArchives.cpp Copyright (c) Ladislav Zezula 2010 */ +/*---------------------------------------------------------------------------*/ +/* Description: */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 18.08.10 1.00 Lad The first version of SFilePatchArchives.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" + +//----------------------------------------------------------------------------- +// Local structures + +#define MAX_SC2_PATCH_PREFIX 0x80 + +#define PATCH_SIGNATURE_HEADER 0x48435450 +#define PATCH_SIGNATURE_MD5 0x5f35444d +#define PATCH_SIGNATURE_XFRM 0x4d524658 + +#define SIZE_OF_XFRM_HEADER 0x0C + +// Header for incremental patch files +typedef struct _MPQ_PATCH_HEADER +{ + //-- PATCH header ----------------------------------- + DWORD dwSignature; // 'PTCH' + DWORD dwSizeOfPatchData; // Size of the entire patch (decompressed) + DWORD dwSizeBeforePatch; // Size of the file before patch + DWORD dwSizeAfterPatch; // Size of file after patch + + //-- MD5 block -------------------------------------- + DWORD dwMD5; // 'MD5_' + DWORD dwMd5BlockSize; // Size of the MD5 block, including the signature and size itself + BYTE md5_before_patch[0x10]; // MD5 of the original (unpached) file + BYTE md5_after_patch[0x10]; // MD5 of the patched file + + //-- XFRM block ------------------------------------- + DWORD dwXFRM; // 'XFRM' + DWORD dwXfrmBlockSize; // Size of the XFRM block, includes XFRM header and patch data + DWORD dwPatchType; // Type of patch ('BSD0' or 'COPY') + + // Followed by the patch data +} MPQ_PATCH_HEADER, *PMPQ_PATCH_HEADER; + +typedef struct _BLIZZARD_BSDIFF40_FILE +{ + ULONGLONG Signature; + ULONGLONG CtrlBlockSize; + ULONGLONG DataBlockSize; + ULONGLONG NewFileSize; +} BLIZZARD_BSDIFF40_FILE, *PBLIZZARD_BSDIFF40_FILE; + +typedef struct _BSDIFF_CTRL_BLOCK +{ + DWORD dwAddDataLength; + DWORD dwMovDataLength; + DWORD dwOldMoveLength; + +} BSDIFF_CTRL_BLOCK, *PBSDIFF_CTRL_BLOCK; + +typedef struct _LOCALIZED_MPQ_INFO +{ + const char * szNameTemplate; // Name template + size_t nLangOffset; // Offset of the language + size_t nLength; // Length of the name template +} LOCALIZED_MPQ_INFO, *PLOCALIZED_MPQ_INFO; + +//----------------------------------------------------------------------------- +// Local variables + +// 4-byte groups for all languages +static const char * LanguageList = "baseteenenUSenGBenCNenTWdeDEesESesMXfrFRitITkoKRptBRptPTruRUzhCNzhTW"; + +// List of localized MPQs for World of Warcraft +static LOCALIZED_MPQ_INFO LocaleMpqs_WoW[] = +{ + {"expansion1-locale-####", 18, 22}, + {"expansion1-speech-####", 18, 22}, + {"expansion2-locale-####", 18, 22}, + {"expansion2-speech-####", 18, 22}, + {"expansion3-locale-####", 18, 22}, + {"expansion3-speech-####", 18, 22}, + {"locale-####", 7, 11}, + {"speech-####", 7, 11}, + {NULL, 0, 0} +}; + +//----------------------------------------------------------------------------- +// Local functions + +static inline bool IsPatchMetadataFile(TFileEntry * pFileEntry) +{ + // The file must ave a name + if(pFileEntry->szFileName != NULL && (pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0) + { + // The file must be small + if(0 < pFileEntry->dwFileSize && pFileEntry->dwFileSize < 0x40) + { + // Compare the plain name + return (_stricmp(GetPlainFileName(pFileEntry->szFileName), PATCH_METADATA_NAME) == 0); + } + } + + // Not a patch_metadata + return false; +} + +static void Decompress_RLE(LPBYTE pbDecompressed, DWORD cbDecompressed, LPBYTE pbCompressed, DWORD cbCompressed) +{ + LPBYTE pbDecompressedEnd = pbDecompressed + cbDecompressed; + LPBYTE pbCompressedEnd = pbCompressed + cbCompressed; + BYTE RepeatCount; + BYTE OneByte; + + // Cut the initial DWORD from the compressed chunk + pbCompressed += sizeof(DWORD); + + // Pre-fill decompressed buffer with zeros + memset(pbDecompressed, 0, cbDecompressed); + + // Unpack + while(pbCompressed < pbCompressedEnd && pbDecompressed < pbDecompressedEnd) + { + OneByte = *pbCompressed++; + + // Is it a repetition byte ? + if(OneByte & 0x80) + { + RepeatCount = (OneByte & 0x7F) + 1; + for(BYTE i = 0; i < RepeatCount; i++) + { + if(pbDecompressed == pbDecompressedEnd || pbCompressed == pbCompressedEnd) + break; + + *pbDecompressed++ = *pbCompressed++; + } + } + else + { + pbDecompressed += (OneByte + 1); + } + } +} + +static DWORD LoadFilePatch_COPY(TMPQFile * hf, PMPQ_PATCH_HEADER pFullPatch) +{ + DWORD cbBytesToRead = pFullPatch->dwSizeOfPatchData - sizeof(MPQ_PATCH_HEADER); + DWORD cbBytesRead = 0; + + // Simply load the rest of the patch + SFileReadFile((HANDLE)hf, (pFullPatch + 1), cbBytesToRead, &cbBytesRead, NULL); + return (cbBytesRead == cbBytesToRead) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT; +} + +static DWORD LoadFilePatch_BSD0(TMPQFile * hf, PMPQ_PATCH_HEADER pFullPatch) +{ + LPBYTE pbDecompressed = (LPBYTE)(pFullPatch + 1); + LPBYTE pbCompressed = NULL; + DWORD cbDecompressed = 0; + DWORD cbCompressed = 0; + DWORD dwBytesRead = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Calculate the size of compressed data + cbDecompressed = pFullPatch->dwSizeOfPatchData - sizeof(MPQ_PATCH_HEADER); + cbCompressed = pFullPatch->dwXfrmBlockSize - SIZE_OF_XFRM_HEADER; + + // Is that file compressed? + if(cbCompressed < cbDecompressed) + { + pbCompressed = STORM_ALLOC(BYTE, cbCompressed); + if(pbCompressed == NULL) + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + + // Read the compressed patch data + if(dwErrCode == ERROR_SUCCESS) + { + SFileReadFile((HANDLE)hf, pbCompressed, cbCompressed, &dwBytesRead, NULL); + if(dwBytesRead != cbCompressed) + dwErrCode = ERROR_FILE_CORRUPT; + } + + // Decompress the data + if(dwErrCode == ERROR_SUCCESS) + Decompress_RLE(pbDecompressed, cbDecompressed, pbCompressed, cbCompressed); + + if(pbCompressed != NULL) + STORM_FREE(pbCompressed); + } + else + { + SFileReadFile((HANDLE)hf, pbDecompressed, cbDecompressed, &dwBytesRead, NULL); + if(dwBytesRead != cbDecompressed) + dwErrCode = ERROR_FILE_CORRUPT; + } + + return dwErrCode; +} + +static DWORD ApplyFilePatch_COPY( + TMPQPatcher * pPatcher, + PMPQ_PATCH_HEADER pFullPatch, + LPBYTE pbTarget, + LPBYTE pbSource) +{ + // Sanity checks + assert(pPatcher->cbMaxFileData >= pPatcher->cbFileData); + pFullPatch = pFullPatch; + + // Copy the patch data as-is + memcpy(pbTarget, pbSource, pPatcher->cbFileData); + return ERROR_SUCCESS; +} + +static DWORD ApplyFilePatch_BSD0( + TMPQPatcher * pPatcher, + PMPQ_PATCH_HEADER pFullPatch, + LPBYTE pbTarget, + LPBYTE pbSource) +{ + PBLIZZARD_BSDIFF40_FILE pBsdiff; + PBSDIFF_CTRL_BLOCK pCtrlBlock; + LPBYTE pbPatchData = (LPBYTE)(pFullPatch + 1); + LPBYTE pDataBlock; + LPBYTE pExtraBlock; + LPBYTE pbOldData = pbSource; + LPBYTE pbNewData = pbTarget; + DWORD dwCombineSize; + DWORD dwNewOffset = 0; // Current position to patch + DWORD dwOldOffset = 0; // Current source position + DWORD dwNewSize; // Patched file size + DWORD dwOldSize = pPatcher->cbFileData; // File size before patch + + // Get pointer to the patch header + // Format of BSDIFF header corresponds to original BSDIFF, which is: + // 0000 8 bytes signature "BSDIFF40" + // 0008 8 bytes size of the control block + // 0010 8 bytes size of the data block + // 0018 8 bytes new size of the patched file + pBsdiff = (PBLIZZARD_BSDIFF40_FILE)pbPatchData; + pbPatchData += sizeof(BLIZZARD_BSDIFF40_FILE); + + // Get pointer to the 32-bit BSDIFF control block + // The control block follows immediately after the BSDIFF header + // and consists of three 32-bit integers + // 0000 4 bytes Length to copy from the BSDIFF data block the new file + // 0004 4 bytes Length to copy from the BSDIFF extra block + // 0008 4 bytes Size to increment source file offset + pCtrlBlock = (PBSDIFF_CTRL_BLOCK)pbPatchData; + pbPatchData += (size_t)BSWAP_INT64_UNSIGNED(pBsdiff->CtrlBlockSize); + + // Get the pointer to the data block + pDataBlock = (LPBYTE)pbPatchData; + pbPatchData += (size_t)BSWAP_INT64_UNSIGNED(pBsdiff->DataBlockSize); + + // Get the pointer to the extra block + pExtraBlock = (LPBYTE)pbPatchData; + dwNewSize = (DWORD)BSWAP_INT64_UNSIGNED(pBsdiff->NewFileSize); + + // Now patch the file + while(dwNewOffset < dwNewSize) + { + DWORD dwAddDataLength = BSWAP_INT32_UNSIGNED(pCtrlBlock->dwAddDataLength); + DWORD dwMovDataLength = BSWAP_INT32_UNSIGNED(pCtrlBlock->dwMovDataLength); + DWORD dwOldMoveLength = BSWAP_INT32_UNSIGNED(pCtrlBlock->dwOldMoveLength); + DWORD i; + + // Sanity check + if((dwNewOffset + dwAddDataLength) > dwNewSize) + return ERROR_FILE_CORRUPT; + + // Read the diff string to the target buffer + memcpy(pbNewData + dwNewOffset, pDataBlock, dwAddDataLength); + pDataBlock += dwAddDataLength; + + // Get the longest block that we can combine + dwCombineSize = ((dwOldOffset + dwAddDataLength) >= dwOldSize) ? (dwOldSize - dwOldOffset) : dwAddDataLength; + if((dwNewOffset + dwCombineSize) > dwNewSize || (dwNewOffset + dwCombineSize) < dwNewOffset) + return ERROR_FILE_CORRUPT; + + // Now combine the patch data with the original file + for(i = 0; i < dwCombineSize; i++) + pbNewData[dwNewOffset + i] = pbNewData[dwNewOffset + i] + pbOldData[dwOldOffset + i]; + + // Move the offsets + dwNewOffset += dwAddDataLength; + dwOldOffset += dwAddDataLength; + + // Sanity check + if((dwNewOffset + dwMovDataLength) > dwNewSize) + return ERROR_FILE_CORRUPT; + + // Copy the data from the extra block in BSDIFF patch + memcpy(pbNewData + dwNewOffset, pExtraBlock, dwMovDataLength); + pExtraBlock += dwMovDataLength; + dwNewOffset += dwMovDataLength; + + // Move the old offset + if(dwOldMoveLength & 0x80000000) + dwOldMoveLength = 0x80000000 - dwOldMoveLength; + dwOldOffset += dwOldMoveLength; + pCtrlBlock++; + } + + // The size after patch must match + if(dwNewOffset != pFullPatch->dwSizeAfterPatch) + return ERROR_FILE_CORRUPT; + + // Update the new data size + pPatcher->cbFileData = dwNewOffset; + return ERROR_SUCCESS; +} + +static PMPQ_PATCH_HEADER LoadFullFilePatch(TMPQFile * hf, MPQ_PATCH_HEADER & PatchHeader) +{ + PMPQ_PATCH_HEADER pFullPatch; + DWORD dwErrCode = ERROR_SUCCESS; + + // BSWAP the entire header, if needed + BSWAP_ARRAY32_UNSIGNED(&PatchHeader, sizeof(DWORD) * 6); + BSWAP_ARRAY32_UNSIGNED(&PatchHeader.dwXFRM, sizeof(DWORD) * 3); + + // Verify the signatures in the patch header + if(PatchHeader.dwSignature != PATCH_SIGNATURE_HEADER || PatchHeader.dwMD5 != PATCH_SIGNATURE_MD5 || PatchHeader.dwXFRM != PATCH_SIGNATURE_XFRM) + return NULL; + + // Allocate space for patch header and compressed data + pFullPatch = (PMPQ_PATCH_HEADER)STORM_ALLOC(BYTE, PatchHeader.dwSizeOfPatchData); + if(pFullPatch != NULL) + { + // Copy the patch header + memcpy(pFullPatch, &PatchHeader, sizeof(MPQ_PATCH_HEADER)); + + // Read the patch, depending on patch type + if(dwErrCode == ERROR_SUCCESS) + { + switch(PatchHeader.dwPatchType) + { + case 0x59504f43: // 'COPY' + dwErrCode = LoadFilePatch_COPY(hf, pFullPatch); + break; + + case 0x30445342: // 'BSD0' + dwErrCode = LoadFilePatch_BSD0(hf, pFullPatch); + break; + + default: + dwErrCode = ERROR_FILE_CORRUPT; + break; + } + } + + // If something failed, free the patch buffer + if(dwErrCode != ERROR_SUCCESS) + { + STORM_FREE(pFullPatch); + pFullPatch = NULL; + } + } + + // Give the result to the caller + return pFullPatch; +} + +static DWORD ApplyFilePatch( + TMPQPatcher * pPatcher, + PMPQ_PATCH_HEADER pFullPatch) +{ + LPBYTE pbSource = (pPatcher->nCounter & 0x1) ? pPatcher->pbFileData2 : pPatcher->pbFileData1; + LPBYTE pbTarget = (pPatcher->nCounter & 0x1) ? pPatcher->pbFileData1 : pPatcher->pbFileData2; + DWORD dwErrCode; + + // Sanity checks + assert(pFullPatch->dwSizeAfterPatch <= pPatcher->cbMaxFileData); + + // Apply the patch according to the type + switch(pFullPatch->dwPatchType) + { + case 0x59504f43: // 'COPY' + dwErrCode = ApplyFilePatch_COPY(pPatcher, pFullPatch, pbTarget, pbSource); + break; + + case 0x30445342: // 'BSD0' + dwErrCode = ApplyFilePatch_BSD0(pPatcher, pFullPatch, pbTarget, pbSource); + break; + + default: + dwErrCode = ERROR_FILE_CORRUPT; + break; + } + + // Verify MD5 after patch + if(dwErrCode == ERROR_SUCCESS && pFullPatch->dwSizeAfterPatch != 0) + { + // Verify the patched file + if(!VerifyDataBlockHash(pbTarget, pFullPatch->dwSizeAfterPatch, pFullPatch->md5_after_patch)) + dwErrCode = ERROR_FILE_CORRUPT; + + // Copy the MD5 of the new block + memcpy(pPatcher->this_md5, pFullPatch->md5_after_patch, MD5_DIGEST_SIZE); + } + + return dwErrCode; +} + +//----------------------------------------------------------------------------- +// Local functions (patch prefix matching) + +static bool CreatePatchPrefix(TMPQArchive * ha, const char * szFileName, size_t nLength) +{ + TMPQNamePrefix * pNewPrefix; + + // If the length of the patch prefix was not entered, find it + // Not that the patch prefix must always begin with backslash + if(szFileName != NULL && nLength == 0) + nLength = strlen(szFileName); + + // Create the patch prefix + pNewPrefix = (TMPQNamePrefix *)STORM_ALLOC(BYTE, sizeof(TMPQNamePrefix) + nLength + 1); + if(pNewPrefix != NULL) + { + // Fill the name prefix. Also add the backslash + if(szFileName && nLength) + { + memcpy(pNewPrefix->szPatchPrefix, szFileName, nLength); + if(pNewPrefix->szPatchPrefix[nLength - 1] != '\\') + pNewPrefix->szPatchPrefix[nLength++] = '\\'; + } + + // Terminate the string and fill the length + pNewPrefix->szPatchPrefix[nLength] = 0; + pNewPrefix->nLength = nLength; + } + + ha->pPatchPrefix = pNewPrefix; + return (pNewPrefix != NULL); +} + +static bool CheckAndCreatePatchPrefix(TMPQArchive * ha, const char * szPatchPrefix, size_t nLength) +{ + char szTempName[MAX_SC2_PATCH_PREFIX + 0x41]; + bool bResult = false; + + // Prepare the patch file name + if(nLength > MAX_SC2_PATCH_PREFIX) + return false; + + // Prepare the patched file name + memcpy(szTempName, szPatchPrefix, nLength); + memcpy(&szTempName[nLength], "\\(patch_metadata)", 18); + + // Verifywhether that file exists + if(GetFileEntryLocale(ha, szTempName, 0) != NULL) + bResult = CreatePatchPrefix(ha, szPatchPrefix, nLength); + + return bResult; +} + +static bool IsMatchingPatchFile( + TMPQArchive * ha, + const char * szFileName, + LPBYTE pbBaseFileMd5) +{ + MPQ_PATCH_HEADER PatchHeader = {0}; + HANDLE hFile = NULL; + DWORD dwTransferred = 0; + DWORD dwFlags = 0; + bool bResult = false; + + // Open the file and load the patch header + if(SFileOpenFileEx((HANDLE)ha, szFileName, SFILE_OPEN_BASE_FILE, &hFile)) + { + // Retrieve the flags. We need to know whether the file is a patch or not + SFileGetFileInfo(hFile, SFileInfoFlags, &dwFlags, sizeof(DWORD), &dwTransferred); + if(dwFlags & MPQ_FILE_PATCH_FILE) + { + // Load the patch header + SFileReadFile(hFile, &PatchHeader, sizeof(MPQ_PATCH_HEADER), &dwTransferred, NULL); + BSWAP_ARRAY32_UNSIGNED(pPatchHeader, sizeof(DWORD) * 6); + + // If the file contains an incremental patch, + // compare the "MD5 before patching" with the base file MD5 + if(dwTransferred == sizeof(MPQ_PATCH_HEADER) && PatchHeader.dwSignature == PATCH_SIGNATURE_HEADER) + bResult = (!memcmp(PatchHeader.md5_before_patch, pbBaseFileMd5, MD5_DIGEST_SIZE)); + } + else + { + // TODO: How to match it if it's not an incremental patch? + // Example: StarCraft II\Updates\enGB\s2-update-enGB-23258.MPQ: + // Mods\Core.SC2Mod\enGB.SC2Assets\StreamingBuckets.txt" + bResult = false; + } + + // Close the file + SFileCloseFile(hFile); + } + + return bResult; +} + +static const char * FindArchiveLanguage(TMPQArchive * ha, PLOCALIZED_MPQ_INFO pMpqInfo) +{ + TFileEntry * pFileEntry; + const char * szLanguage = LanguageList; + char szFileName[0x40]; + + // Iterate through all localized languages + while(pMpqInfo->szNameTemplate != NULL) + { + // Iterate through all languages + for(szLanguage = LanguageList; szLanguage[0] != 0; szLanguage += 4) + { + // Construct the file name + memcpy(szFileName, pMpqInfo->szNameTemplate, pMpqInfo->nLength); + szFileName[pMpqInfo->nLangOffset + 0] = szLanguage[0]; + szFileName[pMpqInfo->nLangOffset + 1] = szLanguage[1]; + szFileName[pMpqInfo->nLangOffset + 2] = szLanguage[2]; + szFileName[pMpqInfo->nLangOffset + 3] = szLanguage[3]; + + // Append the suffix + memcpy(szFileName + pMpqInfo->nLength, "-md5.lst", 9); + + // Check whether the name exists + pFileEntry = GetFileEntryLocale(ha, szFileName, 0); + if(pFileEntry != NULL) + return szLanguage; + } + + // Move to the next language name + pMpqInfo++; + } + + // Not found + return NULL; +} + +//----------------------------------------------------------------------------- +// Finding ratch prefix for an temporary build of WoW (Pre-Cataclysm) + +static bool FindPatchPrefix_WoW_13164_13623(TMPQArchive * haBase, TMPQArchive * haPatch) +{ + const char * szPatchPrefix; + char szNamePrefix[0x08]; + + // Try to find the language of the MPQ archive + szPatchPrefix = FindArchiveLanguage(haBase, LocaleMpqs_WoW); + if(szPatchPrefix == NULL) + szPatchPrefix = "Base"; + + // Format the patch prefix + szNamePrefix[0] = szPatchPrefix[0]; + szNamePrefix[1] = szPatchPrefix[1]; + szNamePrefix[2] = szPatchPrefix[2]; + szNamePrefix[3] = szPatchPrefix[3]; + szNamePrefix[4] = '\\'; + szNamePrefix[5] = 0; + return CreatePatchPrefix(haPatch, szNamePrefix, 5); +} + +//----------------------------------------------------------------------------- +// Finding patch prefix for Starcraft II (Pre-Legacy of the Void) + +// +// This method tries to match the patch by placement of the archive (in the game subdirectory) +// +// Archive Path: %GAME_DIR%\Mods\SwarmMulti.SC2Mod\Base.SC2Data +// Patch Prefix: Mods\SwarmMulti.SC2Mod\Base.SC2Data +// +// Archive Path: %ANY_DIR%\MPQ_2013_v4_Mods#Liberty.SC2Mod#enGB.SC2Data +// Patch Prefix: Mods\Liberty.SC2Mod\enGB.SC2Data +// + +static bool CheckPatchPrefix_SC2_ArchiveName( + TMPQArchive * haPatch, + const TCHAR * szPathPtr, + const TCHAR * szSeparator, + const TCHAR * szPathEnd, + const TCHAR * szExpectedString, + size_t cchExpectedString) +{ + char szPatchPrefix[MAX_SC2_PATCH_PREFIX+0x41]; + size_t nLength = 0; + bool bResult = false; + + // Check whether the length is equal to the length of the expected string + if((size_t)(szSeparator - szPathPtr) == cchExpectedString) + { + // Now check the string itself + if(!_tcsnicmp(szPathPtr, szExpectedString, szSeparator - szPathPtr)) + { + // Copy the name string + for(; szPathPtr < szPathEnd; szPathPtr++) + { + if(szPathPtr[0] != _T('/') && szPathPtr[0] != _T('#')) + szPatchPrefix[nLength++] = (char)szPathPtr[0]; + else + szPatchPrefix[nLength++] = '\\'; + } + + // Check and create the patch prefix + bResult = CheckAndCreatePatchPrefix(haPatch, szPatchPrefix, nLength); + } + } + + return bResult; +} + +static bool FindPatchPrefix_SC2_ArchiveName(TMPQArchive * haBase, TMPQArchive * haPatch) +{ + const TCHAR * szPathBegin = FileStream_GetFileName(haBase->pStream); + const TCHAR * szSeparator = NULL; + const TCHAR * szPathEnd = szPathBegin + _tcslen(szPathBegin); + const TCHAR * szPathPtr; + int nSlashCount = 0; + int nDotCount = 0; + + // Skip the part where the patch prefix would be too long + if((szPathEnd - szPathBegin) > MAX_SC2_PATCH_PREFIX) + szPathBegin = szPathEnd - MAX_SC2_PATCH_PREFIX; + + // Search for the file extension + for(szPathPtr = szPathEnd; szPathPtr > szPathBegin; szPathPtr--) + { + if(szPathPtr[0] == _T('.')) + { + nDotCount++; + break; + } + } + + // Search for the possible begin of the prefix name + for(/* NOTHING */; szPathPtr > szPathBegin; szPathPtr--) + { + // Check the slashes, backslashes and hashes + if(szPathPtr[0] == _T('\\') || szPathPtr[0] == _T('/') || szPathPtr[0] == _T('#')) + { + if(nDotCount == 0) + return false; + szSeparator = szPathPtr; + nSlashCount++; + } + + // Check the path parts + if(szSeparator != NULL && nSlashCount >= nDotCount) + { + if(CheckPatchPrefix_SC2_ArchiveName(haPatch, szPathPtr, szSeparator, szPathEnd, _T("Battle.net"), 10)) + return true; + if(CheckPatchPrefix_SC2_ArchiveName(haPatch, szPathPtr, szSeparator, szPathEnd, _T("Campaigns"), 9)) + return true; + if(CheckPatchPrefix_SC2_ArchiveName(haPatch, szPathPtr, szSeparator, szPathEnd, _T("Mods"), 4)) + return true; + } + } + + // Not matched, sorry + return false; +} + +// +// This method tries to read the patch prefix from a helper file +// +// Example +// ========================================================= +// MPQ File Name: MPQ_2013_v4_Base1.SC2Data +// Helper File : MPQ_2013_v4_Base1.SC2Data-PATCH +// File Contains: PatchPrefix=Mods\Core.SC2Mod\Base.SC2Data +// Patch Prefix : Mods\Core.SC2Mod\Base.SC2Data +// + +static bool ExtractPatchPrefixFromFile(const TCHAR * szHelperFile, char * szPatchPrefix, size_t nMaxChars, size_t * PtrLength) +{ + TFileStream * pStream; + ULONGLONG FileSize = 0; + size_t nLength; + char szFileData[MAX_PATH+1]; + bool bResult = false; + + pStream = FileStream_OpenFile(szHelperFile, STREAM_FLAG_READ_ONLY); + if(pStream != NULL) + { + // Retrieve and check the file size + FileStream_GetSize(pStream, &FileSize); + if(12 <= FileSize && FileSize < MAX_PATH) + { + // Read the entire file to memory + if(FileStream_Read(pStream, NULL, szFileData, (DWORD)FileSize)) + { + // Terminate the buffer with zero + szFileData[(DWORD)FileSize] = 0; + + // The file data must begin with the "PatchPrefix" variable + if(!_strnicmp(szFileData, "PatchPrefix", 11)) + { + char * szLinePtr = szFileData + 11; + char * szLineEnd; + + // Skip spaces or '=' + while(szLinePtr[0] == ' ' || szLinePtr[0] == '=') + szLinePtr++; + szLineEnd = szLinePtr; + + // Find the end + while(szLineEnd[0] != 0 && szLineEnd[0] != 0x0A && szLineEnd[0] != 0x0D) + szLineEnd++; + nLength = (size_t)(szLineEnd - szLinePtr); + + // Copy the variable + if(szLineEnd > szLinePtr && nLength <= nMaxChars) + { + memcpy(szPatchPrefix, szLinePtr, nLength); + szPatchPrefix[nLength] = 0; + PtrLength[0] = nLength; + bResult = true; + } + } + } + } + + // Close the stream + FileStream_Close(pStream); + } + + return bResult; +} + + +static bool FindPatchPrefix_SC2_HelperFile(TMPQArchive * haBase, TMPQArchive * haPatch) +{ + TCHAR szHelperFile[MAX_PATH+1]; + char szPatchPrefix[MAX_SC2_PATCH_PREFIX+0x41]; + size_t nLength = 0; + bool bResult = false; + + // Create the name of the patch helper file + _tcscpy(szHelperFile, FileStream_GetFileName(haBase->pStream)); + if(_tcslen(szHelperFile) + 6 > MAX_PATH) + return false; + _tcscat(szHelperFile, _T("-PATCH")); + + // Open the patch helper file and read the line + if(ExtractPatchPrefixFromFile(szHelperFile, szPatchPrefix, MAX_SC2_PATCH_PREFIX, &nLength)) + bResult = CheckAndCreatePatchPrefix(haPatch, szPatchPrefix, nLength); + + return bResult; +} + +// +// Find match in Starcraft II patch MPQs +// Match a LST file in the root directory if the MPQ with any of the file in subdirectories +// +// The problem: +// File in the base MPQ: enGB-md5.lst +// File in the patch MPQ: Campaigns\Liberty.SC2Campaign\enGB.SC2Assets\enGB-md5.lst +// Campaigns\Liberty.SC2Campaign\enGB.SC2Data\enGB-md5.lst +// Campaigns\LibertyStory.SC2Campaign\enGB.SC2Data\enGB-md5.lst +// Campaigns\LibertyStory.SC2Campaign\enGB.SC2Data\enGB-md5.lst Mods\Core.SC2Mod\enGB.SC2Assets\enGB-md5.lst +// Mods\Core.SC2Mod\enGB.SC2Data\enGB-md5.lst +// Mods\Liberty.SC2Mod\enGB.SC2Assets\enGB-md5.lst +// Mods\Liberty.SC2Mod\enGB.SC2Data\enGB-md5.lst +// Mods\LibertyMulti.SC2Mod\enGB.SC2Data\enGB-md5.lst +// +// Solution: +// We need to match the file by its MD5 +// + +static bool FindPatchPrefix_SC2_MatchFiles(TMPQArchive * haBase, TMPQArchive * haPatch, TFileEntry * pBaseEntry) +{ + TMPQNamePrefix * pPatchPrefix; + char * szPatchFileName; + char * szPlainName; + size_t cchWorkBuffer = 0x400; + bool bResult = false; + + // First-level patches: Find the same file within the patch archive + // and verify by MD5-before-patch + if(haBase->haPatch == NULL) + { + TFileEntry * pFileTableEnd = haPatch->pFileTable + haPatch->dwFileTableSize; + TFileEntry * pFileEntry; + + // Allocate working buffer for merging LST file + szPatchFileName = STORM_ALLOC(char, cchWorkBuffer); + if(szPatchFileName != NULL) + { + // Parse the entire file table + for(pFileEntry = haPatch->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) + { + // Look for "patch_metadata" file + if(IsPatchMetadataFile(pFileEntry)) + { + // Construct the name of the MD5 file + strcpy(szPatchFileName, pFileEntry->szFileName); + szPlainName = (char *)GetPlainFileName(szPatchFileName); + strcpy(szPlainName, pBaseEntry->szFileName); + + // Check for matching MD5 file + if(IsMatchingPatchFile(haPatch, szPatchFileName, pBaseEntry->md5)) + { + bResult = CreatePatchPrefix(haPatch, szPatchFileName, (size_t)(szPlainName - szPatchFileName)); + break; + } + } + } + + // Delete the merge buffer + STORM_FREE(szPatchFileName); + } + } + + // For second-level patches, just take the patch prefix from the lower level patch + else + { + // There must be at least two patches in the chain + assert(haBase->haPatch->pPatchPrefix != NULL); + pPatchPrefix = haBase->haPatch->pPatchPrefix; + + // Copy the patch prefix + bResult = CreatePatchPrefix(haPatch, + pPatchPrefix->szPatchPrefix, + pPatchPrefix->nLength); + } + + return bResult; +} + +// Note: pBaseEntry is the file entry of the base version of "StreamingBuckets.txt" +static bool FindPatchPrefix_SC2(TMPQArchive * haBase, TMPQArchive * haPatch, TFileEntry * pBaseEntry) +{ + // Method 1: Try it by the placement of the archive. + // Works when someone is opening an archive in the game (sub)directory + if(FindPatchPrefix_SC2_ArchiveName(haBase, haPatch)) + return true; + + // Method 2: Try to locate the Name.Ext-PATCH file and read the patch prefix from it + if(FindPatchPrefix_SC2_HelperFile(haBase, haPatch)) + return true; + + // Method 3: Try to pair any version of "StreamingBuckets.txt" from the patch MPQ + // with the "StreamingBuckets.txt" in the base MPQ. Does not always work + if(FindPatchPrefix_SC2_MatchFiles(haBase, haPatch, pBaseEntry)) + return true; + + return false; +} + +// +// Patch prefix is the path subdirectory where the patched files are within MPQ. +// +// Example 1: +// Main MPQ: locale-enGB.MPQ +// Patch MPQ: wow-update-12694.MPQ +// File in main MPQ: DBFilesClient\Achievement.dbc +// File in patch MPQ: enGB\DBFilesClient\Achievement.dbc +// Path prefix: enGB +// +// Example 2: +// Main MPQ: expansion1.MPQ +// Patch MPQ: wow-update-12694.MPQ +// File in main MPQ: DBFilesClient\Achievement.dbc +// File in patch MPQ: Base\DBFilesClient\Achievement.dbc +// Path prefix: Base +// +// Example 3: +// Main MPQ: %GAME%\Battle.net\Battle.net.MPQ +// Patch MPQ: s2-update-base-26147.MPQ +// File in main MPQ: Battle.net\i18n\deDE\String\CLIENT_ACHIEVEMENTS.xml +// File in patch MPQ: Battle.net\Battle.net.MPQ\Battle.net\i18n\deDE\String\CLIENT_ACHIEVEMENTS.xml +// Path prefix: Battle.net\Battle.net.MPQ +// +// Example 4: +// Main MPQ: %GAME%\Campaigns\Liberty.SC2Campaign\enGB.SC2Data +// *OR* %ANY_DIR%\%ANY_NAME%Campaigns#Liberty.SC2Campaign#enGB.SC2Data +// Patch MPQ: s2-update-enGB-23258.MPQ +// File in main MPQ: LocalizedData\GameHotkeys.txt +// File in patch MPQ: Campaigns\Liberty.SC2Campaign\enGB.SC2Data\LocalizedData\GameHotkeys.txt +// Patch Prefix: Campaigns\Liberty.SC2Campaign\enGB.SC2Data +// + +static bool FindPatchPrefix(TMPQArchive * haBase, TMPQArchive * haPatch, const char * szPatchPathPrefix) +{ + TFileEntry * pFileEntry; + + // If the patch prefix was explicitly entered, we use that one + if(szPatchPathPrefix != NULL) + return CreatePatchPrefix(haPatch, szPatchPathPrefix, 0); + + // Patches for World of Warcraft - they mostly do not use prefix. + // All patches that use patch prefix have the "base\\(patch_metadata) file present + if(GetFileEntryLocale(haPatch, "base\\" PATCH_METADATA_NAME, 0)) + return FindPatchPrefix_WoW_13164_13623(haBase, haPatch); + + // Updates for Starcraft II + // Match: LocalizedData\GameHotkeys.txt <==> Campaigns\Liberty.SC2Campaign\enGB.SC2Data\LocalizedData\GameHotkeys.txt + // All Starcraft II base archives seem to have the file "StreamingBuckets.txt" present + pFileEntry = GetFileEntryLocale(haBase, "StreamingBuckets.txt", 0); + if(pFileEntry != NULL) + return FindPatchPrefix_SC2(haBase, haPatch, pFileEntry); + + // Diablo III patch MPQs don't use patch prefix + // Hearthstone MPQs don't use patch prefix + CreatePatchPrefix(haPatch, NULL, 0); + return true; +} + +//----------------------------------------------------------------------------- +// Public functions (StormLib internals) + +bool IsIncrementalPatchFile(const void * pvData, DWORD cbData, LPDWORD pdwPatchedFileSize) +{ + PMPQ_PATCH_HEADER pPatchHeader = (PMPQ_PATCH_HEADER)pvData; + BLIZZARD_BSDIFF40_FILE DiffFile; + DWORD dwPatchType; + + if(cbData >= sizeof(MPQ_PATCH_HEADER) + sizeof(BLIZZARD_BSDIFF40_FILE)) + { + dwPatchType = BSWAP_INT32_UNSIGNED(pPatchHeader->dwPatchType); + if(dwPatchType == 0x30445342) + { + // Give the caller the patch file size + if(pdwPatchedFileSize != NULL) + { + Decompress_RLE((LPBYTE)&DiffFile, sizeof(BLIZZARD_BSDIFF40_FILE), (LPBYTE)(pPatchHeader + 1), sizeof(BLIZZARD_BSDIFF40_FILE)); + DiffFile.NewFileSize = BSWAP_INT64_UNSIGNED(DiffFile.NewFileSize); + *pdwPatchedFileSize = (DWORD)DiffFile.NewFileSize; + return true; + } + } + } + + return false; +} + +DWORD Patch_InitPatcher(TMPQPatcher * pPatcher, TMPQFile * hf) +{ + DWORD cbMaxFileData = 0; + + // Overflow check + if((cbMaxFileData + (DWORD)sizeof(MPQ_PATCH_HEADER)) < cbMaxFileData) + return ERROR_NOT_ENOUGH_MEMORY; + if(hf->hfPatch == NULL) + return ERROR_INVALID_PARAMETER; + + // Initialize the entire structure with zeros + memset(pPatcher, 0, sizeof(TMPQPatcher)); + + // Copy the MD5 of the current file + memcpy(pPatcher->this_md5, hf->pFileEntry->md5, MD5_DIGEST_SIZE); + + // Find out the biggest data size needed during the patching process + while(hf != NULL) + { + if(hf->pFileEntry->dwFileSize > cbMaxFileData) + cbMaxFileData = hf->pFileEntry->dwFileSize; + hf = hf->hfPatch; + } + + // Allocate primary and secondary buffer + pPatcher->pbFileData1 = STORM_ALLOC(BYTE, cbMaxFileData); + pPatcher->pbFileData2 = STORM_ALLOC(BYTE, cbMaxFileData); + if(!pPatcher->pbFileData1 || !pPatcher->pbFileData2) + return ERROR_NOT_ENOUGH_MEMORY; + + pPatcher->cbMaxFileData = cbMaxFileData; + return ERROR_SUCCESS; +} + +// +// Note: The patch may either be applied to the base file or to the previous version +// In Starcraft II, Mods\Core.SC2Mod\Base.SC2Data, file StreamingBuckets.txt: +// +// Base file MD5: 31376b0344b6df59ad009d4296125539 +// +// s2-update-base-23258: from 31376b0344b6df59ad009d4296125539 to 941a82683452e54bf024a8d491501824 +// s2-update-base-24540: from 31376b0344b6df59ad009d4296125539 to 941a82683452e54bf024a8d491501824 +// s2-update-base-26147: from 31376b0344b6df59ad009d4296125539 to d5d5253c762fac6b9761240288a0771a +// s2-update-base-28522: from 31376b0344b6df59ad009d4296125539 to 5a76c4b356920aab7afd22e0e1913d7a +// s2-update-base-30508: from 31376b0344b6df59ad009d4296125539 to 8cb0d4799893fe801cc78ae4488a3671 +// s2-update-base-32283: from 31376b0344b6df59ad009d4296125539 to 8cb0d4799893fe801cc78ae4488a3671 +// +// We don't keep all intermediate versions in memory, as it would cause massive +// memory usage during patching process. A prime example is the file +// DBFilesClient\\Item-Sparse.db2 from locale-enGB.MPQ (WoW 16965), which has +// 9 patches in a row, each requiring 70 MB memory (35 MB patch data + 35 MB work buffer) +// + +DWORD Patch_Process(TMPQPatcher * pPatcher, TMPQFile * hf) +{ + PMPQ_PATCH_HEADER pFullPatch; + MPQ_PATCH_HEADER PatchHeader1; + MPQ_PATCH_HEADER PatchHeader2 = {0}; + TMPQFile * hfBase = hf; + DWORD cbBytesRead = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Move to the first patch + assert(hfBase->pbFileData == NULL); + assert(hfBase->cbFileData == 0); + hf = hf->hfPatch; + + // Read the header of the current patch + SFileReadFile((HANDLE)hf, &PatchHeader1, sizeof(MPQ_PATCH_HEADER), &cbBytesRead, NULL); + if(cbBytesRead != sizeof(MPQ_PATCH_HEADER)) + return ERROR_FILE_CORRUPT; + + // Perform the patching process + while(dwErrCode == ERROR_SUCCESS && hf != NULL) + { + // Try to read the next patch header. If the md5_before_patch + // still matches we go directly to the next one and repeat + while(hf->hfPatch != NULL) + { + // Attempt to read the patch header + SFileReadFile((HANDLE)hf->hfPatch, &PatchHeader2, sizeof(MPQ_PATCH_HEADER), &cbBytesRead, NULL); + if(cbBytesRead != sizeof(MPQ_PATCH_HEADER)) + return ERROR_FILE_CORRUPT; + + // Compare the md5_before_patch + if(memcmp(PatchHeader2.md5_before_patch, pPatcher->this_md5, MD5_DIGEST_SIZE)) + break; + + // Move one patch fuhrter + PatchHeader1 = PatchHeader2; + hf = hf->hfPatch; + } + + // Allocate memory for the patch data + pFullPatch = LoadFullFilePatch(hf, PatchHeader1); + if(pFullPatch != NULL) + { + // Apply the patch + dwErrCode = ApplyFilePatch(pPatcher, pFullPatch); + STORM_FREE(pFullPatch); + } + else + { + dwErrCode = ERROR_FILE_CORRUPT; + } + + // Move to the next patch + PatchHeader1 = PatchHeader2; + pPatcher->nCounter++; + hf = hf->hfPatch; + } + + // Put the result data to the file structure + if(dwErrCode == ERROR_SUCCESS) + { + // Swap the pointer to the file data structure + if(pPatcher->nCounter & 0x01) + { + hfBase->pbFileData = pPatcher->pbFileData2; + pPatcher->pbFileData2 = NULL; + } + else + { + hfBase->pbFileData = pPatcher->pbFileData1; + pPatcher->pbFileData1 = NULL; + } + + // Also supply the data size + hfBase->cbFileData = pPatcher->cbFileData; + } + + return ERROR_SUCCESS; +} + +void Patch_Finalize(TMPQPatcher * pPatcher) +{ + if(pPatcher != NULL) + { + if(pPatcher->pbFileData1 != NULL) + STORM_FREE(pPatcher->pbFileData1); + if(pPatcher->pbFileData2 != NULL) + STORM_FREE(pPatcher->pbFileData2); + + memset(pPatcher, 0, sizeof(TMPQPatcher)); + } +} + + +//----------------------------------------------------------------------------- +// Public functions + +bool WINAPI SFileOpenPatchArchive( + HANDLE hMpq, + const TCHAR * szPatchMpqName, + const char * szPatchPathPrefix, + DWORD dwFlags) +{ + TMPQArchive * haPatch; + TMPQArchive * ha = (TMPQArchive *)hMpq; + HANDLE hPatchMpq = NULL; + DWORD dwErrCode = ERROR_SUCCESS; + + // Keep compiler happy + dwFlags = dwFlags; + + // Verify input parameters + if(!IsValidMpqHandle(hMpq)) + dwErrCode = ERROR_INVALID_HANDLE; + if(szPatchMpqName == NULL || *szPatchMpqName == 0) + dwErrCode = ERROR_INVALID_PARAMETER; + + // + // We don't allow adding patches to archives that have been open for write + // + // Error scenario: + // + // 1) Open archive for writing + // 2) Modify or replace a file + // 3) Add patch archive to the opened MPQ + // 4) Read patched file + // 5) Now what ? + // + + if(dwErrCode == ERROR_SUCCESS) + { + if(!(ha->dwFlags & MPQ_FLAG_READ_ONLY)) + dwErrCode = ERROR_ACCESS_DENIED; + } + + // Open the archive like it is normal archive + if(dwErrCode == ERROR_SUCCESS) + { + if(SFileOpenArchive(szPatchMpqName, 0, MPQ_OPEN_READ_ONLY | MPQ_OPEN_PATCH, &hPatchMpq)) + { + // Cast the archive handle to structure pointer + haPatch = (TMPQArchive *)hPatchMpq; + + // We need to remember the proper patch prefix to match names of patched files + if(FindPatchPrefix(ha, (TMPQArchive *)hPatchMpq, szPatchPathPrefix)) + { + // Now add the patch archive to the list of patches to the original MPQ + while(ha != NULL) + { + if(ha->haPatch == NULL) + { + haPatch->haBase = ha; + ha->haPatch = haPatch; + return true; + } + + // Move to the next archive + ha = ha->haPatch; + } + } + + // Close the archive + SFileCloseArchive(hPatchMpq); + dwErrCode = ERROR_CANT_FIND_PATCH_PREFIX; + } + else + { + dwErrCode = GetLastError(); + } + } + + SetLastError(dwErrCode); + return false; +} + +bool WINAPI SFileIsPatchedArchive(HANDLE hMpq) +{ + TMPQArchive * ha = (TMPQArchive *)hMpq; + + // Verify input parameters + if(!IsValidMpqHandle(hMpq)) + return false; + + return (ha->haPatch != NULL); +} diff --git a/StormLib/src/SFileReadFile.cpp b/StormLib/src/SFileReadFile.cpp new file mode 100644 index 000000000..34edc069f --- /dev/null +++ b/StormLib/src/SFileReadFile.cpp @@ -0,0 +1,897 @@ +/*****************************************************************************/ +/* SFileReadFile.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Description : */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* xx.xx.99 1.00 Lad The first version of SFileReadFile.cpp */ +/* 24.03.99 1.00 Lad Added the SFileGetFileInfo function */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" + +//----------------------------------------------------------------------------- +// Local functions + +// hf - MPQ File handle. +// pbBuffer - Pointer to target buffer to store sectors. +// dwByteOffset - Position of sector in the file (relative to file begin) +// dwBytesToRead - Number of bytes to read. Must be multiplier of sector size. +// pdwBytesRead - Stored number of bytes loaded +static DWORD ReadMpqSectors(TMPQFile * hf, LPBYTE pbBuffer, DWORD dwByteOffset, DWORD dwBytesToRead, LPDWORD pdwBytesRead) +{ + ULONGLONG RawFilePos; + TMPQArchive * ha = hf->ha; + TFileEntry * pFileEntry = hf->pFileEntry; + LPBYTE pbRawSector = NULL; + LPBYTE pbOutSector = pbBuffer; + LPBYTE pbInSector = pbBuffer; + DWORD dwRawBytesToRead; + DWORD dwRawSectorOffset = dwByteOffset; + DWORD dwSectorsToRead = dwBytesToRead / ha->dwSectorSize; + DWORD dwSectorIndex = dwByteOffset / ha->dwSectorSize; + DWORD dwSectorsDone = 0; + DWORD dwBytesRead = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Note that dwByteOffset must be aligned to size of one sector + // Note that dwBytesToRead must be a multiplier of one sector size + // This is local function, so we won't check if that's true. + // Note that files stored in single units are processed by a separate function + + // If there is not enough bytes remaining, cut dwBytesToRead + if((dwByteOffset + dwBytesToRead) > hf->dwDataSize) + dwBytesToRead = hf->dwDataSize - dwByteOffset; + dwRawBytesToRead = dwBytesToRead; + + // Perform all necessary work to do with compressed files + if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) + { + // If the sector positions are not loaded yet, do it + if(hf->SectorOffsets == NULL) + { + dwErrCode = AllocateSectorOffsets(hf, true); + if(dwErrCode != ERROR_SUCCESS || hf->SectorOffsets == NULL) + return dwErrCode; + } + + // If the sector checksums are not loaded yet, load them now. + if(hf->SectorChksums == NULL && (pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC) && hf->bLoadedSectorCRCs == false) + { + // + // Sector CRCs is plain crap feature. It is almost never present, + // often it's empty, or the end offset of sector CRCs is zero. + // We only try to load sector CRCs once, and regardless if it fails + // or not, we won't try that again for the given file. + // + + AllocateSectorChecksums(hf, true); + hf->bLoadedSectorCRCs = true; + } + + // TODO: If the raw data MD5s are not loaded yet, load them now + // Only do it if the MPQ is of format 4.0 +// if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_4 && ha->pHeader->dwRawChunkSize != 0) +// { +// dwErrCode = AllocateRawMD5s(hf, true); +// if(dwErrCode != ERROR_SUCCESS) +// return dwErrCode; +// } + + // Assign the temporary buffer as target for read operation + dwRawSectorOffset = hf->SectorOffsets[dwSectorIndex]; + dwRawBytesToRead = hf->SectorOffsets[dwSectorIndex + dwSectorsToRead] - dwRawSectorOffset; + + // If the file is compressed, also allocate secondary buffer + pbInSector = pbRawSector = STORM_ALLOC(BYTE, dwRawBytesToRead); + if(pbRawSector == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + } + + // Calculate raw file offset where the sector(s) are stored. + RawFilePos = CalculateRawSectorOffset(hf, dwRawSectorOffset); + + // Set file pointer and read all required sectors + if(FileStream_Read(ha->pStream, &RawFilePos, pbInSector, dwRawBytesToRead)) + { + // Now we have to decrypt and decompress all file sectors that have been loaded + for(DWORD i = 0; i < dwSectorsToRead; i++) + { + DWORD dwRawBytesInThisSector = ha->dwSectorSize; + DWORD dwBytesInThisSector = ha->dwSectorSize; + DWORD dwIndex = dwSectorIndex + i; + + // If there is not enough bytes in the last sector, + // cut the number of bytes in this sector + if(dwRawBytesInThisSector > dwBytesToRead) + dwRawBytesInThisSector = dwBytesToRead; + if(dwBytesInThisSector > dwBytesToRead) + dwBytesInThisSector = dwBytesToRead; + + // If the file is compressed, we have to adjust the raw sector size + if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) + dwRawBytesInThisSector = hf->SectorOffsets[dwIndex + 1] - hf->SectorOffsets[dwIndex]; + + // If the file is encrypted, we have to decrypt the sector + if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) + { + BSWAP_ARRAY32_UNSIGNED(pbInSector, dwRawBytesInThisSector); + + // If we don't know the key, try to detect it by file content + if(hf->dwFileKey == 0) + { + hf->dwFileKey = DetectFileKeyByContent(pbInSector, dwBytesInThisSector, hf->dwDataSize); + if(hf->dwFileKey == 0) + { + dwErrCode = ERROR_UNKNOWN_FILE_KEY; + break; + } + } + + DecryptMpqBlock(pbInSector, dwRawBytesInThisSector, hf->dwFileKey + dwIndex); + BSWAP_ARRAY32_UNSIGNED(pbInSector, dwRawBytesInThisSector); + } + + // If the file has sector CRC check turned on, perform it + if(hf->bCheckSectorCRCs && hf->SectorChksums != NULL) + { + DWORD dwAdlerExpected = hf->SectorChksums[dwIndex]; + DWORD dwAdlerValue = 0; + + // We can only check sector CRC when it's not zero + // Neither can we check it if it's 0xFFFFFFFF. + if(dwAdlerExpected != 0 && dwAdlerExpected != 0xFFFFFFFF) + { + dwAdlerValue = adler32(0, pbInSector, dwRawBytesInThisSector); + if(dwAdlerValue != dwAdlerExpected) + { + dwErrCode = ERROR_CHECKSUM_ERROR; + break; + } + } + } + + // If the sector is really compressed, decompress it. + // WARNING : Some sectors may not be compressed, it can be determined only + // by comparing uncompressed and compressed size !!! + if(dwRawBytesInThisSector < dwBytesInThisSector) + { + int cbOutSector = dwBytesInThisSector; + int cbInSector = dwRawBytesInThisSector; + int nResult = 0; + + // Is the file compressed by Blizzard's multiple compression ? + if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS) + { + // Remember the last used compression + hf->dwCompression0 = pbInSector[0]; + + // Decompress the data + if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2) + nResult = SCompDecompress2(pbOutSector, &cbOutSector, pbInSector, cbInSector); + else + nResult = SCompDecompress(pbOutSector, &cbOutSector, pbInSector, cbInSector); + } + + // Is the file compressed by PKWARE Data Compression Library ? + else if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE) + { + nResult = SCompExplode(pbOutSector, &cbOutSector, pbInSector, cbInSector); + } + + // Did the decompression fail ? + if(nResult == 0) + { + dwErrCode = ERROR_FILE_CORRUPT; + break; + } + } + else + { + if(pbOutSector != pbInSector) + memcpy(pbOutSector, pbInSector, dwBytesInThisSector); + } + + // Move pointers + dwBytesToRead -= dwBytesInThisSector; + dwByteOffset += dwBytesInThisSector; + dwBytesRead += dwBytesInThisSector; + pbOutSector += dwBytesInThisSector; + pbInSector += dwRawBytesInThisSector; + dwSectorsDone++; + } + } + else + { + dwErrCode = GetLastError(); + } + + // Free all used buffers + if(pbRawSector != NULL) + STORM_FREE(pbRawSector); + + // Give the caller thenumber of bytes read + *pdwBytesRead = dwBytesRead; + return dwErrCode; +} + +static DWORD ReadMpqFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead) +{ + ULONGLONG RawFilePos = hf->RawFilePos; + TMPQArchive * ha = hf->ha; + TFileEntry * pFileEntry = hf->pFileEntry; + LPBYTE pbCompressed = NULL; + LPBYTE pbRawData; + DWORD dwErrCode = ERROR_SUCCESS; + + // If the file buffer is not allocated yet, do it. + if(hf->pbFileSector == NULL) + { + dwErrCode = AllocateSectorBuffer(hf); + if(dwErrCode != ERROR_SUCCESS || hf->pbFileSector == NULL) + return dwErrCode; + } + + // If the file is a patch file, adjust raw data offset + if(hf->pPatchInfo != NULL) + RawFilePos += hf->pPatchInfo->dwLength; + pbRawData = hf->pbFileSector; + + // If the file sector is not loaded yet, do it + if(hf->dwSectorOffs != 0) + { + // Is the file compressed? + if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) + { + // Allocate space for compressed data + pbCompressed = STORM_ALLOC(BYTE, pFileEntry->dwCmpSize); + if(pbCompressed == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + pbRawData = pbCompressed; + } + + // Load the raw (compressed, encrypted) data + if(!FileStream_Read(ha->pStream, &RawFilePos, pbRawData, pFileEntry->dwCmpSize)) + { + STORM_FREE(pbCompressed); + return GetLastError(); + } + + // If the file is encrypted, we have to decrypt the data first + if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) + { + BSWAP_ARRAY32_UNSIGNED(pbRawData, pFileEntry->dwCmpSize); + DecryptMpqBlock(pbRawData, pFileEntry->dwCmpSize, hf->dwFileKey); + BSWAP_ARRAY32_UNSIGNED(pbRawData, pFileEntry->dwCmpSize); + } + + // If the file is compressed, we have to decompress it now + if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) + { + int cbOutBuffer = (int)hf->dwDataSize; + int cbInBuffer = (int)pFileEntry->dwCmpSize; + int nResult = 0; + + // + // If the file is an incremental patch, the size of compressed data + // is determined as pFileEntry->dwCmpSize - sizeof(TPatchInfo) + // + // In "wow-update-12694.MPQ" from Wow-Cataclysm BETA: + // + // File CmprSize DcmpSize DataSize Compressed? + // -------------------------------------- ---------- -------- -------- --------------- + // esES\DBFilesClient\LightSkyBox.dbc 0xBE->0xA2 0xBC 0xBC Yes + // deDE\DBFilesClient\MountCapability.dbc 0x93->0x77 0x77 0x77 No + // + + if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) + cbInBuffer = cbInBuffer - sizeof(TPatchInfo); + + // Is the file compressed by Blizzard's multiple compression ? + if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS) + { + // Remember the last used compression + hf->dwCompression0 = pbRawData[0]; + + // Decompress the file + if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2) + nResult = SCompDecompress2(hf->pbFileSector, &cbOutBuffer, pbRawData, cbInBuffer); + else + nResult = SCompDecompress(hf->pbFileSector, &cbOutBuffer, pbRawData, cbInBuffer); + } + + // Is the file compressed by PKWARE Data Compression Library ? + // Note: Single unit files compressed with IMPLODE are not supported by Blizzard + else if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE) + nResult = SCompExplode(hf->pbFileSector, &cbOutBuffer, pbRawData, cbInBuffer); + + dwErrCode = (nResult != 0) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT; + } + else + { + if(hf->pbFileSector != NULL && pbRawData != hf->pbFileSector) + memcpy(hf->pbFileSector, pbRawData, hf->dwDataSize); + } + + // Free the decompression buffer. + if(pbCompressed != NULL) + STORM_FREE(pbCompressed); + + // The file sector is now properly loaded + hf->dwSectorOffs = 0; + } + + // At this moment, we have the file loaded into the file buffer. + // Copy as much as the caller wants + if(dwErrCode == ERROR_SUCCESS && hf->dwSectorOffs == 0) + { + // File position is greater or equal to file size ? + if(dwFilePos >= hf->dwDataSize) + { + *pdwBytesRead = 0; + return ERROR_SUCCESS; + } + + // If not enough bytes remaining in the file, cut them + if((hf->dwDataSize - dwFilePos) < dwToRead) + dwToRead = (hf->dwDataSize - dwFilePos); + + // Copy the bytes + memcpy(pvBuffer, hf->pbFileSector + dwFilePos, dwToRead); + + // Give the number of bytes read + *pdwBytesRead = dwToRead; + } + + // An error, sorry + return dwErrCode; +} + +static DWORD ReadMpkFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead) +{ + ULONGLONG RawFilePos = hf->RawFilePos + 0x0C; // For some reason, MPK files start at position (hf->RawFilePos + 0x0C) + TMPQArchive * ha = hf->ha; + TFileEntry * pFileEntry = hf->pFileEntry; + LPBYTE pbCompressed = NULL; + LPBYTE pbRawData = hf->pbFileSector; + DWORD dwErrCode = ERROR_SUCCESS; + + // We do not support patch files in MPK archives + assert(hf->pPatchInfo == NULL); + + // If the file buffer is not allocated yet, do it. + if(hf->pbFileSector == NULL) + { + dwErrCode = AllocateSectorBuffer(hf); + if(dwErrCode != ERROR_SUCCESS || hf->pbFileSector == NULL) + return dwErrCode; + pbRawData = hf->pbFileSector; + } + + // If the file sector is not loaded yet, do it + if(hf->dwSectorOffs != 0) + { + // Is the file compressed? + if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) + { + // Allocate space for compressed data + pbCompressed = STORM_ALLOC(BYTE, pFileEntry->dwCmpSize); + if(pbCompressed == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + pbRawData = pbCompressed; + } + + // Load the raw (compressed, encrypted) data + if(!FileStream_Read(ha->pStream, &RawFilePos, pbRawData, pFileEntry->dwCmpSize)) + { + STORM_FREE(pbCompressed); + return GetLastError(); + } + + // If the file is encrypted, we have to decrypt the data first + if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) + { + DecryptMpkTable(pbRawData, pFileEntry->dwCmpSize); + } + + // If the file is compressed, we have to decompress it now + if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) + { + int cbOutBuffer = (int)hf->dwDataSize; + + hf->dwCompression0 = pbRawData[0]; + if(!SCompDecompressMpk(hf->pbFileSector, &cbOutBuffer, pbRawData, (int)pFileEntry->dwCmpSize)) + dwErrCode = ERROR_FILE_CORRUPT; + } + else + { + if(pbRawData != hf->pbFileSector) + memcpy(hf->pbFileSector, pbRawData, hf->dwDataSize); + } + + // Free the decompression buffer. + if(pbCompressed != NULL) + STORM_FREE(pbCompressed); + + // The file sector is now properly loaded + hf->dwSectorOffs = 0; + } + + // At this moment, we have the file loaded into the file buffer. + // Copy as much as the caller wants + if(dwErrCode == ERROR_SUCCESS && hf->dwSectorOffs == 0) + { + // File position is greater or equal to file size ? + if(dwFilePos >= hf->dwDataSize) + { + *pdwBytesRead = 0; + return ERROR_SUCCESS; + } + + // If not enough bytes remaining in the file, cut them + if((hf->dwDataSize - dwFilePos) < dwToRead) + dwToRead = (hf->dwDataSize - dwFilePos); + + // Copy the bytes + memcpy(pvBuffer, hf->pbFileSector + dwFilePos, dwToRead); + + // Give the number of bytes read + *pdwBytesRead = dwToRead; + return ERROR_SUCCESS; + } + + // An error, sorry + return ERROR_CAN_NOT_COMPLETE; +} + + +static DWORD ReadMpqFileSectorFile(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwBytesToRead, LPDWORD pdwBytesRead) +{ + TMPQArchive * ha = hf->ha; + LPBYTE pbBuffer = (BYTE *)pvBuffer; + DWORD dwTotalBytesRead = 0; // Total bytes read in all three parts + DWORD dwSectorSizeMask = ha->dwSectorSize - 1; // Mask for block size, usually 0x0FFF + DWORD dwFileSectorPos; // File offset of the loaded sector + DWORD dwBytesRead; // Number of bytes read (temporary variable) + DWORD dwErrCode; + + // If the file position is at or beyond end of file, do nothing + if(dwFilePos >= hf->dwDataSize) + { + *pdwBytesRead = 0; + return ERROR_SUCCESS; + } + + // If not enough bytes in the file remaining, cut them + if(dwBytesToRead > (hf->dwDataSize - dwFilePos)) + dwBytesToRead = (hf->dwDataSize - dwFilePos); + + // Compute sector position in the file + dwFileSectorPos = dwFilePos & ~dwSectorSizeMask; // Position in the block + + // If the file sector buffer is not allocated yet, do it now + if(hf->pbFileSector == NULL) + { + dwErrCode = AllocateSectorBuffer(hf); + if(dwErrCode != ERROR_SUCCESS || hf->pbFileSector == NULL) + return dwErrCode; + } + + // Load the first (incomplete) file sector + if(dwFilePos & dwSectorSizeMask) + { + DWORD dwBytesInSector = ha->dwSectorSize; + DWORD dwBufferOffs = dwFilePos & dwSectorSizeMask; + DWORD dwToCopy; + + // Is the file sector already loaded ? + if(hf->dwSectorOffs != dwFileSectorPos) + { + // Load one MPQ sector into archive buffer + dwErrCode = ReadMpqSectors(hf, hf->pbFileSector, dwFileSectorPos, ha->dwSectorSize, &dwBytesInSector); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + // Remember that the data loaded to the sector have new file offset + hf->dwSectorOffs = dwFileSectorPos; + } + else + { + if((dwFileSectorPos + dwBytesInSector) > hf->dwDataSize) + dwBytesInSector = hf->dwDataSize - dwFileSectorPos; + } + + // Copy the data from the offset in the loaded sector to the end of the sector + dwToCopy = dwBytesInSector - dwBufferOffs; + if(dwToCopy > dwBytesToRead) + dwToCopy = dwBytesToRead; + + // Copy data from sector buffer into target buffer + memcpy(pbBuffer, hf->pbFileSector + dwBufferOffs, dwToCopy); + + // Update pointers and byte counts + dwTotalBytesRead += dwToCopy; + dwFileSectorPos += dwBytesInSector; + pbBuffer += dwToCopy; + dwBytesToRead -= dwToCopy; + } + + // Load the whole ("middle") sectors only if there is at least one full sector to be read + if(dwBytesToRead >= ha->dwSectorSize) + { + DWORD dwBlockBytes = dwBytesToRead & ~dwSectorSizeMask; + + // Load all sectors to the output buffer + dwErrCode = ReadMpqSectors(hf, pbBuffer, dwFileSectorPos, dwBlockBytes, &dwBytesRead); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + // Update pointers + dwTotalBytesRead += dwBytesRead; + dwFileSectorPos += dwBytesRead; + pbBuffer += dwBytesRead; + dwBytesToRead -= dwBytesRead; + } + + // Read the terminating sector + if(dwBytesToRead > 0) + { + DWORD dwToCopy = ha->dwSectorSize; + + // Is the file sector already loaded ? + if(hf->dwSectorOffs != dwFileSectorPos) + { + // Load one MPQ sector into archive buffer + dwErrCode = ReadMpqSectors(hf, hf->pbFileSector, dwFileSectorPos, ha->dwSectorSize, &dwBytesRead); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + // Remember that the data loaded to the sector have new file offset + hf->dwSectorOffs = dwFileSectorPos; + } + + // Check number of bytes read + if(dwToCopy > dwBytesToRead) + dwToCopy = dwBytesToRead; + + // Copy the data from the cached last sector to the caller's buffer + memcpy(pbBuffer, hf->pbFileSector, dwToCopy); + + // Update pointers + dwTotalBytesRead += dwToCopy; + } + + // Store total number of bytes read to the caller + *pdwBytesRead = dwTotalBytesRead; + return ERROR_SUCCESS; +} + +static DWORD ReadMpqFilePatchFile(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead) +{ + TMPQPatcher Patcher; + DWORD dwBytesToRead = dwToRead; + DWORD dwBytesRead = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Make sure that the patch file is loaded completely + if(dwErrCode == ERROR_SUCCESS && hf->pbFileData == NULL) + { + // Initialize patching process and allocate data + dwErrCode = Patch_InitPatcher(&Patcher, hf); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + // Set the current data size + Patcher.cbFileData = hf->pFileEntry->dwFileSize; + + // Initialize the patcher object with initial file data + if(hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) + dwErrCode = ReadMpqFileSingleUnit(hf, Patcher.pbFileData1, 0, Patcher.cbFileData, &dwBytesRead); + else + dwErrCode = ReadMpqFileSectorFile(hf, Patcher.pbFileData1, 0, Patcher.cbFileData, &dwBytesRead); + + // Perform the patching process + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = Patch_Process(&Patcher, hf); + + // Finalize the patcher structure + Patch_Finalize(&Patcher); + dwBytesRead = 0; + } + + // If there is something to read, do it + if(dwErrCode == ERROR_SUCCESS) + { + if(dwFilePos < hf->cbFileData) + { + // Make sure we don't copy more than file size + if((dwFilePos + dwToRead) > hf->cbFileData) + dwToRead = hf->cbFileData - dwFilePos; + + // Copy the appropriate amount of the file data to the caller's buffer + memcpy(pvBuffer, hf->pbFileData + dwFilePos, dwToRead); + dwBytesRead = dwToRead; + } + + // Set the proper error code + dwErrCode = (dwBytesRead == dwBytesToRead) ? ERROR_SUCCESS : ERROR_HANDLE_EOF; + } + + // Give the result to the caller + if(pdwBytesRead != NULL) + *pdwBytesRead = dwBytesRead; + return dwErrCode; +} + +static DWORD ReadMpqFileLocalFile(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead) +{ + ULONGLONG FilePosition1 = dwFilePos; + ULONGLONG FilePosition2; + DWORD dwBytesRead = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + assert(hf->pStream != NULL); + + // Because stream I/O functions are designed to read + // "all or nothing", we compare file position before and after, + // and if they differ, we assume that number of bytes read + // is the difference between them + + if(!FileStream_Read(hf->pStream, &FilePosition1, pvBuffer, dwToRead)) + { + // If not all bytes have been read, then return the number of bytes read + if((dwErrCode = GetLastError()) == ERROR_HANDLE_EOF) + { + FileStream_GetPos(hf->pStream, &FilePosition2); + dwBytesRead = (DWORD)(FilePosition2 - FilePosition1); + } + } + else + { + dwBytesRead = dwToRead; + } + + *pdwBytesRead = dwBytesRead; + return dwErrCode; +} + +//----------------------------------------------------------------------------- +// SFileReadFile + +bool WINAPI SFileReadFile(HANDLE hFile, void * pvBuffer, DWORD dwToRead, LPDWORD pdwRead, LPOVERLAPPED lpOverlapped) +{ + TMPQFile * hf = (TMPQFile *)hFile; + DWORD dwBytesRead = 0; // Number of bytes read + DWORD dwErrCode = ERROR_SUCCESS; + + // Always zero the result + if(pdwRead != NULL) + *pdwRead = 0; + lpOverlapped = lpOverlapped; + + // Check valid parameters + if(!IsValidFileHandle(hFile)) + { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + + if(pvBuffer == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + // If we didn't load the patch info yet, do it now + if(hf->pFileEntry != NULL && (hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) && hf->pPatchInfo == NULL) + { + dwErrCode = AllocatePatchInfo(hf, true); + if(dwErrCode != ERROR_SUCCESS || hf->pPatchInfo == NULL) + { + SetLastError(dwErrCode); + return false; + } + } + + // Clear the last used compression + hf->dwCompression0 = 0; + + // If the file is local file, read the data directly from the stream + if(hf->pStream != NULL) + { + dwErrCode = ReadMpqFileLocalFile(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead); + } + + // If the file is a patch file, we have to read it special way + else if(hf->hfPatch != NULL && (hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0) + { + dwErrCode = ReadMpqFilePatchFile(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead); + } + + // If the archive is a MPK archive, we need special way to read the file + else if(hf->ha->dwSubType == MPQ_SUBTYPE_MPK) + { + dwErrCode = ReadMpkFileSingleUnit(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead); + } + + // If the file is single unit file, redirect it to read file + else if(hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) + { + dwErrCode = ReadMpqFileSingleUnit(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead); + } + + // Otherwise read it as sector based MPQ file + else + { + dwErrCode = ReadMpqFileSectorFile(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead); + } + + // Increment the file position + hf->dwFilePos += dwBytesRead; + + // Give the caller the number of bytes read + if(pdwRead != NULL) + *pdwRead = dwBytesRead; + + // If the read operation succeeded, but not full number of bytes was read, + // set the last error to ERROR_HANDLE_EOF + if(dwErrCode == ERROR_SUCCESS && (dwBytesRead < dwToRead)) + dwErrCode = ERROR_HANDLE_EOF; + + // If something failed, set the last error value + if(dwErrCode != ERROR_SUCCESS) + SetLastError(dwErrCode); + return (dwErrCode == ERROR_SUCCESS); +} + +//----------------------------------------------------------------------------- +// SFileGetFileSize + +DWORD WINAPI SFileGetFileSize(HANDLE hFile, LPDWORD pdwFileSizeHigh) +{ + ULONGLONG FileSize; + TMPQFile * hf = (TMPQFile *)hFile; + + // Validate the file handle before we go on + if(IsValidFileHandle(hFile)) + { + // Make sure that the variable is initialized + FileSize = 0; + + // If the file is patched file, we have to get the size of the last version + if(hf->hfPatch != NULL) + { + // Walk through the entire patch chain, take the last version + while(hf != NULL) + { + // Get the size of the currently pointed version + FileSize = hf->pFileEntry->dwFileSize; + + // Move to the next patch file in the hierarchy + hf = hf->hfPatch; + } + } + else + { + // Is it a local file ? + if(hf->pStream != NULL) + { + FileStream_GetSize(hf->pStream, &FileSize); + } + else + { + FileSize = hf->dwDataSize; + } + } + + // If opened from archive, return file size + if(pdwFileSizeHigh != NULL) + *pdwFileSizeHigh = (DWORD)(FileSize >> 32); + return (DWORD)FileSize; + } + + SetLastError(ERROR_INVALID_HANDLE); + return SFILE_INVALID_SIZE; +} + +DWORD WINAPI SFileSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * plFilePosHigh, DWORD dwMoveMethod) +{ + TMPQFile * hf = (TMPQFile *)hFile; + ULONGLONG OldPosition; + ULONGLONG NewPosition; + ULONGLONG FileSize; + ULONGLONG DeltaPos; + + // If the hFile is not a valid file handle, return an error. + if(!IsValidFileHandle(hFile)) + { + SetLastError(ERROR_INVALID_HANDLE); + return SFILE_INVALID_POS; + } + + // Retrieve the file size for handling the limits + if(hf->pStream != NULL) + { + FileStream_GetSize(hf->pStream, &FileSize); + } + else + { + FileSize = SFileGetFileSize(hFile, NULL); + } + + // Handle the NULL and non-NULL values of plFilePosHigh + // Non-NULL: The DeltaPos is combined from lFilePos and *lpFilePosHigh + // NULL: The DeltaPos is sign-extended value of lFilePos + DeltaPos = (plFilePosHigh != NULL) ? MAKE_OFFSET64(plFilePosHigh[0], lFilePos) : (ULONGLONG)(LONGLONG)lFilePos; + + // Get the relative point where to move from + switch(dwMoveMethod) + { + case FILE_BEGIN: + + // Move relative to the file begin. + OldPosition = 0; + break; + + case FILE_CURRENT: + + // Retrieve the current file position + if(hf->pStream != NULL) + { + FileStream_GetPos(hf->pStream, &OldPosition); + } + else + { + OldPosition = hf->dwFilePos; + } + break; + + case FILE_END: + + // Move relative to the end of the file + OldPosition = FileSize; + break; + + default: + SetLastError(ERROR_INVALID_PARAMETER); + return SFILE_INVALID_POS; + } + + // Calculate the new position + NewPosition = OldPosition + DeltaPos; + + // If moving backward, don't allow the new position go negative + if((LONGLONG)DeltaPos < 0) + { + if(NewPosition > FileSize) // Position is negative + { + SetLastError(ERROR_NEGATIVE_SEEK); + return SFILE_INVALID_POS; + } + } + + // If moving forward, don't allow the new position go past the end of the file + else + { + if(NewPosition > FileSize) + NewPosition = FileSize; + } + + // Now apply the file pointer to the file + if(hf->pStream != NULL) + { + if(!FileStream_Read(hf->pStream, &NewPosition, NULL, 0)) + return SFILE_INVALID_POS; + } + + // Also, store the new file position to the TMPQFile struct + hf->dwFilePos = (DWORD)NewPosition; + + // Return the new file position + if(plFilePosHigh != NULL) + *plFilePosHigh = (LONG)(NewPosition >> 32); + return (DWORD)NewPosition; +} diff --git a/StormLib/src/SFileVerify.cpp b/StormLib/src/SFileVerify.cpp new file mode 100644 index 000000000..01719e441 --- /dev/null +++ b/StormLib/src/SFileVerify.cpp @@ -0,0 +1,1054 @@ +/*****************************************************************************/ +/* SFileVerify.cpp Copyright (c) Ladislav Zezula 2010 */ +/*---------------------------------------------------------------------------*/ +/* MPQ files and MPQ archives verification. */ +/* */ +/* The MPQ signature verification has been written by Jean-Francois Roy */ +/* and Justin Olbrantz (Quantam). */ +/* The MPQ public keys have been created by MPQKit, using OpenSSL library. */ +/* */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 04.05.10 1.00 Lad The first version of SFileVerify.cpp */ +/*****************************************************************************/ + +#define __STORMLIB_SELF__ +#include "StormLib.h" +#include "StormCommon.h" + +//----------------------------------------------------------------------------- +// Local defines + +#define MPQ_DIGEST_UNIT_SIZE 0x10000 + +//----------------------------------------------------------------------------- +// Known Blizzard public keys +// Created by Jean-Francois Roy using OpenSSL + +static const char * szBlizzardWeakPrivateKey = + "-----BEGIN PRIVATE KEY-----" + "MIIBOQIBAAJBAJJidwS/uILMBSO5DLGsBFknIXWWjQJe2kfdfEk3G/j66w4KkhZ1" + "V61Rt4zLaMVCYpDun7FLwRjkMDSepO1q2DcCAwEAAQJANtiztVDMJh2hE1hjPDKy" + "UmEJ9U/aN3gomuKOjbQbQ/bWWcM/WfhSVHmPqtqh/bQI2UXFr0rnXngeteZHLr/b" + "8QIhAMuWriSKGMACw18/rVVfUrThs915odKBH1Alr3vMVVzZAiEAuBHPSQkgwcb6" + "L4MWaiKuOzq08mSyNqPeN8oSy18q848CIHeMn+3s+eOmu7su1UYQl6yH7OrdBd1q" + "3UxfFNEJiAbhAiAqxdCyOxHGlbM7aS3DOg3cq5ayoN2cvtV7h1R4t8OmVwIgF+5z" + "/6vkzBUsZhd8Nwyis+MeQYH0rpFpMKdTlqmPF2Q=" + "-----END PRIVATE KEY-----"; + +static const char * szBlizzardWeakPublicKey = + "-----BEGIN PUBLIC KEY-----" + "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJJidwS/uILMBSO5DLGsBFknIXWWjQJe" + "2kfdfEk3G/j66w4KkhZ1V61Rt4zLaMVCYpDun7FLwRjkMDSepO1q2DcCAwEAAQ==" + "-----END PUBLIC KEY-----"; + +static const char * szBlizzardStrongPublicKey = + "-----BEGIN PUBLIC KEY-----" + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsQZ+ziT2h8h+J/iMQpgd" + "tH1HaJzOBE3agjU4yMPcrixaPOZoA4t8bwfey7qczfWywocYo3pleytFF+IuD4HD" + "Fl9OXN1SFyupSgMx1EGZlgbFAomnbq9MQJyMqQtMhRAjFgg4TndS7YNb+JMSAEKp" + "kXNqY28n/EVBHD5TsMuVCL579gIenbr61dI92DDEdy790IzIG0VKWLh/KOTcTJfm" + "Ds/7HQTkGouVW+WUsfekuqNQo7ND9DBnhLjLjptxeFE2AZqYcA1ao3S9LN3GL1tW" + "lVXFIX9c7fWqaVTQlZ2oNsI/ARVApOK3grNgqvwH6YoVYVXjNJEo5sQJsPsdV/hk" + "dwIDAQAB" + "-----END PUBLIC KEY-----"; + +static const char * szWarcraft3MapPublicKey = + "-----BEGIN PUBLIC KEY-----" + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1BwklUUQ3UvjizOBRoF5" + "yyOVc7KD+oGOQH5i6eUk1yfs0luCC70kNucNrfqhmviywVtahRse1JtXCPrx2bd3" + "iN8Dx91fbkxjYIOGTsjYoHKTp0BbaFkJih776fcHgnFSb+7mJcDuJVvJOXxEH6w0" + "1vo6VtujCqj1arqbyoal+xtAaczF3us5cOEp45sR1zAWTn1+7omN7VWV4QqJPaDS" + "gBSESc0l1grO0i1VUSumayk7yBKIkb+LBvcG6WnYZHCi7VdLmaxER5m8oZfER66b" + "heHoiSQIZf9PAY6Guw2DT5BTc54j/AaLQAKf2qcRSgQLVo5kQaddF3rCpsXoB/74" + "6QIDAQAB" + "-----END PUBLIC KEY-----"; + +static const char * szWowPatchPublicKey = + "-----BEGIN PUBLIC KEY-----" + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwOsMV0LagAWPEtEQM6b9" + "6FHFkUyGbbyda2/Dfc9dyl21E9QvX+Yw7qKRMAKPzA2TlQQLZKvXpnKXF/YIK5xa" + "5uwg9CEHCEAYolLG4xn0FUOE0E/0PuuytI0p0ICe6rk00PifZzTr8na2wI/l/GnQ" + "bvnIVF1ck6cslATpQJ5JJVMXzoFlUABS19WESw4MXuJAS3AbMhxNWdEhVv7eO51c" + "yGjRLy9QjogZODZTY0fSEksgBqQxNCoYVJYI/sF5K2flDsGqrIp0OdJ6teJlzg1Y" + "UjYnb6bKjlidXoHEXI2TgA/mD6O3XFIt08I9s3crOCTgICq7cgX35qrZiIVWZdRv" + "TwIDAQAB" + "-----END PUBLIC KEY-----"; + +static const char * szWowSurveyPublicKey = + "-----BEGIN PUBLIC KEY-----" + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnIt1DR6nRyyKsy2qahHe" + "MKLtacatn/KxieHcwH87wLBxKy+jZ0gycTmJ7SaTdBAEMDs/V5IPIXEtoqYnid2c" + "63TmfGDU92oc3Ph1PWUZ2PWxBhT06HYxRdbrgHw9/I29pNPi/607x+lzPORITOgU" + "BR6MR8au8HsQP4bn4vkJNgnSgojh48/XQOB/cAln7As1neP61NmVimoLR4Bwi3zt" + "zfgrZaUpyeNCUrOYJmH09YIjbBySTtXOUidoPHjFrMsCWpr6xs8xbETbs7MJFL6a" + "vcUfTT67qfIZ9RsuKfnXJTIrV0kwDSjjuNXiPTmWAehSsiHIsrUXX5RNcwsSjClr" + "nQIDAQAB" + "-----END PUBLIC KEY-----"; + +static const char * szStarcraft2MapPublicKey = + "-----BEGIN PUBLIC KEY-----" + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmk4GT8zb+ICC25a17KZB" + "q/ygKGJ2VSO6IT5PGHJlm1KfnHBA4B6SH3xMlJ4c6eG2k7QevZv+FOhjsAHubyWq" + "2VKqWbrIFKv2ILc2RfMn8J9EDVRxvcxh6slRrVL69D0w1tfVGjMiKq2Fym5yGoRT" + "E7CRgDqbAbXP9LBsCNWHiJLwfxMGzHbk8pIl9oia5pvM7ofZamSHchxlpy6xa4GJ" + "7xKN01YCNvklTL1D7uol3wkwcHc7vrF8QwuJizuA5bSg4poEGtH62BZOYi+UL/z0" + "31YK+k9CbQyM0X0pJoJoYz1TK+Y5J7vBnXCZtfcTYQ/ZzN6UcxTa57dJaiOlCh9z" + "nQIDAQAB" + "-----END PUBLIC KEY-----"; + +//----------------------------------------------------------------------------- +// Local functions + +static void memrev(unsigned char *buf, size_t count) +{ + unsigned char *r; + + for (r = buf + count - 1; buf < r; buf++, r--) + { + *buf ^= *r; + *r ^= *buf; + *buf ^= *r; + } +} + +static bool decode_base64_key(const char * szKeyBase64, rsa_key * key) +{ + unsigned char decoded_key[0x200]; + const char * szBase64Begin; + const char * szBase64End; + unsigned long decoded_length = sizeof(decoded_key); + unsigned long length; + + // Find out the begin of the BASE64 data + szBase64Begin = szKeyBase64 + strlen("-----BEGIN PUBLIC KEY-----"); + szBase64End = szBase64Begin + strlen(szBase64Begin) - strlen("-----END PUBLIC KEY-----"); + if(szBase64End[0] != '-') + return false; + + // decode the base64 string + length = (unsigned long)(szBase64End - szBase64Begin); + if(base64_decode((unsigned char *)szBase64Begin, length, decoded_key, &decoded_length) != CRYPT_OK) + return false; + + // Create RSA key + if(rsa_import(decoded_key, decoded_length, key) != CRYPT_OK) + return false; + + return true; +} + +static void GetPlainAnsiFileName( + const TCHAR * szFileName, + char * szPlainName) +{ + const TCHAR * szPlainNameT = GetPlainFileName(szFileName); + + // Convert the plain name to ANSI + while(*szPlainNameT != 0) + *szPlainName++ = (char)*szPlainNameT++; + *szPlainName = 0; +} + +// Calculate begin and end of the MPQ archive +static void CalculateArchiveRange( + TMPQArchive * ha, + PMPQ_SIGNATURE_INFO pSI) +{ + ULONGLONG TempPos = 0; + char szMapHeader[0x200]; + + // Get the MPQ begin + pSI->BeginMpqData = ha->MpqPos; + + // Warcraft III maps are signed from the map header to the end + if(FileStream_Read(ha->pStream, &TempPos, szMapHeader, sizeof(szMapHeader))) + { + // Is it a map header ? + if(szMapHeader[0] == 'H' && szMapHeader[1] == 'M' && szMapHeader[2] == '3' && szMapHeader[3] == 'W') + { + // We will have to hash since the map header + pSI->BeginMpqData = 0; + } + } + + // Get the MPQ data end. This is stored in the MPQ header + pSI->EndMpqData = ha->MpqPos + ha->pHeader->ArchiveSize64; + + // Get the size of the entire file + FileStream_GetSize(ha->pStream, &pSI->EndOfFile); +} + +static bool CalculateMpqHashMd5( + TMPQArchive * ha, + PMPQ_SIGNATURE_INFO pSI, + LPBYTE pMd5Digest) +{ + hash_state md5_state; + ULONGLONG BeginBuffer; + ULONGLONG EndBuffer; + LPBYTE pbDigestBuffer = NULL; + + // Allocate buffer for creating the MPQ digest. + pbDigestBuffer = STORM_ALLOC(BYTE, MPQ_DIGEST_UNIT_SIZE); + if(pbDigestBuffer == NULL) + return false; + + // Initialize the MD5 hash state + md5_init(&md5_state); + + // Set the byte offset of begin of the data + BeginBuffer = pSI->BeginMpqData; + + // Create the digest + for(;;) + { + ULONGLONG BytesRemaining; + LPBYTE pbSigBegin = NULL; + LPBYTE pbSigEnd = NULL; + DWORD dwToRead = MPQ_DIGEST_UNIT_SIZE; + + // Check the number of bytes remaining + BytesRemaining = pSI->EndMpqData - BeginBuffer; + if(BytesRemaining < MPQ_DIGEST_UNIT_SIZE) + dwToRead = (DWORD)BytesRemaining; + if(dwToRead == 0) + break; + + // Read the next chunk + if(!FileStream_Read(ha->pStream, &BeginBuffer, pbDigestBuffer, dwToRead)) + { + STORM_FREE(pbDigestBuffer); + return false; + } + + // Move the current byte offset + EndBuffer = BeginBuffer + dwToRead; + + // Check if the signature is within the loaded digest + if(BeginBuffer <= pSI->BeginExclude && pSI->BeginExclude < EndBuffer) + pbSigBegin = pbDigestBuffer + (size_t)(pSI->BeginExclude - BeginBuffer); + if(BeginBuffer <= pSI->EndExclude && pSI->EndExclude < EndBuffer) + pbSigEnd = pbDigestBuffer + (size_t)(pSI->EndExclude - BeginBuffer); + + // Zero the part that belongs to the signature + if(pbSigBegin != NULL || pbSigEnd != NULL) + { + if(pbSigBegin == NULL) + pbSigBegin = pbDigestBuffer; + if(pbSigEnd == NULL) + pbSigEnd = pbDigestBuffer + dwToRead; + + memset(pbSigBegin, 0, (pbSigEnd - pbSigBegin)); + } + + // Pass the buffer to the hashing function + md5_process(&md5_state, pbDigestBuffer, dwToRead); + + // Move pointers + BeginBuffer += dwToRead; + } + + // Finalize the MD5 hash + md5_done(&md5_state, pMd5Digest); + STORM_FREE(pbDigestBuffer); + return true; +} + +static void AddTailToSha1( + hash_state * psha1_state, + const char * szTail) +{ + unsigned char * pbTail = (unsigned char *)szTail; + unsigned char szUpperCase[0x200]; + unsigned long nLength = 0; + + // Convert the tail to uppercase + // Note that we don't need to terminate the string with zero + while(*pbTail != 0) + { + szUpperCase[nLength++] = AsciiToUpperTable[*pbTail++]; + } + + // Append the tail to the SHA1 + sha1_process(psha1_state, szUpperCase, nLength); +} + +static bool CalculateMpqHashSha1( + TMPQArchive * ha, + PMPQ_SIGNATURE_INFO pSI, + unsigned char * sha1_tail0, + unsigned char * sha1_tail1, + unsigned char * sha1_tail2) +{ + ULONGLONG BeginBuffer; + hash_state sha1_state_temp; + hash_state sha1_state; + LPBYTE pbDigestBuffer = NULL; + char szPlainName[MAX_PATH]; + + // Allocate buffer for creating the MPQ digest. + pbDigestBuffer = STORM_ALLOC(BYTE, MPQ_DIGEST_UNIT_SIZE); + if(pbDigestBuffer == NULL) + return false; + + // Initialize SHA1 state structure + sha1_init(&sha1_state); + + // Calculate begin of data to be hashed + BeginBuffer = pSI->BeginMpqData; + + // Create the digest + for(;;) + { + ULONGLONG BytesRemaining; + DWORD dwToRead = MPQ_DIGEST_UNIT_SIZE; + + // Check the number of bytes remaining + BytesRemaining = pSI->EndMpqData - BeginBuffer; + if(BytesRemaining < MPQ_DIGEST_UNIT_SIZE) + dwToRead = (DWORD)BytesRemaining; + if(dwToRead == 0) + break; + + // Read the next chunk + if(!FileStream_Read(ha->pStream, &BeginBuffer, pbDigestBuffer, dwToRead)) + { + STORM_FREE(pbDigestBuffer); + return false; + } + + // Pass the buffer to the hashing function + sha1_process(&sha1_state, pbDigestBuffer, dwToRead); + + // Move pointers + BeginBuffer += dwToRead; + } + + // Add all three known tails and generate three hashes + memcpy(&sha1_state_temp, &sha1_state, sizeof(hash_state)); + sha1_done(&sha1_state_temp, sha1_tail0); + + memcpy(&sha1_state_temp, &sha1_state, sizeof(hash_state)); + GetPlainAnsiFileName(FileStream_GetFileName(ha->pStream), szPlainName); + AddTailToSha1(&sha1_state_temp, szPlainName); + sha1_done(&sha1_state_temp, sha1_tail1); + + memcpy(&sha1_state_temp, &sha1_state, sizeof(hash_state)); + AddTailToSha1(&sha1_state_temp, "ARCHIVE"); + sha1_done(&sha1_state_temp, sha1_tail2); + + // Finalize the MD5 hash + STORM_FREE(pbDigestBuffer); + return true; +} + +static DWORD VerifyRawMpqData( + TMPQArchive * ha, + ULONGLONG ByteOffset, + DWORD dwDataSize) +{ + ULONGLONG DataOffset = ha->MpqPos + ByteOffset; + LPBYTE pbDataChunk; + LPBYTE pbMD5Array1; // Calculated MD5 array + LPBYTE pbMD5Array2; // MD5 array loaded from the MPQ + DWORD dwBytesInChunk; + DWORD dwChunkCount; + DWORD dwChunkSize = ha->pHeader->dwRawChunkSize; + DWORD dwMD5Size; + DWORD dwErrCode = ERROR_SUCCESS; + + // Don't verify zero-sized blocks + if(dwDataSize == 0) + return ERROR_SUCCESS; + + // Get the number of data chunks to calculate MD5 + assert(dwChunkSize != 0); + dwChunkCount = ((dwDataSize - 1) / dwChunkSize) + 1; + dwMD5Size = dwChunkCount * MD5_DIGEST_SIZE; + + // Allocate space for data chunk and for the MD5 array + pbDataChunk = STORM_ALLOC(BYTE, dwChunkSize); + if(pbDataChunk == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // Allocate space for MD5 array + pbMD5Array1 = STORM_ALLOC(BYTE, dwMD5Size); + pbMD5Array2 = STORM_ALLOC(BYTE, dwMD5Size); + if(pbMD5Array1 == NULL || pbMD5Array2 == NULL) + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + + // Calculate MD5 of each data chunk + if(dwErrCode == ERROR_SUCCESS) + { + LPBYTE pbMD5 = pbMD5Array1; + + for(DWORD i = 0; i < dwChunkCount; i++) + { + // Get the number of bytes in the chunk + dwBytesInChunk = STORMLIB_MIN(dwChunkSize, dwDataSize); + + // Read the data chunk + if(!FileStream_Read(ha->pStream, &DataOffset, pbDataChunk, dwBytesInChunk)) + { + dwErrCode = ERROR_FILE_CORRUPT; + break; + } + + // Calculate MD5 + CalculateDataBlockHash(pbDataChunk, dwBytesInChunk, pbMD5); + + // Move pointers and offsets + DataOffset += dwBytesInChunk; + dwDataSize -= dwBytesInChunk; + pbMD5 += MD5_DIGEST_SIZE; + } + } + + // Read the MD5 array + if(dwErrCode == ERROR_SUCCESS) + { + // Read the array of MD5 + if(!FileStream_Read(ha->pStream, &DataOffset, pbMD5Array2, dwMD5Size)) + dwErrCode = GetLastError(); + } + + // Compare the array of MD5 + if(dwErrCode == ERROR_SUCCESS) + { + // Compare the MD5 + if(memcmp(pbMD5Array1, pbMD5Array2, dwMD5Size)) + dwErrCode = ERROR_FILE_CORRUPT; + } + + // Free memory and return result + if(pbMD5Array2 != NULL) + STORM_FREE(pbMD5Array2); + if(pbMD5Array1 != NULL) + STORM_FREE(pbMD5Array1); + if(pbDataChunk != NULL) + STORM_FREE(pbDataChunk); + return dwErrCode; +} + +static DWORD VerifyWeakSignature( + TMPQArchive * ha, + PMPQ_SIGNATURE_INFO pSI) +{ + BYTE RevSignature[MPQ_WEAK_SIGNATURE_SIZE]; + BYTE Md5Digest[MD5_DIGEST_SIZE]; + rsa_key key; + int hash_idx = find_hash("md5"); + int result = 0; + + // The signature might be zeroed out. In that case, we ignore it + if(!IsValidSignature(pSI->Signature)) + return ERROR_WEAK_SIGNATURE_OK; + + // Calculate hash of the entire archive, skipping the (signature) file + if(!CalculateMpqHashMd5(ha, pSI, Md5Digest)) + return ERROR_VERIFY_FAILED; + + // Import the Blizzard key in OpenSSL format + if(!decode_base64_key(szBlizzardWeakPublicKey, &key)) + return ERROR_VERIFY_FAILED; + + // Verify the signature + memcpy(RevSignature, &pSI->Signature[8], MPQ_WEAK_SIGNATURE_SIZE); + memrev(RevSignature, MPQ_WEAK_SIGNATURE_SIZE); + rsa_verify_hash_ex(RevSignature, MPQ_WEAK_SIGNATURE_SIZE, Md5Digest, sizeof(Md5Digest), LTC_LTC_PKCS_1_V1_5, hash_idx, 0, &result, &key); + rsa_free(&key); + + // Return the result + return result ? ERROR_WEAK_SIGNATURE_OK : ERROR_WEAK_SIGNATURE_ERROR; +} + +static DWORD VerifyStrongSignatureWithKey( + unsigned char * reversed_signature, + unsigned char * padded_digest, + const char * szPublicKey) +{ + rsa_key key; + int result = 0; + + // Import the Blizzard key in OpenSSL format + if(!decode_base64_key(szPublicKey, &key)) + { + assert(false); + return ERROR_VERIFY_FAILED; + } + + // Verify the signature + if(rsa_verify_simple(reversed_signature, MPQ_STRONG_SIGNATURE_SIZE, padded_digest, MPQ_STRONG_SIGNATURE_SIZE, &result, &key) != CRYPT_OK) + return ERROR_VERIFY_FAILED; + + // Free the key and return result + rsa_free(&key); + return result ? ERROR_STRONG_SIGNATURE_OK : ERROR_STRONG_SIGNATURE_ERROR; +} + +static DWORD VerifyStrongSignature( + TMPQArchive * ha, + PMPQ_SIGNATURE_INFO pSI) +{ + unsigned char reversed_signature[MPQ_STRONG_SIGNATURE_SIZE]; + unsigned char Sha1Digest_tail0[SHA1_DIGEST_SIZE]; + unsigned char Sha1Digest_tail1[SHA1_DIGEST_SIZE]; + unsigned char Sha1Digest_tail2[SHA1_DIGEST_SIZE]; + unsigned char padded_digest[MPQ_STRONG_SIGNATURE_SIZE]; + DWORD dwResult; + size_t digest_offset; + + // Calculate SHA1 hash of the archive + if(!CalculateMpqHashSha1(ha, pSI, Sha1Digest_tail0, Sha1Digest_tail1, Sha1Digest_tail2)) + return ERROR_VERIFY_FAILED; + + // Prepare the signature for decryption + memcpy(reversed_signature, &pSI->Signature[4], MPQ_STRONG_SIGNATURE_SIZE); + memrev(reversed_signature, MPQ_STRONG_SIGNATURE_SIZE); + + // Prepare the padded digest for comparison + digest_offset = sizeof(padded_digest) - SHA1_DIGEST_SIZE; + memset(padded_digest, 0xbb, digest_offset); + padded_digest[0] = 0x0b; + + // Try Blizzard Strong public key with no SHA1 tail + memcpy(padded_digest + digest_offset, Sha1Digest_tail0, SHA1_DIGEST_SIZE); + memrev(padded_digest + digest_offset, SHA1_DIGEST_SIZE); + dwResult = VerifyStrongSignatureWithKey(reversed_signature, padded_digest, szBlizzardStrongPublicKey); + if(dwResult == ERROR_STRONG_SIGNATURE_OK) + return dwResult; + + // Try War 3 map public key with plain file name as SHA1 tail + memcpy(padded_digest + digest_offset, Sha1Digest_tail1, SHA1_DIGEST_SIZE); + memrev(padded_digest + digest_offset, SHA1_DIGEST_SIZE); + dwResult = VerifyStrongSignatureWithKey(reversed_signature, padded_digest, szWarcraft3MapPublicKey); + if(dwResult == ERROR_STRONG_SIGNATURE_OK) + return dwResult; + + // Try WoW-TBC public key with "ARCHIVE" as SHA1 tail + memcpy(padded_digest + digest_offset, Sha1Digest_tail2, SHA1_DIGEST_SIZE); + memrev(padded_digest + digest_offset, SHA1_DIGEST_SIZE); + dwResult = VerifyStrongSignatureWithKey(reversed_signature, padded_digest, szWowPatchPublicKey); + if(dwResult == ERROR_STRONG_SIGNATURE_OK) + return dwResult; + + // Try Survey public key with no SHA1 tail + memcpy(padded_digest + digest_offset, Sha1Digest_tail0, SHA1_DIGEST_SIZE); + memrev(padded_digest + digest_offset, SHA1_DIGEST_SIZE); + dwResult = VerifyStrongSignatureWithKey(reversed_signature, padded_digest, szWowSurveyPublicKey); + if(dwResult == ERROR_STRONG_SIGNATURE_OK) + return dwResult; + + // Try Starcraft II public key with no SHA1 tail + memcpy(padded_digest + digest_offset, Sha1Digest_tail0, SHA1_DIGEST_SIZE); + memrev(padded_digest + digest_offset, SHA1_DIGEST_SIZE); + dwResult = VerifyStrongSignatureWithKey(reversed_signature, padded_digest, szStarcraft2MapPublicKey); + if(dwResult == ERROR_STRONG_SIGNATURE_OK) + return dwResult; + + return ERROR_STRONG_SIGNATURE_ERROR; +} + +static DWORD VerifyFile( + HANDLE hMpq, + const char * szFileName, + LPDWORD pdwCrc32, + char * pMD5, + DWORD dwFlags) +{ + hash_state md5_state; + unsigned char * pFileMd5; + unsigned char md5[MD5_DIGEST_SIZE]; + TFileEntry * pFileEntry; + TMPQFile * hf; + BYTE Buffer[0x1000]; + HANDLE hFile = NULL; + DWORD dwVerifyResult = 0; + DWORD dwTotalBytes = 0; + DWORD dwCrc32 = 0; + + // + // Note: When the MPQ is patched, it will + // automatically check the patched version of the file + // + + // Make sure the md5 is initialized + memset(md5, 0, sizeof(md5)); + + // If we have to verify raw data MD5, do it before file open + if(dwFlags & SFILE_VERIFY_RAW_MD5) + { + TMPQArchive * ha = (TMPQArchive *)hMpq; + + // Parse the base MPQ and all patches + while(ha != NULL) + { + // Does the archive have support for raw MD5? + if(ha->pHeader->dwRawChunkSize != 0) + { + // The file has raw MD5 if the archive supports it + dwVerifyResult |= VERIFY_FILE_HAS_RAW_MD5; + + // Find file entry for the file + pFileEntry = GetFileEntryLocale(ha, szFileName, g_lcFileLocale); + if(pFileEntry != NULL) + { + // If the file's raw MD5 doesn't match, don't bother with more checks + if(VerifyRawMpqData(ha, pFileEntry->ByteOffset, pFileEntry->dwCmpSize) != ERROR_SUCCESS) + return dwVerifyResult | VERIFY_FILE_RAW_MD5_ERROR; + } + } + + // Move to the next patch + ha = ha->haPatch; + } + } + + // Attempt to open the file + if(SFileOpenFileEx(hMpq, szFileName, SFILE_OPEN_FROM_MPQ, &hFile)) + { + // Get the file size + hf = (TMPQFile *)hFile; + pFileEntry = hf->pFileEntry; + dwTotalBytes = SFileGetFileSize(hFile, NULL); + + // Initialize the CRC32 and MD5 contexts + md5_init(&md5_state); + dwCrc32 = crc32(0, Z_NULL, 0); + + // Also turn on sector checksum verification + if(dwFlags & SFILE_VERIFY_SECTOR_CRC) + hf->bCheckSectorCRCs = true; + + // Go through entire file and update both CRC32 and MD5 + for(;;) + { + DWORD dwBytesRead = 0; + + // Read data from file + SFileReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL); + if(dwBytesRead == 0) + { + if(GetLastError() == ERROR_CHECKSUM_ERROR) + dwVerifyResult |= VERIFY_FILE_SECTOR_CRC_ERROR; + break; + } + + // Update CRC32 value + if(dwFlags & SFILE_VERIFY_FILE_CRC) + dwCrc32 = crc32(dwCrc32, Buffer, dwBytesRead); + + // Update MD5 value + if(dwFlags & SFILE_VERIFY_FILE_MD5) + md5_process(&md5_state, Buffer, dwBytesRead); + + // Decrement the total size + dwTotalBytes -= dwBytesRead; + } + + // If the file has sector checksums, indicate it in the flags + if(dwFlags & SFILE_VERIFY_SECTOR_CRC) + { + if((hf->pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC) && hf->SectorChksums != NULL && hf->SectorChksums[0] != 0) + dwVerifyResult |= VERIFY_FILE_HAS_SECTOR_CRC; + } + + // Check if the entire file has been read + // No point in checking CRC32 and MD5 if not + // Skip checksum checks if the file has patches + if(dwTotalBytes == 0) + { + // Check CRC32 and MD5 only if there is no patches + if(hf->hfPatch == NULL) + { + // Check if the CRC32 matches. + if(dwFlags & SFILE_VERIFY_FILE_CRC) + { + // Only check the CRC32 if it is valid + if(pFileEntry->dwCrc32 != 0) + { + dwVerifyResult |= VERIFY_FILE_HAS_CHECKSUM; + if(dwCrc32 != pFileEntry->dwCrc32) + dwVerifyResult |= VERIFY_FILE_CHECKSUM_ERROR; + } + } + + // Check if MD5 matches + if(dwFlags & SFILE_VERIFY_FILE_MD5) + { + // Patch files have their MD5 saved in the patch info + pFileMd5 = (hf->pPatchInfo != NULL) ? hf->pPatchInfo->md5 : pFileEntry->md5; + md5_done(&md5_state, md5); + + // Only check the MD5 if it is valid + if(IsValidMD5(pFileMd5)) + { + dwVerifyResult |= VERIFY_FILE_HAS_MD5; + if(memcmp(md5, pFileMd5, MD5_DIGEST_SIZE)) + dwVerifyResult |= VERIFY_FILE_MD5_ERROR; + } + } + } + else + { + // Patched files are MD5-checked automatically + dwVerifyResult |= VERIFY_FILE_HAS_MD5; + } + } + else + { + dwVerifyResult |= VERIFY_READ_ERROR; + } + + SFileCloseFile(hFile); + } + else + { + // Remember that the file couldn't be open + dwVerifyResult |= VERIFY_OPEN_ERROR; + } + + // If the caller required CRC32 and/or MD5, give it to him + if(pdwCrc32 != NULL) + *pdwCrc32 = dwCrc32; + if(pMD5 != NULL) + memcpy(pMD5, md5, MD5_DIGEST_SIZE); + + return dwVerifyResult; +} + +// Used in SFileGetFileInfo +bool QueryMpqSignatureInfo( + TMPQArchive * ha, + PMPQ_SIGNATURE_INFO pSI) +{ + TFileEntry * pFileEntry; + ULONGLONG ExtraBytes; + DWORD dwFileSize; + + // Make sure it's all zeroed + memset(pSI, 0, sizeof(MPQ_SIGNATURE_INFO)); + + // Calculate the range of the MPQ + CalculateArchiveRange(ha, pSI); + + // If there is "(signature)" file in the MPQ, it has a weak signature + pFileEntry = GetFileEntryLocale(ha, SIGNATURE_NAME, LANG_NEUTRAL); + if(pFileEntry != NULL) + { + // Calculate the begin and end of the signature file itself + pSI->BeginExclude = ha->MpqPos + pFileEntry->ByteOffset; + pSI->EndExclude = pSI->BeginExclude + pFileEntry->dwCmpSize; + dwFileSize = (DWORD)(pSI->EndExclude - pSI->BeginExclude); + + // Does the signature have proper size? + if(dwFileSize == MPQ_SIGNATURE_FILE_SIZE) + { + // Read the weak signature + if(!FileStream_Read(ha->pStream, &pSI->BeginExclude, pSI->Signature, dwFileSize)) + return false; + + pSI->SignatureTypes |= SIGNATURE_TYPE_WEAK; + pSI->cbSignatureSize = dwFileSize; + return true; + } + } + + // If there is extra bytes beyond the end of the archive, + // it's the strong signature + ExtraBytes = pSI->EndOfFile - pSI->EndMpqData; + if(ExtraBytes >= (MPQ_STRONG_SIGNATURE_SIZE + 4)) + { + // Read the strong signature + if(!FileStream_Read(ha->pStream, &pSI->EndMpqData, pSI->Signature, (MPQ_STRONG_SIGNATURE_SIZE + 4))) + return false; + + // Check the signature header "NGIS" + if(pSI->Signature[0] != 'N' || pSI->Signature[1] != 'G' || pSI->Signature[2] != 'I' || pSI->Signature[3] != 'S') + return true; //Not a valid signature, but another filetype could've been appended so not always an error. + + pSI->SignatureTypes |= SIGNATURE_TYPE_STRONG; + return true; + } + + // Succeeded, but no known signature found + return true; +} + +//----------------------------------------------------------------------------- +// Support for weak signature + +DWORD SSignFileCreate(TMPQArchive * ha) +{ + TMPQFile * hf = NULL; + BYTE EmptySignature[MPQ_SIGNATURE_FILE_SIZE]; + DWORD dwErrCode = ERROR_SUCCESS; + + // Only save the signature if we should do so + if(ha->dwFileFlags3 != 0) + { + // The (signature) file must be non-encrypted and non-compressed + assert(ha->dwFlags & MPQ_FLAG_SIGNATURE_NEW); + assert(ha->dwFileFlags3 == MPQ_FILE_EXISTS); + assert(ha->dwReservedFiles > 0); + + // Create the (signature) file file in the MPQ + // Note that the file must not be compressed or encrypted + dwErrCode = SFileAddFile_Init(ha, SIGNATURE_NAME, + 0, + sizeof(EmptySignature), + LANG_NEUTRAL, + ha->dwFileFlags3 | MPQ_FILE_REPLACEEXISTING, + &hf); + + // Write the empty signature file to the archive + if(dwErrCode == ERROR_SUCCESS) + { + // Write the empty zeroed file to the MPQ + memset(EmptySignature, 0, sizeof(EmptySignature)); + dwErrCode = SFileAddFile_Write(hf, EmptySignature, (DWORD)sizeof(EmptySignature), 0); + SFileAddFile_Finish(hf); + + // Clear the invalid mark + ha->dwFlags &= ~(MPQ_FLAG_SIGNATURE_NEW | MPQ_FLAG_SIGNATURE_NONE); + ha->dwReservedFiles--; + } + } + + return dwErrCode; +} + +DWORD SSignFileFinish(TMPQArchive * ha) +{ + MPQ_SIGNATURE_INFO si; + unsigned long signature_len = MPQ_WEAK_SIGNATURE_SIZE; + BYTE WeakSignature[MPQ_SIGNATURE_FILE_SIZE]; + BYTE Md5Digest[MD5_DIGEST_SIZE]; + rsa_key key; + int hash_idx = find_hash("md5"); + + // Sanity checks + assert((ha->dwFlags & MPQ_FLAG_CHANGED) == 0); + assert(ha->dwFileFlags3 == MPQ_FILE_EXISTS); + + // Query the weak signature info + memset(&si, 0, sizeof(MPQ_SIGNATURE_INFO)); + if(!QueryMpqSignatureInfo(ha, &si)) + return ERROR_FILE_CORRUPT; + + // There must be exactly one signature + if(si.SignatureTypes != SIGNATURE_TYPE_WEAK) + return ERROR_FILE_CORRUPT; + + // Calculate MD5 of the entire archive + if(!CalculateMpqHashMd5(ha, &si, Md5Digest)) + return ERROR_VERIFY_FAILED; + + // Decode the private key + if(!decode_base64_key(szBlizzardWeakPrivateKey, &key)) + return ERROR_VERIFY_FAILED; + + // Sign the hash + memset(WeakSignature, 0, sizeof(WeakSignature)); + rsa_sign_hash_ex(Md5Digest, sizeof(Md5Digest), WeakSignature + 8, &signature_len, LTC_LTC_PKCS_1_V1_5, 0, 0, hash_idx, 0, &key); + memrev(WeakSignature + 8, MPQ_WEAK_SIGNATURE_SIZE); + rsa_free(&key); + + // Write the signature to the MPQ. Don't use SFile* functions, but write the hash directly + if(!FileStream_Write(ha->pStream, &si.BeginExclude, WeakSignature, MPQ_SIGNATURE_FILE_SIZE)) + return GetLastError(); + + return ERROR_SUCCESS; +} + +//----------------------------------------------------------------------------- +// Public (exported) functions + +bool WINAPI SFileGetFileChecksums(HANDLE hMpq, const char * szFileName, LPDWORD pdwCrc32, char * pMD5) +{ + DWORD dwVerifyResult; + DWORD dwVerifyFlags = 0; + + if(pdwCrc32 != NULL) + dwVerifyFlags |= SFILE_VERIFY_FILE_CRC; + if(pMD5 != NULL) + dwVerifyFlags |= SFILE_VERIFY_FILE_MD5; + + dwVerifyResult = VerifyFile(hMpq, + szFileName, + pdwCrc32, + pMD5, + dwVerifyFlags); + + // If verification failed, return zero + if(dwVerifyResult & VERIFY_FILE_ERROR_MASK) + { + SetLastError(ERROR_FILE_CORRUPT); + return false; + } + + return true; +} + + +DWORD WINAPI SFileVerifyFile(HANDLE hMpq, const char * szFileName, DWORD dwFlags) +{ + return VerifyFile(hMpq, + szFileName, + NULL, + NULL, + dwFlags); +} + +// Verifies raw data of the archive Only works for MPQs version 4 or newer +DWORD WINAPI SFileVerifyRawData(HANDLE hMpq, DWORD dwWhatToVerify, const char * szFileName) +{ + TMPQArchive * ha = (TMPQArchive *)hMpq; + TFileEntry * pFileEntry; + TMPQHeader * pHeader; + + // Verify input parameters + if(!IsValidMpqHandle(hMpq)) + return ERROR_INVALID_PARAMETER; + pHeader = ha->pHeader; + + // If the archive doesn't have raw data MD5, report it as OK + if(pHeader->dwRawChunkSize == 0) + return ERROR_SUCCESS; + + // If we have to verify MPQ header, do it + switch(dwWhatToVerify) + { + case SFILE_VERIFY_MPQ_HEADER: + + // Only if the header is of version 4 or newer + if(pHeader->dwHeaderSize >= (MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE)) + return VerifyRawMpqData(ha, 0, MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE); + return ERROR_SUCCESS; + + case SFILE_VERIFY_HET_TABLE: + + // Only if we have HET table + if(pHeader->HetTablePos64 && pHeader->HetTableSize64) + return VerifyRawMpqData(ha, pHeader->HetTablePos64, (DWORD)pHeader->HetTableSize64); + return ERROR_SUCCESS; + + case SFILE_VERIFY_BET_TABLE: + + // Only if we have BET table + if(pHeader->BetTablePos64 && pHeader->BetTableSize64) + return VerifyRawMpqData(ha, pHeader->BetTablePos64, (DWORD)pHeader->BetTableSize64); + return ERROR_SUCCESS; + + case SFILE_VERIFY_HASH_TABLE: + + // Hash table is not protected by MD5 + return ERROR_SUCCESS; + + case SFILE_VERIFY_BLOCK_TABLE: + + // Block table is not protected by MD5 + return ERROR_SUCCESS; + + case SFILE_VERIFY_HIBLOCK_TABLE: + + // It is unknown if the hi-block table is protected my MD5 or not. + return ERROR_SUCCESS; + + case SFILE_VERIFY_FILE: + + // Verify parameters + if(szFileName == NULL || *szFileName == 0) + return ERROR_INVALID_PARAMETER; + + // Get the offset of a file + pFileEntry = GetFileEntryLocale(ha, szFileName, g_lcFileLocale); + if(pFileEntry == NULL) + return ERROR_FILE_NOT_FOUND; + + return VerifyRawMpqData(ha, pFileEntry->ByteOffset, pFileEntry->dwCmpSize); + } + + return ERROR_INVALID_PARAMETER; +} + + +// Verifies the archive against the signature +DWORD WINAPI SFileVerifyArchive(HANDLE hMpq) +{ + MPQ_SIGNATURE_INFO si; + TMPQArchive * ha = (TMPQArchive *)hMpq; + + // Verify input parameters + if(!IsValidMpqHandle(hMpq)) + return ERROR_VERIFY_FAILED; + + // If the archive was modified, we need to flush it + if(ha->dwFlags & MPQ_FLAG_CHANGED) + SFileFlushArchive(hMpq); + + // Get the MPQ signature and signature type + memset(&si, 0, sizeof(MPQ_SIGNATURE_INFO)); + if(!QueryMpqSignatureInfo(ha, &si)) + return ERROR_VERIFY_FAILED; + + // If there is no signature + if(si.SignatureTypes == 0) + return ERROR_NO_SIGNATURE; + + // We haven't seen a MPQ with both signatures + assert(si.SignatureTypes == SIGNATURE_TYPE_WEAK || si.SignatureTypes == SIGNATURE_TYPE_STRONG); + + // Verify the strong signature, if present + if(si.SignatureTypes & SIGNATURE_TYPE_STRONG) + return VerifyStrongSignature(ha, &si); + + // Verify the weak signature, if present + if(si.SignatureTypes & SIGNATURE_TYPE_WEAK) + return VerifyWeakSignature(ha, &si); + + return ERROR_NO_SIGNATURE; +} + +// Verifies the archive against the signature +bool WINAPI SFileSignArchive(HANDLE hMpq, DWORD dwSignatureType) +{ + TMPQArchive * ha; + + // Verify the archive handle + ha = IsValidMpqHandle(hMpq); + if(ha == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + // We only support weak signature, and only for MPQs version 1.0 + if(dwSignatureType != SIGNATURE_TYPE_WEAK) + { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + + // The archive must not be malformed and must not be read-only + if(ha->dwFlags & (MPQ_FLAG_READ_ONLY | MPQ_FLAG_MALFORMED)) + { + SetLastError(ERROR_ACCESS_DENIED); + return false; + } + + // If the signature is not there yet + if(ha->dwFileFlags3 == 0) + { + // Turn the signature on. The signature will + // be applied when the archive is closed + ha->dwFlags |= MPQ_FLAG_SIGNATURE_NEW | MPQ_FLAG_CHANGED; + ha->dwFileFlags3 = MPQ_FILE_EXISTS; + ha->dwReservedFiles++; + } + + return true; +} + diff --git a/StormLib/src/StormCommon.h b/StormLib/src/StormCommon.h new file mode 100644 index 000000000..ecbc43130 --- /dev/null +++ b/StormLib/src/StormCommon.h @@ -0,0 +1,440 @@ +/*****************************************************************************/ +/* SCommon.h Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Common functions for encryption/decryption from Storm.dll. Included by */ +/* SFile*** functions, do not include and do not use this file directly */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 24.03.03 1.00 Lad The first version of SFileCommon.h */ +/* 12.06.04 1.00 Lad Renamed to SCommon.h */ +/* 06.09.10 1.00 Lad Renamed to StormCommon.h */ +/*****************************************************************************/ + +#ifndef __STORMCOMMON_H__ +#define __STORMCOMMON_H__ + +//----------------------------------------------------------------------------- +// Compression support + +// Include functions from Pkware Data Compression Library +#include "pklib/pklib.h" + +// Include functions from Huffmann compression +#include "huffman/huff.h" + +// Include functions from IMA ADPCM compression +#include "adpcm/adpcm.h" + +// Include functions from SPARSE compression +#include "sparse/sparse.h" + +// Include functions from LZMA compression +#include "lzma/C/LzmaEnc.h" +#include "lzma/C/LzmaDec.h" + +// Include functions from zlib +#ifndef __SYS_ZLIB + #include "zlib/zlib.h" +#else + #include +#endif + +// Include functions from bzlib +#ifndef __SYS_BZLIB + #include "bzip2/bzlib.h" +#else + #include +#endif + +//----------------------------------------------------------------------------- +// Cryptography support + +// Headers from LibTomCrypt +#include "libtomcrypt/src/headers/tomcrypt.h" + +// For HashStringJenkins +#include "jenkins/lookup.h" + +//----------------------------------------------------------------------------- +// StormLib private defines + +#define ID_MPQ_FILE 0x46494c45 // Used internally for checking TMPQFile ('FILE') + +// Prevent problems with CRT "min" and "max" functions, +// as they are not defined on all platforms +#define STORMLIB_MIN(a, b) ((a < b) ? a : b) +#define STORMLIB_MAX(a, b) ((a > b) ? a : b) +#define STORMLIB_UNUSED(p) ((void)(p)) + +// Checks for data pointers aligned to 4-byte boundary +#define STORMLIB_DWORD_ALIGNED(ptr) (((size_t)(ptr) & 0x03) == 0) + +// Macro for building 64-bit file offset from two 32-bit +#define MAKE_OFFSET64(hi, lo) (((ULONGLONG)hi << 32) | (ULONGLONG)lo) + +//----------------------------------------------------------------------------- +// MTYPE definition - specifies what kind of MPQ is the map type + +typedef enum _MTYPE +{ + MapTypeNotChecked, // The map type was not checked yet + MapTypeNotRecognized, // The file does not seems to be a map + MapTypeAviFile, // The file is actually an AVI file (Warcraft III cinematics) + MapTypeWarcraft3, // The file is a Warcraft III map + MapTypeStarcraft2 // The file is a Starcraft II map +} MTYPE, *PMTYPE; + +//----------------------------------------------------------------------------- +// MPQ signature information + +// Size of each signature type +#define MPQ_WEAK_SIGNATURE_SIZE 64 +#define MPQ_STRONG_SIGNATURE_SIZE 256 +#define MPQ_STRONG_SIGNATURE_ID 0x5349474E // ID of the strong signature ("NGIS") +#define MPQ_SIGNATURE_FILE_SIZE (MPQ_WEAK_SIGNATURE_SIZE + 8) + +// MPQ signature info +typedef struct _MPQ_SIGNATURE_INFO +{ + ULONGLONG BeginMpqData; // File offset where the hashing starts + ULONGLONG BeginExclude; // Begin of the excluded area (used for (signature) file) + ULONGLONG EndExclude; // End of the excluded area (used for (signature) file) + ULONGLONG EndMpqData; // File offset where the hashing ends + ULONGLONG EndOfFile; // Size of the entire file + BYTE Signature[MPQ_STRONG_SIGNATURE_SIZE + 0x10]; + DWORD cbSignatureSize; // Length of the signature + DWORD SignatureTypes; // See SIGNATURE_TYPE_XXX + +} MPQ_SIGNATURE_INFO, *PMPQ_SIGNATURE_INFO; + +//----------------------------------------------------------------------------- +// Memory management +// +// We use our own macros for allocating/freeing memory. If you want +// to redefine them, please keep the following rules: +// +// - The memory allocation must return NULL if not enough memory +// (i.e not to throw exception) +// - The allocating function does not need to fill the allocated buffer with zeros +// - Memory freeing function doesn't have to test the pointer to NULL +// + +//#if defined(_MSC_VER) && defined(_DEBUG) +// +//#define STORM_ALLOC(type, nitems) (type *)HeapAlloc(GetProcessHeap(), 0, ((nitems) * sizeof(type))) +//#define STORM_REALLOC(type, ptr, nitems) (type *)HeapReAlloc(GetProcessHeap(), 0, ptr, ((nitems) * sizeof(type))) +//#define STORM_FREE(ptr) HeapFree(GetProcessHeap(), 0, ptr) +// +//#else + +#define STORM_ALLOC(type, nitems) (type *)malloc((nitems) * sizeof(type)) +#define STORM_REALLOC(type, ptr, nitems) (type *)realloc(ptr, ((nitems) * sizeof(type))) +#define STORM_FREE(ptr) free(ptr) + +//#endif + +//----------------------------------------------------------------------------- +// StormLib internal global variables + +extern DWORD g_dwMpqSignature; // Marker for MPQ header +extern DWORD g_dwHashTableKey; // Key for hash table +extern DWORD g_dwBlockTableKey; // Key for block table +extern LCID g_lcFileLocale; // Preferred file locale + +//----------------------------------------------------------------------------- +// Conversion to uppercase/lowercase (and "/" to "\") + +extern unsigned char AsciiToLowerTable[256]; +extern unsigned char AsciiToUpperTable[256]; + +//----------------------------------------------------------------------------- +// Safe string functions + +template +XCHAR * IntToString(XCHAR * szBuffer, size_t cchMaxChars, XINT nValue, size_t nDigitCount = 0) +{ + XCHAR * szBufferEnd = szBuffer + cchMaxChars - 1; + XCHAR szNumberRev[0x20]; + size_t nLength = 0; + + // Always put the first digit + szNumberRev[nLength++] = (XCHAR)(nValue % 10) + '0'; + nValue /= 10; + + // Continue as long as we have non-zero + while(nValue != 0) + { + szNumberRev[nLength++] = (XCHAR)(nValue % 10) + '0'; + nValue /= 10; + } + + // Fill zeros, if needed + while(szBuffer < szBufferEnd && nLength < nDigitCount) + { + *szBuffer++ = '0'; + nDigitCount--; + } + + // Fill the buffer + while(szBuffer < szBufferEnd && nLength > 0) + { + nLength--; + *szBuffer++ = szNumberRev[nLength]; + } + + // Terminate the number with zeros + szBuffer[0] = 0; + return szBuffer; +} + +char * StringCopy(char * szTarget, size_t cchTarget, const char * szSource); +void StringCat(char * szTarget, size_t cchTargetMax, const char * szSource); +void StringCreatePseudoFileName(char * szBuffer, size_t cchMaxChars, unsigned int nIndex, const char * szExtension); + +#ifdef _UNICODE +void StringCopy(TCHAR * szTarget, size_t cchTarget, const char * szSource); +void StringCopy(char * szTarget, size_t cchTarget, const TCHAR * szSource); +void StringCopy(TCHAR * szTarget, size_t cchTarget, const TCHAR * szSource); +void StringCat(TCHAR * szTarget, size_t cchTargetMax, const TCHAR * szSource); +#endif + +//----------------------------------------------------------------------------- +// Encryption and decryption functions + +#define MPQ_HASH_TABLE_INDEX 0x000 +#define MPQ_HASH_NAME_A 0x100 +#define MPQ_HASH_NAME_B 0x200 +#define MPQ_HASH_FILE_KEY 0x300 +#define MPQ_HASH_KEY2_MIX 0x400 + +DWORD HashString(const char * szFileName, DWORD dwHashType); +DWORD HashStringSlash(const char * szFileName, DWORD dwHashType); +DWORD HashStringLower(const char * szFileName, DWORD dwHashType); + +void InitializeMpqCryptography(); + +DWORD GetNearestPowerOfTwo(DWORD dwFileCount); + +bool IsPseudoFileName(const char * szFileName, LPDWORD pdwFileIndex); +ULONGLONG HashStringJenkins(const char * szFileName); + +DWORD GetDefaultSpecialFileFlags(DWORD dwFileSize, USHORT wFormatVersion); + +void EncryptMpqBlock(void * pvDataBlock, DWORD dwLength, DWORD dwKey); +void DecryptMpqBlock(void * pvDataBlock, DWORD dwLength, DWORD dwKey); + +DWORD DetectFileKeyBySectorSize(LPDWORD EncryptedData, DWORD dwSectorSize, DWORD dwSectorOffsLen); +DWORD DetectFileKeyByContent(void * pvEncryptedData, DWORD dwSectorSize, DWORD dwFileSize); +DWORD DecryptFileKey(const char * szFileName, ULONGLONG MpqPos, DWORD dwFileSize, DWORD dwFlags); + +bool IsValidMD5(LPBYTE pbMd5); +bool IsValidSignature(LPBYTE pbSignature); +bool VerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5); +void CalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_hash); + +//----------------------------------------------------------------------------- +// Handle validation functions + +TMPQArchive * IsValidMpqHandle(HANDLE hMpq); +TMPQFile * IsValidFileHandle(HANDLE hFile); + +//----------------------------------------------------------------------------- +// Support for MPQ file tables + +ULONGLONG FileOffsetFromMpqOffset(TMPQArchive * ha, ULONGLONG MpqOffset); +ULONGLONG CalculateRawSectorOffset(TMPQFile * hf, DWORD dwSectorOffset); + +DWORD ConvertMpqHeaderToFormat4(TMPQArchive * ha, ULONGLONG MpqOffset, ULONGLONG FileSize, DWORD dwFlags, MTYPE MapType); + +bool IsValidHashEntry(TMPQArchive * ha, TMPQHash * pHash); + +TMPQHash * FindFreeHashEntry(TMPQArchive * ha, DWORD dwStartIndex, DWORD dwName1, DWORD dwName2, LCID lcLocale); +TMPQHash * GetFirstHashEntry(TMPQArchive * ha, const char * szFileName); +TMPQHash * GetNextHashEntry(TMPQArchive * ha, TMPQHash * pFirstHash, TMPQHash * pPrevHash); +TMPQHash * AllocateHashEntry(TMPQArchive * ha, TFileEntry * pFileEntry, LCID lcLocale); + +TMPQExtHeader * LoadExtTable(TMPQArchive * ha, ULONGLONG ByteOffset, size_t Size, DWORD dwSignature, DWORD dwKey); +TMPQHetTable * LoadHetTable(TMPQArchive * ha); +TMPQBetTable * LoadBetTable(TMPQArchive * ha); + +TMPQBlock * LoadBlockTable(TMPQArchive * ha, bool bDontFixEntries = false); +TMPQBlock * TranslateBlockTable(TMPQArchive * ha, ULONGLONG * pcbTableSize, bool * pbNeedHiBlockTable); + +ULONGLONG FindFreeMpqSpace(TMPQArchive * ha); + +// Functions that load the HET and BET tables +DWORD CreateHashTable(TMPQArchive * ha, DWORD dwHashTableSize); +DWORD LoadAnyHashTable(TMPQArchive * ha); +DWORD BuildFileTable(TMPQArchive * ha); +DWORD DefragmentFileTable(TMPQArchive * ha); + +DWORD CreateFileTable(TMPQArchive * ha, DWORD dwFileTableSize); +DWORD RebuildHetTable(TMPQArchive * ha); +DWORD RebuildFileTable(TMPQArchive * ha, DWORD dwNewHashTableSize); +DWORD SaveMPQTables(TMPQArchive * ha); + +TMPQHetTable * CreateHetTable(DWORD dwEntryCount, DWORD dwTotalCount, DWORD dwHashBitSize, LPBYTE pbSrcData); +void FreeHetTable(TMPQHetTable * pHetTable); + +TMPQBetTable * CreateBetTable(DWORD dwMaxFileCount); +void FreeBetTable(TMPQBetTable * pBetTable); + +// Functions for finding files in the file table +TFileEntry * GetFileEntryLocale2(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex); +TFileEntry * GetFileEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale); +TFileEntry * GetFileEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex); + +// Allocates file name in the file entry +void AllocateFileName(TMPQArchive * ha, TFileEntry * pFileEntry, const char * szFileName); + +// Allocates new file entry in the MPQ tables. Reuses existing, if possible +TFileEntry * AllocateFileEntry(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex); +DWORD RenameFileEntry(TMPQArchive * ha, TMPQFile * hf, const char * szNewFileName); +DWORD DeleteFileEntry(TMPQArchive * ha, TMPQFile * hf); + +// Invalidates entries for (listfile) and (attributes) +void InvalidateInternalFiles(TMPQArchive * ha); + +// Retrieves information about the strong signature +bool QueryMpqSignatureInfo(TMPQArchive * ha, PMPQ_SIGNATURE_INFO pSignatureInfo); + +//----------------------------------------------------------------------------- +// Support for alternate file formats (SBaseSubTypes.cpp) + +DWORD ConvertSqpHeaderToFormat4(TMPQArchive * ha, ULONGLONG FileSize, DWORD dwFlags); +TMPQHash * LoadSqpHashTable(TMPQArchive * ha); +TMPQBlock * LoadSqpBlockTable(TMPQArchive * ha); + +DWORD ConvertMpkHeaderToFormat4(TMPQArchive * ha, ULONGLONG FileSize, DWORD dwFlags); +void DecryptMpkTable(void * pvMpkTable, size_t cbSize); +TMPQHash * LoadMpkHashTable(TMPQArchive * ha); +TMPQBlock * LoadMpkBlockTable(TMPQArchive * ha); +int SCompDecompressMpk(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); + +//----------------------------------------------------------------------------- +// Common functions - MPQ File + +TMPQFile * CreateFileHandle(TMPQArchive * ha, TFileEntry * pFileEntry); +TMPQFile * CreateWritableHandle(TMPQArchive * ha, DWORD dwFileSize); +void * LoadMpqTable(TMPQArchive * ha, ULONGLONG ByteOffset, LPBYTE pbTableHash, DWORD dwCompressedSize, DWORD dwRealSize, DWORD dwKey, bool * pbTableIsCut); +DWORD AllocateSectorBuffer(TMPQFile * hf); +DWORD AllocatePatchInfo(TMPQFile * hf, bool bLoadFromFile); +DWORD AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile); +DWORD AllocateSectorChecksums(TMPQFile * hf, bool bLoadFromFile); +DWORD WritePatchInfo(TMPQFile * hf); +DWORD WriteSectorOffsets(TMPQFile * hf); +DWORD WriteSectorChecksums(TMPQFile * hf); +DWORD WriteMemDataMD5(TFileStream * pStream, ULONGLONG RawDataOffs, void * pvRawData, DWORD dwRawDataSize, DWORD dwChunkSize, LPDWORD pcbTotalSize); +DWORD WriteMpqDataMD5(TFileStream * pStream, ULONGLONG RawDataOffs, DWORD dwRawDataSize, DWORD dwChunkSize); +void FreeFileHandle(TMPQFile *& hf); +void FreeArchiveHandle(TMPQArchive *& ha); + +//----------------------------------------------------------------------------- +// Patch functions + +// Structure used for the patching process +typedef struct _TMPQPatcher +{ + BYTE this_md5[MD5_DIGEST_SIZE]; // MD5 of the current file state + LPBYTE pbFileData1; // Primary working buffer + LPBYTE pbFileData2; // Secondary working buffer + DWORD cbMaxFileData; // Maximum allowed size of the patch data + DWORD cbFileData; // Current size of the result data + DWORD nCounter; // Counter of the patch process + +} TMPQPatcher; + +bool IsIncrementalPatchFile(const void * pvData, DWORD cbData, LPDWORD pdwPatchedFileSize); +DWORD Patch_InitPatcher(TMPQPatcher * pPatcher, TMPQFile * hf); +DWORD Patch_Process(TMPQPatcher * pPatcher, TMPQFile * hf); +void Patch_Finalize(TMPQPatcher * pPatcher); + +//----------------------------------------------------------------------------- +// Utility functions + +bool IsInternalMpqFileName(const char * szFileName); + +template +const XCHAR * GetPlainFileName(const XCHAR * szFileName) +{ + const XCHAR * szPlainName = szFileName; + + while(*szFileName != 0) + { + if(*szFileName == '\\' || *szFileName == '/') + szPlainName = szFileName + 1; + szFileName++; + } + + return szPlainName; +} + +//----------------------------------------------------------------------------- +// Internal support for MPQ modifications + +DWORD SFileAddFile_Init( + TMPQArchive * ha, + const char * szArchivedName, + ULONGLONG ft, + DWORD dwFileSize, + LCID lcLocale, + DWORD dwFlags, + TMPQFile ** phf + ); + +DWORD SFileAddFile_Init( + TMPQArchive * ha, + TMPQFile * hfSrc, + TMPQFile ** phf + ); + +DWORD SFileAddFile_Write( + TMPQFile * hf, + const void * pvData, + DWORD dwSize, + DWORD dwCompression + ); + +DWORD SFileAddFile_Finish( + TMPQFile * hf + ); + +//----------------------------------------------------------------------------- +// Attributes support + +DWORD SAttrLoadAttributes(TMPQArchive * ha); +DWORD SAttrFileSaveToMpq(TMPQArchive * ha); + +//----------------------------------------------------------------------------- +// Listfile functions + +DWORD SListFileSaveToMpq(TMPQArchive * ha); + +//----------------------------------------------------------------------------- +// Weak signature support + +DWORD SSignFileCreate(TMPQArchive * ha); +DWORD SSignFileFinish(TMPQArchive * ha); + +//----------------------------------------------------------------------------- +// Dump data support + +#ifdef __STORMLIB_DUMP_DATA__ + +void DumpMpqHeader(TMPQHeader * pHeader); +void DumpHashTable(TMPQHash * pHashTable, DWORD dwHashTableSize); +void DumpHetAndBetTable(TMPQHetTable * pHetTable, TMPQBetTable * pBetTable); +void DumpFileTable(TFileEntry * pFileTable, DWORD dwFileTableSize); + +#else + +#define DumpMpqHeader(h) /* */ +#define DumpHashTable(t, s) /* */ +#define DumpHetAndBetTable(t, s) /* */ +#define DumpFileTable(t, s) /* */ + +#endif + +#endif // __STORMCOMMON_H__ + diff --git a/StormLib/src/StormLib.exp b/StormLib/src/StormLib.exp new file mode 100644 index 000000000..bf370aafd --- /dev/null +++ b/StormLib/src/StormLib.exp @@ -0,0 +1,74 @@ +# +# Export file for Mac OS X +# Copyright (c) 2009 Sam Wilkins +# swilkins1337@gmail.com +# + +_SFileSetLocale +_SFileGetLocale + +_SFileOpenArchive +_SFileCreateArchive +_SFileFlushArchive +_SFileCloseArchive + +_SFileAddListFile + +_SFileSetCompactCallback +_SFileCompactArchive + +_SFileGetMaxFileCount +_SFileSetMaxFileCount + +_SFileGetAttributes +_SFileSetAttributes +_SFileUpdateFileAttributes + +_SFileOpenPatchArchive +_SFileIsPatchedArchive + +_SFileOpenFileEx +_SFileGetFileSize +_SFileSetFilePointer +_SFileReadFile +_SFileCloseFile + +_SFileHasFile +_SFileGetFileName +_SFileGetFileInfo + +_SFileExtractFile + +_SFileVerifyFile +_SFileVerifyRawData +_SFileVerifyArchive + +_SFileFindFirstFile +_SFileFindNextFile +_SFileFindClose + +_SListFileFindFirstFile +_SListFileFindNextFile +_SListFileFindClose + +_SFileEnumLocales + +_SFileCreateFile +_SFileWriteFile +_SFileFinishFile +_SFileAddFileEx +_SFileAddFile +_SFileAddWave +_SFileRemoveFile +_SFileRenameFile +_SFileSetFileLocale +_SFileSetDataCompression +_SFileSetAddFileCallback + +_SCompImplode +_SCompExplode +_SCompCompress +_SCompDecompress + +_SetLastError +_GetLastError diff --git a/libultraship/libultraship/Lib/StormLib/StormLib.h b/StormLib/src/StormLib.h similarity index 99% rename from libultraship/libultraship/Lib/StormLib/StormLib.h rename to StormLib/src/StormLib.h index bde8d5e8b..4652ecad4 100644 --- a/libultraship/libultraship/Lib/StormLib/StormLib.h +++ b/StormLib/src/StormLib.h @@ -117,11 +117,7 @@ extern "C" { #ifdef _DLL #pragma comment(lib, "StormLibDUD.lib") // Debug Unicode CRT-DLL version #else -#ifndef _WIN64 - #pragma comment(lib, "StormLibDUS32.lib") // Debug Unicode CRT-LIB version -#else - #pragma comment(lib, "StormLibDUS64.lib") // Debug Unicode CRT-LIB version -#endif + #pragma comment(lib, "StormLibDUS.lib") // Debug Unicode CRT-LIB version #endif #endif #else // RELEASE VERSIONS @@ -135,11 +131,7 @@ extern "C" { #ifdef _DLL #pragma comment(lib, "StormLibRUD.lib") // Release Unicode CRT-DLL version #else -#ifndef _WIN64 - #pragma comment(lib, "StormLibRUS32.lib") // Release Unicode CRT-LIB version -#else - #pragma comment(lib, "StormLibRUS64.lib") // Release Unicode CRT-LIB version -#endif + #pragma comment(lib, "StormLibRUS.lib") // Release Unicode CRT-LIB version #endif #endif #endif @@ -857,6 +849,10 @@ typedef struct _TMPQArchive ULONGLONG CompactBytesProcessed; // Amount of bytes that have been processed during a particular compact call ULONGLONG CompactTotalBytes; // Total amount of bytes to be compacted void * pvCompactUserData; // User data thats passed to the callback + + // OTR + TFileEntry* lastFreeSpaceEntry; + bool useFreeSpaceOptimization; } TMPQArchive; // File handle structure diff --git a/libultraship/libultraship/Lib/StormLib/StormPort.h b/StormLib/src/StormPort.h similarity index 100% rename from libultraship/libultraship/Lib/StormLib/StormPort.h rename to StormLib/src/StormPort.h diff --git a/StormLib/src/adpcm/adpcm.cpp b/StormLib/src/adpcm/adpcm.cpp new file mode 100644 index 000000000..fb0efbfd7 --- /dev/null +++ b/StormLib/src/adpcm/adpcm.cpp @@ -0,0 +1,401 @@ +/*****************************************************************************/ +/* adpcm.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* This module contains implementation of adpcm decompression method used by */ +/* Storm.dll to decompress WAVE files. Thanks to Tom Amigo for releasing */ +/* his sources. */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 11.03.03 1.00 Lad Splitted from Pkware.cpp */ +/* 20.05.03 2.00 Lad Added compression */ +/* 19.11.03 2.01 Dan Big endian handling */ +/* 10.01.13 3.00 Lad Refactored, beautified, documented :-) */ +/*****************************************************************************/ + +#include + +#include "adpcm.h" + +//----------------------------------------------------------------------------- +// Tables necessary dor decompression + +static int NextStepTable[] = +{ + -1, 0, -1, 4, -1, 2, -1, 6, + -1, 1, -1, 5, -1, 3, -1, 7, + -1, 1, -1, 5, -1, 3, -1, 7, + -1, 2, -1, 4, -1, 6, -1, 8 +}; + +static int StepSizeTable[] = +{ + 7, 8, 9, 10, 11, 12, 13, 14, + 16, 17, 19, 21, 23, 25, 28, 31, + 34, 37, 41, 45, 50, 55, 60, 66, + 73, 80, 88, 97, 107, 118, 130, 143, + 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, + 724, 796, 876, 963, 1060, 1166, 1282, 1411, + 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, + 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, + 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, + 32767 +}; + +//----------------------------------------------------------------------------- +// Helper class for writing output ADPCM data + +class TADPCMStream +{ + public: + + TADPCMStream(void * pvBuffer, size_t cbBuffer) + { + pbBufferEnd = (unsigned char *)pvBuffer + cbBuffer; + pbBuffer = (unsigned char *)pvBuffer; + } + + bool ReadByteSample(unsigned char & ByteSample) + { + // Check if there is enough space in the buffer + if(pbBuffer >= pbBufferEnd) + return false; + + ByteSample = *pbBuffer++; + return true; + } + + bool WriteByteSample(unsigned char ByteSample) + { + // Check if there is enough space in the buffer + if(pbBuffer >= pbBufferEnd) + return false; + + *pbBuffer++ = ByteSample; + return true; + } + + bool ReadWordSample(short & OneSample) + { + // Check if we have enough space in the output buffer + if((size_t)(pbBufferEnd - pbBuffer) < sizeof(short)) + return false; + + // Write the sample + OneSample = pbBuffer[0] + (((short)pbBuffer[1]) << 0x08); + pbBuffer += sizeof(short); + return true; + } + + bool WriteWordSample(short OneSample) + { + // Check if we have enough space in the output buffer + if((size_t)(pbBufferEnd - pbBuffer) < sizeof(short)) + return false; + + // Write the sample + *pbBuffer++ = (unsigned char)(OneSample & 0xFF); + *pbBuffer++ = (unsigned char)(OneSample >> 0x08); + return true; + } + + int LengthProcessed(void * pvOutBuffer) + { + return (int)((unsigned char *)pbBuffer - (unsigned char *)pvOutBuffer); + } + + unsigned char * pbBufferEnd; + unsigned char * pbBuffer; +}; + +//---------------------------------------------------------------------------- +// Local functions + +static inline short GetNextStepIndex(int StepIndex, unsigned int EncodedSample) +{ + // Get the next step index + StepIndex = StepIndex + NextStepTable[EncodedSample & 0x1F]; + + // Don't make the step index overflow + if(StepIndex < 0) + StepIndex = 0; + else if(StepIndex > 88) + StepIndex = 88; + + return (short)StepIndex; +} + +static inline int UpdatePredictedSample(int PredictedSample, int EncodedSample, int Difference) +{ + // Is the sign bit set? + if(EncodedSample & 0x40) + { + PredictedSample -= Difference; + if(PredictedSample <= -32768) + PredictedSample = -32768; + } + else + { + PredictedSample += Difference; + if(PredictedSample >= 32767) + PredictedSample = 32767; + } + + return PredictedSample; +} + +static inline int DecodeSample(int PredictedSample, int EncodedSample, int StepSize, int Difference) +{ + if(EncodedSample & 0x01) + Difference += (StepSize >> 0); + + if(EncodedSample & 0x02) + Difference += (StepSize >> 1); + + if(EncodedSample & 0x04) + Difference += (StepSize >> 2); + + if(EncodedSample & 0x08) + Difference += (StepSize >> 3); + + if(EncodedSample & 0x10) + Difference += (StepSize >> 4); + + if(EncodedSample & 0x20) + Difference += (StepSize >> 5); + + return UpdatePredictedSample(PredictedSample, EncodedSample, Difference); +} + +//---------------------------------------------------------------------------- +// Compression routine + +int CompressADPCM(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int cbInBuffer, int ChannelCount, int CompressionLevel) +{ + TADPCMStream os(pvOutBuffer, cbOutBuffer); // The output stream + TADPCMStream is(pvInBuffer, cbInBuffer); // The input stream + unsigned char BitShift = (unsigned char)(CompressionLevel - 1); + short PredictedSamples[MAX_ADPCM_CHANNEL_COUNT];// Predicted samples for each channel + short StepIndexes[MAX_ADPCM_CHANNEL_COUNT]; // Step indexes for each channel + short InputSample; // Input sample for the current channel + int TotalStepSize; + int ChannelIndex; + int AbsDifference; + int Difference; + int MaxBitMask; + int StepSize; + +// _tprintf(_T("== CMPR Started ==============\n")); + + // First byte in the output stream contains zero. The second one contains the compression level + os.WriteByteSample(0); + if(!os.WriteByteSample(BitShift)) + return 2; + + // Set the initial step index for each channel + PredictedSamples[0] = PredictedSamples[1] = 0; + StepIndexes[0] = StepIndexes[1] = INITIAL_ADPCM_STEP_INDEX; + + // Next, InitialSample value for each channel follows + for(int i = 0; i < ChannelCount; i++) + { + // Get the initial sample from the input stream + if(!is.ReadWordSample(InputSample)) + return os.LengthProcessed(pvOutBuffer); + + // Store the initial sample to our sample array + PredictedSamples[i] = InputSample; + + // Also store the loaded sample to the output stream + if(!os.WriteWordSample(InputSample)) + return os.LengthProcessed(pvOutBuffer); + } + + // Get the initial index + ChannelIndex = ChannelCount - 1; + + // Now keep reading the input data as long as there is something in the input buffer + while(is.ReadWordSample(InputSample)) + { + int EncodedSample = 0; + + // If we have two channels, we need to flip the channel index + ChannelIndex = (ChannelIndex + 1) % ChannelCount; + + // Get the difference from the previous sample. + // If the difference is negative, set the sign bit to the encoded sample + AbsDifference = InputSample - PredictedSamples[ChannelIndex]; + if(AbsDifference < 0) + { + AbsDifference = -AbsDifference; + EncodedSample |= 0x40; + } + + // If the difference is too low (higher that difference treshold), + // write a step index modifier marker + StepSize = StepSizeTable[StepIndexes[ChannelIndex]]; + if(AbsDifference < (StepSize >> CompressionLevel)) + { + if(StepIndexes[ChannelIndex] != 0) + StepIndexes[ChannelIndex]--; + + os.WriteByteSample(0x80); + } + else + { + // If the difference is too high, write marker that + // indicates increase in step size + while(AbsDifference > (StepSize << 1)) + { + if(StepIndexes[ChannelIndex] >= 0x58) + break; + + // Modify the step index + StepIndexes[ChannelIndex] += 8; + if(StepIndexes[ChannelIndex] > 0x58) + StepIndexes[ChannelIndex] = 0x58; + + // Write the "modify step index" marker + StepSize = StepSizeTable[StepIndexes[ChannelIndex]]; + os.WriteByteSample(0x81); + } + + // Get the limit bit value + MaxBitMask = (1 << (BitShift - 1)); + MaxBitMask = (MaxBitMask > 0x20) ? 0x20 : MaxBitMask; + Difference = StepSize >> BitShift; + TotalStepSize = 0; + + for(int BitVal = 0x01; BitVal <= MaxBitMask; BitVal <<= 1) + { + if((TotalStepSize + StepSize) <= AbsDifference) + { + TotalStepSize += StepSize; + EncodedSample |= BitVal; + } + StepSize >>= 1; + } + + PredictedSamples[ChannelIndex] = (short)UpdatePredictedSample(PredictedSamples[ChannelIndex], + EncodedSample, + Difference + TotalStepSize); + // Write the encoded sample to the output stream + if(!os.WriteByteSample((unsigned char)EncodedSample)) + break; + + // Calculates the step index to use for the next encode + StepIndexes[ChannelIndex] = GetNextStepIndex(StepIndexes[ChannelIndex], EncodedSample); + } + } + +// _tprintf(_T("== CMPR Ended ================\n")); + return os.LengthProcessed(pvOutBuffer); +} + +//---------------------------------------------------------------------------- +// Decompression routine + +int DecompressADPCM(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int cbInBuffer, int ChannelCount) +{ + TADPCMStream os(pvOutBuffer, cbOutBuffer); // Output stream + TADPCMStream is(pvInBuffer, cbInBuffer); // Input stream + unsigned char EncodedSample; + unsigned char BitShift; + short PredictedSamples[MAX_ADPCM_CHANNEL_COUNT]; // Predicted sample for each channel + short StepIndexes[MAX_ADPCM_CHANNEL_COUNT]; // Predicted step index for each channel + int ChannelIndex; // Current channel index + + // Initialize the StepIndex for each channel + PredictedSamples[0] = PredictedSamples[1] = 0; + StepIndexes[0] = StepIndexes[1] = INITIAL_ADPCM_STEP_INDEX; + +// _tprintf(_T("== DCMP Started ==============\n")); + + // The first byte is always zero, the second one contains bit shift (compression level - 1) + is.ReadByteSample(BitShift); + is.ReadByteSample(BitShift); +// _tprintf(_T("DCMP: BitShift = %u\n"), (unsigned int)(unsigned char)BitShift); + + // Next, InitialSample value for each channel follows + for(int i = 0; i < ChannelCount; i++) + { + // Get the initial sample from the input stream + short InitialSample; + + // Attempt to read the initial sample + if(!is.ReadWordSample(InitialSample)) + return os.LengthProcessed(pvOutBuffer); + +// _tprintf(_T("DCMP: Loaded InitialSample[%u]: %04X\n"), i, (unsigned int)(unsigned short)InitialSample); + + // Store the initial sample to our sample array + PredictedSamples[i] = InitialSample; + + // Also store the loaded sample to the output stream + if(!os.WriteWordSample(InitialSample)) + return os.LengthProcessed(pvOutBuffer); + } + + // Get the initial index + ChannelIndex = ChannelCount - 1; + + // Keep reading as long as there is something in the input buffer + while(is.ReadByteSample(EncodedSample)) + { +// _tprintf(_T("DCMP: Loaded Encoded Sample: %02X\n"), (unsigned int)(unsigned char)EncodedSample); + + // If we have two channels, we need to flip the channel index + ChannelIndex = (ChannelIndex + 1) % ChannelCount; + + if(EncodedSample == 0x80) + { + if(StepIndexes[ChannelIndex] != 0) + StepIndexes[ChannelIndex]--; + +// _tprintf(_T("DCMP: Writing Decoded Sample: %04lX\n"), (unsigned int)(unsigned short)PredictedSamples[ChannelIndex]); + if(!os.WriteWordSample(PredictedSamples[ChannelIndex])) + return os.LengthProcessed(pvOutBuffer); + } + else if(EncodedSample == 0x81) + { + // Modify the step index + StepIndexes[ChannelIndex] += 8; + if(StepIndexes[ChannelIndex] > 0x58) + StepIndexes[ChannelIndex] = 0x58; + +// _tprintf(_T("DCMP: New value of StepIndex: %04lX\n"), (unsigned int)(unsigned short)StepIndexes[ChannelIndex]); + + // Next pass, keep going on the same channel + ChannelIndex = (ChannelIndex + 1) % ChannelCount; + } + else + { + int StepIndex = StepIndexes[ChannelIndex]; + int StepSize = StepSizeTable[StepIndex]; + + // Encode one sample + PredictedSamples[ChannelIndex] = (short)DecodeSample(PredictedSamples[ChannelIndex], + EncodedSample, + StepSize, + StepSize >> BitShift); + +// _tprintf(_T("DCMP: Writing decoded sample: %04X\n"), (unsigned int)(unsigned short)PredictedSamples[ChannelIndex]); + + // Write the decoded sample to the output stream + if(!os.WriteWordSample(PredictedSamples[ChannelIndex])) + break; + + // Calculates the step index to use for the next encode + StepIndexes[ChannelIndex] = GetNextStepIndex(StepIndex, EncodedSample); +// _tprintf(_T("DCMP: New step index: %04X\n"), (unsigned int)(unsigned short)StepIndexes[ChannelIndex]); + } + } + +// _tprintf(_T("DCMP: Total length written: %u\n"), (unsigned int)os.LengthProcessed(pvOutBuffer)); +// _tprintf(_T("== DCMP Ended ================\n")); + + // Return total bytes written since beginning of the output buffer + return os.LengthProcessed(pvOutBuffer); +} diff --git a/StormLib/src/adpcm/adpcm.h b/StormLib/src/adpcm/adpcm.h new file mode 100644 index 000000000..b1bf36143 --- /dev/null +++ b/StormLib/src/adpcm/adpcm.h @@ -0,0 +1,26 @@ +/*****************************************************************************/ +/* adpcm.h Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Header file for adpcm decompress functions */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 31.03.03 1.00 Lad The first version of adpcm.h */ +/*****************************************************************************/ + +#ifndef __ADPCM_H__ +#define __ADPCM_H__ + +//----------------------------------------------------------------------------- +// Defines + +#define MAX_ADPCM_CHANNEL_COUNT 2 +#define INITIAL_ADPCM_STEP_INDEX 0x2C + +//----------------------------------------------------------------------------- +// Public functions + +int CompressADPCM (void * pvOutBuffer, int dwOutLength, void * pvInBuffer, int dwInLength, int nCmpType, int ChannelCount); +int DecompressADPCM(void * pvOutBuffer, int dwOutLength, void * pvInBuffer, int dwInLength, int ChannelCount); + +#endif // __ADPCM_H__ diff --git a/StormLib/src/bzip2/blocksort.c b/StormLib/src/bzip2/blocksort.c new file mode 100644 index 000000000..bd2dec157 --- /dev/null +++ b/StormLib/src/bzip2/blocksort.c @@ -0,0 +1,1094 @@ + +/*-------------------------------------------------------------*/ +/*--- Block sorting machinery ---*/ +/*--- blocksort.c ---*/ +/*-------------------------------------------------------------*/ + +/* ------------------------------------------------------------------ + This file is part of bzip2/libbzip2, a program and library for + lossless, block-sorting data compression. + + bzip2/libbzip2 version 1.0.5 of 10 December 2007 + Copyright (C) 1996-2007 Julian Seward + + Please read the WARNING, DISCLAIMER and PATENTS sections in the + README file. + + This program is released under the terms of the license contained + in the file LICENSE. + ------------------------------------------------------------------ */ + + +#include "bzlib_private.h" + +/*---------------------------------------------*/ +/*--- Fallback O(N log(N)^2) sorting ---*/ +/*--- algorithm, for repetitive blocks ---*/ +/*---------------------------------------------*/ + +/*---------------------------------------------*/ +static +__inline__ +void fallbackSimpleSort ( UInt32* fmap, + UInt32* eclass, + Int32 lo, + Int32 hi ) +{ + Int32 i, j, tmp; + UInt32 ec_tmp; + + if (lo == hi) return; + + if (hi - lo > 3) { + for ( i = hi-4; i >= lo; i-- ) { + tmp = fmap[i]; + ec_tmp = eclass[tmp]; + for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 ) + fmap[j-4] = fmap[j]; + fmap[j-4] = tmp; + } + } + + for ( i = hi-1; i >= lo; i-- ) { + tmp = fmap[i]; + ec_tmp = eclass[tmp]; + for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ ) + fmap[j-1] = fmap[j]; + fmap[j-1] = tmp; + } +} + + +/*---------------------------------------------*/ +#define fswap(zz1, zz2) \ + { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; } + +#define fvswap(zzp1, zzp2, zzn) \ +{ \ + Int32 yyp1 = (zzp1); \ + Int32 yyp2 = (zzp2); \ + Int32 yyn = (zzn); \ + while (yyn > 0) { \ + fswap(fmap[yyp1], fmap[yyp2]); \ + yyp1++; yyp2++; yyn--; \ + } \ +} + + +#define fmin(a,b) ((a) < (b)) ? (a) : (b) + +#define fpush(lz,hz) { stackLo[sp] = lz; \ + stackHi[sp] = hz; \ + sp++; } + +#define fpop(lz,hz) { sp--; \ + lz = stackLo[sp]; \ + hz = stackHi[sp]; } + +#define FALLBACK_QSORT_SMALL_THRESH 10 +#define FALLBACK_QSORT_STACK_SIZE 100 + + +static +void fallbackQSort3 ( UInt32* fmap, + UInt32* eclass, + Int32 loSt, + Int32 hiSt ) +{ + Int32 unLo, unHi, ltLo, gtHi, n, m; + Int32 sp, lo, hi; + UInt32 med, r, r3; + Int32 stackLo[FALLBACK_QSORT_STACK_SIZE]; + Int32 stackHi[FALLBACK_QSORT_STACK_SIZE]; + + r = 0; + + sp = 0; + fpush ( loSt, hiSt ); + + while (sp > 0) { + + AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 ); + + fpop ( lo, hi ); + if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) { + fallbackSimpleSort ( fmap, eclass, lo, hi ); + continue; + } + + /* Random partitioning. Median of 3 sometimes fails to + avoid bad cases. Median of 9 seems to help but + looks rather expensive. This too seems to work but + is cheaper. Guidance for the magic constants + 7621 and 32768 is taken from Sedgewick's algorithms + book, chapter 35. + */ + r = ((r * 7621) + 1) % 32768; + r3 = r % 3; + if (r3 == 0) med = eclass[fmap[lo]]; else + if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else + med = eclass[fmap[hi]]; + + unLo = ltLo = lo; + unHi = gtHi = hi; + + while (1) { + while (1) { + if (unLo > unHi) break; + n = (Int32)eclass[fmap[unLo]] - (Int32)med; + if (n == 0) { + fswap(fmap[unLo], fmap[ltLo]); + ltLo++; unLo++; + continue; + }; + if (n > 0) break; + unLo++; + } + while (1) { + if (unLo > unHi) break; + n = (Int32)eclass[fmap[unHi]] - (Int32)med; + if (n == 0) { + fswap(fmap[unHi], fmap[gtHi]); + gtHi--; unHi--; + continue; + }; + if (n < 0) break; + unHi--; + } + if (unLo > unHi) break; + fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--; + } + + AssertD ( unHi == unLo-1, "fallbackQSort3(2)" ); + + if (gtHi < ltLo) continue; + + n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n); + m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m); + + n = lo + unLo - ltLo - 1; + m = hi - (gtHi - unHi) + 1; + + if (n - lo > hi - m) { + fpush ( lo, n ); + fpush ( m, hi ); + } else { + fpush ( m, hi ); + fpush ( lo, n ); + } + } +} + +#undef fmin +#undef fpush +#undef fpop +#undef fswap +#undef fvswap +#undef FALLBACK_QSORT_SMALL_THRESH +#undef FALLBACK_QSORT_STACK_SIZE + + +/*---------------------------------------------*/ +/* Pre: + nblock > 0 + eclass exists for [0 .. nblock-1] + ((UChar*)eclass) [0 .. nblock-1] holds block + ptr exists for [0 .. nblock-1] + + Post: + ((UChar*)eclass) [0 .. nblock-1] holds block + All other areas of eclass destroyed + fmap [0 .. nblock-1] holds sorted order + bhtab [ 0 .. 2+(nblock/32) ] destroyed +*/ + +#define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31)) +#define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31)) +#define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31))) +#define WORD_BH(zz) bhtab[(zz) >> 5] +#define UNALIGNED_BH(zz) ((zz) & 0x01f) + +static +void fallbackSort ( UInt32* fmap, + UInt32* eclass, + UInt32* bhtab, + Int32 nblock, + Int32 verb ) +{ + Int32 ftab[257]; + Int32 ftabCopy[256]; + Int32 H, i, j, k, l, r, cc, cc1; + Int32 nNotDone; + Int32 nBhtab; + UChar* eclass8 = (UChar*)eclass; + + /*-- + Initial 1-char radix sort to generate + initial fmap and initial BH bits. + --*/ + if (verb >= 4) + VPrintf0 ( " bucket sorting ...\n" ); + for (i = 0; i < 257; i++) ftab[i] = 0; + for (i = 0; i < nblock; i++) ftab[eclass8[i]]++; + for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i]; + for (i = 1; i < 257; i++) ftab[i] += ftab[i-1]; + + for (i = 0; i < nblock; i++) { + j = eclass8[i]; + k = ftab[j] - 1; + ftab[j] = k; + fmap[k] = i; + } + + nBhtab = 2 + (nblock / 32); + for (i = 0; i < nBhtab; i++) bhtab[i] = 0; + for (i = 0; i < 256; i++) SET_BH(ftab[i]); + + /*-- + Inductively refine the buckets. Kind-of an + "exponential radix sort" (!), inspired by the + Manber-Myers suffix array construction algorithm. + --*/ + + /*-- set sentinel bits for block-end detection --*/ + for (i = 0; i < 32; i++) { + SET_BH(nblock + 2*i); + CLEAR_BH(nblock + 2*i + 1); + } + + /*-- the log(N) loop --*/ + H = 1; + while (1) { + + if (verb >= 4) + VPrintf1 ( " depth %6d has ", H ); + + j = 0; + for (i = 0; i < nblock; i++) { + if (ISSET_BH(i)) j = i; + k = fmap[i] - H; if (k < 0) k += nblock; + eclass[k] = j; + } + + nNotDone = 0; + r = -1; + while (1) { + + /*-- find the next non-singleton bucket --*/ + k = r + 1; + while (ISSET_BH(k) && UNALIGNED_BH(k)) k++; + if (ISSET_BH(k)) { + while (WORD_BH(k) == 0xffffffff) k += 32; + while (ISSET_BH(k)) k++; + } + l = k - 1; + if (l >= nblock) break; + while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++; + if (!ISSET_BH(k)) { + while (WORD_BH(k) == 0x00000000) k += 32; + while (!ISSET_BH(k)) k++; + } + r = k - 1; + if (r >= nblock) break; + + /*-- now [l, r] bracket current bucket --*/ + if (r > l) { + nNotDone += (r - l + 1); + fallbackQSort3 ( fmap, eclass, l, r ); + + /*-- scan bucket and generate header bits-- */ + cc = -1; + for (i = l; i <= r; i++) { + cc1 = eclass[fmap[i]]; + if (cc != cc1) { SET_BH(i); cc = cc1; }; + } + } + } + + if (verb >= 4) + VPrintf1 ( "%6d unresolved strings\n", nNotDone ); + + H *= 2; + if (H > nblock || nNotDone == 0) break; + } + + /*-- + Reconstruct the original block in + eclass8 [0 .. nblock-1], since the + previous phase destroyed it. + --*/ + if (verb >= 4) + VPrintf0 ( " reconstructing block ...\n" ); + j = 0; + for (i = 0; i < nblock; i++) { + while (ftabCopy[j] == 0) j++; + ftabCopy[j]--; + eclass8[fmap[i]] = (UChar)j; + } + AssertH ( j < 256, 1005 ); +} + +#undef SET_BH +#undef CLEAR_BH +#undef ISSET_BH +#undef WORD_BH +#undef UNALIGNED_BH + + +/*---------------------------------------------*/ +/*--- The main, O(N^2 log(N)) sorting ---*/ +/*--- algorithm. Faster for "normal" ---*/ +/*--- non-repetitive blocks. ---*/ +/*---------------------------------------------*/ + +/*---------------------------------------------*/ +static +__inline__ +Bool mainGtU ( UInt32 i1, + UInt32 i2, + UChar* block, + UInt16* quadrant, + UInt32 nblock, + Int32* budget ) +{ + Int32 k; + UChar c1, c2; + UInt16 s1, s2; + + AssertD ( i1 != i2, "mainGtU" ); + /* 1 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + i1++; i2++; + /* 2 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + i1++; i2++; + /* 3 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + i1++; i2++; + /* 4 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + i1++; i2++; + /* 5 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + i1++; i2++; + /* 6 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + i1++; i2++; + /* 7 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + i1++; i2++; + /* 8 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + i1++; i2++; + /* 9 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + i1++; i2++; + /* 10 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + i1++; i2++; + /* 11 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + i1++; i2++; + /* 12 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + i1++; i2++; + + k = nblock + 8; + + do { + /* 1 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + s1 = quadrant[i1]; s2 = quadrant[i2]; + if (s1 != s2) return (s1 > s2); + i1++; i2++; + /* 2 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + s1 = quadrant[i1]; s2 = quadrant[i2]; + if (s1 != s2) return (s1 > s2); + i1++; i2++; + /* 3 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + s1 = quadrant[i1]; s2 = quadrant[i2]; + if (s1 != s2) return (s1 > s2); + i1++; i2++; + /* 4 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + s1 = quadrant[i1]; s2 = quadrant[i2]; + if (s1 != s2) return (s1 > s2); + i1++; i2++; + /* 5 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + s1 = quadrant[i1]; s2 = quadrant[i2]; + if (s1 != s2) return (s1 > s2); + i1++; i2++; + /* 6 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + s1 = quadrant[i1]; s2 = quadrant[i2]; + if (s1 != s2) return (s1 > s2); + i1++; i2++; + /* 7 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + s1 = quadrant[i1]; s2 = quadrant[i2]; + if (s1 != s2) return (s1 > s2); + i1++; i2++; + /* 8 */ + c1 = block[i1]; c2 = block[i2]; + if (c1 != c2) return (c1 > c2); + s1 = quadrant[i1]; s2 = quadrant[i2]; + if (s1 != s2) return (s1 > s2); + i1++; i2++; + + if (i1 >= nblock) i1 -= nblock; + if (i2 >= nblock) i2 -= nblock; + + k -= 8; + (*budget)--; + } + while (k >= 0); + + return False; +} + + +/*---------------------------------------------*/ +/*-- + Knuth's increments seem to work better + than Incerpi-Sedgewick here. Possibly + because the number of elems to sort is + usually small, typically <= 20. +--*/ +static +Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280, + 9841, 29524, 88573, 265720, + 797161, 2391484 }; + +static +void mainSimpleSort ( UInt32* ptr, + UChar* block, + UInt16* quadrant, + Int32 nblock, + Int32 lo, + Int32 hi, + Int32 d, + Int32* budget ) +{ + Int32 i, j, h, bigN, hp; + UInt32 v; + + bigN = hi - lo + 1; + if (bigN < 2) return; + + hp = 0; + while (incs[hp] < bigN) hp++; + hp--; + + for (; hp >= 0; hp--) { + h = incs[hp]; + + i = lo + h; + while (True) { + + /*-- copy 1 --*/ + if (i > hi) break; + v = ptr[i]; + j = i; + while ( mainGtU ( + ptr[j-h]+d, v+d, block, quadrant, nblock, budget + ) ) { + ptr[j] = ptr[j-h]; + j = j - h; + if (j <= (lo + h - 1)) break; + } + ptr[j] = v; + i++; + + /*-- copy 2 --*/ + if (i > hi) break; + v = ptr[i]; + j = i; + while ( mainGtU ( + ptr[j-h]+d, v+d, block, quadrant, nblock, budget + ) ) { + ptr[j] = ptr[j-h]; + j = j - h; + if (j <= (lo + h - 1)) break; + } + ptr[j] = v; + i++; + + /*-- copy 3 --*/ + if (i > hi) break; + v = ptr[i]; + j = i; + while ( mainGtU ( + ptr[j-h]+d, v+d, block, quadrant, nblock, budget + ) ) { + ptr[j] = ptr[j-h]; + j = j - h; + if (j <= (lo + h - 1)) break; + } + ptr[j] = v; + i++; + + if (*budget < 0) return; + } + } +} + + +/*---------------------------------------------*/ +/*-- + The following is an implementation of + an elegant 3-way quicksort for strings, + described in a paper "Fast Algorithms for + Sorting and Searching Strings", by Robert + Sedgewick and Jon L. Bentley. +--*/ + +#define mswap(zz1, zz2) \ + { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; } + +#define mvswap(zzp1, zzp2, zzn) \ +{ \ + Int32 yyp1 = (zzp1); \ + Int32 yyp2 = (zzp2); \ + Int32 yyn = (zzn); \ + while (yyn > 0) { \ + mswap(ptr[yyp1], ptr[yyp2]); \ + yyp1++; yyp2++; yyn--; \ + } \ +} + +static +__inline__ +UChar mmed3 ( UChar a, UChar b, UChar c ) +{ + UChar t; + if (a > b) { t = a; a = b; b = t; }; + if (b > c) { + b = c; + if (a > b) b = a; + } + return b; +} + +#define mmin(a,b) ((a) < (b)) ? (a) : (b) + +#define mpush(lz,hz,dz) { stackLo[sp] = lz; \ + stackHi[sp] = hz; \ + stackD [sp] = dz; \ + sp++; } + +#define mpop(lz,hz,dz) { sp--; \ + lz = stackLo[sp]; \ + hz = stackHi[sp]; \ + dz = stackD [sp]; } + + +#define mnextsize(az) (nextHi[az]-nextLo[az]) + +#define mnextswap(az,bz) \ + { Int32 tz; \ + tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \ + tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \ + tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; } + + +#define MAIN_QSORT_SMALL_THRESH 20 +#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT) +#define MAIN_QSORT_STACK_SIZE 100 + +static +void mainQSort3 ( UInt32* ptr, + UChar* block, + UInt16* quadrant, + Int32 nblock, + Int32 loSt, + Int32 hiSt, + Int32 dSt, + Int32* budget ) +{ + Int32 unLo, unHi, ltLo, gtHi, n, m, med; + Int32 sp, lo, hi, d; + + Int32 stackLo[MAIN_QSORT_STACK_SIZE]; + Int32 stackHi[MAIN_QSORT_STACK_SIZE]; + Int32 stackD [MAIN_QSORT_STACK_SIZE]; + + Int32 nextLo[3]; + Int32 nextHi[3]; + Int32 nextD [3]; + + sp = 0; + mpush ( loSt, hiSt, dSt ); + + while (sp > 0) { + + AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 ); + + mpop ( lo, hi, d ); + if (hi - lo < MAIN_QSORT_SMALL_THRESH || + d > MAIN_QSORT_DEPTH_THRESH) { + mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget ); + if (*budget < 0) return; + continue; + } + + med = (Int32) + mmed3 ( block[ptr[ lo ]+d], + block[ptr[ hi ]+d], + block[ptr[ (lo+hi)>>1 ]+d] ); + + unLo = ltLo = lo; + unHi = gtHi = hi; + + while (True) { + while (True) { + if (unLo > unHi) break; + n = ((Int32)block[ptr[unLo]+d]) - med; + if (n == 0) { + mswap(ptr[unLo], ptr[ltLo]); + ltLo++; unLo++; continue; + }; + if (n > 0) break; + unLo++; + } + while (True) { + if (unLo > unHi) break; + n = ((Int32)block[ptr[unHi]+d]) - med; + if (n == 0) { + mswap(ptr[unHi], ptr[gtHi]); + gtHi--; unHi--; continue; + }; + if (n < 0) break; + unHi--; + } + if (unLo > unHi) break; + mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--; + } + + AssertD ( unHi == unLo-1, "mainQSort3(2)" ); + + if (gtHi < ltLo) { + mpush(lo, hi, d+1 ); + continue; + } + + n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n); + m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m); + + n = lo + unLo - ltLo - 1; + m = hi - (gtHi - unHi) + 1; + + nextLo[0] = lo; nextHi[0] = n; nextD[0] = d; + nextLo[1] = m; nextHi[1] = hi; nextD[1] = d; + nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1; + + if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); + if (mnextsize(1) < mnextsize(2)) mnextswap(1,2); + if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); + + AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" ); + AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" ); + + mpush (nextLo[0], nextHi[0], nextD[0]); + mpush (nextLo[1], nextHi[1], nextD[1]); + mpush (nextLo[2], nextHi[2], nextD[2]); + } +} + +#undef mswap +#undef mvswap +#undef mpush +#undef mpop +#undef mmin +#undef mnextsize +#undef mnextswap +#undef MAIN_QSORT_SMALL_THRESH +#undef MAIN_QSORT_DEPTH_THRESH +#undef MAIN_QSORT_STACK_SIZE + + +/*---------------------------------------------*/ +/* Pre: + nblock > N_OVERSHOOT + block32 exists for [0 .. nblock-1 +N_OVERSHOOT] + ((UChar*)block32) [0 .. nblock-1] holds block + ptr exists for [0 .. nblock-1] + + Post: + ((UChar*)block32) [0 .. nblock-1] holds block + All other areas of block32 destroyed + ftab [0 .. 65536 ] destroyed + ptr [0 .. nblock-1] holds sorted order + if (*budget < 0), sorting was abandoned +*/ + +#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8]) +#define SETMASK (1 << 21) +#define CLEARMASK (~(SETMASK)) + +static +void mainSort ( UInt32* ptr, + UChar* block, + UInt16* quadrant, + UInt32* ftab, + Int32 nblock, + Int32 verb, + Int32* budget ) +{ + Int32 i, j, k, ss, sb; + Int32 runningOrder[256]; + Bool bigDone[256]; + Int32 copyStart[256]; + Int32 copyEnd [256]; + UChar c1; + Int32 numQSorted; + UInt16 s; + if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" ); + + /*-- set up the 2-byte frequency table --*/ + for (i = 65536; i >= 0; i--) ftab[i] = 0; + + j = block[0] << 8; + i = nblock-1; + for (; i >= 3; i -= 4) { + quadrant[i] = 0; + j = (j >> 8) | ( ((UInt16)block[i]) << 8); + ftab[j]++; + quadrant[i-1] = 0; + j = (j >> 8) | ( ((UInt16)block[i-1]) << 8); + ftab[j]++; + quadrant[i-2] = 0; + j = (j >> 8) | ( ((UInt16)block[i-2]) << 8); + ftab[j]++; + quadrant[i-3] = 0; + j = (j >> 8) | ( ((UInt16)block[i-3]) << 8); + ftab[j]++; + } + for (; i >= 0; i--) { + quadrant[i] = 0; + j = (j >> 8) | ( ((UInt16)block[i]) << 8); + ftab[j]++; + } + + /*-- (emphasises close relationship of block & quadrant) --*/ + for (i = 0; i < BZ_N_OVERSHOOT; i++) { + block [nblock+i] = block[i]; + quadrant[nblock+i] = 0; + } + + if (verb >= 4) VPrintf0 ( " bucket sorting ...\n" ); + + /*-- Complete the initial radix sort --*/ + for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1]; + + s = block[0] << 8; + i = nblock-1; + for (; i >= 3; i -= 4) { + s = (s >> 8) | (block[i] << 8); + j = ftab[s] -1; + ftab[s] = j; + ptr[j] = i; + s = (s >> 8) | (block[i-1] << 8); + j = ftab[s] -1; + ftab[s] = j; + ptr[j] = i-1; + s = (s >> 8) | (block[i-2] << 8); + j = ftab[s] -1; + ftab[s] = j; + ptr[j] = i-2; + s = (s >> 8) | (block[i-3] << 8); + j = ftab[s] -1; + ftab[s] = j; + ptr[j] = i-3; + } + for (; i >= 0; i--) { + s = (s >> 8) | (block[i] << 8); + j = ftab[s] -1; + ftab[s] = j; + ptr[j] = i; + } + + /*-- + Now ftab contains the first loc of every small bucket. + Calculate the running order, from smallest to largest + big bucket. + --*/ + for (i = 0; i <= 255; i++) { + bigDone [i] = False; + runningOrder[i] = i; + } + + { + Int32 vv; + Int32 h = 1; + do h = 3 * h + 1; while (h <= 256); + do { + h = h / 3; + for (i = h; i <= 255; i++) { + vv = runningOrder[i]; + j = i; + while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) { + runningOrder[j] = runningOrder[j-h]; + j = j - h; + if (j <= (h - 1)) goto zero; + } + zero: + runningOrder[j] = vv; + } + } while (h != 1); + } + + /*-- + The main sorting loop. + --*/ + + numQSorted = 0; + + for (i = 0; i <= 255; i++) { + + /*-- + Process big buckets, starting with the least full. + Basically this is a 3-step process in which we call + mainQSort3 to sort the small buckets [ss, j], but + also make a big effort to avoid the calls if we can. + --*/ + ss = runningOrder[i]; + + /*-- + Step 1: + Complete the big bucket [ss] by quicksorting + any unsorted small buckets [ss, j], for j != ss. + Hopefully previous pointer-scanning phases have already + completed many of the small buckets [ss, j], so + we don't have to sort them at all. + --*/ + for (j = 0; j <= 255; j++) { + if (j != ss) { + sb = (ss << 8) + j; + if ( ! (ftab[sb] & SETMASK) ) { + Int32 lo = ftab[sb] & CLEARMASK; + Int32 hi = (ftab[sb+1] & CLEARMASK) - 1; + if (hi > lo) { + if (verb >= 4) + VPrintf4 ( " qsort [0x%x, 0x%x] " + "done %d this %d\n", + ss, j, numQSorted, hi - lo + 1 ); + mainQSort3 ( + ptr, block, quadrant, nblock, + lo, hi, BZ_N_RADIX, budget + ); + numQSorted += (hi - lo + 1); + if (*budget < 0) return; + } + } + ftab[sb] |= SETMASK; + } + } + + AssertH ( !bigDone[ss], 1006 ); + + /*-- + Step 2: + Now scan this big bucket [ss] so as to synthesise the + sorted order for small buckets [t, ss] for all t, + including, magically, the bucket [ss,ss] too. + This will avoid doing Real Work in subsequent Step 1's. + --*/ + { + for (j = 0; j <= 255; j++) { + copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK; + copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1; + } + for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) { + k = ptr[j]-1; if (k < 0) k += nblock; + c1 = block[k]; + if (!bigDone[c1]) + ptr[ copyStart[c1]++ ] = k; + } + for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) { + k = ptr[j]-1; if (k < 0) k += nblock; + c1 = block[k]; + if (!bigDone[c1]) + ptr[ copyEnd[c1]-- ] = k; + } + } + + AssertH ( (copyStart[ss]-1 == copyEnd[ss]) + || + /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1. + Necessity for this case is demonstrated by compressing + a sequence of approximately 48.5 million of character + 251; 1.0.0/1.0.1 will then die here. */ + (copyStart[ss] == 0 && copyEnd[ss] == nblock-1), + 1007 ) + + for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK; + + /*-- + Step 3: + The [ss] big bucket is now done. Record this fact, + and update the quadrant descriptors. Remember to + update quadrants in the overshoot area too, if + necessary. The "if (i < 255)" test merely skips + this updating for the last bucket processed, since + updating for the last bucket is pointless. + + The quadrant array provides a way to incrementally + cache sort orderings, as they appear, so as to + make subsequent comparisons in fullGtU() complete + faster. For repetitive blocks this makes a big + difference (but not big enough to be able to avoid + the fallback sorting mechanism, exponential radix sort). + + The precise meaning is: at all times: + + for 0 <= i < nblock and 0 <= j <= nblock + + if block[i] != block[j], + + then the relative values of quadrant[i] and + quadrant[j] are meaningless. + + else { + if quadrant[i] < quadrant[j] + then the string starting at i lexicographically + precedes the string starting at j + + else if quadrant[i] > quadrant[j] + then the string starting at j lexicographically + precedes the string starting at i + + else + the relative ordering of the strings starting + at i and j has not yet been determined. + } + --*/ + bigDone[ss] = True; + + if (i < 255) { + Int32 bbStart = ftab[ss << 8] & CLEARMASK; + Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart; + Int32 shifts = 0; + + while ((bbSize >> shifts) > 65534) shifts++; + + for (j = bbSize-1; j >= 0; j--) { + Int32 a2update = ptr[bbStart + j]; + UInt16 qVal = (UInt16)(j >> shifts); + quadrant[a2update] = qVal; + if (a2update < BZ_N_OVERSHOOT) + quadrant[a2update + nblock] = qVal; + } + AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 ); + } + + } + + if (verb >= 4) + VPrintf3 ( " %d pointers, %d sorted, %d scanned\n", + nblock, numQSorted, nblock - numQSorted ); +} + +#undef BIGFREQ +#undef SETMASK +#undef CLEARMASK + + +/*---------------------------------------------*/ +/* Pre: + nblock > 0 + arr2 exists for [0 .. nblock-1 +N_OVERSHOOT] + ((UChar*)arr2) [0 .. nblock-1] holds block + arr1 exists for [0 .. nblock-1] + + Post: + ((UChar*)arr2) [0 .. nblock-1] holds block + All other areas of block destroyed + ftab [ 0 .. 65536 ] destroyed + arr1 [0 .. nblock-1] holds sorted order +*/ +void BZ2_blockSort ( EState* s ) +{ + UInt32* ptr = s->ptr; + UChar* block = s->block; + UInt32* ftab = s->ftab; + Int32 nblock = s->nblock; + Int32 verb = s->verbosity; + Int32 wfact = s->workFactor; + UInt16* quadrant; + Int32 budget; + Int32 budgetInit; + Int32 i; + + if (nblock < 10000) { + fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb ); + } else { + /* Calculate the location for quadrant, remembering to get + the alignment right. Assumes that &(block[0]) is at least + 2-byte aligned -- this should be ok since block is really + the first section of arr2. + */ + i = nblock+BZ_N_OVERSHOOT; + if (i & 1) i++; + quadrant = (UInt16*)(&(block[i])); + + /* (wfact-1) / 3 puts the default-factor-30 + transition point at very roughly the same place as + with v0.1 and v0.9.0. + Not that it particularly matters any more, since the + resulting compressed stream is now the same regardless + of whether or not we use the main sort or fallback sort. + */ + if (wfact < 1 ) wfact = 1; + if (wfact > 100) wfact = 100; + budgetInit = nblock * ((wfact-1) / 3); + budget = budgetInit; + + mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget ); + if (verb >= 3) + VPrintf3 ( " %d work, %d block, ratio %5.2f\n", + budgetInit - budget, + nblock, + (float)(budgetInit - budget) / + (float)(nblock==0 ? 1 : nblock) ); + if (budget < 0) { + if (verb >= 2) + VPrintf0 ( " too repetitive; using fallback" + " sorting algorithm\n" ); + fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb ); + } + } + + s->origPtr = -1; + for (i = 0; i < s->nblock; i++) + if (ptr[i] == 0) + { s->origPtr = i; break; }; + + AssertH( s->origPtr != -1, 1003 ); +} + + +/*-------------------------------------------------------------*/ +/*--- end blocksort.c ---*/ +/*-------------------------------------------------------------*/ diff --git a/StormLib/src/bzip2/bzlib.c b/StormLib/src/bzip2/bzlib.c new file mode 100644 index 000000000..b98f3e586 --- /dev/null +++ b/StormLib/src/bzip2/bzlib.c @@ -0,0 +1,1573 @@ + +/*-------------------------------------------------------------*/ +/*--- Library top-level functions. ---*/ +/*--- bzlib.c ---*/ +/*-------------------------------------------------------------*/ + +/* ------------------------------------------------------------------ + This file is part of bzip2/libbzip2, a program and library for + lossless, block-sorting data compression. + + bzip2/libbzip2 version 1.0.5 of 10 December 2007 + Copyright (C) 1996-2007 Julian Seward + + Please read the WARNING, DISCLAIMER and PATENTS sections in the + README file. + + This program is released under the terms of the license contained + in the file LICENSE. + ------------------------------------------------------------------ */ + +/* CHANGES + 0.9.0 -- original version. + 0.9.0a/b -- no changes in this file. + 0.9.0c -- made zero-length BZ_FLUSH work correctly in bzCompress(). + fixed bzWrite/bzRead to ignore zero-length requests. + fixed bzread to correctly handle read requests after EOF. + wrong parameter order in call to bzDecompressInit in + bzBuffToBuffDecompress. Fixed. +*/ + +#define _CRT_SECURE_NO_WARNINGS +#include "bzlib_private.h" + + +/*---------------------------------------------------*/ +/*--- Compression stuff ---*/ +/*---------------------------------------------------*/ + + +/*---------------------------------------------------*/ +#ifndef BZ_NO_STDIO +void BZ2_bz__AssertH__fail ( int errcode ) +{ + fprintf(stderr, + "\n\nbzip2/libbzip2: internal error number %d.\n" + "This is a bug in bzip2/libbzip2, %s.\n" + "Please report it to me at: jseward@bzip.org. If this happened\n" + "when you were using some program which uses libbzip2 as a\n" + "component, you should also report this bug to the author(s)\n" + "of that program. Please make an effort to report this bug;\n" + "timely and accurate bug reports eventually lead to higher\n" + "quality software. Thanks. Julian Seward, 10 December 2007.\n\n", + errcode, + BZ2_bzlibVersion() + ); + + if (errcode == 1007) { + fprintf(stderr, + "\n*** A special note about internal error number 1007 ***\n" + "\n" + "Experience suggests that a common cause of i.e. 1007\n" + "is unreliable memory or other hardware. The 1007 assertion\n" + "just happens to cross-check the results of huge numbers of\n" + "memory reads/writes, and so acts (unintendedly) as a stress\n" + "test of your memory system.\n" + "\n" + "I suggest the following: try compressing the file again,\n" + "possibly monitoring progress in detail with the -vv flag.\n" + "\n" + "* If the error cannot be reproduced, and/or happens at different\n" + " points in compression, you may have a flaky memory system.\n" + " Try a memory-test program. I have used Memtest86\n" + " (www.memtest86.com). At the time of writing it is free (GPLd).\n" + " Memtest86 tests memory much more thorougly than your BIOSs\n" + " power-on test, and may find failures that the BIOS doesn't.\n" + "\n" + "* If the error can be repeatably reproduced, this is a bug in\n" + " bzip2, and I would very much like to hear about it. Please\n" + " let me know, and, ideally, save a copy of the file causing the\n" + " problem -- without which I will be unable to investigate it.\n" + "\n" + ); + } + + exit(3); +} +#endif + + +/*---------------------------------------------------*/ +static +int bz_config_ok ( void ) +{ + if (sizeof(int) != 4) return 0; + if (sizeof(short) != 2) return 0; + if (sizeof(char) != 1) return 0; + return 1; +} + + +/*---------------------------------------------------*/ +static +void* default_bzalloc ( void* opaque, Int32 items, Int32 size ) +{ + void* v = malloc ( items * size ); + return v; +} + +static +void default_bzfree ( void* opaque, void* addr ) +{ + if (addr != NULL) free ( addr ); +} + + +/*---------------------------------------------------*/ +static +void prepare_new_block ( EState* s ) +{ + Int32 i; + s->nblock = 0; + s->numZ = 0; + s->state_out_pos = 0; + BZ_INITIALISE_CRC ( s->blockCRC ); + for (i = 0; i < 256; i++) s->inUse[i] = False; + s->blockNo++; +} + + +/*---------------------------------------------------*/ +static +void init_RL ( EState* s ) +{ + s->state_in_ch = 256; + s->state_in_len = 0; +} + + +static +Bool isempty_RL ( EState* s ) +{ + if (s->state_in_ch < 256 && s->state_in_len > 0) + return False; else + return True; +} + + +/*---------------------------------------------------*/ +int BZ_API(BZ2_bzCompressInit) + ( bz_stream* strm, + int blockSize100k, + int verbosity, + int workFactor ) +{ + Int32 n; + EState* s; + + if (!bz_config_ok()) return BZ_CONFIG_ERROR; + + if (strm == NULL || + blockSize100k < 1 || blockSize100k > 9 || + workFactor < 0 || workFactor > 250) + return BZ_PARAM_ERROR; + + if (workFactor == 0) workFactor = 30; + if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc; + if (strm->bzfree == NULL) strm->bzfree = default_bzfree; + + s = BZALLOC( sizeof(EState) ); + if (s == NULL) return BZ_MEM_ERROR; + s->strm = strm; + + s->arr1 = NULL; + s->arr2 = NULL; + s->ftab = NULL; + + n = 100000 * blockSize100k; + s->arr1 = BZALLOC( n * sizeof(UInt32) ); + s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) ); + s->ftab = BZALLOC( 65537 * sizeof(UInt32) ); + + if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) { + if (s->arr1 != NULL) BZFREE(s->arr1); + if (s->arr2 != NULL) BZFREE(s->arr2); + if (s->ftab != NULL) BZFREE(s->ftab); + if (s != NULL) BZFREE(s); + return BZ_MEM_ERROR; + } + + s->blockNo = 0; + s->state = BZ_S_INPUT; + s->mode = BZ_M_RUNNING; + s->combinedCRC = 0; + s->blockSize100k = blockSize100k; + s->nblockMAX = 100000 * blockSize100k - 19; + s->verbosity = verbosity; + s->workFactor = workFactor; + + s->block = (UChar*)s->arr2; + s->mtfv = (UInt16*)s->arr1; + s->zbits = NULL; + s->ptr = (UInt32*)s->arr1; + + strm->state = s; + strm->total_in_lo32 = 0; + strm->total_in_hi32 = 0; + strm->total_out_lo32 = 0; + strm->total_out_hi32 = 0; + init_RL ( s ); + prepare_new_block ( s ); + return BZ_OK; +} + + +/*---------------------------------------------------*/ +static +void add_pair_to_block ( EState* s ) +{ + Int32 i; + UChar ch = (UChar)(s->state_in_ch); + for (i = 0; i < s->state_in_len; i++) { + BZ_UPDATE_CRC( s->blockCRC, ch ); + } + s->inUse[s->state_in_ch] = True; + switch (s->state_in_len) { + case 1: + s->block[s->nblock] = (UChar)ch; s->nblock++; + break; + case 2: + s->block[s->nblock] = (UChar)ch; s->nblock++; + s->block[s->nblock] = (UChar)ch; s->nblock++; + break; + case 3: + s->block[s->nblock] = (UChar)ch; s->nblock++; + s->block[s->nblock] = (UChar)ch; s->nblock++; + s->block[s->nblock] = (UChar)ch; s->nblock++; + break; + default: + s->inUse[s->state_in_len-4] = True; + s->block[s->nblock] = (UChar)ch; s->nblock++; + s->block[s->nblock] = (UChar)ch; s->nblock++; + s->block[s->nblock] = (UChar)ch; s->nblock++; + s->block[s->nblock] = (UChar)ch; s->nblock++; + s->block[s->nblock] = ((UChar)(s->state_in_len-4)); + s->nblock++; + break; + } +} + + +/*---------------------------------------------------*/ +static +void flush_RL ( EState* s ) +{ + if (s->state_in_ch < 256) add_pair_to_block ( s ); + init_RL ( s ); +} + + +/*---------------------------------------------------*/ +#define ADD_CHAR_TO_BLOCK(zs,zchh0) \ +{ \ + UInt32 zchh = (UInt32)(zchh0); \ + /*-- fast track the common case --*/ \ + if (zchh != zs->state_in_ch && \ + zs->state_in_len == 1) { \ + UChar ch = (UChar)(zs->state_in_ch); \ + BZ_UPDATE_CRC( zs->blockCRC, ch ); \ + zs->inUse[zs->state_in_ch] = True; \ + zs->block[zs->nblock] = (UChar)ch; \ + zs->nblock++; \ + zs->state_in_ch = zchh; \ + } \ + else \ + /*-- general, uncommon cases --*/ \ + if (zchh != zs->state_in_ch || \ + zs->state_in_len == 255) { \ + if (zs->state_in_ch < 256) \ + add_pair_to_block ( zs ); \ + zs->state_in_ch = zchh; \ + zs->state_in_len = 1; \ + } else { \ + zs->state_in_len++; \ + } \ +} + + +/*---------------------------------------------------*/ +static +Bool copy_input_until_stop ( EState* s ) +{ + Bool progress_in = False; + + if (s->mode == BZ_M_RUNNING) { + + /*-- fast track the common case --*/ + while (True) { + /*-- block full? --*/ + if (s->nblock >= s->nblockMAX) break; + /*-- no input? --*/ + if (s->strm->avail_in == 0) break; + progress_in = True; + ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); + s->strm->next_in++; + s->strm->avail_in--; + s->strm->total_in_lo32++; + if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++; + } + + } else { + + /*-- general, uncommon case --*/ + while (True) { + /*-- block full? --*/ + if (s->nblock >= s->nblockMAX) break; + /*-- no input? --*/ + if (s->strm->avail_in == 0) break; + /*-- flush/finish end? --*/ + if (s->avail_in_expect == 0) break; + progress_in = True; + ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); + s->strm->next_in++; + s->strm->avail_in--; + s->strm->total_in_lo32++; + if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++; + s->avail_in_expect--; + } + } + return progress_in; +} + + +/*---------------------------------------------------*/ +static +Bool copy_output_until_stop ( EState* s ) +{ + Bool progress_out = False; + + while (True) { + + /*-- no output space? --*/ + if (s->strm->avail_out == 0) break; + + /*-- block done? --*/ + if (s->state_out_pos >= s->numZ) break; + + progress_out = True; + *(s->strm->next_out) = s->zbits[s->state_out_pos]; + s->state_out_pos++; + s->strm->avail_out--; + s->strm->next_out++; + s->strm->total_out_lo32++; + if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; + } + + return progress_out; +} + + +/*---------------------------------------------------*/ +static +Bool handle_compress ( bz_stream* strm ) +{ + Bool progress_in = False; + Bool progress_out = False; + EState* s = strm->state; + + while (True) { + + if (s->state == BZ_S_OUTPUT) { + progress_out |= copy_output_until_stop ( s ); + if (s->state_out_pos < s->numZ) break; + if (s->mode == BZ_M_FINISHING && + s->avail_in_expect == 0 && + isempty_RL(s)) break; + prepare_new_block ( s ); + s->state = BZ_S_INPUT; + if (s->mode == BZ_M_FLUSHING && + s->avail_in_expect == 0 && + isempty_RL(s)) break; + } + + if (s->state == BZ_S_INPUT) { + progress_in |= copy_input_until_stop ( s ); + if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) { + flush_RL ( s ); + BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) ); + s->state = BZ_S_OUTPUT; + } + else + if (s->nblock >= s->nblockMAX) { + BZ2_compressBlock ( s, False ); + s->state = BZ_S_OUTPUT; + } + else + if (s->strm->avail_in == 0) { + break; + } + } + + } + + return progress_in || progress_out; +} + + +/*---------------------------------------------------*/ +int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action ) +{ + Bool progress; + EState* s; + if (strm == NULL) return BZ_PARAM_ERROR; + s = strm->state; + if (s == NULL) return BZ_PARAM_ERROR; + if (s->strm != strm) return BZ_PARAM_ERROR; + + preswitch: + switch (s->mode) { + + case BZ_M_IDLE: + return BZ_SEQUENCE_ERROR; + + case BZ_M_RUNNING: + if (action == BZ_RUN) { + progress = handle_compress ( strm ); + return progress ? BZ_RUN_OK : BZ_PARAM_ERROR; + } + else + if (action == BZ_FLUSH) { + s->avail_in_expect = strm->avail_in; + s->mode = BZ_M_FLUSHING; + goto preswitch; + } + else + if (action == BZ_FINISH) { + s->avail_in_expect = strm->avail_in; + s->mode = BZ_M_FINISHING; + goto preswitch; + } + else + return BZ_PARAM_ERROR; + + case BZ_M_FLUSHING: + if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR; + if (s->avail_in_expect != s->strm->avail_in) + return BZ_SEQUENCE_ERROR; + progress = handle_compress ( strm ); + if (s->avail_in_expect > 0 || !isempty_RL(s) || + s->state_out_pos < s->numZ) return BZ_FLUSH_OK; + s->mode = BZ_M_RUNNING; + return BZ_RUN_OK; + + case BZ_M_FINISHING: + if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR; + if (s->avail_in_expect != s->strm->avail_in) + return BZ_SEQUENCE_ERROR; + progress = handle_compress ( strm ); + if (!progress) return BZ_SEQUENCE_ERROR; + if (s->avail_in_expect > 0 || !isempty_RL(s) || + s->state_out_pos < s->numZ) return BZ_FINISH_OK; + s->mode = BZ_M_IDLE; + return BZ_STREAM_END; + } + return BZ_OK; /*--not reached--*/ +} + + +/*---------------------------------------------------*/ +int BZ_API(BZ2_bzCompressEnd) ( bz_stream *strm ) +{ + EState* s; + if (strm == NULL) return BZ_PARAM_ERROR; + s = strm->state; + if (s == NULL) return BZ_PARAM_ERROR; + if (s->strm != strm) return BZ_PARAM_ERROR; + + if (s->arr1 != NULL) BZFREE(s->arr1); + if (s->arr2 != NULL) BZFREE(s->arr2); + if (s->ftab != NULL) BZFREE(s->ftab); + BZFREE(strm->state); + + strm->state = NULL; + + return BZ_OK; +} + + +/*---------------------------------------------------*/ +/*--- Decompression stuff ---*/ +/*---------------------------------------------------*/ + +/*---------------------------------------------------*/ +int BZ_API(BZ2_bzDecompressInit) + ( bz_stream* strm, + int verbosity, + int small ) +{ + DState* s; + + if (!bz_config_ok()) return BZ_CONFIG_ERROR; + + if (strm == NULL) return BZ_PARAM_ERROR; + if (small != 0 && small != 1) return BZ_PARAM_ERROR; + if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR; + + if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc; + if (strm->bzfree == NULL) strm->bzfree = default_bzfree; + + s = BZALLOC( sizeof(DState) ); + if (s == NULL) return BZ_MEM_ERROR; + s->strm = strm; + strm->state = s; + s->state = BZ_X_MAGIC_1; + s->bsLive = 0; + s->bsBuff = 0; + s->calculatedCombinedCRC = 0; + strm->total_in_lo32 = 0; + strm->total_in_hi32 = 0; + strm->total_out_lo32 = 0; + strm->total_out_hi32 = 0; + s->smallDecompress = (Bool)small; + s->ll4 = NULL; + s->ll16 = NULL; + s->tt = NULL; + s->currBlockNo = 0; + s->verbosity = verbosity; + + return BZ_OK; +} + + +/*---------------------------------------------------*/ +/* Return True iff data corruption is discovered. + Returns False if there is no problem. +*/ +static +Bool unRLE_obuf_to_output_FAST ( DState* s ) +{ + UChar k1; + + if (s->blockRandomised) { + + while (True) { + /* try to finish existing run */ + while (True) { + if (s->strm->avail_out == 0) return False; + if (s->state_out_len == 0) break; + *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; + BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); + s->state_out_len--; + s->strm->next_out++; + s->strm->avail_out--; + s->strm->total_out_lo32++; + if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; + } + + /* can a new run be started? */ + if (s->nblock_used == s->save_nblock+1) return False; + + /* Only caused by corrupt data stream? */ + if (s->nblock_used > s->save_nblock+1) + return True; + + s->state_out_len = 1; + s->state_out_ch = s->k0; + BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; + k1 ^= BZ_RAND_MASK; s->nblock_used++; + if (s->nblock_used == s->save_nblock+1) continue; + if (k1 != s->k0) { s->k0 = k1; continue; }; + + s->state_out_len = 2; + BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; + k1 ^= BZ_RAND_MASK; s->nblock_used++; + if (s->nblock_used == s->save_nblock+1) continue; + if (k1 != s->k0) { s->k0 = k1; continue; }; + + s->state_out_len = 3; + BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; + k1 ^= BZ_RAND_MASK; s->nblock_used++; + if (s->nblock_used == s->save_nblock+1) continue; + if (k1 != s->k0) { s->k0 = k1; continue; }; + + BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; + k1 ^= BZ_RAND_MASK; s->nblock_used++; + s->state_out_len = ((Int32)k1) + 4; + BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK; + s->k0 ^= BZ_RAND_MASK; s->nblock_used++; + } + + } else { + + /* restore */ + UInt32 c_calculatedBlockCRC = s->calculatedBlockCRC; + UChar c_state_out_ch = s->state_out_ch; + Int32 c_state_out_len = s->state_out_len; + Int32 c_nblock_used = s->nblock_used; + Int32 c_k0 = s->k0; + UInt32* c_tt = s->tt; + UInt32 c_tPos = s->tPos; + char* cs_next_out = s->strm->next_out; + unsigned int cs_avail_out = s->strm->avail_out; + Int32 ro_blockSize100k = s->blockSize100k; + /* end restore */ + + UInt32 avail_out_INIT = cs_avail_out; + Int32 s_save_nblockPP = s->save_nblock+1; + unsigned int total_out_lo32_old; + + while (True) { + + /* try to finish existing run */ + if (c_state_out_len > 0) { + while (True) { + if (cs_avail_out == 0) goto return_notr; + if (c_state_out_len == 1) break; + *( (UChar*)(cs_next_out) ) = c_state_out_ch; + BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch ); + c_state_out_len--; + cs_next_out++; + cs_avail_out--; + } + s_state_out_len_eq_one: + { + if (cs_avail_out == 0) { + c_state_out_len = 1; goto return_notr; + }; + *( (UChar*)(cs_next_out) ) = c_state_out_ch; + BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch ); + cs_next_out++; + cs_avail_out--; + } + } + /* Only caused by corrupt data stream? */ + if (c_nblock_used > s_save_nblockPP) + return True; + + /* can a new run be started? */ + if (c_nblock_used == s_save_nblockPP) { + c_state_out_len = 0; goto return_notr; + }; + c_state_out_ch = c_k0; + BZ_GET_FAST_C(k1); c_nblock_used++; + if (k1 != c_k0) { + c_k0 = k1; goto s_state_out_len_eq_one; + }; + if (c_nblock_used == s_save_nblockPP) + goto s_state_out_len_eq_one; + + c_state_out_len = 2; + BZ_GET_FAST_C(k1); c_nblock_used++; + if (c_nblock_used == s_save_nblockPP) continue; + if (k1 != c_k0) { c_k0 = k1; continue; }; + + c_state_out_len = 3; + BZ_GET_FAST_C(k1); c_nblock_used++; + if (c_nblock_used == s_save_nblockPP) continue; + if (k1 != c_k0) { c_k0 = k1; continue; }; + + BZ_GET_FAST_C(k1); c_nblock_used++; + c_state_out_len = ((Int32)k1) + 4; + BZ_GET_FAST_C(c_k0); c_nblock_used++; + } + + return_notr: + total_out_lo32_old = s->strm->total_out_lo32; + s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out); + if (s->strm->total_out_lo32 < total_out_lo32_old) + s->strm->total_out_hi32++; + + /* save */ + s->calculatedBlockCRC = c_calculatedBlockCRC; + s->state_out_ch = c_state_out_ch; + s->state_out_len = c_state_out_len; + s->nblock_used = c_nblock_used; + s->k0 = c_k0; + s->tt = c_tt; + s->tPos = c_tPos; + s->strm->next_out = cs_next_out; + s->strm->avail_out = cs_avail_out; + /* end save */ + } + return False; +} + + + +/*---------------------------------------------------*/ +__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab ) +{ + Int32 nb, na, mid; + nb = 0; + na = 256; + do { + mid = (nb + na) >> 1; + if (indx >= cftab[mid]) nb = mid; else na = mid; + } + while (na - nb != 1); + return nb; +} + + +/*---------------------------------------------------*/ +/* Return True iff data corruption is discovered. + Returns False if there is no problem. +*/ +static +Bool unRLE_obuf_to_output_SMALL ( DState* s ) +{ + UChar k1; + + if (s->blockRandomised) { + + while (True) { + /* try to finish existing run */ + while (True) { + if (s->strm->avail_out == 0) return False; + if (s->state_out_len == 0) break; + *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; + BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); + s->state_out_len--; + s->strm->next_out++; + s->strm->avail_out--; + s->strm->total_out_lo32++; + if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; + } + + /* can a new run be started? */ + if (s->nblock_used == s->save_nblock+1) return False; + + /* Only caused by corrupt data stream? */ + if (s->nblock_used > s->save_nblock+1) + return True; + + s->state_out_len = 1; + s->state_out_ch = s->k0; + BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; + k1 ^= BZ_RAND_MASK; s->nblock_used++; + if (s->nblock_used == s->save_nblock+1) continue; + if (k1 != s->k0) { s->k0 = k1; continue; }; + + s->state_out_len = 2; + BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; + k1 ^= BZ_RAND_MASK; s->nblock_used++; + if (s->nblock_used == s->save_nblock+1) continue; + if (k1 != s->k0) { s->k0 = k1; continue; }; + + s->state_out_len = 3; + BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; + k1 ^= BZ_RAND_MASK; s->nblock_used++; + if (s->nblock_used == s->save_nblock+1) continue; + if (k1 != s->k0) { s->k0 = k1; continue; }; + + BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; + k1 ^= BZ_RAND_MASK; s->nblock_used++; + s->state_out_len = ((Int32)k1) + 4; + BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK; + s->k0 ^= BZ_RAND_MASK; s->nblock_used++; + } + + } else { + + while (True) { + /* try to finish existing run */ + while (True) { + if (s->strm->avail_out == 0) return False; + if (s->state_out_len == 0) break; + *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; + BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); + s->state_out_len--; + s->strm->next_out++; + s->strm->avail_out--; + s->strm->total_out_lo32++; + if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; + } + + /* can a new run be started? */ + if (s->nblock_used == s->save_nblock+1) return False; + + /* Only caused by corrupt data stream? */ + if (s->nblock_used > s->save_nblock+1) + return True; + + s->state_out_len = 1; + s->state_out_ch = s->k0; + BZ_GET_SMALL(k1); s->nblock_used++; + if (s->nblock_used == s->save_nblock+1) continue; + if (k1 != s->k0) { s->k0 = k1; continue; }; + + s->state_out_len = 2; + BZ_GET_SMALL(k1); s->nblock_used++; + if (s->nblock_used == s->save_nblock+1) continue; + if (k1 != s->k0) { s->k0 = k1; continue; }; + + s->state_out_len = 3; + BZ_GET_SMALL(k1); s->nblock_used++; + if (s->nblock_used == s->save_nblock+1) continue; + if (k1 != s->k0) { s->k0 = k1; continue; }; + + BZ_GET_SMALL(k1); s->nblock_used++; + s->state_out_len = ((Int32)k1) + 4; + BZ_GET_SMALL(s->k0); s->nblock_used++; + } + + } +} + + +/*---------------------------------------------------*/ +int BZ_API(BZ2_bzDecompress) ( bz_stream *strm ) +{ + Bool corrupt; + DState* s; + if (strm == NULL) return BZ_PARAM_ERROR; + s = strm->state; + if (s == NULL) return BZ_PARAM_ERROR; + if (s->strm != strm) return BZ_PARAM_ERROR; + + while (True) { + if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR; + if (s->state == BZ_X_OUTPUT) { + if (s->smallDecompress) + corrupt = unRLE_obuf_to_output_SMALL ( s ); else + corrupt = unRLE_obuf_to_output_FAST ( s ); + if (corrupt) return BZ_DATA_ERROR; + if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) { + BZ_FINALISE_CRC ( s->calculatedBlockCRC ); + if (s->verbosity >= 3) + VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, + s->calculatedBlockCRC ); + if (s->verbosity >= 2) VPrintf0 ( "]" ); + if (s->calculatedBlockCRC != s->storedBlockCRC) + return BZ_DATA_ERROR; + s->calculatedCombinedCRC + = (s->calculatedCombinedCRC << 1) | + (s->calculatedCombinedCRC >> 31); + s->calculatedCombinedCRC ^= s->calculatedBlockCRC; + s->state = BZ_X_BLKHDR_1; + } else { + return BZ_OK; + } + } + if (s->state >= BZ_X_MAGIC_1) { + Int32 r = BZ2_decompress ( s ); + if (r == BZ_STREAM_END) { + if (s->verbosity >= 3) + VPrintf2 ( "\n combined CRCs: stored = 0x%08x, computed = 0x%08x", + s->storedCombinedCRC, s->calculatedCombinedCRC ); + if (s->calculatedCombinedCRC != s->storedCombinedCRC) + return BZ_DATA_ERROR; + return r; + } + if (s->state != BZ_X_OUTPUT) return r; + } + } + + AssertH ( 0, 6001 ); + + return 0; /*NOTREACHED*/ +} + + +/*---------------------------------------------------*/ +int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm ) +{ + DState* s; + if (strm == NULL) return BZ_PARAM_ERROR; + s = strm->state; + if (s == NULL) return BZ_PARAM_ERROR; + if (s->strm != strm) return BZ_PARAM_ERROR; + + if (s->tt != NULL) BZFREE(s->tt); + if (s->ll16 != NULL) BZFREE(s->ll16); + if (s->ll4 != NULL) BZFREE(s->ll4); + + BZFREE(strm->state); + strm->state = NULL; + + return BZ_OK; +} + + +#ifndef BZ_NO_STDIO +/*---------------------------------------------------*/ +/*--- File I/O stuff ---*/ +/*---------------------------------------------------*/ + +#define BZ_SETERR(eee) \ +{ \ + if (bzerror != NULL) *bzerror = eee; \ + if (bzf != NULL) bzf->lastErr = eee; \ +} + +typedef + struct { + FILE* handle; + Char buf[BZ_MAX_UNUSED]; + Int32 bufN; + Bool writing; + bz_stream strm; + Int32 lastErr; + Bool initialisedOk; + } + bzFile; + + +/*---------------------------------------------*/ +static Bool myfeof ( FILE* f ) +{ + Int32 c = fgetc ( f ); + if (c == EOF) return True; + ungetc ( c, f ); + return False; +} + + +/*---------------------------------------------------*/ +BZFILE* BZ_API(BZ2_bzWriteOpen) + ( int* bzerror, + FILE* f, + int blockSize100k, + int verbosity, + int workFactor ) +{ + Int32 ret; + bzFile* bzf = NULL; + + BZ_SETERR(BZ_OK); + + if (f == NULL || + (blockSize100k < 1 || blockSize100k > 9) || + (workFactor < 0 || workFactor > 250) || + (verbosity < 0 || verbosity > 4)) + { BZ_SETERR(BZ_PARAM_ERROR); return NULL; }; + + if (ferror(f)) + { BZ_SETERR(BZ_IO_ERROR); return NULL; }; + + bzf = malloc ( sizeof(bzFile) ); + if (bzf == NULL) + { BZ_SETERR(BZ_MEM_ERROR); return NULL; }; + + BZ_SETERR(BZ_OK); + bzf->initialisedOk = False; + bzf->bufN = 0; + bzf->handle = f; + bzf->writing = True; + bzf->strm.bzalloc = NULL; + bzf->strm.bzfree = NULL; + bzf->strm.opaque = NULL; + + if (workFactor == 0) workFactor = 30; + ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k, + verbosity, workFactor ); + if (ret != BZ_OK) + { BZ_SETERR(ret); free(bzf); return NULL; }; + + bzf->strm.avail_in = 0; + bzf->initialisedOk = True; + return bzf; +} + + + +/*---------------------------------------------------*/ +void BZ_API(BZ2_bzWrite) + ( int* bzerror, + BZFILE* b, + void* buf, + int len ) +{ + Int32 n, n2, ret; + bzFile* bzf = (bzFile*)b; + + BZ_SETERR(BZ_OK); + if (bzf == NULL || buf == NULL || len < 0) + { BZ_SETERR(BZ_PARAM_ERROR); return; }; + if (!(bzf->writing)) + { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; + if (ferror(bzf->handle)) + { BZ_SETERR(BZ_IO_ERROR); return; }; + + if (len == 0) + { BZ_SETERR(BZ_OK); return; }; + + bzf->strm.avail_in = len; + bzf->strm.next_in = buf; + + while (True) { + bzf->strm.avail_out = BZ_MAX_UNUSED; + bzf->strm.next_out = bzf->buf; + ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN ); + if (ret != BZ_RUN_OK) + { BZ_SETERR(ret); return; }; + + if (bzf->strm.avail_out < BZ_MAX_UNUSED) { + n = BZ_MAX_UNUSED - bzf->strm.avail_out; + n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), + n, bzf->handle ); + if (n != n2 || ferror(bzf->handle)) + { BZ_SETERR(BZ_IO_ERROR); return; }; + } + + if (bzf->strm.avail_in == 0) + { BZ_SETERR(BZ_OK); return; }; + } +} + + +/*---------------------------------------------------*/ +void BZ_API(BZ2_bzWriteClose) + ( int* bzerror, + BZFILE* b, + int abandon, + unsigned int* nbytes_in, + unsigned int* nbytes_out ) +{ + BZ2_bzWriteClose64 ( bzerror, b, abandon, + nbytes_in, NULL, nbytes_out, NULL ); +} + + +void BZ_API(BZ2_bzWriteClose64) + ( int* bzerror, + BZFILE* b, + int abandon, + unsigned int* nbytes_in_lo32, + unsigned int* nbytes_in_hi32, + unsigned int* nbytes_out_lo32, + unsigned int* nbytes_out_hi32 ) +{ + Int32 n, n2, ret; + bzFile* bzf = (bzFile*)b; + + if (bzf == NULL) + { BZ_SETERR(BZ_OK); return; }; + if (!(bzf->writing)) + { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; + if (ferror(bzf->handle)) + { BZ_SETERR(BZ_IO_ERROR); return; }; + + if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0; + if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0; + if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0; + if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0; + + if ((!abandon) && bzf->lastErr == BZ_OK) { + while (True) { + bzf->strm.avail_out = BZ_MAX_UNUSED; + bzf->strm.next_out = bzf->buf; + ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH ); + if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END) + { BZ_SETERR(ret); return; }; + + if (bzf->strm.avail_out < BZ_MAX_UNUSED) { + n = BZ_MAX_UNUSED - bzf->strm.avail_out; + n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), + n, bzf->handle ); + if (n != n2 || ferror(bzf->handle)) + { BZ_SETERR(BZ_IO_ERROR); return; }; + } + + if (ret == BZ_STREAM_END) break; + } + } + + if ( !abandon && !ferror ( bzf->handle ) ) { + fflush ( bzf->handle ); + if (ferror(bzf->handle)) + { BZ_SETERR(BZ_IO_ERROR); return; }; + } + + if (nbytes_in_lo32 != NULL) + *nbytes_in_lo32 = bzf->strm.total_in_lo32; + if (nbytes_in_hi32 != NULL) + *nbytes_in_hi32 = bzf->strm.total_in_hi32; + if (nbytes_out_lo32 != NULL) + *nbytes_out_lo32 = bzf->strm.total_out_lo32; + if (nbytes_out_hi32 != NULL) + *nbytes_out_hi32 = bzf->strm.total_out_hi32; + + BZ_SETERR(BZ_OK); + BZ2_bzCompressEnd ( &(bzf->strm) ); + free ( bzf ); +} + + +/*---------------------------------------------------*/ +BZFILE* BZ_API(BZ2_bzReadOpen) + ( int* bzerror, + FILE* f, + int verbosity, + int small, + void* unused, + int nUnused ) +{ + bzFile* bzf = NULL; + int ret; + + BZ_SETERR(BZ_OK); + + if (f == NULL || + (small != 0 && small != 1) || + (verbosity < 0 || verbosity > 4) || + (unused == NULL && nUnused != 0) || + (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED))) + { BZ_SETERR(BZ_PARAM_ERROR); return NULL; }; + + if (ferror(f)) + { BZ_SETERR(BZ_IO_ERROR); return NULL; }; + + bzf = malloc ( sizeof(bzFile) ); + if (bzf == NULL) + { BZ_SETERR(BZ_MEM_ERROR); return NULL; }; + + BZ_SETERR(BZ_OK); + + bzf->initialisedOk = False; + bzf->handle = f; + bzf->bufN = 0; + bzf->writing = False; + bzf->strm.bzalloc = NULL; + bzf->strm.bzfree = NULL; + bzf->strm.opaque = NULL; + + while (nUnused > 0) { + bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++; + unused = ((void*)( 1 + ((UChar*)(unused)) )); + nUnused--; + } + + ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small ); + if (ret != BZ_OK) + { BZ_SETERR(ret); free(bzf); return NULL; }; + + bzf->strm.avail_in = bzf->bufN; + bzf->strm.next_in = bzf->buf; + + bzf->initialisedOk = True; + return bzf; +} + + +/*---------------------------------------------------*/ +void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b ) +{ + bzFile* bzf = (bzFile*)b; + + BZ_SETERR(BZ_OK); + if (bzf == NULL) + { BZ_SETERR(BZ_OK); return; }; + + if (bzf->writing) + { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; + + if (bzf->initialisedOk) + (void)BZ2_bzDecompressEnd ( &(bzf->strm) ); + free ( bzf ); +} + + +/*---------------------------------------------------*/ +int BZ_API(BZ2_bzRead) + ( int* bzerror, + BZFILE* b, + void* buf, + int len ) +{ + Int32 n, ret; + bzFile* bzf = (bzFile*)b; + + BZ_SETERR(BZ_OK); + + if (bzf == NULL || buf == NULL || len < 0) + { BZ_SETERR(BZ_PARAM_ERROR); return 0; }; + + if (bzf->writing) + { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; }; + + if (len == 0) + { BZ_SETERR(BZ_OK); return 0; }; + + bzf->strm.avail_out = len; + bzf->strm.next_out = buf; + + while (True) { + + if (ferror(bzf->handle)) + { BZ_SETERR(BZ_IO_ERROR); return 0; }; + + if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) { + n = fread ( bzf->buf, sizeof(UChar), + BZ_MAX_UNUSED, bzf->handle ); + if (ferror(bzf->handle)) + { BZ_SETERR(BZ_IO_ERROR); return 0; }; + bzf->bufN = n; + bzf->strm.avail_in = bzf->bufN; + bzf->strm.next_in = bzf->buf; + } + + ret = BZ2_bzDecompress ( &(bzf->strm) ); + + if (ret != BZ_OK && ret != BZ_STREAM_END) + { BZ_SETERR(ret); return 0; }; + + if (ret == BZ_OK && myfeof(bzf->handle) && + bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0) + { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; }; + + if (ret == BZ_STREAM_END) + { BZ_SETERR(BZ_STREAM_END); + return len - bzf->strm.avail_out; }; + if (bzf->strm.avail_out == 0) + { BZ_SETERR(BZ_OK); return len; }; + + } + + return 0; /*not reached*/ +} + + +/*---------------------------------------------------*/ +void BZ_API(BZ2_bzReadGetUnused) + ( int* bzerror, + BZFILE* b, + void** unused, + int* nUnused ) +{ + bzFile* bzf = (bzFile*)b; + if (bzf == NULL) + { BZ_SETERR(BZ_PARAM_ERROR); return; }; + if (bzf->lastErr != BZ_STREAM_END) + { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; + if (unused == NULL || nUnused == NULL) + { BZ_SETERR(BZ_PARAM_ERROR); return; }; + + BZ_SETERR(BZ_OK); + *nUnused = bzf->strm.avail_in; + *unused = bzf->strm.next_in; +} +#endif + + +/*---------------------------------------------------*/ +/*--- Misc convenience stuff ---*/ +/*---------------------------------------------------*/ + +/*---------------------------------------------------*/ +int BZ_API(BZ2_bzBuffToBuffCompress) + ( char* dest, + unsigned int* destLen, + char* source, + unsigned int sourceLen, + int blockSize100k, + int verbosity, + int workFactor ) +{ + bz_stream strm; + int ret; + + if (dest == NULL || destLen == NULL || + source == NULL || + blockSize100k < 1 || blockSize100k > 9 || + verbosity < 0 || verbosity > 4 || + workFactor < 0 || workFactor > 250) + return BZ_PARAM_ERROR; + + if (workFactor == 0) workFactor = 30; + strm.bzalloc = NULL; + strm.bzfree = NULL; + strm.opaque = NULL; + ret = BZ2_bzCompressInit ( &strm, blockSize100k, + verbosity, workFactor ); + if (ret != BZ_OK) return ret; + + strm.next_in = source; + strm.next_out = dest; + strm.avail_in = sourceLen; + strm.avail_out = *destLen; + + ret = BZ2_bzCompress ( &strm, BZ_FINISH ); + if (ret == BZ_FINISH_OK) goto output_overflow; + if (ret != BZ_STREAM_END) goto errhandler; + + /* normal termination */ + *destLen -= strm.avail_out; + BZ2_bzCompressEnd ( &strm ); + return BZ_OK; + + output_overflow: + BZ2_bzCompressEnd ( &strm ); + return BZ_OUTBUFF_FULL; + + errhandler: + BZ2_bzCompressEnd ( &strm ); + return ret; +} + + +/*---------------------------------------------------*/ +int BZ_API(BZ2_bzBuffToBuffDecompress) + ( char* dest, + unsigned int* destLen, + char* source, + unsigned int sourceLen, + int small, + int verbosity ) +{ + bz_stream strm; + int ret; + + if (dest == NULL || destLen == NULL || + source == NULL || + (small != 0 && small != 1) || + verbosity < 0 || verbosity > 4) + return BZ_PARAM_ERROR; + + strm.bzalloc = NULL; + strm.bzfree = NULL; + strm.opaque = NULL; + ret = BZ2_bzDecompressInit ( &strm, verbosity, small ); + if (ret != BZ_OK) return ret; + + strm.next_in = source; + strm.next_out = dest; + strm.avail_in = sourceLen; + strm.avail_out = *destLen; + + ret = BZ2_bzDecompress ( &strm ); + if (ret == BZ_OK) goto output_overflow_or_eof; + if (ret != BZ_STREAM_END) goto errhandler; + + /* normal termination */ + *destLen -= strm.avail_out; + BZ2_bzDecompressEnd ( &strm ); + return BZ_OK; + + output_overflow_or_eof: + if (strm.avail_out > 0) { + BZ2_bzDecompressEnd ( &strm ); + return BZ_UNEXPECTED_EOF; + } else { + BZ2_bzDecompressEnd ( &strm ); + return BZ_OUTBUFF_FULL; + }; + + errhandler: + BZ2_bzDecompressEnd ( &strm ); + return ret; +} + + +/*---------------------------------------------------*/ +/*-- + Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp) + to support better zlib compatibility. + This code is not _officially_ part of libbzip2 (yet); + I haven't tested it, documented it, or considered the + threading-safeness of it. + If this code breaks, please contact both Yoshioka and me. +--*/ +/*---------------------------------------------------*/ + +/*---------------------------------------------------*/ +/*-- + return version like "0.9.5d, 4-Sept-1999". +--*/ +const char * BZ_API(BZ2_bzlibVersion)(void) +{ + return BZ_VERSION; +} + + +#ifndef BZ_NO_STDIO +/*---------------------------------------------------*/ + +#if defined(_WIN32) || defined(OS2) || defined(MSDOS) +# include +# include +# define SET_BINARY_MODE(file) _setmode(_fileno(file),O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif +static +BZFILE * bzopen_or_bzdopen + ( const char *path, /* no use when bzdopen */ + int fd, /* no use when bzdopen */ + const char *mode, + int open_mode) /* bzopen: 0, bzdopen:1 */ +{ + int bzerr; + char unused[BZ_MAX_UNUSED]; + int blockSize100k = 9; + int writing = 0; + char mode2[10] = ""; + FILE *fp = NULL; + BZFILE *bzfp = NULL; + int verbosity = 0; + int workFactor = 30; + int smallMode = 0; + int nUnused = 0; + + if (mode == NULL) return NULL; + while (*mode) { + switch (*mode) { + case 'r': + writing = 0; break; + case 'w': + writing = 1; break; + case 's': + smallMode = 1; break; + default: + if (isdigit((int)(*mode))) { + blockSize100k = *mode-BZ_HDR_0; + } + } + mode++; + } + strcat(mode2, writing ? "w" : "r" ); + strcat(mode2,"b"); /* binary mode */ + + if (open_mode==0) { + if (path==NULL || strcmp(path,"")==0) { + fp = (writing ? stdout : stdin); + SET_BINARY_MODE(fp); + } else { + fp = fopen(path,mode2); + } + } else { +#ifdef BZ_STRICT_ANSI + fp = NULL; +#else + fp = _fdopen(fd,mode2); +#endif + } + if (fp == NULL) return NULL; + + if (writing) { + /* Guard against total chaos and anarchy -- JRS */ + if (blockSize100k < 1) blockSize100k = 1; + if (blockSize100k > 9) blockSize100k = 9; + bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k, + verbosity,workFactor); + } else { + bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode, + unused,nUnused); + } + if (bzfp == NULL) { + if (fp != stdin && fp != stdout) fclose(fp); + return NULL; + } + return bzfp; +} + + +/*---------------------------------------------------*/ +/*-- + open file for read or write. + ex) bzopen("file","w9") + case path="" or NULL => use stdin or stdout. +--*/ +BZFILE * BZ_API(BZ2_bzopen) + ( const char *path, + const char *mode ) +{ + return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0); +} + + +/*---------------------------------------------------*/ +BZFILE * BZ_API(BZ2_bzdopen) + ( int fd, + const char *mode ) +{ + return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1); +} + + +/*---------------------------------------------------*/ +int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len ) +{ + int bzerr, nread; + if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0; + nread = BZ2_bzRead(&bzerr,b,buf,len); + if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) { + return nread; + } else { + return -1; + } +} + + +/*---------------------------------------------------*/ +int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len ) +{ + int bzerr; + + BZ2_bzWrite(&bzerr,b,buf,len); + if(bzerr == BZ_OK){ + return len; + }else{ + return -1; + } +} + + +/*---------------------------------------------------*/ +int BZ_API(BZ2_bzflush) (BZFILE *b) +{ + /* do nothing now... */ + return 0; +} + + +/*---------------------------------------------------*/ +void BZ_API(BZ2_bzclose) (BZFILE* b) +{ + int bzerr; + FILE *fp; + + if (b==NULL) {return;} + fp = ((bzFile *)b)->handle; + if(((bzFile*)b)->writing){ + BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL); + if(bzerr != BZ_OK){ + BZ2_bzWriteClose(NULL,b,1,NULL,NULL); + } + }else{ + BZ2_bzReadClose(&bzerr,b); + } + if(fp!=stdin && fp!=stdout){ + fclose(fp); + } +} + + +/*---------------------------------------------------*/ +/*-- + return last error code +--*/ +static const char *bzerrorstrings[] = { + "OK" + ,"SEQUENCE_ERROR" + ,"PARAM_ERROR" + ,"MEM_ERROR" + ,"DATA_ERROR" + ,"DATA_ERROR_MAGIC" + ,"IO_ERROR" + ,"UNEXPECTED_EOF" + ,"OUTBUFF_FULL" + ,"CONFIG_ERROR" + ,"???" /* for future */ + ,"???" /* for future */ + ,"???" /* for future */ + ,"???" /* for future */ + ,"???" /* for future */ + ,"???" /* for future */ +}; + + +const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum) +{ + int err = ((bzFile *)b)->lastErr; + + if(err>0) err = 0; + *errnum = err; + return bzerrorstrings[err*-1]; +} +#endif + + +/*-------------------------------------------------------------*/ +/*--- end bzlib.c ---*/ +/*-------------------------------------------------------------*/ diff --git a/StormLib/src/bzip2/bzlib.h b/StormLib/src/bzip2/bzlib.h new file mode 100644 index 000000000..c5b75d6d8 --- /dev/null +++ b/StormLib/src/bzip2/bzlib.h @@ -0,0 +1,282 @@ + +/*-------------------------------------------------------------*/ +/*--- Public header file for the library. ---*/ +/*--- bzlib.h ---*/ +/*-------------------------------------------------------------*/ + +/* ------------------------------------------------------------------ + This file is part of bzip2/libbzip2, a program and library for + lossless, block-sorting data compression. + + bzip2/libbzip2 version 1.0.5 of 10 December 2007 + Copyright (C) 1996-2007 Julian Seward + + Please read the WARNING, DISCLAIMER and PATENTS sections in the + README file. + + This program is released under the terms of the license contained + in the file LICENSE. + ------------------------------------------------------------------ */ + + +#ifndef _BZLIB_H +#define _BZLIB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define BZ_RUN 0 +#define BZ_FLUSH 1 +#define BZ_FINISH 2 + +#define BZ_OK 0 +#define BZ_RUN_OK 1 +#define BZ_FLUSH_OK 2 +#define BZ_FINISH_OK 3 +#define BZ_STREAM_END 4 +#define BZ_SEQUENCE_ERROR (-1) +#define BZ_PARAM_ERROR (-2) +#define BZ_MEM_ERROR (-3) +#define BZ_DATA_ERROR (-4) +#define BZ_DATA_ERROR_MAGIC (-5) +#define BZ_IO_ERROR (-6) +#define BZ_UNEXPECTED_EOF (-7) +#define BZ_OUTBUFF_FULL (-8) +#define BZ_CONFIG_ERROR (-9) + +typedef + struct { + char *next_in; + unsigned int avail_in; + unsigned int total_in_lo32; + unsigned int total_in_hi32; + + char *next_out; + unsigned int avail_out; + unsigned int total_out_lo32; + unsigned int total_out_hi32; + + void *state; + + void *(*bzalloc)(void *,int,int); + void (*bzfree)(void *,void *); + void *opaque; + } + bz_stream; + + +#ifndef BZ_IMPORT +#define BZ_EXPORT +#endif + +#ifndef BZ_NO_STDIO +/* Need a definitition for FILE */ +#include +#endif + +#ifdef _WIN32 +# include +# ifdef small + /* windows.h define small to char */ +# undef small +# endif +# ifdef BZ_EXPORT +# define BZ_API(func) WINAPI func +# define BZ_EXTERN extern +# else + /* import windows dll dynamically */ +# define BZ_API(func) (WINAPI * func) +# define BZ_EXTERN +# endif +#else +# define BZ_API(func) func +# define BZ_EXTERN extern +#endif + + +/*-- Core (low-level) library functions --*/ + +BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( + bz_stream* strm, + int blockSize100k, + int verbosity, + int workFactor + ); + +BZ_EXTERN int BZ_API(BZ2_bzCompress) ( + bz_stream* strm, + int action + ); + +BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( + bz_stream* strm + ); + +BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( + bz_stream *strm, + int verbosity, + int small + ); + +BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( + bz_stream* strm + ); + +BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( + bz_stream *strm + ); + + + +/*-- High(er) level library functions --*/ + +#ifndef BZ_NO_STDIO +#define BZ_MAX_UNUSED 5000 + +typedef void BZFILE; + +BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( + int* bzerror, + FILE* f, + int verbosity, + int small, + void* unused, + int nUnused + ); + +BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( + int* bzerror, + BZFILE* b + ); + +BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( + int* bzerror, + BZFILE* b, + void** unused, + int* nUnused + ); + +BZ_EXTERN int BZ_API(BZ2_bzRead) ( + int* bzerror, + BZFILE* b, + void* buf, + int len + ); + +BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( + int* bzerror, + FILE* f, + int blockSize100k, + int verbosity, + int workFactor + ); + +BZ_EXTERN void BZ_API(BZ2_bzWrite) ( + int* bzerror, + BZFILE* b, + void* buf, + int len + ); + +BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( + int* bzerror, + BZFILE* b, + int abandon, + unsigned int* nbytes_in, + unsigned int* nbytes_out + ); + +BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( + int* bzerror, + BZFILE* b, + int abandon, + unsigned int* nbytes_in_lo32, + unsigned int* nbytes_in_hi32, + unsigned int* nbytes_out_lo32, + unsigned int* nbytes_out_hi32 + ); +#endif + + +/*-- Utility functions --*/ + +BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( + char* dest, + unsigned int* destLen, + char* source, + unsigned int sourceLen, + int blockSize100k, + int verbosity, + int workFactor + ); + +BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( + char* dest, + unsigned int* destLen, + char* source, + unsigned int sourceLen, + int small, + int verbosity + ); + + +/*-- + Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp) + to support better zlib compatibility. + This code is not _officially_ part of libbzip2 (yet); + I haven't tested it, documented it, or considered the + threading-safeness of it. + If this code breaks, please contact both Yoshioka and me. +--*/ + +BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) ( + void + ); + +#ifndef BZ_NO_STDIO +BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) ( + const char *path, + const char *mode + ); + +BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) ( + int fd, + const char *mode + ); + +BZ_EXTERN int BZ_API(BZ2_bzread) ( + BZFILE* b, + void* buf, + int len + ); + +BZ_EXTERN int BZ_API(BZ2_bzwrite) ( + BZFILE* b, + void* buf, + int len + ); + +BZ_EXTERN int BZ_API(BZ2_bzflush) ( + BZFILE* b + ); + +BZ_EXTERN void BZ_API(BZ2_bzclose) ( + BZFILE* b + ); + +BZ_EXTERN const char * BZ_API(BZ2_bzerror) ( + BZFILE *b, + int *errnum + ); +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/*-------------------------------------------------------------*/ +/*--- end bzlib.h ---*/ +/*-------------------------------------------------------------*/ diff --git a/StormLib/src/bzip2/bzlib_private.h b/StormLib/src/bzip2/bzlib_private.h new file mode 100644 index 000000000..23427879b --- /dev/null +++ b/StormLib/src/bzip2/bzlib_private.h @@ -0,0 +1,509 @@ + +/*-------------------------------------------------------------*/ +/*--- Private header file for the library. ---*/ +/*--- bzlib_private.h ---*/ +/*-------------------------------------------------------------*/ + +/* ------------------------------------------------------------------ + This file is part of bzip2/libbzip2, a program and library for + lossless, block-sorting data compression. + + bzip2/libbzip2 version 1.0.5 of 10 December 2007 + Copyright (C) 1996-2007 Julian Seward + + Please read the WARNING, DISCLAIMER and PATENTS sections in the + README file. + + This program is released under the terms of the license contained + in the file LICENSE. + ------------------------------------------------------------------ */ + + +#ifndef _BZLIB_PRIVATE_H +#define _BZLIB_PRIVATE_H + +#include + +#ifndef BZ_NO_STDIO +#include +#include +#include +#endif + +#include "bzlib.h" + + + +/*-- General stuff. --*/ + +#define BZ_VERSION "1.0.5, 10-Dec-2007" + +typedef char Char; +typedef unsigned char Bool; +typedef unsigned char UChar; +typedef int Int32; +typedef unsigned int UInt32; +typedef short Int16; +typedef unsigned short UInt16; + +#define True ((Bool)1) +#define False ((Bool)0) + +#ifndef __GNUC__ +#define __inline__ /* */ +#endif + +#ifndef BZ_NO_STDIO + +extern void BZ2_bz__AssertH__fail ( int errcode ); +#define AssertH(cond,errcode) \ + { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); } + +#if BZ_DEBUG +#define AssertD(cond,msg) \ + { if (!(cond)) { \ + fprintf ( stderr, \ + "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\ + exit(1); \ + }} +#else +#define AssertD(cond,msg) /* */ +#endif + +#define VPrintf0(zf) \ + fprintf(stderr,zf) +#define VPrintf1(zf,za1) \ + fprintf(stderr,zf,za1) +#define VPrintf2(zf,za1,za2) \ + fprintf(stderr,zf,za1,za2) +#define VPrintf3(zf,za1,za2,za3) \ + fprintf(stderr,zf,za1,za2,za3) +#define VPrintf4(zf,za1,za2,za3,za4) \ + fprintf(stderr,zf,za1,za2,za3,za4) +#define VPrintf5(zf,za1,za2,za3,za4,za5) \ + fprintf(stderr,zf,za1,za2,za3,za4,za5) + +#else + +extern void bz_internal_error ( int errcode ); +#define AssertH(cond,errcode) \ + { if (!(cond)) bz_internal_error ( errcode ); } +#define AssertD(cond,msg) do { } while (0) +#define VPrintf0(zf) do { } while (0) +#define VPrintf1(zf,za1) do { } while (0) +#define VPrintf2(zf,za1,za2) do { } while (0) +#define VPrintf3(zf,za1,za2,za3) do { } while (0) +#define VPrintf4(zf,za1,za2,za3,za4) do { } while (0) +#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0) + +#endif + + +#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1) +#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp)) + + +/*-- Header bytes. --*/ + +#define BZ_HDR_B 0x42 /* 'B' */ +#define BZ_HDR_Z 0x5a /* 'Z' */ +#define BZ_HDR_h 0x68 /* 'h' */ +#define BZ_HDR_0 0x30 /* '0' */ + +/*-- Constants for the back end. --*/ + +#define BZ_MAX_ALPHA_SIZE 258 +#define BZ_MAX_CODE_LEN 23 + +#define BZ_RUNA 0 +#define BZ_RUNB 1 + +#define BZ_N_GROUPS 6 +#define BZ_G_SIZE 50 +#define BZ_N_ITERS 4 + +#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE)) + + + +/*-- Stuff for randomising repetitive blocks. --*/ + +extern Int32 BZ2_rNums[512]; + +#define BZ_RAND_DECLS \ + Int32 rNToGo; \ + Int32 rTPos \ + +#define BZ_RAND_INIT_MASK \ + s->rNToGo = 0; \ + s->rTPos = 0 \ + +#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0) + +#define BZ_RAND_UPD_MASK \ + if (s->rNToGo == 0) { \ + s->rNToGo = BZ2_rNums[s->rTPos]; \ + s->rTPos++; \ + if (s->rTPos == 512) s->rTPos = 0; \ + } \ + s->rNToGo--; + + + +/*-- Stuff for doing CRCs. --*/ + +extern UInt32 BZ2_crc32Table[256]; + +#define BZ_INITIALISE_CRC(crcVar) \ +{ \ + crcVar = 0xffffffffL; \ +} + +#define BZ_FINALISE_CRC(crcVar) \ +{ \ + crcVar = ~(crcVar); \ +} + +#define BZ_UPDATE_CRC(crcVar,cha) \ +{ \ + crcVar = (crcVar << 8) ^ \ + BZ2_crc32Table[(crcVar >> 24) ^ \ + ((UChar)cha)]; \ +} + + + +/*-- States and modes for compression. --*/ + +#define BZ_M_IDLE 1 +#define BZ_M_RUNNING 2 +#define BZ_M_FLUSHING 3 +#define BZ_M_FINISHING 4 + +#define BZ_S_OUTPUT 1 +#define BZ_S_INPUT 2 + +#define BZ_N_RADIX 2 +#define BZ_N_QSORT 12 +#define BZ_N_SHELL 18 +#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2) + + + + +/*-- Structure holding all the compression-side stuff. --*/ + +typedef + struct { + /* pointer back to the struct bz_stream */ + bz_stream* strm; + + /* mode this stream is in, and whether inputting */ + /* or outputting data */ + Int32 mode; + Int32 state; + + /* remembers avail_in when flush/finish requested */ + UInt32 avail_in_expect; + + /* for doing the block sorting */ + UInt32* arr1; + UInt32* arr2; + UInt32* ftab; + Int32 origPtr; + + /* aliases for arr1 and arr2 */ + UInt32* ptr; + UChar* block; + UInt16* mtfv; + UChar* zbits; + + /* for deciding when to use the fallback sorting algorithm */ + Int32 workFactor; + + /* run-length-encoding of the input */ + UInt32 state_in_ch; + Int32 state_in_len; + BZ_RAND_DECLS; + + /* input and output limits and current posns */ + Int32 nblock; + Int32 nblockMAX; + Int32 numZ; + Int32 state_out_pos; + + /* map of bytes used in block */ + Int32 nInUse; + Bool inUse[256]; + UChar unseqToSeq[256]; + + /* the buffer for bit stream creation */ + UInt32 bsBuff; + Int32 bsLive; + + /* block and combined CRCs */ + UInt32 blockCRC; + UInt32 combinedCRC; + + /* misc administratium */ + Int32 verbosity; + Int32 blockNo; + Int32 blockSize100k; + + /* stuff for coding the MTF values */ + Int32 nMTF; + Int32 mtfFreq [BZ_MAX_ALPHA_SIZE]; + UChar selector [BZ_MAX_SELECTORS]; + UChar selectorMtf[BZ_MAX_SELECTORS]; + + UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; + Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; + Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; + /* second dimension: only 3 needed; 4 makes index calculations faster */ + UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4]; + + } + EState; + + + +/*-- externs for compression. --*/ + +extern void +BZ2_blockSort ( EState* ); + +extern void +BZ2_compressBlock ( EState*, Bool ); + +extern void +BZ2_bsInitWrite ( EState* ); + +extern void +BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 ); + +extern void +BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 ); + + + +/*-- states for decompression. --*/ + +#define BZ_X_IDLE 1 +#define BZ_X_OUTPUT 2 + +#define BZ_X_MAGIC_1 10 +#define BZ_X_MAGIC_2 11 +#define BZ_X_MAGIC_3 12 +#define BZ_X_MAGIC_4 13 +#define BZ_X_BLKHDR_1 14 +#define BZ_X_BLKHDR_2 15 +#define BZ_X_BLKHDR_3 16 +#define BZ_X_BLKHDR_4 17 +#define BZ_X_BLKHDR_5 18 +#define BZ_X_BLKHDR_6 19 +#define BZ_X_BCRC_1 20 +#define BZ_X_BCRC_2 21 +#define BZ_X_BCRC_3 22 +#define BZ_X_BCRC_4 23 +#define BZ_X_RANDBIT 24 +#define BZ_X_ORIGPTR_1 25 +#define BZ_X_ORIGPTR_2 26 +#define BZ_X_ORIGPTR_3 27 +#define BZ_X_MAPPING_1 28 +#define BZ_X_MAPPING_2 29 +#define BZ_X_SELECTOR_1 30 +#define BZ_X_SELECTOR_2 31 +#define BZ_X_SELECTOR_3 32 +#define BZ_X_CODING_1 33 +#define BZ_X_CODING_2 34 +#define BZ_X_CODING_3 35 +#define BZ_X_MTF_1 36 +#define BZ_X_MTF_2 37 +#define BZ_X_MTF_3 38 +#define BZ_X_MTF_4 39 +#define BZ_X_MTF_5 40 +#define BZ_X_MTF_6 41 +#define BZ_X_ENDHDR_2 42 +#define BZ_X_ENDHDR_3 43 +#define BZ_X_ENDHDR_4 44 +#define BZ_X_ENDHDR_5 45 +#define BZ_X_ENDHDR_6 46 +#define BZ_X_CCRC_1 47 +#define BZ_X_CCRC_2 48 +#define BZ_X_CCRC_3 49 +#define BZ_X_CCRC_4 50 + + + +/*-- Constants for the fast MTF decoder. --*/ + +#define MTFA_SIZE 4096 +#define MTFL_SIZE 16 + + + +/*-- Structure holding all the decompression-side stuff. --*/ + +typedef + struct { + /* pointer back to the struct bz_stream */ + bz_stream* strm; + + /* state indicator for this stream */ + Int32 state; + + /* for doing the final run-length decoding */ + UChar state_out_ch; + Int32 state_out_len; + Bool blockRandomised; + BZ_RAND_DECLS; + + /* the buffer for bit stream reading */ + UInt32 bsBuff; + Int32 bsLive; + + /* misc administratium */ + Int32 blockSize100k; + Bool smallDecompress; + Int32 currBlockNo; + Int32 verbosity; + + /* for undoing the Burrows-Wheeler transform */ + Int32 origPtr; + UInt32 tPos; + Int32 k0; + Int32 unzftab[256]; + Int32 nblock_used; + Int32 cftab[257]; + Int32 cftabCopy[257]; + + /* for undoing the Burrows-Wheeler transform (FAST) */ + UInt32 *tt; + + /* for undoing the Burrows-Wheeler transform (SMALL) */ + UInt16 *ll16; + UChar *ll4; + + /* stored and calculated CRCs */ + UInt32 storedBlockCRC; + UInt32 storedCombinedCRC; + UInt32 calculatedBlockCRC; + UInt32 calculatedCombinedCRC; + + /* map of bytes used in block */ + Int32 nInUse; + Bool inUse[256]; + Bool inUse16[16]; + UChar seqToUnseq[256]; + + /* for decoding the MTF values */ + UChar mtfa [MTFA_SIZE]; + Int32 mtfbase[256 / MTFL_SIZE]; + UChar selector [BZ_MAX_SELECTORS]; + UChar selectorMtf[BZ_MAX_SELECTORS]; + UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; + + Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; + Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; + Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; + Int32 minLens[BZ_N_GROUPS]; + + /* save area for scalars in the main decompress code */ + Int32 save_i; + Int32 save_j; + Int32 save_t; + Int32 save_alphaSize; + Int32 save_nGroups; + Int32 save_nSelectors; + Int32 save_EOB; + Int32 save_groupNo; + Int32 save_groupPos; + Int32 save_nextSym; + Int32 save_nblockMAX; + Int32 save_nblock; + Int32 save_es; + Int32 save_N; + Int32 save_curr; + Int32 save_zt; + Int32 save_zn; + Int32 save_zvec; + Int32 save_zj; + Int32 save_gSel; + Int32 save_gMinlen; + Int32* save_gLimit; + Int32* save_gBase; + Int32* save_gPerm; + + } + DState; + + + +/*-- Macros for decompression. --*/ + +#define BZ_GET_FAST(cccc) \ + /* c_tPos is unsigned, hence test < 0 is pointless. */ \ + if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \ + s->tPos = s->tt[s->tPos]; \ + cccc = (UChar)(s->tPos & 0xff); \ + s->tPos >>= 8; + +#define BZ_GET_FAST_C(cccc) \ + /* c_tPos is unsigned, hence test < 0 is pointless. */ \ + if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \ + c_tPos = c_tt[c_tPos]; \ + cccc = (UChar)(c_tPos & 0xff); \ + c_tPos >>= 8; + +#define SET_LL4(i,n) \ + { if (((i) & 0x1) == 0) \ + s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \ + s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \ + } + +#define GET_LL4(i) \ + ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF) + +#define SET_LL(i,n) \ + { s->ll16[i] = (UInt16)(n & 0x0000ffff); \ + SET_LL4(i, n >> 16); \ + } + +#define GET_LL(i) \ + (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16)) + +#define BZ_GET_SMALL(cccc) \ + /* c_tPos is unsigned, hence test < 0 is pointless. */ \ + if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \ + cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \ + s->tPos = GET_LL(s->tPos); + + +/*-- externs for decompression. --*/ + +extern Int32 +BZ2_indexIntoF ( Int32, Int32* ); + +extern Int32 +BZ2_decompress ( DState* ); + +extern void +BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*, + Int32, Int32, Int32 ); + + +#endif + + +/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/ + +#ifdef BZ_NO_STDIO +#ifndef NULL +#define NULL 0 +#endif +#endif + + +/*-------------------------------------------------------------*/ +/*--- end bzlib_private.h ---*/ +/*-------------------------------------------------------------*/ diff --git a/StormLib/src/bzip2/compress.c b/StormLib/src/bzip2/compress.c new file mode 100644 index 000000000..8c80a0797 --- /dev/null +++ b/StormLib/src/bzip2/compress.c @@ -0,0 +1,672 @@ + +/*-------------------------------------------------------------*/ +/*--- Compression machinery (not incl block sorting) ---*/ +/*--- compress.c ---*/ +/*-------------------------------------------------------------*/ + +/* ------------------------------------------------------------------ + This file is part of bzip2/libbzip2, a program and library for + lossless, block-sorting data compression. + + bzip2/libbzip2 version 1.0.5 of 10 December 2007 + Copyright (C) 1996-2007 Julian Seward + + Please read the WARNING, DISCLAIMER and PATENTS sections in the + README file. + + This program is released under the terms of the license contained + in the file LICENSE. + ------------------------------------------------------------------ */ + + +/* CHANGES + 0.9.0 -- original version. + 0.9.0a/b -- no changes in this file. + 0.9.0c -- changed setting of nGroups in sendMTFValues() + so as to do a bit better on small files +*/ + +#include "bzlib_private.h" + + +/*---------------------------------------------------*/ +/*--- Bit stream I/O ---*/ +/*---------------------------------------------------*/ + +/*---------------------------------------------------*/ +void BZ2_bsInitWrite ( EState* s ) +{ + s->bsLive = 0; + s->bsBuff = 0; +} + + +/*---------------------------------------------------*/ +static +void bsFinishWrite ( EState* s ) +{ + while (s->bsLive > 0) { + s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24); + s->numZ++; + s->bsBuff <<= 8; + s->bsLive -= 8; + } +} + + +/*---------------------------------------------------*/ +#define bsNEEDW(nz) \ +{ \ + while (s->bsLive >= 8) { \ + s->zbits[s->numZ] \ + = (UChar)(s->bsBuff >> 24); \ + s->numZ++; \ + s->bsBuff <<= 8; \ + s->bsLive -= 8; \ + } \ +} + + +/*---------------------------------------------------*/ +static +__inline__ +void bsW ( EState* s, Int32 n, UInt32 v ) +{ + bsNEEDW ( n ); + s->bsBuff |= (v << (32 - s->bsLive - n)); + s->bsLive += n; +} + + +/*---------------------------------------------------*/ +static +void bsPutUInt32 ( EState* s, UInt32 u ) +{ + bsW ( s, 8, (u >> 24) & 0xffL ); + bsW ( s, 8, (u >> 16) & 0xffL ); + bsW ( s, 8, (u >> 8) & 0xffL ); + bsW ( s, 8, u & 0xffL ); +} + + +/*---------------------------------------------------*/ +static +void bsPutUChar ( EState* s, UChar c ) +{ + bsW( s, 8, (UInt32)c ); +} + + +/*---------------------------------------------------*/ +/*--- The back end proper ---*/ +/*---------------------------------------------------*/ + +/*---------------------------------------------------*/ +static +void makeMaps_e ( EState* s ) +{ + Int32 i; + s->nInUse = 0; + for (i = 0; i < 256; i++) + if (s->inUse[i]) { + s->unseqToSeq[i] = s->nInUse; + s->nInUse++; + } +} + + +/*---------------------------------------------------*/ +static +void generateMTFValues ( EState* s ) +{ + UChar yy[256]; + Int32 i, j; + Int32 zPend; + Int32 wr; + Int32 EOB; + + /* + After sorting (eg, here), + s->arr1 [ 0 .. s->nblock-1 ] holds sorted order, + and + ((UChar*)s->arr2) [ 0 .. s->nblock-1 ] + holds the original block data. + + The first thing to do is generate the MTF values, + and put them in + ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ]. + Because there are strictly fewer or equal MTF values + than block values, ptr values in this area are overwritten + with MTF values only when they are no longer needed. + + The final compressed bitstream is generated into the + area starting at + (UChar*) (&((UChar*)s->arr2)[s->nblock]) + + These storage aliases are set up in bzCompressInit(), + except for the last one, which is arranged in + compressBlock(). + */ + UInt32* ptr = s->ptr; + UChar* block = s->block; + UInt16* mtfv = s->mtfv; + + makeMaps_e ( s ); + EOB = s->nInUse+1; + + for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0; + + wr = 0; + zPend = 0; + for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i; + + for (i = 0; i < s->nblock; i++) { + UChar ll_i; + AssertD ( wr <= i, "generateMTFValues(1)" ); + j = ptr[i]-1; if (j < 0) j += s->nblock; + ll_i = s->unseqToSeq[block[j]]; + AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" ); + + if (yy[0] == ll_i) { + zPend++; + } else { + + if (zPend > 0) { + zPend--; + while (True) { + if (zPend & 1) { + mtfv[wr] = BZ_RUNB; wr++; + s->mtfFreq[BZ_RUNB]++; + } else { + mtfv[wr] = BZ_RUNA; wr++; + s->mtfFreq[BZ_RUNA]++; + } + if (zPend < 2) break; + zPend = (zPend - 2) / 2; + }; + zPend = 0; + } + { + register UChar rtmp; + register UChar* ryy_j; + register UChar rll_i; + rtmp = yy[1]; + yy[1] = yy[0]; + ryy_j = &(yy[1]); + rll_i = ll_i; + while ( rll_i != rtmp ) { + register UChar rtmp2; + ryy_j++; + rtmp2 = rtmp; + rtmp = *ryy_j; + *ryy_j = rtmp2; + }; + yy[0] = rtmp; + j = ryy_j - &(yy[0]); + mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++; + } + + } + } + + if (zPend > 0) { + zPend--; + while (True) { + if (zPend & 1) { + mtfv[wr] = BZ_RUNB; wr++; + s->mtfFreq[BZ_RUNB]++; + } else { + mtfv[wr] = BZ_RUNA; wr++; + s->mtfFreq[BZ_RUNA]++; + } + if (zPend < 2) break; + zPend = (zPend - 2) / 2; + }; + zPend = 0; + } + + mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++; + + s->nMTF = wr; +} + + +/*---------------------------------------------------*/ +#define BZ_LESSER_ICOST 0 +#define BZ_GREATER_ICOST 15 + +static +void sendMTFValues ( EState* s ) +{ + Int32 v, t, i, j, gs, ge, totc, bt, bc, iter; + Int32 nSelectors, alphaSize, minLen, maxLen, selCtr; + Int32 nGroups, nBytes; + + /*-- + UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; + is a global since the decoder also needs it. + + Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; + Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; + are also globals only used in this proc. + Made global to keep stack frame size small. + --*/ + + + UInt16 cost[BZ_N_GROUPS]; + Int32 fave[BZ_N_GROUPS]; + + UInt16* mtfv = s->mtfv; + + if (s->verbosity >= 3) + VPrintf3( " %d in block, %d after MTF & 1-2 coding, " + "%d+2 syms in use\n", + s->nblock, s->nMTF, s->nInUse ); + + alphaSize = s->nInUse+2; + for (t = 0; t < BZ_N_GROUPS; t++) + for (v = 0; v < alphaSize; v++) + s->len[t][v] = BZ_GREATER_ICOST; + + /*--- Decide how many coding tables to use ---*/ + AssertH ( s->nMTF > 0, 3001 ); + if (s->nMTF < 200) nGroups = 2; else + if (s->nMTF < 600) nGroups = 3; else + if (s->nMTF < 1200) nGroups = 4; else + if (s->nMTF < 2400) nGroups = 5; else + nGroups = 6; + + /*--- Generate an initial set of coding tables ---*/ + { + Int32 nPart, remF, tFreq, aFreq; + + nPart = nGroups; + remF = s->nMTF; + gs = 0; + while (nPart > 0) { + tFreq = remF / nPart; + ge = gs-1; + aFreq = 0; + while (aFreq < tFreq && ge < alphaSize-1) { + ge++; + aFreq += s->mtfFreq[ge]; + } + + if (ge > gs + && nPart != nGroups && nPart != 1 + && ((nGroups-nPart) % 2 == 1)) { + aFreq -= s->mtfFreq[ge]; + ge--; + } + + if (s->verbosity >= 3) + VPrintf5( " initial group %d, [%d .. %d], " + "has %d syms (%4.1f%%)\n", + nPart, gs, ge, aFreq, + (100.0 * (float)aFreq) / (float)(s->nMTF) ); + + for (v = 0; v < alphaSize; v++) + if (v >= gs && v <= ge) + s->len[nPart-1][v] = BZ_LESSER_ICOST; else + s->len[nPart-1][v] = BZ_GREATER_ICOST; + + nPart--; + gs = ge+1; + remF -= aFreq; + } + } + + /*--- + Iterate up to BZ_N_ITERS times to improve the tables. + ---*/ + for (iter = 0; iter < BZ_N_ITERS; iter++) { + + for (t = 0; t < nGroups; t++) fave[t] = 0; + + for (t = 0; t < nGroups; t++) + for (v = 0; v < alphaSize; v++) + s->rfreq[t][v] = 0; + + /*--- + Set up an auxiliary length table which is used to fast-track + the common case (nGroups == 6). + ---*/ + if (nGroups == 6) { + for (v = 0; v < alphaSize; v++) { + s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v]; + s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v]; + s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v]; + } + } + + nSelectors = 0; + totc = 0; + gs = 0; + while (True) { + + /*--- Set group start & end marks. --*/ + if (gs >= s->nMTF) break; + ge = gs + BZ_G_SIZE - 1; + if (ge >= s->nMTF) ge = s->nMTF-1; + + /*-- + Calculate the cost of this group as coded + by each of the coding tables. + --*/ + for (t = 0; t < nGroups; t++) cost[t] = 0; + + if (nGroups == 6 && 50 == ge-gs+1) { + /*--- fast track the common case ---*/ + register UInt32 cost01, cost23, cost45; + register UInt16 icv; + cost01 = cost23 = cost45 = 0; + +# define BZ_ITER(nn) \ + icv = mtfv[gs+(nn)]; \ + cost01 += s->len_pack[icv][0]; \ + cost23 += s->len_pack[icv][1]; \ + cost45 += s->len_pack[icv][2]; \ + + BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4); + BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9); + BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14); + BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19); + BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24); + BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29); + BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34); + BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39); + BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44); + BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49); + +# undef BZ_ITER + + cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16; + cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16; + cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16; + + } else { + /*--- slow version which correctly handles all situations ---*/ + for (i = gs; i <= ge; i++) { + UInt16 icv = mtfv[i]; + for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv]; + } + } + + /*-- + Find the coding table which is best for this group, + and record its identity in the selector table. + --*/ + bc = 999999999; bt = -1; + for (t = 0; t < nGroups; t++) + if (cost[t] < bc) { bc = cost[t]; bt = t; }; + totc += bc; + fave[bt]++; + s->selector[nSelectors] = bt; + nSelectors++; + + /*-- + Increment the symbol frequencies for the selected table. + --*/ + if (nGroups == 6 && 50 == ge-gs+1) { + /*--- fast track the common case ---*/ + +# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++ + + BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4); + BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9); + BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14); + BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19); + BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24); + BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29); + BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34); + BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39); + BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44); + BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49); + +# undef BZ_ITUR + + } else { + /*--- slow version which correctly handles all situations ---*/ + for (i = gs; i <= ge; i++) + s->rfreq[bt][ mtfv[i] ]++; + } + + gs = ge+1; + } + if (s->verbosity >= 3) { + VPrintf2 ( " pass %d: size is %d, grp uses are ", + iter+1, totc/8 ); + for (t = 0; t < nGroups; t++) + VPrintf1 ( "%d ", fave[t] ); + VPrintf0 ( "\n" ); + } + + /*-- + Recompute the tables based on the accumulated frequencies. + --*/ + /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See + comment in huffman.c for details. */ + for (t = 0; t < nGroups; t++) + BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), + alphaSize, 17 /*20*/ ); + } + + + AssertH( nGroups < 8, 3002 ); + AssertH( nSelectors < 32768 && + nSelectors <= (2 + (900000 / BZ_G_SIZE)), + 3003 ); + + + /*--- Compute MTF values for the selectors. ---*/ + { + UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp; + for (i = 0; i < nGroups; i++) pos[i] = i; + for (i = 0; i < nSelectors; i++) { + ll_i = s->selector[i]; + j = 0; + tmp = pos[j]; + while ( ll_i != tmp ) { + j++; + tmp2 = tmp; + tmp = pos[j]; + pos[j] = tmp2; + }; + pos[0] = tmp; + s->selectorMtf[i] = j; + } + }; + + /*--- Assign actual codes for the tables. --*/ + for (t = 0; t < nGroups; t++) { + minLen = 32; + maxLen = 0; + for (i = 0; i < alphaSize; i++) { + if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; + if (s->len[t][i] < minLen) minLen = s->len[t][i]; + } + AssertH ( !(maxLen > 17 /*20*/ ), 3004 ); + AssertH ( !(minLen < 1), 3005 ); + BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), + minLen, maxLen, alphaSize ); + } + + /*--- Transmit the mapping table. ---*/ + { + Bool inUse16[16]; + for (i = 0; i < 16; i++) { + inUse16[i] = False; + for (j = 0; j < 16; j++) + if (s->inUse[i * 16 + j]) inUse16[i] = True; + } + + nBytes = s->numZ; + for (i = 0; i < 16; i++) + if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0); + + for (i = 0; i < 16; i++) + if (inUse16[i]) + for (j = 0; j < 16; j++) { + if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0); + } + + if (s->verbosity >= 3) + VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes ); + } + + /*--- Now the selectors. ---*/ + nBytes = s->numZ; + bsW ( s, 3, nGroups ); + bsW ( s, 15, nSelectors ); + for (i = 0; i < nSelectors; i++) { + for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1); + bsW(s,1,0); + } + if (s->verbosity >= 3) + VPrintf1( "selectors %d, ", s->numZ-nBytes ); + + /*--- Now the coding tables. ---*/ + nBytes = s->numZ; + + for (t = 0; t < nGroups; t++) { + Int32 curr = s->len[t][0]; + bsW ( s, 5, curr ); + for (i = 0; i < alphaSize; i++) { + while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ }; + while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ }; + bsW ( s, 1, 0 ); + } + } + + if (s->verbosity >= 3) + VPrintf1 ( "code lengths %d, ", s->numZ-nBytes ); + + /*--- And finally, the block data proper ---*/ + nBytes = s->numZ; + selCtr = 0; + gs = 0; + while (True) { + if (gs >= s->nMTF) break; + ge = gs + BZ_G_SIZE - 1; + if (ge >= s->nMTF) ge = s->nMTF-1; + AssertH ( s->selector[selCtr] < nGroups, 3006 ); + + if (nGroups == 6 && 50 == ge-gs+1) { + /*--- fast track the common case ---*/ + UInt16 mtfv_i; + UChar* s_len_sel_selCtr + = &(s->len[s->selector[selCtr]][0]); + Int32* s_code_sel_selCtr + = &(s->code[s->selector[selCtr]][0]); + +# define BZ_ITAH(nn) \ + mtfv_i = mtfv[gs+(nn)]; \ + bsW ( s, \ + s_len_sel_selCtr[mtfv_i], \ + s_code_sel_selCtr[mtfv_i] ) + + BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4); + BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9); + BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14); + BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19); + BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24); + BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29); + BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34); + BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39); + BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44); + BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49); + +# undef BZ_ITAH + + } else { + /*--- slow version which correctly handles all situations ---*/ + for (i = gs; i <= ge; i++) { + bsW ( s, + s->len [s->selector[selCtr]] [mtfv[i]], + s->code [s->selector[selCtr]] [mtfv[i]] ); + } + } + + + gs = ge+1; + selCtr++; + } + AssertH( selCtr == nSelectors, 3007 ); + + if (s->verbosity >= 3) + VPrintf1( "codes %d\n", s->numZ-nBytes ); +} + + +/*---------------------------------------------------*/ +void BZ2_compressBlock ( EState* s, Bool is_last_block ) +{ + if (s->nblock > 0) { + + BZ_FINALISE_CRC ( s->blockCRC ); + s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31); + s->combinedCRC ^= s->blockCRC; + if (s->blockNo > 1) s->numZ = 0; + + if (s->verbosity >= 2) + VPrintf4( " block %d: crc = 0x%08x, " + "combined CRC = 0x%08x, size = %d\n", + s->blockNo, s->blockCRC, s->combinedCRC, s->nblock ); + + BZ2_blockSort ( s ); + } + + s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]); + + /*-- If this is the first block, create the stream header. --*/ + if (s->blockNo == 1) { + BZ2_bsInitWrite ( s ); + bsPutUChar ( s, BZ_HDR_B ); + bsPutUChar ( s, BZ_HDR_Z ); + bsPutUChar ( s, BZ_HDR_h ); + bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) ); + } + + if (s->nblock > 0) { + + bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 ); + bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 ); + bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 ); + + /*-- Now the block's CRC, so it is in a known place. --*/ + bsPutUInt32 ( s, s->blockCRC ); + + /*-- + Now a single bit indicating (non-)randomisation. + As of version 0.9.5, we use a better sorting algorithm + which makes randomisation unnecessary. So always set + the randomised bit to 'no'. Of course, the decoder + still needs to be able to handle randomised blocks + so as to maintain backwards compatibility with + older versions of bzip2. + --*/ + bsW(s,1,0); + + bsW ( s, 24, s->origPtr ); + generateMTFValues ( s ); + sendMTFValues ( s ); + } + + + /*-- If this is the last block, add the stream trailer. --*/ + if (is_last_block) { + + bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 ); + bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 ); + bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 ); + bsPutUInt32 ( s, s->combinedCRC ); + if (s->verbosity >= 2) + VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC ); + bsFinishWrite ( s ); + } +} + + +/*-------------------------------------------------------------*/ +/*--- end compress.c ---*/ +/*-------------------------------------------------------------*/ diff --git a/StormLib/src/bzip2/crctable.c b/StormLib/src/bzip2/crctable.c new file mode 100644 index 000000000..215687b2c --- /dev/null +++ b/StormLib/src/bzip2/crctable.c @@ -0,0 +1,104 @@ + +/*-------------------------------------------------------------*/ +/*--- Table for doing CRCs ---*/ +/*--- crctable.c ---*/ +/*-------------------------------------------------------------*/ + +/* ------------------------------------------------------------------ + This file is part of bzip2/libbzip2, a program and library for + lossless, block-sorting data compression. + + bzip2/libbzip2 version 1.0.5 of 10 December 2007 + Copyright (C) 1996-2007 Julian Seward + + Please read the WARNING, DISCLAIMER and PATENTS sections in the + README file. + + This program is released under the terms of the license contained + in the file LICENSE. + ------------------------------------------------------------------ */ + + +#include "bzlib_private.h" + +/*-- + I think this is an implementation of the AUTODIN-II, + Ethernet & FDDI 32-bit CRC standard. Vaguely derived + from code by Rob Warnock, in Section 51 of the + comp.compression FAQ. +--*/ + +UInt32 BZ2_crc32Table[256] = { + + /*-- Ugly, innit? --*/ + + 0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L, + 0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L, + 0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L, + 0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL, + 0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L, + 0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L, + 0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L, + 0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL, + 0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L, + 0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L, + 0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L, + 0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL, + 0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L, + 0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L, + 0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L, + 0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL, + 0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL, + 0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L, + 0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L, + 0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL, + 0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL, + 0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L, + 0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L, + 0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL, + 0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL, + 0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L, + 0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L, + 0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL, + 0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL, + 0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L, + 0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L, + 0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL, + 0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L, + 0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL, + 0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL, + 0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L, + 0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L, + 0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL, + 0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL, + 0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L, + 0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L, + 0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL, + 0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL, + 0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L, + 0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L, + 0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL, + 0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL, + 0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L, + 0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L, + 0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL, + 0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L, + 0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L, + 0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L, + 0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL, + 0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L, + 0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L, + 0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L, + 0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL, + 0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L, + 0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L, + 0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L, + 0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL, + 0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L, + 0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L +}; + + +/*-------------------------------------------------------------*/ +/*--- end crctable.c ---*/ +/*-------------------------------------------------------------*/ diff --git a/StormLib/src/bzip2/decompress.c b/StormLib/src/bzip2/decompress.c new file mode 100644 index 000000000..bba5e0fa3 --- /dev/null +++ b/StormLib/src/bzip2/decompress.c @@ -0,0 +1,626 @@ + +/*-------------------------------------------------------------*/ +/*--- Decompression machinery ---*/ +/*--- decompress.c ---*/ +/*-------------------------------------------------------------*/ + +/* ------------------------------------------------------------------ + This file is part of bzip2/libbzip2, a program and library for + lossless, block-sorting data compression. + + bzip2/libbzip2 version 1.0.5 of 10 December 2007 + Copyright (C) 1996-2007 Julian Seward + + Please read the WARNING, DISCLAIMER and PATENTS sections in the + README file. + + This program is released under the terms of the license contained + in the file LICENSE. + ------------------------------------------------------------------ */ + + +#include "bzlib_private.h" + + +/*---------------------------------------------------*/ +static +void makeMaps_d ( DState* s ) +{ + Int32 i; + s->nInUse = 0; + for (i = 0; i < 256; i++) + if (s->inUse[i]) { + s->seqToUnseq[s->nInUse] = i; + s->nInUse++; + } +} + + +/*---------------------------------------------------*/ +#define RETURN(rrr) \ + { retVal = rrr; goto save_state_and_return; }; + +#define GET_BITS(lll,vvv,nnn) \ + case lll: s->state = lll; \ + while (True) { \ + if (s->bsLive >= nnn) { \ + UInt32 v; \ + v = (s->bsBuff >> \ + (s->bsLive-nnn)) & ((1 << nnn)-1); \ + s->bsLive -= nnn; \ + vvv = v; \ + break; \ + } \ + if (s->strm->avail_in == 0) RETURN(BZ_OK); \ + s->bsBuff \ + = (s->bsBuff << 8) | \ + ((UInt32) \ + (*((UChar*)(s->strm->next_in)))); \ + s->bsLive += 8; \ + s->strm->next_in++; \ + s->strm->avail_in--; \ + s->strm->total_in_lo32++; \ + if (s->strm->total_in_lo32 == 0) \ + s->strm->total_in_hi32++; \ + } + +#define GET_UCHAR(lll,uuu) \ + GET_BITS(lll,uuu,8) + +#define GET_BIT(lll,uuu) \ + GET_BITS(lll,uuu,1) + +/*---------------------------------------------------*/ +#define GET_MTF_VAL(label1,label2,lval) \ +{ \ + if (groupPos == 0) { \ + groupNo++; \ + if (groupNo >= nSelectors) \ + RETURN(BZ_DATA_ERROR); \ + groupPos = BZ_G_SIZE; \ + gSel = s->selector[groupNo]; \ + gMinlen = s->minLens[gSel]; \ + gLimit = &(s->limit[gSel][0]); \ + gPerm = &(s->perm[gSel][0]); \ + gBase = &(s->base[gSel][0]); \ + } \ + groupPos--; \ + zn = gMinlen; \ + GET_BITS(label1, zvec, zn); \ + while (1) { \ + if (zn > 20 /* the longest code */) \ + RETURN(BZ_DATA_ERROR); \ + if (zvec <= gLimit[zn]) break; \ + zn++; \ + GET_BIT(label2, zj); \ + zvec = (zvec << 1) | zj; \ + }; \ + if (zvec - gBase[zn] < 0 \ + || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \ + RETURN(BZ_DATA_ERROR); \ + lval = gPerm[zvec - gBase[zn]]; \ +} + + +/*---------------------------------------------------*/ +Int32 BZ2_decompress ( DState* s ) +{ + UChar uc; + Int32 retVal; + Int32 minLen, maxLen; + bz_stream* strm = s->strm; + + /* stuff that needs to be saved/restored */ + Int32 i; + Int32 j; + Int32 t; + Int32 alphaSize; + Int32 nGroups; + Int32 nSelectors; + Int32 EOB; + Int32 groupNo; + Int32 groupPos; + Int32 nextSym; + Int32 nblockMAX; + Int32 nblock; + Int32 es; + Int32 N; + Int32 curr; + Int32 zt; + Int32 zn; + Int32 zvec; + Int32 zj; + Int32 gSel; + Int32 gMinlen; + Int32* gLimit; + Int32* gBase; + Int32* gPerm; + + if (s->state == BZ_X_MAGIC_1) { + /*initialise the save area*/ + s->save_i = 0; + s->save_j = 0; + s->save_t = 0; + s->save_alphaSize = 0; + s->save_nGroups = 0; + s->save_nSelectors = 0; + s->save_EOB = 0; + s->save_groupNo = 0; + s->save_groupPos = 0; + s->save_nextSym = 0; + s->save_nblockMAX = 0; + s->save_nblock = 0; + s->save_es = 0; + s->save_N = 0; + s->save_curr = 0; + s->save_zt = 0; + s->save_zn = 0; + s->save_zvec = 0; + s->save_zj = 0; + s->save_gSel = 0; + s->save_gMinlen = 0; + s->save_gLimit = NULL; + s->save_gBase = NULL; + s->save_gPerm = NULL; + } + + /*restore from the save area*/ + i = s->save_i; + j = s->save_j; + t = s->save_t; + alphaSize = s->save_alphaSize; + nGroups = s->save_nGroups; + nSelectors = s->save_nSelectors; + EOB = s->save_EOB; + groupNo = s->save_groupNo; + groupPos = s->save_groupPos; + nextSym = s->save_nextSym; + nblockMAX = s->save_nblockMAX; + nblock = s->save_nblock; + es = s->save_es; + N = s->save_N; + curr = s->save_curr; + zt = s->save_zt; + zn = s->save_zn; + zvec = s->save_zvec; + zj = s->save_zj; + gSel = s->save_gSel; + gMinlen = s->save_gMinlen; + gLimit = s->save_gLimit; + gBase = s->save_gBase; + gPerm = s->save_gPerm; + + retVal = BZ_OK; + + switch (s->state) { + + GET_UCHAR(BZ_X_MAGIC_1, uc); + if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC); + + GET_UCHAR(BZ_X_MAGIC_2, uc); + if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC); + + GET_UCHAR(BZ_X_MAGIC_3, uc) + if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC); + + GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8) + if (s->blockSize100k < (BZ_HDR_0 + 1) || + s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC); + s->blockSize100k -= BZ_HDR_0; + + if (s->smallDecompress) { + s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) ); + s->ll4 = BZALLOC( + ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) + ); + if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR); + } else { + s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) ); + if (s->tt == NULL) RETURN(BZ_MEM_ERROR); + } + + GET_UCHAR(BZ_X_BLKHDR_1, uc); + + if (uc == 0x17) goto endhdr_2; + if (uc != 0x31) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_BLKHDR_2, uc); + if (uc != 0x41) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_BLKHDR_3, uc); + if (uc != 0x59) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_BLKHDR_4, uc); + if (uc != 0x26) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_BLKHDR_5, uc); + if (uc != 0x53) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_BLKHDR_6, uc); + if (uc != 0x59) RETURN(BZ_DATA_ERROR); + + s->currBlockNo++; + if (s->verbosity >= 2) + VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo ); + + s->storedBlockCRC = 0; + GET_UCHAR(BZ_X_BCRC_1, uc); + s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_BCRC_2, uc); + s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_BCRC_3, uc); + s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_BCRC_4, uc); + s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); + + GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1); + + s->origPtr = 0; + GET_UCHAR(BZ_X_ORIGPTR_1, uc); + s->origPtr = (s->origPtr << 8) | ((Int32)uc); + GET_UCHAR(BZ_X_ORIGPTR_2, uc); + s->origPtr = (s->origPtr << 8) | ((Int32)uc); + GET_UCHAR(BZ_X_ORIGPTR_3, uc); + s->origPtr = (s->origPtr << 8) | ((Int32)uc); + + if (s->origPtr < 0) + RETURN(BZ_DATA_ERROR); + if (s->origPtr > 10 + 100000*s->blockSize100k) + RETURN(BZ_DATA_ERROR); + + /*--- Receive the mapping table ---*/ + for (i = 0; i < 16; i++) { + GET_BIT(BZ_X_MAPPING_1, uc); + if (uc == 1) + s->inUse16[i] = True; else + s->inUse16[i] = False; + } + + for (i = 0; i < 256; i++) s->inUse[i] = False; + + for (i = 0; i < 16; i++) + if (s->inUse16[i]) + for (j = 0; j < 16; j++) { + GET_BIT(BZ_X_MAPPING_2, uc); + if (uc == 1) s->inUse[i * 16 + j] = True; + } + makeMaps_d ( s ); + if (s->nInUse == 0) RETURN(BZ_DATA_ERROR); + alphaSize = s->nInUse+2; + + /*--- Now the selectors ---*/ + GET_BITS(BZ_X_SELECTOR_1, nGroups, 3); + if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR); + GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15); + if (nSelectors < 1) RETURN(BZ_DATA_ERROR); + for (i = 0; i < nSelectors; i++) { + j = 0; + while (True) { + GET_BIT(BZ_X_SELECTOR_3, uc); + if (uc == 0) break; + j++; + if (j >= nGroups) RETURN(BZ_DATA_ERROR); + } + s->selectorMtf[i] = j; + } + + /*--- Undo the MTF values for the selectors. ---*/ + { + UChar pos[BZ_N_GROUPS], tmp, v; + for (v = 0; v < nGroups; v++) pos[v] = v; + + for (i = 0; i < nSelectors; i++) { + v = s->selectorMtf[i]; + tmp = pos[v]; + while (v > 0) { pos[v] = pos[v-1]; v--; } + pos[0] = tmp; + s->selector[i] = tmp; + } + } + + /*--- Now the coding tables ---*/ + for (t = 0; t < nGroups; t++) { + GET_BITS(BZ_X_CODING_1, curr, 5); + for (i = 0; i < alphaSize; i++) { + while (True) { + if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR); + GET_BIT(BZ_X_CODING_2, uc); + if (uc == 0) break; + GET_BIT(BZ_X_CODING_3, uc); + if (uc == 0) curr++; else curr--; + } + s->len[t][i] = curr; + } + } + + /*--- Create the Huffman decoding tables ---*/ + for (t = 0; t < nGroups; t++) { + minLen = 32; + maxLen = 0; + for (i = 0; i < alphaSize; i++) { + if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; + if (s->len[t][i] < minLen) minLen = s->len[t][i]; + } + BZ2_hbCreateDecodeTables ( + &(s->limit[t][0]), + &(s->base[t][0]), + &(s->perm[t][0]), + &(s->len[t][0]), + minLen, maxLen, alphaSize + ); + s->minLens[t] = minLen; + } + + /*--- Now the MTF values ---*/ + + EOB = s->nInUse+1; + nblockMAX = 100000 * s->blockSize100k; + groupNo = -1; + groupPos = 0; + + for (i = 0; i <= 255; i++) s->unzftab[i] = 0; + + /*-- MTF init --*/ + { + Int32 ii, jj, kk; + kk = MTFA_SIZE-1; + for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) { + for (jj = MTFL_SIZE-1; jj >= 0; jj--) { + s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj); + kk--; + } + s->mtfbase[ii] = kk + 1; + } + } + /*-- end MTF init --*/ + + nblock = 0; + GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym); + + while (True) { + + if (nextSym == EOB) break; + + if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) { + + es = -1; + N = 1; + do { + if (nextSym == BZ_RUNA) es = es + (0+1) * N; else + if (nextSym == BZ_RUNB) es = es + (1+1) * N; + N = N * 2; + GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym); + } + while (nextSym == BZ_RUNA || nextSym == BZ_RUNB); + + es++; + uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ]; + s->unzftab[uc] += es; + + if (s->smallDecompress) + while (es > 0) { + if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); + s->ll16[nblock] = (UInt16)uc; + nblock++; + es--; + } + else + while (es > 0) { + if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); + s->tt[nblock] = (UInt32)uc; + nblock++; + es--; + }; + + continue; + + } else { + + if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); + + /*-- uc = MTF ( nextSym-1 ) --*/ + { + Int32 ii, jj, kk, pp, lno, off; + UInt32 nn; + nn = (UInt32)(nextSym - 1); + + if (nn < MTFL_SIZE) { + /* avoid general-case expense */ + pp = s->mtfbase[0]; + uc = s->mtfa[pp+nn]; + while (nn > 3) { + Int32 z = pp+nn; + s->mtfa[(z) ] = s->mtfa[(z)-1]; + s->mtfa[(z)-1] = s->mtfa[(z)-2]; + s->mtfa[(z)-2] = s->mtfa[(z)-3]; + s->mtfa[(z)-3] = s->mtfa[(z)-4]; + nn -= 4; + } + while (nn > 0) { + s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; + }; + s->mtfa[pp] = uc; + } else { + /* general case */ + lno = nn / MTFL_SIZE; + off = nn % MTFL_SIZE; + pp = s->mtfbase[lno] + off; + uc = s->mtfa[pp]; + while (pp > s->mtfbase[lno]) { + s->mtfa[pp] = s->mtfa[pp-1]; pp--; + }; + s->mtfbase[lno]++; + while (lno > 0) { + s->mtfbase[lno]--; + s->mtfa[s->mtfbase[lno]] + = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1]; + lno--; + } + s->mtfbase[0]--; + s->mtfa[s->mtfbase[0]] = uc; + if (s->mtfbase[0] == 0) { + kk = MTFA_SIZE-1; + for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) { + for (jj = MTFL_SIZE-1; jj >= 0; jj--) { + s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj]; + kk--; + } + s->mtfbase[ii] = kk + 1; + } + } + } + } + /*-- end uc = MTF ( nextSym-1 ) --*/ + + s->unzftab[s->seqToUnseq[uc]]++; + if (s->smallDecompress) + s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else + s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]); + nblock++; + + GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym); + continue; + } + } + + /* Now we know what nblock is, we can do a better sanity + check on s->origPtr. + */ + if (s->origPtr < 0 || s->origPtr >= nblock) + RETURN(BZ_DATA_ERROR); + + /*-- Set up cftab to facilitate generation of T^(-1) --*/ + s->cftab[0] = 0; + for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1]; + for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1]; + for (i = 0; i <= 256; i++) { + if (s->cftab[i] < 0 || s->cftab[i] > nblock) { + /* s->cftab[i] can legitimately be == nblock */ + RETURN(BZ_DATA_ERROR); + } + } + + s->state_out_len = 0; + s->state_out_ch = 0; + BZ_INITIALISE_CRC ( s->calculatedBlockCRC ); + s->state = BZ_X_OUTPUT; + if (s->verbosity >= 2) VPrintf0 ( "rt+rld" ); + + if (s->smallDecompress) { + + /*-- Make a copy of cftab, used in generation of T --*/ + for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i]; + + /*-- compute the T vector --*/ + for (i = 0; i < nblock; i++) { + uc = (UChar)(s->ll16[i]); + SET_LL(i, s->cftabCopy[uc]); + s->cftabCopy[uc]++; + } + + /*-- Compute T^(-1) by pointer reversal on T --*/ + i = s->origPtr; + j = GET_LL(i); + do { + Int32 tmp = GET_LL(j); + SET_LL(j, i); + i = j; + j = tmp; + } + while (i != s->origPtr); + + s->tPos = s->origPtr; + s->nblock_used = 0; + if (s->blockRandomised) { + BZ_RAND_INIT_MASK; + BZ_GET_SMALL(s->k0); s->nblock_used++; + BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; + } else { + BZ_GET_SMALL(s->k0); s->nblock_used++; + } + + } else { + + /*-- compute the T^(-1) vector --*/ + for (i = 0; i < nblock; i++) { + uc = (UChar)(s->tt[i] & 0xff); + s->tt[s->cftab[uc]] |= (i << 8); + s->cftab[uc]++; + } + + s->tPos = s->tt[s->origPtr] >> 8; + s->nblock_used = 0; + if (s->blockRandomised) { + BZ_RAND_INIT_MASK; + BZ_GET_FAST(s->k0); s->nblock_used++; + BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; + } else { + BZ_GET_FAST(s->k0); s->nblock_used++; + } + + } + + RETURN(BZ_OK); + + + + endhdr_2: + + GET_UCHAR(BZ_X_ENDHDR_2, uc); + if (uc != 0x72) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_ENDHDR_3, uc); + if (uc != 0x45) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_ENDHDR_4, uc); + if (uc != 0x38) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_ENDHDR_5, uc); + if (uc != 0x50) RETURN(BZ_DATA_ERROR); + GET_UCHAR(BZ_X_ENDHDR_6, uc); + if (uc != 0x90) RETURN(BZ_DATA_ERROR); + + s->storedCombinedCRC = 0; + GET_UCHAR(BZ_X_CCRC_1, uc); + s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_CCRC_2, uc); + s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_CCRC_3, uc); + s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); + GET_UCHAR(BZ_X_CCRC_4, uc); + s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); + + s->state = BZ_X_IDLE; + RETURN(BZ_STREAM_END); + + default: AssertH ( False, 4001 ); + } + + AssertH ( False, 4002 ); + + save_state_and_return: + + s->save_i = i; + s->save_j = j; + s->save_t = t; + s->save_alphaSize = alphaSize; + s->save_nGroups = nGroups; + s->save_nSelectors = nSelectors; + s->save_EOB = EOB; + s->save_groupNo = groupNo; + s->save_groupPos = groupPos; + s->save_nextSym = nextSym; + s->save_nblockMAX = nblockMAX; + s->save_nblock = nblock; + s->save_es = es; + s->save_N = N; + s->save_curr = curr; + s->save_zt = zt; + s->save_zn = zn; + s->save_zvec = zvec; + s->save_zj = zj; + s->save_gSel = gSel; + s->save_gMinlen = gMinlen; + s->save_gLimit = gLimit; + s->save_gBase = gBase; + s->save_gPerm = gPerm; + + return retVal; +} + + +/*-------------------------------------------------------------*/ +/*--- end decompress.c ---*/ +/*-------------------------------------------------------------*/ diff --git a/StormLib/src/bzip2/huffman.c b/StormLib/src/bzip2/huffman.c new file mode 100644 index 000000000..87e79e38a --- /dev/null +++ b/StormLib/src/bzip2/huffman.c @@ -0,0 +1,205 @@ + +/*-------------------------------------------------------------*/ +/*--- Huffman coding low-level stuff ---*/ +/*--- huffman.c ---*/ +/*-------------------------------------------------------------*/ + +/* ------------------------------------------------------------------ + This file is part of bzip2/libbzip2, a program and library for + lossless, block-sorting data compression. + + bzip2/libbzip2 version 1.0.5 of 10 December 2007 + Copyright (C) 1996-2007 Julian Seward + + Please read the WARNING, DISCLAIMER and PATENTS sections in the + README file. + + This program is released under the terms of the license contained + in the file LICENSE. + ------------------------------------------------------------------ */ + + +#include "bzlib_private.h" + +/*---------------------------------------------------*/ +#define WEIGHTOF(zz0) ((zz0) & 0xffffff00) +#define DEPTHOF(zz1) ((zz1) & 0x000000ff) +#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3)) + +#define ADDWEIGHTS(zw1,zw2) \ + (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \ + (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2))) + +#define UPHEAP(z) \ +{ \ + Int32 zz, tmp; \ + zz = z; tmp = heap[zz]; \ + while (weight[tmp] < weight[heap[zz >> 1]]) { \ + heap[zz] = heap[zz >> 1]; \ + zz >>= 1; \ + } \ + heap[zz] = tmp; \ +} + +#define DOWNHEAP(z) \ +{ \ + Int32 zz, yy, tmp; \ + zz = z; tmp = heap[zz]; \ + while (True) { \ + yy = zz << 1; \ + if (yy > nHeap) break; \ + if (yy < nHeap && \ + weight[heap[yy+1]] < weight[heap[yy]]) \ + yy++; \ + if (weight[tmp] < weight[heap[yy]]) break; \ + heap[zz] = heap[yy]; \ + zz = yy; \ + } \ + heap[zz] = tmp; \ +} + + +/*---------------------------------------------------*/ +void BZ2_hbMakeCodeLengths ( UChar *len, + Int32 *freq, + Int32 alphaSize, + Int32 maxLen ) +{ + /*-- + Nodes and heap entries run from 1. Entry 0 + for both the heap and nodes is a sentinel. + --*/ + Int32 nNodes, nHeap, n1, n2, i, j, k; + Bool tooLong; + + Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ]; + Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ]; + Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; + + for (i = 0; i < alphaSize; i++) + weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8; + + while (True) { + + nNodes = alphaSize; + nHeap = 0; + + heap[0] = 0; + weight[0] = 0; + parent[0] = -2; + + for (i = 1; i <= alphaSize; i++) { + parent[i] = -1; + nHeap++; + heap[nHeap] = i; + UPHEAP(nHeap); + } + + AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 ); + + while (nHeap > 1) { + n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); + n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); + nNodes++; + parent[n1] = parent[n2] = nNodes; + weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]); + parent[nNodes] = -1; + nHeap++; + heap[nHeap] = nNodes; + UPHEAP(nHeap); + } + + AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 ); + + tooLong = False; + for (i = 1; i <= alphaSize; i++) { + j = 0; + k = i; + while (parent[k] >= 0) { k = parent[k]; j++; } + len[i-1] = j; + if (j > maxLen) tooLong = True; + } + + if (! tooLong) break; + + /* 17 Oct 04: keep-going condition for the following loop used + to be 'i < alphaSize', which missed the last element, + theoretically leading to the possibility of the compressor + looping. However, this count-scaling step is only needed if + one of the generated Huffman code words is longer than + maxLen, which up to and including version 1.0.2 was 20 bits, + which is extremely unlikely. In version 1.0.3 maxLen was + changed to 17 bits, which has minimal effect on compression + ratio, but does mean this scaling step is used from time to + time, enough to verify that it works. + + This means that bzip2-1.0.3 and later will only produce + Huffman codes with a maximum length of 17 bits. However, in + order to preserve backwards compatibility with bitstreams + produced by versions pre-1.0.3, the decompressor must still + handle lengths of up to 20. */ + + for (i = 1; i <= alphaSize; i++) { + j = weight[i] >> 8; + j = 1 + (j / 2); + weight[i] = j << 8; + } + } +} + + +/*---------------------------------------------------*/ +void BZ2_hbAssignCodes ( Int32 *code, + UChar *length, + Int32 minLen, + Int32 maxLen, + Int32 alphaSize ) +{ + Int32 n, vec, i; + + vec = 0; + for (n = minLen; n <= maxLen; n++) { + for (i = 0; i < alphaSize; i++) + if (length[i] == n) { code[i] = vec; vec++; }; + vec <<= 1; + } +} + + +/*---------------------------------------------------*/ +void BZ2_hbCreateDecodeTables ( Int32 *limit, + Int32 *base, + Int32 *perm, + UChar *length, + Int32 minLen, + Int32 maxLen, + Int32 alphaSize ) +{ + Int32 pp, i, j, vec; + + pp = 0; + for (i = minLen; i <= maxLen; i++) + for (j = 0; j < alphaSize; j++) + if (length[j] == i) { perm[pp] = j; pp++; }; + + for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0; + for (i = 0; i < alphaSize; i++) base[length[i]+1]++; + + for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1]; + + for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0; + vec = 0; + + for (i = minLen; i <= maxLen; i++) { + vec += (base[i+1] - base[i]); + limit[i] = vec-1; + vec <<= 1; + } + for (i = minLen + 1; i <= maxLen; i++) + base[i] = ((limit[i-1] + 1) << 1) - base[i]; +} + + +/*-------------------------------------------------------------*/ +/*--- end huffman.c ---*/ +/*-------------------------------------------------------------*/ diff --git a/StormLib/src/bzip2/randtable.c b/StormLib/src/bzip2/randtable.c new file mode 100644 index 000000000..068b76367 --- /dev/null +++ b/StormLib/src/bzip2/randtable.c @@ -0,0 +1,84 @@ + +/*-------------------------------------------------------------*/ +/*--- Table for randomising repetitive blocks ---*/ +/*--- randtable.c ---*/ +/*-------------------------------------------------------------*/ + +/* ------------------------------------------------------------------ + This file is part of bzip2/libbzip2, a program and library for + lossless, block-sorting data compression. + + bzip2/libbzip2 version 1.0.5 of 10 December 2007 + Copyright (C) 1996-2007 Julian Seward + + Please read the WARNING, DISCLAIMER and PATENTS sections in the + README file. + + This program is released under the terms of the license contained + in the file LICENSE. + ------------------------------------------------------------------ */ + + +#include "bzlib_private.h" + + +/*---------------------------------------------*/ +Int32 BZ2_rNums[512] = { + 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, + 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, + 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, + 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, + 878, 465, 811, 169, 869, 675, 611, 697, 867, 561, + 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, + 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, + 170, 607, 520, 932, 727, 476, 693, 425, 174, 647, + 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, + 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, + 641, 801, 220, 162, 819, 984, 589, 513, 495, 799, + 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, + 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, + 98, 553, 163, 354, 666, 933, 424, 341, 533, 870, + 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, + 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, + 184, 943, 795, 384, 383, 461, 404, 758, 839, 887, + 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, + 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, + 652, 934, 970, 447, 318, 353, 859, 672, 112, 785, + 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, + 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, + 653, 282, 762, 623, 680, 81, 927, 626, 789, 125, + 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, + 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, + 857, 956, 358, 619, 580, 124, 737, 594, 701, 612, + 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, + 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, + 344, 805, 988, 739, 511, 655, 814, 334, 249, 515, + 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, + 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, + 686, 754, 806, 760, 493, 403, 415, 394, 687, 700, + 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, + 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, + 680, 879, 194, 572, 640, 724, 926, 56, 204, 700, + 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, + 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, + 134, 108, 571, 364, 631, 212, 174, 643, 304, 329, + 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, + 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, + 170, 514, 364, 692, 829, 82, 855, 953, 676, 246, + 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, + 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, + 896, 831, 547, 261, 524, 462, 293, 465, 502, 56, + 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, + 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, + 61, 688, 793, 644, 986, 403, 106, 366, 905, 644, + 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, + 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, + 920, 176, 193, 713, 857, 265, 203, 50, 668, 108, + 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, + 936, 638 +}; + + +/*-------------------------------------------------------------*/ +/*--- end randtable.c ---*/ +/*-------------------------------------------------------------*/ diff --git a/StormLib/src/huffman/huff.cpp b/StormLib/src/huffman/huff.cpp new file mode 100644 index 000000000..6930354bb --- /dev/null +++ b/StormLib/src/huffman/huff.cpp @@ -0,0 +1,892 @@ +/*****************************************************************************/ +/* huffman.cpp Copyright (c) Ladislav Zezula 1998-2003 */ +/*---------------------------------------------------------------------------*/ +/* This module contains Huffmann (de)compression methods */ +/* */ +/* Authors : Ladislav Zezula (ladik@zezula.net) */ +/* ShadowFlare (BlakFlare@hotmail.com) */ +/* */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* xx.xx.xx 1.00 Lad The first version of dcmp.cpp */ +/* 03.05.03 1.00 Lad Added compression methods */ +/* 19.11.03 1.01 Dan Big endian handling */ +/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */ +/* 09.01.13 3.00 Lad Refactored, beautified, documented :-) */ +/*****************************************************************************/ + +#include +#include + +#include "huff.h" + +//----------------------------------------------------------------------------- +// Table of byte-to-weight values + +// Table for (de)compression. Every compression type has 258 entries +static unsigned char ByteToWeight_00[] = +{ + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00 +}; + +// Data for compression type 0x01 +static unsigned char ByteToWeight_01[] = +{ + 0x54, 0x16, 0x16, 0x0D, 0x0C, 0x08, 0x06, 0x05, 0x06, 0x05, 0x06, 0x03, 0x04, 0x04, 0x03, 0x05, + 0x0E, 0x0B, 0x14, 0x13, 0x13, 0x09, 0x0B, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, + 0x0D, 0x07, 0x09, 0x06, 0x06, 0x04, 0x03, 0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, + 0x09, 0x06, 0x04, 0x04, 0x04, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04, + 0x08, 0x03, 0x04, 0x07, 0x09, 0x05, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, + 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, + 0x06, 0x0A, 0x08, 0x08, 0x06, 0x07, 0x04, 0x03, 0x04, 0x04, 0x02, 0x02, 0x04, 0x02, 0x03, 0x03, + 0x04, 0x03, 0x07, 0x07, 0x09, 0x06, 0x04, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x0A, 0x02, 0x02, 0x03, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x03, 0x05, 0x02, 0x03, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x09, 0x08, 0x0C, 0x02, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03, + 0x04, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, + 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B, + 0x00, 0x00 +}; + +// Data for compression type 0x02 +static unsigned char ByteToWeight_02[] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x06, 0x0E, 0x10, 0x04, + 0x06, 0x08, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01, + 0x01, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0x02, 0x03, 0x03, 0x02, + 0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01, + 0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A, + 0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +// Data for compression type 0x03 +static unsigned char ByteToWeight_03[] = +{ + 0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03, + 0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, + 0x05, 0x01, 0x01, 0x01, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x0A, 0x04, 0x02, 0x01, 0x06, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, + 0x05, 0x02, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03, + 0x01, 0x03, 0x01, 0x01, 0x02, 0x05, 0x01, 0x01, 0x04, 0x03, 0x05, 0x01, 0x03, 0x01, 0x03, 0x03, + 0x02, 0x01, 0x04, 0x03, 0x0A, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x01, 0x0A, 0x02, 0x05, 0x01, 0x01, 0x02, 0x07, 0x02, 0x17, 0x01, 0x05, 0x01, 0x01, + 0x0E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x06, 0x02, 0x01, 0x04, 0x05, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11, + 0x00, 0x00 +}; + +// Data for compression type 0x04 +static unsigned char ByteToWeight_04[] = +{ + 0xFF, 0xFB, 0x98, 0x9A, 0x84, 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +// Data for compression type 0x05 +static unsigned char ByteToWeight_05[] = +{ + 0xFF, 0xF1, 0x9D, 0x9E, 0x9A, 0x9B, 0x9A, 0x97, 0x93, 0x93, 0x8C, 0x8E, 0x86, 0x88, 0x80, 0x82, + 0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37, + 0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D, + 0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + + // Data for compression type 0x06 +static unsigned char ByteToWeight_06[] = +{ + 0xC3, 0xCB, 0xF5, 0x41, 0xFF, 0x7B, 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBF, 0xCC, 0xF2, 0x40, 0xFD, 0x7C, 0xF7, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +// Data for compression type 0x07 +static unsigned char ByteToWeight_07[] = +{ + 0xC3, 0xD9, 0xEF, 0x3D, 0xF9, 0x7C, 0xE9, 0x1E, 0xFD, 0xAB, 0xF1, 0x2C, 0xFC, 0x5B, 0xFE, 0x17, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBD, 0xD9, 0xEC, 0x3D, 0xF5, 0x7D, 0xE8, 0x1D, 0xFB, 0xAE, 0xF0, 0x2C, 0xFB, 0x5C, 0xFF, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +// Data for compression type 0x08 +static unsigned char ByteToWeight_08[] = +{ + 0xBA, 0xC5, 0xDA, 0x33, 0xE3, 0x6D, 0xD8, 0x18, 0xE5, 0x94, 0xDA, 0x23, 0xDF, 0x4A, 0xD1, 0x10, + 0xEE, 0xAF, 0xE4, 0x2C, 0xEA, 0x5A, 0xDE, 0x15, 0xF4, 0x87, 0xE9, 0x21, 0xF6, 0x43, 0xFC, 0x12, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xB0, 0xC7, 0xD8, 0x33, 0xE3, 0x6B, 0xD6, 0x18, 0xE7, 0x95, 0xD8, 0x23, 0xDB, 0x49, 0xD0, 0x11, + 0xE9, 0xB2, 0xE2, 0x2B, 0xE8, 0x5C, 0xDD, 0x15, 0xF1, 0x87, 0xE7, 0x20, 0xF7, 0x44, 0xFF, 0x13, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5F, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +static unsigned char * WeightTables[0x09] = +{ + ByteToWeight_00, + ByteToWeight_01, + ByteToWeight_02, + ByteToWeight_03, + ByteToWeight_04, + ByteToWeight_05, + ByteToWeight_06, + ByteToWeight_07, + ByteToWeight_08 +}; + +//----------------------------------------------------------------------------- +// Debug/diagnostics + +#ifdef _DEBUG +void DumpHuffmannTree(THTreeItem * pItem) +{ + THTreeItem * pChildLo; // Item with the lower weight + THTreeItem * pChildHi; // Item with the higher weight + + // Get the lower-weight branch + pChildLo = pItem->pChildLo; + if(pChildLo != NULL) + { + // Get the higher-weight branch + pChildHi = pChildLo->pPrev; + + // Parse the lower-weight branch + DumpHuffmannTree(pChildHi); + DumpHuffmannTree(pChildLo); + } +} +#endif + +//----------------------------------------------------------------------------- +// TInputStream functions + +TInputStream::TInputStream(void * pvInBuffer, size_t cbInBuffer) +{ + pbInBufferEnd = (unsigned char *)pvInBuffer + cbInBuffer; + pbInBuffer = (unsigned char *)pvInBuffer; + BitBuffer = 0; + BitCount = 0; +} + +// Gets 7 bits from the stream. DOES NOT remove the bits from input stream +unsigned int TInputStream::Peek7Bits() +{ + unsigned int dwReloadByte = 0; + + // If there is not enough bits to get the value, + // we have to add 8 more bits from the input buffer + if(BitCount < 7) + { + dwReloadByte = *pbInBuffer++; + BitBuffer |= dwReloadByte << BitCount; + BitCount += 8; + } + + // Return the first available 7 bits. DO NOT remove them from the input stream + return (BitBuffer & 0x7F); +} + +// Gets one bit from input stream +unsigned int TInputStream::Get1Bit() +{ + unsigned int OneBit = 0; + + // Ensure that the input stream is reloaded, if there are no bits left + if(BitCount == 0) + { + // Refill the bit buffer + BitBuffer = *pbInBuffer++; + BitCount = 8; + } + + // Copy the bit from bit buffer to the variable + OneBit = (BitBuffer & 0x01); + BitBuffer >>= 1; + BitCount--; + + return OneBit; +} + +// Gets the whole byte from the input stream. +unsigned int TInputStream::Get8Bits() +{ + unsigned int dwReloadByte = 0; + unsigned int dwOneByte = 0; + + // If there is not enough bits to get the value, + // we have to add 8 more bits from the input buffer + if(BitCount < 8) + { + dwReloadByte = *pbInBuffer++; + BitBuffer |= dwReloadByte << BitCount; + BitCount += 8; + } + + // Return the lowest 8 its + dwOneByte = (BitBuffer & 0xFF); + BitBuffer >>= 8; + BitCount -= 8; + return dwOneByte; +} + +void TInputStream::SkipBits(unsigned int dwBitsToSkip) +{ + unsigned int dwReloadByte = 0; + + // If there is not enough bits in the buffer, + // we have to add 8 more bits from the input buffer + if(BitCount < dwBitsToSkip) + { + dwReloadByte = *pbInBuffer++; + BitBuffer |= dwReloadByte << BitCount; + BitCount += 8; + } + + // Skip the remaining bits + BitBuffer >>= dwBitsToSkip; + BitCount -= dwBitsToSkip; +} + +//----------------------------------------------------------------------------- +// TOutputStream functions + +TOutputStream::TOutputStream(void * pvOutBuffer, size_t cbOutLength) +{ + pbOutBufferEnd = (unsigned char *)pvOutBuffer + cbOutLength; + pbOutBuffer = (unsigned char *)pvOutBuffer; + BitBuffer = 0; + BitCount = 0; +} + +void TOutputStream::PutBits(unsigned int dwValue, unsigned int nBitCount) +{ + BitBuffer |= (dwValue << BitCount); + BitCount += nBitCount; + + // Flush completed bytes + while(BitCount >= 8) + { + if(pbOutBuffer < pbOutBufferEnd) + *pbOutBuffer++ = (unsigned char)BitBuffer; + + BitBuffer >>= 8; + BitCount -= 8; + } +} + +void TOutputStream::Flush() +{ + while(BitCount != 0) + { + if(pbOutBuffer < pbOutBufferEnd) + *pbOutBuffer++ = (unsigned char)BitBuffer; + + BitBuffer >>= 8; + BitCount -= ((BitCount > 8) ? 8 : BitCount); + } +} + +//----------------------------------------------------------------------------- +// Methods of the THTreeItem struct + +void THTreeItem::RemoveItem() +{ + if(pNext != NULL) + { + pPrev->pNext = pNext; + pNext->pPrev = pPrev; + pNext = pPrev = NULL; + } +} + +//----------------------------------------------------------------------------- +// THuffmannTree class functions + +THuffmannTree::THuffmannTree(bool bCompression) +{ + pFirst = pLast = LIST_HEAD(); + MinValidValue = 1; + ItemsUsed = 0; + bIsCmp0 = 0; + + memset(ItemsByByte, 0, sizeof(ItemsByByte)); + + // If we are going to decompress data, we need to invalidate all item links + // We do so by zeroing their ValidValue, so it becomes lower MinValidValue + if(bCompression == false) + { + memset(QuickLinks, 0, sizeof(QuickLinks)); + } +} + +THuffmannTree::~THuffmannTree() +{ + // Our Huffmann tree does not use any memory allocations, + // so we don't need to do eny code in the destructor +} + +void THuffmannTree::LinkTwoItems(THTreeItem * pItem1, THTreeItem * pItem2) +{ + pItem2->pNext = pItem1->pNext; + pItem2->pPrev = pItem1->pNext->pPrev; + pItem1->pNext->pPrev = pItem2; + pItem1->pNext = pItem2; +} + +// Inserts item into the tree (?) +void THuffmannTree::InsertItem(THTreeItem * pNewItem, TInsertPoint InsertPoint, THTreeItem * pInsertPoint) +{ + // Remove the item from the tree + pNewItem->RemoveItem(); + + if(pInsertPoint == NULL) + pInsertPoint = LIST_HEAD(); + + switch(InsertPoint) + { + case InsertAfter: + LinkTwoItems(pInsertPoint, pNewItem); + return; + + case InsertBefore: + pNewItem->pNext = pInsertPoint; // Set next item (or pointer to pointer to first item) + pNewItem->pPrev = pInsertPoint->pPrev; // Set prev item (or last item in the tree) + pInsertPoint->pPrev->pNext = pNewItem; + pInsertPoint->pPrev = pNewItem; // Set the next/last item + return; + } +} + +THTreeItem * THuffmannTree::FindHigherOrEqualItem(THTreeItem * pItem, unsigned int Weight) +{ + // Parse all existing items + if(pItem != NULL) + { + while(pItem != LIST_HEAD()) + { + if(pItem->Weight >= Weight) + return pItem; + + pItem = pItem->pPrev; + } + } + + // If not found, we just get the first item + return LIST_HEAD(); +} + +THTreeItem * THuffmannTree::CreateNewItem(unsigned int DecompressedValue, unsigned int Weight, TInsertPoint InsertPoint) +{ + THTreeItem * pNewItem = NULL; + + // Don't let the item buffer run out of space + if(ItemsUsed < HUFF_ITEM_COUNT) + { + // Allocate new item from the item pool + pNewItem = &ItemBuffer[ItemsUsed++]; + + // Insert this item to the top of the tree + InsertItem(pNewItem, InsertPoint, NULL); + + // Fill the rest of the item + pNewItem->DecompressedValue = DecompressedValue; + pNewItem->Weight = Weight; + pNewItem->pParent = NULL; + pNewItem->pChildLo = NULL; + } + + return pNewItem; +} + +unsigned int THuffmannTree::FixupItemPosByWeight(THTreeItem * pNewItem, unsigned int MaxWeight) +{ + THTreeItem * pHigherItem; + + if(pNewItem->Weight < MaxWeight) + { + // Find an item that has higher weight than this one + pHigherItem = FindHigherOrEqualItem(pLast, pNewItem->Weight); + + // Remove the item and put it to the new position + pNewItem->RemoveItem(); + LinkTwoItems(pHigherItem, pNewItem); + } + else + { + MaxWeight = pNewItem->Weight; + } + + // Return the (updated) maximum weight + return MaxWeight; +} + +// Builds Huffman tree. Called with the first 8 bits loaded from input stream +bool THuffmannTree::BuildTree(unsigned int CompressionType) +{ + THTreeItem * pNewItem; + THTreeItem * pChildLo; + THTreeItem * pChildHi; + unsigned char * WeightTable; + unsigned int MaxWeight; // [ESP+10] - The greatest character found in table + + // Clear all pointers in HTree item array + memset(ItemsByByte, 0, sizeof(ItemsByByte)); + MaxWeight = 0; + + // Ensure that the compression type is in range + if((CompressionType & 0x0F) > 0x08) + return false; + WeightTable = WeightTables[CompressionType & 0x0F]; + + // Build the linear list of entries that is sorted by byte weight + for(unsigned int i = 0; i < 0x100; i++) + { + // Skip all the bytes which are zero. + if(WeightTable[i] != 0) + { + // Create new tree item + ItemsByByte[i] = pNewItem = CreateNewItem(i, WeightTable[i], InsertAfter); + + // We need to put the item to the right place in the list + MaxWeight = FixupItemPosByWeight(pNewItem, MaxWeight); + } + } + + // Insert termination entries at the end of the list + ItemsByByte[0x100] = CreateNewItem(0x100, 1, InsertBefore); + ItemsByByte[0x101] = CreateNewItem(0x101, 1, InsertBefore); + + // Now we need to build the tree. We start at the last entry + // and go backwards to the first one + pChildLo = pLast; + + // Work as long as both children are valid + // pChildHi is child with higher weight, pChildLo is the one with lower weight + while(pChildLo != LIST_HEAD()) + { + // Also get and verify the higher-weight child + pChildHi = pChildLo->pPrev; + if(pChildHi == LIST_HEAD()) + break; + + // Create new parent item for the children + pNewItem = CreateNewItem(0, pChildHi->Weight + pChildLo->Weight, InsertAfter); + if(pNewItem == NULL) + return false; + + // Link both child items to their new parent + pChildLo->pParent = pNewItem; + pChildHi->pParent = pNewItem; + pNewItem->pChildLo = pChildLo; + + // Fixup the item's position by its weight + MaxWeight = FixupItemPosByWeight(pNewItem, MaxWeight); + + // Get the previous lower-weight child + pChildLo = pChildHi->pPrev; + } + + // Initialize the MinValidValue to 1, which invalidates all quick-link items + MinValidValue = 1; + return true; +} + +void THuffmannTree::IncWeightsAndRebalance(THTreeItem * pItem) +{ + THTreeItem * pHigherItem; // A previous item with greater or equal weight + THTreeItem * pChildHi; // The higher-weight child + THTreeItem * pChildLo; // The lower-weight child + THTreeItem * pParent; + + // Climb up the tree and increment weight of each tree item + for(; pItem != NULL; pItem = pItem->pParent) + { + // Increment the item's weight + pItem->Weight++; + + // Find a previous item with equal or greater weight, which is not equal to this item + pHigherItem = FindHigherOrEqualItem(pItem->pPrev, pItem->Weight); + pChildHi = pHigherItem->pNext; + + // If the item is not equal to the tree item, we need to rebalance the tree + if(pChildHi != pItem) + { + // Move the previous item to the RIGHT from the given item + pChildHi->RemoveItem(); + LinkTwoItems(pItem, pChildHi); + + // Move the given item AFTER the greater-weight tree item + pItem->RemoveItem(); + LinkTwoItems(pHigherItem, pItem); + + // We need to maintain the tree so that pChildHi->Weight is >= pChildLo->Weight. + // Rebalance the tree accordingly. + pChildLo = pChildHi->pParent->pChildLo; + pParent = pItem->pParent; + if(pParent->pChildLo == pItem) + pParent->pChildLo = pChildHi; + if(pChildLo == pChildHi) + pChildHi->pParent->pChildLo = pItem; + pParent = pItem->pParent; + pItem->pParent = pChildHi->pParent; + pChildHi->pParent = pParent; + + // Increment the global valid value. This invalidates all quick-link items. + MinValidValue++; + } + } +} + +bool THuffmannTree::InsertNewBranchAndRebalance(unsigned int Value1, unsigned int Value2) +{ + THTreeItem * pLastItem = pLast; + THTreeItem * pChildHi; + THTreeItem * pChildLo; + + // Create higher-weight child + pChildHi = CreateNewItem(Value1, pLastItem->Weight, InsertBefore); + if(pChildHi != NULL) + { + pChildHi->pParent = pLastItem; + ItemsByByte[Value1] = pChildHi; + + // Create lower-weight child + pChildLo = CreateNewItem(Value2, 0, InsertBefore); + if(pChildLo != NULL) + { + pChildLo->pParent = pLastItem; + pLastItem->pChildLo = pChildLo; + ItemsByByte[Value2] = pChildLo; + + IncWeightsAndRebalance(pChildLo); + return true; + } + } + + // No more space in the tree buffer + return false; +} + +void THuffmannTree::EncodeOneByte(TOutputStream * os, THTreeItem * pItem) +{ + THTreeItem * pParent = pItem->pParent; + unsigned int BitBuffer = 0; + unsigned int BitCount = 0; + + // Put 1's as long as there is parent + while(pParent != NULL) + { + // Fill the bit buffer + BitBuffer = (BitBuffer << 1) | ((pParent->pChildLo != pItem) ? 1 : 0); + BitCount++; + + // Move to the parent + pItem = pParent; + pParent = pParent->pParent; + } + + // Write the bits to the output stream + os->PutBits(BitBuffer, BitCount); +} + +unsigned int THuffmannTree::DecodeOneByte(TInputStream * is) +{ + THTreeItem * pItemLink = NULL; + THTreeItem * pItem; + unsigned int ItemLinkIndex; + unsigned int BitCount = 0; + + // Check for the end of the input stream + if(is->pbInBuffer >= is->pbInBufferEnd && is->BitCount < 7) + return 0x1FF; + + // Get the eventual quick-link index + ItemLinkIndex = is->Peek7Bits(); + + // Is the quick-link item valid? + if(QuickLinks[ItemLinkIndex].ValidValue > MinValidValue) + { + // If that item needs less than 7 bits, we can get decompressed value directly + if(QuickLinks[ItemLinkIndex].ValidBits <= 7) + { + is->SkipBits(QuickLinks[ItemLinkIndex].ValidBits); + return QuickLinks[ItemLinkIndex].DecompressedValue; + } + + // Otherwise we cannot get decompressed value directly + // but we can skip 7 levels of tree parsing + pItem = QuickLinks[ItemLinkIndex].pItem; + is->SkipBits(7); + } + else + { + // Just a sanity check + if(pFirst == LIST_HEAD()) + return 0x1FF; + + // We don't have the quick-link item, we need to parse the tree from its root + pItem = pFirst; + } + + // Step down the tree until we find a terminal item + while(pItem->pChildLo != NULL) + { + // If the next bit in the compressed stream is set, we get the higher-weight + // child. Otherwise, get the lower-weight child. + pItem = is->Get1Bit() ? pItem->pChildLo->pPrev : pItem->pChildLo; + BitCount++; + + // If the number of loaded bits reached 7, + // remember the current item for storing into quick-link item array + if(BitCount == 7) + pItemLink = pItem; + } + + // If we didn't get the item from the quick-link array, + // set the entry in it + if(QuickLinks[ItemLinkIndex].ValidValue < MinValidValue) + { + // If the current compressed byte was more than 7 bits, + // set a quick-link item with pointer to tree item + if(BitCount > 7) + { + QuickLinks[ItemLinkIndex].ValidValue = MinValidValue; + QuickLinks[ItemLinkIndex].ValidBits = BitCount; + QuickLinks[ItemLinkIndex].pItem = pItemLink; + } + else + { + // Limit the quick-decompress item to lower amount of bits + // Coverity fix 84457: (x >> 32) has undefined behavior + ItemLinkIndex = (BitCount != 0) ? ItemLinkIndex & (0xFFFFFFFF >> (32 - BitCount)) : 0; + while(ItemLinkIndex < LINK_ITEM_COUNT) + { + // Fill the quick-decompress item + QuickLinks[ItemLinkIndex].ValidValue = MinValidValue; + QuickLinks[ItemLinkIndex].ValidBits = BitCount; + QuickLinks[ItemLinkIndex].DecompressedValue = pItem->DecompressedValue; + + // Increment the index + ItemLinkIndex += (1 << BitCount); + } + } + } + + // Return the decompressed value from the found item + return pItem->DecompressedValue; +} + +unsigned int THuffmannTree::Compress(TOutputStream * os, void * pvInBuffer, int cbInBuffer, int CompressionType) +{ + unsigned char * pbInBufferEnd = (unsigned char *)pvInBuffer + cbInBuffer; + unsigned char * pbInBuffer = (unsigned char *)pvInBuffer; + unsigned char * pbOutBuff = os->pbOutBuffer; + unsigned char InputByte; + + if(!BuildTree(CompressionType)) + return 0; + bIsCmp0 = (CompressionType == 0); + + // Store the compression type into output buffer + os->PutBits(CompressionType, 8); + + // Process the entire input buffer + while(pbInBuffer < pbInBufferEnd) + { + // Get the (next) byte from the input buffer + InputByte = *pbInBuffer++; + + // Do we have an item for such input value? + if(ItemsByByte[InputByte] == NULL) + { + // Encode the relationship + EncodeOneByte(os, ItemsByByte[0x101]); + + // Store the loaded byte into output stream + os->PutBits(InputByte, 8); + + if(!InsertNewBranchAndRebalance(pLast->DecompressedValue, InputByte)) + return 0; + + if(bIsCmp0) + { + IncWeightsAndRebalance(ItemsByByte[InputByte]); + continue; + } + + IncWeightsAndRebalance(ItemsByByte[InputByte]); + } + else + { + EncodeOneByte(os, ItemsByByte[InputByte]); + } + + if(bIsCmp0) + { + IncWeightsAndRebalance(ItemsByByte[InputByte]); + } + } + + // Put the termination mark to the compressed stream + EncodeOneByte(os, ItemsByByte[0x100]); + + // Flush the remaining bits + os->Flush(); + return (unsigned int)(os->pbOutBuffer - pbOutBuff); +} + +// Decompression using Huffman tree (1500E450) +unsigned int THuffmannTree::Decompress(void * pvOutBuffer, unsigned int cbOutLength, TInputStream * is) +{ + unsigned char * pbOutBufferEnd = (unsigned char *)pvOutBuffer + cbOutLength; + unsigned char * pbOutBuffer = (unsigned char *)pvOutBuffer; + unsigned int DecompressedValue = 0; + unsigned int CompressionType = 0; + + // Test the output length. Must not be NULL. + if(cbOutLength == 0) + return 0; + + // Get the compression type from the input stream + CompressionType = is->Get8Bits(); + bIsCmp0 = (CompressionType == 0) ? 1 : 0; + + // Build the Huffman tree + if(!BuildTree(CompressionType)) + return 0; + + // Process the entire input buffer until end of the stream + while((DecompressedValue = DecodeOneByte(is)) != 0x100) + { + // Did an error occur? + if(DecompressedValue == 0x1FF) // An error occurred + return 0; + + // Huffman tree needs to be modified + if(DecompressedValue == 0x101) + { + // The decompressed byte is stored in the next 8 bits + DecompressedValue = is->Get8Bits(); + + if(!InsertNewBranchAndRebalance(pLast->DecompressedValue, DecompressedValue)) + return 0; + + if(bIsCmp0 == 0) + IncWeightsAndRebalance(ItemsByByte[DecompressedValue]); + } + + // A byte successfully decoded - store it in the output stream + *pbOutBuffer++ = (unsigned char)DecompressedValue; + if(pbOutBuffer >= pbOutBufferEnd) + break; + + if(bIsCmp0) + { + IncWeightsAndRebalance(ItemsByByte[DecompressedValue]); + } + } + + return (unsigned int)(pbOutBuffer - (unsigned char *)pvOutBuffer); +} + diff --git a/StormLib/src/huffman/huff.h b/StormLib/src/huffman/huff.h new file mode 100644 index 000000000..b75acbb86 --- /dev/null +++ b/StormLib/src/huffman/huff.h @@ -0,0 +1,143 @@ +/*****************************************************************************/ +/* huffman.h Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Description : */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* xx.xx.xx 1.00 Lad The first version of huffman.h */ +/* 03.05.03 2.00 Lad Added compression */ +/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */ +/*****************************************************************************/ + +#ifndef __HUFFMAN_H__ +#define __HUFFMAN_H__ + +//----------------------------------------------------------------------------- +// Defines + +#define HUFF_ITEM_COUNT 0x203 // Number of items in the item pool +#define LINK_ITEM_COUNT 0x80 // Maximum number of quick-link items + +//----------------------------------------------------------------------------- +// Structures and classes + +// Input stream for Huffmann decompression +class TInputStream +{ + public: + + TInputStream(void * pvInBuffer, size_t cbInBuffer); + unsigned int Get1Bit(); + unsigned int Peek7Bits(); + unsigned int Get8Bits(); + void SkipBits(unsigned int BitCount); + + unsigned char * pbInBufferEnd; // End position in the the input buffer + unsigned char * pbInBuffer; // Current position in the the input buffer + unsigned int BitBuffer; // Input bit buffer + unsigned int BitCount; // Number of bits remaining in 'dwBitBuff' +}; + + +// Output stream for Huffmann compression +class TOutputStream +{ + public: + + TOutputStream(void * pvOutBuffer, size_t cbOutLength); + void PutBits(unsigned int dwValue, unsigned int nBitCount); + void Flush(); + + unsigned char * pbOutBufferEnd; // End position in the output buffer + unsigned char * pbOutBuffer; // Current position in the output buffer + unsigned int BitBuffer; // Bit buffer + unsigned int BitCount; // Number of bits in the bit buffer +}; + +// A virtual tree item that represents the head of the item list +#define LIST_HEAD() ((THTreeItem *)(&pFirst)) + +enum TInsertPoint +{ + InsertAfter = 1, + InsertBefore = 2 +}; + +// Huffmann tree item +struct THTreeItem +{ + THTreeItem() { pPrev = pNext = NULL; DecompressedValue = 0; Weight = 0; pParent = pChildLo = NULL; } +// ~THTreeItem() { RemoveItem(); } + + void RemoveItem(); +// void RemoveEntry(); + + THTreeItem * pNext; // Pointer to lower-weight tree item + THTreeItem * pPrev; // Pointer to higher-weight item + unsigned int DecompressedValue; // 08 - Decompressed byte value (also index in the array) + unsigned int Weight; // 0C - Weight + THTreeItem * pParent; // 10 - Pointer to parent item (NULL if none) + THTreeItem * pChildLo; // 14 - Pointer to the child with lower-weight child ("left child") +}; + + +// Structure used for quick navigating in the huffmann tree. +// Allows skipping up to 7 bits in the compressed stream, thus +// decompressing a bit faster. Sometimes it can even get the decompressed +// byte directly. +struct TQuickLink +{ + unsigned int ValidValue; // If greater than THuffmannTree::MinValidValue, the entry is valid + unsigned int ValidBits; // Number of bits that are valid for this item link + union + { + THTreeItem * pItem; // Pointer to the item within the Huffmann tree + unsigned int DecompressedValue; // Value for direct decompression + }; +}; + + +// Structure for Huffman tree (Size 0x3674 bytes). Because I'm not expert +// for the decompression, I do not know actually if the class is really a Hufmann +// tree. If someone knows the decompression details, please let me know +class THuffmannTree +{ + public: + + THuffmannTree(bool bCompression); + ~THuffmannTree(); + + void LinkTwoItems(THTreeItem * pItem1, THTreeItem * pItem2); + void InsertItem(THTreeItem * item, TInsertPoint InsertPoint, THTreeItem * item2); + + THTreeItem * FindHigherOrEqualItem(THTreeItem * pItem, unsigned int Weight); + THTreeItem * CreateNewItem(unsigned int DecompressedValue, unsigned int Weight, TInsertPoint InsertPoint); + + unsigned int FixupItemPosByWeight(THTreeItem * pItem, unsigned int MaxWeight); + bool BuildTree(unsigned int CompressionType); + + void IncWeightsAndRebalance(THTreeItem * pItem); + bool InsertNewBranchAndRebalance(unsigned int Value1, unsigned int Value2); + + void EncodeOneByte(TOutputStream * os, THTreeItem * pItem); + unsigned int DecodeOneByte(TInputStream * is); + + unsigned int Compress(TOutputStream * os, void * pvInBuffer, int cbInBuffer, int nCmpType); + unsigned int Decompress(void * pvOutBuffer, unsigned int cbOutLength, TInputStream * is); + + THTreeItem ItemBuffer[HUFF_ITEM_COUNT]; // Buffer for tree items. No memory allocation is needed + unsigned int ItemsUsed; // Number of tree items used from ItemBuffer + + // Head of the linear item list + THTreeItem * pFirst; // Pointer to the highest weight item + THTreeItem * pLast; // Pointer to the lowest weight item + + THTreeItem * ItemsByByte[0x102]; // Array of item pointers, one for each possible byte value + TQuickLink QuickLinks[LINK_ITEM_COUNT]; // Array of quick-link items + + unsigned int MinValidValue; // A minimum value of TQDecompress::ValidValue to be considered valid + unsigned int bIsCmp0; // 1 if compression type 0 +}; + +#endif // __HUFFMAN_H__ diff --git a/StormLib/src/jenkins/lookup.h b/StormLib/src/jenkins/lookup.h new file mode 100644 index 000000000..54ccc979c --- /dev/null +++ b/StormLib/src/jenkins/lookup.h @@ -0,0 +1,24 @@ +#ifndef __LOOKUP3_H__ +#define __LOOKUP3_H__ + +#ifdef WIN32 +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#else +#include /* defines uint32_t etc */ +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +uint32_t hashlittle(const void *key, size_t length, uint32_t initval); +void hashlittle2(const void *key, size_t length, uint32_t *pc, uint32_t *pb); + +#ifdef __cplusplus +} +#endif + +#endif // __LOOKUP3_H__ diff --git a/StormLib/src/jenkins/lookup3.c b/StormLib/src/jenkins/lookup3.c new file mode 100644 index 000000000..6af56b481 --- /dev/null +++ b/StormLib/src/jenkins/lookup3.c @@ -0,0 +1,1003 @@ +/* +------------------------------------------------------------------------------- +lookup3.c, by Bob Jenkins, May 2006, Public Domain. + +These are functions for producing 32-bit hashes for hash table lookup. +hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() +are externally useful functions. Routines to test the hash are included +if SELF_TEST is defined. You can use this free for any purpose. It's in +the public domain. It has no warranty. + +You probably want to use hashlittle(). hashlittle() and hashbig() +hash byte arrays. hashlittle() is is faster than hashbig() on +little-endian machines. Intel and AMD are little-endian machines. +On second thought, you probably want hashlittle2(), which is identical to +hashlittle() except it returns two 32-bit hashes for the price of one. +You could implement hashbig2() if you wanted but I haven't bothered here. + +If you want to find a hash of, say, exactly 7 integers, do + a = i1; b = i2; c = i3; + mix(a,b,c); + a += i4; b += i5; c += i6; + mix(a,b,c); + a += i7; + final(a,b,c); +then use c as the hash value. If you have a variable length array of +4-byte integers to hash, use hashword(). If you have a byte array (like +a character string), use hashlittle(). If you have several byte arrays, or +a mix of things, see the comments above hashlittle(). + +Why is this so big? I read 12 bytes at a time into 3 4-byte integers, +then mix those integers. This is fast (you can do a lot more thorough +mixing with 12*3 instructions on 3 integers than you can with 3 instructions +on 1 byte), but shoehorning those bytes into integers efficiently is messy. +------------------------------------------------------------------------------- +*/ +//#define SELF_TEST 1 + +#include /* defines printf for tests */ +#include /* defines time_t for timings in the test */ + +#ifdef linux +#include /* attempt to define endianness */ +#include /* attempt to define endianness */ +#endif + +#include "lookup.h" + +/* + * My best guess at if you are big-endian or little-endian. This may + * need adjustment. + */ +#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ + __BYTE_ORDER == __LITTLE_ENDIAN) || \ + (defined(i386) || defined(__i386__) || defined(__i486__) || \ + defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL)) +# define HASH_LITTLE_ENDIAN 1 +# define HASH_BIG_ENDIAN 0 +#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ + __BYTE_ORDER == __BIG_ENDIAN) || \ + (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel)) +# define HASH_LITTLE_ENDIAN 0 +# define HASH_BIG_ENDIAN 1 +#else +# define HASH_LITTLE_ENDIAN 0 +# define HASH_BIG_ENDIAN 0 +#endif + +#define hashsize(n) ((uint32_t)1<<(n)) +#define hashmask(n) (hashsize(n)-1) +#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) + +/* +------------------------------------------------------------------------------- +mix -- mix 3 32-bit values reversibly. + +This is reversible, so any information in (a,b,c) before mix() is +still in (a,b,c) after mix(). + +If four pairs of (a,b,c) inputs are run through mix(), or through +mix() in reverse, there are at least 32 bits of the output that +are sometimes the same for one pair and different for another pair. +This was tested for: +* pairs that differed by one bit, by two bits, in any combination + of top bits of (a,b,c), or in any combination of bottom bits of + (a,b,c). +* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + is commonly produced by subtraction) look like a single 1-bit + difference. +* the base values were pseudorandom, all zero but one bit set, or + all zero plus a counter that starts at zero. + +Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that +satisfy this are + 4 6 8 16 19 4 + 9 15 3 18 27 15 + 14 9 3 7 17 3 +Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing +for "differ" defined as + with a one-bit base and a two-bit delta. I +used http://burtleburtle.net/bob/hash/avalanche.html to choose +the operations, constants, and arrangements of the variables. + +This does not achieve avalanche. There are input bits of (a,b,c) +that fail to affect some output bits of (a,b,c), especially of a. The +most thoroughly mixed value is c, but it doesn't really even achieve +avalanche in c. + +This allows some parallelism. Read-after-writes are good at doubling +the number of bits affected, so the goal of mixing pulls in the opposite +direction as the goal of parallelism. I did what I could. Rotates +seem to cost as much as shifts on every machine I could lay my hands +on, and rotates are much kinder to the top and bottom bits, so I used +rotates. +------------------------------------------------------------------------------- +*/ +#define mix(a,b,c) \ +{ \ + a -= c; a ^= rot(c, 4); c += b; \ + b -= a; b ^= rot(a, 6); a += c; \ + c -= b; c ^= rot(b, 8); b += a; \ + a -= c; a ^= rot(c,16); c += b; \ + b -= a; b ^= rot(a,19); a += c; \ + c -= b; c ^= rot(b, 4); b += a; \ +} + +/* +------------------------------------------------------------------------------- +final -- final mixing of 3 32-bit values (a,b,c) into c + +Pairs of (a,b,c) values differing in only a few bits will usually +produce values of c that look totally different. This was tested for +* pairs that differed by one bit, by two bits, in any combination + of top bits of (a,b,c), or in any combination of bottom bits of + (a,b,c). +* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + is commonly produced by subtraction) look like a single 1-bit + difference. +* the base values were pseudorandom, all zero but one bit set, or + all zero plus a counter that starts at zero. + +These constants passed: + 14 11 25 16 4 14 24 + 12 14 25 16 4 14 24 +and these came close: + 4 8 15 26 3 22 24 + 10 8 15 26 3 22 24 + 11 8 15 26 3 22 24 +------------------------------------------------------------------------------- +*/ +#define final(a,b,c) \ +{ \ + c ^= b; c -= rot(b,14); \ + a ^= c; a -= rot(c,11); \ + b ^= a; b -= rot(a,25); \ + c ^= b; c -= rot(b,16); \ + a ^= c; a -= rot(c,4); \ + b ^= a; b -= rot(a,14); \ + c ^= b; c -= rot(b,24); \ +} + +/* +-------------------------------------------------------------------- + This works on all machines. To be useful, it requires + -- that the key be an array of uint32_t's, and + -- that the length be the number of uint32_t's in the key + + The function hashword() is identical to hashlittle() on little-endian + machines, and identical to hashbig() on big-endian machines, + except that the length has to be measured in uint32_ts rather than in + bytes. hashlittle() is more complicated than hashword() only because + hashlittle() has to dance around fitting the key bytes into registers. +-------------------------------------------------------------------- +*/ +uint32_t hashword( +const uint32_t *k, /* the key, an array of uint32_t values */ +size_t length, /* the length of the key, in uint32_ts */ +uint32_t initval) /* the previous hash, or an arbitrary value */ +{ + uint32_t a,b,c; + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + (((uint32_t)length)<<2) + initval; + + /*------------------------------------------------- handle most of the key */ + while (length > 3) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 3; + k += 3; + } + + /*------------------------------------------- handle the last 3 uint32_t's */ + switch(length) /* all the case statements fall through */ + { + case 3 : c+=k[2]; + case 2 : b+=k[1]; + case 1 : a+=k[0]; + final(a,b,c); + case 0: /* case 0: nothing left to add */ + break; + } + /*------------------------------------------------------ report the result */ + return c; +} + + +/* +-------------------------------------------------------------------- +hashword2() -- same as hashword(), but take two seeds and return two +32-bit values. pc and pb must both be nonnull, and *pc and *pb must +both be initialized with seeds. If you pass in (*pb)==0, the output +(*pc) will be the same as the return value from hashword(). +-------------------------------------------------------------------- +*/ +void hashword2 ( +const uint32_t *k, /* the key, an array of uint32_t values */ +size_t length, /* the length of the key, in uint32_ts */ +uint32_t *pc, /* IN: seed OUT: primary hash value */ +uint32_t *pb) /* IN: more seed OUT: secondary hash value */ +{ + uint32_t a,b,c; + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ((uint32_t)(length<<2)) + *pc; + c += *pb; + + /*------------------------------------------------- handle most of the key */ + while (length > 3) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 3; + k += 3; + } + + /*------------------------------------------- handle the last 3 uint32_t's */ + switch(length) /* all the case statements fall through */ + { + case 3 : c+=k[2]; + case 2 : b+=k[1]; + case 1 : a+=k[0]; + final(a,b,c); + case 0: /* case 0: nothing left to add */ + break; + } + /*------------------------------------------------------ report the result */ + *pc=c; *pb=b; +} + + +/* +------------------------------------------------------------------------------- +hashlittle() -- hash a variable-length key into a 32-bit value + k : the key (the unaligned variable-length array of bytes) + length : the length of the key, counting by bytes + initval : can be any 4-byte value +Returns a 32-bit value. Every bit of the key affects every bit of +the return value. Two keys differing by one or two bits will have +totally different hash values. + +The best hash table sizes are powers of 2. There is no need to do +mod a prime (mod is sooo slow!). If you need less than 32 bits, +use a bitmask. For example, if you need only 10 bits, do + h = (h & hashmask(10)); +In which case, the hash table should have hashsize(10) elements. + +If you are hashing n strings (uint8_t **)k, do it like this: + for (i=0, h=0; i 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + /* + * "k[2]&0xffffff" actually reads beyond the end of the string, but + * then masks off the part it's not allowed to read. Because the + * string is aligned, the masked-off tail is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; + case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; + case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=k[1]&0xffffff; a+=k[0]; break; + case 6 : b+=k[1]&0xffff; a+=k[0]; break; + case 5 : b+=k[1]&0xff; a+=k[0]; break; + case 4 : a+=k[0]; break; + case 3 : a+=k[0]&0xffffff; break; + case 2 : a+=k[0]&0xffff; break; + case 1 : a+=k[0]&0xff; break; + case 0 : return c; /* zero length strings require no mixing */ + } + +#else /* make valgrind happy */ + + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ + case 1 : a+=k8[0]; break; + case 0 : return c; + } + +#endif /* !valgrind */ + + } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { + const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ + const uint8_t *k8; + + /*--------------- all but last block: aligned reads and different mixing */ + while (length > 12) + { + a += k[0] + (((uint32_t)k[1])<<16); + b += k[2] + (((uint32_t)k[3])<<16); + c += k[4] + (((uint32_t)k[5])<<16); + mix(a,b,c); + length -= 12; + k += 6; + } + + /*----------------------------- handle the last (probably partial) block */ + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[4]+(((uint32_t)k[5])<<16); + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=k[4]; + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=k[2]; + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=k[0]; + break; + case 1 : a+=k8[0]; + break; + case 0 : return c; /* zero length requires no mixing */ + } + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + a += ((uint32_t)k[1])<<8; + a += ((uint32_t)k[2])<<16; + a += ((uint32_t)k[3])<<24; + b += k[4]; + b += ((uint32_t)k[5])<<8; + b += ((uint32_t)k[6])<<16; + b += ((uint32_t)k[7])<<24; + c += k[8]; + c += ((uint32_t)k[9])<<8; + c += ((uint32_t)k[10])<<16; + c += ((uint32_t)k[11])<<24; + mix(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=((uint32_t)k[11])<<24; + case 11: c+=((uint32_t)k[10])<<16; + case 10: c+=((uint32_t)k[9])<<8; + case 9 : c+=k[8]; + case 8 : b+=((uint32_t)k[7])<<24; + case 7 : b+=((uint32_t)k[6])<<16; + case 6 : b+=((uint32_t)k[5])<<8; + case 5 : b+=k[4]; + case 4 : a+=((uint32_t)k[3])<<24; + case 3 : a+=((uint32_t)k[2])<<16; + case 2 : a+=((uint32_t)k[1])<<8; + case 1 : a+=k[0]; + break; + case 0 : return c; + } + } + + final(a,b,c); + return c; +} + + +/* + * hashlittle2: return 2 32-bit hash values + * + * This is identical to hashlittle(), except it returns two 32-bit hash + * values instead of just one. This is good enough for hash table + * lookup with 2^^64 buckets, or if you want a second hash if you're not + * happy with the first, or if you want a probably-unique 64-bit ID for + * the key. *pc is better mixed than *pb, so use *pc first. If you want + * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)". + */ +void hashlittle2( + const void *key, /* the key to hash */ + size_t length, /* length of the key */ + uint32_t *pc, /* IN: primary initval, OUT: primary hash */ + uint32_t *pb) /* IN: secondary initval, OUT: secondary hash */ +{ + uint32_t a,b,c; /* internal state */ + union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ((uint32_t)length) + *pc; + c += *pb; + + u.ptr = key; + if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { + const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ + const uint8_t *k8; + + /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + /* + * "k[2]&0xffffff" actually reads beyond the end of the string, but + * then masks off the part it's not allowed to read. Because the + * string is aligned, the masked-off tail is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; + case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; + case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=k[1]&0xffffff; a+=k[0]; break; + case 6 : b+=k[1]&0xffff; a+=k[0]; break; + case 5 : b+=k[1]&0xff; a+=k[0]; break; + case 4 : a+=k[0]; break; + case 3 : a+=k[0]&0xffffff; break; + case 2 : a+=k[0]&0xffff; break; + case 1 : a+=k[0]&0xff; break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + +#else /* make valgrind happy */ + + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ + case 1 : a+=k8[0]; break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + +#endif /* !valgrind */ + + } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { + const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ + const uint8_t *k8; + + /*--------------- all but last block: aligned reads and different mixing */ + while (length > 12) + { + a += k[0] + (((uint32_t)k[1])<<16); + b += k[2] + (((uint32_t)k[3])<<16); + c += k[4] + (((uint32_t)k[5])<<16); + mix(a,b,c); + length -= 12; + k += 6; + } + + /*----------------------------- handle the last (probably partial) block */ + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[4]+(((uint32_t)k[5])<<16); + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=k[4]; + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=k[2]; + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=k[0]; + break; + case 1 : a+=k8[0]; + break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + a += ((uint32_t)k[1])<<8; + a += ((uint32_t)k[2])<<16; + a += ((uint32_t)k[3])<<24; + b += k[4]; + b += ((uint32_t)k[5])<<8; + b += ((uint32_t)k[6])<<16; + b += ((uint32_t)k[7])<<24; + c += k[8]; + c += ((uint32_t)k[9])<<8; + c += ((uint32_t)k[10])<<16; + c += ((uint32_t)k[11])<<24; + mix(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=((uint32_t)k[11])<<24; + case 11: c+=((uint32_t)k[10])<<16; + case 10: c+=((uint32_t)k[9])<<8; + case 9 : c+=k[8]; + case 8 : b+=((uint32_t)k[7])<<24; + case 7 : b+=((uint32_t)k[6])<<16; + case 6 : b+=((uint32_t)k[5])<<8; + case 5 : b+=k[4]; + case 4 : a+=((uint32_t)k[3])<<24; + case 3 : a+=((uint32_t)k[2])<<16; + case 2 : a+=((uint32_t)k[1])<<8; + case 1 : a+=k[0]; + break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + } + + final(a,b,c); + *pc=c; *pb=b; +} + + + +/* + * hashbig(): + * This is the same as hashword() on big-endian machines. It is different + * from hashlittle() on all machines. hashbig() takes advantage of + * big-endian byte ordering. + */ +uint32_t hashbig( const void *key, size_t length, uint32_t initval) +{ + uint32_t a,b,c; + union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */ + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; + + u.ptr = key; + if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) { + const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ + const uint8_t *k8; + + /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + /* + * "k[2]<<8" actually reads beyond the end of the string, but + * then shifts out the part it's not allowed to read. Because the + * string is aligned, the illegal read is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break; + case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break; + case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=k[1]&0xffffff00; a+=k[0]; break; + case 6 : b+=k[1]&0xffff0000; a+=k[0]; break; + case 5 : b+=k[1]&0xff000000; a+=k[0]; break; + case 4 : a+=k[0]; break; + case 3 : a+=k[0]&0xffffff00; break; + case 2 : a+=k[0]&0xffff0000; break; + case 1 : a+=k[0]&0xff000000; break; + case 0 : return c; /* zero length strings require no mixing */ + } + +#else /* make valgrind happy */ + + k8 = (const uint8_t *)k; + switch(length) /* all the case statements fall through */ + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<8; /* fall through */ + case 10: c+=((uint32_t)k8[9])<<16; /* fall through */ + case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */ + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<8; /* fall through */ + case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */ + case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */ + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<8; /* fall through */ + case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */ + case 1 : a+=((uint32_t)k8[0])<<24; break; + case 0 : return c; + } + +#endif /* !VALGRIND */ + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += ((uint32_t)k[0])<<24; + a += ((uint32_t)k[1])<<16; + a += ((uint32_t)k[2])<<8; + a += ((uint32_t)k[3]); + b += ((uint32_t)k[4])<<24; + b += ((uint32_t)k[5])<<16; + b += ((uint32_t)k[6])<<8; + b += ((uint32_t)k[7]); + c += ((uint32_t)k[8])<<24; + c += ((uint32_t)k[9])<<16; + c += ((uint32_t)k[10])<<8; + c += ((uint32_t)k[11]); + mix(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=k[11]; + case 11: c+=((uint32_t)k[10])<<8; + case 10: c+=((uint32_t)k[9])<<16; + case 9 : c+=((uint32_t)k[8])<<24; + case 8 : b+=k[7]; + case 7 : b+=((uint32_t)k[6])<<8; + case 6 : b+=((uint32_t)k[5])<<16; + case 5 : b+=((uint32_t)k[4])<<24; + case 4 : a+=k[3]; + case 3 : a+=((uint32_t)k[2])<<8; + case 2 : a+=((uint32_t)k[1])<<16; + case 1 : a+=((uint32_t)k[0])<<24; + break; + case 0 : return c; + } + } + + final(a,b,c); + return c; +} + + +#ifdef SELF_TEST + +/* used for timings */ +void driver1() +{ + uint8_t buf[256]; + uint32_t i; + uint32_t h=0; + time_t a,z; + + time(&a); + for (i=0; i<256; ++i) buf[i] = 'x'; + for (i=0; i<1; ++i) + { + h = hashlittle(&buf[0],1,h); + } + time(&z); + if (z-a > 0) printf("time %d %.8x\n", z-a, h); +} + +/* check that every input bit changes every output bit half the time */ +#define HASHSTATE 1 +#define HASHLEN 1 +#define MAXPAIR 60 +#define MAXLEN 70 +void driver2() +{ + uint8_t qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1]; + uint32_t c[HASHSTATE], d[HASHSTATE], i=0, j=0, k, l, m=0, z; + uint32_t e[HASHSTATE],f[HASHSTATE],g[HASHSTATE],h[HASHSTATE]; + uint32_t x[HASHSTATE],y[HASHSTATE]; + uint32_t hlen; + + printf("No more than %d trials should ever be needed \n",MAXPAIR/2); + for (hlen=0; hlen < MAXLEN; ++hlen) + { + z=0; + for (i=0; i>(8-j)); + c[0] = hashlittle(a, hlen, m); + b[i] ^= ((k+1)<>(8-j)); + d[0] = hashlittle(b, hlen, m); + /* check every bit is 1, 0, set, and not set at least once */ + for (l=0; lz) z=k; + if (k==MAXPAIR) + { + printf("Some bit didn't change: "); + printf("%.8x %.8x %.8x %.8x %.8x %.8x ", + e[0],f[0],g[0],h[0],x[0],y[0]); + printf("i %d j %d m %d len %d\n", i, j, m, hlen); + } + if (z==MAXPAIR) goto done; + } + } + } + done: + if (z < MAXPAIR) + { + printf("Mix success %2d bytes %2d initvals ",i,m); + printf("required %d trials\n", z/2); + } + } + printf("\n"); +} + +/* Check for reading beyond the end of the buffer and alignment problems */ +void driver3() +{ + uint8_t buf[MAXLEN+20], *b; + uint32_t len; + uint8_t q[] = "This is the time for all good men to come to the aid of their country..."; + uint32_t h; + uint8_t qq[] = "xThis is the time for all good men to come to the aid of their country..."; + uint32_t i; + uint8_t qqq[] = "xxThis is the time for all good men to come to the aid of their country..."; + uint32_t j; + uint8_t qqqq[] = "xxxThis is the time for all good men to come to the aid of their country..."; + uint32_t ref,x,y; + uint8_t *p; + + printf("Endianness. These lines should all be the same (for values filled in):\n"); + printf("%.8x %.8x %.8x\n", + hashword((const uint32_t *)q, (sizeof(q)-1)/4, 13), + hashword((const uint32_t *)q, (sizeof(q)-5)/4, 13), + hashword((const uint32_t *)q, (sizeof(q)-9)/4, 13)); + p = q; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), + hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), + hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), + hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), + hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), + hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); + p = &qq[1]; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), + hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), + hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), + hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), + hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), + hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); + p = &qqq[2]; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), + hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), + hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), + hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), + hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), + hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); + p = &qqqq[3]; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), + hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), + hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), + hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), + hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), + hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); + printf("\n"); + + /* check that hashlittle2 and hashlittle produce the same results */ + i=47; j=0; + hashlittle2(q, sizeof(q), &i, &j); + if (hashlittle(q, sizeof(q), 47) != i) + printf("hashlittle2 and hashlittle mismatch\n"); + + /* check that hashword2 and hashword produce the same results */ + len = 0xdeadbeef; + i=47, j=0; + hashword2(&len, 1, &i, &j); + if (hashword(&len, 1, 47) != i) + printf("hashword2 and hashword mismatch %x %x\n", + i, hashword(&len, 1, 47)); + + /* check hashlittle doesn't read before or after the ends of the string */ + for (h=0, b=buf+1; h<8; ++h, ++b) + { + for (i=0; imd5.state[0]; + b = md->md5.state[1]; + c = md->md5.state[2]; + d = md->md5.state[3]; + +#ifdef LTC_SMALL_CODE + for (i = 0; i < 16; ++i) { + FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); + t = d; d = c; c = b; b = a; a = t; + } + + for (; i < 32; ++i) { + GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); + t = d; d = c; c = b; b = a; a = t; + } + + for (; i < 48; ++i) { + HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); + t = d; d = c; c = b; b = a; a = t; + } + + for (; i < 64; ++i) { + II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); + t = d; d = c; c = b; b = a; a = t; + } + +#else + FF(a,b,c,d,W[0],7,0xd76aa478UL) + FF(d,a,b,c,W[1],12,0xe8c7b756UL) + FF(c,d,a,b,W[2],17,0x242070dbUL) + FF(b,c,d,a,W[3],22,0xc1bdceeeUL) + FF(a,b,c,d,W[4],7,0xf57c0fafUL) + FF(d,a,b,c,W[5],12,0x4787c62aUL) + FF(c,d,a,b,W[6],17,0xa8304613UL) + FF(b,c,d,a,W[7],22,0xfd469501UL) + FF(a,b,c,d,W[8],7,0x698098d8UL) + FF(d,a,b,c,W[9],12,0x8b44f7afUL) + FF(c,d,a,b,W[10],17,0xffff5bb1UL) + FF(b,c,d,a,W[11],22,0x895cd7beUL) + FF(a,b,c,d,W[12],7,0x6b901122UL) + FF(d,a,b,c,W[13],12,0xfd987193UL) + FF(c,d,a,b,W[14],17,0xa679438eUL) + FF(b,c,d,a,W[15],22,0x49b40821UL) + GG(a,b,c,d,W[1],5,0xf61e2562UL) + GG(d,a,b,c,W[6],9,0xc040b340UL) + GG(c,d,a,b,W[11],14,0x265e5a51UL) + GG(b,c,d,a,W[0],20,0xe9b6c7aaUL) + GG(a,b,c,d,W[5],5,0xd62f105dUL) + GG(d,a,b,c,W[10],9,0x02441453UL) + GG(c,d,a,b,W[15],14,0xd8a1e681UL) + GG(b,c,d,a,W[4],20,0xe7d3fbc8UL) + GG(a,b,c,d,W[9],5,0x21e1cde6UL) + GG(d,a,b,c,W[14],9,0xc33707d6UL) + GG(c,d,a,b,W[3],14,0xf4d50d87UL) + GG(b,c,d,a,W[8],20,0x455a14edUL) + GG(a,b,c,d,W[13],5,0xa9e3e905UL) + GG(d,a,b,c,W[2],9,0xfcefa3f8UL) + GG(c,d,a,b,W[7],14,0x676f02d9UL) + GG(b,c,d,a,W[12],20,0x8d2a4c8aUL) + HH(a,b,c,d,W[5],4,0xfffa3942UL) + HH(d,a,b,c,W[8],11,0x8771f681UL) + HH(c,d,a,b,W[11],16,0x6d9d6122UL) + HH(b,c,d,a,W[14],23,0xfde5380cUL) + HH(a,b,c,d,W[1],4,0xa4beea44UL) + HH(d,a,b,c,W[4],11,0x4bdecfa9UL) + HH(c,d,a,b,W[7],16,0xf6bb4b60UL) + HH(b,c,d,a,W[10],23,0xbebfbc70UL) + HH(a,b,c,d,W[13],4,0x289b7ec6UL) + HH(d,a,b,c,W[0],11,0xeaa127faUL) + HH(c,d,a,b,W[3],16,0xd4ef3085UL) + HH(b,c,d,a,W[6],23,0x04881d05UL) + HH(a,b,c,d,W[9],4,0xd9d4d039UL) + HH(d,a,b,c,W[12],11,0xe6db99e5UL) + HH(c,d,a,b,W[15],16,0x1fa27cf8UL) + HH(b,c,d,a,W[2],23,0xc4ac5665UL) + II(a,b,c,d,W[0],6,0xf4292244UL) + II(d,a,b,c,W[7],10,0x432aff97UL) + II(c,d,a,b,W[14],15,0xab9423a7UL) + II(b,c,d,a,W[5],21,0xfc93a039UL) + II(a,b,c,d,W[12],6,0x655b59c3UL) + II(d,a,b,c,W[3],10,0x8f0ccc92UL) + II(c,d,a,b,W[10],15,0xffeff47dUL) + II(b,c,d,a,W[1],21,0x85845dd1UL) + II(a,b,c,d,W[8],6,0x6fa87e4fUL) + II(d,a,b,c,W[15],10,0xfe2ce6e0UL) + II(c,d,a,b,W[6],15,0xa3014314UL) + II(b,c,d,a,W[13],21,0x4e0811a1UL) + II(a,b,c,d,W[4],6,0xf7537e82UL) + II(d,a,b,c,W[11],10,0xbd3af235UL) + II(c,d,a,b,W[2],15,0x2ad7d2bbUL) + II(b,c,d,a,W[9],21,0xeb86d391UL) +#endif + + md->md5.state[0] = md->md5.state[0] + a; + md->md5.state[1] = md->md5.state[1] + b; + md->md5.state[2] = md->md5.state[2] + c; + md->md5.state[3] = md->md5.state[3] + d; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int md5_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _md5_compress(md, buf); + burn_stack(sizeof(ulong32) * 21); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int md5_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->md5.state[0] = 0x67452301UL; + md->md5.state[1] = 0xefcdab89UL; + md->md5.state[2] = 0x98badcfeUL; + md->md5.state[3] = 0x10325476UL; + md->md5.curlen = 0; + md->md5.length = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(md5_process, md5_compress, md5, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (16 bytes) + @return CRYPT_OK if successful +*/ +int md5_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->md5.curlen >= sizeof(md->md5.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->md5.length += md->md5.curlen * 8; + + /* append the '1' bit */ + md->md5.buf[md->md5.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->md5.curlen > 56) { + while (md->md5.curlen < 64) { + md->md5.buf[md->md5.curlen++] = (unsigned char)0; + } + md5_compress(md, md->md5.buf); + md->md5.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->md5.curlen < 56) { + md->md5.buf[md->md5.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->md5.length, md->md5.buf+56); + md5_compress(md, md->md5.buf); + + /* copy output */ + for (i = 0; i < 4; i++) { + STORE32L(md->md5.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int md5_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[16]; + } tests[] = { + { "", + { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, + 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } }, + { "a", + {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, + 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } }, + { "abc", + { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, + 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } }, + { "message digest", + { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, + 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } }, + { "abcdefghijklmnopqrstuvwxyz", + { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, + 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, + 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } }, + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, + 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }, + { NULL, { 0 } } + }; + + int i; + unsigned char tmp[16]; + hash_state md; + + for (i = 0; tests[i].msg != NULL; i++) { + md5_init(&md); + md5_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + md5_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 16) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + + + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/md5.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:25:28 $ */ diff --git a/StormLib/src/libtomcrypt/src/hashes/sha1.c b/StormLib/src/libtomcrypt/src/hashes/sha1.c new file mode 100644 index 000000000..409d09542 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/hashes/sha1.c @@ -0,0 +1,288 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../headers/tomcrypt.h" + +/** + @file sha1.c + LTC_SHA1 code by Tom St Denis +*/ + + +#ifdef LTC_SHA1 + +const struct ltc_hash_descriptor sha1_desc = +{ + "sha1", + 2, + 20, + 64, + + /* OID */ + { 1, 3, 14, 3, 2, 26, }, + 6, + + &sha1_init, + &sha1_process, + &sha1_done, + &sha1_test, + NULL +}; + +#define F0(x,y,z) (z ^ (x & (y ^ z))) +#define F1(x,y,z) (x ^ y ^ z) +#define F2(x,y,z) ((x & y) | (z & (x | y))) +#define F3(x,y,z) (x ^ y ^ z) + +#ifdef LTC_CLEAN_STACK +static int _sha1_compress(hash_state *md, unsigned char *buf) +#else +static int sha1_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 a,b,c,d,e,W[80],i; +#ifdef LTC_SMALL_CODE + ulong32 t; +#endif + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32H(W[i], buf + (4*i)); + } + + /* copy state */ + a = md->sha1.state[0]; + b = md->sha1.state[1]; + c = md->sha1.state[2]; + d = md->sha1.state[3]; + e = md->sha1.state[4]; + + /* expand it */ + for (i = 16; i < 80; i++) { + W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); + } + + /* compress */ + /* round one */ + #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30); + #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30); + #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30); + #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30); + +#ifdef LTC_SMALL_CODE + + for (i = 0; i < 20; ) { + FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + } + + for (; i < 40; ) { + FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + } + + for (; i < 60; ) { + FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + } + + for (; i < 80; ) { + FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + } + +#else + + for (i = 0; i < 20; ) { + FF0(a,b,c,d,e,i++); + FF0(e,a,b,c,d,i++); + FF0(d,e,a,b,c,i++); + FF0(c,d,e,a,b,i++); + FF0(b,c,d,e,a,i++); + } + + /* round two */ + for (; i < 40; ) { + FF1(a,b,c,d,e,i++); + FF1(e,a,b,c,d,i++); + FF1(d,e,a,b,c,i++); + FF1(c,d,e,a,b,i++); + FF1(b,c,d,e,a,i++); + } + + /* round three */ + for (; i < 60; ) { + FF2(a,b,c,d,e,i++); + FF2(e,a,b,c,d,i++); + FF2(d,e,a,b,c,i++); + FF2(c,d,e,a,b,i++); + FF2(b,c,d,e,a,i++); + } + + /* round four */ + for (; i < 80; ) { + FF3(a,b,c,d,e,i++); + FF3(e,a,b,c,d,i++); + FF3(d,e,a,b,c,i++); + FF3(c,d,e,a,b,i++); + FF3(b,c,d,e,a,i++); + } +#endif + + #undef FF0 + #undef FF1 + #undef FF2 + #undef FF3 + + /* store */ + md->sha1.state[0] = md->sha1.state[0] + a; + md->sha1.state[1] = md->sha1.state[1] + b; + md->sha1.state[2] = md->sha1.state[2] + c; + md->sha1.state[3] = md->sha1.state[3] + d; + md->sha1.state[4] = md->sha1.state[4] + e; + + return CRYPT_OK; +} + +#ifdef LTC_CLEAN_STACK +static int sha1_compress(hash_state *md, unsigned char *buf) +{ + int err; + err = _sha1_compress(md, buf); + burn_stack(sizeof(ulong32) * 87); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha1_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + md->sha1.state[0] = 0x67452301UL; + md->sha1.state[1] = 0xefcdab89UL; + md->sha1.state[2] = 0x98badcfeUL; + md->sha1.state[3] = 0x10325476UL; + md->sha1.state[4] = 0xc3d2e1f0UL; + md->sha1.curlen = 0; + md->sha1.length = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(sha1_process, sha1_compress, sha1, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (20 bytes) + @return CRYPT_OK if successful +*/ +int sha1_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->sha1.curlen >= sizeof(md->sha1.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->sha1.length += md->sha1.curlen * 8; + + /* append the '1' bit */ + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->sha1.curlen > 56) { + while (md->sha1.curlen < 64) { + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; + } + sha1_compress(md, md->sha1.buf); + md->sha1.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->sha1.curlen < 56) { + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->sha1.length, md->sha1.buf+56); + sha1_compress(md, md->sha1.buf); + + /* copy output */ + for (i = 0; i < 5; i++) { + STORE32H(md->sha1.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha1_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[20]; + } tests[] = { + { "abc", + { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, + 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, + 0x9c, 0xd0, 0xd8, 0x9d } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, + 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, + 0xE5, 0x46, 0x70, 0xF1 } + } + }; + + int i; + unsigned char tmp[20]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha1_init(&md); + sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha1_done(&md, tmp); + if (XMEMCMP(tmp, tests[i].hash, 20) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + + + +/* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha1.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:25:28 $ */ diff --git a/StormLib/src/libtomcrypt/src/headers/tomcrypt.h b/StormLib/src/libtomcrypt/src/headers/tomcrypt.h new file mode 100644 index 000000000..7df3f5a8a --- /dev/null +++ b/StormLib/src/libtomcrypt/src/headers/tomcrypt.h @@ -0,0 +1,91 @@ +#ifndef TOMCRYPT_H_ +#define TOMCRYPT_H_ +#include +#include +#include +#include +#include +#include +#include + +/* use configuration data */ +#include "tomcrypt_custom.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* version */ +#define CRYPT 0x0117 +#define SCRYPT "1.17" + +/* max size of either a cipher/hash block or symmetric key [largest of the two] */ +#define MAXBLOCKSIZE 128 + +/* descriptor table size */ +#define TAB_SIZE 32 + +#ifdef _MSC_VER +#pragma warning(disable: 4333) // der_encode_utf8_string.c(91) : warning C4333: '>>' : right shift by too large amount, data loss +#endif + +/* error codes [will be expanded in future releases] */ +enum { + CRYPT_OK=0, /* Result OK */ + CRYPT_ERROR, /* Generic Error */ + CRYPT_NOP, /* Not a failure but no operation was performed */ + + CRYPT_INVALID_KEYSIZE, /* Invalid key size given */ + CRYPT_INVALID_ROUNDS, /* Invalid number of rounds */ + CRYPT_FAIL_TESTVECTOR, /* Algorithm failed test vectors */ + + CRYPT_BUFFER_OVERFLOW, /* Not enough space for output */ + CRYPT_INVALID_PACKET, /* Invalid input packet given */ + + CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */ + CRYPT_ERROR_READPRNG, /* Could not read enough from PRNG */ + + CRYPT_INVALID_CIPHER, /* Invalid cipher specified */ + CRYPT_INVALID_HASH, /* Invalid hash specified */ + CRYPT_INVALID_PRNG, /* Invalid PRNG specified */ + + CRYPT_MEM, /* Out of memory */ + + CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */ + CRYPT_PK_NOT_PRIVATE, /* Requires a private PK key */ + + CRYPT_INVALID_ARG, /* Generic invalid argument */ + CRYPT_FILE_NOTFOUND, /* File Not Found */ + + CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */ + CRYPT_PK_INVALID_SYSTEM,/* Invalid PK system specified */ + CRYPT_PK_DUP, /* Duplicate key already in key ring */ + CRYPT_PK_NOT_FOUND, /* Key not found in keyring */ + CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */ + + CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */ + CRYPT_PK_INVALID_PADDING /* Invalid padding on input */ +}; + +#include "tomcrypt_cfg.h" +#include "tomcrypt_macros.h" +#include "tomcrypt_cipher.h" +#include "tomcrypt_hash.h" +#include "tomcrypt_mac.h" +#include "tomcrypt_prng.h" +#include "tomcrypt_pk.h" +#include "tomcrypt_math.h" +#include "tomcrypt_misc.h" +#include "tomcrypt_argchk.h" +#include "tomcrypt_pkcs.h" + +#ifdef __cplusplus + } +#endif + +#endif /* TOMCRYPT_H_ */ + + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt.h,v $ */ +/* $Revision: 1.21 $ */ +/* $Date: 2006/12/16 19:34:05 $ */ diff --git a/StormLib/src/libtomcrypt/src/headers/tomcrypt_argchk.h b/StormLib/src/libtomcrypt/src/headers/tomcrypt_argchk.h new file mode 100644 index 000000000..cfc93ad7e --- /dev/null +++ b/StormLib/src/libtomcrypt/src/headers/tomcrypt_argchk.h @@ -0,0 +1,38 @@ +/* Defines the LTC_ARGCHK macro used within the library */ +/* ARGTYPE is defined in mycrypt_cfg.h */ +#if ARGTYPE == 0 + +#include + +/* this is the default LibTomCrypt macro */ +void crypt_argchk(char *v, char *s, int d); +#define LTC_ARGCHK(x) if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) + +#elif ARGTYPE == 1 + +/* fatal type of error */ +#define LTC_ARGCHK(x) assert((x)) +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) + +#elif ARGTYPE == 2 + +#define LTC_ARGCHK(x) if (!(x)) { fprintf(stderr, "\nwarning: ARGCHK failed at %s:%d\n", __FILE__, __LINE__); } +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) + +#elif ARGTYPE == 3 + +#define LTC_ARGCHK(x) +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) + +#elif ARGTYPE == 4 + +#define LTC_ARGCHK(x) if (!(x)) return CRYPT_INVALID_ARG; +#define LTC_ARGCHKVD(x) if (!(x)) return; + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_argchk.h,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/08/27 20:50:21 $ */ diff --git a/StormLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h b/StormLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h new file mode 100644 index 000000000..335d55f06 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h @@ -0,0 +1,144 @@ +/* This is the build config file. + * + * With this you can setup what to inlcude/exclude automatically during any build. Just comment + * out the line that #define's the word for the thing you want to remove. phew! + */ + +#ifndef TOMCRYPT_CFG_H +#define TOMCRYPT_CFG_H + +#if defined(_WIN32) || defined(_MSC_VER) +#define LTC_CALL __cdecl +#else +#ifndef LTC_CALL + #define LTC_CALL +#endif +#endif + +#ifndef LTC_EXPORT +#define LTC_EXPORT +#endif + +/* certain platforms use macros for these, making the prototypes broken */ +#ifndef LTC_NO_PROTOTYPES + +/* you can change how memory allocation works ... */ +LTC_EXPORT void * LTC_CALL XMALLOC(size_t n); +LTC_EXPORT void * LTC_CALL XREALLOC(void *p, size_t n); +LTC_EXPORT void * LTC_CALL XCALLOC(size_t n, size_t s); +LTC_EXPORT void LTC_CALL XFREE(void *p); + +LTC_EXPORT void LTC_CALL XQSORT(void *base, size_t nmemb, size_t size, int(LTC_CALL * compar)(const void *, const void *)); + +/* change the clock function too */ +LTC_EXPORT clock_t LTC_CALL XCLOCK(void); +#endif // LTC_NO_PROTOTYPES + +/* various other functions */ +#ifndef LTC_NO_PROTOTYPES_MEMCPY +LTC_EXPORT void * LTC_CALL XMEMCPY(void *dest, const void *src, size_t n); +#endif + +#ifndef LTC_NO_PROTOTYPES_MEMCMP +LTC_EXPORT int LTC_CALL XMEMCMP(const void *s1, const void *s2, size_t n); +#endif + +#ifndef LTC_NO_PROTOTYPES_MEMSET +LTC_EXPORT void * LTC_CALL XMEMSET(void *s, int c, size_t n); +#endif + +#ifndef LTC_NO_PROTOTYPES_STRCMP +LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2); +#endif + +/* type of argument checking, 0=default, 1=fatal and 2=error+continue, 3=nothing */ +#ifndef ARGTYPE + #define ARGTYPE 0 +#endif + +/* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code + * + * Note: in order to use the optimized macros your platform must support unaligned 32 and 64 bit read/writes. + * The x86 platforms allow this but some others [ARM for instance] do not. On those platforms you **MUST** + * use the portable [slower] macros. + */ + +/* detect x86-32 machines somewhat */ +#if !defined(__STRICT_ANSI__) && (defined(INTEL_CC) || (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__)))) + #define ENDIAN_LITTLE + #define ENDIAN_32BITWORD + #define LTC_FAST + #define LTC_FAST_TYPE unsigned long +#endif + +/* detects MIPS R5900 processors (PS2) */ +#if (defined(__R5900) || defined(R5900) || defined(__R5900__)) && (defined(_mips) || defined(__mips__) || defined(mips)) + #define ENDIAN_LITTLE + #define ENDIAN_64BITWORD +#endif + +/* detect amd64 */ +#if !defined(__STRICT_ANSI__) && defined(__x86_64__) + #define ENDIAN_LITTLE + #define ENDIAN_64BITWORD + #define LTC_FAST + #define LTC_FAST_TYPE unsigned long +#endif + +/* detect PPC32 */ +#if !defined(__STRICT_ANSI__) && defined(LTC_PPC32) + #define ENDIAN_BIG + #define ENDIAN_32BITWORD + #define LTC_FAST + #define LTC_FAST_TYPE unsigned long +#endif + +/* detect sparc and sparc64 */ +#if defined(__sparc__) + #define ENDIAN_BIG + #if defined(__arch64__) + #define ENDIAN_64BITWORD + #else + #define ENDIAN_32BITWORD + #endif +#endif + + +#ifdef LTC_NO_FAST + #ifdef LTC_FAST + #undef LTC_FAST + #endif +#endif + +/* No asm is a quick way to disable anything "not portable" */ +#ifdef LTC_NO_ASM + #undef ENDIAN_LITTLE + #undef ENDIAN_BIG + #undef ENDIAN_32BITWORD + #undef ENDIAN_64BITWORD + #undef LTC_FAST + #undef LTC_FAST_TYPE + #define LTC_NO_ROLC + #define LTC_NO_BSWAP +#endif + +/* #define ENDIAN_LITTLE */ +/* #define ENDIAN_BIG */ + +/* #define ENDIAN_32BITWORD */ +/* #define ENDIAN_64BITWORD */ + +#if (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD)) + #error You must specify a word size as well as endianess in tomcrypt_cfg.h +#endif + +#if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) + #define ENDIAN_NEUTRAL +#endif + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_cfg.h,v $ */ +/* $Revision: 1.19 $ */ +/* $Date: 2006/12/04 02:19:48 $ */ diff --git a/StormLib/src/libtomcrypt/src/headers/tomcrypt_cipher.h b/StormLib/src/libtomcrypt/src/headers/tomcrypt_cipher.h new file mode 100644 index 000000000..bd740bf4a --- /dev/null +++ b/StormLib/src/libtomcrypt/src/headers/tomcrypt_cipher.h @@ -0,0 +1,891 @@ +/* ---- SYMMETRIC KEY STUFF ----- + * + * We put each of the ciphers scheduled keys in their own structs then we put all of + * the key formats in one union. This makes the function prototypes easier to use. + */ +#ifdef LTC_BLOWFISH +struct blowfish_key { + ulong32 S[4][256]; + ulong32 K[18]; +}; +#endif + +#ifdef LTC_RC5 +struct rc5_key { + int rounds; + ulong32 K[50]; +}; +#endif + +#ifdef LTC_RC6 +struct rc6_key { + ulong32 K[44]; +}; +#endif + +#ifdef LTC_SAFERP +struct saferp_key { + unsigned char K[33][16]; + long rounds; +}; +#endif + +#ifdef LTC_RIJNDAEL +struct rijndael_key { + ulong32 eK[60], dK[60]; + int Nr; +}; +#endif + +#ifdef LTC_KSEED +struct kseed_key { + ulong32 K[32], dK[32]; +}; +#endif + +#ifdef LTC_KASUMI +struct kasumi_key { + ulong32 KLi1[8], KLi2[8], + KOi1[8], KOi2[8], KOi3[8], + KIi1[8], KIi2[8], KIi3[8]; +}; +#endif + +#ifdef LTC_XTEA +struct xtea_key { + unsigned long A[32], B[32]; +}; +#endif + +#ifdef LTC_TWOFISH +#ifndef LTC_TWOFISH_SMALL + struct twofish_key { + ulong32 S[4][256], K[40]; + }; +#else + struct twofish_key { + ulong32 K[40]; + unsigned char S[32], start; + }; +#endif +#endif + +#ifdef LTC_SAFER +#define LTC_SAFER_K64_DEFAULT_NOF_ROUNDS 6 +#define LTC_SAFER_K128_DEFAULT_NOF_ROUNDS 10 +#define LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS 8 +#define LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS 10 +#define LTC_SAFER_MAX_NOF_ROUNDS 13 +#define LTC_SAFER_BLOCK_LEN 8 +#define LTC_SAFER_KEY_LEN (1 + LTC_SAFER_BLOCK_LEN * (1 + 2 * LTC_SAFER_MAX_NOF_ROUNDS)) +typedef unsigned char safer_block_t[LTC_SAFER_BLOCK_LEN]; +typedef unsigned char safer_key_t[LTC_SAFER_KEY_LEN]; +struct safer_key { safer_key_t key; }; +#endif + +#ifdef LTC_RC2 +struct rc2_key { unsigned xkey[64]; }; +#endif + +#ifdef LTC_DES +struct des_key { + ulong32 ek[32], dk[32]; +}; + +struct des3_key { + ulong32 ek[3][32], dk[3][32]; +}; +#endif + +#ifdef LTC_CAST5 +struct cast5_key { + ulong32 K[32], keylen; +}; +#endif + +#ifdef LTC_NOEKEON +struct noekeon_key { + ulong32 K[4], dK[4]; +}; +#endif + +#ifdef LTC_SKIPJACK +struct skipjack_key { + unsigned char key[10]; +}; +#endif + +#ifdef LTC_KHAZAD +struct khazad_key { + ulong64 roundKeyEnc[8 + 1]; + ulong64 roundKeyDec[8 + 1]; +}; +#endif + +#ifdef LTC_ANUBIS +struct anubis_key { + int keyBits; + int R; + ulong32 roundKeyEnc[18 + 1][4]; + ulong32 roundKeyDec[18 + 1][4]; +}; +#endif + +#ifdef LTC_MULTI2 +struct multi2_key { + int N; + ulong32 uk[8]; +}; +#endif + +typedef union Symmetric_key { +#ifdef LTC_DES + struct des_key des; + struct des3_key des3; +#endif +#ifdef LTC_RC2 + struct rc2_key rc2; +#endif +#ifdef LTC_SAFER + struct safer_key safer; +#endif +#ifdef LTC_TWOFISH + struct twofish_key twofish; +#endif +#ifdef LTC_BLOWFISH + struct blowfish_key blowfish; +#endif +#ifdef LTC_RC5 + struct rc5_key rc5; +#endif +#ifdef LTC_RC6 + struct rc6_key rc6; +#endif +#ifdef LTC_SAFERP + struct saferp_key saferp; +#endif +#ifdef LTC_RIJNDAEL + struct rijndael_key rijndael; +#endif +#ifdef LTC_XTEA + struct xtea_key xtea; +#endif +#ifdef LTC_CAST5 + struct cast5_key cast5; +#endif +#ifdef LTC_NOEKEON + struct noekeon_key noekeon; +#endif +#ifdef LTC_SKIPJACK + struct skipjack_key skipjack; +#endif +#ifdef LTC_KHAZAD + struct khazad_key khazad; +#endif +#ifdef LTC_ANUBIS + struct anubis_key anubis; +#endif +#ifdef LTC_KSEED + struct kseed_key kseed; +#endif +#ifdef LTC_KASUMI + struct kasumi_key kasumi; +#endif +#ifdef LTC_MULTI2 + struct multi2_key multi2; +#endif + void *data; +} symmetric_key; + +#ifdef LTC_ECB_MODE +/** A block cipher ECB structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen; + /** The scheduled key */ + symmetric_key key; +} symmetric_ECB; +#endif + +#ifdef LTC_CFB_MODE +/** A block cipher CFB structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, + /** The padding offset */ + padlen; + /** The current IV */ + unsigned char IV[MAXBLOCKSIZE], + /** The pad used to encrypt/decrypt */ + pad[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; +} symmetric_CFB; +#endif + +#ifdef LTC_OFB_MODE +/** A block cipher OFB structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, + /** The padding offset */ + padlen; + /** The current IV */ + unsigned char IV[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; +} symmetric_OFB; +#endif + +#ifdef LTC_CBC_MODE +/** A block cipher CBC structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen; + /** The current IV */ + unsigned char IV[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; +} symmetric_CBC; +#endif + + +#ifdef LTC_CTR_MODE +/** A block cipher CTR structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, + /** The padding offset */ + padlen, + /** The mode (endianess) of the CTR, 0==little, 1==big */ + mode, + /** counter width */ + ctrlen; + + /** The counter */ + unsigned char ctr[MAXBLOCKSIZE], + /** The pad used to encrypt/decrypt */ + pad[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; +} symmetric_CTR; +#endif + + +#ifdef LTC_LRW_MODE +/** A LRW structure */ +typedef struct { + /** The index of the cipher chosen (must be a 128-bit block cipher) */ + int cipher; + + /** The current IV */ + unsigned char IV[16], + + /** the tweak key */ + tweak[16], + + /** The current pad, it's the product of the first 15 bytes against the tweak key */ + pad[16]; + + /** The scheduled symmetric key */ + symmetric_key key; + +#ifdef LRW_TABLES + /** The pre-computed multiplication table */ + unsigned char PC[16][256][16]; +#endif +} symmetric_LRW; +#endif + +#ifdef LTC_F8_MODE +/** A block cipher F8 structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, + /** The padding offset */ + padlen; + /** The current IV */ + unsigned char IV[MAXBLOCKSIZE], + MIV[MAXBLOCKSIZE]; + /** Current block count */ + ulong32 blockcnt; + /** The scheduled key */ + symmetric_key key; +} symmetric_F8; +#endif + + +/** cipher descriptor table, last entry has "name == NULL" to mark the end of table */ +extern struct ltc_cipher_descriptor { + /** name of cipher */ + char *name; + /** internal ID */ + unsigned char ID; + /** min keysize (octets) */ + int min_key_length, + /** max keysize (octets) */ + max_key_length, + /** block size (octets) */ + block_length, + /** default number of rounds */ + default_rounds; + /** Setup the cipher + @param key The input symmetric key + @param keylen The length of the input key (octets) + @param num_rounds The requested number of rounds (0==default) + @param skey [out] The destination of the scheduled key + @return CRYPT_OK if successful + */ + int (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); + /** Encrypt a block + @param pt The plaintext + @param ct [out] The ciphertext + @param skey The scheduled key + @return CRYPT_OK if successful + */ + int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); + /** Decrypt a block + @param ct The ciphertext + @param pt [out] The plaintext + @param skey The scheduled key + @return CRYPT_OK if successful + */ + int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); + /** Test the block cipher + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled + */ + int (*test)(void); + + /** Terminate the context + @param skey The scheduled key + */ + void (*done)(symmetric_key *skey); + + /** Determine a key size + @param keysize [in/out] The size of the key desired and the suggested size + @return CRYPT_OK if successful + */ + int (*keysize)(int *keysize); + +/** Accelerators **/ + /** Accelerated ECB encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey); + + /** Accelerated ECB decryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey); + + /** Accelerated CBC encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey); + + /** Accelerated CBC decryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey); + + /** Accelerated CTR encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param mode little or big endian counter (mode=0 or mode=1) + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey); + + /** Accelerated LRW + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param tweak The LRW tweak + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_lrw_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey); + + /** Accelerated LRW + @param ct Ciphertext + @param pt Plaintext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param tweak The LRW tweak + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_lrw_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey); + + /** Accelerated CCM packet (one-shot) + @param key The secret key to use + @param keylen The length of the secret key (octets) + @param uskey A previously scheduled key [optional can be NULL] + @param nonce The session nonce [use once] + @param noncelen The length of the nonce + @param header The header for the session + @param headerlen The length of the header (octets) + @param pt [out] The plaintext + @param ptlen The length of the plaintext (octets) + @param ct [out] The ciphertext + @param tag [out] The destination tag + @param taglen [in/out] The max size and resulting size of the authentication tag + @param direction Encrypt or Decrypt direction (0 or 1) + @return CRYPT_OK if successful + */ + int (*accel_ccm_memory)( + const unsigned char *key, unsigned long keylen, + symmetric_key *uskey, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); + + /** Accelerated GCM packet (one shot) + @param key The secret key + @param keylen The length of the secret key + @param IV The initial vector + @param IVlen The length of the initial vector + @param adata The additional authentication data (header) + @param adatalen The length of the adata + @param pt The plaintext + @param ptlen The length of the plaintext (ciphertext length is the same) + @param ct The ciphertext + @param tag [out] The MAC tag + @param taglen [in/out] The MAC tag length + @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) + @return CRYPT_OK on success + */ + int (*accel_gcm_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *IV, unsigned long IVlen, + const unsigned char *adata, unsigned long adatalen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); + + /** Accelerated one shot LTC_OMAC + @param key The secret key + @param keylen The key length (octets) + @param in The message + @param inlen Length of message (octets) + @param out [out] Destination for tag + @param outlen [in/out] Initial and final size of out + @return CRYPT_OK on success + */ + int (*omac_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + + /** Accelerated one shot XCBC + @param key The secret key + @param keylen The key length (octets) + @param in The message + @param inlen Length of message (octets) + @param out [out] Destination for tag + @param outlen [in/out] Initial and final size of out + @return CRYPT_OK on success + */ + int (*xcbc_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + + /** Accelerated one shot F9 + @param key The secret key + @param keylen The key length (octets) + @param in The message + @param inlen Length of message (octets) + @param out [out] Destination for tag + @param outlen [in/out] Initial and final size of out + @return CRYPT_OK on success + @remark Requires manual padding + */ + int (*f9_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +} cipher_descriptor[]; + +#ifdef LTC_BLOWFISH +int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int blowfish_test(void); +void blowfish_done(symmetric_key *skey); +int blowfish_keysize(int *keysize); +extern const struct ltc_cipher_descriptor blowfish_desc; +#endif + +#ifdef LTC_RC5 +int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int rc5_test(void); +void rc5_done(symmetric_key *skey); +int rc5_keysize(int *keysize); +extern const struct ltc_cipher_descriptor rc5_desc; +#endif + +#ifdef LTC_RC6 +int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int rc6_test(void); +void rc6_done(symmetric_key *skey); +int rc6_keysize(int *keysize); +extern const struct ltc_cipher_descriptor rc6_desc; +#endif + +#ifdef LTC_RC2 +int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int rc2_test(void); +void rc2_done(symmetric_key *skey); +int rc2_keysize(int *keysize); +extern const struct ltc_cipher_descriptor rc2_desc; +#endif + +#ifdef LTC_SAFERP +int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int saferp_test(void); +void saferp_done(symmetric_key *skey); +int saferp_keysize(int *keysize); +extern const struct ltc_cipher_descriptor saferp_desc; +#endif + +#ifdef LTC_SAFER +int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +int safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +int safer_k64_test(void); +int safer_sk64_test(void); +int safer_sk128_test(void); +void safer_done(symmetric_key *skey); +int safer_64_keysize(int *keysize); +int safer_128_keysize(int *keysize); +extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk64_desc, safer_sk128_desc; +#endif + +#ifdef LTC_RIJNDAEL + +/* make aes an alias */ +#define aes_setup rijndael_setup +#define aes_ecb_encrypt rijndael_ecb_encrypt +#define aes_ecb_decrypt rijndael_ecb_decrypt +#define aes_test rijndael_test +#define aes_done rijndael_done +#define aes_keysize rijndael_keysize + +#define aes_enc_setup rijndael_enc_setup +#define aes_enc_ecb_encrypt rijndael_enc_ecb_encrypt +#define aes_enc_keysize rijndael_enc_keysize + +int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int rijndael_test(void); +void rijndael_done(symmetric_key *skey); +int rijndael_keysize(int *keysize); +int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +void rijndael_enc_done(symmetric_key *skey); +int rijndael_enc_keysize(int *keysize); +extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc; +extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc; +#endif + +#ifdef LTC_XTEA +int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int xtea_test(void); +void xtea_done(symmetric_key *skey); +int xtea_keysize(int *keysize); +extern const struct ltc_cipher_descriptor xtea_desc; +#endif + +#ifdef LTC_TWOFISH +int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int twofish_test(void); +void twofish_done(symmetric_key *skey); +int twofish_keysize(int *keysize); +extern const struct ltc_cipher_descriptor twofish_desc; +#endif + +#ifdef LTC_DES +int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int des_test(void); +void des_done(symmetric_key *skey); +int des_keysize(int *keysize); +int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int des3_test(void); +void des3_done(symmetric_key *skey); +int des3_keysize(int *keysize); +extern const struct ltc_cipher_descriptor des_desc, des3_desc; +#endif + +#ifdef LTC_CAST5 +int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int cast5_test(void); +void cast5_done(symmetric_key *skey); +int cast5_keysize(int *keysize); +extern const struct ltc_cipher_descriptor cast5_desc; +#endif + +#ifdef LTC_NOEKEON +int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int noekeon_test(void); +void noekeon_done(symmetric_key *skey); +int noekeon_keysize(int *keysize); +extern const struct ltc_cipher_descriptor noekeon_desc; +#endif + +#ifdef LTC_SKIPJACK +int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int skipjack_test(void); +void skipjack_done(symmetric_key *skey); +int skipjack_keysize(int *keysize); +extern const struct ltc_cipher_descriptor skipjack_desc; +#endif + +#ifdef LTC_KHAZAD +int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int khazad_test(void); +void khazad_done(symmetric_key *skey); +int khazad_keysize(int *keysize); +extern const struct ltc_cipher_descriptor khazad_desc; +#endif + +#ifdef LTC_ANUBIS +int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int anubis_test(void); +void anubis_done(symmetric_key *skey); +int anubis_keysize(int *keysize); +extern const struct ltc_cipher_descriptor anubis_desc; +#endif + +#ifdef LTC_KSEED +int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int kseed_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int kseed_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int kseed_test(void); +void kseed_done(symmetric_key *skey); +int kseed_keysize(int *keysize); +extern const struct ltc_cipher_descriptor kseed_desc; +#endif + +#ifdef LTC_KASUMI +int kasumi_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int kasumi_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int kasumi_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int kasumi_test(void); +void kasumi_done(symmetric_key *skey); +int kasumi_keysize(int *keysize); +extern const struct ltc_cipher_descriptor kasumi_desc; +#endif + + +#ifdef LTC_MULTI2 +int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int multi2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int multi2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int multi2_test(void); +void multi2_done(symmetric_key *skey); +int multi2_keysize(int *keysize); +extern const struct ltc_cipher_descriptor multi2_desc; +#endif + +#ifdef LTC_ECB_MODE +int ecb_start(int cipher, const unsigned char *key, + int keylen, int num_rounds, symmetric_ECB *ecb); +int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb); +int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb); +int ecb_done(symmetric_ECB *ecb); +#endif + +#ifdef LTC_CFB_MODE +int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CFB *cfb); +int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb); +int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb); +int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb); +int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb); +int cfb_done(symmetric_CFB *cfb); +#endif + +#ifdef LTC_OFB_MODE +int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_OFB *ofb); +int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb); +int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb); +int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb); +int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb); +int ofb_done(symmetric_OFB *ofb); +#endif + +#ifdef LTC_CBC_MODE +int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CBC *cbc); +int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc); +int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc); +int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc); +int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc); +int cbc_done(symmetric_CBC *cbc); +#endif + +#ifdef LTC_CTR_MODE + +#define CTR_COUNTER_LITTLE_ENDIAN 0x0000 +#define CTR_COUNTER_BIG_ENDIAN 0x1000 +#define LTC_CTR_RFC3686 0x2000 + +int ctr_start( int cipher, + const unsigned char *IV, + const unsigned char *key, int keylen, + int num_rounds, int ctr_mode, + symmetric_CTR *ctr); +int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr); +int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr); +int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr); +int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr); +int ctr_done(symmetric_CTR *ctr); +int ctr_test(void); +#endif + +#ifdef LTC_LRW_MODE + +#define LRW_ENCRYPT 0 +#define LRW_DECRYPT 1 + +int lrw_start( int cipher, + const unsigned char *IV, + const unsigned char *key, int keylen, + const unsigned char *tweak, + int num_rounds, + symmetric_LRW *lrw); +int lrw_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_LRW *lrw); +int lrw_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_LRW *lrw); +int lrw_getiv(unsigned char *IV, unsigned long *len, symmetric_LRW *lrw); +int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw); +int lrw_done(symmetric_LRW *lrw); +int lrw_test(void); + +/* don't call */ +int lrw_process(const unsigned char *pt, unsigned char *ct, unsigned long len, int mode, symmetric_LRW *lrw); +#endif + +#ifdef LTC_F8_MODE +int f8_start( int cipher, const unsigned char *IV, + const unsigned char *key, int keylen, + const unsigned char *salt_key, int skeylen, + int num_rounds, symmetric_F8 *f8); +int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_F8 *f8); +int f8_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_F8 *f8); +int f8_getiv(unsigned char *IV, unsigned long *len, symmetric_F8 *f8); +int f8_setiv(const unsigned char *IV, unsigned long len, symmetric_F8 *f8); +int f8_done(symmetric_F8 *f8); +int f8_test_mode(void); +#endif + +#ifdef LTC_XTS_MODE +typedef struct { + symmetric_key key1, key2; + int cipher; +} symmetric_xts; + +int xts_start( int cipher, + const unsigned char *key1, + const unsigned char *key2, + unsigned long keylen, + int num_rounds, + symmetric_xts *xts); + +int xts_encrypt( + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + const unsigned char *tweak, + symmetric_xts *xts); +int xts_decrypt( + const unsigned char *ct, unsigned long ptlen, + unsigned char *pt, + const unsigned char *tweak, + symmetric_xts *xts); + +void xts_done(symmetric_xts *xts); +int xts_test(void); +void xts_mult_x(unsigned char *I); +#endif + +int find_cipher(const char *name); +int find_cipher_any(const char *name, int blocklen, int keylen); +int find_cipher_id(unsigned char ID); +int register_cipher(const struct ltc_cipher_descriptor *cipher); +int unregister_cipher(const struct ltc_cipher_descriptor *cipher); +int cipher_is_valid(int idx); + +LTC_MUTEX_PROTO(ltc_cipher_mutex) + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_cipher.h,v $ */ +/* $Revision: 1.54 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/StormLib/src/libtomcrypt/src/headers/tomcrypt_custom.h b/StormLib/src/libtomcrypt/src/headers/tomcrypt_custom.h new file mode 100644 index 000000000..312a4c256 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/headers/tomcrypt_custom.h @@ -0,0 +1,424 @@ +#ifndef TOMCRYPT_CUSTOM_H_ +#define TOMCRYPT_CUSTOM_H_ + +#define LTC_NO_CIPHERS +#define LTC_NO_HASHES +#define LTC_NO_MACS +#define LTC_NO_PRNGS +#define LTC_NO_CURVES +#define LTC_NO_MODES +#define LTC_NO_PKCS +#define LTC_NO_ROLC + +#define LTC_SOURCE +#define LTC_SHA1 +#define LTC_MD5 +#define LTC_DER +#define LTC_RC4 + +#define USE_LTM +#define LTM_DESC + +/* macros for various libc functions you can change for embedded targets */ +#ifndef XMALLOC + #ifdef malloc + #define LTC_NO_PROTOTYPES + #endif +#define XMALLOC LibTomMalloc +#endif +#ifndef XREALLOC + #ifdef realloc + #define LTC_NO_PROTOTYPES + #endif +#define XREALLOC LibTomRealloc +#endif +#ifndef XCALLOC + #ifdef calloc + #define LTC_NO_PROTOTYPES + #endif +#define XCALLOC LibTomCalloc +#endif +#ifndef XFREE + #ifdef free + #define LTC_NO_PROTOTYPES + #endif +#define XFREE LibTomFree +#endif + +#ifndef XMEMSET + #ifdef memset + #define LTC_NO_PROTOTYPES_MEMSET + #endif +#define XMEMSET memset +#endif +#ifndef XMEMCPY + #ifdef memcpy + #define LTC_NO_PROTOTYPES_MEMCPY + #endif +#define XMEMCPY memcpy +#endif +#ifndef XMEMCMP + #ifdef memcmp + #define LTC_NO_PROTOTYPES_MEMCMP + #endif +#define XMEMCMP memcmp +#endif +#ifndef XSTRCMP + #ifdef strcmp + #define LTC_NO_PROTOTYPES_STRCMP + #endif +#define XSTRCMP strcmp +#endif + +#ifndef XCLOCK +#define XCLOCK LibTomClock +#endif +#ifndef XCLOCKS_PER_SEC +#define XCLOCKS_PER_SEC CLOCKS_PER_SEC +#endif + +#ifndef XQSORT + #ifdef qsort + #define LTC_NO_PROTOTYPES + #endif +#define XQSORT LibTomQsort +#endif + +/* Easy button? */ +#ifdef LTC_EASY + #define LTC_NO_CIPHERS + #define LTC_RIJNDAEL + #define LTC_BLOWFISH + #define LTC_DES + #define LTC_CAST5 + + #define LTC_NO_MODES + #define LTC_ECB_MODE + #define LTC_CBC_MODE + #define LTC_CTR_MODE + + #define LTC_NO_HASHES + #define LTC_SHA1 + #define LTC_SHA512 + #define LTC_SHA384 + #define LTC_SHA256 + #define LTC_SHA224 + + #define LTC_NO_MACS + #define LTC_HMAC + #define LTC_OMAC + #define LTC_CCM_MODE + + #define LTC_NO_PRNGS + #define LTC_SPRNG + #define LTC_YARROW + #define LTC_DEVRANDOM + #define TRY_URANDOM_FIRST + + #define LTC_NO_PK + #define LTC_MRSA + #define LTC_MECC +#endif + +/* Use small code where possible */ +/* #define LTC_SMALL_CODE */ + +/* Enable self-test test vector checking */ +#ifndef LTC_NO_TEST + #define LTC_TEST +#endif + +/* clean the stack of functions which put private information on stack */ +/* #define LTC_CLEAN_STACK */ + +/* disable all file related functions */ +/* #define LTC_NO_FILE */ + +/* disable all forms of ASM */ +/* #define LTC_NO_ASM */ + +/* disable FAST mode */ +/* #define LTC_NO_FAST */ + +/* disable BSWAP on x86 */ +/* #define LTC_NO_BSWAP */ + +/* ---> Symmetric Block Ciphers <--- */ +#ifndef LTC_NO_CIPHERS + +#define LTC_BLOWFISH +#define LTC_RC2 +#define LTC_RC5 +#define LTC_RC6 +#define LTC_SAFERP +#define LTC_RIJNDAEL +#define LTC_XTEA +/* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format + * (saves 4KB of ram), _ALL_TABLES enables all tables during setup */ +#define LTC_TWOFISH +#ifndef LTC_NO_TABLES + #define LTC_TWOFISH_TABLES + /* #define LTC_TWOFISH_ALL_TABLES */ +#else + #define LTC_TWOFISH_SMALL +#endif +/* #define LTC_TWOFISH_SMALL */ +/* LTC_DES includes EDE triple-LTC_DES */ +#define LTC_DES +#define LTC_CAST5 +#define LTC_NOEKEON +#define LTC_SKIPJACK +#define LTC_SAFER +#define LTC_KHAZAD +#define LTC_ANUBIS +#define LTC_ANUBIS_TWEAK +#define LTC_KSEED +#define LTC_KASUMI + +#endif /* LTC_NO_CIPHERS */ + + +/* ---> Block Cipher Modes of Operation <--- */ +#ifndef LTC_NO_MODES + +#define LTC_CFB_MODE +#define LTC_OFB_MODE +#define LTC_ECB_MODE +#define LTC_CBC_MODE +#define LTC_CTR_MODE + +/* F8 chaining mode */ +#define LTC_F8_MODE + +/* LRW mode */ +#define LTC_LRW_MODE +#ifndef LTC_NO_TABLES + /* like GCM mode this will enable 16 8x128 tables [64KB] that make + * seeking very fast. + */ + #define LRW_TABLES +#endif + +/* XTS mode */ +#define LTC_XTS_MODE + +#endif /* LTC_NO_MODES */ + +/* ---> One-Way Hash Functions <--- */ +#ifndef LTC_NO_HASHES + +#define LTC_CHC_HASH +#define LTC_WHIRLPOOL +#define LTC_SHA512 +#define LTC_SHA384 +#define LTC_SHA256 +#define LTC_SHA224 +#define LTC_TIGER +#define LTC_SHA1 +#define LTC_MD5 +#define LTC_MD4 +#define LTC_MD2 +#define LTC_RIPEMD128 +#define LTC_RIPEMD160 +#define LTC_RIPEMD256 +#define LTC_RIPEMD320 + +#endif /* LTC_NO_HASHES */ + +/* ---> MAC functions <--- */ +#ifndef LTC_NO_MACS + +#define LTC_HMAC +#define LTC_OMAC +#define LTC_PMAC +#define LTC_XCBC +#define LTC_F9_MODE +#define LTC_PELICAN + +#if defined(LTC_PELICAN) && !defined(LTC_RIJNDAEL) + #error Pelican-MAC requires LTC_RIJNDAEL +#endif + +/* ---> Encrypt + Authenticate Modes <--- */ + +#define LTC_EAX_MODE +#if defined(LTC_EAX_MODE) && !(defined(LTC_CTR_MODE) && defined(LTC_OMAC)) + #error LTC_EAX_MODE requires CTR and LTC_OMAC mode +#endif + +#define LTC_OCB_MODE +#define LTC_CCM_MODE +#define LTC_GCM_MODE + +/* Use 64KiB tables */ +#ifndef LTC_NO_TABLES + #define LTC_GCM_TABLES +#endif + +/* USE SSE2? requires GCC works on x86_32 and x86_64*/ +#ifdef LTC_GCM_TABLES +/* #define LTC_GCM_TABLES_SSE2 */ +#endif + +#endif /* LTC_NO_MACS */ + +/* Various tidbits of modern neatoness */ +#define LTC_BASE64 + +/* --> Pseudo Random Number Generators <--- */ +#ifndef LTC_NO_PRNGS + +/* Yarrow */ +#define LTC_YARROW +/* which descriptor of AES to use? */ +/* 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full] */ +#define LTC_YARROW_AES 0 + +#if defined(LTC_YARROW) && !defined(LTC_CTR_MODE) + #error LTC_YARROW requires LTC_CTR_MODE chaining mode to be defined! +#endif + +/* a PRNG that simply reads from an available system source */ +#define LTC_SPRNG + +/* The LTC_RC4 stream cipher */ +#define LTC_RC4 + +/* Fortuna PRNG */ +#define LTC_FORTUNA +/* reseed every N calls to the read function */ +#define LTC_FORTUNA_WD 10 +/* number of pools (4..32) can save a bit of ram by lowering the count */ +#define LTC_FORTUNA_POOLS 32 + +/* Greg's LTC_SOBER128 PRNG ;-0 */ +#define LTC_SOBER128 + +/* the *nix style /dev/random device */ +#define LTC_DEVRANDOM +/* try /dev/urandom before trying /dev/random */ +#define TRY_URANDOM_FIRST + +#endif /* LTC_NO_PRNGS */ + +/* ---> math provider? <--- */ +#ifndef LTC_NO_MATH + +/* LibTomMath */ +#define LTM_LTC_DESC + +/* TomsFastMath */ +//#define TFM_LTC_DESC + +#endif /* LTC_NO_MATH */ + +/* ---> Public Key Crypto <--- */ +#ifndef LTC_NO_PK + +/* Include RSA support */ +#define LTC_MRSA + +/* Include Katja (a Rabin variant like RSA) */ +/* #define MKAT */ + +/* Digital Signature Algorithm */ +#define LTC_MDSA + +/* ECC */ +#define LTC_MECC + +/* use Shamir's trick for point mul (speeds up signature verification) */ +#define LTC_ECC_SHAMIR + +#if defined(TFM_LTC_DESC) && defined(LTC_MECC) + #define LTC_MECC_ACCEL +#endif + +/* do we want fixed point ECC */ +/* #define LTC_MECC_FP */ + +/* Timing Resistant? */ +/* #define LTC_ECC_TIMING_RESISTANT */ + +#endif /* LTC_NO_PK */ + +/* LTC_PKCS #1 (RSA) and #5 (Password Handling) stuff */ +#ifndef LTC_NO_PKCS + +#define LTC_PKCS_1 +#define LTC_PKCS_5 + +/* Include ASN.1 DER (required by DSA/RSA) */ +#define LTC_DER + +#endif /* LTC_NO_PKCS */ + +/* cleanup */ + +#ifdef LTC_MECC +/* Supported ECC Key Sizes */ +#ifndef LTC_NO_CURVES + #define ECC112 + #define ECC128 + #define ECC160 + #define ECC192 + #define ECC224 + #define ECC256 + #define ECC384 + #define ECC521 +#endif +#endif + +#if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(MKATJA) + /* Include the MPI functionality? (required by the PK algorithms) */ + #define MPI +#endif + +#ifdef LTC_MRSA + #define LTC_PKCS_1 +#endif + +#if defined(LTC_DER) && !defined(MPI) + #error ASN.1 DER requires MPI functionality +#endif + +#if (defined(LTC_MDSA) || defined(LTC_MRSA) || defined(LTC_MECC) || defined(MKATJA)) && !defined(LTC_DER) + #error PK requires ASN.1 DER functionality, make sure LTC_DER is enabled +#endif + +/* THREAD management */ +#ifdef LTC_PTHREAD + +#include + +#define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER; +#define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x; +#define LTC_MUTEX_TYPE(x) pthread_mutex_t x; +#define LTC_MUTEX_INIT(x) pthread_mutex_init(x, NULL); +#define LTC_MUTEX_LOCK(x) pthread_mutex_lock(x); +#define LTC_MUTEX_UNLOCK(x) pthread_mutex_unlock(x); + +#else + +/* default no functions */ +#define LTC_MUTEX_GLOBAL(x) +#define LTC_MUTEX_PROTO(x) +#define LTC_MUTEX_TYPE(x) +#define LTC_MUTEX_INIT(x) +#define LTC_MUTEX_LOCK(x) +#define LTC_MUTEX_UNLOCK(x) + +#endif + +/* Debuggers */ + +/* define this if you use Valgrind, note: it CHANGES the way SOBER-128 and LTC_RC4 work (see the code) */ +/* #define LTC_VALGRIND */ + +#endif + + + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_custom.h,v $ */ +/* $Revision: 1.73 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/StormLib/src/libtomcrypt/src/headers/tomcrypt_hash.h b/StormLib/src/libtomcrypt/src/headers/tomcrypt_hash.h new file mode 100644 index 000000000..18553ebf9 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/headers/tomcrypt_hash.h @@ -0,0 +1,378 @@ +/* ---- HASH FUNCTIONS ---- */ +#ifdef LTC_SHA512 +struct sha512_state { + ulong64 length, state[8]; + unsigned long curlen; + unsigned char buf[128]; +}; +#endif + +#ifdef LTC_SHA256 +struct sha256_state { + ulong64 length; + ulong32 state[8], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_SHA1 +struct sha1_state { + ulong64 length; + ulong32 state[5], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_MD5 +struct md5_state { + ulong64 length; + ulong32 state[4], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_MD4 +struct md4_state { + ulong64 length; + ulong32 state[4], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_TIGER +struct tiger_state { + ulong64 state[3], length; + unsigned long curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_MD2 +struct md2_state { + unsigned char chksum[16], X[48], buf[16]; + unsigned long curlen; +}; +#endif + +#ifdef LTC_RIPEMD128 +struct rmd128_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[4]; +}; +#endif + +#ifdef LTC_RIPEMD160 +struct rmd160_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[5]; +}; +#endif + +#ifdef LTC_RIPEMD256 +struct rmd256_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[8]; +}; +#endif + +#ifdef LTC_RIPEMD320 +struct rmd320_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[10]; +}; +#endif + +#ifdef LTC_WHIRLPOOL +struct whirlpool_state { + ulong64 length, state[8]; + unsigned char buf[64]; + ulong32 curlen; +}; +#endif + +#ifdef LTC_CHC_HASH +struct chc_state { + ulong64 length; + unsigned char state[MAXBLOCKSIZE], buf[MAXBLOCKSIZE]; + ulong32 curlen; +}; +#endif + +typedef union Hash_state { +#ifdef LTC_CHC_HASH + struct chc_state chc; +#endif +#ifdef LTC_WHIRLPOOL + struct whirlpool_state whirlpool; +#endif +#ifdef LTC_SHA512 + struct sha512_state sha512; +#endif +#ifdef LTC_SHA256 + struct sha256_state sha256; +#endif +#ifdef LTC_SHA1 + struct sha1_state sha1; +#endif +#ifdef LTC_MD5 + struct md5_state md5; +#endif +#ifdef LTC_MD4 + struct md4_state md4; +#endif +#ifdef LTC_MD2 + struct md2_state md2; +#endif +#ifdef LTC_TIGER + struct tiger_state tiger; +#endif +#ifdef LTC_RIPEMD128 + struct rmd128_state rmd128; +#endif +#ifdef LTC_RIPEMD160 + struct rmd160_state rmd160; +#endif +#ifdef LTC_RIPEMD256 + struct rmd256_state rmd256; +#endif +#ifdef LTC_RIPEMD320 + struct rmd320_state rmd320; +#endif + void *data; +} hash_state; + +/** hash descriptor */ +extern struct ltc_hash_descriptor { + /** name of hash */ + char *name; + /** internal ID */ + unsigned char ID; + /** Size of digest in octets */ + unsigned long hashsize; + /** Input block size in octets */ + unsigned long blocksize; + /** ASN.1 OID */ + unsigned long OID[16]; + /** Length of DER encoding */ + unsigned long OIDlen; + + /** Init a hash state + @param hash The hash to initialize + @return CRYPT_OK if successful + */ + int (*init)(hash_state *hash); + /** Process a block of data + @param hash The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful + */ + int (*process)(hash_state *hash, const unsigned char *in, unsigned long inlen); + /** Produce the digest and store it + @param hash The hash state + @param out [out] The destination of the digest + @return CRYPT_OK if successful + */ + int (*done)(hash_state *hash, unsigned char *out); + /** Self-test + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled + */ + int (*test)(void); + + /* accelerated hmac callback: if you need to-do multiple packets just use the generic hmac_memory and provide a hash callback */ + int (*hmac_block)(const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +} hash_descriptor[]; + +#ifdef LTC_CHC_HASH +int chc_register(int cipher); +int chc_init(hash_state * md); +int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int chc_done(hash_state * md, unsigned char *hash); +int chc_test(void); +extern const struct ltc_hash_descriptor chc_desc; +#endif + +#ifdef LTC_WHIRLPOOL +int whirlpool_init(hash_state * md); +int whirlpool_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int whirlpool_done(hash_state * md, unsigned char *hash); +int whirlpool_test(void); +extern const struct ltc_hash_descriptor whirlpool_desc; +#endif + +#ifdef LTC_SHA512 +int sha512_init(hash_state * md); +int sha512_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha512_done(hash_state * md, unsigned char *hash); +int sha512_test(void); +extern const struct ltc_hash_descriptor sha512_desc; +#endif + +#ifdef LTC_SHA384 +#ifndef LTC_SHA512 + #error LTC_SHA512 is required for LTC_SHA384 +#endif +int sha384_init(hash_state * md); +#define sha384_process sha512_process +int sha384_done(hash_state * md, unsigned char *hash); +int sha384_test(void); +extern const struct ltc_hash_descriptor sha384_desc; +#endif + +#ifdef LTC_SHA256 +int sha256_init(hash_state * md); +int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha256_done(hash_state * md, unsigned char *hash); +int sha256_test(void); +extern const struct ltc_hash_descriptor sha256_desc; + +#ifdef LTC_SHA224 +#ifndef LTC_SHA256 + #error LTC_SHA256 is required for LTC_SHA224 +#endif +int sha224_init(hash_state * md); +#define sha224_process sha256_process +int sha224_done(hash_state * md, unsigned char *hash); +int sha224_test(void); +extern const struct ltc_hash_descriptor sha224_desc; +#endif +#endif + +#ifdef LTC_SHA1 +int sha1_init(hash_state * md); +int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha1_done(hash_state * md, unsigned char *hash); +int sha1_test(void); +extern const struct ltc_hash_descriptor sha1_desc; +#endif + +#ifdef LTC_MD5 +int md5_init(hash_state * md); +int md5_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int md5_done(hash_state * md, unsigned char *hash); +int md5_test(void); +extern const struct ltc_hash_descriptor md5_desc; +#endif + +#ifdef LTC_MD4 +int md4_init(hash_state * md); +int md4_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int md4_done(hash_state * md, unsigned char *hash); +int md4_test(void); +extern const struct ltc_hash_descriptor md4_desc; +#endif + +#ifdef LTC_MD2 +int md2_init(hash_state * md); +int md2_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int md2_done(hash_state * md, unsigned char *hash); +int md2_test(void); +extern const struct ltc_hash_descriptor md2_desc; +#endif + +#ifdef LTC_TIGER +int tiger_init(hash_state * md); +int tiger_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int tiger_done(hash_state * md, unsigned char *hash); +int tiger_test(void); +extern const struct ltc_hash_descriptor tiger_desc; +#endif + +#ifdef LTC_RIPEMD128 +int rmd128_init(hash_state * md); +int rmd128_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int rmd128_done(hash_state * md, unsigned char *hash); +int rmd128_test(void); +extern const struct ltc_hash_descriptor rmd128_desc; +#endif + +#ifdef LTC_RIPEMD160 +int rmd160_init(hash_state * md); +int rmd160_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int rmd160_done(hash_state * md, unsigned char *hash); +int rmd160_test(void); +extern const struct ltc_hash_descriptor rmd160_desc; +#endif + +#ifdef LTC_RIPEMD256 +int rmd256_init(hash_state * md); +int rmd256_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int rmd256_done(hash_state * md, unsigned char *hash); +int rmd256_test(void); +extern const struct ltc_hash_descriptor rmd256_desc; +#endif + +#ifdef LTC_RIPEMD320 +int rmd320_init(hash_state * md); +int rmd320_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int rmd320_done(hash_state * md, unsigned char *hash); +int rmd320_test(void); +extern const struct ltc_hash_descriptor rmd320_desc; +#endif + + +int find_hash(const char *name); +int find_hash_id(unsigned char ID); +int find_hash_oid(const unsigned long *ID, unsigned long IDlen); +int find_hash_any(const char *name, int digestlen); +int register_hash(const struct ltc_hash_descriptor *hash); +int unregister_hash(const struct ltc_hash_descriptor *hash); +int hash_is_valid(int idx); + +LTC_MUTEX_PROTO(ltc_hash_mutex) + +int hash_memory(int hash, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); +int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen); +int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen); + +/* a simple macro for making hash "process" functions */ +#define HASH_PROCESS(func_name, compress_name, state_var, block_size) \ +int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) \ +{ \ + unsigned long n; \ + int err; \ + LTC_ARGCHK(md != NULL); \ + LTC_ARGCHK(in != NULL); \ + if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \ + return CRYPT_INVALID_ARG; \ + } \ + while (inlen > 0) { \ + if (md-> state_var .curlen == 0 && inlen >= block_size) { \ + if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) { \ + return err; \ + } \ + md-> state_var .length += block_size * 8; \ + in += block_size; \ + inlen -= block_size; \ + } else { \ + n = MIN(inlen, (block_size - md-> state_var .curlen)); \ + memcpy(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n); \ + md-> state_var .curlen += n; \ + in += n; \ + inlen -= n; \ + if (md-> state_var .curlen == block_size) { \ + if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) { \ + return err; \ + } \ + md-> state_var .length += 8*block_size; \ + md-> state_var .curlen = 0; \ + } \ + } \ + } \ + return CRYPT_OK; \ +} + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_hash.h,v $ */ +/* $Revision: 1.22 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/headers/tomcrypt_mac.h b/StormLib/src/libtomcrypt/src/headers/tomcrypt_mac.h new file mode 100644 index 000000000..7ad9516bd --- /dev/null +++ b/StormLib/src/libtomcrypt/src/headers/tomcrypt_mac.h @@ -0,0 +1,384 @@ +#ifdef LTC_HMAC +typedef struct Hmac_state { + hash_state md; + int hash; + hash_state hashstate; + unsigned char *key; +} hmac_state; + +int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen); +int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen); +int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen); +int hmac_test(void); +int hmac_memory(int hash, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int hmac_memory_multi(int hash, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); +int hmac_file(int hash, const char *fname, const unsigned char *key, + unsigned long keylen, + unsigned char *dst, unsigned long *dstlen); +#endif + +#ifdef LTC_OMAC + +typedef struct { + int cipher_idx, + buflen, + blklen; + unsigned char block[MAXBLOCKSIZE], + prev[MAXBLOCKSIZE], + Lu[2][MAXBLOCKSIZE]; + symmetric_key key; +} omac_state; + +int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen); +int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen); +int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen); +int omac_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int omac_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); +int omac_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +int omac_test(void); +#endif /* LTC_OMAC */ + +#ifdef LTC_PMAC + +typedef struct { + unsigned char Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ + Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */ + Lr[MAXBLOCKSIZE], /* L * x^-1 */ + block[MAXBLOCKSIZE], /* currently accumulated block */ + checksum[MAXBLOCKSIZE]; /* current checksum */ + + symmetric_key key; /* scheduled key for cipher */ + unsigned long block_index; /* index # for current block */ + int cipher_idx, /* cipher idx */ + block_len, /* length of block */ + buflen; /* number of bytes in the buffer */ +} pmac_state; + +int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen); +int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen); +int pmac_done(pmac_state *pmac, unsigned char *out, unsigned long *outlen); + +int pmac_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *msg, unsigned long msglen, + unsigned char *out, unsigned long *outlen); + +int pmac_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); + +int pmac_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); + +int pmac_test(void); + +/* internal functions */ +int pmac_ntz(unsigned long x); +void pmac_shift_xor(pmac_state *pmac); + +#endif /* PMAC */ + +#ifdef LTC_EAX_MODE + +#if !(defined(LTC_OMAC) && defined(LTC_CTR_MODE)) + #error LTC_EAX_MODE requires LTC_OMAC and CTR +#endif + +typedef struct { + unsigned char N[MAXBLOCKSIZE]; + symmetric_CTR ctr; + omac_state headeromac, ctomac; +} eax_state; + +int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen); + +int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length); +int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length); +int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length); +int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen); + +int eax_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +int eax_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + unsigned char *tag, unsigned long taglen, + int *stat); + + int eax_test(void); +#endif /* EAX MODE */ + +#ifdef LTC_OCB_MODE +typedef struct { + unsigned char L[MAXBLOCKSIZE], /* L value */ + Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ + Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */ + Lr[MAXBLOCKSIZE], /* L * x^-1 */ + R[MAXBLOCKSIZE], /* R value */ + checksum[MAXBLOCKSIZE]; /* current checksum */ + + symmetric_key key; /* scheduled key for cipher */ + unsigned long block_index; /* index # for current block */ + int cipher, /* cipher idx */ + block_len; /* length of block */ +} ocb_state; + +int ocb_init(ocb_state *ocb, int cipher, + const unsigned char *key, unsigned long keylen, const unsigned char *nonce); + +int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct); +int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt); + +int ocb_done_encrypt(ocb_state *ocb, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +int ocb_done_decrypt(ocb_state *ocb, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, int *stat); + +int ocb_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +int ocb_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, + int *stat); + +int ocb_test(void); + +/* internal functions */ +void ocb_shift_xor(ocb_state *ocb, unsigned char *Z); +int ocb_ntz(unsigned long x); +int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode); + +#endif /* LTC_OCB_MODE */ + +#ifdef LTC_CCM_MODE + +#define CCM_ENCRYPT 0 +#define CCM_DECRYPT 1 + +int ccm_memory(int cipher, + const unsigned char *key, unsigned long keylen, + symmetric_key *uskey, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); + +int ccm_test(void); + +#endif /* LTC_CCM_MODE */ + +#if defined(LRW_MODE) || defined(LTC_GCM_MODE) +void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c); +#endif + + +/* table shared between GCM and LRW */ +#if defined(LTC_GCM_TABLES) || defined(LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST)) +extern const unsigned char gcm_shift_table[]; +#endif + +#ifdef LTC_GCM_MODE + +#define GCM_ENCRYPT 0 +#define GCM_DECRYPT 1 + +#define LTC_GCM_MODE_IV 0 +#define LTC_GCM_MODE_AAD 1 +#define LTC_GCM_MODE_TEXT 2 + +typedef struct { + symmetric_key K; + unsigned char H[16], /* multiplier */ + X[16], /* accumulator */ + Y[16], /* counter */ + Y_0[16], /* initial counter */ + buf[16]; /* buffer for stuff */ + + int cipher, /* which cipher */ + ivmode, /* Which mode is the IV in? */ + mode, /* mode the GCM code is in */ + buflen; /* length of data in buf */ + + ulong64 totlen, /* 64-bit counter used for IV and AAD */ + pttotlen; /* 64-bit counter for the PT */ + +#ifdef LTC_GCM_TABLES + unsigned char PC[16][256][16] /* 16 tables of 8x128 */ +#ifdef LTC_GCM_TABLES_SSE2 +__attribute__ ((aligned (16))) +#endif +; +#endif +} gcm_state; + +void gcm_mult_h(gcm_state *gcm, unsigned char *I); + +int gcm_init(gcm_state *gcm, int cipher, + const unsigned char *key, int keylen); + +int gcm_reset(gcm_state *gcm); + +int gcm_add_iv(gcm_state *gcm, + const unsigned char *IV, unsigned long IVlen); + +int gcm_add_aad(gcm_state *gcm, + const unsigned char *adata, unsigned long adatalen); + +int gcm_process(gcm_state *gcm, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + int direction); + +int gcm_done(gcm_state *gcm, + unsigned char *tag, unsigned long *taglen); + +int gcm_memory( int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *IV, unsigned long IVlen, + const unsigned char *adata, unsigned long adatalen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); +int gcm_test(void); + +#endif /* LTC_GCM_MODE */ + +#ifdef LTC_PELICAN + +typedef struct pelican_state +{ + symmetric_key K; + unsigned char state[16]; + int buflen; +} pelican_state; + +int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen); +int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen); +int pelican_done(pelican_state *pelmac, unsigned char *out); +int pelican_test(void); + +int pelican_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out); + +#endif + +#ifdef LTC_XCBC + +/* add this to "keylen" to xcbc_init to use a pure three-key XCBC MAC */ +#define LTC_XCBC_PURE 0x8000UL + +typedef struct { + unsigned char K[3][MAXBLOCKSIZE], + IV[MAXBLOCKSIZE]; + + symmetric_key key; + + int cipher, + buflen, + blocksize; +} xcbc_state; + +int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen); +int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen); +int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen); +int xcbc_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int xcbc_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); +int xcbc_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +int xcbc_test(void); + +#endif + +#ifdef LTC_F9_MODE + +typedef struct { + unsigned char akey[MAXBLOCKSIZE], + ACC[MAXBLOCKSIZE], + IV[MAXBLOCKSIZE]; + + symmetric_key key; + + int cipher, + buflen, + keylen, + blocksize; +} f9_state; + +int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen); +int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen); +int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen); +int f9_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int f9_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); +int f9_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +int f9_test(void); + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_mac.h,v $ */ +/* $Revision: 1.23 $ */ +/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/StormLib/src/libtomcrypt/src/headers/tomcrypt_macros.h b/StormLib/src/libtomcrypt/src/headers/tomcrypt_macros.h new file mode 100644 index 000000000..53bda9bb4 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/headers/tomcrypt_macros.h @@ -0,0 +1,424 @@ +/* fix for MSVC ...evil! */ +#ifdef _MSC_VER + #define CONST64(n) n ## ui64 + typedef unsigned __int64 ulong64; +#else + #define CONST64(n) n ## ULL + typedef unsigned long long ulong64; +#endif + +/* this is the "32-bit at least" data type + * Re-define it to suit your platform but it must be at least 32-bits + */ +#if defined(__x86_64__) || (defined(__sparc__) && defined(__arch64__)) + typedef unsigned ulong32; +#else + typedef unsigned long ulong32; +#endif + +/* ---- HELPER MACROS ---- */ +#ifdef ENDIAN_NEUTRAL + +#define STORE32L(x, y) \ + { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD32L(x, y) \ + { x = ((unsigned long)((y)[3] & 255)<<24) | \ + ((unsigned long)((y)[2] & 255)<<16) | \ + ((unsigned long)((y)[1] & 255)<<8) | \ + ((unsigned long)((y)[0] & 255)); } + +#define STORE64L(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#define STORE32H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } + +#define LOAD32H(x, y) \ + { x = ((unsigned long)((y)[0] & 255)<<24) | \ + ((unsigned long)((y)[1] & 255)<<16) | \ + ((unsigned long)((y)[2] & 255)<<8) | \ + ((unsigned long)((y)[3] & 255)); } + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } + +#endif /* ENDIAN_NEUTRAL */ + +#ifdef ENDIAN_LITTLE + +#if !defined(LTC_NO_BSWAP) && (defined(INTEL_CC) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__) || defined(__x86_64__)))) + +#define STORE32H(x, y) \ +asm __volatile__ ( \ + "bswapl %0 \n\t" \ + "movl %0,(%1)\n\t" \ + "bswapl %0 \n\t" \ + ::"r"(x), "r"(y)); + +#define LOAD32H(x, y) \ +asm __volatile__ ( \ + "movl (%1),%0\n\t" \ + "bswapl %0\n\t" \ + :"=r"(x): "r"(y)); + +#else + +#define STORE32H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } + +#define LOAD32H(x, y) \ + { x = ((unsigned long)((y)[0] & 255)<<24) | \ + ((unsigned long)((y)[1] & 255)<<16) | \ + ((unsigned long)((y)[2] & 255)<<8) | \ + ((unsigned long)((y)[3] & 255)); } + +#endif + + +/* x86_64 processor */ +#if !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__)) + +#define STORE64H(x, y) \ +asm __volatile__ ( \ + "bswapq %0 \n\t" \ + "movq %0,(%1)\n\t" \ + "bswapq %0 \n\t" \ + ::"r"(x), "r"(y)); + +#define LOAD64H(x, y) \ +asm __volatile__ ( \ + "movq (%1),%0\n\t" \ + "bswapq %0\n\t" \ + :"=r"(x): "r"(y)); + +#else + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } + +#endif + +#ifdef ENDIAN_32BITWORD + +#define STORE32L(x, y) \ + { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } + +#define LOAD32L(x, y) \ + XMEMCPY(&(x), y, 4); + +#define STORE64L(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#else /* 64-bit words then */ + +#define STORE32L(x, y) \ + { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } + +#define LOAD32L(x, y) \ + { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } + +#define STORE64L(x, y) \ + { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } + +#define LOAD64L(x, y) \ + { XMEMCPY(&(x), y, 8); } + +#endif /* ENDIAN_64BITWORD */ + +#endif /* ENDIAN_LITTLE */ + +#ifdef ENDIAN_BIG +#define STORE32L(x, y) \ + { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD32L(x, y) \ + { x = ((unsigned long)((y)[3] & 255)<<24) | \ + ((unsigned long)((y)[2] & 255)<<16) | \ + ((unsigned long)((y)[1] & 255)<<8) | \ + ((unsigned long)((y)[0] & 255)); } + +#define STORE64L(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#ifdef ENDIAN_32BITWORD + +#define STORE32H(x, y) \ + { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } + +#define LOAD32H(x, y) \ + XMEMCPY(&(x), y, 4); + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \ + (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); } + +#else /* 64-bit words then */ + +#define STORE32H(x, y) \ + { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } + +#define LOAD32H(x, y) \ + { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } + +#define STORE64H(x, y) \ + { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } + +#define LOAD64H(x, y) \ + { XMEMCPY(&(x), y, 8); } + +#endif /* ENDIAN_64BITWORD */ +#endif /* ENDIAN_BIG */ + +#define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \ + ((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) ) + + +/* 32-bit Rotates */ +#if defined(_MSC_VER) + +/* instrinsic rotate */ +#include +#pragma intrinsic(_lrotr,_lrotl) +#define ROR(x,n) _lrotr(x,n) +#define ROL(x,n) _lrotl(x,n) +#define RORc(x,n) _lrotr(x,n) +#define ROLc(x,n) _lrotl(x,n) + +#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(LTC_NO_ASM) + +static inline unsigned ROL(unsigned word, int i) +{ + asm ("roll %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +static inline unsigned ROR(unsigned word, int i) +{ + asm ("rorl %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +#ifndef LTC_NO_ROLC + +static inline unsigned ROLc(unsigned word, const int i) +{ + asm ("roll %2,%0" + :"=r" (word) + :"0" (word),"I" (i)); + return word; +} + +static inline unsigned RORc(unsigned word, const int i) +{ + asm ("rorl %2,%0" + :"=r" (word) + :"0" (word),"I" (i)); + return word; +} + +#else + +#define ROLc ROL +#define RORc ROR + +#endif + +#elif !defined(__STRICT_ANSI__) && defined(LTC_PPC32) + +static inline unsigned ROL(unsigned word, int i) +{ + asm ("rotlw %0,%0,%2" + :"=r" (word) + :"0" (word),"r" (i)); + return word; +} + +static inline unsigned ROR(unsigned word, int i) +{ + asm ("rotlw %0,%0,%2" + :"=r" (word) + :"0" (word),"r" (32-i)); + return word; +} + +#ifndef LTC_NO_ROLC + +static inline unsigned ROLc(unsigned word, const int i) +{ + asm ("rotlwi %0,%0,%2" + :"=r" (word) + :"0" (word),"I" (i)); + return word; +} + +static inline unsigned RORc(unsigned word, const int i) +{ + asm ("rotrwi %0,%0,%2" + :"=r" (word) + :"0" (word),"I" (i)); + return word; +} + +#else + +#define ROLc ROL +#define RORc ROR + +#endif + + +#else + +/* rotates the hard way */ +#define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) +#define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) +#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) +#define RORc(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) + +#endif + + +/* 64-bit Rotates */ +#if !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__x86_64__) && !defined(LTC_NO_ASM) + +static inline unsigned long ROL64(unsigned long word, int i) +{ + asm("rolq %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +static inline unsigned long ROR64(unsigned long word, int i) +{ + asm("rorq %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +#ifndef LTC_NO_ROLC + +static inline unsigned long ROL64c(unsigned long word, const int i) +{ + asm("rolq %2,%0" + :"=r" (word) + :"0" (word),"J" (i)); + return word; +} + +static inline unsigned long ROR64c(unsigned long word, const int i) +{ + asm("rorq %2,%0" + :"=r" (word) + :"0" (word),"J" (i)); + return word; +} + +#else /* LTC_NO_ROLC */ + +#define ROL64c ROL64 +#define ROR64c ROR64 + +#endif + +#else /* Not x86_64 */ + +#define ROL64(x, y) \ + ( (((x)<<((ulong64)(y)&63)) | \ + (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#define ROR64(x, y) \ + ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ + ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#define ROL64c(x, y) \ + ( (((x)<<((ulong64)(y)&63)) | \ + (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#define ROR64c(x, y) \ + ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ + ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#endif + +#ifndef MAX + #define MAX(x, y) ( ((x)>(y))?(x):(y) ) +#endif + +#ifndef MIN + #define MIN(x, y) ( ((x)<(y))?(x):(y) ) +#endif + +/* extract a byte portably */ +#ifdef _MSC_VER + #define byte(x, n) ((unsigned char)((x) >> (8 * (n)))) +#else + #define byte(x, n) (((x) >> (8 * (n))) & 255) +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_macros.h,v $ */ +/* $Revision: 1.15 $ */ +/* $Date: 2006/11/29 23:43:57 $ */ diff --git a/StormLib/src/libtomcrypt/src/headers/tomcrypt_math.h b/StormLib/src/libtomcrypt/src/headers/tomcrypt_math.h new file mode 100644 index 000000000..a05d7fff9 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/headers/tomcrypt_math.h @@ -0,0 +1,500 @@ +/** math functions **/ + +#define LTC_MP_LT -1 +#define LTC_MP_EQ 0 +#define LTC_MP_GT 1 + +#define LTC_MP_NO 0 +#define LTC_MP_YES 1 + +#ifndef LTC_MECC + typedef void ecc_point; +#endif + +#ifndef LTC_MRSA + typedef void rsa_key; +#endif + +/** math descriptor */ +typedef struct { + /** Name of the math provider */ + char *name; + + /** Bits per digit, amount of bits must fit in an unsigned long */ + int bits_per_digit; + +/* ---- init/deinit functions ---- */ + + /** initialize a bignum + @param a The number to initialize + @return CRYPT_OK on success + */ + int (*init)(void **a); + + /** init copy + @param dst The number to initialize and write to + @param src The number to copy from + @return CRYPT_OK on success + */ + int (*init_copy)(void **dst, void *src); + + /** deinit + @param a The number to free + @return CRYPT_OK on success + */ + void (*deinit)(void *a); + +/* ---- data movement ---- */ + + /** negate + @param src The number to negate + @param dst The destination + @return CRYPT_OK on success + */ + int (*neg)(void *src, void *dst); + + /** copy + @param src The number to copy from + @param dst The number to write to + @return CRYPT_OK on success + */ + int (*copy)(void *src, void *dst); + +/* ---- trivial low level functions ---- */ + + /** set small constant + @param a Number to write to + @param n Source upto bits_per_digit (actually meant for very small constants) + @return CRYPT_OK on succcess + */ + int (*set_int)(void *a, unsigned long n); + + /** get small constant + @param a Number to read, only fetches upto bits_per_digit from the number + @return The lower bits_per_digit of the integer (unsigned) + */ + unsigned long (*get_int)(void *a); + + /** get digit n + @param a The number to read from + @param n The number of the digit to fetch + @return The bits_per_digit sized n'th digit of a + */ + unsigned long (*get_digit)(void *a, int n); + + /** Get the number of digits that represent the number + @param a The number to count + @return The number of digits used to represent the number + */ + int (*get_digit_count)(void *a); + + /** compare two integers + @param a The left side integer + @param b The right side integer + @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison) + */ + int (*compare)(void *a, void *b); + + /** compare against int + @param a The left side integer + @param b The right side integer (upto bits_per_digit) + @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison) + */ + int (*compare_d)(void *a, unsigned long n); + + /** Count the number of bits used to represent the integer + @param a The integer to count + @return The number of bits required to represent the integer + */ + int (*count_bits)(void * a); + + /** Count the number of LSB bits which are zero + @param a The integer to count + @return The number of contiguous zero LSB bits + */ + int (*count_lsb_bits)(void *a); + + /** Compute a power of two + @param a The integer to store the power in + @param n The power of two you want to store (a = 2^n) + @return CRYPT_OK on success + */ + int (*twoexpt)(void *a , int n); + +/* ---- radix conversions ---- */ + + /** read ascii string + @param a The integer to store into + @param str The string to read + @param radix The radix the integer has been represented in (2-64) + @return CRYPT_OK on success + */ + int (*read_radix)(void *a, const char *str, int radix); + + /** write number to string + @param a The integer to store + @param str The destination for the string + @param radix The radix the integer is to be represented in (2-64) + @return CRYPT_OK on success + */ + int (*write_radix)(void *a, char *str, int radix); + + /** get size as unsigned char string + @param a The integer to get the size (when stored in array of octets) + @return The length of the integer + */ + unsigned long (*unsigned_size)(void *a); + + /** store an integer as an array of octets + @param src The integer to store + @param dst The buffer to store the integer in + @return CRYPT_OK on success + */ + int (*unsigned_write)(void *src, unsigned char *dst); + + /** read an array of octets and store as integer + @param dst The integer to load + @param src The array of octets + @param len The number of octets + @return CRYPT_OK on success + */ + int (*unsigned_read)(void *dst, unsigned char *src, unsigned long len); + +/* ---- basic math ---- */ + + /** add two integers + @param a The first source integer + @param b The second source integer + @param c The destination of "a + b" + @return CRYPT_OK on success + */ + int (*add)(void *a, void *b, void *c); + + + /** add two integers + @param a The first source integer + @param b The second source integer (single digit of upto bits_per_digit in length) + @param c The destination of "a + b" + @return CRYPT_OK on success + */ + int (*addi)(void *a, unsigned long b, void *c); + + /** subtract two integers + @param a The first source integer + @param b The second source integer + @param c The destination of "a - b" + @return CRYPT_OK on success + */ + int (*sub)(void *a, void *b, void *c); + + /** subtract two integers + @param a The first source integer + @param b The second source integer (single digit of upto bits_per_digit in length) + @param c The destination of "a - b" + @return CRYPT_OK on success + */ + int (*subi)(void *a, unsigned long b, void *c); + + /** multiply two integers + @param a The first source integer + @param b The second source integer (single digit of upto bits_per_digit in length) + @param c The destination of "a * b" + @return CRYPT_OK on success + */ + int (*mul)(void *a, void *b, void *c); + + /** multiply two integers + @param a The first source integer + @param b The second source integer (single digit of upto bits_per_digit in length) + @param c The destination of "a * b" + @return CRYPT_OK on success + */ + int (*muli)(void *a, unsigned long b, void *c); + + /** Square an integer + @param a The integer to square + @param b The destination + @return CRYPT_OK on success + */ + int (*sqr)(void *a, void *b); + + /** Divide an integer + @param a The dividend + @param b The divisor + @param c The quotient (can be NULL to signify don't care) + @param d The remainder (can be NULL to signify don't care) + @return CRYPT_OK on success + */ + int (*mpdiv)(void *a, void *b, void *c, void *d); + + /** divide by two + @param a The integer to divide (shift right) + @param b The destination + @return CRYPT_OK on success + */ + int (*div_2)(void *a, void *b); + + /** Get remainder (small value) + @param a The integer to reduce + @param b The modulus (upto bits_per_digit in length) + @param c The destination for the residue + @return CRYPT_OK on success + */ + int (*modi)(void *a, unsigned long b, unsigned long *c); + + /** gcd + @param a The first integer + @param b The second integer + @param c The destination for (a, b) + @return CRYPT_OK on success + */ + int (*gcd)(void *a, void *b, void *c); + + /** lcm + @param a The first integer + @param b The second integer + @param c The destination for [a, b] + @return CRYPT_OK on success + */ + int (*lcm)(void *a, void *b, void *c); + + /** Modular multiplication + @param a The first source + @param b The second source + @param c The modulus + @param d The destination (a*b mod c) + @return CRYPT_OK on success + */ + int (*mulmod)(void *a, void *b, void *c, void *d); + + /** Modular squaring + @param a The first source + @param b The modulus + @param c The destination (a*a mod b) + @return CRYPT_OK on success + */ + int (*sqrmod)(void *a, void *b, void *c); + + /** Modular inversion + @param a The value to invert + @param b The modulus + @param c The destination (1/a mod b) + @return CRYPT_OK on success + */ + int (*invmod)(void *, void *, void *); + +/* ---- reduction ---- */ + + /** setup montgomery + @param a The modulus + @param b The destination for the reduction digit + @return CRYPT_OK on success + */ + int (*montgomery_setup)(void *a, void **b); + + /** get normalization value + @param a The destination for the normalization value + @param b The modulus + @return CRYPT_OK on success + */ + int (*montgomery_normalization)(void *a, void *b); + + /** reduce a number + @param a The number [and dest] to reduce + @param b The modulus + @param c The value "b" from montgomery_setup() + @return CRYPT_OK on success + */ + int (*montgomery_reduce)(void *a, void *b, void *c); + + /** clean up (frees memory) + @param a The value "b" from montgomery_setup() + @return CRYPT_OK on success + */ + void (*montgomery_deinit)(void *a); + +/* ---- exponentiation ---- */ + + /** Modular exponentiation + @param a The base integer + @param b The power (can be negative) integer + @param c The modulus integer + @param d The destination + @return CRYPT_OK on success + */ + int (*exptmod)(void *a, void *b, void *c, void *d); + + /** Primality testing + @param a The integer to test + @param b The destination of the result (FP_YES if prime) + @return CRYPT_OK on success + */ + int (*isprime)(void *a, int *b); + +/* ---- (optional) ecc point math ---- */ + + /** ECC GF(p) point multiplication (from the NIST curves) + @param k The integer to multiply the point by + @param G The point to multiply + @param R The destination for kG + @param modulus The modulus for the field + @param map Boolean indicated whether to map back to affine or not (can be ignored if you work in affine only) + @return CRYPT_OK on success + */ + int (*ecc_ptmul)(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); + + /** ECC GF(p) point addition + @param P The first point + @param Q The second point + @param R The destination of P + Q + @param modulus The modulus + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success + */ + int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp); + + /** ECC GF(p) point double + @param P The first point + @param R The destination of 2P + @param modulus The modulus + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success + */ + int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *modulus, void *mp); + + /** ECC mapping from projective to affine, currently uses (x,y,z) => (x/z^2, y/z^3, 1) + @param P The point to map + @param modulus The modulus + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success + @remark The mapping can be different but keep in mind a ecc_point only has three + integers (x,y,z) so if you use a different mapping you have to make it fit. + */ + int (*ecc_map)(ecc_point *P, void *modulus, void *mp); + + /** Computes kA*A + kB*B = C using Shamir's Trick + @param A First point to multiply + @param kA What to multiple A by + @param B Second point to multiply + @param kB What to multiple B by + @param C [out] Destination point (can overlap with A or B + @param modulus Modulus for curve + @return CRYPT_OK on success + */ + int (*ecc_mul2add)(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, + void *modulus); + +/* ---- (optional) rsa optimized math (for internal CRT) ---- */ + + /** RSA Key Generation + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param size The size of the modulus (key size) desired (octets) + @param e The "e" value (public key). e==65537 is a good choice + @param key [out] Destination of a newly created private key pair + @return CRYPT_OK if successful, upon error all allocated ram is freed + */ + int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key); + + + /** RSA exponentiation + @param in The octet array representing the base + @param inlen The length of the input + @param out The destination (to be stored in an octet array format) + @param outlen The length of the output buffer and the resulting size (zero padded to the size of the modulus) + @param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA + @param key The RSA key to use + @return CRYPT_OK on success + */ + int (*rsa_me)(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + rsa_key *key); +} ltc_math_descriptor; + +extern ltc_math_descriptor ltc_mp; + +int ltc_init_multi(void **a, ...); +void ltc_deinit_multi(void *a, ...); + +#ifdef LTM_DESC +extern const ltc_math_descriptor ltm_desc; +#endif + +#ifdef TFM_DESC +extern const ltc_math_descriptor tfm_desc; +#endif + +#ifdef GMP_DESC +extern const ltc_math_descriptor gmp_desc; +#endif + +#if !defined(DESC_DEF_ONLY) && defined(LTC_SOURCE) + +#define MP_DIGIT_BIT ltc_mp.bits_per_digit + +/* some handy macros */ +#define mp_init(a) ltc_mp.init(a) +#define mp_init_multi ltc_init_multi +#define mp_clear(a) ltc_mp.deinit(a) +#define mp_clear_multi ltc_deinit_multi +#define mp_init_copy(a, b) ltc_mp.init_copy(a, b) + +#define mp_neg(a, b) ltc_mp.neg(a, b) +#define mp_copy(a, b) ltc_mp.copy(a, b) + +#define mp_set(a, b) ltc_mp.set_int(a, b) +#define mp_set_int(a, b) ltc_mp.set_int(a, b) +#define mp_get_int(a) ltc_mp.get_int(a) +#define mp_get_digit(a, n) ltc_mp.get_digit(a, n) +#define mp_get_digit_count(a) ltc_mp.get_digit_count(a) +#define mp_cmp(a, b) ltc_mp.compare(a, b) +#define mp_cmp_d(a, b) ltc_mp.compare_d(a, b) +#define mp_count_bits(a) ltc_mp.count_bits(a) +#define mp_cnt_lsb(a) ltc_mp.count_lsb_bits(a) +#define mp_2expt(a, b) ltc_mp.twoexpt(a, b) + +#define mp_read_radix(a, b, c) ltc_mp.read_radix(a, b, c) +#define mp_toradix(a, b, c) ltc_mp.write_radix(a, b, c) +#define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a) +#define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b) +#define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c) + +#define mp_add(a, b, c) ltc_mp.add(a, b, c) +#define mp_add_d(a, b, c) ltc_mp.addi(a, b, c) +#define mp_sub(a, b, c) ltc_mp.sub(a, b, c) +#define mp_sub_d(a, b, c) ltc_mp.subi(a, b, c) +#define mp_mul(a, b, c) ltc_mp.mul(a, b, c) +#define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c) +#define mp_sqr(a, b) ltc_mp.sqr(a, b) +#define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d) +#define mp_div_2(a, b) ltc_mp.div_2(a, b) +#define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c) +#define mp_mod_d(a, b, c) ltc_mp.modi(a, b, c) +#define mp_gcd(a, b, c) ltc_mp.gcd(a, b, c) +#define mp_lcm(a, b, c) ltc_mp.lcm(a, b, c) + +#define mp_mulmod(a, b, c, d) ltc_mp.mulmod(a, b, c, d) +#define mp_sqrmod(a, b, c) ltc_mp.sqrmod(a, b, c) +#define mp_invmod(a, b, c) ltc_mp.invmod(a, b, c) + +#define mp_montgomery_setup(a, b) ltc_mp.montgomery_setup(a, b) +#define mp_montgomery_normalization(a, b) ltc_mp.montgomery_normalization(a, b) +#define mp_montgomery_reduce(a, b, c) ltc_mp.montgomery_reduce(a, b, c) +#define mp_montgomery_free(a) ltc_mp.montgomery_deinit(a) + +#define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d) +#define mp_prime_is_prime(a, b, c) ltc_mp.isprime(a, c) + +#define mp_iszero(a) (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO) +#define mp_isodd(a) (mp_get_digit_count(a) > 0 ? (mp_get_digit(a, 0) & 1 ? LTC_MP_YES : LTC_MP_NO) : LTC_MP_NO) +#define mp_exch(a, b) do { void *ABC__tmp = a; a = b; b = ABC__tmp; } while(0); + +#define mp_tohex(a, b) mp_toradix(a, b, 16) + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_math.h,v $ */ +/* $Revision: 1.44 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/headers/tomcrypt_misc.h b/StormLib/src/libtomcrypt/src/headers/tomcrypt_misc.h new file mode 100644 index 000000000..f5384cacc --- /dev/null +++ b/StormLib/src/libtomcrypt/src/headers/tomcrypt_misc.h @@ -0,0 +1,23 @@ +/* ---- LTC_BASE64 Routines ---- */ +#ifdef LTC_BASE64 +int base64_encode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); + +int base64_decode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); +#endif + +/* ---- MEM routines ---- */ +void zeromem(void *dst, size_t len); +void burn_stack(unsigned long len); + +const char *error_to_string(int err); + +extern const char *crypt_build_settings; + +/* ---- HMM ---- */ +int crypt_fsa(void *mp, ...); + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_misc.h,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/headers/tomcrypt_pk.h b/StormLib/src/libtomcrypt/src/headers/tomcrypt_pk.h new file mode 100644 index 000000000..b5f277a88 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/headers/tomcrypt_pk.h @@ -0,0 +1,558 @@ +/* ---- NUMBER THEORY ---- */ + +enum { + PK_PUBLIC=0, + PK_PRIVATE=1 +}; + +int rand_prime(void *N, long len, prng_state *prng, int wprng); + +/* ---- RSA ---- */ +#ifdef LTC_MRSA + +/* Min and Max RSA key sizes (in bits) */ +#define MIN_RSA_SIZE 1024 +#define MAX_RSA_SIZE 4096 + +/** RSA LTC_PKCS style key */ +typedef struct Rsa_key { + /** Type of key, PK_PRIVATE or PK_PUBLIC */ + int type; + /** The public exponent */ + void *e; + /** The private exponent */ + void *d; + /** The modulus */ + void *N; + /** The p factor of N */ + void *p; + /** The q factor of N */ + void *q; + /** The 1/q mod p CRT param */ + void *qP; + /** The d mod (p - 1) CRT param */ + void *dP; + /** The d mod (q - 1) CRT param */ + void *dQ; +} rsa_key; + +int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key); + +int rsa_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + rsa_key *key); + +void rsa_free(rsa_key *key); + +/* These use LTC_PKCS #1 v2.0 padding */ +#define rsa_encrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, _key) \ + rsa_encrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, LTC_LTC_PKCS_1_OAEP, _key) + +#define rsa_decrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, _stat, _key) \ + rsa_decrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, LTC_LTC_PKCS_1_OAEP, _stat, _key) + +#define rsa_sign_hash(_in, _inlen, _out, _outlen, _prng, _prng_idx, _hash_idx, _saltlen, _key) \ + rsa_sign_hash_ex(_in, _inlen, _out, _outlen, LTC_LTC_PKCS_1_PSS, _prng, _prng_idx, _hash_idx, _saltlen, _key) + +#define rsa_verify_hash(_sig, _siglen, _hash, _hashlen, _hash_idx, _saltlen, _stat, _key) \ + rsa_verify_hash_ex(_sig, _siglen, _hash, _hashlen, LTC_LTC_PKCS_1_PSS, _hash_idx, _saltlen, _stat, _key) + +/* These can be switched between LTC_PKCS #1 v2.x and LTC_PKCS #1 v1.5 paddings */ +int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + prng_state *prng, int prng_idx, int hash_idx, int padding, rsa_key *key); + +int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + int hash_idx, int padding, + int *stat, rsa_key *key); + +int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + int padding, + prng_state *prng, int prng_idx, + int hash_idx, unsigned long saltlen, + rsa_key *key); + +int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int padding, + int hash_idx, unsigned long saltlen, + int *stat, rsa_key *key); + +/* LTC_PKCS #1 import/export */ +int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key); +int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key); + +/* Ladik: Added for verifying Blizzard strong signature verification */ +int rsa_verify_simple(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, + rsa_key *key); + +#endif + +/* ---- Katja ---- */ +#ifdef MKAT + +/* Min and Max KAT key sizes (in bits) */ +#define MIN_KAT_SIZE 1024 +#define MAX_KAT_SIZE 4096 + +/** Katja LTC_PKCS style key */ +typedef struct KAT_key { + /** Type of key, PK_PRIVATE or PK_PUBLIC */ + int type; + /** The private exponent */ + void *d; + /** The modulus */ + void *N; + /** The p factor of N */ + void *p; + /** The q factor of N */ + void *q; + /** The 1/q mod p CRT param */ + void *qP; + /** The d mod (p - 1) CRT param */ + void *dP; + /** The d mod (q - 1) CRT param */ + void *dQ; + /** The pq param */ + void *pq; +} katja_key; + +int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key); + +int katja_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + katja_key *key); + +void katja_free(katja_key *key); + +/* These use LTC_PKCS #1 v2.0 padding */ +int katja_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + prng_state *prng, int prng_idx, int hash_idx, katja_key *key); + +int katja_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + int hash_idx, int *stat, + katja_key *key); + +/* LTC_PKCS #1 import/export */ +int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key); +int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key); + +#endif + +/* ---- ECC Routines ---- */ +#ifdef LTC_MECC + +/* size of our temp buffers for exported keys */ +#define ECC_BUF_SIZE 256 + +/* max private key size */ +#define ECC_MAXSIZE 66 + +/** Structure defines a NIST GF(p) curve */ +typedef struct { + /** The size of the curve in octets */ + int size; + + /** name of curve */ + char *name; + + /** The prime that defines the field the curve is in (encoded in hex) */ + char *prime; + + /** The fields B param (hex) */ + char *B; + + /** The order of the curve (hex) */ + char *order; + + /** The x co-ordinate of the base point on the curve (hex) */ + char *Gx; + + /** The y co-ordinate of the base point on the curve (hex) */ + char *Gy; +} ltc_ecc_set_type; + +/** A point on a ECC curve, stored in Jacbobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpretted as affine */ +typedef struct { + /** The x co-ordinate */ + void *x; + + /** The y co-ordinate */ + void *y; + + /** The z co-ordinate */ + void *z; +} ecc_point; + +/** An ECC key */ +typedef struct { + /** Type of key, PK_PRIVATE or PK_PUBLIC */ + int type; + + /** Index into the ltc_ecc_sets[] for the parameters of this curve; if -1, then this key is using user supplied curve in dp */ + int idx; + + /** pointer to domain parameters; either points to NIST curves (identified by idx >= 0) or user supplied curve */ + const ltc_ecc_set_type *dp; + + /** The public key */ + ecc_point pubkey; + + /** The private key */ + void *k; +} ecc_key; + +/** the ECC params provided */ +extern const ltc_ecc_set_type ltc_ecc_sets[]; + +int ecc_test(void); +void ecc_sizes(int *low, int *high); +int ecc_get_size(ecc_key *key); + +int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key); +int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp); +void ecc_free(ecc_key *key); + +int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); +int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key); +int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp); + +int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen); +int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key); +int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp); + +int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, + unsigned char *out, unsigned long *outlen); + +int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash, + ecc_key *key); + +int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + ecc_key *key); + +int ecc_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_key *key); + +int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, ecc_key *key); + +/* low level functions */ +ecc_point *ltc_ecc_new_point(void); +void ltc_ecc_del_point(ecc_point *p); +int ltc_ecc_is_valid_idx(int n); + +/* point ops (mp == montgomery digit) */ +#if !defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC) || defined(GMP_LTC_DESC) +/* R = 2P */ +int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp); + +/* R = P + Q */ +int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp); +#endif + +#if defined(LTC_MECC_FP) +/* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */ +int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); + +/* functions for saving/loading/freeing/adding to fixed point cache */ +int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen); +int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen); +void ltc_ecc_fp_free(void); +int ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock); + +/* lock/unlock all points currently in fixed point cache */ +void ltc_ecc_fp_tablelock(int lock); +#endif + +/* R = kG */ +int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); + +#ifdef LTC_ECC_SHAMIR +/* kA*A + kB*B = C */ +int ltc_ecc_mul2add(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, + void *modulus); + +#ifdef LTC_MECC_FP +/* Shamir's trick with optimized point multiplication using fixed point cache */ +int ltc_ecc_fp_mul2add(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, void *modulus); +#endif + +#endif + + +/* map P to affine from projective */ +int ltc_ecc_map(ecc_point *P, void *modulus, void *mp); + +#endif + +#ifdef LTC_MDSA + +/* Max diff between group and modulus size in bytes */ +#define LTC_MDSA_DELTA 512 + +/* Max DSA group size in bytes (default allows 4k-bit groups) */ +#define LTC_MDSA_MAX_GROUP 512 + +/** DSA key structure */ +typedef struct { + /** The key type, PK_PRIVATE or PK_PUBLIC */ + int type; + + /** The order of the sub-group used in octets */ + int qord; + + /** The generator */ + void *g; + + /** The prime used to generate the sub-group */ + void *q; + + /** The large prime that generats the field the contains the sub-group */ + void *p; + + /** The private key */ + void *x; + + /** The public key */ + void *y; +} dsa_key; + +int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key); +void dsa_free(dsa_key *key); + +int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen, + void *r, void *s, + prng_state *prng, int wprng, dsa_key *key); + +int dsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dsa_key *key); + +int dsa_verify_hash_raw( void *r, void *s, + const unsigned char *hash, unsigned long hashlen, + int *stat, dsa_key *key); + +int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, dsa_key *key); + +int dsa_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash, + dsa_key *key); + +int dsa_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + dsa_key *key); + +int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key); +int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key); +int dsa_verify_key(dsa_key *key, int *stat); + +int dsa_shared_secret(void *private_key, void *base, + dsa_key *public_key, + unsigned char *out, unsigned long *outlen); +#endif + +#ifdef LTC_DER +/* DER handling */ + +enum { + LTC_ASN1_EOL, + LTC_ASN1_BOOLEAN, + LTC_ASN1_INTEGER, + LTC_ASN1_SHORT_INTEGER, + LTC_ASN1_BIT_STRING, + LTC_ASN1_OCTET_STRING, + LTC_ASN1_NULL, + LTC_ASN1_OBJECT_IDENTIFIER, + LTC_ASN1_IA5_STRING, + LTC_ASN1_PRINTABLE_STRING, + LTC_ASN1_UTF8_STRING, + LTC_ASN1_UTCTIME, + LTC_ASN1_CHOICE, + LTC_ASN1_SEQUENCE, + LTC_ASN1_SET, + LTC_ASN1_SETOF +}; + +/** A LTC ASN.1 list type */ +typedef struct ltc_asn1_list_ { + /** The LTC ASN.1 enumerated type identifier */ + int type; + /** The data to encode or place for decoding */ + void *data; + /** The size of the input or resulting output */ + unsigned long size; + /** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */ + int used; + /** prev/next entry in the list */ + struct ltc_asn1_list_ *prev, *next, *child, *parent; +} ltc_asn1_list; + +#define LTC_SET_ASN1(list, index, Type, Data, Size) \ + do { \ + int LTC_MACRO_temp = (index); \ + ltc_asn1_list *LTC_MACRO_list = (list); \ + LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \ + LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \ + LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \ + LTC_MACRO_list[LTC_MACRO_temp].used = 0; \ + } while (0); + +/* SEQUENCE */ +int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int type_of); + +#define der_encode_sequence(list, inlen, out, outlen) der_encode_sequence_ex(list, inlen, out, outlen, LTC_ASN1_SEQUENCE) + +int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, + ltc_asn1_list *list, unsigned long outlen, int ordered); + +#define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1) + +int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, + unsigned long *outlen); + +/* SET */ +#define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 0) +#define der_length_set der_length_sequence +int der_encode_set(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +/* VA list handy helpers with triplets of */ +int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...); +int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...); + +/* FLEXI DECODER handle unknown list decoder */ +int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out); +void der_free_sequence_flexi(ltc_asn1_list *list); +void der_sequence_free(ltc_asn1_list *in); + +/* BOOLEAN */ +int der_length_boolean(unsigned long *outlen); +int der_encode_boolean(int in, + unsigned char *out, unsigned long *outlen); +int der_decode_boolean(const unsigned char *in, unsigned long inlen, + int *out); +/* INTEGER */ +int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen); +int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num); +int der_length_integer(void *num, unsigned long *len); + +/* INTEGER -- handy for 0..2^32-1 values */ +int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num); +int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen); +int der_length_short_integer(unsigned long num, unsigned long *outlen); + +/* BIT STRING */ +int der_encode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_bit_string(unsigned long nbits, unsigned long *outlen); + +/* OCTET STRING */ +int der_encode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_octet_string(unsigned long noctets, unsigned long *outlen); + +/* OBJECT IDENTIFIER */ +int der_encode_object_identifier(unsigned long *words, unsigned long nwords, + unsigned char *out, unsigned long *outlen); +int der_decode_object_identifier(const unsigned char *in, unsigned long inlen, + unsigned long *words, unsigned long *outlen); +int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen); +unsigned long der_object_identifier_bits(unsigned long x); + +/* IA5 STRING */ +int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); + +int der_ia5_char_encode(int c); +int der_ia5_value_decode(int v); + +/* Printable STRING */ +int der_encode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); + +int der_printable_char_encode(int c); +int der_printable_value_decode(int v); + +/* UTF-8 */ +#if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED) || defined (__WCHAR_TYPE__)) && !defined(LTC_NO_WCHAR) +#include +#else +typedef ulong32 wchar_t; +#endif + +int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, + wchar_t *out, unsigned long *outlen); +unsigned long der_utf8_charsize(const wchar_t c); +int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen); + + +/* CHOICE */ +int der_decode_choice(const unsigned char *in, unsigned long *inlen, + ltc_asn1_list *list, unsigned long outlen); + +/* UTCTime */ +typedef struct { + unsigned YY, /* year */ + MM, /* month */ + DD, /* day */ + hh, /* hour */ + mm, /* minute */ + ss, /* second */ + off_dir, /* timezone offset direction 0 == +, 1 == - */ + off_hh, /* timezone offset hours */ + off_mm; /* timezone offset minutes */ +} ltc_utctime; + +int der_encode_utctime(ltc_utctime *utctime, + unsigned char *out, unsigned long *outlen); + +int der_decode_utctime(const unsigned char *in, unsigned long *inlen, + ltc_utctime *out); + +int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen); + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_pk.h,v $ */ +/* $Revision: 1.81 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/headers/tomcrypt_pkcs.h b/StormLib/src/libtomcrypt/src/headers/tomcrypt_pkcs.h new file mode 100644 index 000000000..84fb82a62 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/headers/tomcrypt_pkcs.h @@ -0,0 +1,89 @@ +/* LTC_PKCS Header Info */ + +/* ===> LTC_PKCS #1 -- RSA Cryptography <=== */ +#ifdef LTC_PKCS_1 + +enum ltc_pkcs_1_v1_5_blocks +{ + LTC_LTC_PKCS_1_EMSA = 1, /* Block type 1 (LTC_PKCS #1 v1.5 signature padding) */ + LTC_LTC_PKCS_1_EME = 2 /* Block type 2 (LTC_PKCS #1 v1.5 encryption padding) */ +}; + +enum ltc_pkcs_1_paddings +{ + LTC_LTC_PKCS_1_V1_5 = 1, /* LTC_PKCS #1 v1.5 padding (\sa ltc_pkcs_1_v1_5_blocks) */ + LTC_LTC_PKCS_1_OAEP = 2, /* LTC_PKCS #1 v2.0 encryption padding */ + LTC_LTC_PKCS_1_PSS = 3 /* LTC_PKCS #1 v2.1 signature padding */ +}; + +int pkcs_1_mgf1( int hash_idx, + const unsigned char *seed, unsigned long seedlen, + unsigned char *mask, unsigned long masklen); + +int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out); +int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen); + +/* *** v1.5 padding */ +int pkcs_1_v1_5_encode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + prng_state *prng, + int prng_idx, + unsigned char *out, + unsigned long *outlen); + +int pkcs_1_v1_5_decode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + unsigned char *out, + unsigned long *outlen, + int *is_valid); + +/* *** v2.1 padding */ +int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, prng_state *prng, + int prng_idx, int hash_idx, + unsigned char *out, unsigned long *outlen); + +int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, int hash_idx, + unsigned char *out, unsigned long *outlen, + int *res); + +int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, + unsigned long saltlen, prng_state *prng, + int prng_idx, int hash_idx, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen); + +int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, + const unsigned char *sig, unsigned long siglen, + unsigned long saltlen, int hash_idx, + unsigned long modulus_bitlen, int *res); + +#endif /* LTC_PKCS_1 */ + +/* ===> LTC_PKCS #5 -- Password Based Cryptography <=== */ +#ifdef LTC_PKCS_5 + +/* Algorithm #1 (old) */ +int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen); + +/* Algorithm #2 (new) */ +int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, unsigned long salt_len, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen); + +#endif /* LTC_PKCS_5 */ + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_pkcs.h,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/headers/tomcrypt_prng.h b/StormLib/src/libtomcrypt/src/headers/tomcrypt_prng.h new file mode 100644 index 000000000..f3e3e550e --- /dev/null +++ b/StormLib/src/libtomcrypt/src/headers/tomcrypt_prng.h @@ -0,0 +1,199 @@ +/* ---- PRNG Stuff ---- */ +#ifdef LTC_YARROW +struct yarrow_prng { + int cipher, hash; + unsigned char pool[MAXBLOCKSIZE]; + symmetric_CTR ctr; + LTC_MUTEX_TYPE(prng_lock) +}; +#endif + +#ifdef LTC_RC4 +struct rc4_prng { + int x, y; + unsigned char buf[256]; +}; +#endif + +#ifdef LTC_FORTUNA +struct fortuna_prng { + hash_state pool[LTC_FORTUNA_POOLS]; /* the pools */ + + symmetric_key skey; + + unsigned char K[32], /* the current key */ + IV[16]; /* IV for CTR mode */ + + unsigned long pool_idx, /* current pool we will add to */ + pool0_len, /* length of 0'th pool */ + wd; + + ulong64 reset_cnt; /* number of times we have reset */ + LTC_MUTEX_TYPE(prng_lock) +}; +#endif + +#ifdef LTC_SOBER128 +struct sober128_prng { + ulong32 R[17], /* Working storage for the shift register */ + initR[17], /* saved register contents */ + konst, /* key dependent constant */ + sbuf; /* partial word encryption buffer */ + + int nbuf, /* number of part-word stream bits buffered */ + flag, /* first add_entropy call or not? */ + set; /* did we call add_entropy to set key? */ + +}; +#endif + +typedef union Prng_state { + char dummy[1]; +#ifdef LTC_YARROW + struct yarrow_prng yarrow; +#endif +#ifdef LTC_RC4 + struct rc4_prng rc4; +#endif +#ifdef LTC_FORTUNA + struct fortuna_prng fortuna; +#endif +#ifdef LTC_SOBER128 + struct sober128_prng sober128; +#endif +} prng_state; + +/** PRNG descriptor */ +extern struct ltc_prng_descriptor { + /** Name of the PRNG */ + char *name; + /** size in bytes of exported state */ + int export_size; + /** Start a PRNG state + @param prng [out] The state to initialize + @return CRYPT_OK if successful + */ + int (*start)(prng_state *prng); + /** Add entropy to the PRNG + @param in The entropy + @param inlen Length of the entropy (octets)\ + @param prng The PRNG state + @return CRYPT_OK if successful + */ + int (*add_entropy)(const unsigned char *in, unsigned long inlen, prng_state *prng); + /** Ready a PRNG state to read from + @param prng The PRNG state to ready + @return CRYPT_OK if successful + */ + int (*ready)(prng_state *prng); + /** Read from the PRNG + @param out [out] Where to store the data + @param outlen Length of data desired (octets) + @param prng The PRNG state to read from + @return Number of octets read + */ + unsigned long (*read)(unsigned char *out, unsigned long outlen, prng_state *prng); + /** Terminate a PRNG state + @param prng The PRNG state to terminate + @return CRYPT_OK if successful + */ + int (*done)(prng_state *prng); + /** Export a PRNG state + @param out [out] The destination for the state + @param outlen [in/out] The max size and resulting size of the PRNG state + @param prng The PRNG to export + @return CRYPT_OK if successful + */ + int (*pexport)(unsigned char *out, unsigned long *outlen, prng_state *prng); + /** Import a PRNG state + @param in The data to import + @param inlen The length of the data to import (octets) + @param prng The PRNG to initialize/import + @return CRYPT_OK if successful + */ + int (*pimport)(const unsigned char *in, unsigned long inlen, prng_state *prng); + /** Self-test the PRNG + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled + */ + int (*test)(void); +} prng_descriptor[]; + +#ifdef LTC_YARROW +int yarrow_start(prng_state *prng); +int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int yarrow_ready(prng_state *prng); +unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int yarrow_done(prng_state *prng); +int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int yarrow_test(void); +extern const struct ltc_prng_descriptor yarrow_desc; +#endif + +#ifdef LTC_FORTUNA +int fortuna_start(prng_state *prng); +int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int fortuna_ready(prng_state *prng); +unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int fortuna_done(prng_state *prng); +int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int fortuna_test(void); +extern const struct ltc_prng_descriptor fortuna_desc; +#endif + +#ifdef LTC_RC4 +int rc4_start(prng_state *prng); +int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int rc4_ready(prng_state *prng); +unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int rc4_done(prng_state *prng); +int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int rc4_test(void); +extern const struct ltc_prng_descriptor rc4_desc; +#endif + +#ifdef LTC_SPRNG +int sprng_start(prng_state *prng); +int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int sprng_ready(prng_state *prng); +unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int sprng_done(prng_state *prng); +int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int sprng_test(void); +extern const struct ltc_prng_descriptor sprng_desc; +#endif + +#ifdef LTC_SOBER128 +int sober128_start(prng_state *prng); +int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int sober128_ready(prng_state *prng); +unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int sober128_done(prng_state *prng); +int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int sober128_test(void); +extern const struct ltc_prng_descriptor sober128_desc; +#endif + +int find_prng(const char *name); +int register_prng(const struct ltc_prng_descriptor *prng); +int unregister_prng(const struct ltc_prng_descriptor *prng); +int prng_is_valid(int idx); +LTC_MUTEX_PROTO(ltc_prng_mutex) + +/* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this + * might not work on all platforms as planned + */ +unsigned long rng_get_bytes(unsigned char *out, + unsigned long outlen, + void (*callback)(void)); + +int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void)); + + +/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_prng.h,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/math/ltm_desc.c b/StormLib/src/libtomcrypt/src/math/ltm_desc.c new file mode 100644 index 000000000..25dc0b322 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/math/ltm_desc.c @@ -0,0 +1,483 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +#define DESC_DEF_ONLY +#include "../headers/tomcrypt.h" + +#ifdef LTM_DESC + +#include "../../../libtommath/tommath.h" + +static const struct { + int mpi_code, ltc_code; +} mpi_to_ltc_codes[] = { + { MP_OKAY , CRYPT_OK}, + { MP_MEM , CRYPT_MEM}, + { MP_VAL , CRYPT_INVALID_ARG}, +}; + +/** + Convert a MPI error to a LTC error (Possibly the most powerful function ever! Oh wait... no) + @param err The error to convert + @return The equivalent LTC error code or CRYPT_ERROR if none found +*/ +static int mpi_to_ltc_error(int err) +{ + int x; + + for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) { + if (err == mpi_to_ltc_codes[x].mpi_code) { + return mpi_to_ltc_codes[x].ltc_code; + } + } + return CRYPT_ERROR; +} + +static int init(void **a) +{ + int err; + + LTC_ARGCHK(a != NULL); + + *a = XCALLOC(1, sizeof(mp_int)); + if (*a == NULL) { + return CRYPT_MEM; + } + + if ((err = mpi_to_ltc_error(mp_init(*a))) != CRYPT_OK) { + XFREE(*a); + } + return err; +} + +static void deinit(void *a) +{ + LTC_ARGCHKVD(a != NULL); + mp_clear(a); + XFREE(a); +} + +static int neg(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_neg(a, b)); +} + +static int copy(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_copy(a, b)); +} + +static int init_copy(void **a, void *b) +{ + if (init(a) != CRYPT_OK) { + return CRYPT_MEM; + } + return copy(b, *a); +} + +/* ---- trivial ---- */ +static int set_int(void *a, unsigned long b) +{ + LTC_ARGCHK(a != NULL); + return mpi_to_ltc_error(mp_set_int(a, b)); +} + +static unsigned long get_int(void *a) +{ + LTC_ARGCHK(a != NULL); + return mp_get_int(a); +} + +static unsigned long get_digit(void *a, int n) +{ + mp_int *A; + LTC_ARGCHK(a != NULL); + A = a; + return (n >= A->used || n < 0) ? 0 : A->dp[n]; +} + +static int get_digit_count(void *a) +{ + mp_int *A; + LTC_ARGCHK(a != NULL); + A = a; + return A->used; +} + +static int compare(void *a, void *b) +{ + int ret; + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + ret = mp_cmp(a, b); + switch (ret) { + case MP_LT: return LTC_MP_LT; + case MP_EQ: return LTC_MP_EQ; + case MP_GT: return LTC_MP_GT; + } + return 0; +} + +static int compare_d(void *a, unsigned long b) +{ + int ret; + LTC_ARGCHK(a != NULL); + ret = mp_cmp_d(a, b); + switch (ret) { + case MP_LT: return LTC_MP_LT; + case MP_EQ: return LTC_MP_EQ; + case MP_GT: return LTC_MP_GT; + } + return 0; +} + +static int count_bits(void *a) +{ + LTC_ARGCHK(a != NULL); + return mp_count_bits(a); +} + +static int count_lsb_bits(void *a) +{ + LTC_ARGCHK(a != NULL); + return mp_cnt_lsb(a); +} + + +static int twoexpt(void *a, int n) +{ + LTC_ARGCHK(a != NULL); + return mpi_to_ltc_error(mp_2expt(a, n)); +} + +/* ---- conversions ---- */ + +/* read ascii string */ +static int read_radix(void *a, const char *b, int radix) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_read_radix(a, b, radix)); +} + +/* write one */ +static int write_radix(void *a, char *b, int radix) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_toradix(a, b, radix)); +} + +/* get size as unsigned char string */ +static unsigned long unsigned_size(void *a) +{ + LTC_ARGCHK(a != NULL); + return mp_unsigned_bin_size(a); +} + +/* store */ +static int unsigned_write(void *a, unsigned char *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_to_unsigned_bin(a, b)); +} + +/* read */ +static int unsigned_read(void *a, unsigned char *b, unsigned long len) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_read_unsigned_bin(a, b, len)); +} + +/* add */ +static int add(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_add(a, b, c)); +} + +static int addi(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_add_d(a, b, c)); +} + +/* sub */ +static int sub(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_sub(a, b, c)); +} + +static int subi(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_sub_d(a, b, c)); +} + +/* mul */ +static int mul(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_mul(a, b, c)); +} + +static int muli(void *a, unsigned long b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_mul_d(a, b, c)); +} + +/* sqr */ +static int sqr(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_sqr(a, b)); +} + +/* div */ +static int divide(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_div(a, b, c, d)); +} + +static int div_2(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_div_2(a, b)); +} + +/* modi */ +static int modi(void *a, unsigned long b, unsigned long *c) +{ + mp_digit tmp; + int err; + + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(c != NULL); + + if ((err = mpi_to_ltc_error(mp_mod_d(a, b, &tmp))) != CRYPT_OK) { + return err; + } + *c = tmp; + return CRYPT_OK; +} + +/* gcd */ +static int gcd(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_gcd(a, b, c)); +} + +/* lcm */ +static int lcm(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_lcm(a, b, c)); +} + +static int mulmod(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(d != NULL); + return mpi_to_ltc_error(mp_mulmod(a,b,c,d)); +} + +static int sqrmod(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_sqrmod(a,b,c)); +} + +/* invmod */ +static int invmod(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_invmod(a, b, c)); +} + +/* setup */ +static int montgomery_setup(void *a, void **b) +{ + int err; + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + *b = XCALLOC(1, sizeof(mp_digit)); + if (*b == NULL) { + return CRYPT_MEM; + } + if ((err = mpi_to_ltc_error(mp_montgomery_setup(a, (mp_digit *)*b))) != CRYPT_OK) { + XFREE(*b); + } + return err; +} + +/* get normalization value */ +static int montgomery_normalization(void *a, void *b) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + return mpi_to_ltc_error(mp_montgomery_calc_normalization(a, b)); +} + +/* reduce */ +static int montgomery_reduce(void *a, void *b, void *c) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + return mpi_to_ltc_error(mp_montgomery_reduce(a, b, *((mp_digit *)c))); +} + +/* clean up */ +static void montgomery_deinit(void *a) +{ + XFREE(a); +} + +static int exptmod(void *a, void *b, void *c, void *d) +{ + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + LTC_ARGCHK(c != NULL); + LTC_ARGCHK(d != NULL); + return mpi_to_ltc_error(mp_exptmod(a,b,c,d)); +} + +static int isprime(void *a, int *b) +{ + int err; + LTC_ARGCHK(a != NULL); + LTC_ARGCHK(b != NULL); + err = mpi_to_ltc_error(mp_prime_is_prime(a, 8, b)); + *b = (*b == MP_YES) ? LTC_MP_YES : LTC_MP_NO; + return err; +} + +const ltc_math_descriptor ltm_desc = { + + "LibTomMath", + (int)DIGIT_BIT, + + &init, + &init_copy, + &deinit, + + &neg, + ©, + + &set_int, + &get_int, + &get_digit, + &get_digit_count, + &compare, + &compare_d, + &count_bits, + &count_lsb_bits, + &twoexpt, + + &read_radix, + &write_radix, + &unsigned_size, + &unsigned_write, + &unsigned_read, + + &add, + &addi, + &sub, + &subi, + &mul, + &muli, + &sqr, + ÷, + &div_2, + &modi, + &gcd, + &lcm, + + &mulmod, + &sqrmod, + &invmod, + + &montgomery_setup, + &montgomery_normalization, + &montgomery_reduce, + &montgomery_deinit, + + &exptmod, + &isprime, + +#ifdef LTC_MECC +#ifdef LTC_MECC_FP + <c_ecc_fp_mulmod, +#else + <c_ecc_mulmod, +#endif + <c_ecc_projective_add_point, + <c_ecc_projective_dbl_point, + <c_ecc_map, +#ifdef LTC_ECC_SHAMIR +#ifdef LTC_MECC_FP + <c_ecc_fp_mul2add, +#else + <c_ecc_mul2add, +#endif /* LTC_MECC_FP */ +#else + NULL, +#endif /* LTC_ECC_SHAMIR */ +#else + NULL, NULL, NULL, NULL, NULL, +#endif /* LTC_MECC */ + +#ifdef LTC_MRSA + &rsa_make_key, + &rsa_exptmod, +#else + NULL, NULL +#endif +}; + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/math/ltm_desc.c,v $ */ +/* $Revision: 1.31 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/math/multi.c b/StormLib/src/libtomcrypt/src/math/multi.c new file mode 100644 index 000000000..7d40040a1 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/math/multi.c @@ -0,0 +1,61 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../headers/tomcrypt.h" + +#ifdef MPI +#include + +int ltc_init_multi(void **a, ...) +{ + void **cur = a; + int np = 0; + va_list args; + + va_start(args, a); + while (cur != NULL) { + if (mp_init(cur) != CRYPT_OK) { + /* failed */ + va_list clean_list; + + va_start(clean_list, a); + cur = a; + while (np--) { + mp_clear(*cur); + cur = va_arg(clean_list, void**); + } + va_end(clean_list); + return CRYPT_MEM; + } + ++np; + cur = va_arg(args, void**); + } + va_end(args); + return CRYPT_OK; +} + +void ltc_deinit_multi(void *a, ...) +{ + void *cur = a; + va_list args; + + va_start(args, a); + while (cur != NULL) { + mp_clear(cur); + cur = va_arg(args, void *); + } + va_end(args); +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/math/multi.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/StormLib/src/libtomcrypt/src/math/rand_prime.c b/StormLib/src/libtomcrypt/src/math/rand_prime.c new file mode 100644 index 000000000..913fa95a4 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/math/rand_prime.c @@ -0,0 +1,87 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../headers/tomcrypt.h" + +/** + @file rand_prime.c + Generate a random prime, Tom St Denis +*/ + +#define USE_BBS 1 + +int rand_prime(void *N, long len, prng_state *prng, int wprng) +{ + int err, res, type; + unsigned char *buf; + + LTC_ARGCHK(N != NULL); + + /* get type */ + if (len < 0) { + type = USE_BBS; + len = -len; + } else { + type = 0; + } + + /* allow sizes between 2 and 512 bytes for a prime size */ + if (len < 2 || len > 512) { + return CRYPT_INVALID_PRIME_SIZE; + } + + /* valid PRNG? Better be! */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* allocate buffer to work with */ + buf = XCALLOC(1, len); + if (buf == NULL) { + return CRYPT_MEM; + } + + do { + /* generate value */ + if (prng_descriptor[wprng].read(buf, len, prng) != (unsigned long)len) { + XFREE(buf); + return CRYPT_ERROR_READPRNG; + } + + /* munge bits */ + buf[0] |= 0x80 | 0x40; + buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); + + /* load value */ + if ((err = mp_read_unsigned_bin(N, buf, len)) != CRYPT_OK) { + XFREE(buf); + return err; + } + + /* test */ + if ((err = mp_prime_is_prime(N, 8, &res)) != CRYPT_OK) { + XFREE(buf); + return err; + } + } while (res == LTC_MP_NO); + +#ifdef LTC_CLEAN_STACK + zeromem(buf, len); +#endif + + XFREE(buf); + return CRYPT_OK; +} + + + +/* $Source: /cvs/libtom/libtomcrypt/src/math/rand_prime.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/StormLib/src/libtomcrypt/src/misc/base64_decode.c b/StormLib/src/libtomcrypt/src/misc/base64_decode.c new file mode 100644 index 000000000..3d13393a1 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/misc/base64_decode.c @@ -0,0 +1,104 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../headers/tomcrypt.h" + +/** + @file base64_decode.c + Compliant base64 code donated by Wayne Scott (wscott@bitmover.com) +*/ + + +#ifdef LTC_BASE64 + +static const unsigned char map[256] = { +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, +255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, +255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255 }; + +/** + base64 decode a block of memory + @param in The base64 data to decode + @param inlen The length of the base64 data + @param out [out] The destination of the binary decoded data + @param outlen [in/out] The max size and resulting size of the decoded data + @return CRYPT_OK if successful +*/ +int base64_decode(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long t, x, y, z; + unsigned char c; + int g; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + g = 3; + for (x = y = z = t = 0; x < inlen; x++) { + c = map[in[x]&0xFF]; + if (c == 255) continue; + /* the final = symbols are read and used to trim the remaining bytes */ + if (c == 254) { + c = 0; + /* prevent g < 0 which would potentially allow an overflow later */ + if (--g < 0) { + return CRYPT_INVALID_PACKET; + } + } else if (g != 3) { + /* we only allow = to be at the end */ + return CRYPT_INVALID_PACKET; + } + + t = (t<<6)|c; + + if (++y == 4) { + if (z + g > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + out[z++] = (unsigned char)((t>>16)&255); + if (g > 1) out[z++] = (unsigned char)((t>>8)&255); + if (g > 2) out[z++] = (unsigned char)(t&255); + y = t = 0; + } + } + if (y != 0) { + return CRYPT_INVALID_PACKET; + } + *outlen = z; + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/base64/base64_decode.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/misc/crypt_argchk.c b/StormLib/src/libtomcrypt/src/misc/crypt_argchk.c new file mode 100644 index 000000000..537516d80 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/misc/crypt_argchk.c @@ -0,0 +1,30 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../headers/tomcrypt.h" +#include + +/** + @file crypt_argchk.c + Perform argument checking, Tom St Denis +*/ + +#if (ARGTYPE == 0) +void crypt_argchk(char *v, char *s, int d) +{ + fprintf(stderr, "LTC_ARGCHK '%s' failure on line %d of file %s\n", + v, d, s); + (void)raise(SIGABRT); +} +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_argchk.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/misc/crypt_find_hash.c b/StormLib/src/libtomcrypt/src/misc/crypt_find_hash.c new file mode 100644 index 000000000..fef2d8cca --- /dev/null +++ b/StormLib/src/libtomcrypt/src/misc/crypt_find_hash.c @@ -0,0 +1,40 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../headers/tomcrypt.h" + +/** + @file crypt_find_hash.c + Find a hash, Tom St Denis +*/ + +/** + Find a registered hash by name + @param name The name of the hash to look for + @return >= 0 if found, -1 if not present +*/ +int find_hash(const char *name) +{ + int x; + LTC_ARGCHK(name != NULL); + LTC_MUTEX_LOCK(<c_hash_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].name != NULL && XSTRCMP(hash_descriptor[x].name, name) == 0) { + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return x; + } + } + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return -1; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_hash.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/misc/crypt_find_prng.c b/StormLib/src/libtomcrypt/src/misc/crypt_find_prng.c new file mode 100644 index 000000000..fafbb0e22 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/misc/crypt_find_prng.c @@ -0,0 +1,41 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../headers/tomcrypt.h" + +/** + @file crypt_find_prng.c + Find a PRNG, Tom St Denis +*/ + +/** + Find a registered PRNG by name + @param name The name of the PRNG to look for + @return >= 0 if found, -1 if not present +*/ +int find_prng(const char *name) +{ + int x; + LTC_ARGCHK(name != NULL); + LTC_MUTEX_LOCK(<c_prng_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if ((prng_descriptor[x].name != NULL) && XSTRCMP(prng_descriptor[x].name, name) == 0) { + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return x; + } + } + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return -1; +} + + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_prng.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/misc/crypt_hash_descriptor.c b/StormLib/src/libtomcrypt/src/misc/crypt_hash_descriptor.c new file mode 100644 index 000000000..5925fd273 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/misc/crypt_hash_descriptor.c @@ -0,0 +1,27 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../headers/tomcrypt.h" + +/** + @file crypt_hash_descriptor.c + Stores the hash descriptor table, Tom St Denis +*/ + +struct ltc_hash_descriptor hash_descriptor[TAB_SIZE] = { +{ NULL, 0, 0, 0, { 0 }, 0, NULL, NULL, NULL, NULL, NULL } +}; + +LTC_MUTEX_GLOBAL(ltc_hash_mutex) + + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_hash_descriptor.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/misc/crypt_hash_is_valid.c b/StormLib/src/libtomcrypt/src/misc/crypt_hash_is_valid.c new file mode 100644 index 000000000..8ed5105b5 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/misc/crypt_hash_is_valid.c @@ -0,0 +1,36 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../headers/tomcrypt.h" + +/** + @file crypt_hash_is_valid.c + Determine if hash is valid, Tom St Denis +*/ + +/* + Test if a hash index is valid + @param idx The index of the hash to search for + @return CRYPT_OK if valid +*/ +int hash_is_valid(int idx) +{ + LTC_MUTEX_LOCK(<c_hash_mutex); + if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) { + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return CRYPT_INVALID_HASH; + } + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return CRYPT_OK; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_hash_is_valid.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/misc/crypt_libc.c b/StormLib/src/libtomcrypt/src/misc/crypt_libc.c new file mode 100644 index 000000000..3457a5209 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/misc/crypt_libc.c @@ -0,0 +1,43 @@ +/*****************************************************************************/ +/* crypt_libc.c Copyright (c) Ladislav Zezula 2010 */ +/*---------------------------------------------------------------------------*/ +/* Description: */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 05.05.10 1.00 Lad The first version of crypt_libc.c */ +/*****************************************************************************/ + +// LibTomCrypt header +#include +#include "../headers/tomcrypt.h" + +LTC_EXPORT void * LTC_CALL LibTomMalloc(size_t n) +{ + return malloc(n); +} + +LTC_EXPORT void * LTC_CALL LibTomCalloc(size_t n, size_t s) +{ + return calloc(n, s); +} + +LTC_EXPORT void * LTC_CALL LibTomRealloc(void *p, size_t n) +{ + return realloc(p, n); +} + +LTC_EXPORT void LTC_CALL LibTomFree(void * p) +{ + free(p); +} + +LTC_EXPORT clock_t LTC_CALL LibTomClock(void) +{ + return clock(); +} + +LTC_EXPORT void LTC_CALL LibTomQsort(void *base, size_t nmemb, size_t size, int(LTC_CALL * compar)(const void *, const void *)) +{ + qsort(base, nmemb, size, compar); +} diff --git a/StormLib/src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c b/StormLib/src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c new file mode 100644 index 000000000..c02a96f33 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c @@ -0,0 +1,13 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../headers/tomcrypt.h" + +ltc_math_descriptor ltc_mp = {0}; diff --git a/StormLib/src/libtomcrypt/src/misc/crypt_prng_descriptor.c b/StormLib/src/libtomcrypt/src/misc/crypt_prng_descriptor.c new file mode 100644 index 000000000..c5b39e0c2 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/misc/crypt_prng_descriptor.c @@ -0,0 +1,26 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../headers/tomcrypt.h" + +/** + @file crypt_prng_descriptor.c + Stores the PRNG descriptors, Tom St Denis +*/ +struct ltc_prng_descriptor prng_descriptor[TAB_SIZE] = { +{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } +}; + +LTC_MUTEX_GLOBAL(ltc_prng_mutex) + + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_prng_descriptor.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/misc/crypt_prng_is_valid.c b/StormLib/src/libtomcrypt/src/misc/crypt_prng_is_valid.c new file mode 100644 index 000000000..d38fd3a3c --- /dev/null +++ b/StormLib/src/libtomcrypt/src/misc/crypt_prng_is_valid.c @@ -0,0 +1,36 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../headers/tomcrypt.h" + +/** + @file crypt_prng_is_valid.c + Determine if PRNG is valid, Tom St Denis +*/ + +/* + Test if a PRNG index is valid + @param idx The index of the PRNG to search for + @return CRYPT_OK if valid +*/ +int prng_is_valid(int idx) +{ + LTC_MUTEX_LOCK(<c_prng_mutex); + if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) { + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return CRYPT_INVALID_PRNG; + } + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return CRYPT_OK; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_prng_is_valid.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/misc/crypt_register_hash.c b/StormLib/src/libtomcrypt/src/misc/crypt_register_hash.c new file mode 100644 index 000000000..173009154 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/misc/crypt_register_hash.c @@ -0,0 +1,54 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../headers/tomcrypt.h" + +/** + @file crypt_register_hash.c + Register a HASH, Tom St Denis +*/ + +/** + Register a hash with the descriptor table + @param hash The hash you wish to register + @return value >= 0 if successfully added (or already present), -1 if unsuccessful +*/ +int register_hash(const struct ltc_hash_descriptor *hash) +{ + int x; + + LTC_ARGCHK(hash != NULL); + + /* is it already registered? */ + LTC_MUTEX_LOCK(<c_hash_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) { + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return x; + } + } + + /* find a blank spot */ + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].name == NULL) { + XMEMCPY(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)); + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return x; + } + } + + /* no spot */ + LTC_MUTEX_UNLOCK(<c_hash_mutex); + return -1; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_register_hash.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/misc/crypt_register_prng.c b/StormLib/src/libtomcrypt/src/misc/crypt_register_prng.c new file mode 100644 index 000000000..29fc9bdf6 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/misc/crypt_register_prng.c @@ -0,0 +1,54 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../headers/tomcrypt.h" + +/** + @file crypt_register_prng.c + Register a PRNG, Tom St Denis +*/ + +/** + Register a PRNG with the descriptor table + @param prng The PRNG you wish to register + @return value >= 0 if successfully added (or already present), -1 if unsuccessful +*/ +int register_prng(const struct ltc_prng_descriptor *prng) +{ + int x; + + LTC_ARGCHK(prng != NULL); + + /* is it already registered? */ + LTC_MUTEX_LOCK(<c_prng_mutex); + for (x = 0; x < TAB_SIZE; x++) { + if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) == 0) { + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return x; + } + } + + /* find a blank spot */ + for (x = 0; x < TAB_SIZE; x++) { + if (prng_descriptor[x].name == NULL) { + XMEMCPY(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)); + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return x; + } + } + + /* no spot */ + LTC_MUTEX_UNLOCK(<c_prng_mutex); + return -1; +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_register_prng.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/misc/zeromem.c b/StormLib/src/libtomcrypt/src/misc/zeromem.c new file mode 100644 index 000000000..faa0efa78 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/misc/zeromem.c @@ -0,0 +1,34 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../headers/tomcrypt.h" + +/** + @file zeromem.c + Zero a block of memory, Tom St Denis +*/ + +/** + Zero a block of memory + @param out The destination of the area to zero + @param outlen The length of the area to zero (octets) +*/ +void zeromem(void *out, size_t outlen) +{ + unsigned char *mem = out; + LTC_ARGCHKVD(out != NULL); + while (outlen-- > 0) { + *mem++ = 0; + } +} + +/* $Source: /cvs/libtom/libtomcrypt/src/misc/zeromem.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c new file mode 100644 index 000000000..e53686750 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c @@ -0,0 +1,102 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_decode_bit_string.c + ASN.1 DER, encode a BIT STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a BIT STRING + @param in The DER encoded BIT STRING + @param inlen The size of the DER BIT STRING + @param out [out] The array of bits stored (one per char) + @param outlen [in/out] The number of bits stored + @return CRYPT_OK if successful +*/ +int der_decode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long dlen, blen, x, y; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* packet must be at least 4 bytes */ + if (inlen < 4) { + return CRYPT_INVALID_ARG; + } + + /* check for 0x03 */ + if ((in[0]&0x1F) != 0x03) { + return CRYPT_INVALID_PACKET; + } + + /* offset in the data */ + x = 1; + + /* get the length of the data */ + if (in[x] & 0x80) { + /* long format get number of length bytes */ + y = in[x++] & 0x7F; + + /* invalid if 0 or > 2 */ + if (y == 0 || y > 2) { + return CRYPT_INVALID_PACKET; + } + + /* read the data len */ + dlen = 0; + while (y--) { + dlen = (dlen << 8) | (unsigned long)in[x++]; + } + } else { + /* short format */ + dlen = in[x++] & 0x7F; + } + + /* is the data len too long or too short? */ + if ((dlen == 0) || (dlen + x > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* get padding count */ + blen = ((dlen - 1) << 3) - (in[x++] & 7); + + /* too many bits? */ + if (blen > *outlen) { + *outlen = blen; + return CRYPT_BUFFER_OVERFLOW; + } + + /* decode/store the bits */ + for (y = 0; y < blen; y++) { + out[y] = (in[x] & (1 << (7 - (y & 7)))) ? 1 : 0; + if ((y & 7) == 7) { + ++x; + } + } + + /* we done */ + *outlen = blen; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_boolean.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_boolean.c new file mode 100644 index 000000000..617d4e861 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_boolean.c @@ -0,0 +1,47 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_decode_boolean.c + ASN.1 DER, decode a BOOLEAN, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Read a BOOLEAN + @param in The destination for the DER encoded BOOLEAN + @param inlen The size of the DER BOOLEAN + @param out [out] The boolean to decode + @return CRYPT_OK if successful +*/ +int der_decode_boolean(const unsigned char *in, unsigned long inlen, + int *out) +{ + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + + if (inlen != 3 || in[0] != 0x01 || in[1] != 0x01 || (in[2] != 0x00 && in[2] != 0xFF)) { + return CRYPT_INVALID_ARG; + } + + *out = (in[2]==0xFF) ? 1 : 0; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/boolean/der_decode_boolean.c,v $ */ +/* $Revision: 1.2 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_choice.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_choice.c new file mode 100644 index 000000000..44a0891be --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_choice.c @@ -0,0 +1,182 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_decode_choice.c + ASN.1 DER, decode a CHOICE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Decode a CHOICE + @param in The DER encoded input + @param inlen [in/out] The size of the input and resulting size of read type + @param list The list of items to decode + @param outlen The number of items in the list + @return CRYPT_OK on success +*/ +int der_decode_choice(const unsigned char *in, unsigned long *inlen, + ltc_asn1_list *list, unsigned long outlen) +{ + unsigned long size, x, z; + void *data; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != NULL); + LTC_ARGCHK(list != NULL); + + /* get blk size */ + if (*inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* set all of the "used" flags to zero */ + for (x = 0; x < outlen; x++) { + list[x].used = 0; + } + + /* now scan until we have a winner */ + for (x = 0; x < outlen; x++) { + size = list[x].size; + data = list[x].data; + + switch (list[x].type) { + case LTC_ASN1_INTEGER: + if (der_decode_integer(in, *inlen, data) == CRYPT_OK) { + if (der_length_integer(data, &z) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_SHORT_INTEGER: + if (der_decode_short_integer(in, *inlen, data) == CRYPT_OK) { + if (der_length_short_integer(size, &z) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_BIT_STRING: + if (der_decode_bit_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_bit_string(size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_OCTET_STRING: + if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_octet_string(size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_NULL: + if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) { + *inlen = 2; + list[x].used = 1; + return CRYPT_OK; + } + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + if (der_decode_object_identifier(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_object_identifier(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_IA5_STRING: + if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_ia5_string(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + + case LTC_ASN1_PRINTABLE_STRING: + if (der_decode_printable_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_printable_string(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_UTF8_STRING: + if (der_decode_utf8_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_utf8_string(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_UTCTIME: + z = *inlen; + if (der_decode_utctime(in, &z, data) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + break; + + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: + if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) { + if (der_length_sequence(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + } + break; + + default: + return CRYPT_INVALID_ARG; + } + } + + return CRYPT_INVALID_PACKET; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c new file mode 100644 index 000000000..f2e073b8d --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c @@ -0,0 +1,96 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_decode_ia5_string.c + ASN.1 DER, encode a IA5 STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a IA5 STRING + @param in The DER encoded IA5 STRING + @param inlen The size of the DER IA5 STRING + @param out [out] The array of octets stored (one per char) + @param outlen [in/out] The number of octets stored + @return CRYPT_OK if successful +*/ +int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int t; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x16 */ + if ((in[0] & 0x1F) != 0x16) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + /* is it too long? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read the data */ + for (y = 0; y < len; y++) { + t = der_ia5_value_decode(in[x++]); + if (t == -1) { + return CRYPT_INVALID_ARG; + } + out[y] = t; + } + + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_integer.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_integer.c new file mode 100644 index 000000000..cca274519 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_integer.c @@ -0,0 +1,110 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_decode_integer.c + ASN.1 DER, decode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Read a mp_int integer + @param in The DER encoded data + @param inlen Size of DER encoded data + @param num The first mp_int to decode + @return CRYPT_OK if successful +*/ +int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num) +{ + unsigned long x, y, z; + int err; + + LTC_ARGCHK(num != NULL); + LTC_ARGCHK(in != NULL); + + /* min DER INTEGER is 0x02 01 00 == 0 */ + if (inlen < (1 + 1 + 1)) { + return CRYPT_INVALID_PACKET; + } + + /* ok expect 0x02 when we AND with 0001 1111 [1F] */ + x = 0; + if ((in[x++] & 0x1F) != 0x02) { + return CRYPT_INVALID_PACKET; + } + + /* now decode the len stuff */ + z = in[x++]; + + if ((z & 0x80) == 0x00) { + /* short form */ + + /* will it overflow? */ + if (x + z > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* no so read it */ + if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, z)) != CRYPT_OK) { + return err; + } + } else { + /* long form */ + z &= 0x7F; + + /* will number of length bytes overflow? (or > 4) */ + if (((x + z) > inlen) || (z > 4) || (z == 0)) { + return CRYPT_INVALID_PACKET; + } + + /* now read it in */ + y = 0; + while (z--) { + y = ((unsigned long)(in[x++])) | (y << 8); + } + + /* now will reading y bytes overrun? */ + if ((x + y) > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* no so read it */ + if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, y)) != CRYPT_OK) { + return err; + } + } + + /* see if it's negative */ + if (in[x] & 0x80) { + void *tmp; + if (mp_init(&tmp) != CRYPT_OK) { + return CRYPT_MEM; + } + + if (mp_2expt(tmp, mp_count_bits(num)) != CRYPT_OK || mp_sub(num, tmp, num) != CRYPT_OK) { + mp_clear(tmp); + return CRYPT_MEM; + } + mp_clear(tmp); + } + + return CRYPT_OK; + +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c new file mode 100644 index 000000000..e7baae88e --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c @@ -0,0 +1,99 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_decode_object_identifier.c + ASN.1 DER, Decode Object Identifier, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Decode OID data and store the array of integers in words + @param in The OID DER encoded data + @param inlen The length of the OID data + @param words [out] The destination of the OID words + @param outlen [in/out] The number of OID words + @return CRYPT_OK if successful +*/ +int der_decode_object_identifier(const unsigned char *in, unsigned long inlen, + unsigned long *words, unsigned long *outlen) +{ + unsigned long x, y, t, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(words != NULL); + LTC_ARGCHK(outlen != NULL); + + /* header is at least 3 bytes */ + if (inlen < 3) { + return CRYPT_INVALID_PACKET; + } + + /* must be room for at least two words */ + if (*outlen < 2) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* decode the packet header */ + x = 0; + if ((in[x++] & 0x1F) != 0x06) { + return CRYPT_INVALID_PACKET; + } + + /* get the length */ + if (in[x] < 128) { + len = in[x++]; + } else { + if (in[x] < 0x81 || in[x] > 0x82) { + return CRYPT_INVALID_PACKET; + } + y = in[x++] & 0x7F; + len = 0; + while (y--) { + len = (len << 8) | (unsigned long)in[x++]; + } + } + + if (len < 1 || (len + x) > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* decode words */ + y = 0; + t = 0; + while (len--) { + t = (t << 7) | (in[x] & 0x7F); + if (!(in[x++] & 0x80)) { + /* store t */ + if (y >= *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + if (y == 0) { + words[0] = t / 40; + words[1] = t % 40; + y = 2; + } else { + words[y++] = t; + } + t = 0; + } + } + + *outlen = y; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c new file mode 100644 index 000000000..523d0baa0 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c @@ -0,0 +1,91 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_decode_octet_string.c + ASN.1 DER, encode a OCTET STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a OCTET STRING + @param in The DER encoded OCTET STRING + @param inlen The size of the DER OCTET STRING + @param out [out] The array of octets stored (one per char) + @param outlen [in/out] The number of octets stored + @return CRYPT_OK if successful +*/ +int der_decode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x04 */ + if ((in[0] & 0x1F) != 0x04) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + /* is it too long? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read the data */ + for (y = 0; y < len; y++) { + out[y] = in[x++]; + } + + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c new file mode 100644 index 000000000..f83259343 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c @@ -0,0 +1,96 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_decode_printable_string.c + ASN.1 DER, encode a printable STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a printable STRING + @param in The DER encoded printable STRING + @param inlen The size of the DER printable STRING + @param out [out] The array of octets stored (one per char) + @param outlen [in/out] The number of octets stored + @return CRYPT_OK if successful +*/ +int der_decode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int t; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x13 */ + if ((in[0] & 0x1F) != 0x13) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + /* is it too long? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read the data */ + for (y = 0; y < len; y++) { + t = der_printable_value_decode(in[x++]); + if (t == -1) { + return CRYPT_INVALID_ARG; + } + out[y] = t; + } + + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c new file mode 100644 index 000000000..9b00f61b0 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c @@ -0,0 +1,287 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" +#include + + +/** + @file der_decode_sequence_ex.c + ASN.1 DER, decode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Decode a SEQUENCE + @param in The DER encoded input + @param inlen The size of the input + @param list The list of items to decode + @param outlen The number of items in the list + @param ordered Search an unordeded or ordered list + @return CRYPT_OK on success +*/ +int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, + ltc_asn1_list *list, unsigned long outlen, int ordered) +{ + int err, type; + unsigned long size, x, y, z, i, blksize; + void *data; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(list != NULL); + + /* get blk size */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */ + x = 0; + if (in[x] != 0x30 && in[x] != 0x31) { + return CRYPT_INVALID_PACKET; + } + ++x; + + if (in[x] < 128) { + blksize = in[x++]; + } else if (in[x] & 0x80) { + if (in[x] < 0x81 || in[x] > 0x83) { + return CRYPT_INVALID_PACKET; + } + y = in[x++] & 0x7F; + + /* would reading the len bytes overrun? */ + if (x + y > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read len */ + blksize = 0; + while (y--) { + blksize = (blksize << 8) | (unsigned long)in[x++]; + } + } + + /* would this blksize overflow? */ + if (x + blksize > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* mark all as unused */ + for (i = 0; i < outlen; i++) { + list[i].used = 0; + } + + /* ok read data */ + inlen = blksize; + for (i = 0; i < outlen; i++) { + z = 0; + type = list[i].type; + size = list[i].size; + data = list[i].data; + if (!ordered && list[i].used == 1) { continue; } + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + z = inlen; + if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = der_length_boolean(&z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_INTEGER: + z = inlen; + if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + if ((err = der_length_integer(data, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_SHORT_INTEGER: + z = inlen; + if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) { + goto LBL_ERR; + } + + break; + + case LTC_ASN1_BIT_STRING: + z = inlen; + if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_OCTET_STRING: + z = inlen; + if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_NULL: + if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) { + if (!ordered) { continue; } + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + z = 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + z = inlen; + if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_IA5_STRING: + z = inlen; + if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + + case LTC_ASN1_PRINTABLE_STRING: + z = inlen; + if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_UTF8_STRING: + z = inlen; + if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_UTCTIME: + z = inlen; + if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + break; + + case LTC_ASN1_SET: + z = inlen; + if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: + /* detect if we have the right type */ + if ((type == LTC_ASN1_SETOF && (in[x] & 0x3F) != 0x31) || (type == LTC_ASN1_SEQUENCE && (in[x] & 0x3F) != 0x30)) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + z = inlen; + if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + break; + + + case LTC_ASN1_CHOICE: + z = inlen; + if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) { + if (!ordered) { continue; } + goto LBL_ERR; + } + break; + + default: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + x += z; + inlen -= z; + list[i].used = 1; + if (!ordered) { + /* restart the decoder */ + i = -1; + } + } + + for (i = 0; i < outlen; i++) { + if (list[i].used == 0) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + } + err = CRYPT_OK; + +LBL_ERR: + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c,v $ */ +/* $Revision: 1.16 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c new file mode 100644 index 000000000..9c648bc89 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c @@ -0,0 +1,386 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_decode_sequence_flexi.c + ASN.1 DER, decode an array of ASN.1 types with a flexi parser, Tom St Denis +*/ + +#ifdef LTC_DER + +static unsigned long fetch_length(const unsigned char *in, unsigned long inlen) +{ + unsigned long x, y, z; + + y = 0; + + /* skip type and read len */ + if (inlen < 2) { + return 0xFFFFFFFF; + } + ++in; ++y; + + /* read len */ + x = *in++; ++y; + + /* <128 means literal */ + if (x < 128) { + return x+y; + } + x &= 0x7F; /* the lower 7 bits are the length of the length */ + inlen -= 2; + + /* len means len of len! */ + if (x == 0 || x > 4 || x > inlen) { + return 0xFFFFFFFF; + } + + y += x; + z = 0; + while (x--) { + z = (z<<8) | ((unsigned long)*in); + ++in; + } + return z+y; +} + +/** + ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements. + @param in The input buffer + @param inlen [in/out] The length of the input buffer and on output the amount of decoded data + @param out [out] A pointer to the linked list + @return CRYPT_OK on success. +*/ +int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out) +{ + ltc_asn1_list *l; + unsigned long err, type, len, totlen, x, y; + void *realloc_tmp; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != NULL); + LTC_ARGCHK(out != NULL); + + l = NULL; + totlen = 0; + + /* scan the input and and get lengths and what not */ + while (*inlen) { + /* read the type byte */ + type = *in; + + /* fetch length */ + len = fetch_length(in, *inlen); + if (len > *inlen) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* alloc new link */ + if (l == NULL) { + l = XCALLOC(1, sizeof(*l)); + if (l == NULL) { + err = CRYPT_MEM; + goto error; + } + } else { + l->next = XCALLOC(1, sizeof(*l)); + if (l->next == NULL) { + err = CRYPT_MEM; + goto error; + } + l->next->prev = l; + l = l->next; + } + + /* now switch on type */ + switch (type) { + case 0x01: /* BOOLEAN */ + l->type = LTC_ASN1_BOOLEAN; + l->size = 1; + l->data = XCALLOC(1, sizeof(int)); + + if ((err = der_decode_boolean(in, *inlen, l->data)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_boolean(&len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x02: /* INTEGER */ + /* init field */ + l->type = LTC_ASN1_INTEGER; + l->size = 1; + if ((err = mp_init(&l->data)) != CRYPT_OK) { + goto error; + } + + /* decode field */ + if ((err = der_decode_integer(in, *inlen, l->data)) != CRYPT_OK) { + goto error; + } + + /* calc length of object */ + if ((err = der_length_integer(l->data, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x03: /* BIT */ + /* init field */ + l->type = LTC_ASN1_BIT_STRING; + l->size = len * 8; /* *8 because we store decoded bits one per char and they are encoded 8 per char. */ + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_bit_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_bit_string(l->size, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x04: /* OCTET */ + + /* init field */ + l->type = LTC_ASN1_OCTET_STRING; + l->size = len; + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_octet_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_octet_string(l->size, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x05: /* NULL */ + + /* valid NULL is 0x05 0x00 */ + if (in[0] != 0x05 || in[1] != 0x00) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* simple to store ;-) */ + l->type = LTC_ASN1_NULL; + l->data = NULL; + l->size = 0; + len = 2; + + break; + + case 0x06: /* OID */ + + /* init field */ + l->type = LTC_ASN1_OBJECT_IDENTIFIER; + l->size = len; + + if ((l->data = XCALLOC(len, sizeof(unsigned long))) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_object_identifier(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_object_identifier(l->data, l->size, &len)) != CRYPT_OK) { + goto error; + } + + /* resize it to save a bunch of mem */ + if ((realloc_tmp = XREALLOC(l->data, l->size * sizeof(unsigned long))) == NULL) { + /* out of heap but this is not an error */ + break; + } + l->data = realloc_tmp; + break; + + case 0x0C: /* UTF8 */ + + /* init field */ + l->type = LTC_ASN1_UTF8_STRING; + l->size = len; + + if ((l->data = XCALLOC(sizeof(wchar_t), l->size)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_utf8_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_utf8_string(l->data, l->size, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x13: /* PRINTABLE */ + + /* init field */ + l->type = LTC_ASN1_PRINTABLE_STRING; + l->size = len; + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_printable_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_printable_string(l->data, l->size, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x16: /* IA5 */ + + /* init field */ + l->type = LTC_ASN1_IA5_STRING; + l->size = len; + + if ((l->data = XCALLOC(1, l->size)) == NULL) { + err = CRYPT_MEM; + goto error; + } + + if ((err = der_decode_ia5_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_ia5_string(l->data, l->size, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x17: /* UTC TIME */ + + /* init field */ + l->type = LTC_ASN1_UTCTIME; + l->size = 1; + + if ((l->data = XCALLOC(1, sizeof(ltc_utctime))) == NULL) { + err = CRYPT_MEM; + goto error; + } + + len = *inlen; + if ((err = der_decode_utctime(in, &len, l->data)) != CRYPT_OK) { + goto error; + } + + if ((err = der_length_utctime(l->data, &len)) != CRYPT_OK) { + goto error; + } + break; + + case 0x30: /* SEQUENCE */ + case 0x31: /* SET */ + + /* init field */ + l->type = (type == 0x30) ? LTC_ASN1_SEQUENCE : LTC_ASN1_SET; + + /* we have to decode the SEQUENCE header and get it's length */ + + /* move past type */ + ++in; --(*inlen); + + /* read length byte */ + x = *in++; --(*inlen); + + /* smallest SEQUENCE/SET header */ + y = 2; + + /* now if it's > 127 the next bytes are the length of the length */ + if (x > 128) { + x &= 0x7F; + in += x; + *inlen -= x; + + /* update sequence header len */ + y += x; + } + + /* Sequence elements go as child */ + len = len - y; + if ((err = der_decode_sequence_flexi(in, &len, &(l->child))) != CRYPT_OK) { + goto error; + } + + /* len update */ + totlen += y; + + /* link them up y0 */ + l->child->parent = l; + + break; + default: + /* invalid byte ... this is a soft error */ + /* remove link */ + l = l->prev; + XFREE(l->next); + l->next = NULL; + goto outside; + } + + /* advance pointers */ + totlen += len; + in += len; + *inlen -= len; + } + +outside: + + /* rewind l please */ + while (l->prev != NULL || l->parent != NULL) { + if (l->parent != NULL) { + l = l->parent; + } else { + l = l->prev; + } + } + + /* return */ + *out = l; + *inlen = totlen; + return CRYPT_OK; + +error: + /* free list */ + der_sequence_free(l); + + return err; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c,v $ */ +/* $Revision: 1.26 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c new file mode 100644 index 000000000..ff633df35 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c @@ -0,0 +1,139 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" +#include + + +/** + @file der_decode_sequence_multi.c + ASN.1 DER, decode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Decode a SEQUENCE type using a VA list + @param in Input buffer + @param inlen Length of input in octets + @remark <...> is of the form (int, unsigned long, void*) + @return CRYPT_OK on success +*/ +int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) +{ + int err, type; + unsigned long size, x; + void *data; + va_list args; + ltc_asn1_list *list; + + LTC_ARGCHK(in != NULL); + + /* get size of output that will be required */ + va_start(args, inlen); + x = 0; + for (;;) { + type = va_arg(args, int); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTF8_STRING: + case LTC_ASN1_UTCTIME: + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: + case LTC_ASN1_CHOICE: + ++x; + break; + + default: + va_end(args); + return CRYPT_INVALID_ARG; + } + } + va_end(args); + + /* allocate structure for x elements */ + if (x == 0) { + return CRYPT_NOP; + } + + list = XCALLOC(sizeof(*list), x); + if (list == NULL) { + return CRYPT_MEM; + } + + /* fill in the structure */ + va_start(args, inlen); + x = 0; + for (;;) { + type = va_arg(args, int); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTF8_STRING: + case LTC_ASN1_UTCTIME: + case LTC_ASN1_SEQUENCE: + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_CHOICE: + list[x].type = type; + list[x].size = size; + list[x++].data = data; + break; + + default: + va_end(args); + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + va_end(args); + + err = der_decode_sequence(in, inlen, list, x); +LBL_ERR: + XFREE(list); + return err; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c,v $ */ +/* $Revision: 1.13 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c new file mode 100644 index 000000000..907e4e1c3 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c @@ -0,0 +1,68 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_decode_short_integer.c + ASN.1 DER, decode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Read a short integer + @param in The DER encoded data + @param inlen Size of data + @param num [out] The integer to decode + @return CRYPT_OK if successful +*/ +int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num) +{ + unsigned long len, x, y; + + LTC_ARGCHK(num != NULL); + LTC_ARGCHK(in != NULL); + + /* check length */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check header */ + x = 0; + if ((in[x++] & 0x1F) != 0x02) { + return CRYPT_INVALID_PACKET; + } + + /* get the packet len */ + len = in[x++]; + + if (x + len > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read number */ + y = 0; + while (len--) { + y = (y<<8) | (unsigned long)in[x++]; + } + *num = y; + + return CRYPT_OK; + +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utctime.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utctime.c new file mode 100644 index 000000000..7f3f0d766 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utctime.c @@ -0,0 +1,127 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_decode_utctime.c + ASN.1 DER, decode a UTCTIME, Tom St Denis +*/ + +#ifdef LTC_DER + +static int char_to_int(unsigned char x) +{ + switch (x) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + } + return 100; +} + +#define DECODE_V(y, max) \ + y = char_to_int(buf[x])*10 + char_to_int(buf[x+1]); \ + if (y >= max) return CRYPT_INVALID_PACKET; \ + x += 2; + +/** + Decodes a UTC time structure in DER format (reads all 6 valid encoding formats) + @param in Input buffer + @param inlen Length of input buffer in octets + @param out [out] Destination of UTC time structure + @return CRYPT_OK if successful +*/ +int der_decode_utctime(const unsigned char *in, unsigned long *inlen, + ltc_utctime *out) +{ + unsigned char buf[32]; + unsigned long x; + int y; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != NULL); + LTC_ARGCHK(out != NULL); + + /* check header */ + if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* decode the string */ + for (x = 0; x < in[1]; x++) { + y = der_ia5_value_decode(in[x+2]); + if (y == -1) { + return CRYPT_INVALID_PACKET; + } + buf[x] = y; + } + *inlen = 2 + x; + + + /* possible encodings are +YYMMDDhhmmZ +YYMMDDhhmm+hh'mm' +YYMMDDhhmm-hh'mm' +YYMMDDhhmmssZ +YYMMDDhhmmss+hh'mm' +YYMMDDhhmmss-hh'mm' + + So let's do a trivial decode upto [including] mm + */ + + x = 0; + DECODE_V(out->YY, 100); + DECODE_V(out->MM, 13); + DECODE_V(out->DD, 32); + DECODE_V(out->hh, 24); + DECODE_V(out->mm, 60); + + /* clear timezone and seconds info */ + out->off_dir = out->off_hh = out->off_mm = out->ss = 0; + + /* now is it Z, +, - or 0-9 */ + if (buf[x] == 'Z') { + return CRYPT_OK; + } else if (buf[x] == '+' || buf[x] == '-') { + out->off_dir = (buf[x++] == '+') ? 0 : 1; + DECODE_V(out->off_hh, 24); + DECODE_V(out->off_mm, 60); + return CRYPT_OK; + } + + /* decode seconds */ + DECODE_V(out->ss, 60); + + /* now is it Z, +, - */ + if (buf[x] == 'Z') { + return CRYPT_OK; + } else if (buf[x] == '+' || buf[x] == '-') { + out->off_dir = (buf[x++] == '+') ? 0 : 1; + DECODE_V(out->off_hh, 24); + DECODE_V(out->off_mm, 60); + return CRYPT_OK; + } else { + return CRYPT_INVALID_PACKET; + } +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c new file mode 100644 index 000000000..898d6cd2a --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c @@ -0,0 +1,111 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_decode_utf8_string.c + ASN.1 DER, encode a UTF8 STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a UTF8 STRING + @param in The DER encoded UTF8 STRING + @param inlen The size of the DER UTF8 STRING + @param out [out] The array of utf8s stored (one per char) + @param outlen [in/out] The number of utf8s stored + @return CRYPT_OK if successful +*/ +int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, + wchar_t *out, unsigned long *outlen) +{ + wchar_t tmp; + unsigned long x, y, z, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x0C */ + if ((in[0] & 0x1F) != 0x0C) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* proceed to decode */ + for (y = 0; x < inlen; ) { + /* get first byte */ + tmp = in[x++]; + + /* count number of bytes */ + for (z = 0; (tmp & 0x80) && (z <= 4); z++, tmp = (tmp << 1) & 0xFF); + + if (z > 4 || (x + (z - 1) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* decode, grab upper bits */ + tmp >>= z; + + /* grab remaining bytes */ + if (z > 1) { --z; } + while (z-- != 0) { + if ((in[x] & 0xC0) != 0x80) { + return CRYPT_INVALID_PACKET; + } + tmp = (tmp << 6) | ((wchar_t)in[x++] & 0x3F); + } + + if (y > *outlen) { + *outlen = y; + return CRYPT_BUFFER_OVERFLOW; + } + out[y++] = tmp; + } + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_decode_utf8_string.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_bit_string.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_bit_string.c new file mode 100644 index 000000000..ca29c58a7 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_bit_string.c @@ -0,0 +1,89 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_encode_bit_string.c + ASN.1 DER, encode a BIT STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a BIT STRING + @param in The array of bits to store (one per char) + @param inlen The number of bits tostore + @param out [out] The destination for the DER encoded BIT STRING + @param outlen [in/out] The max size and resulting size of the DER BIT STRING + @return CRYPT_OK if successful +*/ +int der_encode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long len, x, y; + unsigned char buf; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* avoid overflows */ + if ((err = der_length_bit_string(inlen, &len)) != CRYPT_OK) { + return err; + } + + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* store header (include bit padding count in length) */ + x = 0; + y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1; + + out[x++] = 0x03; + if (y < 128) { + out[x++] = (unsigned char)y; + } else if (y < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)y; + } else if (y < 65536) { + out[x++] = 0x82; + out[x++] = (unsigned char)((y>>8)&255); + out[x++] = (unsigned char)(y&255); + } + + /* store number of zero padding bits */ + out[x++] = (unsigned char)((8 - inlen) & 7); + + /* store the bits in big endian format */ + for (y = buf = 0; y < inlen; y++) { + buf |= (in[y] ? 1 : 0) << (7 - (y & 7)); + if ((y & 7) == 7) { + out[x++] = buf; + buf = 0; + } + } + /* store last byte */ + if (inlen & 7) { + out[x++] = buf; + } + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_boolean.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_boolean.c new file mode 100644 index 000000000..ded2731f9 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_boolean.c @@ -0,0 +1,51 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_encode_boolean.c + ASN.1 DER, encode a BOOLEAN, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a BOOLEAN + @param in The boolean to encode + @param out [out] The destination for the DER encoded BOOLEAN + @param outlen [in/out] The max size and resulting size of the DER BOOLEAN + @return CRYPT_OK if successful +*/ +int der_encode_boolean(int in, + unsigned char *out, unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(out != NULL); + + if (*outlen < 3) { + *outlen = 3; + return CRYPT_BUFFER_OVERFLOW; + } + + *outlen = 3; + out[0] = 0x01; + out[1] = 0x01; + out[2] = in ? 0xFF : 0x00; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/boolean/der_encode_boolean.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_ia5_string.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_ia5_string.c new file mode 100644 index 000000000..30d3f4374 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_ia5_string.c @@ -0,0 +1,85 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_encode_ia5_string.c + ASN.1 DER, encode a IA5 STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Store an IA5 STRING + @param in The array of IA5 to store (one per char) + @param inlen The number of IA5 to store + @param out [out] The destination for the DER encoded IA5 STRING + @param outlen [in/out] The max size and resulting size of the DER IA5 STRING + @return CRYPT_OK if successful +*/ +int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + if ((err = der_length_ia5_string(in, inlen, &len)) != CRYPT_OK) { + return err; + } + + /* too big? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x16; + if (inlen < 128) { + out[x++] = (unsigned char)inlen; + } else if (inlen < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)inlen; + } else if (inlen < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else if (inlen < 16777216UL) { + out[x++] = 0x83; + out[x++] = (unsigned char)((inlen>>16)&255); + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else { + return CRYPT_INVALID_ARG; + } + + /* store octets */ + for (y = 0; y < inlen; y++) { + out[x++] = der_ia5_char_encode(in[y]); + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_encode_ia5_string.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_integer.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_integer.c new file mode 100644 index 000000000..4137a94bb --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_integer.c @@ -0,0 +1,130 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_encode_integer.c + ASN.1 DER, encode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/* Exports a positive bignum as DER format (upto 2^32 bytes in size) */ +/** + Store a mp_int integer + @param num The first mp_int to encode + @param out [out] The destination for the DER encoded integers + @param outlen [in/out] The max size and resulting size of the DER encoded integers + @return CRYPT_OK if successful +*/ +int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen) +{ + unsigned long tmplen, y; + int err, leading_zero; + + LTC_ARGCHK(num != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* find out how big this will be */ + if ((err = der_length_integer(num, &tmplen)) != CRYPT_OK) { + return err; + } + + if (*outlen < tmplen) { + *outlen = tmplen; + return CRYPT_BUFFER_OVERFLOW; + } + + if (mp_cmp_d(num, 0) != LTC_MP_LT) { + /* we only need a leading zero if the msb of the first byte is one */ + if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) { + leading_zero = 1; + } else { + leading_zero = 0; + } + + /* get length of num in bytes (plus 1 since we force the msbyte to zero) */ + y = mp_unsigned_bin_size(num) + leading_zero; + } else { + leading_zero = 0; + y = mp_count_bits(num); + y = y + (8 - (y & 7)); + y = y >> 3; + if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --y; + } + + /* now store initial data */ + *out++ = 0x02; + if (y < 128) { + /* short form */ + *out++ = (unsigned char)y; + } else if (y < 256) { + *out++ = 0x81; + *out++ = (unsigned char)y; + } else if (y < 65536UL) { + *out++ = 0x82; + *out++ = (unsigned char)((y>>8)&255); + *out++ = (unsigned char)y; + } else if (y < 16777216UL) { + *out++ = 0x83; + *out++ = (unsigned char)((y>>16)&255); + *out++ = (unsigned char)((y>>8)&255); + *out++ = (unsigned char)y; + } else { + return CRYPT_INVALID_ARG; + } + + /* now store msbyte of zero if num is non-zero */ + if (leading_zero) { + *out++ = 0x00; + } + + /* if it's not zero store it as big endian */ + if (mp_cmp_d(num, 0) == LTC_MP_GT) { + /* now store the mpint */ + if ((err = mp_to_unsigned_bin(num, out)) != CRYPT_OK) { + return err; + } + } else if (mp_iszero(num) != LTC_MP_YES) { + void *tmp; + + /* negative */ + if (mp_init(&tmp) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* 2^roundup and subtract */ + y = mp_count_bits(num); + y = y + (8 - (y & 7)); + if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) y -= 8; + if (mp_2expt(tmp, y) != CRYPT_OK || mp_add(tmp, num, tmp) != CRYPT_OK) { + mp_clear(tmp); + return CRYPT_MEM; + } + if ((err = mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) { + mp_clear(tmp); + return err; + } + mp_clear(tmp); + } + + /* we good */ + *outlen = tmplen; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_object_identifier.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_object_identifier.c new file mode 100644 index 000000000..68e216276 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_object_identifier.c @@ -0,0 +1,111 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_encode_object_identifier.c + ASN.1 DER, Encode Object Identifier, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Encode an OID + @param words The words to encode (upto 32-bits each) + @param nwords The number of words in the OID + @param out [out] Destination of OID data + @param outlen [in/out] The max and resulting size of the OID + @return CRYPT_OK if successful +*/ +int der_encode_object_identifier(unsigned long *words, unsigned long nwords, + unsigned char *out, unsigned long *outlen) +{ + unsigned long i, x, y, z, t, mask, wordbuf; + int err; + + LTC_ARGCHK(words != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* check length */ + if ((err = der_length_object_identifier(words, nwords, &x)) != CRYPT_OK) { + return err; + } + if (x > *outlen) { + *outlen = x; + return CRYPT_BUFFER_OVERFLOW; + } + + /* compute length to store OID data */ + z = 0; + wordbuf = words[0] * 40 + words[1]; + for (y = 1; y < nwords; y++) { + t = der_object_identifier_bits(wordbuf); + z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0); + if (y < nwords - 1) { + wordbuf = words[y + 1]; + } + } + + /* store header + length */ + x = 0; + out[x++] = 0x06; + if (z < 128) { + out[x++] = (unsigned char)z; + } else if (z < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)z; + } else if (z < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((z>>8)&255); + out[x++] = (unsigned char)(z&255); + } else { + return CRYPT_INVALID_ARG; + } + + /* store first byte */ + wordbuf = words[0] * 40 + words[1]; + for (i = 1; i < nwords; i++) { + /* store 7 bit words in little endian */ + t = wordbuf & 0xFFFFFFFF; + if (t) { + y = x; + mask = 0; + while (t) { + out[x++] = (unsigned char)((t & 0x7F) | mask); + t >>= 7; + mask |= 0x80; /* upper bit is set on all but the last byte */ + } + /* now swap bytes y...x-1 */ + z = x - 1; + while (y < z) { + t = out[y]; out[y] = out[z]; out[z] = (unsigned char)t; + ++y; + --z; + } + } else { + /* zero word */ + out[x++] = 0x00; + } + + if (i < nwords - 1) { + wordbuf = words[i + 1]; + } + } + + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_octet_string.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_octet_string.c new file mode 100644 index 000000000..b3ee7f4a4 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_octet_string.c @@ -0,0 +1,86 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_encode_octet_string.c + ASN.1 DER, encode a OCTET STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store an OCTET STRING + @param in The array of OCTETS to store (one per char) + @param inlen The number of OCTETS to store + @param out [out] The destination for the DER encoded OCTET STRING + @param outlen [in/out] The max size and resulting size of the DER OCTET STRING + @return CRYPT_OK if successful +*/ +int der_encode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + if ((err = der_length_octet_string(inlen, &len)) != CRYPT_OK) { + return err; + } + + /* too big? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x04; + if (inlen < 128) { + out[x++] = (unsigned char)inlen; + } else if (inlen < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)inlen; + } else if (inlen < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else if (inlen < 16777216UL) { + out[x++] = 0x83; + out[x++] = (unsigned char)((inlen>>16)&255); + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else { + return CRYPT_INVALID_ARG; + } + + /* store octets */ + for (y = 0; y < inlen; y++) { + out[x++] = in[y]; + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_encode_octet_string.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_printable_string.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_printable_string.c new file mode 100644 index 000000000..a1dab5f40 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_printable_string.c @@ -0,0 +1,85 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_encode_printable_string.c + ASN.1 DER, encode a printable STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Store an printable STRING + @param in The array of printable to store (one per char) + @param inlen The number of printable to store + @param out [out] The destination for the DER encoded printable STRING + @param outlen [in/out] The max size and resulting size of the DER printable STRING + @return CRYPT_OK if successful +*/ +int der_encode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + if ((err = der_length_printable_string(in, inlen, &len)) != CRYPT_OK) { + return err; + } + + /* too big? */ + if (len > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x13; + if (inlen < 128) { + out[x++] = (unsigned char)inlen; + } else if (inlen < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)inlen; + } else if (inlen < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else if (inlen < 16777216UL) { + out[x++] = 0x83; + out[x++] = (unsigned char)((inlen>>16)&255); + out[x++] = (unsigned char)((inlen>>8)&255); + out[x++] = (unsigned char)(inlen&255); + } else { + return CRYPT_INVALID_ARG; + } + + /* store octets */ + for (y = 0; y < inlen; y++) { + out[x++] = der_printable_char_encode(in[y]); + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_encode_printable_string.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_sequence_ex.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_sequence_ex.c new file mode 100644 index 000000000..3df19cf4a --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_sequence_ex.c @@ -0,0 +1,335 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" +#include + + +/** + @file der_encode_sequence_ex.c + ASN.1 DER, encode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Encode a SEQUENCE + @param list The list of items to encode + @param inlen The number of items in the list + @param out [out] The destination + @param outlen [in/out] The size of the output + @param type_of LTC_ASN1_SEQUENCE or LTC_ASN1_SET/LTC_ASN1_SETOF + @return CRYPT_OK on success +*/ +int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int type_of) +{ + int err, type; + unsigned long size, x, y, z, i; + void *data; + + LTC_ARGCHK(list != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get size of output that will be required */ + y = 0; + for (i = 0; i < inlen; i++) { + type = list[i].type; + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + if ((err = der_length_boolean(&x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_INTEGER: + if ((err = der_length_integer(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SHORT_INTEGER: + if ((err = der_length_short_integer(*((unsigned long*)data), &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_BIT_STRING: + if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_OCTET_STRING: + if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_NULL: + y += 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_IA5_STRING: + if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_PRINTABLE_STRING: + if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_UTF8_STRING: + if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_UTCTIME: + if ((err = der_length_utctime(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: + if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + default: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + + /* calc header size */ + z = y; + if (y < 128) { + y += 2; + } else if (y < 256) { + /* 0x30 0x81 LL */ + y += 3; + } else if (y < 65536UL) { + /* 0x30 0x82 LL LL */ + y += 4; + } else if (y < 16777216UL) { + /* 0x30 0x83 LL LL LL */ + y += 5; + } else { + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + + /* too big ? */ + if (*outlen < y) { + *outlen = y; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* store header */ + x = 0; + out[x++] = (type_of == LTC_ASN1_SEQUENCE) ? 0x30 : 0x31; + + if (z < 128) { + out[x++] = (unsigned char)z; + } else if (z < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)z; + } else if (z < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((z>>8UL)&255); + out[x++] = (unsigned char)(z&255); + } else if (z < 16777216UL) { + out[x++] = 0x83; + out[x++] = (unsigned char)((z>>16UL)&255); + out[x++] = (unsigned char)((z>>8UL)&255); + out[x++] = (unsigned char)(z&255); + } + + /* store data */ + *outlen -= x; + for (i = 0; i < inlen; i++) { + type = list[i].type; + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + z = *outlen; + if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_INTEGER: + z = *outlen; + if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_SHORT_INTEGER: + z = *outlen; + if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_BIT_STRING: + z = *outlen; + if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_OCTET_STRING: + z = *outlen; + if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_NULL: + out[x++] = 0x05; + out[x++] = 0x00; + *outlen -= 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + z = *outlen; + if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_IA5_STRING: + z = *outlen; + if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_PRINTABLE_STRING: + z = *outlen; + if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_UTF8_STRING: + z = *outlen; + if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_UTCTIME: + z = *outlen; + if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_SET: + z = *outlen; + if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_SETOF: + z = *outlen; + if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_SEQUENCE: + z = *outlen; + if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + default: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + *outlen = x; + err = CRYPT_OK; + +LBL_ERR: + return err; +} + +#endif diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_sequence_multi.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_sequence_multi.c new file mode 100644 index 000000000..782f042e1 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_sequence_multi.c @@ -0,0 +1,138 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" +#include + + +/** + @file der_encode_sequence_multi.c + ASN.1 DER, encode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Encode a SEQUENCE type using a VA list + @param out [out] Destination for data + @param outlen [in/out] Length of buffer and resulting length of output + @remark <...> is of the form (int, unsigned long, void*) + @return CRYPT_OK on success +*/ +int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) +{ + int err, type; + unsigned long size, x; + void *data; + va_list args; + ltc_asn1_list *list; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get size of output that will be required */ + va_start(args, outlen); + x = 0; + for (;;) { + type = va_arg(args, int); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTF8_STRING: + case LTC_ASN1_UTCTIME: + case LTC_ASN1_SEQUENCE: + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + ++x; + break; + + default: + va_end(args); + return CRYPT_INVALID_ARG; + } + } + va_end(args); + + /* allocate structure for x elements */ + if (x == 0) { + return CRYPT_NOP; + } + + list = XCALLOC(sizeof(*list), x); + if (list == NULL) { + return CRYPT_MEM; + } + + /* fill in the structure */ + va_start(args, outlen); + x = 0; + for (;;) { + type = va_arg(args, int); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTF8_STRING: + case LTC_ASN1_UTCTIME: + case LTC_ASN1_SEQUENCE: + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + list[x].type = type; + list[x].size = size; + list[x++].data = data; + break; + + default: + va_end(args); + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + va_end(args); + + err = der_encode_sequence(list, x, out, outlen); +LBL_ERR: + XFREE(list); + return err; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c,v $ */ +/* $Revision: 1.12 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_set.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_set.c new file mode 100644 index 000000000..25d247d18 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_set.c @@ -0,0 +1,103 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_encode_set.c + ASN.1 DER, Encode a SET, Tom St Denis +*/ + +#ifdef LTC_DER + +/* LTC define to ASN.1 TAG */ +static int ltc_to_asn1(int v) +{ + switch (v) { + case LTC_ASN1_BOOLEAN: return 0x01; + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: return 0x02; + case LTC_ASN1_BIT_STRING: return 0x03; + case LTC_ASN1_OCTET_STRING: return 0x04; + case LTC_ASN1_NULL: return 0x05; + case LTC_ASN1_OBJECT_IDENTIFIER: return 0x06; + case LTC_ASN1_UTF8_STRING: return 0x0C; + case LTC_ASN1_PRINTABLE_STRING: return 0x13; + case LTC_ASN1_IA5_STRING: return 0x16; + case LTC_ASN1_UTCTIME: return 0x17; + case LTC_ASN1_SEQUENCE: return 0x30; + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: return 0x31; + default: return -1; + } +} + + +static int LTC_CALL qsort_helper1(const void *a, const void *b) +{ + ltc_asn1_list *A = (ltc_asn1_list *)a, *B = (ltc_asn1_list *)b; + int r; + + r = ltc_to_asn1(A->type) - ltc_to_asn1(B->type); + + /* for QSORT the order is UNDEFINED if they are "equal" which means it is NOT DETERMINISTIC. So we force it to be :-) */ + if (r == 0) { + /* their order in the original list now determines the position */ + return A->used - B->used; + } else { + return r; + } +} + +/* + Encode a SET type + @param list The list of items to encode + @param inlen The number of items in the list + @param out [out] The destination + @param outlen [in/out] The size of the output + @return CRYPT_OK on success +*/ +int der_encode_set(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + ltc_asn1_list *copy; + unsigned long x; + int err; + + /* make copy of list */ + copy = XCALLOC(inlen, sizeof(*copy)); + if (copy == NULL) { + return CRYPT_MEM; + } + + /* fill in used member with index so we can fully sort it */ + for (x = 0; x < inlen; x++) { + copy[x] = list[x]; + copy[x].used = x; + } + + /* sort it by the "type" field */ + XQSORT(copy, inlen, sizeof(*copy), &qsort_helper1); + + /* call der_encode_sequence_ex() */ + err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET); + + /* free list */ + XFREE(copy); + + return err; +} + + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/set/der_encode_set.c,v $ */ +/* $Revision: 1.12 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_setof.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_setof.c new file mode 100644 index 000000000..0987cabe8 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_setof.c @@ -0,0 +1,162 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_encode_setof.c + ASN.1 DER, Encode SET OF, Tom St Denis +*/ + +#ifdef LTC_DER + +struct edge { + unsigned char *start; + unsigned long size; +}; + +static int LTC_CALL qsort_helper2(const void *a, const void *b) +{ + struct edge *A = (struct edge *)a, *B = (struct edge *)b; + int r; + unsigned long x; + + /* compare min length */ + r = XMEMCMP(A->start, B->start, MIN(A->size, B->size)); + + if (r == 0 && A->size != B->size) { + if (A->size > B->size) { + for (x = B->size; x < A->size; x++) { + if (A->start[x]) { + return 1; + } + } + } else { + for (x = A->size; x < B->size; x++) { + if (B->start[x]) { + return -1; + } + } + } + } + + return r; +} + +/** + Encode a SETOF stucture + @param list The list of items to encode + @param inlen The number of items in the list + @param out [out] The destination + @param outlen [in/out] The size of the output + @return CRYPT_OK on success +*/ +int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, z, hdrlen; + int err; + struct edge *edges; + unsigned char *ptr, *buf; + + /* check that they're all the same type */ + for (x = 1; x < inlen; x++) { + if (list[x].type != list[x-1].type) { + return CRYPT_INVALID_ARG; + } + } + + /* alloc buffer to store copy of output */ + buf = XCALLOC(1, *outlen); + if (buf == NULL) { + return CRYPT_MEM; + } + + /* encode list */ + if ((err = der_encode_sequence_ex(list, inlen, buf, outlen, LTC_ASN1_SETOF)) != CRYPT_OK) { + XFREE(buf); + return err; + } + + /* allocate edges */ + edges = XCALLOC(inlen, sizeof(*edges)); + if (edges == NULL) { + XFREE(buf); + return CRYPT_MEM; + } + + /* skip header */ + ptr = buf + 1; + + /* now skip length data */ + x = *ptr++; + if (x >= 0x80) { + ptr += (x & 0x7F); + } + + /* get the size of the static header */ + hdrlen = (unsigned long)((size_t)ptr - (size_t)buf); + + + /* scan for edges */ + x = 0; + while (ptr < (buf + *outlen)) { + /* store start */ + edges[x].start = ptr; + + /* skip type */ + z = 1; + + /* parse length */ + y = ptr[z++]; + if (y < 128) { + edges[x].size = y; + } else { + y &= 0x7F; + edges[x].size = 0; + while (y--) { + edges[x].size = (edges[x].size << 8) | ((unsigned long)ptr[z++]); + } + } + + /* skip content */ + edges[x].size += z; + ptr += edges[x].size; + ++x; + } + + /* sort based on contents (using edges) */ + XQSORT(edges, inlen, sizeof(*edges), &qsort_helper2); + + /* copy static header */ + XMEMCPY(out, buf, hdrlen); + + /* copy+sort using edges+indecies to output from buffer */ + for (y = hdrlen, x = 0; x < inlen; x++) { + XMEMCPY(out+y, edges[x].start, edges[x].size); + y += edges[x].size; + } + +#ifdef LTC_CLEAN_STACK + zeromem(buf, *outlen); +#endif + + /* free buffers */ + XFREE(edges); + XFREE(buf); + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c,v $ */ +/* $Revision: 1.12 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_short_integer.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_short_integer.c new file mode 100644 index 000000000..9b167d084 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_short_integer.c @@ -0,0 +1,97 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_encode_short_integer.c + ASN.1 DER, encode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a short integer in the range (0,2^32-1) + @param num The integer to encode + @param out [out] The destination for the DER encoded integers + @param outlen [in/out] The max size and resulting size of the DER encoded integers + @return CRYPT_OK if successful +*/ +int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen) +{ + unsigned long len, x, y, z; + int err; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* force to 32 bits */ + num &= 0xFFFFFFFFUL; + + /* find out how big this will be */ + if ((err = der_length_short_integer(num, &len)) != CRYPT_OK) { + return err; + } + + if (*outlen < len) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* get len of output */ + z = 0; + y = num; + while (y) { + ++z; + y >>= 8; + } + + /* handle zero */ + if (z == 0) { + z = 1; + } + + /* see if msb is set */ + z += (num&(1UL<<((z<<3) - 1))) ? 1 : 0; + + /* adjust the number so the msB is non-zero */ + for (x = 0; (z <= 4) && (x < (4 - z)); x++) { + num <<= 8; + } + + /* store header */ + x = 0; + out[x++] = 0x02; + out[x++] = (unsigned char)z; + + /* if 31st bit is set output a leading zero and decrement count */ + if (z == 5) { + out[x++] = 0; + --z; + } + + /* store values */ + for (y = 0; y < z; y++) { + out[x++] = (unsigned char)((num >> 24) & 0xFF); + num <<= 8; + } + + /* we good */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_encode_short_integer.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_utctime.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_utctime.c new file mode 100644 index 000000000..167a2b490 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_utctime.c @@ -0,0 +1,83 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_encode_utctime.c + ASN.1 DER, encode a UTCTIME, Tom St Denis +*/ + +#ifdef LTC_DER + +static const char *baseten = "0123456789"; + +#define STORE_V(y) \ + out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \ + out[x++] = der_ia5_char_encode(baseten[y % 10]); + +/** + Encodes a UTC time structure in DER format + @param utctime The UTC time structure to encode + @param out The destination of the DER encoding of the UTC time structure + @param outlen [in/out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_encode_utctime(ltc_utctime *utctime, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, tmplen; + int err; + + LTC_ARGCHK(utctime != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((err = der_length_utctime(utctime, &tmplen)) != CRYPT_OK) { + return err; + } + if (tmplen > *outlen) { + *outlen = tmplen; + return CRYPT_BUFFER_OVERFLOW; + } + + /* store header */ + out[0] = 0x17; + + /* store values */ + x = 2; + STORE_V(utctime->YY); + STORE_V(utctime->MM); + STORE_V(utctime->DD); + STORE_V(utctime->hh); + STORE_V(utctime->mm); + STORE_V(utctime->ss); + + if (utctime->off_mm || utctime->off_hh) { + out[x++] = der_ia5_char_encode(utctime->off_dir ? '-' : '+'); + STORE_V(utctime->off_hh); + STORE_V(utctime->off_mm); + } else { + out[x++] = der_ia5_char_encode('Z'); + } + + /* store length */ + out[1] = (unsigned char)(x - 2); + + /* all good let's return */ + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_utf8_string.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_utf8_string.c new file mode 100644 index 000000000..84d8d0621 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_utf8_string.c @@ -0,0 +1,105 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_encode_utf8_string.c + ASN.1 DER, encode a UTF8 STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store an UTF8 STRING + @param in The array of UTF8 to store (one per wchar_t) + @param inlen The number of UTF8 to store + @param out [out] The destination for the DER encoded UTF8 STRING + @param outlen [in/out] The max size and resulting size of the DER UTF8 STRING + @return CRYPT_OK if successful +*/ +int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + for (x = len = 0; x < inlen; x++) { + if (in[x] < 0 || in[x] > 0x1FFFF) { + return CRYPT_INVALID_ARG; + } + len += der_utf8_charsize(in[x]); + } + + if (len < 128) { + y = 2 + len; + } else if (len < 256) { + y = 3 + len; + } else if (len < 65536UL) { + y = 4 + len; + } else if (len < 16777216UL) { + y = 5 + len; + } else { + return CRYPT_INVALID_ARG; + } + + /* too big? */ + if (y > *outlen) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x0C; + if (len < 128) { + out[x++] = (unsigned char)len; + } else if (len < 256) { + out[x++] = 0x81; + out[x++] = (unsigned char)len; + } else if (len < 65536UL) { + out[x++] = 0x82; + out[x++] = (unsigned char)((len>>8)&255); + out[x++] = (unsigned char)(len&255); + } else if (len < 16777216UL) { + out[x++] = 0x83; + out[x++] = (unsigned char)((len>>16)&255); + out[x++] = (unsigned char)((len>>8)&255); + out[x++] = (unsigned char)(len&255); + } else { + return CRYPT_INVALID_ARG; + } + + /* store UTF8 */ + for (y = 0; y < inlen; y++) { + switch (der_utf8_charsize(in[y])) { + case 1: out[x++] = (unsigned char)in[y]; break; + case 2: out[x++] = 0xC0 | ((in[y] >> 6) & 0x1F); out[x++] = 0x80 | (in[y] & 0x3F); break; + case 3: out[x++] = 0xE0 | ((in[y] >> 12) & 0x0F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break; + case 4: out[x++] = 0xF0 | ((in[y] >> 18) & 0x07); out[x++] = 0x80 | ((in[y] >> 12) & 0x3F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break; + } + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_encode_utf8_string.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_length_bit_string.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_bit_string.c new file mode 100644 index 000000000..2bffa3b63 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_bit_string.c @@ -0,0 +1,54 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_length_bit_string.c + ASN.1 DER, get length of BIT STRING, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Gets length of DER encoding of BIT STRING + @param nbits The number of bits in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_bit_string(unsigned long nbits, unsigned long *outlen) +{ + unsigned long nbytes; + LTC_ARGCHK(outlen != NULL); + + /* get the number of the bytes */ + nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1; + + if (nbytes < 128) { + /* 03 LL PP DD DD DD ... */ + *outlen = 2 + nbytes; + } else if (nbytes < 256) { + /* 03 81 LL PP DD DD DD ... */ + *outlen = 3 + nbytes; + } else if (nbytes < 65536) { + /* 03 82 LL LL PP DD DD DD ... */ + *outlen = 4 + nbytes; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_length_boolean.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_boolean.c new file mode 100644 index 000000000..e34ce5c65 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_boolean.c @@ -0,0 +1,35 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_length_boolean.c + ASN.1 DER, get length of a BOOLEAN, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Gets length of DER encoding of a BOOLEAN + @param outlen [out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_length_boolean(unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + *outlen = 3; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/boolean/der_length_boolean.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c new file mode 100644 index 000000000..473bc7932 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c @@ -0,0 +1,194 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_length_ia5_string.c + ASN.1 DER, get length of IA5 STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +static const struct { + int code, value; +} ia5_table[] = { +{ '\0', 0 }, +{ '\a', 7 }, +{ '\b', 8 }, +{ '\t', 9 }, +{ '\n', 10 }, +{ '\f', 12 }, +{ '\r', 13 }, +{ ' ', 32 }, +{ '!', 33 }, +{ '"', 34 }, +{ '#', 35 }, +{ '$', 36 }, +{ '%', 37 }, +{ '&', 38 }, +{ '\'', 39 }, +{ '(', 40 }, +{ ')', 41 }, +{ '*', 42 }, +{ '+', 43 }, +{ ',', 44 }, +{ '-', 45 }, +{ '.', 46 }, +{ '/', 47 }, +{ '0', 48 }, +{ '1', 49 }, +{ '2', 50 }, +{ '3', 51 }, +{ '4', 52 }, +{ '5', 53 }, +{ '6', 54 }, +{ '7', 55 }, +{ '8', 56 }, +{ '9', 57 }, +{ ':', 58 }, +{ ';', 59 }, +{ '<', 60 }, +{ '=', 61 }, +{ '>', 62 }, +{ '?', 63 }, +{ '@', 64 }, +{ 'A', 65 }, +{ 'B', 66 }, +{ 'C', 67 }, +{ 'D', 68 }, +{ 'E', 69 }, +{ 'F', 70 }, +{ 'G', 71 }, +{ 'H', 72 }, +{ 'I', 73 }, +{ 'J', 74 }, +{ 'K', 75 }, +{ 'L', 76 }, +{ 'M', 77 }, +{ 'N', 78 }, +{ 'O', 79 }, +{ 'P', 80 }, +{ 'Q', 81 }, +{ 'R', 82 }, +{ 'S', 83 }, +{ 'T', 84 }, +{ 'U', 85 }, +{ 'V', 86 }, +{ 'W', 87 }, +{ 'X', 88 }, +{ 'Y', 89 }, +{ 'Z', 90 }, +{ '[', 91 }, +{ '\\', 92 }, +{ ']', 93 }, +{ '^', 94 }, +{ '_', 95 }, +{ '`', 96 }, +{ 'a', 97 }, +{ 'b', 98 }, +{ 'c', 99 }, +{ 'd', 100 }, +{ 'e', 101 }, +{ 'f', 102 }, +{ 'g', 103 }, +{ 'h', 104 }, +{ 'i', 105 }, +{ 'j', 106 }, +{ 'k', 107 }, +{ 'l', 108 }, +{ 'm', 109 }, +{ 'n', 110 }, +{ 'o', 111 }, +{ 'p', 112 }, +{ 'q', 113 }, +{ 'r', 114 }, +{ 's', 115 }, +{ 't', 116 }, +{ 'u', 117 }, +{ 'v', 118 }, +{ 'w', 119 }, +{ 'x', 120 }, +{ 'y', 121 }, +{ 'z', 122 }, +{ '{', 123 }, +{ '|', 124 }, +{ '}', 125 }, +{ '~', 126 } +}; + +int der_ia5_char_encode(int c) +{ + int x; + for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) { + if (ia5_table[x].code == c) { + return ia5_table[x].value; + } + } + return -1; +} + +int der_ia5_value_decode(int v) +{ + int x; + for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) { + if (ia5_table[x].value == v) { + return ia5_table[x].code; + } + } + return -1; +} + +/** + Gets length of DER encoding of IA5 STRING + @param octets The values you want to encode + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) +{ + unsigned long x; + + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(octets != NULL); + + /* scan string for validity */ + for (x = 0; x < noctets; x++) { + if (der_ia5_char_encode(octets[x]) == -1) { + return CRYPT_INVALID_ARG; + } + } + + if (noctets < 128) { + /* 16 LL DD DD DD ... */ + *outlen = 2 + noctets; + } else if (noctets < 256) { + /* 16 81 LL DD DD DD ... */ + *outlen = 3 + noctets; + } else if (noctets < 65536UL) { + /* 16 82 LL LL DD DD DD ... */ + *outlen = 4 + noctets; + } else if (noctets < 16777216UL) { + /* 16 83 LL LL LL DD DD DD ... */ + *outlen = 5 + noctets; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_length_integer.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_integer.c new file mode 100644 index 000000000..540d205f0 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_integer.c @@ -0,0 +1,82 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_length_integer.c + ASN.1 DER, get length of encoding, Tom St Denis +*/ + + +#ifdef LTC_DER +/** + Gets length of DER encoding of num + @param num The int to get the size of + @param outlen [out] The length of the DER encoding for the given integer + @return CRYPT_OK if successful +*/ +int der_length_integer(void *num, unsigned long *outlen) +{ + unsigned long z, len; + int leading_zero; + + LTC_ARGCHK(num != NULL); + LTC_ARGCHK(outlen != NULL); + + if (mp_cmp_d(num, 0) != LTC_MP_LT) { + /* positive */ + + /* we only need a leading zero if the msb of the first byte is one */ + if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) { + leading_zero = 1; + } else { + leading_zero = 0; + } + + /* size for bignum */ + z = len = leading_zero + mp_unsigned_bin_size(num); + } else { + /* it's negative */ + /* find power of 2 that is a multiple of eight and greater than count bits */ + leading_zero = 0; + z = mp_count_bits(num); + z = z + (8 - (z & 7)); + if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --z; + len = z = z >> 3; + } + + /* now we need a length */ + if (z < 128) { + /* short form */ + ++len; + } else { + /* long form (relies on z != 0), assumes length bytes < 128 */ + ++len; + + while (z) { + ++len; + z >>= 8; + } + } + + /* we need a 0x02 to indicate it's INTEGER */ + ++len; + + /* return length */ + *outlen = len; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c new file mode 100644 index 000000000..94c326f7c --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c @@ -0,0 +1,89 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_length_object_identifier.c + ASN.1 DER, get length of Object Identifier, Tom St Denis +*/ + +#ifdef LTC_DER + +unsigned long der_object_identifier_bits(unsigned long x) +{ + unsigned long c; + x &= 0xFFFFFFFF; + c = 0; + while (x) { + ++c; + x >>= 1; + } + return c; +} + + +/** + Gets length of DER encoding of Object Identifier + @param nwords The number of OID words + @param words The actual OID words to get the size of + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen) +{ + unsigned long y, z, t, wordbuf; + + LTC_ARGCHK(words != NULL); + LTC_ARGCHK(outlen != NULL); + + + /* must be >= 2 words */ + if (nwords < 2) { + return CRYPT_INVALID_ARG; + } + + /* word1 = 0,1,2,3 and word2 0..39 */ + if (words[0] > 3 || (words[0] < 2 && words[1] > 39)) { + return CRYPT_INVALID_ARG; + } + + /* leading word is the first two */ + z = 0; + wordbuf = words[0] * 40 + words[1]; + for (y = 1; y < nwords; y++) { + t = der_object_identifier_bits(wordbuf); + z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0); + if (y < nwords - 1) { + /* grab next word */ + wordbuf = words[y+1]; + } + } + + /* now depending on the length our length encoding changes */ + if (z < 128) { + z += 2; + } else if (z < 256) { + z += 3; + } else if (z < 65536UL) { + z += 4; + } else { + return CRYPT_INVALID_ARG; + } + + *outlen = z; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_length_octet_string.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_octet_string.c new file mode 100644 index 000000000..acd4053c1 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_octet_string.c @@ -0,0 +1,53 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_length_octet_string.c + ASN.1 DER, get length of OCTET STRING, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Gets length of DER encoding of OCTET STRING + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_octet_string(unsigned long noctets, unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + + if (noctets < 128) { + /* 04 LL DD DD DD ... */ + *outlen = 2 + noctets; + } else if (noctets < 256) { + /* 04 81 LL DD DD DD ... */ + *outlen = 3 + noctets; + } else if (noctets < 65536UL) { + /* 04 82 LL LL DD DD DD ... */ + *outlen = 4 + noctets; + } else if (noctets < 16777216UL) { + /* 04 83 LL LL LL DD DD DD ... */ + *outlen = 5 + noctets; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_length_printable_string.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_printable_string.c new file mode 100644 index 000000000..ef1ed0ede --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_printable_string.c @@ -0,0 +1,166 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_length_printable_string.c + ASN.1 DER, get length of Printable STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +static const struct { + int code, value; +} printable_table[] = { +{ ' ', 32 }, +{ '\'', 39 }, +{ '(', 40 }, +{ ')', 41 }, +{ '+', 43 }, +{ ',', 44 }, +{ '-', 45 }, +{ '.', 46 }, +{ '/', 47 }, +{ '0', 48 }, +{ '1', 49 }, +{ '2', 50 }, +{ '3', 51 }, +{ '4', 52 }, +{ '5', 53 }, +{ '6', 54 }, +{ '7', 55 }, +{ '8', 56 }, +{ '9', 57 }, +{ ':', 58 }, +{ '=', 61 }, +{ '?', 63 }, +{ 'A', 65 }, +{ 'B', 66 }, +{ 'C', 67 }, +{ 'D', 68 }, +{ 'E', 69 }, +{ 'F', 70 }, +{ 'G', 71 }, +{ 'H', 72 }, +{ 'I', 73 }, +{ 'J', 74 }, +{ 'K', 75 }, +{ 'L', 76 }, +{ 'M', 77 }, +{ 'N', 78 }, +{ 'O', 79 }, +{ 'P', 80 }, +{ 'Q', 81 }, +{ 'R', 82 }, +{ 'S', 83 }, +{ 'T', 84 }, +{ 'U', 85 }, +{ 'V', 86 }, +{ 'W', 87 }, +{ 'X', 88 }, +{ 'Y', 89 }, +{ 'Z', 90 }, +{ 'a', 97 }, +{ 'b', 98 }, +{ 'c', 99 }, +{ 'd', 100 }, +{ 'e', 101 }, +{ 'f', 102 }, +{ 'g', 103 }, +{ 'h', 104 }, +{ 'i', 105 }, +{ 'j', 106 }, +{ 'k', 107 }, +{ 'l', 108 }, +{ 'm', 109 }, +{ 'n', 110 }, +{ 'o', 111 }, +{ 'p', 112 }, +{ 'q', 113 }, +{ 'r', 114 }, +{ 's', 115 }, +{ 't', 116 }, +{ 'u', 117 }, +{ 'v', 118 }, +{ 'w', 119 }, +{ 'x', 120 }, +{ 'y', 121 }, +{ 'z', 122 }, +}; + +int der_printable_char_encode(int c) +{ + int x; + for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) { + if (printable_table[x].code == c) { + return printable_table[x].value; + } + } + return -1; +} + +int der_printable_value_decode(int v) +{ + int x; + for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) { + if (printable_table[x].value == v) { + return printable_table[x].code; + } + } + return -1; +} + +/** + Gets length of DER encoding of Printable STRING + @param octets The values you want to encode + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) +{ + unsigned long x; + + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(octets != NULL); + + /* scan string for validity */ + for (x = 0; x < noctets; x++) { + if (der_printable_char_encode(octets[x]) == -1) { + return CRYPT_INVALID_ARG; + } + } + + if (noctets < 128) { + /* 16 LL DD DD DD ... */ + *outlen = 2 + noctets; + } else if (noctets < 256) { + /* 16 81 LL DD DD DD ... */ + *outlen = 3 + noctets; + } else if (noctets < 65536UL) { + /* 16 82 LL LL DD DD DD ... */ + *outlen = 4 + noctets; + } else if (noctets < 16777216UL) { + /* 16 83 LL LL LL DD DD DD ... */ + *outlen = 5 + noctets; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_length_sequence.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_sequence.c new file mode 100644 index 000000000..e75ed7e7e --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_sequence.c @@ -0,0 +1,169 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_length_sequence.c + ASN.1 DER, length a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Get the length of a DER sequence + @param list The sequences of items in the SEQUENCE + @param inlen The number of items + @param outlen [out] The length required in octets to store it + @return CRYPT_OK on success +*/ +int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, + unsigned long *outlen) +{ + int err, type; + unsigned long size, x, y, z, i; + void *data; + + LTC_ARGCHK(list != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get size of output that will be required */ + y = 0; + for (i = 0; i < inlen; i++) { + type = list[i].type; + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_BOOLEAN: + if ((err = der_length_boolean(&x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_INTEGER: + if ((err = der_length_integer(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SHORT_INTEGER: + if ((err = der_length_short_integer(*((unsigned long *)data), &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_BIT_STRING: + if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_OCTET_STRING: + if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_NULL: + y += 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_IA5_STRING: + if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_PRINTABLE_STRING: + if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_UTCTIME: + if ((err = der_length_utctime(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_UTF8_STRING: + if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: + if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + + default: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + + /* calc header size */ + z = y; + if (y < 128) { + y += 2; + } else if (y < 256) { + /* 0x30 0x81 LL */ + y += 3; + } else if (y < 65536UL) { + /* 0x30 0x82 LL LL */ + y += 4; + } else if (y < 16777216UL) { + /* 0x30 0x83 LL LL LL */ + y += 5; + } else { + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + + /* store size */ + *outlen = y; + err = CRYPT_OK; + +LBL_ERR: + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c,v $ */ +/* $Revision: 1.14 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_length_short_integer.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_short_integer.c new file mode 100644 index 000000000..afa6dd0ee --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_short_integer.c @@ -0,0 +1,70 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_length_short_integer.c + ASN.1 DER, get length of encoding, Tom St Denis +*/ + + +#ifdef LTC_DER +/** + Gets length of DER encoding of num + @param num The integer to get the size of + @param outlen [out] The length of the DER encoding for the given integer + @return CRYPT_OK if successful +*/ +int der_length_short_integer(unsigned long num, unsigned long *outlen) +{ + unsigned long z, y, len; + + LTC_ARGCHK(outlen != NULL); + + /* force to 32 bits */ + num &= 0xFFFFFFFFUL; + + /* get the number of bytes */ + z = 0; + y = num; + while (y) { + ++z; + y >>= 8; + } + + /* handle zero */ + if (z == 0) { + z = 1; + } + + /* we need a 0x02 to indicate it's INTEGER */ + len = 1; + + /* length byte */ + ++len; + + /* bytes in value */ + len += z; + + /* see if msb is set */ + len += (num&(1UL<<((z<<3) - 1))) ? 1 : 0; + + /* return length */ + *outlen = len; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utctime.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utctime.c new file mode 100644 index 000000000..1296babba --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utctime.c @@ -0,0 +1,46 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_length_utctime.c + ASN.1 DER, get length of UTCTIME, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Gets length of DER encoding of UTCTIME + @param utctime The UTC time structure to get the size of + @param outlen [out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(utctime != NULL); + + if (utctime->off_hh == 0 && utctime->off_mm == 0) { + /* we encode as YYMMDDhhmmssZ */ + *outlen = 2 + 13; + } else { + /* we encode as YYMMDDhhmmss{+|-}hh'mm' */ + *outlen = 2 + 17; + } + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c new file mode 100644 index 000000000..514db8450 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c @@ -0,0 +1,83 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_length_utf8_string.c + ASN.1 DER, get length of UTF8 STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +/** Return the size in bytes of a UTF-8 character + @param c The UTF-8 character to measure + @return The size in bytes +*/ +unsigned long der_utf8_charsize(const wchar_t c) +{ + if (c <= 0x7F) { + return 1; + } else if (c <= 0x7FF) { + return 2; + } else if (c <= 0xFFFF) { + return 3; + } else { + return 4; + } +} + +/** + Gets length of DER encoding of UTF8 STRING + @param in The characters to measure the length of + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen) +{ + unsigned long x, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(outlen != NULL); + + len = 0; + for (x = 0; x < noctets; x++) { + if (in[x] < 0 || in[x] > 0x10FFFF) { + return CRYPT_INVALID_ARG; + } + len += der_utf8_charsize(in[x]); + } + + if (len < 128) { + /* 0C LL DD DD DD ... */ + *outlen = 2 + len; + } else if (len < 256) { + /* 0C 81 LL DD DD DD ... */ + *outlen = 3 + len; + } else if (len < 65536UL) { + /* 0C 82 LL LL DD DD DD ... */ + *outlen = 4 + len; + } else if (len < 16777216UL) { + /* 0C 83 LL LL LL DD DD DD ... */ + *outlen = 5 + len; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_length_utf8_string.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/asn1/der_sequence_free.c b/StormLib/src/libtomcrypt/src/pk/asn1/der_sequence_free.c new file mode 100644 index 000000000..488721539 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/asn1/der_sequence_free.c @@ -0,0 +1,65 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file der_sequence_free.c + ASN.1 DER, free's a structure allocated by der_decode_sequence_flexi(), Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Free memory allocated by der_decode_sequence_flexi() + @param in The list to free +*/ +void der_sequence_free(ltc_asn1_list *in) +{ + ltc_asn1_list *l; + + /* walk to the start of the chain */ + while (in->prev != NULL || in->parent != NULL) { + if (in->parent != NULL) { + in = in->parent; + } else { + in = in->prev; + } + } + + /* now walk the list and free stuff */ + while (in != NULL) { + /* is there a child? */ + if (in->child) { + /* disconnect */ + in->child->parent = NULL; + der_sequence_free(in->child); + } + + switch (in->type) { + case LTC_ASN1_SET: + case LTC_ASN1_SETOF: + case LTC_ASN1_SEQUENCE: break; + case LTC_ASN1_INTEGER : if (in->data != NULL) { mp_clear(in->data); } break; + default : if (in->data != NULL) { XFREE(in->data); } + } + + /* move to next and free current */ + l = in->next; + free(in); + in = l; + } +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_free.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c b/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c new file mode 100644 index 000000000..5a1324c49 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c @@ -0,0 +1,76 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "../../headers/tomcrypt.h" + +/** + @file ltc_ecc_map.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Map a projective jacbobian point back to affine space + @param P [in/out] The point to map + @param modulus The modulus of the field the ECC curve is in + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success +*/ +int ltc_ecc_map(ecc_point *P, void *modulus, void *mp) +{ + void *t1, *t2; + int err; + + LTC_ARGCHK(P != NULL); + LTC_ARGCHK(modulus != NULL); + LTC_ARGCHK(mp != NULL); + + if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) { + return CRYPT_MEM; + } + + /* first map z back to normal */ + if ((err = mp_montgomery_reduce(P->z, modulus, mp)) != CRYPT_OK) { goto done; } + + /* get 1/z */ + if ((err = mp_invmod(P->z, modulus, t1)) != CRYPT_OK) { goto done; } + + /* get 1/z^2 and 1/z^3 */ + if ((err = mp_sqr(t1, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_mod(t2, modulus, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_mul(t1, t2, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_mod(t1, modulus, t1)) != CRYPT_OK) { goto done; } + + /* multiply against x/y */ + if ((err = mp_mul(P->x, t2, P->x)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(P->x, modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = mp_mul(P->y, t1, P->y)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(P->y, modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = mp_set(P->z, 1)) != CRYPT_OK) { goto done; } + + err = CRYPT_OK; +done: + mp_clear_multi(t1, t2, NULL); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_map.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ + diff --git a/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c b/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c new file mode 100644 index 000000000..2c468eaaf --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c @@ -0,0 +1,207 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "../../headers/tomcrypt.h" + +/** + @file ltc_ecc_mul2add.c + ECC Crypto, Shamir's Trick, Tom St Denis +*/ + +#ifdef LTC_MECC + +#ifdef LTC_ECC_SHAMIR + +/** Computes kA*A + kB*B = C using Shamir's Trick + @param A First point to multiply + @param kA What to multiple A by + @param B Second point to multiply + @param kB What to multiple B by + @param C [out] Destination point (can overlap with A or B + @param modulus Modulus for curve + @return CRYPT_OK on success +*/ +int ltc_ecc_mul2add(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, + void *modulus) +{ + ecc_point *precomp[16]; + unsigned bitbufA, bitbufB, lenA, lenB, len, x, y, nA, nB, nibble; + unsigned char *tA, *tB; + int err, first; + void *mp, *mu; + + /* argchks */ + LTC_ARGCHK(A != NULL); + LTC_ARGCHK(B != NULL); + LTC_ARGCHK(C != NULL); + LTC_ARGCHK(kA != NULL); + LTC_ARGCHK(kB != NULL); + LTC_ARGCHK(modulus != NULL); + + /* allocate memory */ + tA = XCALLOC(1, ECC_BUF_SIZE); + if (tA == NULL) { + return CRYPT_MEM; + } + tB = XCALLOC(1, ECC_BUF_SIZE); + if (tB == NULL) { + XFREE(tA); + return CRYPT_MEM; + } + + /* get sizes */ + lenA = mp_unsigned_bin_size(kA); + lenB = mp_unsigned_bin_size(kB); + len = MAX(lenA, lenB); + + /* sanity check */ + if ((lenA > ECC_BUF_SIZE) || (lenB > ECC_BUF_SIZE)) { + err = CRYPT_INVALID_ARG; + goto ERR_T; + } + + /* extract and justify kA */ + mp_to_unsigned_bin(kA, (len - lenA) + tA); + + /* extract and justify kB */ + mp_to_unsigned_bin(kB, (len - lenB) + tB); + + /* allocate the table */ + for (x = 0; x < 16; x++) { + precomp[x] = ltc_ecc_new_point(); + if (precomp[x] == NULL) { + for (y = 0; y < x; ++y) { + ltc_ecc_del_point(precomp[y]); + } + err = CRYPT_MEM; + goto ERR_T; + } + } + + /* init montgomery reduction */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { + goto ERR_P; + } + if ((err = mp_init(&mu)) != CRYPT_OK) { + goto ERR_MP; + } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { + goto ERR_MU; + } + + /* copy ones ... */ + if ((err = mp_mulmod(A->x, mu, modulus, precomp[1]->x)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_mulmod(A->y, mu, modulus, precomp[1]->y)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_mulmod(A->z, mu, modulus, precomp[1]->z)) != CRYPT_OK) { goto ERR_MU; } + + if ((err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z)) != CRYPT_OK) { goto ERR_MU; } + + /* precomp [i,0](A + B) table */ + if ((err = ltc_mp.ecc_ptdbl(precomp[1], precomp[2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + if ((err = ltc_mp.ecc_ptadd(precomp[1], precomp[2], precomp[3], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + + /* precomp [0,i](A + B) table */ + if ((err = ltc_mp.ecc_ptdbl(precomp[1<<2], precomp[2<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + if ((err = ltc_mp.ecc_ptadd(precomp[1<<2], precomp[2<<2], precomp[3<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + + /* precomp [i,j](A + B) table (i != 0, j != 0) */ + for (x = 1; x < 4; x++) { + for (y = 1; y < 4; y++) { + if ((err = ltc_mp.ecc_ptadd(precomp[x], precomp[(y<<2)], precomp[x+(y<<2)], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + } + } + + nibble = 3; + first = 1; + bitbufA = tA[0]; + bitbufB = tB[0]; + + /* for every byte of the multiplicands */ + for (x = -1;; ) { + /* grab a nibble */ + if (++nibble == 4) { + ++x; if (x == len) break; + bitbufA = tA[x]; + bitbufB = tB[x]; + nibble = 0; + } + + /* extract two bits from both, shift/update */ + nA = (bitbufA >> 6) & 0x03; + nB = (bitbufB >> 6) & 0x03; + bitbufA = (bitbufA << 2) & 0xFF; + bitbufB = (bitbufB << 2) & 0xFF; + + /* if both zero, if first, continue */ + if ((nA == 0) && (nB == 0) && (first == 1)) { + continue; + } + + /* double twice, only if this isn't the first */ + if (first == 0) { + /* double twice */ + if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + } + + /* if not both zero */ + if ((nA != 0) || (nB != 0)) { + if (first == 1) { + /* if first, copy from table */ + first = 0; + if ((err = mp_copy(precomp[nA + (nB<<2)]->x, C->x)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_copy(precomp[nA + (nB<<2)]->y, C->y)) != CRYPT_OK) { goto ERR_MU; } + if ((err = mp_copy(precomp[nA + (nB<<2)]->z, C->z)) != CRYPT_OK) { goto ERR_MU; } + } else { + /* if not first, add from table */ + if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } + } + } + } + + /* reduce to affine */ + err = ltc_ecc_map(C, modulus, mp); + + /* clean up */ +ERR_MU: + mp_clear(mu); +ERR_MP: + mp_montgomery_free(mp); +ERR_P: + for (x = 0; x < 16; x++) { + ltc_ecc_del_point(precomp[x]); + } +ERR_T: +#ifdef LTC_CLEAN_STACK + zeromem(tA, ECC_BUF_SIZE); + zeromem(tB, ECC_BUF_SIZE); +#endif + XFREE(tA); + XFREE(tB); + + return err; +} + +#endif +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c b/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c new file mode 100644 index 000000000..f9d0cad83 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c @@ -0,0 +1,222 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "../../headers/tomcrypt.h" + +/** + @file ltc_ecc_mulmod.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC +#ifndef LTC_ECC_TIMING_RESISTANT + +/* size of sliding window, don't change this! */ +#define WINSIZE 4 + +/** + Perform a point multiplication + @param k The scalar to multiply by + @param G The base point + @param R [out] Destination for kG + @param modulus The modulus of the field the ECC curve is in + @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective) + @return CRYPT_OK on success +*/ +int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map) +{ + ecc_point *tG, *M[8]; + int i, j, err; + void *mu, *mp; + unsigned long buf; + int first, bitbuf, bitcpy, bitcnt, mode, digidx; + + LTC_ARGCHK(k != NULL); + LTC_ARGCHK(G != NULL); + LTC_ARGCHK(R != NULL); + LTC_ARGCHK(modulus != NULL); + + /* init montgomery reduction */ + if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { + return err; + } + if ((err = mp_init(&mu)) != CRYPT_OK) { + mp_montgomery_free(mp); + return err; + } + if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { + mp_montgomery_free(mp); + mp_clear(mu); + return err; + } + + /* alloc ram for window temps */ + for (i = 0; i < 8; i++) { + M[i] = ltc_ecc_new_point(); + if (M[i] == NULL) { + for (j = 0; j < i; j++) { + ltc_ecc_del_point(M[j]); + } + mp_montgomery_free(mp); + mp_clear(mu); + return CRYPT_MEM; + } + } + + /* make a copy of G incase R==G */ + tG = ltc_ecc_new_point(); + if (tG == NULL) { err = CRYPT_MEM; goto done; } + + /* tG = G and convert to montgomery */ + if (mp_cmp_d(mu, 1) == LTC_MP_EQ) { + if ((err = mp_copy(G->x, tG->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(G->y, tG->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(G->z, tG->z)) != CRYPT_OK) { goto done; } + } else { + if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK) { goto done; } + if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK) { goto done; } + if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK) { goto done; } + } + mp_clear(mu); + mu = NULL; + + /* calc the M tab, which holds kG for k==8..15 */ + /* M[0] == 8G */ + if ((err = ltc_mp.ecc_ptdbl(tG, M[0], modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; } + + /* now find (8+k)G for k=1..7 */ + for (j = 9; j < 16; j++) { + if ((err = ltc_mp.ecc_ptadd(M[j-9], tG, M[j-8], modulus, mp)) != CRYPT_OK) { goto done; } + } + + /* setup sliding window */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = mp_get_digit_count(k) - 1; + bitcpy = bitbuf = 0; + first = 1; + + /* perform ops */ + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + if (digidx == -1) { + break; + } + buf = mp_get_digit(k, digidx); + bitcnt = (int) ltc_mp.bits_per_digit; + --digidx; + } + + /* grab the next msb from the ltiplicand */ + i = (buf >> (ltc_mp.bits_per_digit - 1)) & 1; + buf <<= 1; + + /* skip leading zero bits */ + if (mode == 0 && i == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we double */ + if (mode == 1 && i == 0) { + if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; } + continue; + } + + /* else we add it to the window */ + bitbuf |= (i << (WINSIZE - ++bitcpy)); + mode = 2; + + if (bitcpy == WINSIZE) { + /* if this is the first window we do a simple copy */ + if (first == 1) { + /* R = kG [k = first window] */ + if ((err = mp_copy(M[bitbuf-8]->x, R->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(M[bitbuf-8]->y, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(M[bitbuf-8]->z, R->z)) != CRYPT_OK) { goto done; } + first = 0; + } else { + /* normal window */ + /* ok window is filled so double as required and add */ + /* double first */ + for (j = 0; j < WINSIZE; j++) { + if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; } + } + + /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */ + if ((err = ltc_mp.ecc_ptadd(R, M[bitbuf-8], R, modulus, mp)) != CRYPT_OK) { goto done; } + } + /* empty window and reset */ + bitcpy = bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then double/add */ + if (mode == 2 && bitcpy > 0) { + /* double then add */ + for (j = 0; j < bitcpy; j++) { + /* only double if we have had at least one add first */ + if (first == 0) { + if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; } + } + + bitbuf <<= 1; + if ((bitbuf & (1 << WINSIZE)) != 0) { + if (first == 1){ + /* first add, so copy */ + if ((err = mp_copy(tG->x, R->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(tG->y, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(tG->z, R->z)) != CRYPT_OK) { goto done; } + first = 0; + } else { + /* then add */ + if ((err = ltc_mp.ecc_ptadd(R, tG, R, modulus, mp)) != CRYPT_OK) { goto done; } + } + } + } + } + + /* map R back from projective space */ + if (map) { + err = ltc_ecc_map(R, modulus, mp); + } else { + err = CRYPT_OK; + } +done: + if (mu != NULL) { + mp_clear(mu); + } + mp_montgomery_free(mp); + ltc_ecc_del_point(tG); + for (i = 0; i < 8; i++) { + ltc_ecc_del_point(M[i]); + } + return err; +} + +#endif + +#undef WINSIZE + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c,v $ */ +/* $Revision: 1.26 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c b/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c new file mode 100644 index 000000000..f5a4acb4c --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c @@ -0,0 +1,60 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "../../headers/tomcrypt.h" + +/** + @file ltc_ecc_points.c + ECC Crypto, Tom St Denis +*/ + +#ifdef LTC_MECC + +/** + Allocate a new ECC point + @return A newly allocated point or NULL on error +*/ +ecc_point *ltc_ecc_new_point(void) +{ + ecc_point *p; + p = XCALLOC(1, sizeof(*p)); + if (p == NULL) { + return NULL; + } + if (mp_init_multi(&p->x, &p->y, &p->z, NULL) != CRYPT_OK) { + XFREE(p); + return NULL; + } + return p; +} + +/** Free an ECC point from memory + @param p The point to free +*/ +void ltc_ecc_del_point(ecc_point *p) +{ + /* prevents free'ing null arguments */ + if (p != NULL) { + mp_clear_multi(p->x, p->y, p->z, NULL); /* note: p->z may be NULL but that's ok with this function anyways */ + XFREE(p); + } +} + +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_points.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ + diff --git a/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c b/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c new file mode 100644 index 000000000..b4416fc77 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c @@ -0,0 +1,196 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "../../headers/tomcrypt.h" + +/** + @file ltc_ecc_projective_add_point.c + ECC Crypto, Tom St Denis +*/ + +#if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC)) + +/** + Add two ECC points + @param P The point to add + @param Q The point to add + @param R [out] The destination of the double + @param modulus The modulus of the field the ECC curve is in + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success +*/ +int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp) +{ + void *t1, *t2, *x, *y, *z; + int err; + + LTC_ARGCHK(P != NULL); + LTC_ARGCHK(Q != NULL); + LTC_ARGCHK(R != NULL); + LTC_ARGCHK(modulus != NULL); + LTC_ARGCHK(mp != NULL); + + if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != CRYPT_OK) { + return err; + } + + /* should we dbl instead? */ + if ((err = mp_sub(modulus, Q->y, t1)) != CRYPT_OK) { goto done; } + + if ( (mp_cmp(P->x, Q->x) == LTC_MP_EQ) && + (Q->z != NULL && mp_cmp(P->z, Q->z) == LTC_MP_EQ) && + (mp_cmp(P->y, Q->y) == LTC_MP_EQ || mp_cmp(P->y, t1) == LTC_MP_EQ)) { + mp_clear_multi(t1, t2, x, y, z, NULL); + return ltc_ecc_projective_dbl_point(P, R, modulus, mp); + } + + if ((err = mp_copy(P->x, x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(P->y, y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(P->z, z)) != CRYPT_OK) { goto done; } + + /* if Z is one then these are no-operations */ + if (Q->z != NULL) { + /* T1 = Z' * Z' */ + if ((err = mp_sqr(Q->z, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* X = X * T1 */ + if ((err = mp_mul(t1, x, x)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; } + /* T1 = Z' * T1 */ + if ((err = mp_mul(Q->z, t1, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* Y = Y * T1 */ + if ((err = mp_mul(t1, y, y)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(y, modulus, mp)) != CRYPT_OK) { goto done; } + } + + /* T1 = Z*Z */ + if ((err = mp_sqr(z, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* T2 = X' * T1 */ + if ((err = mp_mul(Q->x, t1, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } + /* T1 = Z * T1 */ + if ((err = mp_mul(z, t1, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* T1 = Y' * T1 */ + if ((err = mp_mul(Q->y, t1, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + + /* Y = Y - T1 */ + if ((err = mp_sub(y, t1, y)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(y, 0) == LTC_MP_LT) { + if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; } + } + /* T1 = 2T1 */ + if ((err = mp_add(t1, t1, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + /* T1 = Y + T1 */ + if ((err = mp_add(t1, y, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + /* X = X - T2 */ + if ((err = mp_sub(x, t2, x)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(x, 0) == LTC_MP_LT) { + if ((err = mp_add(x, modulus, x)) != CRYPT_OK) { goto done; } + } + /* T2 = 2T2 */ + if ((err = mp_add(t2, t2, t2)) != CRYPT_OK) { goto done; } + if (mp_cmp(t2, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + /* T2 = X + T2 */ + if ((err = mp_add(t2, x, t2)) != CRYPT_OK) { goto done; } + if (mp_cmp(t2, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + + /* if Z' != 1 */ + if (Q->z != NULL) { + /* Z = Z * Z' */ + if ((err = mp_mul(z, Q->z, z)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; } + } + + /* Z = Z * X */ + if ((err = mp_mul(z, x, z)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; } + + /* T1 = T1 * X */ + if ((err = mp_mul(t1, x, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* X = X * X */ + if ((err = mp_sqr(x, x)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; } + /* T2 = T2 * x */ + if ((err = mp_mul(t2, x, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } + /* T1 = T1 * X */ + if ((err = mp_mul(t1, x, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + + /* X = Y*Y */ + if ((err = mp_sqr(y, x)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; } + /* X = X - T2 */ + if ((err = mp_sub(x, t2, x)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(x, 0) == LTC_MP_LT) { + if ((err = mp_add(x, modulus, x)) != CRYPT_OK) { goto done; } + } + + /* T2 = T2 - X */ + if ((err = mp_sub(t2, x, t2)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(t2, 0) == LTC_MP_LT) { + if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + /* T2 = T2 - X */ + if ((err = mp_sub(t2, x, t2)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(t2, 0) == LTC_MP_LT) { + if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + /* T2 = T2 * Y */ + if ((err = mp_mul(t2, y, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } + /* Y = T2 - T1 */ + if ((err = mp_sub(t2, t1, y)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(y, 0) == LTC_MP_LT) { + if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; } + } + /* Y = Y/2 */ + if (mp_isodd(y)) { + if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; } + } + if ((err = mp_div_2(y, y)) != CRYPT_OK) { goto done; } + + if ((err = mp_copy(x, R->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(y, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(z, R->z)) != CRYPT_OK) { goto done; } + + err = CRYPT_OK; +done: + mp_clear_multi(t1, t2, x, y, z, NULL); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c,v $ */ +/* $Revision: 1.16 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ + diff --git a/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c b/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c new file mode 100644 index 000000000..b990e0a14 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c @@ -0,0 +1,147 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ +#include "../../headers/tomcrypt.h" + +/** + @file ltc_ecc_projective_dbl_point.c + ECC Crypto, Tom St Denis +*/ + +#if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC)) + +/** + Double an ECC point + @param P The point to double + @param R [out] The destination of the double + @param modulus The modulus of the field the ECC curve is in + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success +*/ +int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp) +{ + void *t1, *t2; + int err; + + LTC_ARGCHK(P != NULL); + LTC_ARGCHK(R != NULL); + LTC_ARGCHK(modulus != NULL); + LTC_ARGCHK(mp != NULL); + + if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) { + return err; + } + + if (P != R) { + if ((err = mp_copy(P->x, R->x)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(P->y, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_copy(P->z, R->z)) != CRYPT_OK) { goto done; } + } + + /* t1 = Z * Z */ + if ((err = mp_sqr(R->z, t1)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } + /* Z = Y * Z */ + if ((err = mp_mul(R->z, R->y, R->z)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(R->z, modulus, mp)) != CRYPT_OK) { goto done; } + /* Z = 2Z */ + if ((err = mp_add(R->z, R->z, R->z)) != CRYPT_OK) { goto done; } + if (mp_cmp(R->z, modulus) != LTC_MP_LT) { + if ((err = mp_sub(R->z, modulus, R->z)) != CRYPT_OK) { goto done; } + } + + /* T2 = X - T1 */ + if ((err = mp_sub(R->x, t1, t2)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(t2, 0) == LTC_MP_LT) { + if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + /* T1 = X + T1 */ + if ((err = mp_add(t1, R->x, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + /* T2 = T1 * T2 */ + if ((err = mp_mul(t1, t2, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } + /* T1 = 2T2 */ + if ((err = mp_add(t2, t2, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + /* T1 = T1 + T2 */ + if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; } + if (mp_cmp(t1, modulus) != LTC_MP_LT) { + if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } + } + + /* Y = 2Y */ + if ((err = mp_add(R->y, R->y, R->y)) != CRYPT_OK) { goto done; } + if (mp_cmp(R->y, modulus) != LTC_MP_LT) { + if ((err = mp_sub(R->y, modulus, R->y)) != CRYPT_OK) { goto done; } + } + /* Y = Y * Y */ + if ((err = mp_sqr(R->y, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; } + /* T2 = Y * Y */ + if ((err = mp_sqr(R->y, t2)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } + /* T2 = T2/2 */ + if (mp_isodd(t2)) { + if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } + } + if ((err = mp_div_2(t2, t2)) != CRYPT_OK) { goto done; } + /* Y = Y * X */ + if ((err = mp_mul(R->y, R->x, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; } + + /* X = T1 * T1 */ + if ((err = mp_sqr(t1, R->x)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(R->x, modulus, mp)) != CRYPT_OK) { goto done; } + /* X = X - Y */ + if ((err = mp_sub(R->x, R->y, R->x)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(R->x, 0) == LTC_MP_LT) { + if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; } + } + /* X = X - Y */ + if ((err = mp_sub(R->x, R->y, R->x)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(R->x, 0) == LTC_MP_LT) { + if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; } + } + + /* Y = Y - X */ + if ((err = mp_sub(R->y, R->x, R->y)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(R->y, 0) == LTC_MP_LT) { + if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; } + } + /* Y = Y * T1 */ + if ((err = mp_mul(R->y, t1, R->y)) != CRYPT_OK) { goto done; } + if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; } + /* Y = Y - T2 */ + if ((err = mp_sub(R->y, t2, R->y)) != CRYPT_OK) { goto done; } + if (mp_cmp_d(R->y, 0) == LTC_MP_LT) { + if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; } + } + + err = CRYPT_OK; +done: + mp_clear_multi(t1, t2, NULL); + return err; +} +#endif +/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c,v $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ + diff --git a/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c b/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c new file mode 100644 index 000000000..e8f641806 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c @@ -0,0 +1,108 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file pkcs_1_mgf1.c + The Mask Generation Function (MGF1) for LTC_PKCS #1, Tom St Denis +*/ + +#ifdef LTC_PKCS_1 + +/** + Perform LTC_PKCS #1 MGF1 (internal) + @param seed The seed for MGF1 + @param seedlen The length of the seed + @param hash_idx The index of the hash desired + @param mask [out] The destination + @param masklen The length of the mask desired + @return CRYPT_OK if successful +*/ +int pkcs_1_mgf1(int hash_idx, + const unsigned char *seed, unsigned long seedlen, + unsigned char *mask, unsigned long masklen) +{ + unsigned long hLen, x; + ulong32 counter; + int err; + hash_state *md; + unsigned char *buf; + + LTC_ARGCHK(seed != NULL); + LTC_ARGCHK(mask != NULL); + + /* ensure valid hash */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + /* get hash output size */ + hLen = hash_descriptor[hash_idx].hashsize; + + /* allocate memory */ + md = XMALLOC(sizeof(hash_state)); + buf = XMALLOC(hLen); + if (md == NULL || buf == NULL) { + if (md != NULL) { + XFREE(md); + } + if (buf != NULL) { + XFREE(buf); + } + return CRYPT_MEM; + } + + /* start counter */ + counter = 0; + + while (masklen > 0) { + /* handle counter */ + STORE32H(counter, buf); + ++counter; + + /* get hash of seed || counter */ + if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(md, seed, seedlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(md, buf, 4)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].done(md, buf)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* store it */ + for (x = 0; x < hLen && masklen > 0; x++, masklen--) { + *mask++ = buf[x]; + } + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(buf, hLen); + zeromem(md, sizeof(hash_state)); +#endif + + XFREE(buf); + XFREE(md); + + return err; +} + +#endif /* LTC_PKCS_1 */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c b/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c new file mode 100644 index 000000000..709ab8a8c --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c @@ -0,0 +1,189 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file pkcs_1_oaep_decode.c + OAEP Padding for LTC_PKCS #1, Tom St Denis +*/ + +#ifdef LTC_PKCS_1 + +/** + LTC_PKCS #1 v2.00 OAEP decode + @param msg The encoded data to decode + @param msglen The length of the encoded data (octets) + @param lparam The session or system data (can be NULL) + @param lparamlen The length of the lparam + @param modulus_bitlen The bit length of the RSA modulus + @param hash_idx The index of the hash desired + @param out [out] Destination of decoding + @param outlen [in/out] The max size and resulting size of the decoding + @param res [out] Result of decoding, 1==valid, 0==invalid + @return CRYPT_OK if successful (even if invalid) +*/ +int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, int hash_idx, + unsigned char *out, unsigned long *outlen, + int *res) +{ + unsigned char *DB, *seed, *mask; + unsigned long hLen, x, y, modulus_len; + int err; + + LTC_ARGCHK(msg != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(res != NULL); + + /* default to invalid packet */ + *res = 0; + + /* test valid hash */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + hLen = hash_descriptor[hash_idx].hashsize; + modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); + + /* test hash/message size */ + if ((2*hLen >= (modulus_len - 2)) || (msglen != modulus_len)) { + return CRYPT_PK_INVALID_SIZE; + } + + /* allocate ram for DB/mask/salt of size modulus_len */ + DB = XMALLOC(modulus_len); + mask = XMALLOC(modulus_len); + seed = XMALLOC(hLen); + if (DB == NULL || mask == NULL || seed == NULL) { + if (DB != NULL) { + XFREE(DB); + } + if (mask != NULL) { + XFREE(mask); + } + if (seed != NULL) { + XFREE(seed); + } + return CRYPT_MEM; + } + + /* ok so it's now in the form + + 0x00 || maskedseed || maskedDB + + 1 || hLen || modulus_len - hLen - 1 + + */ + + /* must have leading 0x00 byte */ + if (msg[0] != 0x00) { + err = CRYPT_OK; + goto LBL_ERR; + } + + /* now read the masked seed */ + x = 1; + XMEMCPY(seed, msg + x, hLen); + x += hLen; + + /* now read the masked DB */ + XMEMCPY(DB, msg + x, modulus_len - hLen - 1); + x += modulus_len - hLen - 1; + + /* compute MGF1 of maskedDB (hLen) */ + if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* XOR against seed */ + for (y = 0; y < hLen; y++) { + seed[y] ^= mask[y]; + } + + /* compute MGF1 of seed (k - hlen - 1) */ + if ((err = pkcs_1_mgf1(hash_idx, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* xor against DB */ + for (y = 0; y < (modulus_len - hLen - 1); y++) { + DB[y] ^= mask[y]; + } + + /* now DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */ + + /* compute lhash and store it in seed [reuse temps!] */ + x = modulus_len; + if (lparam != NULL) { + if ((err = hash_memory(hash_idx, lparam, lparamlen, seed, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + } else { + /* can't pass hash_memory a NULL so use DB with zero length */ + if ((err = hash_memory(hash_idx, DB, 0, seed, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + } + + /* compare the lhash'es */ + if (XMEMCMP(seed, DB, hLen) != 0) { + err = CRYPT_OK; + goto LBL_ERR; + } + + /* now zeroes before a 0x01 */ + for (x = hLen; x < (modulus_len - hLen - 1) && DB[x] == 0x00; x++) { + /* step... */ + } + + /* error out if wasn't 0x01 */ + if (x == (modulus_len - hLen - 1) || DB[x] != 0x01) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + /* rest is the message (and skip 0x01) */ + if ((modulus_len - hLen - 1 - ++x) > *outlen) { + *outlen = modulus_len - hLen - 1 - x; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* copy message */ + *outlen = modulus_len - hLen - 1 - x; + XMEMCPY(out, DB + x, modulus_len - hLen - 1 - x); + x += modulus_len - hLen - 1; + + /* valid packet */ + *res = 1; + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(DB, modulus_len); + zeromem(seed, hLen); + zeromem(mask, modulus_len); +#endif + + XFREE(seed); + XFREE(mask); + XFREE(DB); + + return err; +} + +#endif /* LTC_PKCS_1 */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c,v $ */ +/* $Revision: 1.13 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c b/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c new file mode 100644 index 000000000..c3a7211ef --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c @@ -0,0 +1,177 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file pkcs_1_pss_decode.c + LTC_PKCS #1 PSS Signature Padding, Tom St Denis +*/ + +#ifdef LTC_PKCS_1 + +/** + LTC_PKCS #1 v2.00 PSS decode + @param msghash The hash to verify + @param msghashlen The length of the hash (octets) + @param sig The signature data (encoded data) + @param siglen The length of the signature data (octets) + @param saltlen The length of the salt used (octets) + @param hash_idx The index of the hash desired + @param modulus_bitlen The bit length of the RSA modulus + @param res [out] The result of the comparison, 1==valid, 0==invalid + @return CRYPT_OK if successful (even if the comparison failed) +*/ +int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, + const unsigned char *sig, unsigned long siglen, + unsigned long saltlen, int hash_idx, + unsigned long modulus_bitlen, int *res) +{ + unsigned char *DB, *mask, *salt, *hash; + unsigned long x, y, hLen, modulus_len; + int err; + hash_state md; + + LTC_ARGCHK(msghash != NULL); + LTC_ARGCHK(res != NULL); + + /* default to invalid */ + *res = 0; + + /* ensure hash is valid */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + + hLen = hash_descriptor[hash_idx].hashsize; + modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); + + /* check sizes */ + if ((saltlen > modulus_len) || + (modulus_len < hLen + saltlen + 2) || (siglen != modulus_len)) { + return CRYPT_PK_INVALID_SIZE; + } + + /* allocate ram for DB/mask/salt/hash of size modulus_len */ + DB = XMALLOC(modulus_len); + mask = XMALLOC(modulus_len); + salt = XMALLOC(modulus_len); + hash = XMALLOC(modulus_len); + if (DB == NULL || mask == NULL || salt == NULL || hash == NULL) { + if (DB != NULL) { + XFREE(DB); + } + if (mask != NULL) { + XFREE(mask); + } + if (salt != NULL) { + XFREE(salt); + } + if (hash != NULL) { + XFREE(hash); + } + return CRYPT_MEM; + } + + /* ensure the 0xBC byte */ + if (sig[siglen-1] != 0xBC) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + /* copy out the DB */ + x = 0; + XMEMCPY(DB, sig + x, modulus_len - hLen - 1); + x += modulus_len - hLen - 1; + + /* copy out the hash */ + XMEMCPY(hash, sig + x, hLen); + x += hLen; + + /* check the MSB */ + if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)))) != 0) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + /* generate mask of length modulus_len - hLen - 1 from hash */ + if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* xor against DB */ + for (y = 0; y < (modulus_len - hLen - 1); y++) { + DB[y] ^= mask[y]; + } + + /* now clear the first byte [make sure smaller than modulus] */ + DB[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)); + + /* DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */ + + /* check for zeroes and 0x01 */ + for (x = 0; x < modulus_len - saltlen - hLen - 2; x++) { + if (DB[x] != 0x00) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + } + + /* check for the 0x01 */ + if (DB[x++] != 0x01) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + + /* M = (eight) 0x00 || msghash || salt, mask = H(M) */ + if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) { + goto LBL_ERR; + } + zeromem(mask, 8); + if ((err = hash_descriptor[hash_idx].process(&md, mask, 8)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(&md, DB+x, saltlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].done(&md, mask)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* mask == hash means valid signature */ + if (XMEMCMP(mask, hash, hLen) == 0) { + *res = 1; + } + + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(DB, modulus_len); + zeromem(mask, modulus_len); + zeromem(salt, modulus_len); + zeromem(hash, modulus_len); +#endif + + XFREE(hash); + XFREE(salt); + XFREE(mask); + XFREE(DB); + + return err; +} + +#endif /* LTC_PKCS_1 */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c,v $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_encode.c b/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_encode.c new file mode 100644 index 000000000..68d5e8615 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_encode.c @@ -0,0 +1,175 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file pkcs_1_pss_encode.c + LTC_PKCS #1 PSS Signature Padding, Tom St Denis +*/ + +#ifdef LTC_PKCS_1 + +/** + LTC_PKCS #1 v2.00 Signature Encoding + @param msghash The hash to encode + @param msghashlen The length of the hash (octets) + @param saltlen The length of the salt desired (octets) + @param prng An active PRNG context + @param prng_idx The index of the PRNG desired + @param hash_idx The index of the hash desired + @param modulus_bitlen The bit length of the RSA modulus + @param out [out] The destination of the encoding + @param outlen [in/out] The max size and resulting size of the encoded data + @return CRYPT_OK if successful +*/ +int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, + unsigned long saltlen, prng_state *prng, + int prng_idx, int hash_idx, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned char *DB, *mask, *salt, *hash; + unsigned long x, y, hLen, modulus_len; + int err; + hash_state md; + + LTC_ARGCHK(msghash != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* ensure hash and PRNG are valid */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { + return err; + } + + hLen = hash_descriptor[hash_idx].hashsize; + modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); + + /* check sizes */ + if ((saltlen > modulus_len) || (modulus_len < hLen + saltlen + 2)) { + return CRYPT_PK_INVALID_SIZE; + } + + /* allocate ram for DB/mask/salt/hash of size modulus_len */ + DB = XMALLOC(modulus_len); + mask = XMALLOC(modulus_len); + salt = XMALLOC(modulus_len); + hash = XMALLOC(modulus_len); + if (DB == NULL || mask == NULL || salt == NULL || hash == NULL) { + if (DB != NULL) { + XFREE(DB); + } + if (mask != NULL) { + XFREE(mask); + } + if (salt != NULL) { + XFREE(salt); + } + if (hash != NULL) { + XFREE(hash); + } + return CRYPT_MEM; + } + + + /* generate random salt */ + if (saltlen > 0) { + if (prng_descriptor[prng_idx].read(salt, saltlen, prng) != saltlen) { + err = CRYPT_ERROR_READPRNG; + goto LBL_ERR; + } + } + + /* M = (eight) 0x00 || msghash || salt, hash = H(M) */ + if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) { + goto LBL_ERR; + } + zeromem(DB, 8); + if ((err = hash_descriptor[hash_idx].process(&md, DB, 8)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].process(&md, salt, saltlen)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = hash_descriptor[hash_idx].done(&md, hash)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* generate DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */ + x = 0; + XMEMSET(DB + x, 0, modulus_len - saltlen - hLen - 2); + x += modulus_len - saltlen - hLen - 2; + DB[x++] = 0x01; + XMEMCPY(DB + x, salt, saltlen); + x += saltlen; + + /* generate mask of length modulus_len - hLen - 1 from hash */ + if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* xor against DB */ + for (y = 0; y < (modulus_len - hLen - 1); y++) { + DB[y] ^= mask[y]; + } + + /* output is DB || hash || 0xBC */ + if (*outlen < modulus_len) { + *outlen = modulus_len; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* DB len = modulus_len - hLen - 1 */ + y = 0; + XMEMCPY(out + y, DB, modulus_len - hLen - 1); + y += modulus_len - hLen - 1; + + /* hash */ + XMEMCPY(out + y, hash, hLen); + y += hLen; + + /* 0xBC */ + out[y] = 0xBC; + + /* now clear the 8*modulus_len - modulus_bitlen most significant bits */ + out[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)); + + /* store output size */ + *outlen = modulus_len; + err = CRYPT_OK; +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(DB, modulus_len); + zeromem(mask, modulus_len); + zeromem(salt, modulus_len); + zeromem(hash, modulus_len); +#endif + + XFREE(hash); + XFREE(salt); + XFREE(mask); + XFREE(DB); + + return err; +} + +#endif /* LTC_PKCS_1 */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_encode.c,v $ */ +/* $Revision: 1.9 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c b/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c new file mode 100644 index 000000000..7c3711c17 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c @@ -0,0 +1,110 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** @file pkcs_1_v1_5_decode.c + * + * LTC_PKCS #1 v1.5 Padding. (Andreas Lange) + */ + +#ifdef LTC_PKCS_1 + +/** @brief LTC_PKCS #1 v1.5 decode. + * + * @param msg The encoded data to decode + * @param msglen The length of the encoded data (octets) + * @param block_type Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks) + * @param modulus_bitlen The bit length of the RSA modulus + * @param out [out] Destination of decoding + * @param outlen [in/out] The max size and resulting size of the decoding + * @param is_valid [out] Boolean whether the padding was valid + * + * @return CRYPT_OK if successful (even if invalid) + */ +int pkcs_1_v1_5_decode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + unsigned char *out, + unsigned long *outlen, + int *is_valid) +{ + unsigned long modulus_len, ps_len, i; + int result; + + /* default to invalid packet */ + *is_valid = 0; + + modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); + + /* test message size */ + + if ((msglen > modulus_len) || (modulus_len < 11)) { + return CRYPT_PK_INVALID_SIZE; + } + + /* separate encoded message */ + + if ((msg[0] != 0x00) || (msg[1] != (unsigned char)block_type)) { + result = CRYPT_INVALID_PACKET; + goto bail; + } + + if (block_type == LTC_LTC_PKCS_1_EME) { + for (i = 2; i < modulus_len; i++) { + /* separator */ + if (msg[i] == 0x00) { break; } + } + ps_len = i++ - 2; + + if ((i >= modulus_len) || (ps_len < 8)) { + /* There was no octet with hexadecimal value 0x00 to separate ps from m, + * or the length of ps is less than 8 octets. + */ + result = CRYPT_INVALID_PACKET; + goto bail; + } + } else { + for (i = 2; i < modulus_len - 1; i++) { + if (msg[i] != 0xFF) { break; } + } + + /* separator check */ + if (msg[i] != 0) { + /* There was no octet with hexadecimal value 0x00 to separate ps from m. */ + result = CRYPT_INVALID_PACKET; + goto bail; + } + + ps_len = i - 2; + } + + if (*outlen < (msglen - (2 + ps_len + 1))) { + *outlen = msglen - (2 + ps_len + 1); + result = CRYPT_BUFFER_OVERFLOW; + goto bail; + } + + *outlen = (msglen - (2 + ps_len + 1)); + XMEMCPY(out, &msg[2 + ps_len + 1], *outlen); + + /* valid packet */ + *is_valid = 1; + result = CRYPT_OK; +bail: + return result; +} /* pkcs_1_v1_5_decode */ + +#endif /* #ifdef LTC_PKCS_1 */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_encode.c b/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_encode.c new file mode 100644 index 000000000..4342919ed --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_encode.c @@ -0,0 +1,111 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/*! \file pkcs_1_v1_5_encode.c + * + * LTC_PKCS #1 v1.5 Padding (Andreas Lange) + */ + +#ifdef LTC_PKCS_1 + +/*! \brief LTC_PKCS #1 v1.5 encode. + * + * \param msg The data to encode + * \param msglen The length of the data to encode (octets) + * \param block_type Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks) + * \param modulus_bitlen The bit length of the RSA modulus + * \param prng An active PRNG state (only for LTC_LTC_PKCS_1_EME) + * \param prng_idx The index of the PRNG desired (only for LTC_LTC_PKCS_1_EME) + * \param out [out] The destination for the encoded data + * \param outlen [in/out] The max size and resulting size of the encoded data + * + * \return CRYPT_OK if successful + */ +int pkcs_1_v1_5_encode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + prng_state *prng, + int prng_idx, + unsigned char *out, + unsigned long *outlen) +{ + unsigned long modulus_len, ps_len, i; + unsigned char *ps; + int result; + + /* valid block_type? */ + if ((block_type != LTC_LTC_PKCS_1_EMSA) && + (block_type != LTC_LTC_PKCS_1_EME)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (block_type == LTC_LTC_PKCS_1_EME) { /* encryption padding, we need a valid PRNG */ + if ((result = prng_is_valid(prng_idx)) != CRYPT_OK) { + return result; + } + } + + modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); + + /* test message size */ + if ((msglen + 11) > modulus_len) { + return CRYPT_PK_INVALID_SIZE; + } + + if (*outlen < modulus_len) { + *outlen = modulus_len; + result = CRYPT_BUFFER_OVERFLOW; + goto bail; + } + + /* generate an octets string PS */ + ps = &out[2]; + ps_len = modulus_len - msglen - 3; + + if (block_type == LTC_LTC_PKCS_1_EME) { + /* now choose a random ps */ + if (prng_descriptor[prng_idx].read(ps, ps_len, prng) != ps_len) { + result = CRYPT_ERROR_READPRNG; + goto bail; + } + + /* transform zero bytes (if any) to non-zero random bytes */ + for (i = 0; i < ps_len; i++) { + while (ps[i] == 0) { + if (prng_descriptor[prng_idx].read(&ps[i], 1, prng) != 1) { + result = CRYPT_ERROR_READPRNG; + goto bail; + } + } + } + } else { + XMEMSET(ps, 0xFF, ps_len); + } + + /* create string of length modulus_len */ + out[0] = 0x00; + out[1] = (unsigned char)block_type; /* block_type 1 or 2 */ + out[2 + ps_len] = 0x00; + XMEMCPY(&out[2 + ps_len + 1], msg, msglen); + *outlen = modulus_len; + + result = CRYPT_OK; +bail: + return result; +} /* pkcs_1_v1_5_encode */ + +#endif /* #ifdef LTC_PKCS_1 */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_encode.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/rsa/rsa_exptmod.c b/StormLib/src/libtomcrypt/src/pk/rsa/rsa_exptmod.c new file mode 100644 index 000000000..ba44106f2 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/rsa/rsa_exptmod.c @@ -0,0 +1,113 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file rsa_exptmod.c + RSA LTC_PKCS exptmod, Tom St Denis +*/ + +#ifdef LTC_MRSA + +/** + Compute an RSA modular exponentiation + @param in The input data to send into RSA + @param inlen The length of the input (octets) + @param out [out] The destination + @param outlen [in/out] The max size and resulting size of the output + @param which Which exponent to use, e.g. PK_PRIVATE or PK_PUBLIC + @param key The RSA key to use + @return CRYPT_OK if successful +*/ +int rsa_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + rsa_key *key) +{ + void *tmp, *tmpa, *tmpb; + unsigned long x; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* is the key of the right type for the operation? */ + if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* must be a private or public operation */ + if (which != PK_PRIVATE && which != PK_PUBLIC) { + return CRYPT_PK_INVALID_TYPE; + } + + /* init and copy into tmp */ + if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != CRYPT_OK) { return err; } + if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto error; } + + /* sanity check on the input */ + if (mp_cmp(key->N, tmp) == LTC_MP_LT) { + err = CRYPT_PK_INVALID_SIZE; + goto error; + } + + /* are we using the private exponent and is the key optimized? */ + if (which == PK_PRIVATE) { + /* tmpa = tmp^dP mod p */ + if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK) { goto error; } + + /* tmpb = tmp^dQ mod q */ + if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK) { goto error; } + + /* tmp = (tmpa - tmpb) * qInv (mod p) */ + if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK) { goto error; } + + /* tmp = tmpb + q * tmp */ + if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK) { goto error; } + if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK) { goto error; } + } else { + /* exptmod it */ + if ((err = mp_exptmod(tmp, key->e, key->N, tmp)) != CRYPT_OK) { goto error; } + } + + /* read it back */ + x = (unsigned long)mp_unsigned_bin_size(key->N); + if (x > *outlen) { + *outlen = x; + err = CRYPT_BUFFER_OVERFLOW; + goto error; + } + + /* this should never happen ... */ + if (mp_unsigned_bin_size(tmp) > mp_unsigned_bin_size(key->N)) { + err = CRYPT_ERROR; + goto error; + } + *outlen = x; + + /* convert it */ + zeromem(out, x); + if ((err = mp_to_unsigned_bin(tmp, out+(x-mp_unsigned_bin_size(tmp)))) != CRYPT_OK) { goto error; } + + /* clean up and return */ + err = CRYPT_OK; +error: + mp_clear_multi(tmp, tmpa, tmpb, NULL); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_exptmod.c,v $ */ +/* $Revision: 1.18 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/rsa/rsa_free.c b/StormLib/src/libtomcrypt/src/pk/rsa/rsa_free.c new file mode 100644 index 000000000..a10ed5928 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/rsa/rsa_free.c @@ -0,0 +1,34 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file rsa_free.c + Free an RSA key, Tom St Denis +*/ + +#ifdef LTC_MRSA + +/** + Free an RSA key from memory + @param key The RSA key to free +*/ +void rsa_free(rsa_key *key) +{ + LTC_ARGCHKVD(key != NULL); + mp_clear_multi(key->e, key->d, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_free.c,v $ */ +/* $Revision: 1.10 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/rsa/rsa_import.c b/StormLib/src/libtomcrypt/src/pk/rsa/rsa_import.c new file mode 100644 index 000000000..6254fd7ff --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/rsa/rsa_import.c @@ -0,0 +1,143 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file rsa_import.c + Import a LTC_PKCS RSA key, Tom St Denis +*/ + +#ifdef LTC_MRSA + +/** + Import an RSAPublicKey or RSAPrivateKey [two-prime only, only support >= 1024-bit keys, defined in LTC_PKCS #1 v2.1] + @param in The packet to import from + @param inlen It's length (octets) + @param key [out] Destination for newly imported key + @return CRYPT_OK if successful, upon error allocated memory is freed +*/ +int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) +{ + int err; + void *zero; + unsigned char *tmpbuf; + unsigned long t, x, y, z, tmpoid[16]; + ltc_asn1_list ssl_pubkey_hashoid[2]; + ltc_asn1_list ssl_pubkey[2]; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + /* init key */ + if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, + &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { + return err; + } + + /* see if the OpenSSL DER format RSA public key will work */ + tmpbuf = XCALLOC(1, MAX_RSA_SIZE*8); + if (tmpbuf == NULL) { + err = CRYPT_MEM; + goto LBL_ERR; + } + + /* this includes the internal hash ID and optional params (NULL in this case) */ + LTC_SET_ASN1(ssl_pubkey_hashoid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0])); + LTC_SET_ASN1(ssl_pubkey_hashoid, 1, LTC_ASN1_NULL, NULL, 0); + + /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey in a **BIT** string ... so we have to extract it + then proceed to convert bit to octet + */ + LTC_SET_ASN1(ssl_pubkey, 0, LTC_ASN1_SEQUENCE, &ssl_pubkey_hashoid, 2); + LTC_SET_ASN1(ssl_pubkey, 1, LTC_ASN1_BIT_STRING, tmpbuf, MAX_RSA_SIZE*8); + + if (der_decode_sequence(in, inlen, + ssl_pubkey, 2UL) == CRYPT_OK) { + + /* ok now we have to reassemble the BIT STRING to an OCTET STRING. Thanks OpenSSL... */ + for (t = y = z = x = 0; x < ssl_pubkey[1].size; x++) { + y = (y << 1) | tmpbuf[x]; + if (++z == 8) { + tmpbuf[t++] = (unsigned char)y; + y = 0; + z = 0; + } + } + + /* now it should be SEQUENCE { INTEGER, INTEGER } */ + if ((err = der_decode_sequence_multi(tmpbuf, t, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + XFREE(tmpbuf); + goto LBL_ERR; + } + XFREE(tmpbuf); + key->type = PK_PUBLIC; + return CRYPT_OK; + } + XFREE(tmpbuf); + + /* not SSL public key, try to match against LTC_PKCS #1 standards */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + + if (mp_cmp_d(key->N, 0) == LTC_MP_EQ) { + if ((err = mp_init(&zero)) != CRYPT_OK) { + goto LBL_ERR; + } + /* it's a private key */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, zero, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_INTEGER, 1UL, key->d, + LTC_ASN1_INTEGER, 1UL, key->p, + LTC_ASN1_INTEGER, 1UL, key->q, + LTC_ASN1_INTEGER, 1UL, key->dP, + LTC_ASN1_INTEGER, 1UL, key->dQ, + LTC_ASN1_INTEGER, 1UL, key->qP, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + mp_clear(zero); + goto LBL_ERR; + } + mp_clear(zero); + key->type = PK_PRIVATE; + } else if (mp_cmp_d(key->N, 1) == LTC_MP_EQ) { + /* we don't support multi-prime RSA */ + err = CRYPT_PK_INVALID_TYPE; + goto LBL_ERR; + } else { + /* it's a public key and we lack e */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + key->type = PK_PUBLIC; + } + return CRYPT_OK; +LBL_ERR: + mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); + return err; +} + +#endif /* LTC_MRSA */ + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_import.c,v $ */ +/* $Revision: 1.23 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/rsa/rsa_make_key.c b/StormLib/src/libtomcrypt/src/pk/rsa/rsa_make_key.c new file mode 100644 index 000000000..bd37b4ae1 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/rsa/rsa_make_key.c @@ -0,0 +1,112 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file rsa_make_key.c + RSA key generation, Tom St Denis +*/ + +#ifdef LTC_MRSA + +/** + Create an RSA key + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param size The size of the modulus (key size) desired (octets) + @param e The "e" value (public key). e==65537 is a good choice + @param key [out] Destination of a newly created private key pair + @return CRYPT_OK if successful, upon error all allocated ram is freed +*/ +int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key) +{ + void *p, *q, *tmp1, *tmp2, *tmp3; + int err; + + LTC_ARGCHK(ltc_mp.name != NULL); + LTC_ARGCHK(key != NULL); + + if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) { + return CRYPT_INVALID_KEYSIZE; + } + + if ((e < 3) || ((e & 1) == 0)) { + return CRYPT_INVALID_ARG; + } + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != CRYPT_OK) { + return err; + } + + /* make primes p and q (optimization provided by Wayne Scott) */ + if ((err = mp_set_int(tmp3, e)) != CRYPT_OK) { goto errkey; } /* tmp3 = e */ + + /* make prime "p" */ + do { + if ((err = rand_prime( p, size/2, prng, wprng)) != CRYPT_OK) { goto errkey; } + if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = p-1 */ + if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = gcd(p-1, e) */ + } while (mp_cmp_d( tmp2, 1) != 0); /* while e divides p-1 */ + + /* make prime "q" */ + do { + if ((err = rand_prime( q, size/2, prng, wprng)) != CRYPT_OK) { goto errkey; } + if ((err = mp_sub_d( q, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = q-1 */ + if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = gcd(q-1, e) */ + } while (mp_cmp_d( tmp2, 1) != 0); /* while e divides q-1 */ + + /* tmp1 = lcm(p-1, q-1) */ + if ((err = mp_sub_d( p, 1, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = p-1 */ + /* tmp1 = q-1 (previous do/while loop) */ + if ((err = mp_lcm( tmp1, tmp2, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = lcm(p-1, q-1) */ + + /* make key */ + if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { + goto errkey; + } + + if ((err = mp_set_int( key->e, e)) != CRYPT_OK) { goto errkey; } /* key->e = e */ + if ((err = mp_invmod( key->e, tmp1, key->d)) != CRYPT_OK) { goto errkey; } /* key->d = 1/e mod lcm(p-1,q-1) */ + if ((err = mp_mul( p, q, key->N)) != CRYPT_OK) { goto errkey; } /* key->N = pq */ + + /* optimize for CRT now */ + /* find d mod q-1 and d mod p-1 */ + if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = q-1 */ + if ((err = mp_sub_d( q, 1, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = p-1 */ + if ((err = mp_mod( key->d, tmp1, key->dP)) != CRYPT_OK) { goto errkey; } /* dP = d mod p-1 */ + if ((err = mp_mod( key->d, tmp2, key->dQ)) != CRYPT_OK) { goto errkey; } /* dQ = d mod q-1 */ + if ((err = mp_invmod( q, p, key->qP)) != CRYPT_OK) { goto errkey; } /* qP = 1/q mod p */ + + if ((err = mp_copy( p, key->p)) != CRYPT_OK) { goto errkey; } + if ((err = mp_copy( q, key->q)) != CRYPT_OK) { goto errkey; } + + /* set key type (in this case it's CRT optimized) */ + key->type = PK_PRIVATE; + + /* return ok and free temps */ + err = CRYPT_OK; + goto cleanup; +errkey: + mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); +cleanup: + mp_clear_multi(tmp3, tmp2, tmp1, p, q, NULL); + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_make_key.c,v $ */ +/* $Revision: 1.16 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/rsa/rsa_sign_hash.c b/StormLib/src/libtomcrypt/src/pk/rsa/rsa_sign_hash.c new file mode 100644 index 000000000..49fb85875 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/rsa/rsa_sign_hash.c @@ -0,0 +1,134 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file rsa_sign_hash.c + RSA LTC_PKCS #1 v1.5 and v2 PSS sign hash, Tom St Denis and Andreas Lange +*/ + +#ifdef LTC_MRSA + +/** + LTC_PKCS #1 pad then sign + @param in The hash to sign + @param inlen The length of the hash to sign (octets) + @param out [out] The signature + @param outlen [in/out] The max size and resulting size of the signature + @param padding Type of padding (LTC_LTC_PKCS_1_PSS or LTC_LTC_PKCS_1_V1_5) + @param prng An active PRNG state + @param prng_idx The index of the PRNG desired + @param hash_idx The index of the hash desired + @param saltlen The length of the salt desired (octets) + @param key The private RSA key to use + @return CRYPT_OK if successful +*/ +int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + int padding, + prng_state *prng, int prng_idx, + int hash_idx, unsigned long saltlen, + rsa_key *key) +{ + unsigned long modulus_bitlen, modulus_bytelen, x, y; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* valid padding? */ + if ((padding != LTC_LTC_PKCS_1_V1_5) && (padding != LTC_LTC_PKCS_1_PSS)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (padding == LTC_LTC_PKCS_1_PSS) { + /* valid prng and hash ? */ + if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { + return err; + } + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + } + + /* get modulus len in bits */ + modulus_bitlen = mp_count_bits((key->N)); + + /* outlen must be at least the size of the modulus */ + modulus_bytelen = mp_unsigned_bin_size((key->N)); + if (modulus_bytelen > *outlen) { + *outlen = modulus_bytelen; + return CRYPT_BUFFER_OVERFLOW; + } + + if (padding == LTC_LTC_PKCS_1_PSS) { + /* PSS pad the key */ + x = *outlen; + if ((err = pkcs_1_pss_encode(in, inlen, saltlen, prng, prng_idx, + hash_idx, modulus_bitlen, out, &x)) != CRYPT_OK) { + return err; + } + } else { + /* LTC_PKCS #1 v1.5 pad the hash */ + unsigned char *tmpin; + ltc_asn1_list digestinfo[2], siginfo[2]; + + /* not all hashes have OIDs... so sad */ + if (hash_descriptor[hash_idx].OIDlen == 0) { + return CRYPT_INVALID_ARG; + } + + /* construct the SEQUENCE + SEQUENCE { + SEQUENCE {hashoid OID + blah NULL + } + hash OCTET STRING + } + */ + LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash_idx].OID, hash_descriptor[hash_idx].OIDlen); + LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); + LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); + LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, in, inlen); + + /* allocate memory for the encoding */ + y = mp_unsigned_bin_size(key->N); + tmpin = XMALLOC(y); + if (tmpin == NULL) { + return CRYPT_MEM; + } + + if ((err = der_encode_sequence(siginfo, 2, tmpin, &y)) != CRYPT_OK) { + XFREE(tmpin); + return err; + } + + x = *outlen; + if ((err = pkcs_1_v1_5_encode(tmpin, y, LTC_LTC_PKCS_1_EMSA, + modulus_bitlen, NULL, 0, + out, &x)) != CRYPT_OK) { + XFREE(tmpin); + return err; + } + XFREE(tmpin); + } + + /* RSA encode it */ + return ltc_mp.rsa_me(out, x, out, outlen, PK_PRIVATE, key); +} + +#endif /* LTC_MRSA */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_sign_hash.c,v $ */ +/* $Revision: 1.11 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c b/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c new file mode 100644 index 000000000..103ae2f53 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c @@ -0,0 +1,167 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file rsa_verify_hash.c + RSA LTC_PKCS #1 v1.5 or v2 PSS signature verification, Tom St Denis and Andreas Lange +*/ + +#ifdef LTC_MRSA + +/** + LTC_PKCS #1 de-sign then v1.5 or PSS depad + @param sig The signature data + @param siglen The length of the signature data (octets) + @param hash The hash of the message that was signed + @param hashlen The length of the hash of the message that was signed (octets) + @param padding Type of padding (LTC_LTC_PKCS_1_PSS or LTC_LTC_PKCS_1_V1_5) + @param hash_idx The index of the desired hash + @param saltlen The length of the salt used during signature + @param stat [out] The result of the signature comparison, 1==valid, 0==invalid + @param key The public RSA key corresponding to the key that performed the signature + @return CRYPT_OK on success (even if the signature is invalid) +*/ +int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int padding, + int hash_idx, unsigned long saltlen, + int *stat, rsa_key *key) +{ + unsigned long modulus_bitlen, modulus_bytelen, x; + int err; + unsigned char *tmpbuf; + + LTC_ARGCHK(hash != NULL); + LTC_ARGCHK(sig != NULL); + LTC_ARGCHK(stat != NULL); + LTC_ARGCHK(key != NULL); + + /* default to invalid */ + *stat = 0; + + /* valid padding? */ + + if ((padding != LTC_LTC_PKCS_1_V1_5) && + (padding != LTC_LTC_PKCS_1_PSS)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (padding == LTC_LTC_PKCS_1_PSS) { + /* valid hash ? */ + if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + return err; + } + } + + /* get modulus len in bits */ + modulus_bitlen = mp_count_bits( (key->N)); + + /* outlen must be at least the size of the modulus */ + modulus_bytelen = mp_unsigned_bin_size( (key->N)); + if (modulus_bytelen != siglen) { + return CRYPT_INVALID_PACKET; + } + + /* allocate temp buffer for decoded sig */ + tmpbuf = XMALLOC(siglen); + if (tmpbuf == NULL) { + return CRYPT_MEM; + } + + /* RSA decode it */ + x = siglen; + if ((err = ltc_mp.rsa_me(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) { + XFREE(tmpbuf); + return err; + } + + /* make sure the output is the right size */ + if (x != siglen) { + XFREE(tmpbuf); + return CRYPT_INVALID_PACKET; + } + + if (padding == LTC_LTC_PKCS_1_PSS) { + /* PSS decode and verify it */ + err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat); + } else { + /* LTC_PKCS #1 v1.5 decode it */ + unsigned char *out; + unsigned long outlen, loid[16]; + int decoded; + ltc_asn1_list digestinfo[2], siginfo[2]; + + /* not all hashes have OIDs... so sad */ + if (hash_descriptor[hash_idx].OIDlen == 0) { + err = CRYPT_INVALID_ARG; + goto bail_2; + } + + /* allocate temp buffer for decoded hash */ + outlen = ((modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0)) - 3; + out = XMALLOC(outlen); + if (out == NULL) { + err = CRYPT_MEM; + goto bail_2; + } + + if ((err = pkcs_1_v1_5_decode(tmpbuf, x, LTC_LTC_PKCS_1_EMSA, modulus_bitlen, out, &outlen, &decoded)) != CRYPT_OK) { + XFREE(out); + goto bail_2; + } + + /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */ + /* construct the SEQUENCE + SEQUENCE { + SEQUENCE {hashoid OID + blah NULL + } + hash OCTET STRING + } + */ + LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, sizeof(loid)/sizeof(loid[0])); + LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); + LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); + LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen); + + if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) { + XFREE(out); + goto bail_2; + } + + /* test OID */ + if ((digestinfo[0].size == hash_descriptor[hash_idx].OIDlen) && + (XMEMCMP(digestinfo[0].data, hash_descriptor[hash_idx].OID, sizeof(unsigned long) * hash_descriptor[hash_idx].OIDlen) == 0) && + (siginfo[1].size == hashlen) && + (XMEMCMP(siginfo[1].data, hash, hashlen) == 0)) { + *stat = 1; + } + +#ifdef LTC_CLEAN_STACK + zeromem(out, outlen); +#endif + XFREE(out); + } + +bail_2: +#ifdef LTC_CLEAN_STACK + zeromem(tmpbuf, siglen); +#endif + XFREE(tmpbuf); + return err; +} + +#endif /* LTC_MRSA */ + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_verify_hash.c,v $ */ +/* $Revision: 1.13 $ */ +/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c b/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c new file mode 100644 index 000000000..6d8888c85 --- /dev/null +++ b/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c @@ -0,0 +1,87 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include "../../headers/tomcrypt.h" + +/** + @file rsa_verify_simple.c + Created by Ladislav Zezula (zezula@volny.cz) as modification + for Blizzard strong signature verification +*/ + +#ifdef LTC_MRSA + +/** + Simple RSA decryption + @param sig The signature data + @param siglen The length of the signature data (octets) + @param hash The hash of the message that was signed + @param hashlen The length of the hash of the message that was signed (octets) + @param stat [out] The result of the signature comparison, 1==valid, 0==invalid + @param key The public RSA key corresponding + @return Error code +*/ +int rsa_verify_simple(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, + rsa_key *key) +{ + unsigned long modulus_bitlen, modulus_bytelen, x; + unsigned char *tmpbuf; + int err; + + LTC_ARGCHK(sig != NULL); + LTC_ARGCHK(hash != NULL); + LTC_ARGCHK(stat != NULL); + LTC_ARGCHK(key != NULL); + + /* default to invalid */ + *stat = 0; + + /* get modulus len in bits */ + modulus_bitlen = mp_count_bits( (key->N)); + + /* outlen must be at least the size of the modulus */ + modulus_bytelen = mp_unsigned_bin_size( (key->N)); + if (modulus_bytelen != siglen) { + return CRYPT_INVALID_PACKET; + } + + /* allocate temp buffer for decoded sig */ + tmpbuf = XMALLOC(siglen); + if (tmpbuf == NULL) { + return CRYPT_MEM; + } + + /* RSA decode it */ + x = siglen; + if ((err = ltc_mp.rsa_me(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) { + XFREE(tmpbuf); + return err; + } + + /* make sure the output is the right size */ + if (x != siglen) { + XFREE(tmpbuf); + return CRYPT_INVALID_PACKET; + } + + /* compare the decrypted signature with the given hash */ + if(x == hashlen && XMEMCMP(tmpbuf, hash, hashlen) == 0) + *stat = 1; + +#ifdef LTC_CLEAN_STACK + zeromem(tmpbuf, siglen); +#endif + XFREE(tmpbuf); + return CRYPT_OK; +} + +#endif /* LTC_MRSA */ diff --git a/StormLib/src/libtommath/bn_fast_mp_invmod.c b/StormLib/src/libtommath/bn_fast_mp_invmod.c new file mode 100644 index 000000000..597d7a9b5 --- /dev/null +++ b/StormLib/src/libtommath/bn_fast_mp_invmod.c @@ -0,0 +1,148 @@ +#include "tommath.h" +#ifdef BN_FAST_MP_INVMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes the modular inverse via binary extended euclidean algorithm, + * that is c = 1/a mod b + * + * Based on slow invmod except this is optimized for the case where b is + * odd as per HAC Note 14.64 on pp. 610 + */ +int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x, y, u, v, B, D; + int res, neg; + + /* 2. [modified] b must be odd */ + if (mp_iseven (b) == 1) { + return MP_VAL; + } + + /* init all our temps */ + if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) { + return res; + } + + /* x == modulus, y == value to invert */ + if ((res = mp_copy (b, &x)) != MP_OKAY) { + goto LBL_ERR; + } + + /* we need y = |a| */ + if ((res = mp_mod (a, b, &y)) != MP_OKAY) { + goto LBL_ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((res = mp_copy (&x, &u)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (&y, &v)) != MP_OKAY) { + goto LBL_ERR; + } + mp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (mp_iseven (&u) == 1) { + /* 4.1 u = u/2 */ + if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { + goto LBL_ERR; + } + /* 4.2 if B is odd then */ + if (mp_isodd (&B) == 1) { + if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* B = B/2 */ + if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 5. while v is even do */ + while (mp_iseven (&v) == 1) { + /* 5.1 v = v/2 */ + if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { + goto LBL_ERR; + } + /* 5.2 if D is odd then */ + if (mp_isodd (&D) == 1) { + /* D = (D-x)/2 */ + if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* D = D/2 */ + if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 6. if u >= v then */ + if (mp_cmp (&u, &v) != MP_LT) { + /* u = u - v, B = B - D */ + if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } else { + /* v - v - u, D = D - B */ + if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* if not zero goto step 4 */ + if (mp_iszero (&u) == 0) { + goto top; + } + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d (&v, 1) != MP_EQ) { + res = MP_VAL; + goto LBL_ERR; + } + + /* b is now the inverse */ + neg = a->sign; + while (D.sign == MP_NEG) { + if ((res = mp_add (&D, b, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + mp_exch (&D, c); + c->sign = neg; + res = MP_OKAY; + +LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); + return res; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_fast_mp_invmod.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_fast_mp_montgomery_reduce.c b/StormLib/src/libtommath/bn_fast_mp_montgomery_reduce.c new file mode 100644 index 000000000..65eed7da1 --- /dev/null +++ b/StormLib/src/libtommath/bn_fast_mp_montgomery_reduce.c @@ -0,0 +1,172 @@ +#include "tommath.h" +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes xR**-1 == x (mod N) via Montgomery Reduction + * + * This is an optimized implementation of montgomery_reduce + * which uses the comba method to quickly calculate the columns of the + * reduction. + * + * Based on Algorithm 14.32 on pp.601 of HAC. +*/ +int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) +{ + int ix, res, olduse; + mp_word W[MP_WARRAY]; + + /* get old used count */ + olduse = x->used; + + /* grow a as required */ + if (x->alloc < n->used + 1) { + if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) { + return res; + } + } + + /* first we have to get the digits of the input into + * an array of double precision words W[...] + */ + { + register mp_word *_W; + register mp_digit *tmpx; + + /* alias for the W[] array */ + _W = W; + + /* alias for the digits of x*/ + tmpx = x->dp; + + /* copy the digits of a into W[0..a->used-1] */ + for (ix = 0; ix < x->used; ix++) { + *_W++ = *tmpx++; + } + + /* zero the high words of W[a->used..m->used*2] */ + for (; ix < n->used * 2 + 1; ix++) { + *_W++ = 0; + } + } + + /* now we proceed to zero successive digits + * from the least significant upwards + */ + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * m' mod b + * + * We avoid a double precision multiplication (which isn't required) + * by casting the value down to a mp_digit. Note this requires + * that W[ix-1] have the carry cleared (see after the inner loop) + */ + register mp_digit mu; + mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); + + /* a = a + mu * m * b**i + * + * This is computed in place and on the fly. The multiplication + * by b**i is handled by offseting which columns the results + * are added to. + * + * Note the comba method normally doesn't handle carries in the + * inner loop In this case we fix the carry from the previous + * column since the Montgomery reduction requires digits of the + * result (so far) [see above] to work. This is + * handled by fixing up one carry after the inner loop. The + * carry fixups are done in order so after these loops the + * first m->used words of W[] have the carries fixed + */ + { + register int iy; + register mp_digit *tmpn; + register mp_word *_W; + + /* alias for the digits of the modulus */ + tmpn = n->dp; + + /* Alias for the columns set by an offset of ix */ + _W = W + ix; + + /* inner loop */ + for (iy = 0; iy < n->used; iy++) { + *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); + } + } + + /* now fix carry for next digit, W[ix+1] */ + W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); + } + + /* now we have to propagate the carries and + * shift the words downward [all those least + * significant digits we zeroed]. + */ + { + register mp_digit *tmpx; + register mp_word *_W, *_W1; + + /* nox fix rest of carries */ + + /* alias for current word */ + _W1 = W + ix; + + /* alias for next word, where the carry goes */ + _W = W + ++ix; + + for (; ix <= n->used * 2 + 1; ix++) { + *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); + } + + /* copy out, A = A/b**n + * + * The result is A/b**n but instead of converting from an + * array of mp_word to mp_digit than calling mp_rshd + * we just copy them in the right order + */ + + /* alias for destination word */ + tmpx = x->dp; + + /* alias for shifted double precision result */ + _W = W + n->used; + + for (ix = 0; ix < n->used + 1; ix++) { + *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); + } + + /* zero oldused digits, if the input a was larger than + * m->used+1 we'll have to clear the digits + */ + for (; ix < olduse; ix++) { + *tmpx++ = 0; + } + } + + /* set the max used and clamp */ + x->used = n->used + 1; + mp_clamp (x); + + /* if A >= m then A = A - m */ + if (mp_cmp_mag (x, n) != MP_LT) { + return s_mp_sub (x, n, x); + } + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_fast_mp_montgomery_reduce.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_fast_s_mp_mul_digs.c b/StormLib/src/libtommath/bn_fast_s_mp_mul_digs.c new file mode 100644 index 000000000..df83f89ec --- /dev/null +++ b/StormLib/src/libtommath/bn_fast_s_mp_mul_digs.c @@ -0,0 +1,107 @@ +#include "tommath.h" +#ifdef BN_FAST_S_MP_MUL_DIGS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Fast (comba) multiplier + * + * This is the fast column-array [comba] multiplier. It is + * designed to compute the columns of the product first + * then handle the carries afterwards. This has the effect + * of making the nested loops that compute the columns very + * simple and schedulable on super-scalar processors. + * + * This has been modified to produce a variable number of + * digits of output so if say only a half-product is required + * you don't have to compute the upper half (a feature + * required for fast Barrett reduction). + * + * Based on Algorithm 14.12 on pp.595 of HAC. + * + */ +int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY]; + register mp_word _W; + + /* grow the destination as required */ + if (c->alloc < digs) { + if ((res = mp_grow (c, digs)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + pa = MIN(digs, a->used + b->used); + + /* clear the carry */ + _W = 0; + for (ix = 0; ix < pa; ix++) { + int tx, ty; + int iy; + mp_digit *tmpx, *tmpy; + + /* get offsets into the two bignums */ + ty = MIN(b->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = b->dp + ty; + + /* this is the number of times the loop will iterrate, essentially + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* execute loop */ + for (iz = 0; iz < iy; ++iz) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + + } + + /* store term */ + W[ix] = ((mp_digit)_W) & MP_MASK; + + /* make next carry */ + _W = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = c->used; + c->used = pa; + + { + register mp_digit *tmpc; + tmpc = c->dp; + for (ix = 0; ix < pa+1; ix++) { + /* now extract the previous digit [below the carry] */ + *tmpc++ = W[ix]; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpc++ = 0; + } + } + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_fast_s_mp_mul_digs.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_fast_s_mp_mul_high_digs.c b/StormLib/src/libtommath/bn_fast_s_mp_mul_high_digs.c new file mode 100644 index 000000000..6866aab75 --- /dev/null +++ b/StormLib/src/libtommath/bn_fast_s_mp_mul_high_digs.c @@ -0,0 +1,98 @@ +#include "tommath.h" +#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* this is a modified version of fast_s_mul_digs that only produces + * output digits *above* digs. See the comments for fast_s_mul_digs + * to see how it works. + * + * This is used in the Barrett reduction since for one of the multiplications + * only the higher digits were needed. This essentially halves the work. + * + * Based on Algorithm 14.12 on pp.595 of HAC. + */ +int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY]; + mp_word _W; + + /* grow the destination as required */ + pa = a->used + b->used; + if (c->alloc < pa) { + if ((res = mp_grow (c, pa)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + pa = a->used + b->used; + _W = 0; + for (ix = digs; ix < pa; ix++) { + int tx, ty, iy; + mp_digit *tmpx, *tmpy; + + /* get offsets into the two bignums */ + ty = MIN(b->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = b->dp + ty; + + /* this is the number of times the loop will iterrate, essentially its + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* execute loop */ + for (iz = 0; iz < iy; iz++) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + } + + /* store term */ + W[ix] = ((mp_digit)_W) & MP_MASK; + + /* make next carry */ + _W = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = c->used; + c->used = pa; + + { + register mp_digit *tmpc; + + tmpc = c->dp + digs; + for (ix = digs; ix < pa; ix++) { + /* now extract the previous digit [below the carry] */ + *tmpc++ = W[ix]; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpc++ = 0; + } + } + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_fast_s_mp_mul_high_digs.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_fast_s_mp_sqr.c b/StormLib/src/libtommath/bn_fast_s_mp_sqr.c new file mode 100644 index 000000000..5f9d58cac --- /dev/null +++ b/StormLib/src/libtommath/bn_fast_s_mp_sqr.c @@ -0,0 +1,114 @@ +#include "tommath.h" +#ifdef BN_FAST_S_MP_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* the jist of squaring... + * you do like mult except the offset of the tmpx [one that + * starts closer to zero] can't equal the offset of tmpy. + * So basically you set up iy like before then you min it with + * (ty-tx) so that it never happens. You double all those + * you add in the inner loop + +After that loop you do the squares and add them in. +*/ + +int fast_s_mp_sqr (mp_int * a, mp_int * b) +{ + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY], *tmpx; + mp_word W1; + + /* grow the destination as required */ + pa = a->used + a->used; + if (b->alloc < pa) { + if ((res = mp_grow (b, pa)) != MP_OKAY) { + return res; + } + } + + /* number of output digits to produce */ + W1 = 0; + for (ix = 0; ix < pa; ix++) { + int tx, ty, iy; + mp_word _W; + mp_digit *tmpy; + + /* clear counter */ + _W = 0; + + /* get offsets into the two bignums */ + ty = MIN(a->used-1, ix); + tx = ix - ty; + + /* setup temp aliases */ + tmpx = a->dp + tx; + tmpy = a->dp + ty; + + /* this is the number of times the loop will iterrate, essentially + while (tx++ < a->used && ty-- >= 0) { ... } + */ + iy = MIN(a->used-tx, ty+1); + + /* now for squaring tx can never equal ty + * we halve the distance since they approach at a rate of 2x + * and we have to round because odd cases need to be executed + */ + iy = MIN(iy, (ty-tx+1)>>1); + + /* execute loop */ + for (iz = 0; iz < iy; iz++) { + _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + } + + /* double the inner product and add carry */ + _W = _W + _W + W1; + + /* even columns have the square term in them */ + if ((ix&1) == 0) { + _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]); + } + + /* store it */ + W[ix] = (mp_digit)(_W & MP_MASK); + + /* make next carry */ + W1 = _W >> ((mp_word)DIGIT_BIT); + } + + /* setup dest */ + olduse = b->used; + b->used = a->used+a->used; + + { + mp_digit *tmpb; + tmpb = b->dp; + for (ix = 0; ix < pa; ix++) { + *tmpb++ = W[ix] & MP_MASK; + } + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpb++ = 0; + } + } + mp_clamp (b); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_fast_s_mp_sqr.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_2expt.c b/StormLib/src/libtommath/bn_mp_2expt.c new file mode 100644 index 000000000..f899eaee4 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_2expt.c @@ -0,0 +1,48 @@ +#include "tommath.h" +#ifdef BN_MP_2EXPT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes a = 2**b + * + * Simple algorithm which zeroes the int, grows it then just sets one bit + * as required. + */ +int +mp_2expt (mp_int * a, int b) +{ + int res; + + /* zero a as per default */ + mp_zero (a); + + /* grow a to accomodate the single bit */ + if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) { + return res; + } + + /* set the used count of where the bit will go */ + a->used = b / DIGIT_BIT + 1; + + /* put the single bit in its place */ + a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); + + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_2expt.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_abs.c b/StormLib/src/libtommath/bn_mp_abs.c new file mode 100644 index 000000000..14f3a7e07 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_abs.c @@ -0,0 +1,43 @@ +#include "tommath.h" +#ifdef BN_MP_ABS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* b = |a| + * + * Simple function copies the input and fixes the sign to positive + */ +int +mp_abs (mp_int * a, mp_int * b) +{ + int res; + + /* copy a to b */ + if (a != b) { + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } + } + + /* force the sign of b to positive */ + b->sign = MP_ZPOS; + + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_abs.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_add.c b/StormLib/src/libtommath/bn_mp_add.c new file mode 100644 index 000000000..b368b21c7 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_add.c @@ -0,0 +1,53 @@ +#include "tommath.h" +#ifdef BN_MP_ADD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* high level addition (handles signs) */ +int mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + /* get sign of both inputs */ + sa = a->sign; + sb = b->sign; + + /* handle two cases, not four */ + if (sa == sb) { + /* both positive or both negative */ + /* add their magnitudes, copy the sign */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* one positive, the other negative */ + /* subtract the one with the greater magnitude from */ + /* the one of the lesser magnitude. The result gets */ + /* the sign of the one with the greater magnitude. */ + if (mp_cmp_mag (a, b) == MP_LT) { + c->sign = sb; + res = s_mp_sub (b, a, c); + } else { + c->sign = sa; + res = s_mp_sub (a, b, c); + } + } + return res; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_add.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_add_d.c b/StormLib/src/libtommath/bn_mp_add_d.c new file mode 100644 index 000000000..c147554bd --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_add_d.c @@ -0,0 +1,112 @@ +#include "tommath.h" +#ifdef BN_MP_ADD_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* single digit addition */ +int +mp_add_d (mp_int * a, mp_digit b, mp_int * c) +{ + int res, ix, oldused; + mp_digit *tmpa, *tmpc, mu; + + /* grow c as required */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* if a is negative and |a| >= b, call c = |a| - b */ + if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) { + /* temporarily fix sign of a */ + a->sign = MP_ZPOS; + + /* c = |a| - b */ + res = mp_sub_d(a, b, c); + + /* fix sign */ + a->sign = c->sign = MP_NEG; + + /* clamp */ + mp_clamp(c); + + return res; + } + + /* old number of used digits in c */ + oldused = c->used; + + /* sign always positive */ + c->sign = MP_ZPOS; + + /* source alias */ + tmpa = a->dp; + + /* destination alias */ + tmpc = c->dp; + + /* if a is positive */ + if (a->sign == MP_ZPOS) { + /* add digit, after this we're propagating + * the carry. + */ + *tmpc = *tmpa++ + b; + mu = *tmpc >> DIGIT_BIT; + *tmpc++ &= MP_MASK; + + /* now handle rest of the digits */ + for (ix = 1; ix < a->used; ix++) { + *tmpc = *tmpa++ + mu; + mu = *tmpc >> DIGIT_BIT; + *tmpc++ &= MP_MASK; + } + /* set final carry */ + ix++; + *tmpc++ = mu; + + /* setup size */ + c->used = a->used + 1; + } else { + /* a was negative and |a| < b */ + c->used = 1; + + /* the result is a single digit */ + if (a->used == 1) { + *tmpc++ = b - a->dp[0]; + } else { + *tmpc++ = b; + } + + /* setup count so the clearing of oldused + * can fall through correctly + */ + ix = 1; + } + + /* now zero to oldused */ + while (ix++ < oldused) { + *tmpc++ = 0; + } + mp_clamp(c); + + return MP_OKAY; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_add_d.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_addmod.c b/StormLib/src/libtommath/bn_mp_addmod.c new file mode 100644 index 000000000..0a21f62e9 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_addmod.c @@ -0,0 +1,41 @@ +#include "tommath.h" +#ifdef BN_MP_ADDMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* d = a + b (mod c) */ +int +mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_add (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_addmod.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_and.c b/StormLib/src/libtommath/bn_mp_and.c new file mode 100644 index 000000000..6b7afc104 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_and.c @@ -0,0 +1,57 @@ +#include "tommath.h" +#ifdef BN_MP_AND_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* AND two ints together */ +int +mp_and (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] &= x->dp[ix]; + } + + /* zero digits above the last from the smallest mp_int */ + for (; ix < t.used; ix++) { + t.dp[ix] = 0; + } + + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_and.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_clamp.c b/StormLib/src/libtommath/bn_mp_clamp.c new file mode 100644 index 000000000..d3cc21c3e --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_clamp.c @@ -0,0 +1,44 @@ +#include "tommath.h" +#ifdef BN_MP_CLAMP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* trim unused digits + * + * This is used to ensure that leading zero digits are + * trimed and the leading "used" digit will be non-zero + * Typically very fast. Also fixes the sign if there + * are no more leading digits + */ +void +mp_clamp (mp_int * a) +{ + /* decrease used while the most significant digit is + * zero. + */ + while (a->used > 0 && a->dp[a->used - 1] == 0) { + --(a->used); + } + + /* reset the sign flag if used == 0 */ + if (a->used == 0) { + a->sign = MP_ZPOS; + } +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_clamp.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_clear.c b/StormLib/src/libtommath/bn_mp_clear.c new file mode 100644 index 000000000..7644c3825 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_clear.c @@ -0,0 +1,44 @@ +#include "tommath.h" +#ifdef BN_MP_CLEAR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* clear one (frees) */ +void +mp_clear (mp_int * a) +{ + int i; + + /* only do anything if a hasn't been freed previously */ + if (a->dp != NULL) { + /* first zero the digits */ + for (i = 0; i < a->used; i++) { + a->dp[i] = 0; + } + + /* free ram */ + XFREE(a->dp); + + /* reset members to make debugging easier */ + a->dp = NULL; + a->alloc = a->used = 0; + a->sign = MP_ZPOS; + } +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_clear.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_clear_multi.c b/StormLib/src/libtommath/bn_mp_clear_multi.c new file mode 100644 index 000000000..a10762436 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_clear_multi.c @@ -0,0 +1,34 @@ +#include "tommath.h" +#ifdef BN_MP_CLEAR_MULTI_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include + +void mp_clear_multi(mp_int *mp, ...) +{ + mp_int* next_mp = mp; + va_list args; + va_start(args, mp); + while (next_mp != NULL) { + mp_clear(next_mp); + next_mp = va_arg(args, mp_int*); + } + va_end(args); +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_clear_multi.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_cmp.c b/StormLib/src/libtommath/bn_mp_cmp.c new file mode 100644 index 000000000..761d2b0dc --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_cmp.c @@ -0,0 +1,43 @@ +#include "tommath.h" +#ifdef BN_MP_CMP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* compare two ints (signed)*/ +int +mp_cmp (mp_int * a, mp_int * b) +{ + /* compare based on sign */ + if (a->sign != b->sign) { + if (a->sign == MP_NEG) { + return MP_LT; + } else { + return MP_GT; + } + } + + /* compare digits */ + if (a->sign == MP_NEG) { + /* if negative compare opposite direction */ + return mp_cmp_mag(b, a); + } else { + return mp_cmp_mag(a, b); + } +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_cmp.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_cmp_d.c b/StormLib/src/libtommath/bn_mp_cmp_d.c new file mode 100644 index 000000000..420dfd31a --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_cmp_d.c @@ -0,0 +1,44 @@ +#include "tommath.h" +#ifdef BN_MP_CMP_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* compare a digit */ +int mp_cmp_d(mp_int * a, mp_digit b) +{ + /* compare based on sign */ + if (a->sign == MP_NEG) { + return MP_LT; + } + + /* compare based on magnitude */ + if (a->used > 1) { + return MP_GT; + } + + /* compare the only digit of a to b */ + if (a->dp[0] > b) { + return MP_GT; + } else if (a->dp[0] < b) { + return MP_LT; + } else { + return MP_EQ; + } +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_cmp_d.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_cmp_mag.c b/StormLib/src/libtommath/bn_mp_cmp_mag.c new file mode 100644 index 000000000..92565a3b8 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_cmp_mag.c @@ -0,0 +1,55 @@ +#include "tommath.h" +#ifdef BN_MP_CMP_MAG_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* compare maginitude of two ints (unsigned) */ +int mp_cmp_mag (mp_int * a, mp_int * b) +{ + int n; + mp_digit *tmpa, *tmpb; + + /* compare based on # of non-zero digits */ + if (a->used > b->used) { + return MP_GT; + } + + if (a->used < b->used) { + return MP_LT; + } + + /* alias for a */ + tmpa = a->dp + (a->used - 1); + + /* alias for b */ + tmpb = b->dp + (a->used - 1); + + /* compare based on digits */ + for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { + if (*tmpa > *tmpb) { + return MP_GT; + } + + if (*tmpa < *tmpb) { + return MP_LT; + } + } + return MP_EQ; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_cmp_mag.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_cnt_lsb.c b/StormLib/src/libtommath/bn_mp_cnt_lsb.c new file mode 100644 index 000000000..60406610e --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_cnt_lsb.c @@ -0,0 +1,53 @@ +#include "tommath.h" +#ifdef BN_MP_CNT_LSB_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +static const int lnz[16] = { + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 +}; + +/* Counts the number of lsbs which are zero before the first zero bit */ +int mp_cnt_lsb(mp_int *a) +{ + int x; + mp_digit q, qq; + + /* easy out */ + if (mp_iszero(a) == 1) { + return 0; + } + + /* scan lower digits until non-zero */ + for (x = 0; x < a->used && a->dp[x] == 0; x++); + q = a->dp[x]; + x *= DIGIT_BIT; + + /* now scan this digit until a 1 is found */ + if ((q & 1) == 0) { + do { + qq = q & 15; + x += lnz[qq]; + q >>= 4; + } while (qq == 0); + } + return x; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_cnt_lsb.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_copy.c b/StormLib/src/libtommath/bn_mp_copy.c new file mode 100644 index 000000000..7828592da --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_copy.c @@ -0,0 +1,68 @@ +#include "tommath.h" +#ifdef BN_MP_COPY_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* copy, b = a */ +int +mp_copy (mp_int * a, mp_int * b) +{ + int res, n; + + /* if dst == src do nothing */ + if (a == b) { + return MP_OKAY; + } + + /* grow dest */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + /* zero b and copy the parameters over */ + { + register mp_digit *tmpa, *tmpb; + + /* pointer aliases */ + + /* source */ + tmpa = a->dp; + + /* destination */ + tmpb = b->dp; + + /* copy all the digits */ + for (n = 0; n < a->used; n++) { + *tmpb++ = *tmpa++; + } + + /* clear high digits */ + for (; n < b->used; n++) { + *tmpb++ = 0; + } + } + + /* copy used count and sign */ + b->used = a->used; + b->sign = a->sign; + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_copy.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_count_bits.c b/StormLib/src/libtommath/bn_mp_count_bits.c new file mode 100644 index 000000000..9d8640fdf --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_count_bits.c @@ -0,0 +1,45 @@ +#include "tommath.h" +#ifdef BN_MP_COUNT_BITS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* returns the number of bits in an int */ +int +mp_count_bits (mp_int * a) +{ + int r; + mp_digit q; + + /* shortcut */ + if (a->used == 0) { + return 0; + } + + /* get number of digits and add that */ + r = (a->used - 1) * DIGIT_BIT; + + /* take the last digit and count the bits in it */ + q = a->dp[a->used - 1]; + while (q > ((mp_digit) 0)) { + ++r; + q >>= ((mp_digit) 1); + } + return r; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_count_bits.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_div.c b/StormLib/src/libtommath/bn_mp_div.c new file mode 100644 index 000000000..3004a3ea0 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_div.c @@ -0,0 +1,292 @@ +#include "tommath.h" +#ifdef BN_MP_DIV_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +#ifdef BN_MP_DIV_SMALL + +/* slower bit-bang division... also smaller */ +int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + mp_int ta, tb, tq, q; + int res, n, n2; + + /* is divisor zero ? */ + if (mp_iszero (b) == 1) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag (a, b) == MP_LT) { + if (d != NULL) { + res = mp_copy (a, d); + } else { + res = MP_OKAY; + } + if (c != NULL) { + mp_zero (c); + } + return res; + } + + /* init our temps */ + if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) { + return res; + } + + + mp_set(&tq, 1); + n = mp_count_bits(a) - mp_count_bits(b); + if (((res = mp_abs(a, &ta)) != MP_OKAY) || + ((res = mp_abs(b, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { + goto LBL_ERR; + } + + while (n-- >= 0) { + if (mp_cmp(&tb, &ta) != MP_GT) { + if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || + ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) { + goto LBL_ERR; + } + } + if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || + ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { + goto LBL_ERR; + } + } + + /* now q == quotient and ta == remainder */ + n = a->sign; + n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG); + if (c != NULL) { + mp_exch(c, &q); + c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2; + } + if (d != NULL) { + mp_exch(d, &ta); + d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n; + } +LBL_ERR: + mp_clear_multi(&ta, &tb, &tq, &q, NULL); + return res; +} + +#else + +/* integer signed division. + * c*b + d == a [e.g. a/b, c=quotient, d=remainder] + * HAC pp.598 Algorithm 14.20 + * + * Note that the description in HAC is horribly + * incomplete. For example, it doesn't consider + * the case where digits are removed from 'x' in + * the inner loop. It also doesn't consider the + * case that y has fewer than three digits, etc.. + * + * The overall algorithm is as described as + * 14.20 from HAC but fixed to treat these cases. +*/ +int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + mp_int q, x, y, t1, t2; + int res, n, t, i, norm, neg; + + /* is divisor zero ? */ + if (mp_iszero (b) == 1) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag (a, b) == MP_LT) { + if (d != NULL) { + res = mp_copy (a, d); + } else { + res = MP_OKAY; + } + if (c != NULL) { + mp_zero (c); + } + return res; + } + + if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) { + return res; + } + q.used = a->used + 2; + + if ((res = mp_init (&t1)) != MP_OKAY) { + goto LBL_Q; + } + + if ((res = mp_init (&t2)) != MP_OKAY) { + goto LBL_T1; + } + + if ((res = mp_init_copy (&x, a)) != MP_OKAY) { + goto LBL_T2; + } + + if ((res = mp_init_copy (&y, b)) != MP_OKAY) { + goto LBL_X; + } + + /* fix the sign */ + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + x.sign = y.sign = MP_ZPOS; + + /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ + norm = mp_count_bits(&y) % DIGIT_BIT; + if (norm < (int)(DIGIT_BIT-1)) { + norm = (DIGIT_BIT-1) - norm; + if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) { + goto LBL_Y; + } + } else { + norm = 0; + } + + /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ + n = x.used - 1; + t = y.used - 1; + + /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ + if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ + goto LBL_Y; + } + + while (mp_cmp (&x, &y) != MP_LT) { + ++(q.dp[n - t]); + if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) { + goto LBL_Y; + } + } + + /* reset y by shifting it back down */ + mp_rshd (&y, n - t); + + /* step 3. for i from n down to (t + 1) */ + for (i = n; i >= (t + 1); i--) { + if (i > x.used) { + continue; + } + + /* step 3.1 if xi == yt then set q{i-t-1} to b-1, + * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ + if (x.dp[i] == y.dp[t]) { + q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1); + } else { + mp_word tmp; + tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT); + tmp |= ((mp_word) x.dp[i - 1]); + tmp /= ((mp_word) y.dp[t]); + if (tmp > (mp_word) MP_MASK) + tmp = MP_MASK; + q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK)); + } + + /* while (q{i-t-1} * (yt * b + y{t-1})) > + xi * b**2 + xi-1 * b + xi-2 + + do q{i-t-1} -= 1; + */ + q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK; + do { + q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK; + + /* find left hand */ + mp_zero (&t1); + t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1]; + t1.dp[1] = y.dp[t]; + t1.used = 2; + if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) { + goto LBL_Y; + } + + /* find right hand */ + t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2]; + t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1]; + t2.dp[2] = x.dp[i]; + t2.used = 3; + } while (mp_cmp_mag(&t1, &t2) == MP_GT); + + /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ + if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) { + goto LBL_Y; + } + + if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { + goto LBL_Y; + } + + if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) { + goto LBL_Y; + } + + /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ + if (x.sign == MP_NEG) { + if ((res = mp_copy (&y, &t1)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { + goto LBL_Y; + } + if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) { + goto LBL_Y; + } + + q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK; + } + } + + /* now q is the quotient and x is the remainder + * [which we have to normalize] + */ + + /* get sign before writing to c */ + x.sign = x.used == 0 ? MP_ZPOS : a->sign; + + if (c != NULL) { + mp_clamp (&q); + mp_exch (&q, c); + c->sign = neg; + } + + if (d != NULL) { + mp_div_2d (&x, norm, &x, NULL); + mp_exch (&x, d); + } + + res = MP_OKAY; + +LBL_Y:mp_clear (&y); +LBL_X:mp_clear (&x); +LBL_T2:mp_clear (&t2); +LBL_T1:mp_clear (&t1); +LBL_Q:mp_clear (&q); + return res; +} + +#endif + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_div.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_div_2.c b/StormLib/src/libtommath/bn_mp_div_2.c new file mode 100644 index 000000000..f3b9d16fa --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_div_2.c @@ -0,0 +1,68 @@ +#include "tommath.h" +#ifdef BN_MP_DIV_2_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* b = a/2 */ +int mp_div_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* copy */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* source alias */ + tmpa = a->dp + b->used - 1; + + /* dest alias */ + tmpb = b->dp + b->used - 1; + + /* carry */ + r = 0; + for (x = b->used - 1; x >= 0; x--) { + /* get the carry for the next iteration */ + rr = *tmpa & 1; + + /* shift the current digit, add in carry and store */ + *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); + + /* forward carry to next iteration */ + r = rr; + } + + /* zero excess digits */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + mp_clamp (b); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_div_2.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_div_2d.c b/StormLib/src/libtommath/bn_mp_div_2d.c new file mode 100644 index 000000000..861ea23a3 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_div_2d.c @@ -0,0 +1,97 @@ +#include "tommath.h" +#ifdef BN_MP_DIV_2D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* shift right by a certain bit count (store quotient in c, optional remainder in d) */ +int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) +{ + mp_digit D, r, rr; + int x, res; + mp_int t; + + + /* if the shift count is <= 0 then we do no work */ + if (b <= 0) { + res = mp_copy (a, c); + if (d != NULL) { + mp_zero (d); + } + return res; + } + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + /* get the remainder */ + if (d != NULL) { + if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + mp_rshd (c, b / DIGIT_BIT); + } + + /* shift any bit count < DIGIT_BIT */ + D = (mp_digit) (b % DIGIT_BIT); + if (D != 0) { + register mp_digit *tmpc, mask, shift; + + /* mask */ + mask = (((mp_digit)1) << D) - 1; + + /* shift for lsb */ + shift = DIGIT_BIT - D; + + /* alias */ + tmpc = c->dp + (c->used - 1); + + /* carry */ + r = 0; + for (x = c->used - 1; x >= 0; x--) { + /* get the lower bits of this word in a temp */ + rr = *tmpc & mask; + + /* shift the current word and mix in the carry bits from the previous word */ + *tmpc = (*tmpc >> D) | (r << shift); + --tmpc; + + /* set the carry to the carry bits of the current word found above */ + r = rr; + } + } + mp_clamp (c); + if (d != NULL) { + mp_exch (&t, d); + } + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_div_2d.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_div_3.c b/StormLib/src/libtommath/bn_mp_div_3.c new file mode 100644 index 000000000..4fc08fc4d --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_div_3.c @@ -0,0 +1,79 @@ +#include "tommath.h" +#ifdef BN_MP_DIV_3_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* divide by three (based on routine from MPI and the GMP manual) */ +int +mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) +{ + mp_int q; + mp_word w, t; + mp_digit b; + int res, ix; + + /* b = 2**DIGIT_BIT / 3 */ + b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3); + + if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { + return res; + } + + q.used = a->used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); + + if (w >= 3) { + /* multiply w by [1/3] */ + t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); + + /* now subtract 3 * [w/3] from w, to get the remainder */ + w -= t+t+t; + + /* fixup the remainder as required since + * the optimization is not exact. + */ + while (w >= 3) { + t += 1; + w -= 3; + } + } else { + t = 0; + } + q.dp[ix] = (mp_digit)t; + } + + /* [optional] store the remainder */ + if (d != NULL) { + *d = (mp_digit)w; + } + + /* [optional] store the quotient */ + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + } + mp_clear(&q); + + return res; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_div_3.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_div_d.c b/StormLib/src/libtommath/bn_mp_div_d.c new file mode 100644 index 000000000..c0318a4a1 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_div_d.c @@ -0,0 +1,115 @@ +#include "tommath.h" +#ifdef BN_MP_DIV_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +static int s_is_power_of_two(mp_digit b, int *p) +{ + int x; + + /* fast return if no power of two */ + if ((b==0) || (b & (b-1))) { + return 0; + } + + for (x = 0; x < DIGIT_BIT; x++) { + if (b == (((mp_digit)1)<dp[0] & ((((mp_digit)1)<used)) != MP_OKAY) { + return res; + } + + q.used = a->used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); + + if (w >= b) { + t = (mp_digit)(w / b); + w -= ((mp_word)t) * ((mp_word)b); + } else { + t = 0; + } + q.dp[ix] = (mp_digit)t; + } + + if (d != NULL) { + *d = (mp_digit)w; + } + + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + } + mp_clear(&q); + + return res; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_div_d.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2007/01/09 04:44:32 $ */ diff --git a/StormLib/src/libtommath/bn_mp_dr_is_modulus.c b/StormLib/src/libtommath/bn_mp_dr_is_modulus.c new file mode 100644 index 000000000..22ba5df3d --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_dr_is_modulus.c @@ -0,0 +1,43 @@ +#include "tommath.h" +#ifdef BN_MP_DR_IS_MODULUS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines if a number is a valid DR modulus */ +int mp_dr_is_modulus(mp_int *a) +{ + int ix; + + /* must be at least two digits */ + if (a->used < 2) { + return 0; + } + + /* must be of the form b**k - a [a <= b] so all + * but the first digit must be equal to -1 (mod b). + */ + for (ix = 1; ix < a->used; ix++) { + if (a->dp[ix] != MP_MASK) { + return 0; + } + } + return 1; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_dr_is_modulus.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_dr_reduce.c b/StormLib/src/libtommath/bn_mp_dr_reduce.c new file mode 100644 index 000000000..0afac941f --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_dr_reduce.c @@ -0,0 +1,94 @@ +#include "tommath.h" +#ifdef BN_MP_DR_REDUCE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reduce "x" in place modulo "n" using the Diminished Radix algorithm. + * + * Based on algorithm from the paper + * + * "Generating Efficient Primes for Discrete Log Cryptosystems" + * Chae Hoon Lim, Pil Joong Lee, + * POSTECH Information Research Laboratories + * + * The modulus must be of a special format [see manual] + * + * Has been modified to use algorithm 7.10 from the LTM book instead + * + * Input x must be in the range 0 <= x <= (n-1)**2 + */ +int +mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k) +{ + int err, i, m; + mp_word r; + mp_digit mu, *tmpx1, *tmpx2; + + /* m = digits in modulus */ + m = n->used; + + /* ensure that "x" has at least 2m digits */ + if (x->alloc < m + m) { + if ((err = mp_grow (x, m + m)) != MP_OKAY) { + return err; + } + } + +/* top of loop, this is where the code resumes if + * another reduction pass is required. + */ +top: + /* aliases for digits */ + /* alias for lower half of x */ + tmpx1 = x->dp; + + /* alias for upper half of x, or x/B**m */ + tmpx2 = x->dp + m; + + /* set carry to zero */ + mu = 0; + + /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ + for (i = 0; i < m; i++) { + r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu; + *tmpx1++ = (mp_digit)(r & MP_MASK); + mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); + } + + /* set final carry */ + *tmpx1++ = mu; + + /* zero words above m */ + for (i = m + 1; i < x->used; i++) { + *tmpx1++ = 0; + } + + /* clamp, sub and return */ + mp_clamp (x); + + /* if x >= n then subtract and reduce again + * Each successive "recursion" makes the input smaller and smaller. + */ + if (mp_cmp_mag (x, n) != MP_LT) { + s_mp_sub(x, n, x); + goto top; + } + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_dr_reduce.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_dr_setup.c b/StormLib/src/libtommath/bn_mp_dr_setup.c new file mode 100644 index 000000000..a5152f713 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_dr_setup.c @@ -0,0 +1,32 @@ +#include "tommath.h" +#ifdef BN_MP_DR_SETUP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines the setup value */ +void mp_dr_setup(mp_int *a, mp_digit *d) +{ + /* the casts are required if DIGIT_BIT is one less than + * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] + */ + *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - + ((mp_word)a->dp[0])); +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_dr_setup.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_exch.c b/StormLib/src/libtommath/bn_mp_exch.c new file mode 100644 index 000000000..e5ec7f577 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_exch.c @@ -0,0 +1,34 @@ +#include "tommath.h" +#ifdef BN_MP_EXCH_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* swap the elements of two integers, for cases where you can't simply swap the + * mp_int pointers around + */ +void +mp_exch (mp_int * a, mp_int * b) +{ + mp_int t; + + t = *a; + *a = *b; + *b = t; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_exch.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_expt_d.c b/StormLib/src/libtommath/bn_mp_expt_d.c new file mode 100644 index 000000000..7bf371ce6 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_expt_d.c @@ -0,0 +1,57 @@ +#include "tommath.h" +#ifdef BN_MP_EXPT_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* calculate c = a**b using a square-multiply algorithm */ +int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) +{ + int res, x; + mp_int g; + + if ((res = mp_init_copy (&g, a)) != MP_OKAY) { + return res; + } + + /* set initial result */ + mp_set (c, 1); + + for (x = 0; x < (int) DIGIT_BIT; x++) { + /* square */ + if ((res = mp_sqr (c, c)) != MP_OKAY) { + mp_clear (&g); + return res; + } + + /* if the bit is set multiply */ + if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) { + if ((res = mp_mul (c, &g, c)) != MP_OKAY) { + mp_clear (&g); + return res; + } + } + + /* shift to next bit */ + b <<= 1; + } + + mp_clear (&g); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_expt_d.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_exptmod.c b/StormLib/src/libtommath/bn_mp_exptmod.c new file mode 100644 index 000000000..27c46ea0a --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_exptmod.c @@ -0,0 +1,112 @@ +#include "tommath.h" +#ifdef BN_MP_EXPTMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + + +/* this is a shell function that calls either the normal or Montgomery + * exptmod functions. Originally the call to the montgomery code was + * embedded in the normal function but that wasted alot of stack space + * for nothing (since 99% of the time the Montgomery code would be called) + */ +int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +{ + int dr; + + /* modulus P must be positive */ + if (P->sign == MP_NEG) { + return MP_VAL; + } + + /* if exponent X is negative we have to recurse */ + if (X->sign == MP_NEG) { +#ifdef BN_MP_INVMOD_C + mp_int tmpG, tmpX; + int err; + + /* first compute 1/G mod P */ + if ((err = mp_init(&tmpG)) != MP_OKAY) { + return err; + } + if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + + /* now get |X| */ + if ((err = mp_init(&tmpX)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { + mp_clear_multi(&tmpG, &tmpX, NULL); + return err; + } + + /* and now compute (1/G)**|X| instead of G**X [X < 0] */ + err = mp_exptmod(&tmpG, &tmpX, P, Y); + mp_clear_multi(&tmpG, &tmpX, NULL); + return err; +#else + /* no invmod */ + return MP_VAL; +#endif + } + +/* modified diminished radix reduction */ +#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C) + if (mp_reduce_is_2k_l(P) == MP_YES) { + return s_mp_exptmod(G, X, P, Y, 1); + } +#endif + +#ifdef BN_MP_DR_IS_MODULUS_C + /* is it a DR modulus? */ + dr = mp_dr_is_modulus(P); +#else + /* default to no */ + dr = 0; +#endif + +#ifdef BN_MP_REDUCE_IS_2K_C + /* if not, is it a unrestricted DR modulus? */ + if (dr == 0) { + dr = mp_reduce_is_2k(P) << 1; + } +#endif + + /* if the modulus is odd or dr != 0 use the montgomery method */ +#ifdef BN_MP_EXPTMOD_FAST_C + if (mp_isodd (P) == 1 || dr != 0) { + return mp_exptmod_fast (G, X, P, Y, dr); + } else { +#endif +#ifdef BN_S_MP_EXPTMOD_C + /* otherwise use the generic Barrett reduction technique */ + return s_mp_exptmod (G, X, P, Y, 0); +#else + /* no exptmod for evens */ + return MP_VAL; +#endif +#ifdef BN_MP_EXPTMOD_FAST_C + } +#endif +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_exptmod.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_exptmod_fast.c b/StormLib/src/libtommath/bn_mp_exptmod_fast.c new file mode 100644 index 000000000..31205d4e2 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_exptmod_fast.c @@ -0,0 +1,321 @@ +#include "tommath.h" +#ifdef BN_MP_EXPTMOD_FAST_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 + * + * Uses a left-to-right k-ary sliding window to compute the modular exponentiation. + * The value of k changes based on the size of the exponent. + * + * Uses Montgomery or Diminished Radix reduction [whichever appropriate] + */ + +#ifdef MP_LOW_MEM + #define TAB_SIZE 32 +#else + #define TAB_SIZE 256 +#endif + +int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) +{ + mp_int M[TAB_SIZE], res; + mp_digit buf, mp; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + + /* use a pointer to the reduction algorithm. This allows us to use + * one of many reduction algorithms without modding the guts of + * the code with if statements everywhere. + */ + int (*redux)(mp_int*,mp_int*,mp_digit); + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* determine and setup reduction code */ + if (redmode == 0) { +#ifdef BN_MP_MONTGOMERY_SETUP_C + /* now setup montgomery */ + if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { + goto LBL_M; + } +#else + err = MP_VAL; + goto LBL_M; +#endif + + /* automatically pick the comba one if available (saves quite a few calls/ifs) */ +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C + if (((P->used * 2 + 1) < MP_WARRAY) && + P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + redux = fast_mp_montgomery_reduce; + } else +#endif + { +#ifdef BN_MP_MONTGOMERY_REDUCE_C + /* use slower baseline Montgomery method */ + redux = mp_montgomery_reduce; +#else + err = MP_VAL; + goto LBL_M; +#endif + } + } else if (redmode == 1) { +#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C) + /* setup DR reduction for moduli of the form B**k - b */ + mp_dr_setup(P, &mp); + redux = mp_dr_reduce; +#else + err = MP_VAL; + goto LBL_M; +#endif + } else { +#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C) + /* setup DR reduction for moduli of the form 2**k - b */ + if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { + goto LBL_M; + } + redux = mp_reduce_2k; +#else + err = MP_VAL; + goto LBL_M; +#endif + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto LBL_M; + } + + /* create M table + * + + * + * The first half of the table is not computed though accept for M[0] and M[1] + */ + + if (redmode == 0) { +#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C + /* now we need R mod m */ + if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { + goto LBL_RES; + } +#else + err = MP_VAL; + goto LBL_RES; +#endif + + /* now set M[1] to G * R mod m */ + if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { + goto LBL_RES; + } + } else { + mp_set(&res, 1); + if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { + goto LBL_RES; + } + } + + /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_RES; + } + + for (x = 0; x < (winsize - 1); x++) { + if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* create upper table */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&M[x], P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits so break */ + if (digidx == -1) { + break; + } + /* read next digit and reset bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int)DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + + /* get next bit of the window */ + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + } + } + + if (redmode == 0) { + /* fixup result if Montgomery reduction is used + * recall that any value in a Montgomery system is + * actually multiplied by R mod n. So we have + * to reduce one more time to cancel out the factor + * of R. + */ + if ((err = redux(&res, P, mp)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* swap res with Y */ + mp_exch (&res, Y); + err = MP_OKAY; +LBL_RES:mp_clear (&res); +LBL_M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} +#endif + + +/* $Source: /cvs/libtom/libtommath/bn_mp_exptmod_fast.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_exteuclid.c b/StormLib/src/libtommath/bn_mp_exteuclid.c new file mode 100644 index 000000000..9881d6edc --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_exteuclid.c @@ -0,0 +1,82 @@ +#include "tommath.h" +#ifdef BN_MP_EXTEUCLID_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Extended euclidean algorithm of (a, b) produces + a*u1 + b*u2 = u3 + */ +int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) +{ + mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp; + int err; + + if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) { + return err; + } + + /* initialize, (u1,u2,u3) = (1,0,a) */ + mp_set(&u1, 1); + if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; } + + /* initialize, (v1,v2,v3) = (0,1,b) */ + mp_set(&v2, 1); + if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; } + + /* loop while v3 != 0 */ + while (mp_iszero(&v3) == MP_NO) { + /* q = u3/v3 */ + if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; } + + /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */ + if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; } + if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; } + if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; } + if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; } + + /* (u1,u2,u3) = (v1,v2,v3) */ + if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; } + + /* (v1,v2,v3) = (t1,t2,t3) */ + if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; } + if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; } + } + + /* make sure U3 >= 0 */ + if (u3.sign == MP_NEG) { + mp_neg(&u1, &u1); + mp_neg(&u2, &u2); + mp_neg(&u3, &u3); + } + + /* copy result out */ + if (U1 != NULL) { mp_exch(U1, &u1); } + if (U2 != NULL) { mp_exch(U2, &u2); } + if (U3 != NULL) { mp_exch(U3, &u3); } + + err = MP_OKAY; +_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL); + return err; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_exteuclid.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_fread.c b/StormLib/src/libtommath/bn_mp_fread.c new file mode 100644 index 000000000..2976b30aa --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_fread.c @@ -0,0 +1,67 @@ +#include "tommath.h" +#ifdef BN_MP_FREAD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* read a bigint from a file stream in ASCII */ +int mp_fread(mp_int *a, int radix, FILE *stream) +{ + int err, ch, neg, y; + + /* clear a */ + mp_zero(a); + + /* if first digit is - then set negative */ + ch = fgetc(stream); + if (ch == '-') { + neg = MP_NEG; + ch = fgetc(stream); + } else { + neg = MP_ZPOS; + } + + for (;;) { + /* find y in the radix map */ + for (y = 0; y < radix; y++) { + if (mp_s_rmap[y] == ch) { + break; + } + } + if (y == radix) { + break; + } + + /* shift up and add */ + if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) { + return err; + } + if ((err = mp_add_d(a, y, a)) != MP_OKAY) { + return err; + } + + ch = fgetc(stream); + } + if (mp_cmp_d(a, 0) != MP_EQ) { + a->sign = neg; + } + + return MP_OKAY; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_fread.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_fwrite.c b/StormLib/src/libtommath/bn_mp_fwrite.c new file mode 100644 index 000000000..6782b2e19 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_fwrite.c @@ -0,0 +1,52 @@ +#include "tommath.h" +#ifdef BN_MP_FWRITE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +int mp_fwrite(mp_int *a, int radix, FILE *stream) +{ + char *buf; + int err, len, x; + + if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) { + return err; + } + + buf = OPT_CAST(char) XMALLOC (len); + if (buf == NULL) { + return MP_MEM; + } + + if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) { + XFREE (buf); + return err; + } + + for (x = 0; x < len; x++) { + if (fputc(buf[x], stream) == EOF) { + XFREE (buf); + return MP_VAL; + } + } + + XFREE (buf); + return MP_OKAY; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_fwrite.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_gcd.c b/StormLib/src/libtommath/bn_mp_gcd.c new file mode 100644 index 000000000..ce980eb6b --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_gcd.c @@ -0,0 +1,105 @@ +#include "tommath.h" +#ifdef BN_MP_GCD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Greatest Common Divisor using the binary method */ +int mp_gcd (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int u, v; + int k, u_lsb, v_lsb, res; + + /* either zero than gcd is the largest */ + if (mp_iszero (a) == MP_YES) { + return mp_abs (b, c); + } + if (mp_iszero (b) == MP_YES) { + return mp_abs (a, c); + } + + /* get copies of a and b we can modify */ + if ((res = mp_init_copy (&u, a)) != MP_OKAY) { + return res; + } + + if ((res = mp_init_copy (&v, b)) != MP_OKAY) { + goto LBL_U; + } + + /* must be positive for the remainder of the algorithm */ + u.sign = v.sign = MP_ZPOS; + + /* B1. Find the common power of two for u and v */ + u_lsb = mp_cnt_lsb(&u); + v_lsb = mp_cnt_lsb(&v); + k = MIN(u_lsb, v_lsb); + + if (k > 0) { + /* divide the power of two out */ + if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { + goto LBL_V; + } + + if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + /* divide any remaining factors of two out */ + if (u_lsb != k) { + if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + if (v_lsb != k) { + if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + while (mp_iszero(&v) == 0) { + /* make sure v is the largest */ + if (mp_cmp_mag(&u, &v) == MP_GT) { + /* swap u and v to make sure v is >= u */ + mp_exch(&u, &v); + } + + /* subtract smallest from largest */ + if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) { + goto LBL_V; + } + + /* Divide out all factors of two */ + if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) { + goto LBL_V; + } + } + + /* multiply by 2**k which we divided out at the beginning */ + if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) { + goto LBL_V; + } + c->sign = MP_ZPOS; + res = MP_OKAY; +LBL_V:mp_clear (&u); +LBL_U:mp_clear (&v); + return res; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_gcd.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_get_int.c b/StormLib/src/libtommath/bn_mp_get_int.c new file mode 100644 index 000000000..d9c76d0d1 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_get_int.c @@ -0,0 +1,45 @@ +#include "tommath.h" +#ifdef BN_MP_GET_INT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* get the lower 32-bits of an mp_int */ +unsigned long mp_get_int(mp_int * a) +{ + int i; + unsigned long res; + + if (a->used == 0) { + return 0; + } + + /* get number of digits of the lsb we have to read */ + i = MIN(a->used,(int)((sizeof(unsigned long)*CHAR_BIT+DIGIT_BIT-1)/DIGIT_BIT))-1; + + /* get most significant digit of result */ + res = DIGIT(a,i); + + while (--i >= 0) { + res = (res << DIGIT_BIT) | DIGIT(a,i); + } + + /* force result to 32-bits always so it is consistent on non 32-bit platforms */ + return res & 0xFFFFFFFFUL; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_get_int.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_grow.c b/StormLib/src/libtommath/bn_mp_grow.c new file mode 100644 index 000000000..a05dad73b --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_grow.c @@ -0,0 +1,57 @@ +#include "tommath.h" +#ifdef BN_MP_GROW_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* grow as required */ +int mp_grow (mp_int * a, int size) +{ + int i; + mp_digit *tmp; + + /* if the alloc size is smaller alloc more ram */ + if (a->alloc < size) { + /* ensure there are always at least MP_PREC digits extra on top */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* reallocate the array a->dp + * + * We store the return in a temporary variable + * in case the operation failed we don't want + * to overwrite the dp member of a. + */ + tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size); + if (tmp == NULL) { + /* reallocation failed but "a" is still valid [can be freed] */ + return MP_MEM; + } + + /* reallocation succeeded so set a->dp */ + a->dp = tmp; + + /* zero excess digits */ + i = a->alloc; + a->alloc = size; + for (; i < a->alloc; i++) { + a->dp[i] = 0; + } + } + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_grow.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_init.c b/StormLib/src/libtommath/bn_mp_init.c new file mode 100644 index 000000000..107d98be6 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_init.c @@ -0,0 +1,46 @@ +#include "tommath.h" +#ifdef BN_MP_INIT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* init a new mp_int */ +int mp_init (mp_int * a) +{ + int i; + + /* allocate memory required and clear it */ + a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the digits to zero */ + for (i = 0; i < MP_PREC; i++) { + a->dp[i] = 0; + } + + /* set the used to zero, allocated digits to the default precision + * and sign to positive */ + a->used = 0; + a->alloc = MP_PREC; + a->sign = MP_ZPOS; + + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_init.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_init_copy.c b/StormLib/src/libtommath/bn_mp_init_copy.c new file mode 100644 index 000000000..3ca1186ce --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_init_copy.c @@ -0,0 +1,32 @@ +#include "tommath.h" +#ifdef BN_MP_INIT_COPY_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* creates "a" then copies b into it */ +int mp_init_copy (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_init (a)) != MP_OKAY) { + return res; + } + return mp_copy (b, a); +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_init_copy.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_init_multi.c b/StormLib/src/libtommath/bn_mp_init_multi.c new file mode 100644 index 000000000..4f6f367ff --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_init_multi.c @@ -0,0 +1,59 @@ +#include "tommath.h" +#ifdef BN_MP_INIT_MULTI_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#include + +int mp_init_multi(mp_int *mp, ...) +{ + mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ + int n = 0; /* Number of ok inits */ + mp_int* cur_arg = mp; + va_list args; + + va_start(args, mp); /* init args to next argument from caller */ + while (cur_arg != NULL) { + if (mp_init(cur_arg) != MP_OKAY) { + /* Oops - error! Back-track and mp_clear what we already + succeeded in init-ing, then return error. + */ + va_list clean_args; + + /* end the current list */ + va_end(args); + + /* now start cleaning up */ + cur_arg = mp; + va_start(clean_args, mp); + while (n--) { + mp_clear(cur_arg); + cur_arg = va_arg(clean_args, mp_int*); + } + va_end(clean_args); + res = MP_MEM; + break; + } + n++; + cur_arg = va_arg(args, mp_int*); + } + va_end(args); + return res; /* Assumed ok, if error flagged above. */ +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_init_multi.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_init_set.c b/StormLib/src/libtommath/bn_mp_init_set.c new file mode 100644 index 000000000..853323f3a --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_init_set.c @@ -0,0 +1,32 @@ +#include "tommath.h" +#ifdef BN_MP_INIT_SET_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* initialize and set a digit */ +int mp_init_set (mp_int * a, mp_digit b) +{ + int err; + if ((err = mp_init(a)) != MP_OKAY) { + return err; + } + mp_set(a, b); + return err; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_init_set.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_init_set_int.c b/StormLib/src/libtommath/bn_mp_init_set_int.c new file mode 100644 index 000000000..b2f8727e3 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_init_set_int.c @@ -0,0 +1,31 @@ +#include "tommath.h" +#ifdef BN_MP_INIT_SET_INT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* initialize and set a digit */ +int mp_init_set_int (mp_int * a, unsigned long b) +{ + int err; + if ((err = mp_init(a)) != MP_OKAY) { + return err; + } + return mp_set_int(a, b); +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_init_set_int.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_init_size.c b/StormLib/src/libtommath/bn_mp_init_size.c new file mode 100644 index 000000000..17b8d9fce --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_init_size.c @@ -0,0 +1,48 @@ +#include "tommath.h" +#ifdef BN_MP_INIT_SIZE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* init an mp_init for a given size */ +int mp_init_size (mp_int * a, int size) +{ + int x; + + /* pad size so there are always extra digits */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* alloc mem */ + a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the members */ + a->used = 0; + a->alloc = size; + a->sign = MP_ZPOS; + + /* zero the digits */ + for (x = 0; x < size; x++) { + a->dp[x] = 0; + } + + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_init_size.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_invmod.c b/StormLib/src/libtommath/bn_mp_invmod.c new file mode 100644 index 000000000..038e584a2 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_invmod.c @@ -0,0 +1,43 @@ +#include "tommath.h" +#ifdef BN_MP_INVMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* hac 14.61, pp608 */ +int mp_invmod (mp_int * a, mp_int * b, mp_int * c) +{ + /* b cannot be negative */ + if (b->sign == MP_NEG || mp_iszero(b) == 1) { + return MP_VAL; + } + +#ifdef BN_FAST_MP_INVMOD_C + /* if the modulus is odd we can use a faster routine instead */ + if (mp_isodd (b) == 1) { + return fast_mp_invmod (a, b, c); + } +#endif + +#ifdef BN_MP_INVMOD_SLOW_C + return mp_invmod_slow(a, b, c); +#endif + + return MP_VAL; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_invmod.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_invmod_slow.c b/StormLib/src/libtommath/bn_mp_invmod_slow.c new file mode 100644 index 000000000..3792a4c23 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_invmod_slow.c @@ -0,0 +1,175 @@ +#include "tommath.h" +#ifdef BN_MP_INVMOD_SLOW_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* hac 14.61, pp608 */ +int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x, y, u, v, A, B, C, D; + int res; + + /* b cannot be negative */ + if (b->sign == MP_NEG || mp_iszero(b) == 1) { + return MP_VAL; + } + + /* init temps */ + if ((res = mp_init_multi(&x, &y, &u, &v, + &A, &B, &C, &D, NULL)) != MP_OKAY) { + return res; + } + + /* x = a, y = b */ + if ((res = mp_mod(a, b, &x)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (b, &y)) != MP_OKAY) { + goto LBL_ERR; + } + + /* 2. [modified] if x,y are both even then return an error! */ + if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) { + res = MP_VAL; + goto LBL_ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((res = mp_copy (&x, &u)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_copy (&y, &v)) != MP_OKAY) { + goto LBL_ERR; + } + mp_set (&A, 1); + mp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (mp_iseven (&u) == 1) { + /* 4.1 u = u/2 */ + if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { + goto LBL_ERR; + } + /* 4.2 if A or B is odd then */ + if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) { + /* A = (A+y)/2, B = (B-x)/2 */ + if ((res = mp_add (&A, &y, &A)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* A = A/2, B = B/2 */ + if ((res = mp_div_2 (&A, &A)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 5. while v is even do */ + while (mp_iseven (&v) == 1) { + /* 5.1 v = v/2 */ + if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { + goto LBL_ERR; + } + /* 5.2 if C or D is odd then */ + if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) { + /* C = (C+y)/2, D = (D-x)/2 */ + if ((res = mp_add (&C, &y, &C)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + /* C = C/2, D = D/2 */ + if ((res = mp_div_2 (&C, &C)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* 6. if u >= v then */ + if (mp_cmp (&u, &v) != MP_LT) { + /* u = u - v, A = A - C, B = B - D */ + if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { + goto LBL_ERR; + } + } else { + /* v - v - u, C = C - A, D = D - B */ + if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* if not zero goto step 4 */ + if (mp_iszero (&u) == 0) + goto top; + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d (&v, 1) != MP_EQ) { + res = MP_VAL; + goto LBL_ERR; + } + + /* if its too low */ + while (mp_cmp_d(&C, 0) == MP_LT) { + if ((res = mp_add(&C, b, &C)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* too big */ + while (mp_cmp_mag(&C, b) != MP_LT) { + if ((res = mp_sub(&C, b, &C)) != MP_OKAY) { + goto LBL_ERR; + } + } + + /* C is now the inverse */ + mp_exch (&C, c); + res = MP_OKAY; +LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); + return res; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_invmod_slow.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_is_square.c b/StormLib/src/libtommath/bn_mp_is_square.c new file mode 100644 index 000000000..5d2fa072c --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_is_square.c @@ -0,0 +1,109 @@ +#include "tommath.h" +#ifdef BN_MP_IS_SQUARE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Check if remainders are possible squares - fast exclude non-squares */ +static const char rem_128[128] = { + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 +}; + +static const char rem_105[105] = { + 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 +}; + +/* Store non-zero to ret if arg is square, and zero if not */ +int mp_is_square(mp_int *arg,int *ret) +{ + int res; + mp_digit c; + mp_int t; + unsigned long r; + + /* Default to Non-square :) */ + *ret = MP_NO; + + if (arg->sign == MP_NEG) { + return MP_VAL; + } + + /* digits used? (TSD) */ + if (arg->used == 0) { + return MP_OKAY; + } + + /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */ + if (rem_128[127 & DIGIT(arg,0)] == 1) { + return MP_OKAY; + } + + /* Next check mod 105 (3*5*7) */ + if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) { + return res; + } + if (rem_105[c] == 1) { + return MP_OKAY; + } + + + if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) { + return res; + } + if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) { + goto ERR; + } + r = mp_get_int(&t); + /* Check for other prime modules, note it's not an ERROR but we must + * free "t" so the easiest way is to goto ERR. We know that res + * is already equal to MP_OKAY from the mp_mod call + */ + if ( (1L<<(r%11)) & 0x5C4L ) goto ERR; + if ( (1L<<(r%13)) & 0x9E4L ) goto ERR; + if ( (1L<<(r%17)) & 0x5CE8L ) goto ERR; + if ( (1L<<(r%19)) & 0x4F50CL ) goto ERR; + if ( (1L<<(r%23)) & 0x7ACCA0L ) goto ERR; + if ( (1L<<(r%29)) & 0xC2EDD0CL ) goto ERR; + if ( (1L<<(r%31)) & 0x6DE2B848L ) goto ERR; + + /* Final check - is sqr(sqrt(arg)) == arg ? */ + if ((res = mp_sqrt(arg,&t)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sqr(&t,&t)) != MP_OKAY) { + goto ERR; + } + + *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO; +ERR:mp_clear(&t); + return res; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_is_square.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_jacobi.c b/StormLib/src/libtommath/bn_mp_jacobi.c new file mode 100644 index 000000000..c70b946f3 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_jacobi.c @@ -0,0 +1,105 @@ +#include "tommath.h" +#ifdef BN_MP_JACOBI_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes the jacobi c = (a | n) (or Legendre if n is prime) + * HAC pp. 73 Algorithm 2.149 + */ +int mp_jacobi (mp_int * a, mp_int * p, int *c) +{ + mp_int a1, p1; + int k, s, r, res; + mp_digit residue; + + /* if p <= 0 return MP_VAL */ + if (mp_cmp_d(p, 0) != MP_GT) { + return MP_VAL; + } + + /* step 1. if a == 0, return 0 */ + if (mp_iszero (a) == 1) { + *c = 0; + return MP_OKAY; + } + + /* step 2. if a == 1, return 1 */ + if (mp_cmp_d (a, 1) == MP_EQ) { + *c = 1; + return MP_OKAY; + } + + /* default */ + s = 0; + + /* step 3. write a = a1 * 2**k */ + if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { + return res; + } + + if ((res = mp_init (&p1)) != MP_OKAY) { + goto LBL_A1; + } + + /* divide out larger power of two */ + k = mp_cnt_lsb(&a1); + if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) { + goto LBL_P1; + } + + /* step 4. if e is even set s=1 */ + if ((k & 1) == 0) { + s = 1; + } else { + /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ + residue = p->dp[0] & 7; + + if (residue == 1 || residue == 7) { + s = 1; + } else if (residue == 3 || residue == 5) { + s = -1; + } + } + + /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */ + if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) { + s = -s; + } + + /* if a1 == 1 we're done */ + if (mp_cmp_d (&a1, 1) == MP_EQ) { + *c = s; + } else { + /* n1 = n mod a1 */ + if ((res = mp_mod (p, &a1, &p1)) != MP_OKAY) { + goto LBL_P1; + } + if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) { + goto LBL_P1; + } + *c = s * r; + } + + /* done */ + res = MP_OKAY; +LBL_P1:mp_clear (&p1); +LBL_A1:mp_clear (&a1); + return res; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_jacobi.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_karatsuba_mul.c b/StormLib/src/libtommath/bn_mp_karatsuba_mul.c new file mode 100644 index 000000000..b15ec2496 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_karatsuba_mul.c @@ -0,0 +1,167 @@ +#include "tommath.h" +#ifdef BN_MP_KARATSUBA_MUL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* c = |a| * |b| using Karatsuba Multiplication using + * three half size multiplications + * + * Let B represent the radix [e.g. 2**DIGIT_BIT] and + * let n represent half of the number of digits in + * the min(a,b) + * + * a = a1 * B**n + a0 + * b = b1 * B**n + b0 + * + * Then, a * b => + a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0 + * + * Note that a1b1 and a0b0 are used twice and only need to be + * computed once. So in total three half size (half # of + * digit) multiplications are performed, a0b0, a1b1 and + * (a1+b1)(a0+b0) + * + * Note that a multiplication of half the digits requires + * 1/4th the number of single precision multiplications so in + * total after one call 25% of the single precision multiplications + * are saved. Note also that the call to mp_mul can end up back + * in this function if the a0, a1, b0, or b1 are above the threshold. + * This is known as divide-and-conquer and leads to the famous + * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than + * the standard O(N**2) that the baseline/comba methods use. + * Generally though the overhead of this method doesn't pay off + * until a certain size (N ~ 80) is reached. + */ +int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x0, x1, y0, y1, t1, x0y0, x1y1; + int B, err; + + /* default the return code to an error */ + err = MP_MEM; + + /* min # of digits */ + B = MIN (a->used, b->used); + + /* now divide in two */ + B = B >> 1; + + /* init copy all the temps */ + if (mp_init_size (&x0, B) != MP_OKAY) + goto ERR; + if (mp_init_size (&x1, a->used - B) != MP_OKAY) + goto X0; + if (mp_init_size (&y0, B) != MP_OKAY) + goto X1; + if (mp_init_size (&y1, b->used - B) != MP_OKAY) + goto Y0; + + /* init temps */ + if (mp_init_size (&t1, B * 2) != MP_OKAY) + goto Y1; + if (mp_init_size (&x0y0, B * 2) != MP_OKAY) + goto T1; + if (mp_init_size (&x1y1, B * 2) != MP_OKAY) + goto X0Y0; + + /* now shift the digits */ + x0.used = y0.used = B; + x1.used = a->used - B; + y1.used = b->used - B; + + { + register int x; + register mp_digit *tmpa, *tmpb, *tmpx, *tmpy; + + /* we copy the digits directly instead of using higher level functions + * since we also need to shift the digits + */ + tmpa = a->dp; + tmpb = b->dp; + + tmpx = x0.dp; + tmpy = y0.dp; + for (x = 0; x < B; x++) { + *tmpx++ = *tmpa++; + *tmpy++ = *tmpb++; + } + + tmpx = x1.dp; + for (x = B; x < a->used; x++) { + *tmpx++ = *tmpa++; + } + + tmpy = y1.dp; + for (x = B; x < b->used; x++) { + *tmpy++ = *tmpb++; + } + } + + /* only need to clamp the lower words since by definition the + * upper words x1/y1 must have a known number of digits + */ + mp_clamp (&x0); + mp_clamp (&y0); + + /* now calc the products x0y0 and x1y1 */ + /* after this x0 is no longer required, free temp [x0==t2]! */ + if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY) + goto X1Y1; /* x0y0 = x0*y0 */ + if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY) + goto X1Y1; /* x1y1 = x1*y1 */ + + /* now calc x1+x0 and y1+y0 */ + if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) + goto X1Y1; /* t1 = x1 - x0 */ + if (s_mp_add (&y1, &y0, &x0) != MP_OKAY) + goto X1Y1; /* t2 = y1 - y0 */ + if (mp_mul (&t1, &x0, &t1) != MP_OKAY) + goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */ + + /* add x0y0 */ + if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY) + goto X1Y1; /* t2 = x0y0 + x1y1 */ + if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY) + goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */ + + /* shift by B */ + if (mp_lshd (&t1, B) != MP_OKAY) + goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<used; + + /* now divide in two */ + B = B >> 1; + + /* init copy all the temps */ + if (mp_init_size (&x0, B) != MP_OKAY) + goto ERR; + if (mp_init_size (&x1, a->used - B) != MP_OKAY) + goto X0; + + /* init temps */ + if (mp_init_size (&t1, a->used * 2) != MP_OKAY) + goto X1; + if (mp_init_size (&t2, a->used * 2) != MP_OKAY) + goto T1; + if (mp_init_size (&x0x0, B * 2) != MP_OKAY) + goto T2; + if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY) + goto X0X0; + + { + register int x; + register mp_digit *dst, *src; + + src = a->dp; + + /* now shift the digits */ + dst = x0.dp; + for (x = 0; x < B; x++) { + *dst++ = *src++; + } + + dst = x1.dp; + for (x = B; x < a->used; x++) { + *dst++ = *src++; + } + } + + x0.used = B; + x1.used = a->used - B; + + mp_clamp (&x0); + + /* now calc the products x0*x0 and x1*x1 */ + if (mp_sqr (&x0, &x0x0) != MP_OKAY) + goto X1X1; /* x0x0 = x0*x0 */ + if (mp_sqr (&x1, &x1x1) != MP_OKAY) + goto X1X1; /* x1x1 = x1*x1 */ + + /* now calc (x1+x0)**2 */ + if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) + goto X1X1; /* t1 = x1 - x0 */ + if (mp_sqr (&t1, &t1) != MP_OKAY) + goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */ + + /* add x0y0 */ + if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY) + goto X1X1; /* t2 = x0x0 + x1x1 */ + if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY) + goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */ + + /* shift by B */ + if (mp_lshd (&t1, B) != MP_OKAY) + goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<sign = MP_ZPOS; + +LBL_T: + mp_clear_multi (&t1, &t2, NULL); + return res; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_lcm.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_lshd.c b/StormLib/src/libtommath/bn_mp_lshd.c new file mode 100644 index 000000000..ffb0defd0 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_lshd.c @@ -0,0 +1,67 @@ +#include "tommath.h" +#ifdef BN_MP_LSHD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* shift left a certain amount of digits */ +int mp_lshd (mp_int * a, int b) +{ + int x, res; + + /* if its less than zero return */ + if (b <= 0) { + return MP_OKAY; + } + + /* grow to fit the new digits */ + if (a->alloc < a->used + b) { + if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { + return res; + } + } + + { + register mp_digit *top, *bottom; + + /* increment the used by the shift amount then copy upwards */ + a->used += b; + + /* top */ + top = a->dp + a->used - 1; + + /* base */ + bottom = a->dp + a->used - 1 - b; + + /* much like mp_rshd this is implemented using a sliding window + * except the window goes the otherway around. Copying from + * the bottom to the top. see bn_mp_rshd.c for more info. + */ + for (x = a->used - 1; x >= b; x--) { + *top-- = *bottom--; + } + + /* zero the lower digits */ + top = a->dp; + for (x = 0; x < b; x++) { + *top++ = 0; + } + } + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_lshd.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_mod.c b/StormLib/src/libtommath/bn_mp_mod.c new file mode 100644 index 000000000..b24c71f9d --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_mod.c @@ -0,0 +1,48 @@ +#include "tommath.h" +#ifdef BN_MP_MOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* c = a mod b, 0 <= c < b */ +int +mp_mod (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int t; + int res; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + if (t.sign != b->sign) { + res = mp_add (b, &t, c); + } else { + res = MP_OKAY; + mp_exch (&t, c); + } + + mp_clear (&t); + return res; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_mod.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_mod_2d.c b/StormLib/src/libtommath/bn_mp_mod_2d.c new file mode 100644 index 000000000..a54a02426 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_mod_2d.c @@ -0,0 +1,55 @@ +#include "tommath.h" +#ifdef BN_MP_MOD_2D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* calc a value mod 2**b */ +int +mp_mod_2d (mp_int * a, int b, mp_int * c) +{ + int x, res; + + /* if b is <= 0 then zero the int */ + if (b <= 0) { + mp_zero (c); + return MP_OKAY; + } + + /* if the modulus is larger than the value than return */ + if (b >= (int) (a->used * DIGIT_BIT)) { + res = mp_copy (a, c); + return res; + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + + /* zero digits above the last digit of the modulus */ + for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { + c->dp[x] = 0; + } + /* clear the digit that is not completely outside/inside the modulus */ + c->dp[b / DIGIT_BIT] &= + (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1)); + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_mod_2d.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_mod_d.c b/StormLib/src/libtommath/bn_mp_mod_d.c new file mode 100644 index 000000000..59886e773 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_mod_d.c @@ -0,0 +1,27 @@ +#include "tommath.h" +#ifdef BN_MP_MOD_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +int +mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) +{ + return mp_div_d(a, b, NULL, c); +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_mod_d.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_montgomery_calc_normalization.c b/StormLib/src/libtommath/bn_mp_montgomery_calc_normalization.c new file mode 100644 index 000000000..fdefcbd99 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_montgomery_calc_normalization.c @@ -0,0 +1,59 @@ +#include "tommath.h" +#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* + * shifts with subtractions when the result is greater than b. + * + * The method is slightly modified to shift B unconditionally upto just under + * the leading bit of b. This saves alot of multiple precision shifting. + */ +int mp_montgomery_calc_normalization (mp_int * a, mp_int * b) +{ + int x, bits, res; + + /* how many bits of last digit does b use */ + bits = mp_count_bits (b) % DIGIT_BIT; + + if (b->used > 1) { + if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) { + return res; + } + } else { + mp_set(a, 1); + bits = 1; + } + + + /* now compute C = A * B mod b */ + for (x = bits - 1; x < (int)DIGIT_BIT; x++) { + if ((res = mp_mul_2 (a, a)) != MP_OKAY) { + return res; + } + if (mp_cmp_mag (a, b) != MP_LT) { + if ((res = s_mp_sub (a, b, a)) != MP_OKAY) { + return res; + } + } + } + + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_montgomery_calc_normalization.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_montgomery_reduce.c b/StormLib/src/libtommath/bn_mp_montgomery_reduce.c new file mode 100644 index 000000000..173848e0a --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_montgomery_reduce.c @@ -0,0 +1,118 @@ +#include "tommath.h" +#ifdef BN_MP_MONTGOMERY_REDUCE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes xR**-1 == x (mod N) via Montgomery Reduction */ +int +mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) +{ + int ix, res, digs; + mp_digit mu; + + /* can the fast reduction [comba] method be used? + * + * Note that unlike in mul you're safely allowed *less* + * than the available columns [255 per default] since carries + * are fixed up in the inner loop. + */ + digs = n->used * 2 + 1; + if ((digs < MP_WARRAY) && + n->used < + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_mp_montgomery_reduce (x, n, rho); + } + + /* grow the input as required */ + if (x->alloc < digs) { + if ((res = mp_grow (x, digs)) != MP_OKAY) { + return res; + } + } + x->used = digs; + + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * rho mod b + * + * The value of rho must be precalculated via + * montgomery_setup() such that + * it equals -1/n0 mod b this allows the + * following inner loop to reduce the + * input one digit at a time + */ + mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK); + + /* a = a + mu * m * b**i */ + { + register int iy; + register mp_digit *tmpn, *tmpx, u; + register mp_word r; + + /* alias for digits of the modulus */ + tmpn = n->dp; + + /* alias for the digits of x [the input] */ + tmpx = x->dp + ix; + + /* set the carry to zero */ + u = 0; + + /* Multiply and add in place */ + for (iy = 0; iy < n->used; iy++) { + /* compute product and sum */ + r = ((mp_word)mu) * ((mp_word)*tmpn++) + + ((mp_word) u) + ((mp_word) * tmpx); + + /* get carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + + /* fix digit */ + *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK)); + } + /* At this point the ix'th digit of x should be zero */ + + + /* propagate carries upwards as required*/ + while (u) { + *tmpx += u; + u = *tmpx >> DIGIT_BIT; + *tmpx++ &= MP_MASK; + } + } + } + + /* at this point the n.used'th least + * significant digits of x are all zero + * which means we can shift x to the + * right by n.used digits and the + * residue is unchanged. + */ + + /* x = x/b**n.used */ + mp_clamp(x); + mp_rshd (x, n->used); + + /* if x >= n then x = x - n */ + if (mp_cmp_mag (x, n) != MP_LT) { + return s_mp_sub (x, n, x); + } + + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_montgomery_reduce.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_montgomery_setup.c b/StormLib/src/libtommath/bn_mp_montgomery_setup.c new file mode 100644 index 000000000..6f277320e --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_montgomery_setup.c @@ -0,0 +1,59 @@ +#include "tommath.h" +#ifdef BN_MP_MONTGOMERY_SETUP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* setups the montgomery reduction stuff */ +int +mp_montgomery_setup (mp_int * n, mp_digit * rho) +{ + mp_digit x, b; + +/* fast inversion mod 2**k + * + * Based on the fact that + * + * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) + * => 2*X*A - X*X*A*A = 1 + * => 2*(1) - (1) = 1 + */ + b = n->dp[0]; + + if ((b & 1) == 0) { + return MP_VAL; + } + + x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ + x *= 2 - b * x; /* here x*a==1 mod 2**8 */ +#if !defined(MP_8BIT) + x *= 2 - b * x; /* here x*a==1 mod 2**16 */ +#endif +#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT)) + x *= 2 - b * x; /* here x*a==1 mod 2**32 */ +#endif +#ifdef MP_64BIT + x *= 2 - b * x; /* here x*a==1 mod 2**64 */ +#endif + + /* rho = -1/m mod b */ + *rho = (unsigned long)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK; + + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_montgomery_setup.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_mul.c b/StormLib/src/libtommath/bn_mp_mul.c new file mode 100644 index 000000000..a1315dac3 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_mul.c @@ -0,0 +1,66 @@ +#include "tommath.h" +#ifdef BN_MP_MUL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* high level multiplication (handles sign) */ +int mp_mul (mp_int * a, mp_int * b, mp_int * c) +{ + int res, neg; + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + + /* use Toom-Cook? */ +#ifdef BN_MP_TOOM_MUL_C + if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { + res = mp_toom_mul(a, b, c); + } else +#endif +#ifdef BN_MP_KARATSUBA_MUL_C + /* use Karatsuba? */ + if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { + res = mp_karatsuba_mul (a, b, c); + } else +#endif + { + /* can we use the fast multiplier? + * + * The fast multiplier can be used if the output will + * have less than MP_WARRAY digits and the number of + * digits won't affect carry propagation + */ + int digs = a->used + b->used + 1; + +#ifdef BN_FAST_S_MP_MUL_DIGS_C + if ((digs < MP_WARRAY) && + MIN(a->used, b->used) <= + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + res = fast_s_mp_mul_digs (a, b, c, digs); + } else +#endif +#ifdef BN_S_MP_MUL_DIGS_C + res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */ +#else + res = MP_VAL; +#endif + + } + c->sign = (c->used > 0) ? neg : MP_ZPOS; + return res; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_mul.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_mul_2.c b/StormLib/src/libtommath/bn_mp_mul_2.c new file mode 100644 index 000000000..3315744f1 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_mul_2.c @@ -0,0 +1,82 @@ +#include "tommath.h" +#ifdef BN_MP_MUL_2_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* b = a*2 */ +int mp_mul_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* grow to accomodate result */ + if (b->alloc < a->used + 1) { + if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* alias for source */ + tmpa = a->dp; + + /* alias for dest */ + tmpb = b->dp; + + /* carry */ + r = 0; + for (x = 0; x < a->used; x++) { + + /* get what will be the *next* carry bit from the + * MSB of the current digit + */ + rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); + + /* now shift up this digit, add in the carry [from the previous] */ + *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; + + /* copy the carry that would be from the source + * digit into the next iteration + */ + r = rr; + } + + /* new leading digit? */ + if (r != 0) { + /* add a MSB which is always 1 at this point */ + *tmpb = 1; + ++(b->used); + } + + /* now zero any excess digits on the destination + * that we didn't write to + */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_mul_2.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_mul_2d.c b/StormLib/src/libtommath/bn_mp_mul_2d.c new file mode 100644 index 000000000..c636c1798 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_mul_2d.c @@ -0,0 +1,85 @@ +#include "tommath.h" +#ifdef BN_MP_MUL_2D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* shift left by a certain bit count */ +int mp_mul_2d (mp_int * a, int b, mp_int * c) +{ + mp_digit d; + int res; + + /* copy */ + if (a != c) { + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + } + + if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) { + if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) { + return res; + } + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { + return res; + } + } + + /* shift any bit count < DIGIT_BIT */ + d = (mp_digit) (b % DIGIT_BIT); + if (d != 0) { + register mp_digit *tmpc, shift, mask, r, rr; + register int x; + + /* bitmask for carries */ + mask = (((mp_digit)1) << d) - 1; + + /* shift for msbs */ + shift = DIGIT_BIT - d; + + /* alias */ + tmpc = c->dp; + + /* carry */ + r = 0; + for (x = 0; x < c->used; x++) { + /* get the higher bits of the current word */ + rr = (*tmpc >> shift) & mask; + + /* shift the current word and OR in the carry */ + *tmpc = ((*tmpc << d) | r) & MP_MASK; + ++tmpc; + + /* set the carry to the carry bits of the current word */ + r = rr; + } + + /* set final carry */ + if (r != 0) { + c->dp[(c->used)++] = r; + } + } + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_mul_2d.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_mul_d.c b/StormLib/src/libtommath/bn_mp_mul_d.c new file mode 100644 index 000000000..a36a76bba --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_mul_d.c @@ -0,0 +1,79 @@ +#include "tommath.h" +#ifdef BN_MP_MUL_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* multiply by a digit */ +int +mp_mul_d (mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit u, *tmpa, *tmpc; + mp_word r; + int ix, res, olduse; + + /* make sure c is big enough to hold a*b */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* get the original destinations used count */ + olduse = c->used; + + /* set the sign */ + c->sign = a->sign; + + /* alias for a->dp [source] */ + tmpa = a->dp; + + /* alias for c->dp [dest] */ + tmpc = c->dp; + + /* zero carry */ + u = 0; + + /* compute columns */ + for (ix = 0; ix < a->used; ix++) { + /* compute product and carry sum for this term */ + r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b); + + /* mask off higher bits to get a single digit */ + *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* send carry into next iteration */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + + /* store final carry [if any] and increment ix offset */ + *tmpc++ = u; + ++ix; + + /* now zero digits above the top */ + while (ix++ < olduse) { + *tmpc++ = 0; + } + + /* set used count */ + c->used = a->used + 1; + mp_clamp(c); + + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_mul_d.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_mulmod.c b/StormLib/src/libtommath/bn_mp_mulmod.c new file mode 100644 index 000000000..8ec98bbdd --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_mulmod.c @@ -0,0 +1,40 @@ +#include "tommath.h" +#ifdef BN_MP_MULMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* d = a * b (mod c) */ +int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_mul (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_mulmod.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_n_root.c b/StormLib/src/libtommath/bn_mp_n_root.c new file mode 100644 index 000000000..f188f5255 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_n_root.c @@ -0,0 +1,132 @@ +#include "tommath.h" +#ifdef BN_MP_N_ROOT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* find the n'th root of an integer + * + * Result found such that (c)**b <= a and (c+1)**b > a + * + * This algorithm uses Newton's approximation + * x[i+1] = x[i] - f(x[i])/f'(x[i]) + * which will find the root in log(N) time where + * each step involves a fair bit. This is not meant to + * find huge roots [square and cube, etc]. + */ +int mp_n_root (mp_int * a, mp_digit b, mp_int * c) +{ + mp_int t1, t2, t3; + int res, neg; + + /* input must be positive if b is even */ + if ((b & 1) == 0 && a->sign == MP_NEG) { + return MP_VAL; + } + + if ((res = mp_init (&t1)) != MP_OKAY) { + return res; + } + + if ((res = mp_init (&t2)) != MP_OKAY) { + goto LBL_T1; + } + + if ((res = mp_init (&t3)) != MP_OKAY) { + goto LBL_T2; + } + + /* if a is negative fudge the sign but keep track */ + neg = a->sign; + a->sign = MP_ZPOS; + + /* t2 = 2 */ + mp_set (&t2, 2); + + do { + /* t1 = t2 */ + if ((res = mp_copy (&t2, &t1)) != MP_OKAY) { + goto LBL_T3; + } + + /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */ + + /* t3 = t1**(b-1) */ + if ((res = mp_expt_d (&t1, b - 1, &t3)) != MP_OKAY) { + goto LBL_T3; + } + + /* numerator */ + /* t2 = t1**b */ + if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) { + goto LBL_T3; + } + + /* t2 = t1**b - a */ + if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) { + goto LBL_T3; + } + + /* denominator */ + /* t3 = t1**(b-1) * b */ + if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) { + goto LBL_T3; + } + + /* t3 = (t1**b - a)/(b * t1**(b-1)) */ + if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) { + goto LBL_T3; + } + + if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) { + goto LBL_T3; + } + } while (mp_cmp (&t1, &t2) != MP_EQ); + + /* result can be off by a few so check */ + for (;;) { + if ((res = mp_expt_d (&t1, b, &t2)) != MP_OKAY) { + goto LBL_T3; + } + + if (mp_cmp (&t2, a) == MP_GT) { + if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) { + goto LBL_T3; + } + } else { + break; + } + } + + /* reset the sign of a first */ + a->sign = neg; + + /* set the result */ + mp_exch (&t1, c); + + /* set the sign of the result */ + c->sign = neg; + + res = MP_OKAY; + +LBL_T3:mp_clear (&t3); +LBL_T2:mp_clear (&t2); +LBL_T1:mp_clear (&t1); + return res; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_n_root.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_neg.c b/StormLib/src/libtommath/bn_mp_neg.c new file mode 100644 index 000000000..87a8b5004 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_neg.c @@ -0,0 +1,40 @@ +#include "tommath.h" +#ifdef BN_MP_NEG_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* b = -a */ +int mp_neg (mp_int * a, mp_int * b) +{ + int res; + if (a != b) { + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } + } + + if (mp_iszero(b) != MP_YES) { + b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS; + } else { + b->sign = MP_ZPOS; + } + + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_neg.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_or.c b/StormLib/src/libtommath/bn_mp_or.c new file mode 100644 index 000000000..12601eaf7 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_or.c @@ -0,0 +1,50 @@ +#include "tommath.h" +#ifdef BN_MP_OR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* OR two ints together */ +int mp_or (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] |= x->dp[ix]; + } + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_or.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_prime_fermat.c b/StormLib/src/libtommath/bn_mp_prime_fermat.c new file mode 100644 index 000000000..297e13c79 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_prime_fermat.c @@ -0,0 +1,62 @@ +#include "tommath.h" +#ifdef BN_MP_PRIME_FERMAT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* performs one Fermat test. + * + * If "a" were prime then b**a == b (mod a) since the order of + * the multiplicative sub-group would be phi(a) = a-1. That means + * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a). + * + * Sets result to 1 if the congruence holds, or zero otherwise. + */ +int mp_prime_fermat (mp_int * a, mp_int * b, int *result) +{ + mp_int t; + int err; + + /* default to composite */ + *result = MP_NO; + + /* ensure b > 1 */ + if (mp_cmp_d(b, 1) != MP_GT) { + return MP_VAL; + } + + /* init t */ + if ((err = mp_init (&t)) != MP_OKAY) { + return err; + } + + /* compute t = b**a mod a */ + if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) { + goto LBL_T; + } + + /* is it equal to b? */ + if (mp_cmp (&t, b) == MP_EQ) { + *result = MP_YES; + } + + err = MP_OKAY; +LBL_T:mp_clear (&t); + return err; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_prime_fermat.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_prime_is_divisible.c b/StormLib/src/libtommath/bn_mp_prime_is_divisible.c new file mode 100644 index 000000000..0ae649835 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_prime_is_divisible.c @@ -0,0 +1,50 @@ +#include "tommath.h" +#ifdef BN_MP_PRIME_IS_DIVISIBLE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines if an integers is divisible by one + * of the first PRIME_SIZE primes or not + * + * sets result to 0 if not, 1 if yes + */ +int mp_prime_is_divisible (mp_int * a, int *result) +{ + int err, ix; + mp_digit res; + + /* default to not */ + *result = MP_NO; + + for (ix = 0; ix < PRIME_SIZE; ix++) { + /* what is a mod LBL_prime_tab[ix] */ + if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) { + return err; + } + + /* is the residue zero? */ + if (res == 0) { + *result = MP_YES; + return MP_OKAY; + } + } + + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_prime_is_divisible.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_prime_is_prime.c b/StormLib/src/libtommath/bn_mp_prime_is_prime.c new file mode 100644 index 000000000..0e1e94bad --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_prime_is_prime.c @@ -0,0 +1,83 @@ +#include "tommath.h" +#ifdef BN_MP_PRIME_IS_PRIME_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* performs a variable number of rounds of Miller-Rabin + * + * Probability of error after t rounds is no more than + + * + * Sets result to 1 if probably prime, 0 otherwise + */ +int mp_prime_is_prime (mp_int * a, int t, int *result) +{ + mp_int b; + int ix, err, res; + + /* default to no */ + *result = MP_NO; + + /* valid value of t? */ + if (t <= 0 || t > PRIME_SIZE) { + return MP_VAL; + } + + /* is the input equal to one of the primes in the table? */ + for (ix = 0; ix < PRIME_SIZE; ix++) { + if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { + *result = 1; + return MP_OKAY; + } + } + + /* first perform trial division */ + if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { + return err; + } + + /* return if it was trivially divisible */ + if (res == MP_YES) { + return MP_OKAY; + } + + /* now perform the miller-rabin rounds */ + if ((err = mp_init (&b)) != MP_OKAY) { + return err; + } + + for (ix = 0; ix < t; ix++) { + /* set the prime */ + mp_set (&b, ltm_prime_tab[ix]); + + if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { + goto LBL_B; + } + + if (res == MP_NO) { + goto LBL_B; + } + } + + /* passed the test */ + *result = MP_YES; +LBL_B:mp_clear (&b); + return err; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_prime_is_prime.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_prime_miller_rabin.c b/StormLib/src/libtommath/bn_mp_prime_miller_rabin.c new file mode 100644 index 000000000..47385bc81 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_prime_miller_rabin.c @@ -0,0 +1,103 @@ +#include "tommath.h" +#ifdef BN_MP_PRIME_MILLER_RABIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Miller-Rabin test of "a" to the base of "b" as described in + * HAC pp. 139 Algorithm 4.24 + * + * Sets result to 0 if definitely composite or 1 if probably prime. + * Randomly the chance of error is no more than 1/4 and often + * very much lower. + */ +int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) +{ + mp_int n1, y, r; + int s, j, err; + + /* default */ + *result = MP_NO; + + /* ensure b > 1 */ + if (mp_cmp_d(b, 1) != MP_GT) { + return MP_VAL; + } + + /* get n1 = a - 1 */ + if ((err = mp_init_copy (&n1, a)) != MP_OKAY) { + return err; + } + if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) { + goto LBL_N1; + } + + /* set 2**s * r = n1 */ + if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) { + goto LBL_N1; + } + + /* count the number of least significant bits + * which are zero + */ + s = mp_cnt_lsb(&r); + + /* now divide n - 1 by 2**s */ + if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) { + goto LBL_R; + } + + /* compute y = b**r mod a */ + if ((err = mp_init (&y)) != MP_OKAY) { + goto LBL_R; + } + if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) { + goto LBL_Y; + } + + /* if y != 1 and y != n1 do */ + if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) { + j = 1; + /* while j <= s-1 and y != n1 */ + while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) { + if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) { + goto LBL_Y; + } + + /* if y == 1 then composite */ + if (mp_cmp_d (&y, 1) == MP_EQ) { + goto LBL_Y; + } + + ++j; + } + + /* if y != n1 then composite */ + if (mp_cmp (&y, &n1) != MP_EQ) { + goto LBL_Y; + } + } + + /* probably prime now */ + *result = MP_YES; +LBL_Y:mp_clear (&y); +LBL_R:mp_clear (&r); +LBL_N1:mp_clear (&n1); + return err; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_prime_miller_rabin.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_prime_next_prime.c b/StormLib/src/libtommath/bn_mp_prime_next_prime.c new file mode 100644 index 000000000..833992bac --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_prime_next_prime.c @@ -0,0 +1,170 @@ +#include "tommath.h" +#ifdef BN_MP_PRIME_NEXT_PRIME_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* finds the next prime after the number "a" using "t" trials + * of Miller-Rabin. + * + * bbs_style = 1 means the prime must be congruent to 3 mod 4 + */ +int mp_prime_next_prime(mp_int *a, int t, int bbs_style) +{ + int err, res, x, y; + mp_digit res_tab[PRIME_SIZE], step, kstep; + mp_int b; + + /* ensure t is valid */ + if (t <= 0 || t > PRIME_SIZE) { + return MP_VAL; + } + + /* force positive */ + a->sign = MP_ZPOS; + + /* simple algo if a is less than the largest prime in the table */ + if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) { + /* find which prime it is bigger than */ + for (x = PRIME_SIZE - 2; x >= 0; x--) { + if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) { + if (bbs_style == 1) { + /* ok we found a prime smaller or + * equal [so the next is larger] + * + * however, the prime must be + * congruent to 3 mod 4 + */ + if ((ltm_prime_tab[x + 1] & 3) != 3) { + /* scan upwards for a prime congruent to 3 mod 4 */ + for (y = x + 1; y < PRIME_SIZE; y++) { + if ((ltm_prime_tab[y] & 3) == 3) { + mp_set(a, ltm_prime_tab[y]); + return MP_OKAY; + } + } + } + } else { + mp_set(a, ltm_prime_tab[x + 1]); + return MP_OKAY; + } + } + } + /* at this point a maybe 1 */ + if (mp_cmp_d(a, 1) == MP_EQ) { + mp_set(a, 2); + return MP_OKAY; + } + /* fall through to the sieve */ + } + + /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */ + if (bbs_style == 1) { + kstep = 4; + } else { + kstep = 2; + } + + /* at this point we will use a combination of a sieve and Miller-Rabin */ + + if (bbs_style == 1) { + /* if a mod 4 != 3 subtract the correct value to make it so */ + if ((a->dp[0] & 3) != 3) { + if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; }; + } + } else { + if (mp_iseven(a) == 1) { + /* force odd */ + if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { + return err; + } + } + } + + /* generate the restable */ + for (x = 1; x < PRIME_SIZE; x++) { + if ((err = mp_mod_d(a, ltm_prime_tab[x], res_tab + x)) != MP_OKAY) { + return err; + } + } + + /* init temp used for Miller-Rabin Testing */ + if ((err = mp_init(&b)) != MP_OKAY) { + return err; + } + + for (;;) { + /* skip to the next non-trivially divisible candidate */ + step = 0; + do { + /* y == 1 if any residue was zero [e.g. cannot be prime] */ + y = 0; + + /* increase step to next candidate */ + step += kstep; + + /* compute the new residue without using division */ + for (x = 1; x < PRIME_SIZE; x++) { + /* add the step to each residue */ + res_tab[x] += kstep; + + /* subtract the modulus [instead of using division] */ + if (res_tab[x] >= ltm_prime_tab[x]) { + res_tab[x] -= ltm_prime_tab[x]; + } + + /* set flag if zero */ + if (res_tab[x] == 0) { + y = 1; + } + } + } while (y == 1 && step < ((((mp_digit)1)<= ((((mp_digit)1)< size) { + return (x == 0) ? sizes[0].t : sizes[x - 1].t; + } + } + return sizes[x-1].t + 1; +} + + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_prime_rabin_miller_trials.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_prime_random_ex.c b/StormLib/src/libtommath/bn_mp_prime_random_ex.c new file mode 100644 index 000000000..4eec3f69e --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_prime_random_ex.c @@ -0,0 +1,125 @@ +#include "tommath.h" +#ifdef BN_MP_PRIME_RANDOM_EX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* makes a truly random prime of a given size (bits), + * + * Flags are as follows: + * + * LTM_PRIME_BBS - make prime congruent to 3 mod 4 + * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) + * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero + * LTM_PRIME_2MSB_ON - make the 2nd highest bit one + * + * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can + * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself + * so it can be NULL + * + */ + +/* This is possibly the mother of all prime generation functions, muahahahahaha! */ +int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat) +{ + unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb; + int res, err, bsize, maskOR_msb_offset; + + /* sanity check the input */ + if (size <= 1 || t <= 0) { + return MP_VAL; + } + + /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */ + if (flags & LTM_PRIME_SAFE) { + flags |= LTM_PRIME_BBS; + } + + /* calc the byte size */ + bsize = (size>>3) + ((size&7)?1:0); + + /* we need a buffer of bsize bytes */ + tmp = OPT_CAST(unsigned char) XMALLOC(bsize); + if (tmp == NULL) { + return MP_MEM; + } + + /* calc the maskAND value for the MSbyte*/ + maskAND = ((size&7) == 0) ? 0xFF : (0xFF >> (8 - (size & 7))); + + /* calc the maskOR_msb */ + maskOR_msb = 0; + maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0; + if (flags & LTM_PRIME_2MSB_ON) { + maskOR_msb |= 0x80 >> ((9 - size) & 7); + } + + /* get the maskOR_lsb */ + maskOR_lsb = 1; + if (flags & LTM_PRIME_BBS) { + maskOR_lsb |= 3; + } + + do { + /* read the bytes */ + if (cb(tmp, bsize, dat) != bsize) { + err = MP_VAL; + goto error; + } + + /* work over the MSbyte */ + tmp[0] &= maskAND; + tmp[0] |= 1 << ((size - 1) & 7); + + /* mix in the maskORs */ + tmp[maskOR_msb_offset] |= maskOR_msb; + tmp[bsize-1] |= maskOR_lsb; + + /* read it in */ + if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; } + + /* is it prime? */ + if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } + if (res == MP_NO) { + continue; + } + + if (flags & LTM_PRIME_SAFE) { + /* see if (a-1)/2 is prime */ + if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { goto error; } + if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; } + + /* is it prime? */ + if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } + } + } while (res == MP_NO); + + if (flags & LTM_PRIME_SAFE) { + /* restore a to the original value */ + if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; } + if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { goto error; } + } + + err = MP_OKAY; +error: + XFREE(tmp); + return err; +} + + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_prime_random_ex.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_radix_size.c b/StormLib/src/libtommath/bn_mp_radix_size.c new file mode 100644 index 000000000..2378f1fc1 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_radix_size.c @@ -0,0 +1,78 @@ +#include "tommath.h" +#ifdef BN_MP_RADIX_SIZE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* returns size of ASCII reprensentation */ +int mp_radix_size (mp_int * a, int radix, int *size) +{ + int res, digs; + mp_int t; + mp_digit d; + + *size = 0; + + /* special case for binary */ + if (radix == 2) { + *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1; + return MP_OKAY; + } + + /* make sure the radix is in range */ + if (radix < 2 || radix > 64) { + return MP_VAL; + } + + if (mp_iszero(a) == MP_YES) { + *size = 2; + return MP_OKAY; + } + + /* digs is the digit count */ + digs = 0; + + /* if it's negative add one for the sign */ + if (a->sign == MP_NEG) { + ++digs; + } + + /* init a copy of the input */ + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + /* force temp to positive */ + t.sign = MP_ZPOS; + + /* fetch out all of the digits */ + while (mp_iszero (&t) == MP_NO) { + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return res; + } + ++digs; + } + mp_clear (&t); + + /* return digs + 1, the 1 is for the NULL byte that would be required. */ + *size = digs + 1; + return MP_OKAY; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_radix_size.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_radix_smap.c b/StormLib/src/libtommath/bn_mp_radix_smap.c new file mode 100644 index 000000000..5cbe9520b --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_radix_smap.c @@ -0,0 +1,24 @@ +#include "tommath.h" +#ifdef BN_MP_RADIX_SMAP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* chars used in radix conversions */ +const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_radix_smap.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_rand.c b/StormLib/src/libtommath/bn_mp_rand.c new file mode 100644 index 000000000..e1241785e --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_rand.c @@ -0,0 +1,55 @@ +#include "tommath.h" +#ifdef BN_MP_RAND_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* makes a pseudo-random int of a given size */ +int +mp_rand (mp_int * a, int digits) +{ + int res; + mp_digit d; + + mp_zero (a); + if (digits <= 0) { + return MP_OKAY; + } + + /* first place a random non-zero digit */ + do { + d = ((mp_digit) abs (rand ())) & MP_MASK; + } while (d == 0); + + if ((res = mp_add_d (a, d, a)) != MP_OKAY) { + return res; + } + + while (--digits > 0) { + if ((res = mp_lshd (a, 1)) != MP_OKAY) { + return res; + } + + if ((res = mp_add_d (a, ((mp_digit) abs (rand ())), a)) != MP_OKAY) { + return res; + } + } + + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_rand.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_read_radix.c b/StormLib/src/libtommath/bn_mp_read_radix.c new file mode 100644 index 000000000..6869668fb --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_read_radix.c @@ -0,0 +1,85 @@ +#include "tommath.h" +#ifdef BN_MP_READ_RADIX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* read a string [ASCII] in a given radix */ +int mp_read_radix (mp_int * a, const char *str, int radix) +{ + int y, res, neg; + char ch; + + /* zero the digit bignum */ + mp_zero(a); + + /* make sure the radix is ok */ + if (radix < 2 || radix > 64) { + return MP_VAL; + } + + /* if the leading digit is a + * minus set the sign to negative. + */ + if (*str == '-') { + ++str; + neg = MP_NEG; + } else { + neg = MP_ZPOS; + } + + /* set the integer to the default of zero */ + mp_zero (a); + + /* process each digit of the string */ + while (*str) { + /* if the radix < 36 the conversion is case insensitive + * this allows numbers like 1AB and 1ab to represent the same value + * [e.g. in hex] + */ + ch = (char) ((radix < 36) ? toupper (*str) : *str); + for (y = 0; y < 64; y++) { + if (ch == mp_s_rmap[y]) { + break; + } + } + + /* if the char was found in the map + * and is less than the given radix add it + * to the number, otherwise exit the loop. + */ + if (y < radix) { + if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { + return res; + } + if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { + return res; + } + } else { + break; + } + ++str; + } + + /* set the sign only if a != 0 */ + if (mp_iszero(a) != 1) { + a->sign = neg; + } + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_read_radix.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_read_signed_bin.c b/StormLib/src/libtommath/bn_mp_read_signed_bin.c new file mode 100644 index 000000000..e9a780c28 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_read_signed_bin.c @@ -0,0 +1,41 @@ +#include "tommath.h" +#ifdef BN_MP_READ_SIGNED_BIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* read signed bin, big endian, first byte is 0==positive or 1==negative */ +int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c) +{ + int res; + + /* read magnitude */ + if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) { + return res; + } + + /* first byte is 0 for positive, non-zero for negative */ + if (b[0] == 0) { + a->sign = MP_ZPOS; + } else { + a->sign = MP_NEG; + } + + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_read_signed_bin.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_read_unsigned_bin.c b/StormLib/src/libtommath/bn_mp_read_unsigned_bin.c new file mode 100644 index 000000000..7d3537041 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_read_unsigned_bin.c @@ -0,0 +1,55 @@ +#include "tommath.h" +#ifdef BN_MP_READ_UNSIGNED_BIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reads a unsigned char array, assumes the msb is stored first [big endian] */ +int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) +{ + int res; + + /* make sure there are at least two digits */ + if (a->alloc < 2) { + if ((res = mp_grow(a, 2)) != MP_OKAY) { + return res; + } + } + + /* zero the int */ + mp_zero (a); + + /* read the bytes in */ + while (c-- > 0) { + if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) { + return res; + } + +#ifndef MP_8BIT + a->dp[0] |= *b++; + a->used += 1; +#else + a->dp[0] = (*b & MP_MASK); + a->dp[1] |= ((*b++ >> 7U) & 1); + a->used += 2; +#endif + } + mp_clamp (a); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_read_unsigned_bin.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_reduce.c b/StormLib/src/libtommath/bn_mp_reduce.c new file mode 100644 index 000000000..3a6bb5aca --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_reduce.c @@ -0,0 +1,100 @@ +#include "tommath.h" +#ifdef BN_MP_REDUCE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reduces x mod m, assumes 0 < x < m**2, mu is + * precomputed via mp_reduce_setup. + * From HAC pp.604 Algorithm 14.42 + */ +int mp_reduce (mp_int * x, mp_int * m, mp_int * mu) +{ + mp_int q; + int res, um = m->used; + + /* q = x */ + if ((res = mp_init_copy (&q, x)) != MP_OKAY) { + return res; + } + + /* q1 = x / b**(k-1) */ + mp_rshd (&q, um - 1); + + /* according to HAC this optimization is ok */ + if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { + if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) { + goto CLEANUP; + } + } else { +#ifdef BN_S_MP_MUL_HIGH_DIGS_C + if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { + goto CLEANUP; + } +#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) + if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { + goto CLEANUP; + } +#else + { + res = MP_VAL; + goto CLEANUP; + } +#endif + } + + /* q3 = q2 / b**(k+1) */ + mp_rshd (&q, um + 1); + + /* x = x mod b**(k+1), quick (no division) */ + if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { + goto CLEANUP; + } + + /* q = q * m mod b**(k+1), quick (no division) */ + if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) { + goto CLEANUP; + } + + /* x = x - q */ + if ((res = mp_sub (x, &q, x)) != MP_OKAY) { + goto CLEANUP; + } + + /* If x < 0, add b**(k+1) to it */ + if (mp_cmp_d (x, 0) == MP_LT) { + mp_set (&q, 1); + if ((res = mp_lshd (&q, um + 1)) != MP_OKAY) + goto CLEANUP; + if ((res = mp_add (x, &q, x)) != MP_OKAY) + goto CLEANUP; + } + + /* Back off if it's too big */ + while (mp_cmp (x, m) != MP_LT) { + if ((res = s_mp_sub (x, m, x)) != MP_OKAY) { + goto CLEANUP; + } + } + +CLEANUP: + mp_clear (&q); + + return res; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_reduce.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_reduce_2k.c b/StormLib/src/libtommath/bn_mp_reduce_2k.c new file mode 100644 index 000000000..3191d8291 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_reduce_2k.c @@ -0,0 +1,61 @@ +#include "tommath.h" +#ifdef BN_MP_REDUCE_2K_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reduces a modulo n where n is of the form 2**p - d */ +int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d) +{ + mp_int q; + int p, res; + + if ((res = mp_init(&q)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(n); +top: + /* q = a/2**p, a = a mod 2**p */ + if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (d != 1) { + /* q = q * d */ + if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) { + goto ERR; + } + } + + /* a = a + q */ + if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (mp_cmp_mag(a, n) != MP_LT) { + s_mp_sub(a, n, a); + goto top; + } + +ERR: + mp_clear(&q); + return res; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_reduce_2k_l.c b/StormLib/src/libtommath/bn_mp_reduce_2k_l.c new file mode 100644 index 000000000..49b7e344e --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_reduce_2k_l.c @@ -0,0 +1,62 @@ +#include "tommath.h" +#ifdef BN_MP_REDUCE_2K_L_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reduces a modulo n where n is of the form 2**p - d + This differs from reduce_2k since "d" can be larger + than a single digit. +*/ +int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d) +{ + mp_int q; + int p, res; + + if ((res = mp_init(&q)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(n); +top: + /* q = a/2**p, a = a mod 2**p */ + if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + goto ERR; + } + + /* q = q * d */ + if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { + goto ERR; + } + + /* a = a + q */ + if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (mp_cmp_mag(a, n) != MP_LT) { + s_mp_sub(a, n, a); + goto top; + } + +ERR: + mp_clear(&q); + return res; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k_l.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_reduce_2k_setup.c b/StormLib/src/libtommath/bn_mp_reduce_2k_setup.c new file mode 100644 index 000000000..aa3b3bad8 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_reduce_2k_setup.c @@ -0,0 +1,47 @@ +#include "tommath.h" +#ifdef BN_MP_REDUCE_2K_SETUP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines the setup value */ +int mp_reduce_2k_setup(mp_int *a, mp_digit *d) +{ + int res, p; + mp_int tmp; + + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(a); + if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + *d = tmp.dp[0]; + mp_clear(&tmp); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k_setup.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_reduce_2k_setup_l.c b/StormLib/src/libtommath/bn_mp_reduce_2k_setup_l.c new file mode 100644 index 000000000..4eca87040 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_reduce_2k_setup_l.c @@ -0,0 +1,44 @@ +#include "tommath.h" +#ifdef BN_MP_REDUCE_2K_SETUP_L_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines the setup value */ +int mp_reduce_2k_setup_l(mp_int *a, mp_int *d) +{ + int res; + mp_int tmp; + + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; + } + + if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) { + goto ERR; + } + + if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear(&tmp); + return res; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k_setup_l.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_reduce_is_2k.c b/StormLib/src/libtommath/bn_mp_reduce_is_2k.c new file mode 100644 index 000000000..b9ede9789 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_reduce_is_2k.c @@ -0,0 +1,52 @@ +#include "tommath.h" +#ifdef BN_MP_REDUCE_IS_2K_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines if mp_reduce_2k can be used */ +int mp_reduce_is_2k(mp_int *a) +{ + int ix, iy, iw; + mp_digit iz; + + if (a->used == 0) { + return MP_NO; + } else if (a->used == 1) { + return MP_YES; + } else if (a->used > 1) { + iy = mp_count_bits(a); + iz = 1; + iw = 1; + + /* Test every bit from the second digit up, must be 1 */ + for (ix = DIGIT_BIT; ix < iy; ix++) { + if ((a->dp[iw] & iz) == 0) { + return MP_NO; + } + iz <<= 1; + if (iz > (mp_digit)MP_MASK) { + ++iw; + iz = 1; + } + } + } + return MP_YES; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_is_2k.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_reduce_is_2k_l.c b/StormLib/src/libtommath/bn_mp_reduce_is_2k_l.c new file mode 100644 index 000000000..787875f8b --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_reduce_is_2k_l.c @@ -0,0 +1,44 @@ +#include "tommath.h" +#ifdef BN_MP_REDUCE_IS_2K_L_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* determines if reduce_2k_l can be used */ +int mp_reduce_is_2k_l(mp_int *a) +{ + int ix, iy; + + if (a->used == 0) { + return MP_NO; + } else if (a->used == 1) { + return MP_YES; + } else if (a->used > 1) { + /* if more than half of the digits are -1 we're sold */ + for (iy = ix = 0; ix < a->used; ix++) { + if (a->dp[ix] == MP_MASK) { + ++iy; + } + } + return (iy >= (a->used/2)) ? MP_YES : MP_NO; + + } + return MP_NO; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_is_2k_l.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_reduce_setup.c b/StormLib/src/libtommath/bn_mp_reduce_setup.c new file mode 100644 index 000000000..00e0a62b9 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_reduce_setup.c @@ -0,0 +1,34 @@ +#include "tommath.h" +#ifdef BN_MP_REDUCE_SETUP_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* pre-calculate the value required for Barrett reduction + * For a given modulus "b" it calulates the value required in "a" + */ +int mp_reduce_setup (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { + return res; + } + return mp_div (a, b, a, NULL); +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_setup.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_rshd.c b/StormLib/src/libtommath/bn_mp_rshd.c new file mode 100644 index 000000000..eac6721ba --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_rshd.c @@ -0,0 +1,72 @@ +#include "tommath.h" +#ifdef BN_MP_RSHD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* shift right a certain amount of digits */ +void mp_rshd (mp_int * a, int b) +{ + int x; + + /* if b <= 0 then ignore it */ + if (b <= 0) { + return; + } + + /* if b > used then simply zero it and return */ + if (a->used <= b) { + mp_zero (a); + return; + } + + { + register mp_digit *bottom, *top; + + /* shift the digits down */ + + /* bottom */ + bottom = a->dp; + + /* top [offset into digits] */ + top = a->dp + b; + + /* this is implemented as a sliding window where + * the window is b-digits long and digits from + * the top of the window are copied to the bottom + * + * e.g. + + b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> + /\ | ----> + \-------------------/ ----> + */ + for (x = 0; x < (a->used - b); x++) { + *bottom++ = *top++; + } + + /* zero the top digits */ + for (; x < a->used; x++) { + *bottom++ = 0; + } + } + + /* remove excess digits */ + a->used -= b; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_rshd.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_set.c b/StormLib/src/libtommath/bn_mp_set.c new file mode 100644 index 000000000..d76d5bbd3 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_set.c @@ -0,0 +1,29 @@ +#include "tommath.h" +#ifdef BN_MP_SET_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* set to a digit */ +void mp_set (mp_int * a, mp_digit b) +{ + mp_zero (a); + a->dp[0] = b & MP_MASK; + a->used = (a->dp[0] != 0) ? 1 : 0; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_set.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_set_int.c b/StormLib/src/libtommath/bn_mp_set_int.c new file mode 100644 index 000000000..68cf0e32b --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_set_int.c @@ -0,0 +1,48 @@ +#include "tommath.h" +#ifdef BN_MP_SET_INT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* set a 32-bit const */ +int mp_set_int (mp_int * a, unsigned long b) +{ + int x, res; + + mp_zero (a); + + /* set four bits at a time */ + for (x = 0; x < 8; x++) { + /* shift the number up four bits */ + if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { + return res; + } + + /* OR in the top four bits of the source */ + a->dp[0] |= (b >> 28) & 15; + + /* shift the source up to the next four bits */ + b <<= 4; + + /* ensure that digits are not clamped off */ + a->used += 1; + } + mp_clamp (a); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_set_int.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_shrink.c b/StormLib/src/libtommath/bn_mp_shrink.c new file mode 100644 index 000000000..54920d140 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_shrink.c @@ -0,0 +1,35 @@ +#include "tommath.h" +#ifdef BN_MP_SHRINK_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* shrink a bignum */ +int mp_shrink (mp_int * a) +{ + mp_digit *tmp; + if (a->alloc != a->used && a->used > 0) { + if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * a->used)) == NULL) { + return MP_MEM; + } + a->dp = tmp; + a->alloc = a->used; + } + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_shrink.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_signed_bin_size.c b/StormLib/src/libtommath/bn_mp_signed_bin_size.c new file mode 100644 index 000000000..b9492a5e5 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_signed_bin_size.c @@ -0,0 +1,27 @@ +#include "tommath.h" +#ifdef BN_MP_SIGNED_BIN_SIZE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* get the size for an signed equivalent */ +int mp_signed_bin_size (mp_int * a) +{ + return 1 + mp_unsigned_bin_size (a); +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_signed_bin_size.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_sqr.c b/StormLib/src/libtommath/bn_mp_sqr.c new file mode 100644 index 000000000..c10fa6f3b --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_sqr.c @@ -0,0 +1,58 @@ +#include "tommath.h" +#ifdef BN_MP_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* computes b = a*a */ +int +mp_sqr (mp_int * a, mp_int * b) +{ + int res; + +#ifdef BN_MP_TOOM_SQR_C + /* use Toom-Cook? */ + if (a->used >= TOOM_SQR_CUTOFF) { + res = mp_toom_sqr(a, b); + /* Karatsuba? */ + } else +#endif +#ifdef BN_MP_KARATSUBA_SQR_C +if (a->used >= KARATSUBA_SQR_CUTOFF) { + res = mp_karatsuba_sqr (a, b); + } else +#endif + { +#ifdef BN_FAST_S_MP_SQR_C + /* can we use the fast comba multiplier? */ + if ((a->used * 2 + 1) < MP_WARRAY && + a->used < + (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) { + res = fast_s_mp_sqr (a, b); + } else +#endif +#ifdef BN_S_MP_SQR_C + res = s_mp_sqr (a, b); +#else + res = MP_VAL; +#endif + } + b->sign = MP_ZPOS; + return res; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_sqr.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_sqrmod.c b/StormLib/src/libtommath/bn_mp_sqrmod.c new file mode 100644 index 000000000..5f4b2f3d6 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_sqrmod.c @@ -0,0 +1,41 @@ +#include "tommath.h" +#ifdef BN_MP_SQRMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* c = a * a (mod b) */ +int +mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_sqr (a, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, b, c); + mp_clear (&t); + return res; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_sqrmod.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_sqrt.c b/StormLib/src/libtommath/bn_mp_sqrt.c new file mode 100644 index 000000000..e15ba98ca --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_sqrt.c @@ -0,0 +1,81 @@ +#include "tommath.h" +#ifdef BN_MP_SQRT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* this function is less generic than mp_n_root, simpler and faster */ +int mp_sqrt(mp_int *arg, mp_int *ret) +{ + int res; + mp_int t1,t2; + + /* must be positive */ + if (arg->sign == MP_NEG) { + return MP_VAL; + } + + /* easy out */ + if (mp_iszero(arg) == MP_YES) { + mp_zero(ret); + return MP_OKAY; + } + + if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) { + return res; + } + + if ((res = mp_init(&t2)) != MP_OKAY) { + goto E2; + } + + /* First approx. (not very bad for large arg) */ + mp_rshd (&t1,t1.used/2); + + /* t1 > 0 */ + if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { + goto E1; + } + if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { + goto E1; + } + if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { + goto E1; + } + /* And now t1 > sqrt(arg) */ + do { + if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { + goto E1; + } + if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { + goto E1; + } + if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { + goto E1; + } + /* t1 >= sqrt(arg) >= t2 at this point */ + } while (mp_cmp_mag(&t1,&t2) == MP_GT); + + mp_exch(&t1,ret); + +E1: mp_clear(&t2); +E2: mp_clear(&t1); + return res; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_sqrt.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_sub.c b/StormLib/src/libtommath/bn_mp_sub.c new file mode 100644 index 000000000..6e7213861 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_sub.c @@ -0,0 +1,59 @@ +#include "tommath.h" +#ifdef BN_MP_SUB_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* high level subtraction (handles signs) */ +int +mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + sa = a->sign; + sb = b->sign; + + if (sa != sb) { + /* subtract a negative from a positive, OR */ + /* subtract a positive from a negative. */ + /* In either case, ADD their magnitudes, */ + /* and use the sign of the first number. */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* subtract a positive from a positive, OR */ + /* subtract a negative from a negative. */ + /* First, take the difference between their */ + /* magnitudes, then... */ + if (mp_cmp_mag (a, b) != MP_LT) { + /* Copy the sign from the first */ + c->sign = sa; + /* The first has a larger or equal magnitude */ + res = s_mp_sub (a, b, c); + } else { + /* The result has the *opposite* sign from */ + /* the first number. */ + c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; + /* The second has a larger magnitude */ + res = s_mp_sub (b, a, c); + } + } + return res; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_sub.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_sub_d.c b/StormLib/src/libtommath/bn_mp_sub_d.c new file mode 100644 index 000000000..aa08e31b3 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_sub_d.c @@ -0,0 +1,93 @@ +#include "tommath.h" +#ifdef BN_MP_SUB_D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* single digit subtraction */ +int +mp_sub_d (mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit *tmpa, *tmpc, mu; + int res, ix, oldused; + + /* grow c as required */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* if a is negative just do an unsigned + * addition [with fudged signs] + */ + if (a->sign == MP_NEG) { + a->sign = MP_ZPOS; + res = mp_add_d(a, b, c); + a->sign = c->sign = MP_NEG; + + /* clamp */ + mp_clamp(c); + + return res; + } + + /* setup regs */ + oldused = c->used; + tmpa = a->dp; + tmpc = c->dp; + + /* if a <= b simply fix the single digit */ + if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) { + if (a->used == 1) { + *tmpc++ = b - *tmpa; + } else { + *tmpc++ = b; + } + ix = 1; + + /* negative/1digit */ + c->sign = MP_NEG; + c->used = 1; + } else { + /* positive/size */ + c->sign = MP_ZPOS; + c->used = a->used; + + /* subtract first digit */ + *tmpc = *tmpa++ - b; + mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); + *tmpc++ &= MP_MASK; + + /* handle rest of the digits */ + for (ix = 1; ix < a->used; ix++) { + *tmpc = *tmpa++ - mu; + mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); + *tmpc++ &= MP_MASK; + } + } + + /* zero excess digits */ + while (ix++ < oldused) { + *tmpc++ = 0; + } + mp_clamp(c); + return MP_OKAY; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_sub_d.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_submod.c b/StormLib/src/libtommath/bn_mp_submod.c new file mode 100644 index 000000000..6617ff42c --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_submod.c @@ -0,0 +1,42 @@ +#include "tommath.h" +#ifdef BN_MP_SUBMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* d = a - b (mod c) */ +int +mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_sub (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_submod.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_to_signed_bin.c b/StormLib/src/libtommath/bn_mp_to_signed_bin.c new file mode 100644 index 000000000..154f64b56 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_to_signed_bin.c @@ -0,0 +1,33 @@ +#include "tommath.h" +#ifdef BN_MP_TO_SIGNED_BIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* store in signed [big endian] format */ +int mp_to_signed_bin (mp_int * a, unsigned char *b) +{ + int res; + + if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) { + return res; + } + b[0] = (unsigned char) ((a->sign == MP_ZPOS) ? 0 : 1); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_to_signed_bin.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_to_signed_bin_n.c b/StormLib/src/libtommath/bn_mp_to_signed_bin_n.c new file mode 100644 index 000000000..e119c380a --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_to_signed_bin_n.c @@ -0,0 +1,31 @@ +#include "tommath.h" +#ifdef BN_MP_TO_SIGNED_BIN_N_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* store in signed [big endian] format */ +int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) +{ + if (*outlen < (unsigned long)mp_signed_bin_size(a)) { + return MP_VAL; + } + *outlen = mp_signed_bin_size(a); + return mp_to_signed_bin(a, b); +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_to_signed_bin_n.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_to_unsigned_bin.c b/StormLib/src/libtommath/bn_mp_to_unsigned_bin.c new file mode 100644 index 000000000..ce69e5bf3 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_to_unsigned_bin.c @@ -0,0 +1,48 @@ +#include "tommath.h" +#ifdef BN_MP_TO_UNSIGNED_BIN_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* store in unsigned [big endian] format */ +int mp_to_unsigned_bin (mp_int * a, unsigned char *b) +{ + int x, res; + mp_int t; + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + x = 0; + while (mp_iszero (&t) == 0) { +#ifndef MP_8BIT + b[x++] = (unsigned char) (t.dp[0] & 255); +#else + b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7)); +#endif + if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + bn_reverse (b, x); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_to_unsigned_bin.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_to_unsigned_bin_n.c b/StormLib/src/libtommath/bn_mp_to_unsigned_bin_n.c new file mode 100644 index 000000000..dfa27c41b --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_to_unsigned_bin_n.c @@ -0,0 +1,31 @@ +#include "tommath.h" +#ifdef BN_MP_TO_UNSIGNED_BIN_N_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* store in unsigned [big endian] format */ +int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) +{ + if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) { + return MP_VAL; + } + *outlen = mp_unsigned_bin_size(a); + return mp_to_unsigned_bin(a, b); +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_to_unsigned_bin_n.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_toom_mul.c b/StormLib/src/libtommath/bn_mp_toom_mul.c new file mode 100644 index 000000000..e48c6b355 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_toom_mul.c @@ -0,0 +1,284 @@ +#include "tommath.h" +#ifdef BN_MP_TOOM_MUL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* multiplication using the Toom-Cook 3-way algorithm + * + * Much more complicated than Karatsuba but has a lower + * asymptotic running time of O(N**1.464). This algorithm is + * only particularly useful on VERY large inputs + * (we're talking 1000s of digits here...). +*/ +int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) +{ + mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = MIN(a->used, b->used) / 3; + + /* a = a2 * B**2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a1, B); + mp_mod_2d(&a1, DIGIT_BIT * B, &a1); + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a2, B*2); + + /* b = b2 * B**2 + b1 * B + b0 */ + if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(b, &b1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&b1, B); + mp_mod_2d(&b1, DIGIT_BIT * B, &b1); + + if ((res = mp_copy(b, &b2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&b2, B*2); + + /* w0 = a0*b0 */ + if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) { + goto ERR; + } + + /* w4 = a2 * b2 */ + if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) { + goto ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) { + goto ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) { + goto ERR; + } + + + /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) { + goto ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, + 2 small divisions and 1 small multiplication + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL); + return res; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_toom_mul.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_toom_sqr.c b/StormLib/src/libtommath/bn_mp_toom_sqr.c new file mode 100644 index 000000000..fd8bc672a --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_toom_sqr.c @@ -0,0 +1,226 @@ +#include "tommath.h" +#ifdef BN_MP_TOOM_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* squaring using Toom-Cook 3-way algorithm */ +int +mp_toom_sqr(mp_int *a, mp_int *b) +{ + mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = a->used / 3; + + /* a = a2 * B**2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a1, B); + mp_mod_2d(&a1, DIGIT_BIT * B, &a1); + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a2, B*2); + + /* w0 = a0*a0 */ + if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { + goto ERR; + } + + /* w4 = a2 * a2 */ + if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { + goto ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))**2 */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))**2 */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + + + /* w2 = (a2 + a1 + a0)**2 */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { + goto ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); + return res; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_toom_sqr.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_toradix.c b/StormLib/src/libtommath/bn_mp_toradix.c new file mode 100644 index 000000000..539abe9ba --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_toradix.c @@ -0,0 +1,75 @@ +#include "tommath.h" +#ifdef BN_MP_TORADIX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* stores a bignum as a ASCII string in a given radix (2..64) */ +int mp_toradix (mp_int * a, char *str, int radix) +{ + int res, digs; + mp_int t; + mp_digit d; + char *_s = str; + + /* check range of the radix */ + if (radix < 2 || radix > 64) { + return MP_VAL; + } + + /* quick out if its zero */ + if (mp_iszero(a) == 1) { + *str++ = '0'; + *str = '\0'; + return MP_OKAY; + } + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + /* if it is negative output a - */ + if (t.sign == MP_NEG) { + ++_s; + *str++ = '-'; + t.sign = MP_ZPOS; + } + + digs = 0; + while (mp_iszero (&t) == 0) { + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return res; + } + *str++ = mp_s_rmap[d]; + ++digs; + } + + /* reverse the digits of the string. In this case _s points + * to the first digit [exluding the sign] of the number] + */ + bn_reverse ((unsigned char *)_s, digs); + + /* append a NULL so the string is properly terminated */ + *str = '\0'; + + mp_clear (&t); + return MP_OKAY; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_toradix.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_toradix_n.c b/StormLib/src/libtommath/bn_mp_toradix_n.c new file mode 100644 index 000000000..0322f8d4b --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_toradix_n.c @@ -0,0 +1,88 @@ +#include "tommath.h" +#ifdef BN_MP_TORADIX_N_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* stores a bignum as a ASCII string in a given radix (2..64) + * + * Stores upto maxlen-1 chars and always a NULL byte + */ +int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen) +{ + int res, digs; + mp_int t; + mp_digit d; + char *_s = str; + + /* check range of the maxlen, radix */ + if (maxlen < 2 || radix < 2 || radix > 64) { + return MP_VAL; + } + + /* quick out if its zero */ + if (mp_iszero(a) == MP_YES) { + *str++ = '0'; + *str = '\0'; + return MP_OKAY; + } + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + /* if it is negative output a - */ + if (t.sign == MP_NEG) { + /* we have to reverse our digits later... but not the - sign!! */ + ++_s; + + /* store the flag and mark the number as positive */ + *str++ = '-'; + t.sign = MP_ZPOS; + + /* subtract a char */ + --maxlen; + } + + digs = 0; + while (mp_iszero (&t) == 0) { + if (--maxlen < 1) { + /* no more room */ + break; + } + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return res; + } + *str++ = mp_s_rmap[d]; + ++digs; + } + + /* reverse the digits of the string. In this case _s points + * to the first digit [exluding the sign] of the number + */ + bn_reverse ((unsigned char *)_s, digs); + + /* append a NULL so the string is properly terminated */ + *str = '\0'; + + mp_clear (&t); + return MP_OKAY; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_toradix_n.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_unsigned_bin_size.c b/StormLib/src/libtommath/bn_mp_unsigned_bin_size.c new file mode 100644 index 000000000..88f3e92dd --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_unsigned_bin_size.c @@ -0,0 +1,28 @@ +#include "tommath.h" +#ifdef BN_MP_UNSIGNED_BIN_SIZE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* get the size for an unsigned equivalent */ +int mp_unsigned_bin_size (mp_int * a) +{ + int size = mp_count_bits (a); + return (size / 8 + ((size & 7) != 0 ? 1 : 0)); +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_unsigned_bin_size.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_xor.c b/StormLib/src/libtommath/bn_mp_xor.c new file mode 100644 index 000000000..bf0446ecf --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_xor.c @@ -0,0 +1,51 @@ +#include "tommath.h" +#ifdef BN_MP_XOR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* XOR two ints together */ +int +mp_xor (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] ^= x->dp[ix]; + } + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_xor.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_mp_zero.c b/StormLib/src/libtommath/bn_mp_zero.c new file mode 100644 index 000000000..f21db5ed5 --- /dev/null +++ b/StormLib/src/libtommath/bn_mp_zero.c @@ -0,0 +1,36 @@ +#include "tommath.h" +#ifdef BN_MP_ZERO_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* set to zero */ +void mp_zero (mp_int * a) +{ + int n; + mp_digit *tmp; + + a->sign = MP_ZPOS; + a->used = 0; + + tmp = a->dp; + for (n = 0; n < a->alloc; n++) { + *tmp++ = 0; + } +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_zero.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_prime_tab.c b/StormLib/src/libtommath/bn_prime_tab.c new file mode 100644 index 000000000..7d306dd56 --- /dev/null +++ b/StormLib/src/libtommath/bn_prime_tab.c @@ -0,0 +1,61 @@ +#include "tommath.h" +#ifdef BN_PRIME_TAB_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +const mp_digit ltm_prime_tab[] = { + 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, + 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, + 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, + 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, +#ifndef MP_8BIT + 0x0083, + 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, + 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, + 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, + 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, + + 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, + 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, + 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, + 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, + 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, + 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, + 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, + 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, + + 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, + 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, + 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, + 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, + 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, + 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, + 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, + 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, + + 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, + 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, + 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, + 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, + 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, + 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, + 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, + 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 +#endif +}; +#endif + +/* $Source: /cvs/libtom/libtommath/bn_prime_tab.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_reverse.c b/StormLib/src/libtommath/bn_reverse.c new file mode 100644 index 000000000..d4a919af4 --- /dev/null +++ b/StormLib/src/libtommath/bn_reverse.c @@ -0,0 +1,39 @@ +#include "tommath.h" +#ifdef BN_REVERSE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* reverse an array, used for radix code */ +void +bn_reverse (unsigned char *s, int len) +{ + int ix, iy; + unsigned char t; + + ix = 0; + iy = len - 1; + while (ix < iy) { + t = s[ix]; + s[ix] = s[iy]; + s[iy] = t; + ++ix; + --iy; + } +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_reverse.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_s_mp_add.c b/StormLib/src/libtommath/bn_s_mp_add.c new file mode 100644 index 000000000..5ea9c6d20 --- /dev/null +++ b/StormLib/src/libtommath/bn_s_mp_add.c @@ -0,0 +1,109 @@ +#include "tommath.h" +#ifdef BN_S_MP_ADD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* low level addition, based on HAC pp.594, Algorithm 14.7 */ +int +s_mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int *x; + int olduse, res, min, max; + + /* find sizes, we let |a| <= |b| which means we have to sort + * them. "x" will point to the input with the most digits + */ + if (a->used > b->used) { + min = b->used; + max = a->used; + x = a; + } else { + min = a->used; + max = b->used; + x = b; + } + + /* init result */ + if (c->alloc < max + 1) { + if ((res = mp_grow (c, max + 1)) != MP_OKAY) { + return res; + } + } + + /* get old used digit count and set new one */ + olduse = c->used; + c->used = max + 1; + + { + register mp_digit u, *tmpa, *tmpb, *tmpc; + register int i; + + /* alias for digit pointers */ + + /* first input */ + tmpa = a->dp; + + /* second input */ + tmpb = b->dp; + + /* destination */ + tmpc = c->dp; + + /* zero the carry */ + u = 0; + for (i = 0; i < min; i++) { + /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ + *tmpc = *tmpa++ + *tmpb++ + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, that is in A+B + * if A or B has more digits add those in + */ + if (min != max) { + for (; i < max; i++) { + /* T[i] = X[i] + U */ + *tmpc = x->dp[i] + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + } + + /* add carry */ + *tmpc++ = u; + + /* clear digits above oldused */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_s_mp_add.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_s_mp_exptmod.c b/StormLib/src/libtommath/bn_s_mp_exptmod.c new file mode 100644 index 000000000..9fb2da8fd --- /dev/null +++ b/StormLib/src/libtommath/bn_s_mp_exptmod.c @@ -0,0 +1,252 @@ +#include "tommath.h" +#ifdef BN_S_MP_EXPTMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ +#ifdef MP_LOW_MEM + #define TAB_SIZE 32 +#else + #define TAB_SIZE 256 +#endif + +int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) +{ + mp_int M[TAB_SIZE], res, mu; + mp_digit buf; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + int (*redux)(mp_int*,mp_int*,mp_int*); + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* create mu, used for Barrett reduction */ + if ((err = mp_init (&mu)) != MP_OKAY) { + goto LBL_M; + } + + if (redmode == 0) { + if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { + goto LBL_MU; + } + redux = mp_reduce; + } else { + if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + redux = mp_reduce_2k_l; + } + + /* create M table + * + * The M table contains powers of the base, + * e.g. M[x] = G**x mod P + * + * The first half of the table is not + * computed though accept for M[0] and M[1] + */ + if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { + goto LBL_MU; + } + + /* compute the value at M[1<<(winsize-1)] by squaring + * M[1] (winsize-1) times + */ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_MU; + } + + for (x = 0; x < (winsize - 1); x++) { + /* square it */ + if ((err = mp_sqr (&M[1 << (winsize - 1)], + &M[1 << (winsize - 1)])) != MP_OKAY) { + goto LBL_MU; + } + + /* reduce modulo P */ + if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + } + + /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) + * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) + */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto LBL_MU; + } + if ((err = redux (&M[x], P, &mu)) != MP_OKAY) { + goto LBL_MU; + } + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto LBL_MU; + } + mp_set (&res, 1); + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits */ + if (digidx == -1) { + break; + } + /* read next digit and reset the bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int) DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto LBL_RES; + } + if ((err = redux (&res, P, &mu)) != MP_OKAY) { + goto LBL_RES; + } + } + } + } + + mp_exch (&res, Y); + err = MP_OKAY; +LBL_RES:mp_clear (&res); +LBL_MU:mp_clear (&mu); +LBL_M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_s_mp_exptmod.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_s_mp_mul_digs.c b/StormLib/src/libtommath/bn_s_mp_mul_digs.c new file mode 100644 index 000000000..f04dacfb9 --- /dev/null +++ b/StormLib/src/libtommath/bn_s_mp_mul_digs.c @@ -0,0 +1,90 @@ +#include "tommath.h" +#ifdef BN_S_MP_MUL_DIGS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* multiplies |a| * |b| and only computes upto digs digits of result + * HAC pp. 595, Algorithm 14.12 Modified so you can control how + * many digits of output are created. + */ +int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ + if (((digs) < MP_WARRAY) && + MIN (a->used, b->used) < + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_s_mp_mul_digs (a, b, c, digs); + } + + if ((res = mp_init_size (&t, digs)) != MP_OKAY) { + return res; + } + t.used = digs; + + /* compute the digits of the product directly */ + pa = a->used; + for (ix = 0; ix < pa; ix++) { + /* set the carry to zero */ + u = 0; + + /* limit ourselves to making digs digits of output */ + pb = MIN (b->used, digs - ix); + + /* setup some aliases */ + /* copy of the digit from a used within the nested loop */ + tmpx = a->dp[ix]; + + /* an alias for the destination shifted ix places */ + tmpt = t.dp + ix; + + /* an alias for the digits of b */ + tmpy = b->dp; + + /* compute the columns of the output and propagate the carry */ + for (iy = 0; iy < pb; iy++) { + /* compute the column as a mp_word */ + r = ((mp_word)*tmpt) + + ((mp_word)tmpx) * ((mp_word)*tmpy++) + + ((mp_word) u); + + /* the new column is the lower part of the result */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry word from the result */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + /* set carry if it is placed below digs */ + if (ix + iy < digs) { + *tmpt = u; + } + } + + mp_clamp (&t); + mp_exch (&t, c); + + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_s_mp_mul_digs.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_s_mp_mul_high_digs.c b/StormLib/src/libtommath/bn_s_mp_mul_high_digs.c new file mode 100644 index 000000000..b1d019925 --- /dev/null +++ b/StormLib/src/libtommath/bn_s_mp_mul_high_digs.c @@ -0,0 +1,81 @@ +#include "tommath.h" +#ifdef BN_S_MP_MUL_HIGH_DIGS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* multiplies |a| * |b| and does not compute the lower digs digits + * [meant to get the higher part of the product] + */ +int +s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ +#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C + if (((a->used + b->used + 1) < MP_WARRAY) + && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_s_mp_mul_high_digs (a, b, c, digs); + } +#endif + + if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) { + return res; + } + t.used = a->used + b->used + 1; + + pa = a->used; + pb = b->used; + for (ix = 0; ix < pa; ix++) { + /* clear the carry */ + u = 0; + + /* left hand side of A[ix] * B[iy] */ + tmpx = a->dp[ix]; + + /* alias to the address of where the digits will be stored */ + tmpt = &(t.dp[digs]); + + /* alias for where to read the right hand side from */ + tmpy = b->dp + (digs - ix); + + for (iy = digs - ix; iy < pb; iy++) { + /* calculate the double precision result */ + r = ((mp_word)*tmpt) + + ((mp_word)tmpx) * ((mp_word)*tmpy++) + + ((mp_word) u); + + /* get the lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* carry the carry */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + *tmpt = u; + } + mp_clamp (&t); + mp_exch (&t, c); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_s_mp_mul_high_digs.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_s_mp_sqr.c b/StormLib/src/libtommath/bn_s_mp_sqr.c new file mode 100644 index 000000000..c1e994efd --- /dev/null +++ b/StormLib/src/libtommath/bn_s_mp_sqr.c @@ -0,0 +1,84 @@ +#include "tommath.h" +#ifdef BN_S_MP_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ +int s_mp_sqr (mp_int * a, mp_int * b) +{ + mp_int t; + int res, ix, iy, pa; + mp_word r; + mp_digit u, tmpx, *tmpt; + + pa = a->used; + if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) { + return res; + } + + /* default used is maximum possible size */ + t.used = 2*pa + 1; + + for (ix = 0; ix < pa; ix++) { + /* first calculate the digit at 2*ix */ + /* calculate double precision result */ + r = ((mp_word) t.dp[2*ix]) + + ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]); + + /* store lower part in result */ + t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + + /* left hand side of A[ix] * A[iy] */ + tmpx = a->dp[ix]; + + /* alias for where to store the results */ + tmpt = t.dp + (2*ix + 1); + + for (iy = ix + 1; iy < pa; iy++) { + /* first calculate the product */ + r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]); + + /* now calculate the double precision result, note we use + * addition instead of *2 since it's easier to optimize + */ + r = ((mp_word) *tmpt) + r + r + ((mp_word) u); + + /* store lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + /* propagate upwards */ + while (u != ((mp_digit) 0)) { + r = ((mp_word) *tmpt) + ((mp_word) u); + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + } + + mp_clamp (&t); + mp_exch (&t, b); + mp_clear (&t); + return MP_OKAY; +} +#endif + +/* $Source: /cvs/libtom/libtommath/bn_s_mp_sqr.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bn_s_mp_sub.c b/StormLib/src/libtommath/bn_s_mp_sub.c new file mode 100644 index 000000000..0ae91cc4d --- /dev/null +++ b/StormLib/src/libtommath/bn_s_mp_sub.c @@ -0,0 +1,89 @@ +#include "tommath.h" +#ifdef BN_S_MP_SUB_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ +int +s_mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int olduse, res, min, max; + + /* find sizes */ + min = b->used; + max = a->used; + + /* init result */ + if (c->alloc < max) { + if ((res = mp_grow (c, max)) != MP_OKAY) { + return res; + } + } + olduse = c->used; + c->used = max; + + { + register mp_digit u, *tmpa, *tmpb, *tmpc; + register int i; + + /* alias for digit pointers */ + tmpa = a->dp; + tmpb = b->dp; + tmpc = c->dp; + + /* set carry to zero */ + u = 0; + for (i = 0; i < min; i++) { + /* T[i] = A[i] - B[i] - U */ + *tmpc = *tmpa++ - *tmpb++ - u; + + /* U = carry bit of T[i] + * Note this saves performing an AND operation since + * if a carry does occur it will propagate all the way to the + * MSB. As a result a single shift is enough to get the carry + */ + u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, e.g. if A has more digits than B */ + for (; i < max; i++) { + /* T[i] = A[i] - U */ + *tmpc = *tmpa++ - u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* clear digits above used (since we may not have grown result above) */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_s_mp_sub.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/bncore.c b/StormLib/src/libtommath/bncore.c new file mode 100644 index 000000000..ad7347f84 --- /dev/null +++ b/StormLib/src/libtommath/bncore.c @@ -0,0 +1,36 @@ +#include "tommath.h" +#ifdef BNCORE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + */ + +/* Known optimal configurations + + CPU /Compiler /MUL CUTOFF/SQR CUTOFF +------------------------------------------------------------- + Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-) + AMD Athlon64 /GCC v3.4.4 / 80/ 120/LTM 0.35 + +*/ + +int KARATSUBA_MUL_CUTOFF = 80, /* Min. number of digits before Karatsuba multiplication is used. */ + KARATSUBA_SQR_CUTOFF = 120, /* Min. number of digits before Karatsuba squaring is used. */ + + TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */ + TOOM_SQR_CUTOFF = 400; +#endif + +/* $Source: /cvs/libtom/libtommath/bncore.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/StormLib/src/libtommath/tommath.h b/StormLib/src/libtommath/tommath.h new file mode 100644 index 000000000..1ead3d04b --- /dev/null +++ b/StormLib/src/libtommath/tommath.h @@ -0,0 +1,584 @@ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com + */ +#ifndef BN_H_ +#define BN_H_ + +#include +#include +#include +#include +#include + +#include "tommath_class.h" + +#ifndef MIN + #define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +#ifndef MAX + #define MAX(x,y) ((x)>(y)?(x):(y)) +#endif + +#ifdef __cplusplus +extern "C" { + +/* C++ compilers don't like assigning void * to mp_digit * */ +#define OPT_CAST(x) (x *) + +#else + +/* C on the other hand doesn't care */ +#define OPT_CAST(x) + +#endif + + +/* detect 64-bit mode if possible */ +#if defined(__x86_64__) + #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT)) + #define MP_64BIT + #endif +#endif + +/* some default configurations. + * + * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits + * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits + * + * At the very least a mp_digit must be able to hold 7 bits + * [any size beyond that is ok provided it doesn't overflow the data type] + */ +#ifdef MP_8BIT + typedef unsigned char mp_digit; + typedef unsigned short mp_word; +#elif defined(MP_16BIT) + typedef unsigned short mp_digit; + typedef unsigned long mp_word; +#elif defined(MP_64BIT) + /* for GCC only on supported platforms */ +#ifndef CRYPT + typedef unsigned long long ulong64; + typedef signed long long long64; +#endif + + typedef unsigned long mp_digit; + typedef unsigned long mp_word __attribute__ ((mode(TI))); + + #define DIGIT_BIT 60 +#else + /* this is the default case, 28-bit digits */ + + /* this is to make porting into LibTomCrypt easier :-) */ +#ifndef CRYPT + #if defined(_MSC_VER) || defined(__BORLANDC__) + typedef unsigned __int64 ulong64; + typedef signed __int64 long64; + #else + typedef unsigned long long ulong64; + typedef signed long long long64; + #endif +#endif + + typedef unsigned long mp_digit; + typedef ulong64 mp_word; + +#ifdef MP_31BIT + /* this is an extension that uses 31-bit digits */ + #define DIGIT_BIT 31 +#else + /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */ + #define DIGIT_BIT 28 + #define MP_28BIT +#endif +#endif + +/* define heap macros */ +#ifndef CRYPT + /* default to libc stuff */ + #ifndef XMALLOC + #define XMALLOC malloc + #define XFREE free + #define XREALLOC realloc + #define XCALLOC calloc + #else + /* prototypes for our heap functions */ + extern void *XMALLOC(size_t n); + extern void *XREALLOC(void *p, size_t n); + extern void *XCALLOC(size_t n, size_t s); + extern void XFREE(void *p); + #endif +#endif + + +/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */ +#ifndef DIGIT_BIT + #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */ +#endif + +#define MP_DIGIT_BIT DIGIT_BIT +#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) +#define MP_DIGIT_MAX MP_MASK + +/* equalities */ +#define MP_LT -1 /* less than */ +#define MP_EQ 0 /* equal to */ +#define MP_GT 1 /* greater than */ + +#define MP_ZPOS 0 /* positive integer */ +#define MP_NEG 1 /* negative */ + +#define MP_OKAY 0 /* ok result */ +#define MP_MEM -2 /* out of mem */ +#define MP_VAL -3 /* invalid input */ +#define MP_RANGE MP_VAL + +#define MP_YES 1 /* yes response */ +#define MP_NO 0 /* no response */ + +/* Primality generation flags */ +#define LTM_PRIME_BBS 0x0001 /* BBS style prime */ +#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */ +#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */ + +typedef int mp_err; + +/* you'll have to tune these... */ +extern int KARATSUBA_MUL_CUTOFF, + KARATSUBA_SQR_CUTOFF, + TOOM_MUL_CUTOFF, + TOOM_SQR_CUTOFF; + +/* define this to use lower memory usage routines (exptmods mostly) */ +/* #define MP_LOW_MEM */ + +/* default precision */ +#ifndef MP_PREC + #ifndef MP_LOW_MEM + #define MP_PREC 32 /* default digits of precision */ + #else + #define MP_PREC 8 /* default digits of precision */ + #endif +#endif + +/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ +#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1)) + +/* the infamous mp_int structure */ +typedef struct { + int used, alloc, sign; + mp_digit *dp; +} mp_int; + +/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */ +typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); + + +#define USED(m) ((m)->used) +#define DIGIT(m,k) ((m)->dp[(k)]) +#define SIGN(m) ((m)->sign) + +/* error code to char* string */ +char *mp_error_to_string(int code); + +/* ---> init and deinit bignum functions <--- */ +/* init a bignum */ +int mp_init(mp_int *a); + +/* free a bignum */ +void mp_clear(mp_int *a); + +/* init a null terminated series of arguments */ +int mp_init_multi(mp_int *mp, ...); + +/* clear a null terminated series of arguments */ +void mp_clear_multi(mp_int *mp, ...); + +/* exchange two ints */ +void mp_exch(mp_int *a, mp_int *b); + +/* shrink ram required for a bignum */ +int mp_shrink(mp_int *a); + +/* grow an int to a given size */ +int mp_grow(mp_int *a, int size); + +/* init to a given number of digits */ +int mp_init_size(mp_int *a, int size); + +/* ---> Basic Manipulations <--- */ +#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) +#define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO) +#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO) + +/* set to zero */ +void mp_zero(mp_int *a); + +/* set to a digit */ +void mp_set(mp_int *a, mp_digit b); + +/* set a 32-bit const */ +int mp_set_int(mp_int *a, unsigned long b); + +/* get a 32-bit value */ +unsigned long mp_get_int(mp_int * a); + +/* initialize and set a digit */ +int mp_init_set (mp_int * a, mp_digit b); + +/* initialize and set 32-bit value */ +int mp_init_set_int (mp_int * a, unsigned long b); + +/* copy, b = a */ +int mp_copy(mp_int *a, mp_int *b); + +/* inits and copies, a = b */ +int mp_init_copy(mp_int *a, mp_int *b); + +/* trim unused digits */ +void mp_clamp(mp_int *a); + +/* ---> digit manipulation <--- */ + +/* right shift by "b" digits */ +void mp_rshd(mp_int *a, int b); + +/* left shift by "b" digits */ +int mp_lshd(mp_int *a, int b); + +/* c = a / 2**b */ +int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d); + +/* b = a/2 */ +int mp_div_2(mp_int *a, mp_int *b); + +/* c = a * 2**b */ +int mp_mul_2d(mp_int *a, int b, mp_int *c); + +/* b = a*2 */ +int mp_mul_2(mp_int *a, mp_int *b); + +/* c = a mod 2**d */ +int mp_mod_2d(mp_int *a, int b, mp_int *c); + +/* computes a = 2**b */ +int mp_2expt(mp_int *a, int b); + +/* Counts the number of lsbs which are zero before the first zero bit */ +int mp_cnt_lsb(mp_int *a); + +/* I Love Earth! */ + +/* makes a pseudo-random int of a given size */ +int mp_rand(mp_int *a, int digits); + +/* ---> binary operations <--- */ +/* c = a XOR b */ +int mp_xor(mp_int *a, mp_int *b, mp_int *c); + +/* c = a OR b */ +int mp_or(mp_int *a, mp_int *b, mp_int *c); + +/* c = a AND b */ +int mp_and(mp_int *a, mp_int *b, mp_int *c); + +/* ---> Basic arithmetic <--- */ + +/* b = -a */ +int mp_neg(mp_int *a, mp_int *b); + +/* b = |a| */ +int mp_abs(mp_int *a, mp_int *b); + +/* compare a to b */ +int mp_cmp(mp_int *a, mp_int *b); + +/* compare |a| to |b| */ +int mp_cmp_mag(mp_int *a, mp_int *b); + +/* c = a + b */ +int mp_add(mp_int *a, mp_int *b, mp_int *c); + +/* c = a - b */ +int mp_sub(mp_int *a, mp_int *b, mp_int *c); + +/* c = a * b */ +int mp_mul(mp_int *a, mp_int *b, mp_int *c); + +/* b = a*a */ +int mp_sqr(mp_int *a, mp_int *b); + +/* a/b => cb + d == a */ +int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* c = a mod b, 0 <= c < b */ +int mp_mod(mp_int *a, mp_int *b, mp_int *c); + +/* ---> single digit functions <--- */ + +/* compare against a single digit */ +int mp_cmp_d(mp_int *a, mp_digit b); + +/* c = a + b */ +int mp_add_d(mp_int *a, mp_digit b, mp_int *c); + +/* c = a - b */ +int mp_sub_d(mp_int *a, mp_digit b, mp_int *c); + +/* c = a * b */ +int mp_mul_d(mp_int *a, mp_digit b, mp_int *c); + +/* a/b => cb + d == a */ +int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d); + +/* a/3 => 3c + d == a */ +int mp_div_3(mp_int *a, mp_int *c, mp_digit *d); + +/* c = a**b */ +int mp_expt_d(mp_int *a, mp_digit b, mp_int *c); + +/* c = a mod b, 0 <= c < b */ +int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c); + +/* ---> number theory <--- */ + +/* d = a + b (mod c) */ +int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* d = a - b (mod c) */ +int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* d = a * b (mod c) */ +int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* c = a * a (mod b) */ +int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c); + +/* c = 1/a (mod b) */ +int mp_invmod(mp_int *a, mp_int *b, mp_int *c); + +/* c = (a, b) */ +int mp_gcd(mp_int *a, mp_int *b, mp_int *c); + +/* produces value such that U1*a + U2*b = U3 */ +int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3); + +/* c = [a, b] or (a*b)/(a, b) */ +int mp_lcm(mp_int *a, mp_int *b, mp_int *c); + +/* finds one of the b'th root of a, such that |c|**b <= |a| + * + * returns error if a < 0 and b is even + */ +int mp_n_root(mp_int *a, mp_digit b, mp_int *c); + +/* special sqrt algo */ +int mp_sqrt(mp_int *arg, mp_int *ret); + +/* is number a square? */ +int mp_is_square(mp_int *arg, int *ret); + +/* computes the jacobi c = (a | n) (or Legendre if b is prime) */ +int mp_jacobi(mp_int *a, mp_int *n, int *c); + +/* used to setup the Barrett reduction for a given modulus b */ +int mp_reduce_setup(mp_int *a, mp_int *b); + +/* Barrett Reduction, computes a (mod b) with a precomputed value c + * + * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely + * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code]. + */ +int mp_reduce(mp_int *a, mp_int *b, mp_int *c); + +/* setups the montgomery reduction */ +int mp_montgomery_setup(mp_int *a, mp_digit *mp); + +/* computes a = B**n mod b without division or multiplication useful for + * normalizing numbers in a Montgomery system. + */ +int mp_montgomery_calc_normalization(mp_int *a, mp_int *b); + +/* computes x/R == x (mod N) via Montgomery Reduction */ +int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); + +/* returns 1 if a is a valid DR modulus */ +int mp_dr_is_modulus(mp_int *a); + +/* sets the value of "d" required for mp_dr_reduce */ +void mp_dr_setup(mp_int *a, mp_digit *d); + +/* reduces a modulo b using the Diminished Radix method */ +int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp); + +/* returns true if a can be reduced with mp_reduce_2k */ +int mp_reduce_is_2k(mp_int *a); + +/* determines k value for 2k reduction */ +int mp_reduce_2k_setup(mp_int *a, mp_digit *d); + +/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ +int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d); + +/* returns true if a can be reduced with mp_reduce_2k_l */ +int mp_reduce_is_2k_l(mp_int *a); + +/* determines k value for 2k reduction */ +int mp_reduce_2k_setup_l(mp_int *a, mp_int *d); + +/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ +int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d); + +/* d = a**b (mod c) */ +int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* ---> Primes <--- */ + +/* number of primes */ +#ifdef MP_8BIT + #define PRIME_SIZE 31 +#else + #define PRIME_SIZE 256 +#endif + +/* table of first PRIME_SIZE primes */ +extern const mp_digit ltm_prime_tab[]; + +/* result=1 if a is divisible by one of the first PRIME_SIZE primes */ +int mp_prime_is_divisible(mp_int *a, int *result); + +/* performs one Fermat test of "a" using base "b". + * Sets result to 0 if composite or 1 if probable prime + */ +int mp_prime_fermat(mp_int *a, mp_int *b, int *result); + +/* performs one Miller-Rabin test of "a" using base "b". + * Sets result to 0 if composite or 1 if probable prime + */ +int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result); + +/* This gives [for a given bit size] the number of trials required + * such that Miller-Rabin gives a prob of failure lower than 2^-96 + */ +int mp_prime_rabin_miller_trials(int size); + +/* performs t rounds of Miller-Rabin on "a" using the first + * t prime bases. Also performs an initial sieve of trial + * division. Determines if "a" is prime with probability + * of error no more than (1/4)**t. + * + * Sets result to 1 if probably prime, 0 otherwise + */ +int mp_prime_is_prime(mp_int *a, int t, int *result); + +/* finds the next prime after the number "a" using "t" trials + * of Miller-Rabin. + * + * bbs_style = 1 means the prime must be congruent to 3 mod 4 + */ +int mp_prime_next_prime(mp_int *a, int t, int bbs_style); + +/* makes a truly random prime of a given size (bytes), + * call with bbs = 1 if you want it to be congruent to 3 mod 4 + * + * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can + * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself + * so it can be NULL + * + * The prime generated will be larger than 2^(8*size). + */ +#define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat) + +/* makes a truly random prime of a given size (bits), + * + * Flags are as follows: + * + * LTM_PRIME_BBS - make prime congruent to 3 mod 4 + * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) + * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero + * LTM_PRIME_2MSB_ON - make the 2nd highest bit one + * + * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can + * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself + * so it can be NULL + * + */ +int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat); + +/* ---> radix conversion <--- */ +int mp_count_bits(mp_int *a); + +int mp_unsigned_bin_size(mp_int *a); +int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c); +int mp_to_unsigned_bin(mp_int *a, unsigned char *b); +int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen); + +int mp_signed_bin_size(mp_int *a); +int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c); +int mp_to_signed_bin(mp_int *a, unsigned char *b); +int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen); + +int mp_read_radix(mp_int *a, const char *str, int radix); +int mp_toradix(mp_int *a, char *str, int radix); +int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen); +int mp_radix_size(mp_int *a, int radix, int *size); + +int mp_fread(mp_int *a, int radix, FILE *stream); +int mp_fwrite(mp_int *a, int radix, FILE *stream); + +#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) +#define mp_raw_size(mp) mp_signed_bin_size(mp) +#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) +#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) +#define mp_mag_size(mp) mp_unsigned_bin_size(mp) +#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) + +#define mp_tobinary(M, S) mp_toradix((M), (S), 2) +#define mp_tooctal(M, S) mp_toradix((M), (S), 8) +#define mp_todecimal(M, S) mp_toradix((M), (S), 10) +#define mp_tohex(M, S) mp_toradix((M), (S), 16) + +/* lowlevel functions, do not call! */ +int s_mp_add(mp_int *a, mp_int *b, mp_int *c); +int s_mp_sub(mp_int *a, mp_int *b, mp_int *c); +#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1) +int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int fast_s_mp_sqr(mp_int *a, mp_int *b); +int s_mp_sqr(mp_int *a, mp_int *b); +int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c); +int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c); +int mp_karatsuba_sqr(mp_int *a, mp_int *b); +int mp_toom_sqr(mp_int *a, mp_int *b); +int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c); +int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c); +int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); +int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode); +int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int mode); +void bn_reverse(unsigned char *s, int len); + +extern const char *mp_s_rmap; + +#ifdef __cplusplus + } +#endif + +#endif + + +/* $Source: /cvs/libtom/libtommath/tommath.h,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/03/31 14:18:44 $ */ diff --git a/StormLib/src/libtommath/tommath_class.h b/StormLib/src/libtommath/tommath_class.h new file mode 100644 index 000000000..18d1553de --- /dev/null +++ b/StormLib/src/libtommath/tommath_class.h @@ -0,0 +1,999 @@ +#if !(defined(LTM1) && defined(LTM2) && defined(LTM3)) +#if defined(LTM2) +#define LTM3 +#endif +#if defined(LTM1) +#define LTM2 +#endif +#define LTM1 + +#if defined(LTM_ALL) +#define BN_ERROR_C +#define BN_FAST_MP_INVMOD_C +#define BN_FAST_MP_MONTGOMERY_REDUCE_C +#define BN_FAST_S_MP_MUL_DIGS_C +#define BN_FAST_S_MP_MUL_HIGH_DIGS_C +#define BN_FAST_S_MP_SQR_C +#define BN_MP_2EXPT_C +#define BN_MP_ABS_C +#define BN_MP_ADD_C +#define BN_MP_ADD_D_C +#define BN_MP_ADDMOD_C +#define BN_MP_AND_C +#define BN_MP_CLAMP_C +#define BN_MP_CLEAR_C +#define BN_MP_CLEAR_MULTI_C +#define BN_MP_CMP_C +#define BN_MP_CMP_D_C +#define BN_MP_CMP_MAG_C +#define BN_MP_CNT_LSB_C +#define BN_MP_COPY_C +#define BN_MP_COUNT_BITS_C +#define BN_MP_DIV_C +#define BN_MP_DIV_2_C +#define BN_MP_DIV_2D_C +#define BN_MP_DIV_3_C +#define BN_MP_DIV_D_C +#define BN_MP_DR_IS_MODULUS_C +#define BN_MP_DR_REDUCE_C +#define BN_MP_DR_SETUP_C +#define BN_MP_EXCH_C +#define BN_MP_EXPT_D_C +#define BN_MP_EXPTMOD_C +#define BN_MP_EXPTMOD_FAST_C +#define BN_MP_EXTEUCLID_C +#define BN_MP_FREAD_C +#define BN_MP_FWRITE_C +#define BN_MP_GCD_C +#define BN_MP_GET_INT_C +#define BN_MP_GROW_C +#define BN_MP_INIT_C +#define BN_MP_INIT_COPY_C +#define BN_MP_INIT_MULTI_C +#define BN_MP_INIT_SET_C +#define BN_MP_INIT_SET_INT_C +#define BN_MP_INIT_SIZE_C +#define BN_MP_INVMOD_C +#define BN_MP_INVMOD_SLOW_C +#define BN_MP_IS_SQUARE_C +#define BN_MP_JACOBI_C +#define BN_MP_KARATSUBA_MUL_C +#define BN_MP_KARATSUBA_SQR_C +#define BN_MP_LCM_C +#define BN_MP_LSHD_C +#define BN_MP_MOD_C +#define BN_MP_MOD_2D_C +#define BN_MP_MOD_D_C +#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +#define BN_MP_MONTGOMERY_REDUCE_C +#define BN_MP_MONTGOMERY_SETUP_C +#define BN_MP_MUL_C +#define BN_MP_MUL_2_C +#define BN_MP_MUL_2D_C +#define BN_MP_MUL_D_C +#define BN_MP_MULMOD_C +#define BN_MP_N_ROOT_C +#define BN_MP_NEG_C +#define BN_MP_OR_C +#define BN_MP_PRIME_FERMAT_C +#define BN_MP_PRIME_IS_DIVISIBLE_C +#define BN_MP_PRIME_IS_PRIME_C +#define BN_MP_PRIME_MILLER_RABIN_C +#define BN_MP_PRIME_NEXT_PRIME_C +#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C +#define BN_MP_PRIME_RANDOM_EX_C +#define BN_MP_RADIX_SIZE_C +#define BN_MP_RADIX_SMAP_C +#define BN_MP_RAND_C +#define BN_MP_READ_RADIX_C +#define BN_MP_READ_SIGNED_BIN_C +#define BN_MP_READ_UNSIGNED_BIN_C +#define BN_MP_REDUCE_C +#define BN_MP_REDUCE_2K_C +#define BN_MP_REDUCE_2K_L_C +#define BN_MP_REDUCE_2K_SETUP_C +#define BN_MP_REDUCE_2K_SETUP_L_C +#define BN_MP_REDUCE_IS_2K_C +#define BN_MP_REDUCE_IS_2K_L_C +#define BN_MP_REDUCE_SETUP_C +#define BN_MP_RSHD_C +#define BN_MP_SET_C +#define BN_MP_SET_INT_C +#define BN_MP_SHRINK_C +#define BN_MP_SIGNED_BIN_SIZE_C +#define BN_MP_SQR_C +#define BN_MP_SQRMOD_C +#define BN_MP_SQRT_C +#define BN_MP_SUB_C +#define BN_MP_SUB_D_C +#define BN_MP_SUBMOD_C +#define BN_MP_TO_SIGNED_BIN_C +#define BN_MP_TO_SIGNED_BIN_N_C +#define BN_MP_TO_UNSIGNED_BIN_C +#define BN_MP_TO_UNSIGNED_BIN_N_C +#define BN_MP_TOOM_MUL_C +#define BN_MP_TOOM_SQR_C +#define BN_MP_TORADIX_C +#define BN_MP_TORADIX_N_C +#define BN_MP_UNSIGNED_BIN_SIZE_C +#define BN_MP_XOR_C +#define BN_MP_ZERO_C +#define BN_PRIME_TAB_C +#define BN_REVERSE_C +#define BN_S_MP_ADD_C +#define BN_S_MP_EXPTMOD_C +#define BN_S_MP_MUL_DIGS_C +#define BN_S_MP_MUL_HIGH_DIGS_C +#define BN_S_MP_SQR_C +#define BN_S_MP_SUB_C +#define BNCORE_C +#endif + +#if defined(BN_ERROR_C) + #define BN_MP_ERROR_TO_STRING_C +#endif + +#if defined(BN_FAST_MP_INVMOD_C) + #define BN_MP_ISEVEN_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_COPY_C + #define BN_MP_MOD_C + #define BN_MP_SET_C + #define BN_MP_DIV_2_C + #define BN_MP_ISODD_C + #define BN_MP_SUB_C + #define BN_MP_CMP_C + #define BN_MP_ISZERO_C + #define BN_MP_CMP_D_C + #define BN_MP_ADD_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C) + #define BN_MP_GROW_C + #define BN_MP_RSHD_C + #define BN_MP_CLAMP_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_FAST_S_MP_MUL_DIGS_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_FAST_S_MP_SQR_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_2EXPT_C) + #define BN_MP_ZERO_C + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_ABS_C) + #define BN_MP_COPY_C +#endif + +#if defined(BN_MP_ADD_C) + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_ADD_D_C) + #define BN_MP_GROW_C + #define BN_MP_SUB_D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_ADDMOD_C) + #define BN_MP_INIT_C + #define BN_MP_ADD_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_AND_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_CLAMP_C) +#endif + +#if defined(BN_MP_CLEAR_C) +#endif + +#if defined(BN_MP_CLEAR_MULTI_C) + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_CMP_C) + #define BN_MP_CMP_MAG_C +#endif + +#if defined(BN_MP_CMP_D_C) +#endif + +#if defined(BN_MP_CMP_MAG_C) +#endif + +#if defined(BN_MP_CNT_LSB_C) + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_COPY_C) + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_COUNT_BITS_C) +#endif + +#if defined(BN_MP_DIV_C) + #define BN_MP_ISZERO_C + #define BN_MP_CMP_MAG_C + #define BN_MP_COPY_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_SET_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_ABS_C + #define BN_MP_MUL_2D_C + #define BN_MP_CMP_C + #define BN_MP_SUB_C + #define BN_MP_ADD_C + #define BN_MP_DIV_2D_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_INIT_C + #define BN_MP_INIT_COPY_C + #define BN_MP_LSHD_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_D_C + #define BN_MP_CLAMP_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DIV_2_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_DIV_2D_C) + #define BN_MP_COPY_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_C + #define BN_MP_MOD_2D_C + #define BN_MP_CLEAR_C + #define BN_MP_RSHD_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_DIV_3_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DIV_D_C) + #define BN_MP_ISZERO_C + #define BN_MP_COPY_C + #define BN_MP_DIV_2D_C + #define BN_MP_DIV_3_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_DR_IS_MODULUS_C) +#endif + +#if defined(BN_MP_DR_REDUCE_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_DR_SETUP_C) +#endif + +#if defined(BN_MP_EXCH_C) +#endif + +#if defined(BN_MP_EXPT_D_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_SET_C + #define BN_MP_SQR_C + #define BN_MP_CLEAR_C + #define BN_MP_MUL_C +#endif + +#if defined(BN_MP_EXPTMOD_C) + #define BN_MP_INIT_C + #define BN_MP_INVMOD_C + #define BN_MP_CLEAR_C + #define BN_MP_ABS_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_REDUCE_IS_2K_L_C + #define BN_S_MP_EXPTMOD_C + #define BN_MP_DR_IS_MODULUS_C + #define BN_MP_REDUCE_IS_2K_C + #define BN_MP_ISODD_C + #define BN_MP_EXPTMOD_FAST_C +#endif + +#if defined(BN_MP_EXPTMOD_FAST_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C + #define BN_MP_MONTGOMERY_SETUP_C + #define BN_FAST_MP_MONTGOMERY_REDUCE_C + #define BN_MP_MONTGOMERY_REDUCE_C + #define BN_MP_DR_SETUP_C + #define BN_MP_DR_REDUCE_C + #define BN_MP_REDUCE_2K_SETUP_C + #define BN_MP_REDUCE_2K_C + #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C + #define BN_MP_MULMOD_C + #define BN_MP_SET_C + #define BN_MP_MOD_C + #define BN_MP_COPY_C + #define BN_MP_SQR_C + #define BN_MP_MUL_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_EXTEUCLID_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_SET_C + #define BN_MP_COPY_C + #define BN_MP_ISZERO_C + #define BN_MP_DIV_C + #define BN_MP_MUL_C + #define BN_MP_SUB_C + #define BN_MP_NEG_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_FREAD_C) + #define BN_MP_ZERO_C + #define BN_MP_S_RMAP_C + #define BN_MP_MUL_D_C + #define BN_MP_ADD_D_C + #define BN_MP_CMP_D_C +#endif + +#if defined(BN_MP_FWRITE_C) + #define BN_MP_RADIX_SIZE_C + #define BN_MP_TORADIX_C +#endif + +#if defined(BN_MP_GCD_C) + #define BN_MP_ISZERO_C + #define BN_MP_ABS_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_S_MP_SUB_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_GET_INT_C) +#endif + +#if defined(BN_MP_GROW_C) +#endif + +#if defined(BN_MP_INIT_C) +#endif + +#if defined(BN_MP_INIT_COPY_C) + #define BN_MP_COPY_C +#endif + +#if defined(BN_MP_INIT_MULTI_C) + #define BN_MP_ERR_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_INIT_SET_C) + #define BN_MP_INIT_C + #define BN_MP_SET_C +#endif + +#if defined(BN_MP_INIT_SET_INT_C) + #define BN_MP_INIT_C + #define BN_MP_SET_INT_C +#endif + +#if defined(BN_MP_INIT_SIZE_C) + #define BN_MP_INIT_C +#endif + +#if defined(BN_MP_INVMOD_C) + #define BN_MP_ISZERO_C + #define BN_MP_ISODD_C + #define BN_FAST_MP_INVMOD_C + #define BN_MP_INVMOD_SLOW_C +#endif + +#if defined(BN_MP_INVMOD_SLOW_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_C + #define BN_MP_COPY_C + #define BN_MP_ISEVEN_C + #define BN_MP_SET_C + #define BN_MP_DIV_2_C + #define BN_MP_ISODD_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_CMP_C + #define BN_MP_CMP_D_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_IS_SQUARE_C) + #define BN_MP_MOD_D_C + #define BN_MP_INIT_SET_INT_C + #define BN_MP_MOD_C + #define BN_MP_GET_INT_C + #define BN_MP_SQRT_C + #define BN_MP_SQR_C + #define BN_MP_CMP_MAG_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_JACOBI_C) + #define BN_MP_CMP_D_C + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_MOD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_KARATSUBA_MUL_C) + #define BN_MP_MUL_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_SUB_C + #define BN_MP_ADD_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_KARATSUBA_SQR_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_SQR_C + #define BN_MP_SUB_C + #define BN_S_MP_ADD_C + #define BN_MP_LSHD_C + #define BN_MP_ADD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_LCM_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_GCD_C + #define BN_MP_CMP_MAG_C + #define BN_MP_DIV_C + #define BN_MP_MUL_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_LSHD_C) + #define BN_MP_GROW_C + #define BN_MP_RSHD_C +#endif + +#if defined(BN_MP_MOD_C) + #define BN_MP_INIT_C + #define BN_MP_DIV_C + #define BN_MP_CLEAR_C + #define BN_MP_ADD_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_MOD_2D_C) + #define BN_MP_ZERO_C + #define BN_MP_COPY_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MOD_D_C) + #define BN_MP_DIV_D_C +#endif + +#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_2EXPT_C + #define BN_MP_SET_C + #define BN_MP_MUL_2_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_MONTGOMERY_REDUCE_C) + #define BN_FAST_MP_MONTGOMERY_REDUCE_C + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C + #define BN_MP_RSHD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_MONTGOMERY_SETUP_C) +#endif + +#if defined(BN_MP_MUL_C) + #define BN_MP_TOOM_MUL_C + #define BN_MP_KARATSUBA_MUL_C + #define BN_FAST_S_MP_MUL_DIGS_C + #define BN_S_MP_MUL_C + #define BN_S_MP_MUL_DIGS_C +#endif + +#if defined(BN_MP_MUL_2_C) + #define BN_MP_GROW_C +#endif + +#if defined(BN_MP_MUL_2D_C) + #define BN_MP_COPY_C + #define BN_MP_GROW_C + #define BN_MP_LSHD_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MUL_D_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_MULMOD_C) + #define BN_MP_INIT_C + #define BN_MP_MUL_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_N_ROOT_C) + #define BN_MP_INIT_C + #define BN_MP_SET_C + #define BN_MP_COPY_C + #define BN_MP_EXPT_D_C + #define BN_MP_MUL_C + #define BN_MP_SUB_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_C + #define BN_MP_CMP_C + #define BN_MP_SUB_D_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_NEG_C) + #define BN_MP_COPY_C + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_OR_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_FERMAT_C) + #define BN_MP_CMP_D_C + #define BN_MP_INIT_C + #define BN_MP_EXPTMOD_C + #define BN_MP_CMP_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_IS_DIVISIBLE_C) + #define BN_MP_MOD_D_C +#endif + +#if defined(BN_MP_PRIME_IS_PRIME_C) + #define BN_MP_CMP_D_C + #define BN_MP_PRIME_IS_DIVISIBLE_C + #define BN_MP_INIT_C + #define BN_MP_SET_C + #define BN_MP_PRIME_MILLER_RABIN_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_MILLER_RABIN_C) + #define BN_MP_CMP_D_C + #define BN_MP_INIT_COPY_C + #define BN_MP_SUB_D_C + #define BN_MP_CNT_LSB_C + #define BN_MP_DIV_2D_C + #define BN_MP_EXPTMOD_C + #define BN_MP_CMP_C + #define BN_MP_SQRMOD_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_NEXT_PRIME_C) + #define BN_MP_CMP_D_C + #define BN_MP_SET_C + #define BN_MP_SUB_D_C + #define BN_MP_ISEVEN_C + #define BN_MP_MOD_D_C + #define BN_MP_INIT_C + #define BN_MP_ADD_D_C + #define BN_MP_PRIME_MILLER_RABIN_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C) +#endif + +#if defined(BN_MP_PRIME_RANDOM_EX_C) + #define BN_MP_READ_UNSIGNED_BIN_C + #define BN_MP_PRIME_IS_PRIME_C + #define BN_MP_SUB_D_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_D_C +#endif + +#if defined(BN_MP_RADIX_SIZE_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_COPY_C + #define BN_MP_ISZERO_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_RADIX_SMAP_C) + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_RAND_C) + #define BN_MP_ZERO_C + #define BN_MP_ADD_D_C + #define BN_MP_LSHD_C +#endif + +#if defined(BN_MP_READ_RADIX_C) + #define BN_MP_ZERO_C + #define BN_MP_S_RMAP_C + #define BN_MP_RADIX_SMAP_C + #define BN_MP_MUL_D_C + #define BN_MP_ADD_D_C + #define BN_MP_ISZERO_C +#endif + +#if defined(BN_MP_READ_SIGNED_BIN_C) + #define BN_MP_READ_UNSIGNED_BIN_C +#endif + +#if defined(BN_MP_READ_UNSIGNED_BIN_C) + #define BN_MP_GROW_C + #define BN_MP_ZERO_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_REDUCE_C) + #define BN_MP_REDUCE_SETUP_C + #define BN_MP_INIT_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_C + #define BN_S_MP_MUL_HIGH_DIGS_C + #define BN_FAST_S_MP_MUL_HIGH_DIGS_C + #define BN_MP_MOD_2D_C + #define BN_S_MP_MUL_DIGS_C + #define BN_MP_SUB_C + #define BN_MP_CMP_D_C + #define BN_MP_SET_C + #define BN_MP_LSHD_C + #define BN_MP_ADD_C + #define BN_MP_CMP_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_2K_C) + #define BN_MP_INIT_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_DIV_2D_C + #define BN_MP_MUL_D_C + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_2K_L_C) + #define BN_MP_INIT_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_DIV_2D_C + #define BN_MP_MUL_C + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_2K_SETUP_C) + #define BN_MP_INIT_C + #define BN_MP_COUNT_BITS_C + #define BN_MP_2EXPT_C + #define BN_MP_CLEAR_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_REDUCE_2K_SETUP_L_C) + #define BN_MP_INIT_C + #define BN_MP_2EXPT_C + #define BN_MP_COUNT_BITS_C + #define BN_S_MP_SUB_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_REDUCE_IS_2K_C) + #define BN_MP_REDUCE_2K_C + #define BN_MP_COUNT_BITS_C +#endif + +#if defined(BN_MP_REDUCE_IS_2K_L_C) +#endif + +#if defined(BN_MP_REDUCE_SETUP_C) + #define BN_MP_2EXPT_C + #define BN_MP_DIV_C +#endif + +#if defined(BN_MP_RSHD_C) + #define BN_MP_ZERO_C +#endif + +#if defined(BN_MP_SET_C) + #define BN_MP_ZERO_C +#endif + +#if defined(BN_MP_SET_INT_C) + #define BN_MP_ZERO_C + #define BN_MP_MUL_2D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_SHRINK_C) +#endif + +#if defined(BN_MP_SIGNED_BIN_SIZE_C) + #define BN_MP_UNSIGNED_BIN_SIZE_C +#endif + +#if defined(BN_MP_SQR_C) + #define BN_MP_TOOM_SQR_C + #define BN_MP_KARATSUBA_SQR_C + #define BN_FAST_S_MP_SQR_C + #define BN_S_MP_SQR_C +#endif + +#if defined(BN_MP_SQRMOD_C) + #define BN_MP_INIT_C + #define BN_MP_SQR_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_SQRT_C) + #define BN_MP_N_ROOT_C + #define BN_MP_ISZERO_C + #define BN_MP_ZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_DIV_C + #define BN_MP_ADD_C + #define BN_MP_DIV_2_C + #define BN_MP_CMP_MAG_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_SUB_C) + #define BN_S_MP_ADD_C + #define BN_MP_CMP_MAG_C + #define BN_S_MP_SUB_C +#endif + +#if defined(BN_MP_SUB_D_C) + #define BN_MP_GROW_C + #define BN_MP_ADD_D_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_SUBMOD_C) + #define BN_MP_INIT_C + #define BN_MP_SUB_C + #define BN_MP_CLEAR_C + #define BN_MP_MOD_C +#endif + +#if defined(BN_MP_TO_SIGNED_BIN_C) + #define BN_MP_TO_UNSIGNED_BIN_C +#endif + +#if defined(BN_MP_TO_SIGNED_BIN_N_C) + #define BN_MP_SIGNED_BIN_SIZE_C + #define BN_MP_TO_SIGNED_BIN_C +#endif + +#if defined(BN_MP_TO_UNSIGNED_BIN_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_ISZERO_C + #define BN_MP_DIV_2D_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_TO_UNSIGNED_BIN_N_C) + #define BN_MP_UNSIGNED_BIN_SIZE_C + #define BN_MP_TO_UNSIGNED_BIN_C +#endif + +#if defined(BN_MP_TOOM_MUL_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_2D_C + #define BN_MP_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_MUL_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2D_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_3_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_TOOM_SQR_C) + #define BN_MP_INIT_MULTI_C + #define BN_MP_MOD_2D_C + #define BN_MP_COPY_C + #define BN_MP_RSHD_C + #define BN_MP_SQR_C + #define BN_MP_MUL_2_C + #define BN_MP_ADD_C + #define BN_MP_SUB_C + #define BN_MP_DIV_2_C + #define BN_MP_MUL_2D_C + #define BN_MP_MUL_D_C + #define BN_MP_DIV_3_C + #define BN_MP_LSHD_C + #define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_TORADIX_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_TORADIX_N_C) + #define BN_MP_ISZERO_C + #define BN_MP_INIT_COPY_C + #define BN_MP_DIV_D_C + #define BN_MP_CLEAR_C + #define BN_MP_S_RMAP_C +#endif + +#if defined(BN_MP_UNSIGNED_BIN_SIZE_C) + #define BN_MP_COUNT_BITS_C +#endif + +#if defined(BN_MP_XOR_C) + #define BN_MP_INIT_COPY_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_MP_ZERO_C) +#endif + +#if defined(BN_PRIME_TAB_C) +#endif + +#if defined(BN_REVERSE_C) +#endif + +#if defined(BN_S_MP_ADD_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BN_S_MP_EXPTMOD_C) + #define BN_MP_COUNT_BITS_C + #define BN_MP_INIT_C + #define BN_MP_CLEAR_C + #define BN_MP_REDUCE_SETUP_C + #define BN_MP_REDUCE_C + #define BN_MP_REDUCE_2K_SETUP_L_C + #define BN_MP_REDUCE_2K_L_C + #define BN_MP_MOD_C + #define BN_MP_COPY_C + #define BN_MP_SQR_C + #define BN_MP_MUL_C + #define BN_MP_SET_C + #define BN_MP_EXCH_C +#endif + +#if defined(BN_S_MP_MUL_DIGS_C) + #define BN_FAST_S_MP_MUL_DIGS_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_MUL_HIGH_DIGS_C) + #define BN_FAST_S_MP_MUL_HIGH_DIGS_C + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_SQR_C) + #define BN_MP_INIT_SIZE_C + #define BN_MP_CLAMP_C + #define BN_MP_EXCH_C + #define BN_MP_CLEAR_C +#endif + +#if defined(BN_S_MP_SUB_C) + #define BN_MP_GROW_C + #define BN_MP_CLAMP_C +#endif + +#if defined(BNCORE_C) +#endif + +#ifdef LTM3 +#define LTM_LAST +#endif +#include "tommath_superclass.h" +#include "tommath_class.h" +#else +#define LTM_LAST +#endif + +/* $Source: /cvs/libtom/libtommath/tommath_class.h,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2005/07/28 11:59:32 $ */ diff --git a/StormLib/src/libtommath/tommath_superclass.h b/StormLib/src/libtommath/tommath_superclass.h new file mode 100644 index 000000000..2fdebe683 --- /dev/null +++ b/StormLib/src/libtommath/tommath_superclass.h @@ -0,0 +1,76 @@ +/* super class file for PK algos */ + +/* default ... include all MPI */ +#define LTM_ALL + +/* RSA only (does not support DH/DSA/ECC) */ +/* #define SC_RSA_1 */ + +/* For reference.... On an Athlon64 optimizing for speed... + + LTM's mpi.o with all functions [striped] is 142KiB in size. + +*/ + +/* Works for RSA only, mpi.o is 68KiB */ +#ifdef SC_RSA_1 + #define BN_MP_SHRINK_C + #define BN_MP_LCM_C + #define BN_MP_PRIME_RANDOM_EX_C + #define BN_MP_INVMOD_C + #define BN_MP_GCD_C + #define BN_MP_MOD_C + #define BN_MP_MULMOD_C + #define BN_MP_ADDMOD_C + #define BN_MP_EXPTMOD_C + #define BN_MP_SET_INT_C + #define BN_MP_INIT_MULTI_C + #define BN_MP_CLEAR_MULTI_C + #define BN_MP_UNSIGNED_BIN_SIZE_C + #define BN_MP_TO_UNSIGNED_BIN_C + #define BN_MP_MOD_D_C + #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C + #define BN_REVERSE_C + #define BN_PRIME_TAB_C + + /* other modifiers */ + #define BN_MP_DIV_SMALL /* Slower division, not critical */ + + /* here we are on the last pass so we turn things off. The functions classes are still there + * but we remove them specifically from the build. This also invokes tweaks in functions + * like removing support for even moduli, etc... + */ +#ifdef LTM_LAST + #undef BN_MP_TOOM_MUL_C + #undef BN_MP_TOOM_SQR_C + #undef BN_MP_KARATSUBA_MUL_C + #undef BN_MP_KARATSUBA_SQR_C + #undef BN_MP_REDUCE_C + #undef BN_MP_REDUCE_SETUP_C + #undef BN_MP_DR_IS_MODULUS_C + #undef BN_MP_DR_SETUP_C + #undef BN_MP_DR_REDUCE_C + #undef BN_MP_REDUCE_IS_2K_C + #undef BN_MP_REDUCE_2K_SETUP_C + #undef BN_MP_REDUCE_2K_C + #undef BN_S_MP_EXPTMOD_C + #undef BN_MP_DIV_3_C + #undef BN_S_MP_MUL_HIGH_DIGS_C + #undef BN_FAST_S_MP_MUL_HIGH_DIGS_C + #undef BN_FAST_MP_INVMOD_C + + /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold + * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines] + * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without + * trouble. + */ + #undef BN_S_MP_MUL_DIGS_C + #undef BN_S_MP_SQR_C + #undef BN_MP_MONTGOMERY_REDUCE_C +#endif + +#endif + +/* $Source: /cvs/libtom/libtommath/tommath_superclass.h,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2005/05/14 13:29:17 $ */ diff --git a/StormLib/src/lzma/C/LzFind.c b/StormLib/src/lzma/C/LzFind.c new file mode 100644 index 000000000..e3ecb0542 --- /dev/null +++ b/StormLib/src/lzma/C/LzFind.c @@ -0,0 +1,761 @@ +/* LzFind.c -- Match finder for LZ algorithms +2009-04-22 : Igor Pavlov : Public domain */ + +#include + +#include "LzFind.h" +#include "LzHash.h" + +#define kEmptyHashValue 0 +#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) +#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ +#define kNormalizeMask (~(kNormalizeStepMin - 1)) +#define kMaxHistorySize ((UInt32)3 << 30) + +#define kStartMaxLen 3 + +static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) +{ + if (!p->directInput) + { + alloc->Free(alloc, p->bufferBase); + p->bufferBase = 0; + } +} + +/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ + +static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) +{ + UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; + if (p->directInput) + { + p->blockSize = blockSize; + return 1; + } + if (p->bufferBase == 0 || p->blockSize != blockSize) + { + LzInWindow_Free(p, alloc); + p->blockSize = blockSize; + p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); + } + return (p->bufferBase != 0); +} + +Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } +Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } + +UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } + +void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) +{ + p->posLimit -= subValue; + p->pos -= subValue; + p->streamPos -= subValue; +} + +static void MatchFinder_ReadBlock(CMatchFinder *p) +{ + if (p->streamEndWasReached || p->result != SZ_OK) + return; + if (p->directInput) + { + UInt32 curSize = 0xFFFFFFFF - p->streamPos; + if (curSize > p->directInputRem) + curSize = (UInt32)p->directInputRem; + p->directInputRem -= curSize; + p->streamPos += curSize; + if (p->directInputRem == 0) + p->streamEndWasReached = 1; + return; + } + for (;;) + { + Byte *dest = p->buffer + (p->streamPos - p->pos); + size_t size = (p->bufferBase + p->blockSize - dest); + if (size == 0) + return; + p->result = p->stream->Read(p->stream, dest, &size); + if (p->result != SZ_OK) + return; + if (size == 0) + { + p->streamEndWasReached = 1; + return; + } + p->streamPos += (UInt32)size; + if (p->streamPos - p->pos > p->keepSizeAfter) + return; + } +} + +void MatchFinder_MoveBlock(CMatchFinder *p) +{ + memmove(p->bufferBase, + p->buffer - p->keepSizeBefore, + (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); + p->buffer = p->bufferBase + p->keepSizeBefore; +} + +int MatchFinder_NeedMove(CMatchFinder *p) +{ + if (p->directInput) + return 0; + /* if (p->streamEndWasReached) return 0; */ + return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); +} + +void MatchFinder_ReadIfRequired(CMatchFinder *p) +{ + if (p->streamEndWasReached) + return; + if (p->keepSizeAfter >= p->streamPos - p->pos) + MatchFinder_ReadBlock(p); +} + +static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) +{ + if (MatchFinder_NeedMove(p)) + MatchFinder_MoveBlock(p); + MatchFinder_ReadBlock(p); +} + +static void MatchFinder_SetDefaultSettings(CMatchFinder *p) +{ + p->cutValue = 32; + p->btMode = 1; + p->numHashBytes = 4; + p->bigHash = 0; +} + +#define kCrcPoly 0xEDB88320 + +void MatchFinder_Construct(CMatchFinder *p) +{ + UInt32 i; + p->bufferBase = 0; + p->directInput = 0; + p->hash = 0; + MatchFinder_SetDefaultSettings(p); + + for (i = 0; i < 256; i++) + { + UInt32 r = i; + int j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); + p->crc[i] = r; + } +} + +static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->hash); + p->hash = 0; +} + +void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) +{ + MatchFinder_FreeThisClassMemory(p, alloc); + LzInWindow_Free(p, alloc); +} + +static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) +{ + size_t sizeInBytes = (size_t)num * sizeof(CLzRef); + if (sizeInBytes / sizeof(CLzRef) != num) + return 0; + return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); +} + +int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, + UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, + ISzAlloc *alloc) +{ + UInt32 sizeReserv; + if (historySize > kMaxHistorySize) + { + MatchFinder_Free(p, alloc); + return 0; + } + sizeReserv = historySize >> 1; + if (historySize > ((UInt32)2 << 30)) + sizeReserv = historySize >> 2; + sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); + + p->keepSizeBefore = historySize + keepAddBufferBefore + 1; + p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; + /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ + if (LzInWindow_Create(p, sizeReserv, alloc)) + { + UInt32 newCyclicBufferSize = historySize + 1; + UInt32 hs; + p->matchMaxLen = matchMaxLen; + { + p->fixedHashSize = 0; + if (p->numHashBytes == 2) + hs = (1 << 16) - 1; + else + { + hs = historySize - 1; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + hs >>= 1; + hs |= 0xFFFF; /* don't change it! It's required for Deflate */ + if (hs > (1 << 24)) + { + if (p->numHashBytes == 3) + hs = (1 << 24) - 1; + else + hs >>= 1; + } + } + p->hashMask = hs; + hs++; + if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; + if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; + if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; + hs += p->fixedHashSize; + } + + { + UInt32 prevSize = p->hashSizeSum + p->numSons; + UInt32 newSize; + p->historySize = historySize; + p->hashSizeSum = hs; + p->cyclicBufferSize = newCyclicBufferSize; + p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); + newSize = p->hashSizeSum + p->numSons; + if (p->hash != 0 && prevSize == newSize) + return 1; + MatchFinder_FreeThisClassMemory(p, alloc); + p->hash = AllocRefs(newSize, alloc); + if (p->hash != 0) + { + p->son = p->hash + p->hashSizeSum; + return 1; + } + } + } + MatchFinder_Free(p, alloc); + return 0; +} + +static void MatchFinder_SetLimits(CMatchFinder *p) +{ + UInt32 limit = kMaxValForNormalize - p->pos; + UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; + if (limit2 < limit) + limit = limit2; + limit2 = p->streamPos - p->pos; + if (limit2 <= p->keepSizeAfter) + { + if (limit2 > 0) + limit2 = 1; + } + else + limit2 -= p->keepSizeAfter; + if (limit2 < limit) + limit = limit2; + { + UInt32 lenLimit = p->streamPos - p->pos; + if (lenLimit > p->matchMaxLen) + lenLimit = p->matchMaxLen; + p->lenLimit = lenLimit; + } + p->posLimit = p->pos + limit; +} + +void MatchFinder_Init(CMatchFinder *p) +{ + UInt32 i; + for (i = 0; i < p->hashSizeSum; i++) + p->hash[i] = kEmptyHashValue; + p->cyclicBufferPos = 0; + p->buffer = p->bufferBase; + p->pos = p->streamPos = p->cyclicBufferSize; + p->result = SZ_OK; + p->streamEndWasReached = 0; + MatchFinder_ReadBlock(p); + MatchFinder_SetLimits(p); +} + +static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) +{ + return (p->pos - p->historySize - 1) & kNormalizeMask; +} + +void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) +{ + UInt32 i; + for (i = 0; i < numItems; i++) + { + UInt32 value = items[i]; + if (value <= subValue) + value = kEmptyHashValue; + else + value -= subValue; + items[i] = value; + } +} + +static void MatchFinder_Normalize(CMatchFinder *p) +{ + UInt32 subValue = MatchFinder_GetSubValue(p); + MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); + MatchFinder_ReduceOffsets(p, subValue); +} + +static void MatchFinder_CheckLimits(CMatchFinder *p) +{ + if (p->pos == kMaxValForNormalize) + MatchFinder_Normalize(p); + if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) + MatchFinder_CheckAndMoveAndRead(p); + if (p->cyclicBufferPos == p->cyclicBufferSize) + p->cyclicBufferPos = 0; + MatchFinder_SetLimits(p); +} + +static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, + UInt32 *distances, UInt32 maxLen) +{ + son[_cyclicBufferPos] = curMatch; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + return distances; + { + const Byte *pb = cur - delta; + curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; + if (pb[maxLen] == cur[maxLen] && *pb == *cur) + { + UInt32 len = 0; + while (++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (maxLen < len) + { + *distances++ = maxLen = len; + *distances++ = delta - 1; + if (len == lenLimit) + return distances; + } + } + } + } +} + +UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, + UInt32 *distances, UInt32 maxLen) +{ + CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; + CLzRef *ptr1 = son + (_cyclicBufferPos << 1); + UInt32 len0 = 0, len1 = 0; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + { + *ptr0 = *ptr1 = kEmptyHashValue; + return distances; + } + { + CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); + const Byte *pb = cur - delta; + UInt32 len = (len0 < len1 ? len0 : len1); + if (pb[len] == cur[len]) + { + if (++len != lenLimit && pb[len] == cur[len]) + while (++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (maxLen < len) + { + *distances++ = maxLen = len; + *distances++ = delta - 1; + if (len == lenLimit) + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return distances; + } + } + } + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + ptr1 = pair + 1; + curMatch = *ptr1; + len1 = len; + } + else + { + *ptr0 = curMatch; + ptr0 = pair; + curMatch = *ptr0; + len0 = len; + } + } + } +} + +static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) +{ + CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; + CLzRef *ptr1 = son + (_cyclicBufferPos << 1); + UInt32 len0 = 0, len1 = 0; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + { + *ptr0 = *ptr1 = kEmptyHashValue; + return; + } + { + CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); + const Byte *pb = cur - delta; + UInt32 len = (len0 < len1 ? len0 : len1); + if (pb[len] == cur[len]) + { + while (++len != lenLimit) + if (pb[len] != cur[len]) + break; + { + if (len == lenLimit) + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return; + } + } + } + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + ptr1 = pair + 1; + curMatch = *ptr1; + len1 = len; + } + else + { + *ptr0 = curMatch; + ptr0 = pair; + curMatch = *ptr0; + len0 = len; + } + } + } +} + +#define MOVE_POS \ + ++p->cyclicBufferPos; \ + p->buffer++; \ + if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); + +#define MOVE_POS_RET MOVE_POS return offset; + +static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } + +#define GET_MATCHES_HEADER2(minLen, ret_op) \ + UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ + lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ + cur = p->buffer; + +#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) +#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue) + +#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue + +#define GET_MATCHES_FOOTER(offset, maxLen) \ + offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ + distances + offset, maxLen) - distances); MOVE_POS_RET; + +#define SKIP_FOOTER \ + SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; + +static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 offset; + GET_MATCHES_HEADER(2) + HASH2_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + offset = 0; + GET_MATCHES_FOOTER(offset, 1) +} + +UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 offset; + GET_MATCHES_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + offset = 0; + GET_MATCHES_FOOTER(offset, 2) +} + +static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 hash2Value, delta2, maxLen, offset; + GET_MATCHES_HEADER(3) + + HASH3_CALC; + + delta2 = p->pos - p->hash[hash2Value]; + curMatch = p->hash[kFix3HashSize + hashValue]; + + p->hash[hash2Value] = + p->hash[kFix3HashSize + hashValue] = p->pos; + + + maxLen = 2; + offset = 0; + if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) + { + for (; maxLen != lenLimit; maxLen++) + if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) + break; + distances[0] = maxLen; + distances[1] = delta2 - 1; + offset = 2; + if (maxLen == lenLimit) + { + SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); + MOVE_POS_RET; + } + } + GET_MATCHES_FOOTER(offset, maxLen) +} + +static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; + GET_MATCHES_HEADER(4) + + HASH4_CALC; + + delta2 = p->pos - p->hash[ hash2Value]; + delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; + curMatch = p->hash[kFix4HashSize + hashValue]; + + p->hash[ hash2Value] = + p->hash[kFix3HashSize + hash3Value] = + p->hash[kFix4HashSize + hashValue] = p->pos; + + maxLen = 1; + offset = 0; + if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) + { + distances[0] = maxLen = 2; + distances[1] = delta2 - 1; + offset = 2; + } + if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) + { + maxLen = 3; + distances[offset + 1] = delta3 - 1; + offset += 2; + delta2 = delta3; + } + if (offset != 0) + { + for (; maxLen != lenLimit; maxLen++) + if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) + break; + distances[offset - 2] = maxLen; + if (maxLen == lenLimit) + { + SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); + MOVE_POS_RET; + } + } + if (maxLen < 3) + maxLen = 3; + GET_MATCHES_FOOTER(offset, maxLen) +} + +static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; + GET_MATCHES_HEADER(4) + + HASH4_CALC; + + delta2 = p->pos - p->hash[ hash2Value]; + delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; + curMatch = p->hash[kFix4HashSize + hashValue]; + + p->hash[ hash2Value] = + p->hash[kFix3HashSize + hash3Value] = + p->hash[kFix4HashSize + hashValue] = p->pos; + + maxLen = 1; + offset = 0; + if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) + { + distances[0] = maxLen = 2; + distances[1] = delta2 - 1; + offset = 2; + } + if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) + { + maxLen = 3; + distances[offset + 1] = delta3 - 1; + offset += 2; + delta2 = delta3; + } + if (offset != 0) + { + for (; maxLen != lenLimit; maxLen++) + if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) + break; + distances[offset - 2] = maxLen; + if (maxLen == lenLimit) + { + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS_RET; + } + } + if (maxLen < 3) + maxLen = 3; + offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), + distances + offset, maxLen) - (distances)); + MOVE_POS_RET +} + +UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 offset; + GET_MATCHES_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), + distances, 2) - (distances)); + MOVE_POS_RET +} + +static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + SKIP_HEADER(2) + HASH2_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + SKIP_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + UInt32 hash2Value; + SKIP_HEADER(3) + HASH3_CALC; + curMatch = p->hash[kFix3HashSize + hashValue]; + p->hash[hash2Value] = + p->hash[kFix3HashSize + hashValue] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + UInt32 hash2Value, hash3Value; + SKIP_HEADER(4) + HASH4_CALC; + curMatch = p->hash[kFix4HashSize + hashValue]; + p->hash[ hash2Value] = + p->hash[kFix3HashSize + hash3Value] = p->pos; + p->hash[kFix4HashSize + hashValue] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + UInt32 hash2Value, hash3Value; + SKIP_HEADER(4) + HASH4_CALC; + curMatch = p->hash[kFix4HashSize + hashValue]; + p->hash[ hash2Value] = + p->hash[kFix3HashSize + hash3Value] = + p->hash[kFix4HashSize + hashValue] = p->pos; + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS + } + while (--num != 0); +} + +void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + SKIP_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS + } + while (--num != 0); +} + +void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) +{ + vTable->Init = (Mf_Init_Func)MatchFinder_Init; + vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; + vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; + vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; + if (!p->btMode) + { + vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; + } + else if (p->numHashBytes == 2) + { + vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; + } + else if (p->numHashBytes == 3) + { + vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; + } + else + { + vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; + } +} diff --git a/StormLib/src/lzma/C/LzFind.h b/StormLib/src/lzma/C/LzFind.h new file mode 100644 index 000000000..010c4b92b --- /dev/null +++ b/StormLib/src/lzma/C/LzFind.h @@ -0,0 +1,115 @@ +/* LzFind.h -- Match finder for LZ algorithms +2009-04-22 : Igor Pavlov : Public domain */ + +#ifndef __LZ_FIND_H +#define __LZ_FIND_H + +#include "Types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef UInt32 CLzRef; + +typedef struct _CMatchFinder +{ + Byte *buffer; + UInt32 pos; + UInt32 posLimit; + UInt32 streamPos; + UInt32 lenLimit; + + UInt32 cyclicBufferPos; + UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ + + UInt32 matchMaxLen; + CLzRef *hash; + CLzRef *son; + UInt32 hashMask; + UInt32 cutValue; + + Byte *bufferBase; + ISeqInStream *stream; + int streamEndWasReached; + + UInt32 blockSize; + UInt32 keepSizeBefore; + UInt32 keepSizeAfter; + + UInt32 numHashBytes; + int directInput; + size_t directInputRem; + int btMode; + int bigHash; + UInt32 historySize; + UInt32 fixedHashSize; + UInt32 hashSizeSum; + UInt32 numSons; + SRes result; + UInt32 crc[256]; +} CMatchFinder; + +#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) +#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) + +#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) + +int MatchFinder_NeedMove(CMatchFinder *p); +Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); +void MatchFinder_MoveBlock(CMatchFinder *p); +void MatchFinder_ReadIfRequired(CMatchFinder *p); + +void MatchFinder_Construct(CMatchFinder *p); + +/* Conditions: + historySize <= 3 GB + keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB +*/ +int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, + UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, + ISzAlloc *alloc); +void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); +void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); +void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); + +UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, + UInt32 *distances, UInt32 maxLen); + +/* +Conditions: + Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. + Mf_GetPointerToCurrentPos_Func's result must be used only before any other function +*/ + +typedef void (*Mf_Init_Func)(void *object); +typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); +typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); +typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); +typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); +typedef void (*Mf_Skip_Func)(void *object, UInt32); + +typedef struct _IMatchFinder +{ + Mf_Init_Func Init; + Mf_GetIndexByte_Func GetIndexByte; + Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; + Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; + Mf_GetMatches_Func GetMatches; + Mf_Skip_Func Skip; +} IMatchFinder; + +void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); + +void MatchFinder_Init(CMatchFinder *p); +UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); +UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); +void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); +void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/StormLib/src/lzma/C/LzFindMt.c b/StormLib/src/lzma/C/LzFindMt.c new file mode 100644 index 000000000..aa41ed98a --- /dev/null +++ b/StormLib/src/lzma/C/LzFindMt.c @@ -0,0 +1,793 @@ +/* LzFindMt.c -- multithreaded Match finder for LZ algorithms +2009-09-20 : Igor Pavlov : Public domain */ + +#include "LzHash.h" + +#include "LzFindMt.h" + +void MtSync_Construct(CMtSync *p) +{ + p->wasCreated = False; + p->csWasInitialized = False; + p->csWasEntered = False; + Thread_Construct(&p->thread); + Event_Construct(&p->canStart); + Event_Construct(&p->wasStarted); + Event_Construct(&p->wasStopped); + Semaphore_Construct(&p->freeSemaphore); + Semaphore_Construct(&p->filledSemaphore); +} + +void MtSync_GetNextBlock(CMtSync *p) +{ + if (p->needStart) + { + p->numProcessedBlocks = 1; + p->needStart = False; + p->stopWriting = False; + p->exit = False; + Event_Reset(&p->wasStarted); + Event_Reset(&p->wasStopped); + + Event_Set(&p->canStart); + Event_Wait(&p->wasStarted); + } + else + { + CriticalSection_Leave(&p->cs); + p->csWasEntered = False; + p->numProcessedBlocks++; + Semaphore_Release1(&p->freeSemaphore); + } + Semaphore_Wait(&p->filledSemaphore); + CriticalSection_Enter(&p->cs); + p->csWasEntered = True; +} + +/* MtSync_StopWriting must be called if Writing was started */ + +void MtSync_StopWriting(CMtSync *p) +{ + UInt32 myNumBlocks = p->numProcessedBlocks; + if (!Thread_WasCreated(&p->thread) || p->needStart) + return; + p->stopWriting = True; + if (p->csWasEntered) + { + CriticalSection_Leave(&p->cs); + p->csWasEntered = False; + } + Semaphore_Release1(&p->freeSemaphore); + + Event_Wait(&p->wasStopped); + + while (myNumBlocks++ != p->numProcessedBlocks) + { + Semaphore_Wait(&p->filledSemaphore); + Semaphore_Release1(&p->freeSemaphore); + } + p->needStart = True; +} + +void MtSync_Destruct(CMtSync *p) +{ + if (Thread_WasCreated(&p->thread)) + { + MtSync_StopWriting(p); + p->exit = True; + if (p->needStart) + Event_Set(&p->canStart); + Thread_Wait(&p->thread); + Thread_Close(&p->thread); + } + if (p->csWasInitialized) + { + CriticalSection_Delete(&p->cs); + p->csWasInitialized = False; + } + + Event_Close(&p->canStart); + Event_Close(&p->wasStarted); + Event_Close(&p->wasStopped); + Semaphore_Close(&p->freeSemaphore); + Semaphore_Close(&p->filledSemaphore); + + p->wasCreated = False; +} + +#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; } + +static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks) +{ + if (p->wasCreated) + return SZ_OK; + + RINOK_THREAD(CriticalSection_Init(&p->cs)); + p->csWasInitialized = True; + + RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart)); + RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStarted)); + RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped)); + + RINOK_THREAD(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks)); + RINOK_THREAD(Semaphore_Create(&p->filledSemaphore, 0, numBlocks)); + + p->needStart = True; + + RINOK_THREAD(Thread_Create(&p->thread, startAddress, obj)); + p->wasCreated = True; + return SZ_OK; +} + +static SRes MtSync_Create(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks) +{ + SRes res = MtSync_Create2(p, startAddress, obj, numBlocks); + if (res != SZ_OK) + MtSync_Destruct(p); + return res; +} + +void MtSync_Init(CMtSync *p) { p->needStart = True; } + +#define kMtMaxValForNormalize 0xFFFFFFFF + +#define DEF_GetHeads2(name, v, action) \ +static void GetHeads ## name(const Byte *p, UInt32 pos, \ +UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \ +{ action; for (; numHeads != 0; numHeads--) { \ +const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } } + +#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;) + +DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; ) +DEF_GetHeads(3, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask) +DEF_GetHeads(4, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask) +DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask) +/* DEF_GetHeads(5, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) */ + +void HashThreadFunc(CMatchFinderMt *mt) +{ + CMtSync *p = &mt->hashSync; + for (;;) + { + UInt32 numProcessedBlocks = 0; + Event_Wait(&p->canStart); + Event_Set(&p->wasStarted); + for (;;) + { + if (p->exit) + return; + if (p->stopWriting) + { + p->numProcessedBlocks = numProcessedBlocks; + Event_Set(&p->wasStopped); + break; + } + + { + CMatchFinder *mf = mt->MatchFinder; + if (MatchFinder_NeedMove(mf)) + { + CriticalSection_Enter(&mt->btSync.cs); + CriticalSection_Enter(&mt->hashSync.cs); + { + const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf); + const Byte *afterPtr; + MatchFinder_MoveBlock(mf); + afterPtr = MatchFinder_GetPointerToCurrentPos(mf); + mt->pointerToCurPos -= beforePtr - afterPtr; + mt->buffer -= beforePtr - afterPtr; + } + CriticalSection_Leave(&mt->btSync.cs); + CriticalSection_Leave(&mt->hashSync.cs); + continue; + } + + Semaphore_Wait(&p->freeSemaphore); + + MatchFinder_ReadIfRequired(mf); + if (mf->pos > (kMtMaxValForNormalize - kMtHashBlockSize)) + { + UInt32 subValue = (mf->pos - mf->historySize - 1); + MatchFinder_ReduceOffsets(mf, subValue); + MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, mf->hashMask + 1); + } + { + UInt32 *heads = mt->hashBuf + ((numProcessedBlocks++) & kMtHashNumBlocksMask) * kMtHashBlockSize; + UInt32 num = mf->streamPos - mf->pos; + heads[0] = 2; + heads[1] = num; + if (num >= mf->numHashBytes) + { + num = num - mf->numHashBytes + 1; + if (num > kMtHashBlockSize - 2) + num = kMtHashBlockSize - 2; + mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc); + heads[0] += num; + } + mf->pos += num; + mf->buffer += num; + } + } + + Semaphore_Release1(&p->filledSemaphore); + } + } +} + +void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p) +{ + MtSync_GetNextBlock(&p->hashSync); + p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize; + p->hashBufPosLimit += p->hashBuf[p->hashBufPos++]; + p->hashNumAvail = p->hashBuf[p->hashBufPos++]; +} + +#define kEmptyHashValue 0 + +/* #define MFMT_GM_INLINE */ + +#ifdef MFMT_GM_INLINE + +#define NO_INLINE MY_FAST_CALL + +Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, + UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes) +{ + do + { + UInt32 *distances = _distances + 1; + UInt32 curMatch = pos - *hash++; + + CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; + CLzRef *ptr1 = son + (_cyclicBufferPos << 1); + UInt32 len0 = 0, len1 = 0; + UInt32 cutValue = _cutValue; + UInt32 maxLen = _maxLen; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + { + *ptr0 = *ptr1 = kEmptyHashValue; + break; + } + { + CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); + const Byte *pb = cur - delta; + UInt32 len = (len0 < len1 ? len0 : len1); + if (pb[len] == cur[len]) + { + if (++len != lenLimit && pb[len] == cur[len]) + while (++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (maxLen < len) + { + *distances++ = maxLen = len; + *distances++ = delta - 1; + if (len == lenLimit) + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + break; + } + } + } + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + ptr1 = pair + 1; + curMatch = *ptr1; + len1 = len; + } + else + { + *ptr0 = curMatch; + ptr0 = pair; + curMatch = *ptr0; + len0 = len; + } + } + } + pos++; + _cyclicBufferPos++; + cur++; + { + UInt32 num = (UInt32)(distances - _distances); + *_distances = num - 1; + _distances += num; + limit -= num; + } + } + while (limit > 0 && --size != 0); + *posRes = pos; + return limit; +} + +#endif + +void BtGetMatches(CMatchFinderMt *p, UInt32 *distances) +{ + UInt32 numProcessed = 0; + UInt32 curPos = 2; + UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2); + distances[1] = p->hashNumAvail; + while (curPos < limit) + { + if (p->hashBufPos == p->hashBufPosLimit) + { + MatchFinderMt_GetNextBlock_Hash(p); + distances[1] = numProcessed + p->hashNumAvail; + if (p->hashNumAvail >= p->numHashBytes) + continue; + for (; p->hashNumAvail != 0; p->hashNumAvail--) + distances[curPos++] = 0; + break; + } + { + UInt32 size = p->hashBufPosLimit - p->hashBufPos; + UInt32 lenLimit = p->matchMaxLen; + UInt32 pos = p->pos; + UInt32 cyclicBufferPos = p->cyclicBufferPos; + if (lenLimit >= p->hashNumAvail) + lenLimit = p->hashNumAvail; + { + UInt32 size2 = p->hashNumAvail - lenLimit + 1; + if (size2 < size) + size = size2; + size2 = p->cyclicBufferSize - cyclicBufferPos; + if (size2 < size) + size = size2; + } + #ifndef MFMT_GM_INLINE + while (curPos < limit && size-- != 0) + { + UInt32 *startDistances = distances + curPos; + UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++], + pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue, + startDistances + 1, p->numHashBytes - 1) - startDistances); + *startDistances = num - 1; + curPos += num; + cyclicBufferPos++; + pos++; + p->buffer++; + } + #else + { + UInt32 posRes; + curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue, + distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos) , size, &posRes); + p->hashBufPos += posRes - pos; + cyclicBufferPos += posRes - pos; + p->buffer += posRes - pos; + pos = posRes; + } + #endif + + numProcessed += pos - p->pos; + p->hashNumAvail -= pos - p->pos; + p->pos = pos; + if (cyclicBufferPos == p->cyclicBufferSize) + cyclicBufferPos = 0; + p->cyclicBufferPos = cyclicBufferPos; + } + } + distances[0] = curPos; +} + +void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex) +{ + CMtSync *sync = &p->hashSync; + if (!sync->needStart) + { + CriticalSection_Enter(&sync->cs); + sync->csWasEntered = True; + } + + BtGetMatches(p, p->btBuf + (globalBlockIndex & kMtBtNumBlocksMask) * kMtBtBlockSize); + + if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize) + { + UInt32 subValue = p->pos - p->cyclicBufferSize; + MatchFinder_Normalize3(subValue, p->son, p->cyclicBufferSize * 2); + p->pos -= subValue; + } + + if (!sync->needStart) + { + CriticalSection_Leave(&sync->cs); + sync->csWasEntered = False; + } +} + +void BtThreadFunc(CMatchFinderMt *mt) +{ + CMtSync *p = &mt->btSync; + for (;;) + { + UInt32 blockIndex = 0; + Event_Wait(&p->canStart); + Event_Set(&p->wasStarted); + for (;;) + { + if (p->exit) + return; + if (p->stopWriting) + { + p->numProcessedBlocks = blockIndex; + MtSync_StopWriting(&mt->hashSync); + Event_Set(&p->wasStopped); + break; + } + Semaphore_Wait(&p->freeSemaphore); + BtFillBlock(mt, blockIndex++); + Semaphore_Release1(&p->filledSemaphore); + } + } +} + +void MatchFinderMt_Construct(CMatchFinderMt *p) +{ + p->hashBuf = 0; + MtSync_Construct(&p->hashSync); + MtSync_Construct(&p->btSync); +} + +void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->hashBuf); + p->hashBuf = 0; +} + +void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc) +{ + MtSync_Destruct(&p->hashSync); + MtSync_Destruct(&p->btSync); + MatchFinderMt_FreeMem(p, alloc); +} + +#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks) +#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks) + +static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; } +static unsigned MY_STD_CALL BtThreadFunc2(void *p) +{ + Byte allocaDummy[0x180]; + int i = 0; + for (i = 0; i < 16; i++) + allocaDummy[i] = (Byte)i; + BtThreadFunc((CMatchFinderMt *)p); + return 0; +} + +SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc) +{ + CMatchFinder *mf = p->MatchFinder; + p->historySize = historySize; + if (kMtBtBlockSize <= matchMaxLen * 4) + return SZ_ERROR_PARAM; + if (p->hashBuf == 0) + { + p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32)); + if (p->hashBuf == 0) + return SZ_ERROR_MEM; + p->btBuf = p->hashBuf + kHashBufferSize; + } + keepAddBufferBefore += (kHashBufferSize + kBtBufferSize); + keepAddBufferAfter += kMtHashBlockSize; + if (!MatchFinder_Create(mf, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter, alloc)) + return SZ_ERROR_MEM; + + RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p, kMtHashNumBlocks)); + RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p, kMtBtNumBlocks)); + return SZ_OK; +} + +/* Call it after ReleaseStream / SetStream */ +void MatchFinderMt_Init(CMatchFinderMt *p) +{ + CMatchFinder *mf = p->MatchFinder; + p->btBufPos = p->btBufPosLimit = 0; + p->hashBufPos = p->hashBufPosLimit = 0; + MatchFinder_Init(mf); + p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf); + p->btNumAvailBytes = 0; + p->lzPos = p->historySize + 1; + + p->hash = mf->hash; + p->fixedHashSize = mf->fixedHashSize; + p->crc = mf->crc; + + p->son = mf->son; + p->matchMaxLen = mf->matchMaxLen; + p->numHashBytes = mf->numHashBytes; + p->pos = mf->pos; + p->buffer = mf->buffer; + p->cyclicBufferPos = mf->cyclicBufferPos; + p->cyclicBufferSize = mf->cyclicBufferSize; + p->cutValue = mf->cutValue; +} + +/* ReleaseStream is required to finish multithreading */ +void MatchFinderMt_ReleaseStream(CMatchFinderMt *p) +{ + MtSync_StopWriting(&p->btSync); + /* p->MatchFinder->ReleaseStream(); */ +} + +void MatchFinderMt_Normalize(CMatchFinderMt *p) +{ + MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize); + p->lzPos = p->historySize + 1; +} + +void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p) +{ + UInt32 blockIndex; + MtSync_GetNextBlock(&p->btSync); + blockIndex = ((p->btSync.numProcessedBlocks - 1) & kMtBtNumBlocksMask); + p->btBufPosLimit = p->btBufPos = blockIndex * kMtBtBlockSize; + p->btBufPosLimit += p->btBuf[p->btBufPos++]; + p->btNumAvailBytes = p->btBuf[p->btBufPos++]; + if (p->lzPos >= kMtMaxValForNormalize - kMtBtBlockSize) + MatchFinderMt_Normalize(p); +} + +const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p) +{ + return p->pointerToCurPos; +} + +#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p); + +UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p) +{ + GET_NEXT_BLOCK_IF_REQUIRED; + return p->btNumAvailBytes; +} + +Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index) +{ + return p->pointerToCurPos[index]; +} + +UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) +{ + UInt32 hash2Value, curMatch2; + UInt32 *hash = p->hash; + const Byte *cur = p->pointerToCurPos; + UInt32 lzPos = p->lzPos; + MT_HASH2_CALC + + curMatch2 = hash[hash2Value]; + hash[hash2Value] = lzPos; + + if (curMatch2 >= matchMinPos) + if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) + { + *distances++ = 2; + *distances++ = lzPos - curMatch2 - 1; + } + return distances; +} + +UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) +{ + UInt32 hash2Value, hash3Value, curMatch2, curMatch3; + UInt32 *hash = p->hash; + const Byte *cur = p->pointerToCurPos; + UInt32 lzPos = p->lzPos; + MT_HASH3_CALC + + curMatch2 = hash[ hash2Value]; + curMatch3 = hash[kFix3HashSize + hash3Value]; + + hash[ hash2Value] = + hash[kFix3HashSize + hash3Value] = + lzPos; + + if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) + { + distances[1] = lzPos - curMatch2 - 1; + if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2]) + { + distances[0] = 3; + return distances + 2; + } + distances[0] = 2; + distances += 2; + } + if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0]) + { + *distances++ = 3; + *distances++ = lzPos - curMatch3 - 1; + } + return distances; +} + +/* +UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) +{ + UInt32 hash2Value, hash3Value, hash4Value, curMatch2, curMatch3, curMatch4; + UInt32 *hash = p->hash; + const Byte *cur = p->pointerToCurPos; + UInt32 lzPos = p->lzPos; + MT_HASH4_CALC + + curMatch2 = hash[ hash2Value]; + curMatch3 = hash[kFix3HashSize + hash3Value]; + curMatch4 = hash[kFix4HashSize + hash4Value]; + + hash[ hash2Value] = + hash[kFix3HashSize + hash3Value] = + hash[kFix4HashSize + hash4Value] = + lzPos; + + if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) + { + distances[1] = lzPos - curMatch2 - 1; + if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2]) + { + distances[0] = (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3; + return distances + 2; + } + distances[0] = 2; + distances += 2; + } + if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0]) + { + distances[1] = lzPos - curMatch3 - 1; + if (cur[(ptrdiff_t)curMatch3 - lzPos + 3] == cur[3]) + { + distances[0] = 4; + return distances + 2; + } + distances[0] = 3; + distances += 2; + } + + if (curMatch4 >= matchMinPos) + if ( + cur[(ptrdiff_t)curMatch4 - lzPos] == cur[0] && + cur[(ptrdiff_t)curMatch4 - lzPos + 3] == cur[3] + ) + { + *distances++ = 4; + *distances++ = lzPos - curMatch4 - 1; + } + return distances; +} +*/ + +#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++; + +UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances) +{ + const UInt32 *btBuf = p->btBuf + p->btBufPos; + UInt32 len = *btBuf++; + p->btBufPos += 1 + len; + p->btNumAvailBytes--; + { + UInt32 i; + for (i = 0; i < len; i += 2) + { + *distances++ = *btBuf++; + *distances++ = *btBuf++; + } + } + INCREASE_LZ_POS + return len; +} + +UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances) +{ + const UInt32 *btBuf = p->btBuf + p->btBufPos; + UInt32 len = *btBuf++; + p->btBufPos += 1 + len; + + if (len == 0) + { + if (p->btNumAvailBytes-- >= 4) + len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances)); + } + else + { + /* Condition: there are matches in btBuf with length < p->numHashBytes */ + UInt32 *distances2; + p->btNumAvailBytes--; + distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances); + do + { + *distances2++ = *btBuf++; + *distances2++ = *btBuf++; + } + while ((len -= 2) != 0); + len = (UInt32)(distances2 - (distances)); + } + INCREASE_LZ_POS + return len; +} + +#define SKIP_HEADER2_MT do { GET_NEXT_BLOCK_IF_REQUIRED +#define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash; +#define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0); + +void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num) +{ + SKIP_HEADER2_MT { p->btNumAvailBytes--; + SKIP_FOOTER_MT +} + +void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num) +{ + SKIP_HEADER_MT(2) + UInt32 hash2Value; + MT_HASH2_CALC + hash[hash2Value] = p->lzPos; + SKIP_FOOTER_MT +} + +void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num) +{ + SKIP_HEADER_MT(3) + UInt32 hash2Value, hash3Value; + MT_HASH3_CALC + hash[kFix3HashSize + hash3Value] = + hash[ hash2Value] = + p->lzPos; + SKIP_FOOTER_MT +} + +/* +void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num) +{ + SKIP_HEADER_MT(4) + UInt32 hash2Value, hash3Value, hash4Value; + MT_HASH4_CALC + hash[kFix4HashSize + hash4Value] = + hash[kFix3HashSize + hash3Value] = + hash[ hash2Value] = + p->lzPos; + SKIP_FOOTER_MT +} +*/ + +void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable) +{ + vTable->Init = (Mf_Init_Func)MatchFinderMt_Init; + vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinderMt_GetIndexByte; + vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes; + vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos; + vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches; + switch(p->MatchFinder->numHashBytes) + { + case 2: + p->GetHeadsFunc = GetHeads2; + p->MixMatchesFunc = (Mf_Mix_Matches)0; + vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip; + vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches; + break; + case 3: + p->GetHeadsFunc = GetHeads3; + p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches2; + vTable->Skip = (Mf_Skip_Func)MatchFinderMt2_Skip; + break; + default: + /* case 4: */ + p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4; + /* p->GetHeadsFunc = GetHeads4; */ + p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3; + vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip; + break; + /* + default: + p->GetHeadsFunc = GetHeads5; + p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches4; + vTable->Skip = (Mf_Skip_Func)MatchFinderMt4_Skip; + break; + */ + } +} diff --git a/StormLib/src/lzma/C/LzFindMt.h b/StormLib/src/lzma/C/LzFindMt.h new file mode 100644 index 000000000..b985af5fe --- /dev/null +++ b/StormLib/src/lzma/C/LzFindMt.h @@ -0,0 +1,105 @@ +/* LzFindMt.h -- multithreaded Match finder for LZ algorithms +2009-02-07 : Igor Pavlov : Public domain */ + +#ifndef __LZ_FIND_MT_H +#define __LZ_FIND_MT_H + +#include "LzFind.h" +#include "Threads.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define kMtHashBlockSize (1 << 13) +#define kMtHashNumBlocks (1 << 3) +#define kMtHashNumBlocksMask (kMtHashNumBlocks - 1) + +#define kMtBtBlockSize (1 << 14) +#define kMtBtNumBlocks (1 << 6) +#define kMtBtNumBlocksMask (kMtBtNumBlocks - 1) + +typedef struct _CMtSync +{ + Bool wasCreated; + Bool needStart; + Bool exit; + Bool stopWriting; + + CThread thread; + CAutoResetEvent canStart; + CAutoResetEvent wasStarted; + CAutoResetEvent wasStopped; + CSemaphore freeSemaphore; + CSemaphore filledSemaphore; + Bool csWasInitialized; + Bool csWasEntered; + CCriticalSection cs; + UInt32 numProcessedBlocks; +} CMtSync; + +typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances); + +/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */ +#define kMtCacheLineDummy 128 + +typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos, + UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc); + +typedef struct _CMatchFinderMt +{ + /* LZ */ + const Byte *pointerToCurPos; + UInt32 *btBuf; + UInt32 btBufPos; + UInt32 btBufPosLimit; + UInt32 lzPos; + UInt32 btNumAvailBytes; + + UInt32 *hash; + UInt32 fixedHashSize; + UInt32 historySize; + const UInt32 *crc; + + Mf_Mix_Matches MixMatchesFunc; + + /* LZ + BT */ + CMtSync btSync; + Byte btDummy[kMtCacheLineDummy]; + + /* BT */ + UInt32 *hashBuf; + UInt32 hashBufPos; + UInt32 hashBufPosLimit; + UInt32 hashNumAvail; + + CLzRef *son; + UInt32 matchMaxLen; + UInt32 numHashBytes; + UInt32 pos; + Byte *buffer; + UInt32 cyclicBufferPos; + UInt32 cyclicBufferSize; /* it must be historySize + 1 */ + UInt32 cutValue; + + /* BT + Hash */ + CMtSync hashSync; + /* Byte hashDummy[kMtCacheLineDummy]; */ + + /* Hash */ + Mf_GetHeads GetHeadsFunc; + CMatchFinder *MatchFinder; +} CMatchFinderMt; + +void MatchFinderMt_Construct(CMatchFinderMt *p); +void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc); +SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc); +void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable); +void MatchFinderMt_ReleaseStream(CMatchFinderMt *p); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/StormLib/src/lzma/C/LzHash.h b/StormLib/src/lzma/C/LzHash.h new file mode 100644 index 000000000..f3e89966c --- /dev/null +++ b/StormLib/src/lzma/C/LzHash.h @@ -0,0 +1,54 @@ +/* LzHash.h -- HASH functions for LZ algorithms +2009-02-07 : Igor Pavlov : Public domain */ + +#ifndef __LZ_HASH_H +#define __LZ_HASH_H + +#define kHash2Size (1 << 10) +#define kHash3Size (1 << 16) +#define kHash4Size (1 << 20) + +#define kFix3HashSize (kHash2Size) +#define kFix4HashSize (kHash2Size + kHash3Size) +#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) + +#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); + +#define HASH3_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } + +#define HASH4_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ + hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } + +#define HASH5_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ + hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ + hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ + hash4Value &= (kHash4Size - 1); } + +/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ +#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; + + +#define MT_HASH2_CALC \ + hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); + +#define MT_HASH3_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } + +#define MT_HASH4_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ + hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } + +#endif diff --git a/StormLib/src/lzma/C/LzmaDec.c b/StormLib/src/lzma/C/LzmaDec.c new file mode 100644 index 000000000..2036761bf --- /dev/null +++ b/StormLib/src/lzma/C/LzmaDec.c @@ -0,0 +1,999 @@ +/* LzmaDec.c -- LZMA Decoder +2009-09-20 : Igor Pavlov : Public domain */ + +#include "LzmaDec.h" + +#include + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_INIT_SIZE 5 + +#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } + +#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) +#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); +#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); +#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ + { UPDATE_0(p); i = (i + i); A0; } else \ + { UPDATE_1(p); i = (i + i) + 1; A1; } +#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) + +#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } +#define TREE_DECODE(probs, limit, i) \ + { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } + +/* #define _LZMA_SIZE_OPT */ + +#ifdef _LZMA_SIZE_OPT +#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) +#else +#define TREE_6_DECODE(probs, i) \ + { i = 1; \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + i -= 0x40; } +#endif + +#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } + +#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) +#define UPDATE_0_CHECK range = bound; +#define UPDATE_1_CHECK range -= bound; code -= bound; +#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ + { UPDATE_0_CHECK; i = (i + i); A0; } else \ + { UPDATE_1_CHECK; i = (i + i) + 1; A1; } +#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) +#define TREE_DECODE_CHECK(probs, limit, i) \ + { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 +#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +#define LZMA_DIC_MIN (1 << 12) + +/* First LZMA-symbol is always decoded. +And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization +Out: + Result: + SZ_OK - OK + SZ_ERROR_DATA - Error + p->remainLen: + < kMatchSpecLenStart : normal remain + = kMatchSpecLenStart : finished + = kMatchSpecLenStart + 1 : Flush marker + = kMatchSpecLenStart + 2 : State Init Marker +*/ + +static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +{ + CLzmaProb *probs = p->probs; + + unsigned state = p->state; + UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; + unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; + unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; + unsigned lc = p->prop.lc; + + Byte *dic = p->dic; + SizeT dicBufSize = p->dicBufSize; + SizeT dicPos = p->dicPos; + + UInt32 processedPos = p->processedPos; + UInt32 checkDicSize = p->checkDicSize; + unsigned len = 0; + + const Byte *buf = p->buf; + UInt32 range = p->range; + UInt32 code = p->code; + + do + { + CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = processedPos & pbMask; + + prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; + IF_BIT_0(prob) + { + unsigned symbol; + UPDATE_0(prob); + prob = probs + Literal; + if (checkDicSize != 0 || processedPos != 0) + prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + + (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); + + if (state < kNumLitStates) + { + state -= (state < 4) ? state : 3; + symbol = 1; + do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); + } + else + { + unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + unsigned offs = 0x100; + state -= (state < 10) ? 3 : 6; + symbol = 1; + do + { + unsigned bit; + CLzmaProb *probLit; + matchByte <<= 1; + bit = (matchByte & offs); + probLit = prob + offs + bit + symbol; + GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) + } + while (symbol < 0x100); + } + dic[dicPos++] = (Byte)symbol; + processedPos++; + continue; + } + else + { + UPDATE_1(prob); + prob = probs + IsRep + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + state += kNumStates; + prob = probs + LenCoder; + } + else + { + UPDATE_1(prob); + if (checkDicSize == 0 && processedPos == 0) + return SZ_ERROR_DATA; + prob = probs + IsRepG0 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; + IF_BIT_0(prob) + { + UPDATE_0(prob); + dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + dicPos++; + processedPos++; + state = state < kNumLitStates ? 9 : 11; + continue; + } + UPDATE_1(prob); + } + else + { + UInt32 distance; + UPDATE_1(prob); + prob = probs + IsRepG1 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + distance = rep1; + } + else + { + UPDATE_1(prob); + prob = probs + IsRepG2 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + distance = rep2; + } + else + { + UPDATE_1(prob); + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = probs + RepLenCoder; + } + { + unsigned limit, offset; + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0(probLen) + { + UPDATE_0(probLen); + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + limit = (1 << kLenNumLowBits); + } + else + { + UPDATE_1(probLen); + probLen = prob + LenChoice2; + IF_BIT_0(probLen) + { + UPDATE_0(probLen); + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + limit = (1 << kLenNumMidBits); + } + else + { + UPDATE_1(probLen); + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + limit = (1 << kLenNumHighBits); + } + } + TREE_DECODE(probLen, limit, len); + len += offset; + } + + if (state >= kNumStates) + { + UInt32 distance; + prob = probs + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); + TREE_6_DECODE(prob, distance); + if (distance >= kStartPosModelIndex) + { + unsigned posSlot = (unsigned)distance; + int numDirectBits = (int)(((distance >> 1) - 1)); + distance = (2 | (distance & 1)); + if (posSlot < kEndPosModelIndex) + { + distance <<= numDirectBits; + prob = probs + SpecPos + distance - posSlot - 1; + { + UInt32 mask = 1; + unsigned i = 1; + do + { + GET_BIT2(prob + i, i, ; , distance |= mask); + mask <<= 1; + } + while (--numDirectBits != 0); + } + } + else + { + numDirectBits -= kNumAlignBits; + do + { + NORMALIZE + range >>= 1; + + { + UInt32 t; + code -= range; + t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ + distance = (distance << 1) + (t + 1); + code += range & t; + } + /* + distance <<= 1; + if (code >= range) + { + code -= range; + distance |= 1; + } + */ + } + while (--numDirectBits != 0); + prob = probs + Align; + distance <<= kNumAlignBits; + { + unsigned i = 1; + GET_BIT2(prob + i, i, ; , distance |= 1); + GET_BIT2(prob + i, i, ; , distance |= 2); + GET_BIT2(prob + i, i, ; , distance |= 4); + GET_BIT2(prob + i, i, ; , distance |= 8); + } + if (distance == (UInt32)0xFFFFFFFF) + { + len += kMatchSpecLenStart; + state -= kNumStates; + break; + } + } + } + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + rep0 = distance + 1; + if (checkDicSize == 0) + { + if (distance >= processedPos) + return SZ_ERROR_DATA; + } + else if (distance >= checkDicSize) + return SZ_ERROR_DATA; + state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; + } + + len += kMatchMinLen; + + if (limit == dicPos) + return SZ_ERROR_DATA; + { + SizeT rem = limit - dicPos; + unsigned curLen = ((rem < len) ? (unsigned)rem : len); + SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); + + processedPos += curLen; + + len -= curLen; + if (pos + curLen <= dicBufSize) + { + Byte *dest = dic + dicPos; + ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; + const Byte *lim = dest + curLen; + dicPos += curLen; + do + *(dest) = (Byte)*(dest + src); + while (++dest != lim); + } + else + { + do + { + dic[dicPos++] = dic[pos]; + if (++pos == dicBufSize) + pos = 0; + } + while (--curLen != 0); + } + } + } + } + while (dicPos < limit && buf < bufLimit); + NORMALIZE; + p->buf = buf; + p->range = range; + p->code = code; + p->remainLen = len; + p->dicPos = dicPos; + p->processedPos = processedPos; + p->reps[0] = rep0; + p->reps[1] = rep1; + p->reps[2] = rep2; + p->reps[3] = rep3; + p->state = state; + + return SZ_OK; +} + +static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) +{ + if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) + { + Byte *dic = p->dic; + SizeT dicPos = p->dicPos; + SizeT dicBufSize = p->dicBufSize; + unsigned len = p->remainLen; + UInt32 rep0 = p->reps[0]; + if (limit - dicPos < len) + len = (unsigned)(limit - dicPos); + + if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) + p->checkDicSize = p->prop.dicSize; + + p->processedPos += len; + p->remainLen -= len; + while (len-- != 0) + { + dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + dicPos++; + } + p->dicPos = dicPos; + } +} + +static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +{ + do + { + SizeT limit2 = limit; + if (p->checkDicSize == 0) + { + UInt32 rem = p->prop.dicSize - p->processedPos; + if (limit - p->dicPos > rem) + limit2 = p->dicPos + rem; + } + RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); + if (p->processedPos >= p->prop.dicSize) + p->checkDicSize = p->prop.dicSize; + LzmaDec_WriteRem(p, limit); + } + while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); + + if (p->remainLen > kMatchSpecLenStart) + { + p->remainLen = kMatchSpecLenStart; + } + return 0; +} + +typedef enum +{ + DUMMY_ERROR, /* unexpected end of input stream */ + DUMMY_LIT, + DUMMY_MATCH, + DUMMY_REP +} ELzmaDummy; + +static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) +{ + UInt32 range = p->range; + UInt32 code = p->code; + const Byte *bufLimit = buf + inSize; + CLzmaProb *probs = p->probs; + unsigned state = p->state; + ELzmaDummy res; + + { + CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); + + prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + + /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ + + prob = probs + Literal; + if (p->checkDicSize != 0 || p->processedPos != 0) + prob += (LZMA_LIT_SIZE * + ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + + (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); + + if (state < kNumLitStates) + { + unsigned symbol = 1; + do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); + } + else + { + unsigned matchByte = p->dic[p->dicPos - p->reps[0] + + ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; + unsigned offs = 0x100; + unsigned symbol = 1; + do + { + unsigned bit; + CLzmaProb *probLit; + matchByte <<= 1; + bit = (matchByte & offs); + probLit = prob + offs + bit + symbol; + GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) + } + while (symbol < 0x100); + } + res = DUMMY_LIT; + } + else + { + unsigned len; + UPDATE_1_CHECK; + + prob = probs + IsRep + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + state = 0; + prob = probs + LenCoder; + res = DUMMY_MATCH; + } + else + { + UPDATE_1_CHECK; + res = DUMMY_REP; + prob = probs + IsRepG0 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + NORMALIZE_CHECK; + return DUMMY_REP; + } + else + { + UPDATE_1_CHECK; + } + } + else + { + UPDATE_1_CHECK; + prob = probs + IsRepG1 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + } + else + { + UPDATE_1_CHECK; + prob = probs + IsRepG2 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + } + else + { + UPDATE_1_CHECK; + } + } + } + state = kNumStates; + prob = probs + RepLenCoder; + } + { + unsigned limit, offset; + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK; + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + limit = 1 << kLenNumLowBits; + } + else + { + UPDATE_1_CHECK; + probLen = prob + LenChoice2; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK; + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + limit = 1 << kLenNumMidBits; + } + else + { + UPDATE_1_CHECK; + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + limit = 1 << kLenNumHighBits; + } + } + TREE_DECODE_CHECK(probLen, limit, len); + len += offset; + } + + if (state < 4) + { + unsigned posSlot; + prob = probs + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + + /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ + + if (posSlot < kEndPosModelIndex) + { + prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; + } + else + { + numDirectBits -= kNumAlignBits; + do + { + NORMALIZE_CHECK + range >>= 1; + code -= range & (((code - range) >> 31) - 1); + /* if (code >= range) code -= range; */ + } + while (--numDirectBits != 0); + prob = probs + Align; + numDirectBits = kNumAlignBits; + } + { + unsigned i = 1; + do + { + GET_BIT_CHECK(prob + i, i); + } + while (--numDirectBits != 0); + } + } + } + } + } + NORMALIZE_CHECK; + return res; +} + + +static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) +{ + p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); + p->range = 0xFFFFFFFF; + p->needFlush = 0; +} + +void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) +{ + p->needFlush = 1; + p->remainLen = 0; + p->tempBufSize = 0; + + if (initDic) + { + p->processedPos = 0; + p->checkDicSize = 0; + p->needInitState = 1; + } + if (initState) + p->needInitState = 1; +} + +void LzmaDec_Init(CLzmaDec *p) +{ + p->dicPos = 0; + LzmaDec_InitDicAndState(p, True, True); +} + +static void LzmaDec_InitStateReal(CLzmaDec *p) +{ + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); + UInt32 i; + CLzmaProb *probs = p->probs; + for (i = 0; i < numProbs; i++) + probs[i] = kBitModelTotal >> 1; + p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; + p->state = 0; + p->needInitState = 0; +} + +SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, + ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT inSize = *srcLen; + (*srcLen) = 0; + LzmaDec_WriteRem(p, dicLimit); + + *status = LZMA_STATUS_NOT_SPECIFIED; + + while (p->remainLen != kMatchSpecLenStart) + { + int checkEndMarkNow; + + if (p->needFlush != 0) + { + for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) + p->tempBuf[p->tempBufSize++] = *src++; + if (p->tempBufSize < RC_INIT_SIZE) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (p->tempBuf[0] != 0) + return SZ_ERROR_DATA; + + LzmaDec_InitRc(p, p->tempBuf); + p->tempBufSize = 0; + } + + checkEndMarkNow = 0; + if (p->dicPos >= dicLimit) + { + if (p->remainLen == 0 && p->code == 0) + { + *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; + return SZ_OK; + } + if (finishMode == LZMA_FINISH_ANY) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_OK; + } + if (p->remainLen != 0) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + checkEndMarkNow = 1; + } + + if (p->needInitState) + LzmaDec_InitStateReal(p); + + if (p->tempBufSize == 0) + { + SizeT processed; + const Byte *bufLimit; + if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + int dummyRes = LzmaDec_TryDummy(p, src, inSize); + if (dummyRes == DUMMY_ERROR) + { + memcpy(p->tempBuf, src, inSize); + p->tempBufSize = (unsigned)inSize; + (*srcLen) += inSize; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (checkEndMarkNow && dummyRes != DUMMY_MATCH) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + bufLimit = src; + } + else + bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; + p->buf = src; + if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) + return SZ_ERROR_DATA; + processed = (SizeT)(p->buf - src); + (*srcLen) += processed; + src += processed; + inSize -= processed; + } + else + { + unsigned rem = p->tempBufSize, lookAhead = 0; + while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) + p->tempBuf[rem++] = src[lookAhead++]; + p->tempBufSize = rem; + if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); + if (dummyRes == DUMMY_ERROR) + { + (*srcLen) += lookAhead; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (checkEndMarkNow && dummyRes != DUMMY_MATCH) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + } + p->buf = p->tempBuf; + if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) + return SZ_ERROR_DATA; + lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); + (*srcLen) += lookAhead; + src += lookAhead; + inSize -= lookAhead; + p->tempBufSize = 0; + } + } + if (p->code == 0) + *status = LZMA_STATUS_FINISHED_WITH_MARK; + return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; +} + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT outSize = *destLen; + SizeT inSize = *srcLen; + *srcLen = *destLen = 0; + for (;;) + { + SizeT inSizeCur = inSize, outSizeCur, dicPos; + ELzmaFinishMode curFinishMode; + SRes res; + if (p->dicPos == p->dicBufSize) + p->dicPos = 0; + dicPos = p->dicPos; + if (outSize > p->dicBufSize - dicPos) + { + outSizeCur = p->dicBufSize; + curFinishMode = LZMA_FINISH_ANY; + } + else + { + outSizeCur = dicPos + outSize; + curFinishMode = finishMode; + } + + res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); + src += inSizeCur; + inSize -= inSizeCur; + *srcLen += inSizeCur; + outSizeCur = p->dicPos - dicPos; + memcpy(dest, p->dic + dicPos, outSizeCur); + dest += outSizeCur; + outSize -= outSizeCur; + *destLen += outSizeCur; + if (res != 0) + return res; + if (outSizeCur == 0 || outSize == 0) + return SZ_OK; + } +} + +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->probs); + p->probs = 0; +} + +static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->dic); + p->dic = 0; +} + +void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) +{ + LzmaDec_FreeProbs(p, alloc); + LzmaDec_FreeDict(p, alloc); +} + +SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) +{ + UInt32 dicSize; + Byte d; + + if (size < LZMA_PROPS_SIZE) + return SZ_ERROR_UNSUPPORTED; + else + dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); + + if (dicSize < LZMA_DIC_MIN) + dicSize = LZMA_DIC_MIN; + p->dicSize = dicSize; + + d = data[0]; + if (d >= (9 * 5 * 5)) + return SZ_ERROR_UNSUPPORTED; + + p->lc = d % 9; + d /= 9; + p->pb = d / 5; + p->lp = d % 5; + + return SZ_OK; +} + +static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) +{ + UInt32 numProbs = LzmaProps_GetNumProbs(propNew); + if (p->probs == 0 || numProbs != p->numProbs) + { + LzmaDec_FreeProbs(p, alloc); + p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); + p->numProbs = numProbs; + if (p->probs == 0) + return SZ_ERROR_MEM; + } + return SZ_OK; +} + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) +{ + CLzmaProps propNew; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)); + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) +{ + CLzmaProps propNew; + SizeT dicBufSize; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)); + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + dicBufSize = propNew.dicSize; + if (p->dic == 0 || dicBufSize != p->dicBufSize) + { + LzmaDec_FreeDict(p, alloc); + p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); + if (p->dic == 0) + { + LzmaDec_FreeProbs(p, alloc); + return SZ_ERROR_MEM; + } + } + p->dicBufSize = dicBufSize; + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, + ELzmaStatus *status, ISzAlloc *alloc) +{ + CLzmaDec p; + SRes res; + SizeT inSize = *srcLen; + SizeT outSize = *destLen; + *srcLen = *destLen = 0; + if (inSize < RC_INIT_SIZE) + return SZ_ERROR_INPUT_EOF; + + LzmaDec_Construct(&p); + res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); + if (res != 0) + return res; + p.dic = dest; + p.dicBufSize = outSize; + + LzmaDec_Init(&p); + + *srcLen = inSize; + res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); + + if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) + res = SZ_ERROR_INPUT_EOF; + + (*destLen) = p.dicPos; + LzmaDec_FreeProbs(&p, alloc); + return res; +} diff --git a/StormLib/src/lzma/C/LzmaDec.h b/StormLib/src/lzma/C/LzmaDec.h new file mode 100644 index 000000000..bf7f084ba --- /dev/null +++ b/StormLib/src/lzma/C/LzmaDec.h @@ -0,0 +1,231 @@ +/* LzmaDec.h -- LZMA Decoder +2009-02-07 : Igor Pavlov : Public domain */ + +#ifndef __LZMA_DEC_H +#define __LZMA_DEC_H + +#include "Types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* #define _LZMA_PROB32 */ +/* _LZMA_PROB32 can increase the speed on some CPUs, + but memory usage for CLzmaDec::probs will be doubled in that case */ + +#ifdef _LZMA_PROB32 +#define CLzmaProb UInt32 +#else +#define CLzmaProb UInt16 +#endif + + +/* ---------- LZMA Properties ---------- */ + +#define LZMA_PROPS_SIZE 5 + +typedef struct _CLzmaProps +{ + unsigned lc, lp, pb; + UInt32 dicSize; +} CLzmaProps; + +/* LzmaProps_Decode - decodes properties +Returns: + SZ_OK + SZ_ERROR_UNSUPPORTED - Unsupported properties +*/ + +SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); + + +/* ---------- LZMA Decoder state ---------- */ + +/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. + Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ + +#define LZMA_REQUIRED_INPUT_MAX 20 + +typedef struct +{ + CLzmaProps prop; + CLzmaProb *probs; + Byte *dic; + const Byte *buf; + UInt32 range, code; + SizeT dicPos; + SizeT dicBufSize; + UInt32 processedPos; + UInt32 checkDicSize; + unsigned state; + UInt32 reps[4]; + unsigned remainLen; + int needFlush; + int needInitState; + UInt32 numProbs; + unsigned tempBufSize; + Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; +} CLzmaDec; + +#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } + +void LzmaDec_Init(CLzmaDec *p); + +/* There are two types of LZMA streams: + 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. + 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ + +typedef enum +{ + LZMA_FINISH_ANY, /* finish at any point */ + LZMA_FINISH_END /* block must be finished at the end */ +} ELzmaFinishMode; + +/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! + + You must use LZMA_FINISH_END, when you know that current output buffer + covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. + + If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, + and output value of destLen will be less than output buffer size limit. + You can check status result also. + + You can use multiple checks to test data integrity after full decompression: + 1) Check Result and "status" variable. + 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. + 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. + You must use correct finish mode in that case. */ + +typedef enum +{ + LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ + LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ + LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ + LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ +} ELzmaStatus; + +/* ELzmaStatus is used only as output value for function call */ + + +/* ---------- Interfaces ---------- */ + +/* There are 3 levels of interfaces: + 1) Dictionary Interface + 2) Buffer Interface + 3) One Call Interface + You can select any of these interfaces, but don't mix functions from different + groups for same object. */ + + +/* There are two variants to allocate state for Dictionary Interface: + 1) LzmaDec_Allocate / LzmaDec_Free + 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs + You can use variant 2, if you set dictionary buffer manually. + For Buffer Interface you must always use variant 1. + +LzmaDec_Allocate* can return: + SZ_OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties +*/ + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); + +SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); +void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); + +/* ---------- Dictionary Interface ---------- */ + +/* You can use it, if you want to eliminate the overhead for data copying from + dictionary to some other external buffer. + You must work with CLzmaDec variables directly in this interface. + + STEPS: + LzmaDec_Constr() + LzmaDec_Allocate() + for (each new stream) + { + LzmaDec_Init() + while (it needs more decompression) + { + LzmaDec_DecodeToDic() + use data from CLzmaDec::dic and update CLzmaDec::dicPos + } + } + LzmaDec_Free() +*/ + +/* LzmaDec_DecodeToDic + + The decoding to internal dictionary buffer (CLzmaDec::dic). + You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! + +finishMode: + It has meaning only if the decoding reaches output limit (dicLimit). + LZMA_FINISH_ANY - Decode just dicLimit bytes. + LZMA_FINISH_END - Stream must be finished after dicLimit. + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_NEEDS_MORE_INPUT + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + SZ_ERROR_DATA - Data error +*/ + +SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- Buffer Interface ---------- */ + +/* It's zlib-like interface. + See LzmaDec_DecodeToDic description for information about STEPS and return results, + but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need + to work with CLzmaDec variables manually. + +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). +*/ + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- One Call Interface ---------- */ + +/* LzmaDecode + +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). +*/ + +SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, + ELzmaStatus *status, ISzAlloc *alloc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/StormLib/src/lzma/C/LzmaEnc.c b/StormLib/src/lzma/C/LzmaEnc.c new file mode 100644 index 000000000..169d4f463 --- /dev/null +++ b/StormLib/src/lzma/C/LzmaEnc.c @@ -0,0 +1,2268 @@ +/* LzmaEnc.c -- LZMA Encoder +2009-11-24 : Igor Pavlov : Public domain */ + +#include + +/* #define SHOW_STAT */ +/* #define SHOW_STAT2 */ + +#if defined(SHOW_STAT) || defined(SHOW_STAT2) +#include +#endif + +#include "LzmaEnc.h" + +#include "LzFind.h" +#ifndef _7ZIP_ST +#include "LzFindMt.h" +#endif + +#ifdef SHOW_STAT +static int ttt = 0; +#endif + +#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) + +#define kBlockSize (9 << 10) +#define kUnpackBlockSize (1 << 18) +#define kMatchArraySize (1 << 21) +#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) + +#define kNumMaxDirectBits (31) + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 +#define kProbInitValue (kBitModelTotal >> 1) + +#define kNumMoveReducingBits 4 +#define kNumBitPriceShiftBits 4 +#define kBitPrice (1 << kNumBitPriceShiftBits) + +void LzmaEncProps_Init(CLzmaEncProps *p) +{ + p->level = 5; + p->dictSize = p->mc = 0; + p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; + p->writeEndMark = 0; +} + +void LzmaEncProps_Normalize(CLzmaEncProps *p) +{ + int level = p->level; + if (level < 0) level = 5; + p->level = level; + if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); + if (p->lc < 0) p->lc = 3; + if (p->lp < 0) p->lp = 0; + if (p->pb < 0) p->pb = 2; + if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); + if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); + if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); + if (p->numHashBytes < 0) p->numHashBytes = 4; + if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); + if (p->numThreads < 0) + p->numThreads = + #ifndef _7ZIP_ST + ((p->btMode && p->algo) ? 2 : 1); + #else + 1; + #endif +} + +UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) +{ + CLzmaEncProps props = *props2; + LzmaEncProps_Normalize(&props); + return props.dictSize; +} + +/* #define LZMA_LOG_BSR */ +/* Define it for Intel's CPU */ + + +#ifdef LZMA_LOG_BSR + +#define kDicLogSizeMaxCompress 30 + +#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } + +UInt32 GetPosSlot1(UInt32 pos) +{ + UInt32 res; + BSR2_RET(pos, res); + return res; +} +#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } +#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } + +#else + +#define kNumLogBits (9 + (int)sizeof(size_t) / 2) +#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) + +void LzmaEnc_FastPosInit(Byte *g_FastPos) +{ + int c = 2, slotFast; + g_FastPos[0] = 0; + g_FastPos[1] = 1; + + for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) + { + UInt32 k = (1 << ((slotFast >> 1) - 1)); + UInt32 j; + for (j = 0; j < k; j++, c++) + g_FastPos[c] = (Byte)slotFast; + } +} + +#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ + (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ + res = p->g_FastPos[pos >> i] + (i * 2); } +/* +#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ + p->g_FastPos[pos >> 6] + 12 : \ + p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } +*/ + +#define GetPosSlot1(pos) p->g_FastPos[pos] +#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } +#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } + +#endif + + +#define LZMA_NUM_REPS 4 + +typedef unsigned CState; + +typedef struct +{ + UInt32 price; + + CState state; + int prev1IsChar; + int prev2; + + UInt32 posPrev2; + UInt32 backPrev2; + + UInt32 posPrev; + UInt32 backPrev; + UInt32 backs[LZMA_NUM_REPS]; +} COptimal; + +#define kNumOpts (1 << 12) + +#define kNumLenToPosStates 4 +#define kNumPosSlotBits 6 +#define kDicLogSizeMin 0 +#define kDicLogSizeMax 32 +#define kDistTableSizeMax (kDicLogSizeMax * 2) + + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) +#define kAlignMask (kAlignTableSize - 1) + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) + +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#ifdef _LZMA_PROB32 +#define CLzmaProb UInt32 +#else +#define CLzmaProb UInt16 +#endif + +#define LZMA_PB_MAX 4 +#define LZMA_LC_MAX 8 +#define LZMA_LP_MAX 4 + +#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) + + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) + +#define LZMA_MATCH_LEN_MIN 2 +#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) + +#define kNumStates 12 + +typedef struct +{ + CLzmaProb choice; + CLzmaProb choice2; + CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; + CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; + CLzmaProb high[kLenNumHighSymbols]; +} CLenEnc; + +typedef struct +{ + CLenEnc p; + UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; + UInt32 tableSize; + UInt32 counters[LZMA_NUM_PB_STATES_MAX]; +} CLenPriceEnc; + +typedef struct +{ + UInt32 range; + Byte cache; + UInt64 low; + UInt64 cacheSize; + Byte *buf; + Byte *bufLim; + Byte *bufBase; + ISeqOutStream *outStream; + UInt64 processed; + SRes res; +} CRangeEnc; + +typedef struct +{ + CLzmaProb *litProbs; + + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb isRep[kNumStates]; + CLzmaProb isRepG0[kNumStates]; + CLzmaProb isRepG1[kNumStates]; + CLzmaProb isRepG2[kNumStates]; + CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; + + CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; + CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; + CLzmaProb posAlignEncoder[1 << kNumAlignBits]; + + CLenPriceEnc lenEnc; + CLenPriceEnc repLenEnc; + + UInt32 reps[LZMA_NUM_REPS]; + UInt32 state; +} CSaveState; + +typedef struct +{ + IMatchFinder matchFinder; + void *matchFinderObj; + + #ifndef _7ZIP_ST + Bool mtMode; + CMatchFinderMt matchFinderMt; + #endif + + CMatchFinder matchFinderBase; + + #ifndef _7ZIP_ST + Byte pad[128]; + #endif + + UInt32 optimumEndIndex; + UInt32 optimumCurrentIndex; + + UInt32 longestMatchLength; + UInt32 numPairs; + UInt32 numAvail; + COptimal opt[kNumOpts]; + + #ifndef LZMA_LOG_BSR + Byte g_FastPos[1 << kNumLogBits]; + #endif + + UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; + UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; + UInt32 numFastBytes; + UInt32 additionalOffset; + UInt32 reps[LZMA_NUM_REPS]; + UInt32 state; + + UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; + UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; + UInt32 alignPrices[kAlignTableSize]; + UInt32 alignPriceCount; + + UInt32 distTableSize; + + unsigned lc, lp, pb; + unsigned lpMask, pbMask; + + CLzmaProb *litProbs; + + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb isRep[kNumStates]; + CLzmaProb isRepG0[kNumStates]; + CLzmaProb isRepG1[kNumStates]; + CLzmaProb isRepG2[kNumStates]; + CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; + + CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; + CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; + CLzmaProb posAlignEncoder[1 << kNumAlignBits]; + + CLenPriceEnc lenEnc; + CLenPriceEnc repLenEnc; + + unsigned lclp; + + Bool fastMode; + + CRangeEnc rc; + + Bool writeEndMark; + UInt64 nowPos64; + UInt32 matchPriceCount; + Bool finished; + Bool multiThread; + + SRes result; + UInt32 dictSize; + UInt32 matchFinderCycles; + + int needInit; + + CSaveState saveState; +} CLzmaEnc; + +void LzmaEnc_SaveState(CLzmaEncHandle pp) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + CSaveState *dest = &p->saveState; + int i; + dest->lenEnc = p->lenEnc; + dest->repLenEnc = p->repLenEnc; + dest->state = p->state; + + for (i = 0; i < kNumStates; i++) + { + memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); + memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); + } + for (i = 0; i < kNumLenToPosStates; i++) + memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); + memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); + memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); + memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); + memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); + memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); + memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); + memcpy(dest->reps, p->reps, sizeof(p->reps)); + memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); +} + +void LzmaEnc_RestoreState(CLzmaEncHandle pp) +{ + CLzmaEnc *dest = (CLzmaEnc *)pp; + const CSaveState *p = &dest->saveState; + int i; + dest->lenEnc = p->lenEnc; + dest->repLenEnc = p->repLenEnc; + dest->state = p->state; + + for (i = 0; i < kNumStates; i++) + { + memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); + memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); + } + for (i = 0; i < kNumLenToPosStates; i++) + memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); + memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); + memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); + memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); + memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); + memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); + memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); + memcpy(dest->reps, p->reps, sizeof(p->reps)); + memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); +} + +SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + CLzmaEncProps props = *props2; + LzmaEncProps_Normalize(&props); + + if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || + props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30)) + return SZ_ERROR_PARAM; + p->dictSize = props.dictSize; + p->matchFinderCycles = props.mc; + { + unsigned fb = props.fb; + if (fb < 5) + fb = 5; + if (fb > LZMA_MATCH_LEN_MAX) + fb = LZMA_MATCH_LEN_MAX; + p->numFastBytes = fb; + } + p->lc = props.lc; + p->lp = props.lp; + p->pb = props.pb; + p->fastMode = (props.algo == 0); + p->matchFinderBase.btMode = props.btMode; + { + UInt32 numHashBytes = 4; + if (props.btMode) + { + if (props.numHashBytes < 2) + numHashBytes = 2; + else if (props.numHashBytes < 4) + numHashBytes = props.numHashBytes; + } + p->matchFinderBase.numHashBytes = numHashBytes; + } + + p->matchFinderBase.cutValue = props.mc; + + p->writeEndMark = props.writeEndMark; + + #ifndef _7ZIP_ST + /* + if (newMultiThread != _multiThread) + { + ReleaseMatchFinder(); + _multiThread = newMultiThread; + } + */ + p->multiThread = (props.numThreads > 1); + #endif + + return SZ_OK; +} + +static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; +static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; +static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; +static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; + +#define IsCharState(s) ((s) < 7) + +#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) + +#define kInfinityPrice (1 << 30) + +static void RangeEnc_Construct(CRangeEnc *p) +{ + p->outStream = 0; + p->bufBase = 0; +} + +#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) + +#define RC_BUF_SIZE (1 << 16) +static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) +{ + if (p->bufBase == 0) + { + p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); + if (p->bufBase == 0) + return 0; + p->bufLim = p->bufBase + RC_BUF_SIZE; + } + return 1; +} + +static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->bufBase); + p->bufBase = 0; +} + +static void RangeEnc_Init(CRangeEnc *p) +{ + /* Stream.Init(); */ + p->low = 0; + p->range = 0xFFFFFFFF; + p->cacheSize = 1; + p->cache = 0; + + p->buf = p->bufBase; + + p->processed = 0; + p->res = SZ_OK; +} + +static void RangeEnc_FlushStream(CRangeEnc *p) +{ + size_t num; + if (p->res != SZ_OK) + return; + num = p->buf - p->bufBase; + if (num != p->outStream->Write(p->outStream, p->bufBase, num)) + p->res = SZ_ERROR_WRITE; + p->processed += num; + p->buf = p->bufBase; +} + +static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) +{ + if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) + { + Byte temp = p->cache; + do + { + Byte *buf = p->buf; + *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); + p->buf = buf; + if (buf == p->bufLim) + RangeEnc_FlushStream(p); + temp = 0xFF; + } + while (--p->cacheSize != 0); + p->cache = (Byte)((UInt32)p->low >> 24); + } + p->cacheSize++; + p->low = (UInt32)p->low << 8; +} + +static void RangeEnc_FlushData(CRangeEnc *p) +{ + int i; + for (i = 0; i < 5; i++) + RangeEnc_ShiftLow(p); +} + +static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) +{ + do + { + p->range >>= 1; + p->low += p->range & (0 - ((value >> --numBits) & 1)); + if (p->range < kTopValue) + { + p->range <<= 8; + RangeEnc_ShiftLow(p); + } + } + while (numBits != 0); +} + +static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) +{ + UInt32 ttt = *prob; + UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; + if (symbol == 0) + { + p->range = newBound; + ttt += (kBitModelTotal - ttt) >> kNumMoveBits; + } + else + { + p->low += newBound; + p->range -= newBound; + ttt -= ttt >> kNumMoveBits; + } + *prob = (CLzmaProb)ttt; + if (p->range < kTopValue) + { + p->range <<= 8; + RangeEnc_ShiftLow(p); + } +} + +static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) +{ + symbol |= 0x100; + do + { + RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); + symbol <<= 1; + } + while (symbol < 0x10000); +} + +static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) +{ + UInt32 offs = 0x100; + symbol |= 0x100; + do + { + matchByte <<= 1; + RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); + symbol <<= 1; + offs &= ~(matchByte ^ symbol); + } + while (symbol < 0x10000); +} + +void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) +{ + UInt32 i; + for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) + { + const int kCyclesBits = kNumBitPriceShiftBits; + UInt32 w = i; + UInt32 bitCount = 0; + int j; + for (j = 0; j < kCyclesBits; j++) + { + w = w * w; + bitCount <<= 1; + while (w >= ((UInt32)1 << 16)) + { + w >>= 1; + bitCount++; + } + } + ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); + } +} + + +#define GET_PRICE(prob, symbol) \ + p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; + +#define GET_PRICEa(prob, symbol) \ + ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; + +#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] +#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] + +#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] +#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] + +static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) +{ + UInt32 price = 0; + symbol |= 0x100; + do + { + price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); + symbol <<= 1; + } + while (symbol < 0x10000); + return price; +} + +static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) +{ + UInt32 price = 0; + UInt32 offs = 0x100; + symbol |= 0x100; + do + { + matchByte <<= 1; + price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); + symbol <<= 1; + offs &= ~(matchByte ^ symbol); + } + while (symbol < 0x10000); + return price; +} + + +static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) +{ + UInt32 m = 1; + int i; + for (i = numBitLevels; i != 0;) + { + UInt32 bit; + i--; + bit = (symbol >> i) & 1; + RangeEnc_EncodeBit(rc, probs + m, bit); + m = (m << 1) | bit; + } +} + +static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) +{ + UInt32 m = 1; + int i; + for (i = 0; i < numBitLevels; i++) + { + UInt32 bit = symbol & 1; + RangeEnc_EncodeBit(rc, probs + m, bit); + m = (m << 1) | bit; + symbol >>= 1; + } +} + +static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) +{ + UInt32 price = 0; + symbol |= (1 << numBitLevels); + while (symbol != 1) + { + price += GET_PRICEa(probs[symbol >> 1], symbol & 1); + symbol >>= 1; + } + return price; +} + +static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) +{ + UInt32 price = 0; + UInt32 m = 1; + int i; + for (i = numBitLevels; i != 0; i--) + { + UInt32 bit = symbol & 1; + symbol >>= 1; + price += GET_PRICEa(probs[m], bit); + m = (m << 1) | bit; + } + return price; +} + + +static void LenEnc_Init(CLenEnc *p) +{ + unsigned i; + p->choice = p->choice2 = kProbInitValue; + for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) + p->low[i] = kProbInitValue; + for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) + p->mid[i] = kProbInitValue; + for (i = 0; i < kLenNumHighSymbols; i++) + p->high[i] = kProbInitValue; +} + +static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) +{ + if (symbol < kLenNumLowSymbols) + { + RangeEnc_EncodeBit(rc, &p->choice, 0); + RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); + } + else + { + RangeEnc_EncodeBit(rc, &p->choice, 1); + if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) + { + RangeEnc_EncodeBit(rc, &p->choice2, 0); + RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); + } + else + { + RangeEnc_EncodeBit(rc, &p->choice2, 1); + RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); + } + } +} + +static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) +{ + UInt32 a0 = GET_PRICE_0a(p->choice); + UInt32 a1 = GET_PRICE_1a(p->choice); + UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); + UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); + UInt32 i = 0; + for (i = 0; i < kLenNumLowSymbols; i++) + { + if (i >= numSymbols) + return; + prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); + } + for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) + { + if (i >= numSymbols) + return; + prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); + } + for (; i < numSymbols; i++) + prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); +} + +static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) +{ + LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); + p->counters[posState] = p->tableSize; +} + +static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) +{ + UInt32 posState; + for (posState = 0; posState < numPosStates; posState++) + LenPriceEnc_UpdateTable(p, posState, ProbPrices); +} + +static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) +{ + LenEnc_Encode(&p->p, rc, symbol, posState); + if (updatePrice) + if (--p->counters[posState] == 0) + LenPriceEnc_UpdateTable(p, posState, ProbPrices); +} + + + + +static void MovePos(CLzmaEnc *p, UInt32 num) +{ + #ifdef SHOW_STAT + ttt += num; + printf("\n MovePos %d", num); + #endif + if (num != 0) + { + p->additionalOffset += num; + p->matchFinder.Skip(p->matchFinderObj, num); + } +} + +static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) +{ + UInt32 lenRes = 0, numPairs; + p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); + #ifdef SHOW_STAT + printf("\n i = %d numPairs = %d ", ttt, numPairs / 2); + ttt++; + { + UInt32 i; + for (i = 0; i < numPairs; i += 2) + printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); + } + #endif + if (numPairs > 0) + { + lenRes = p->matches[numPairs - 2]; + if (lenRes == p->numFastBytes) + { + const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + UInt32 distance = p->matches[numPairs - 1] + 1; + UInt32 numAvail = p->numAvail; + if (numAvail > LZMA_MATCH_LEN_MAX) + numAvail = LZMA_MATCH_LEN_MAX; + { + const Byte *pby2 = pby - distance; + for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); + } + } + } + p->additionalOffset++; + *numDistancePairsRes = numPairs; + return lenRes; +} + + +#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; +#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; +#define IsShortRep(p) ((p)->backPrev == 0) + +static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) +{ + return + GET_PRICE_0(p->isRepG0[state]) + + GET_PRICE_0(p->isRep0Long[state][posState]); +} + +static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) +{ + UInt32 price; + if (repIndex == 0) + { + price = GET_PRICE_0(p->isRepG0[state]); + price += GET_PRICE_1(p->isRep0Long[state][posState]); + } + else + { + price = GET_PRICE_1(p->isRepG0[state]); + if (repIndex == 1) + price += GET_PRICE_0(p->isRepG1[state]); + else + { + price += GET_PRICE_1(p->isRepG1[state]); + price += GET_PRICE(p->isRepG2[state], repIndex - 2); + } + } + return price; +} + +static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) +{ + return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + + GetPureRepPrice(p, repIndex, state, posState); +} + +static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) +{ + UInt32 posMem = p->opt[cur].posPrev; + UInt32 backMem = p->opt[cur].backPrev; + p->optimumEndIndex = cur; + do + { + if (p->opt[cur].prev1IsChar) + { + MakeAsChar(&p->opt[posMem]) + p->opt[posMem].posPrev = posMem - 1; + if (p->opt[cur].prev2) + { + p->opt[posMem - 1].prev1IsChar = False; + p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; + p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; + } + } + { + UInt32 posPrev = posMem; + UInt32 backCur = backMem; + + backMem = p->opt[posPrev].backPrev; + posMem = p->opt[posPrev].posPrev; + + p->opt[posPrev].backPrev = backCur; + p->opt[posPrev].posPrev = cur; + cur = posPrev; + } + } + while (cur != 0); + *backRes = p->opt[0].backPrev; + p->optimumCurrentIndex = p->opt[0].posPrev; + return p->optimumCurrentIndex; +} + +#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) + +static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) +{ + UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur; + UInt32 matchPrice, repMatchPrice, normalMatchPrice; + UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; + UInt32 *matches; + const Byte *data; + Byte curByte, matchByte; + if (p->optimumEndIndex != p->optimumCurrentIndex) + { + const COptimal *opt = &p->opt[p->optimumCurrentIndex]; + UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; + *backRes = opt->backPrev; + p->optimumCurrentIndex = opt->posPrev; + return lenRes; + } + p->optimumCurrentIndex = p->optimumEndIndex = 0; + + if (p->additionalOffset == 0) + mainLen = ReadMatchDistances(p, &numPairs); + else + { + mainLen = p->longestMatchLength; + numPairs = p->numPairs; + } + + numAvail = p->numAvail; + if (numAvail < 2) + { + *backRes = (UInt32)(-1); + return 1; + } + if (numAvail > LZMA_MATCH_LEN_MAX) + numAvail = LZMA_MATCH_LEN_MAX; + + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + repMaxIndex = 0; + for (i = 0; i < LZMA_NUM_REPS; i++) + { + UInt32 lenTest; + const Byte *data2; + reps[i] = p->reps[i]; + data2 = data - (reps[i] + 1); + if (data[0] != data2[0] || data[1] != data2[1]) + { + repLens[i] = 0; + continue; + } + for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); + repLens[i] = lenTest; + if (lenTest > repLens[repMaxIndex]) + repMaxIndex = i; + } + if (repLens[repMaxIndex] >= p->numFastBytes) + { + UInt32 lenRes; + *backRes = repMaxIndex; + lenRes = repLens[repMaxIndex]; + MovePos(p, lenRes - 1); + return lenRes; + } + + matches = p->matches; + if (mainLen >= p->numFastBytes) + { + *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; + MovePos(p, mainLen - 1); + return mainLen; + } + curByte = *data; + matchByte = *(data - (reps[0] + 1)); + + if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2) + { + *backRes = (UInt32)-1; + return 1; + } + + p->opt[0].state = (CState)p->state; + + posState = (position & p->pbMask); + + { + const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); + p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + + (!IsCharState(p->state) ? + LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : + LitEnc_GetPrice(probs, curByte, p->ProbPrices)); + } + + MakeAsChar(&p->opt[1]); + + matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); + repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); + + if (matchByte == curByte) + { + UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); + if (shortRepPrice < p->opt[1].price) + { + p->opt[1].price = shortRepPrice; + MakeAsShortRep(&p->opt[1]); + } + } + lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]); + + if (lenEnd < 2) + { + *backRes = p->opt[1].backPrev; + return 1; + } + + p->opt[1].posPrev = 0; + for (i = 0; i < LZMA_NUM_REPS; i++) + p->opt[0].backs[i] = reps[i]; + + len = lenEnd; + do + p->opt[len--].price = kInfinityPrice; + while (len >= 2); + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + UInt32 repLen = repLens[i]; + UInt32 price; + if (repLen < 2) + continue; + price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); + do + { + UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; + COptimal *opt = &p->opt[repLen]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = 0; + opt->backPrev = i; + opt->prev1IsChar = False; + } + } + while (--repLen >= 2); + } + + normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); + + len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); + if (len <= mainLen) + { + UInt32 offs = 0; + while (len > matches[offs]) + offs += 2; + for (; ; len++) + { + COptimal *opt; + UInt32 distance = matches[offs + 1]; + + UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; + UInt32 lenToPosState = GetLenToPosState(len); + if (distance < kNumFullDistances) + curAndLenPrice += p->distancesPrices[lenToPosState][distance]; + else + { + UInt32 slot; + GetPosSlot2(distance, slot); + curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; + } + opt = &p->opt[len]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = 0; + opt->backPrev = distance + LZMA_NUM_REPS; + opt->prev1IsChar = False; + } + if (len == matches[offs]) + { + offs += 2; + if (offs == numPairs) + break; + } + } + } + + cur = 0; + + #ifdef SHOW_STAT2 + if (position >= 0) + { + unsigned i; + printf("\n pos = %4X", position); + for (i = cur; i <= lenEnd; i++) + printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); + } + #endif + + for (;;) + { + UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; + UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; + Bool nextIsChar; + Byte curByte, matchByte; + const Byte *data; + COptimal *curOpt; + COptimal *nextOpt; + + cur++; + if (cur == lenEnd) + return Backward(p, backRes, cur); + + newLen = ReadMatchDistances(p, &numPairs); + if (newLen >= p->numFastBytes) + { + p->numPairs = numPairs; + p->longestMatchLength = newLen; + return Backward(p, backRes, cur); + } + position++; + curOpt = &p->opt[cur]; + posPrev = curOpt->posPrev; + if (curOpt->prev1IsChar) + { + posPrev--; + if (curOpt->prev2) + { + state = p->opt[curOpt->posPrev2].state; + if (curOpt->backPrev2 < LZMA_NUM_REPS) + state = kRepNextStates[state]; + else + state = kMatchNextStates[state]; + } + else + state = p->opt[posPrev].state; + state = kLiteralNextStates[state]; + } + else + state = p->opt[posPrev].state; + if (posPrev == cur - 1) + { + if (IsShortRep(curOpt)) + state = kShortRepNextStates[state]; + else + state = kLiteralNextStates[state]; + } + else + { + UInt32 pos; + const COptimal *prevOpt; + if (curOpt->prev1IsChar && curOpt->prev2) + { + posPrev = curOpt->posPrev2; + pos = curOpt->backPrev2; + state = kRepNextStates[state]; + } + else + { + pos = curOpt->backPrev; + if (pos < LZMA_NUM_REPS) + state = kRepNextStates[state]; + else + state = kMatchNextStates[state]; + } + prevOpt = &p->opt[posPrev]; + if (pos < LZMA_NUM_REPS) + { + UInt32 i; + reps[0] = prevOpt->backs[pos]; + for (i = 1; i <= pos; i++) + reps[i] = prevOpt->backs[i - 1]; + for (; i < LZMA_NUM_REPS; i++) + reps[i] = prevOpt->backs[i]; + } + else + { + UInt32 i; + reps[0] = (pos - LZMA_NUM_REPS); + for (i = 1; i < LZMA_NUM_REPS; i++) + reps[i] = prevOpt->backs[i - 1]; + } + } + curOpt->state = (CState)state; + + curOpt->backs[0] = reps[0]; + curOpt->backs[1] = reps[1]; + curOpt->backs[2] = reps[2]; + curOpt->backs[3] = reps[3]; + + curPrice = curOpt->price; + nextIsChar = False; + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + curByte = *data; + matchByte = *(data - (reps[0] + 1)); + + posState = (position & p->pbMask); + + curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); + { + const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); + curAnd1Price += + (!IsCharState(state) ? + LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : + LitEnc_GetPrice(probs, curByte, p->ProbPrices)); + } + + nextOpt = &p->opt[cur + 1]; + + if (curAnd1Price < nextOpt->price) + { + nextOpt->price = curAnd1Price; + nextOpt->posPrev = cur; + MakeAsChar(nextOpt); + nextIsChar = True; + } + + matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); + repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); + + if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) + { + UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); + if (shortRepPrice <= nextOpt->price) + { + nextOpt->price = shortRepPrice; + nextOpt->posPrev = cur; + MakeAsShortRep(nextOpt); + nextIsChar = True; + } + } + numAvailFull = p->numAvail; + { + UInt32 temp = kNumOpts - 1 - cur; + if (temp < numAvailFull) + numAvailFull = temp; + } + + if (numAvailFull < 2) + continue; + numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); + + if (!nextIsChar && matchByte != curByte) /* speed optimization */ + { + /* try Literal + rep0 */ + UInt32 temp; + UInt32 lenTest2; + const Byte *data2 = data - (reps[0] + 1); + UInt32 limit = p->numFastBytes + 1; + if (limit > numAvailFull) + limit = numAvailFull; + + for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); + lenTest2 = temp - 1; + if (lenTest2 >= 2) + { + UInt32 state2 = kLiteralNextStates[state]; + UInt32 posStateNext = (position + 1) & p->pbMask; + UInt32 nextRepMatchPrice = curAnd1Price + + GET_PRICE_1(p->isMatch[state2][posStateNext]) + + GET_PRICE_1(p->isRep[state2]); + /* for (; lenTest2 >= 2; lenTest2--) */ + { + UInt32 curAndLenPrice; + COptimal *opt; + UInt32 offset = cur + 1 + lenTest2; + while (lenEnd < offset) + p->opt[++lenEnd].price = kInfinityPrice; + curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); + opt = &p->opt[offset]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur + 1; + opt->backPrev = 0; + opt->prev1IsChar = True; + opt->prev2 = False; + } + } + } + } + + startLen = 2; /* speed optimization */ + { + UInt32 repIndex; + for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) + { + UInt32 lenTest; + UInt32 lenTestTemp; + UInt32 price; + const Byte *data2 = data - (reps[repIndex] + 1); + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); + while (lenEnd < cur + lenTest) + p->opt[++lenEnd].price = kInfinityPrice; + lenTestTemp = lenTest; + price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); + do + { + UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; + COptimal *opt = &p->opt[cur + lenTest]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur; + opt->backPrev = repIndex; + opt->prev1IsChar = False; + } + } + while (--lenTest >= 2); + lenTest = lenTestTemp; + + if (repIndex == 0) + startLen = lenTest + 1; + + /* if (_maxMode) */ + { + UInt32 lenTest2 = lenTest + 1; + UInt32 limit = lenTest2 + p->numFastBytes; + UInt32 nextRepMatchPrice; + if (limit > numAvailFull) + limit = numAvailFull; + for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); + lenTest2 -= lenTest + 1; + if (lenTest2 >= 2) + { + UInt32 state2 = kRepNextStates[state]; + UInt32 posStateNext = (position + lenTest) & p->pbMask; + UInt32 curAndLenCharPrice = + price + p->repLenEnc.prices[posState][lenTest - 2] + + GET_PRICE_0(p->isMatch[state2][posStateNext]) + + LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), + data[lenTest], data2[lenTest], p->ProbPrices); + state2 = kLiteralNextStates[state2]; + posStateNext = (position + lenTest + 1) & p->pbMask; + nextRepMatchPrice = curAndLenCharPrice + + GET_PRICE_1(p->isMatch[state2][posStateNext]) + + GET_PRICE_1(p->isRep[state2]); + + /* for (; lenTest2 >= 2; lenTest2--) */ + { + UInt32 curAndLenPrice; + COptimal *opt; + UInt32 offset = cur + lenTest + 1 + lenTest2; + while (lenEnd < offset) + p->opt[++lenEnd].price = kInfinityPrice; + curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); + opt = &p->opt[offset]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur + lenTest + 1; + opt->backPrev = 0; + opt->prev1IsChar = True; + opt->prev2 = True; + opt->posPrev2 = cur; + opt->backPrev2 = repIndex; + } + } + } + } + } + } + /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ + if (newLen > numAvail) + { + newLen = numAvail; + for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2); + matches[numPairs] = newLen; + numPairs += 2; + } + if (newLen >= startLen) + { + UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); + UInt32 offs, curBack, posSlot; + UInt32 lenTest; + while (lenEnd < cur + newLen) + p->opt[++lenEnd].price = kInfinityPrice; + + offs = 0; + while (startLen > matches[offs]) + offs += 2; + curBack = matches[offs + 1]; + GetPosSlot2(curBack, posSlot); + for (lenTest = /*2*/ startLen; ; lenTest++) + { + UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; + UInt32 lenToPosState = GetLenToPosState(lenTest); + COptimal *opt; + if (curBack < kNumFullDistances) + curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; + else + curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; + + opt = &p->opt[cur + lenTest]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur; + opt->backPrev = curBack + LZMA_NUM_REPS; + opt->prev1IsChar = False; + } + + if (/*_maxMode && */lenTest == matches[offs]) + { + /* Try Match + Literal + Rep0 */ + const Byte *data2 = data - (curBack + 1); + UInt32 lenTest2 = lenTest + 1; + UInt32 limit = lenTest2 + p->numFastBytes; + UInt32 nextRepMatchPrice; + if (limit > numAvailFull) + limit = numAvailFull; + for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); + lenTest2 -= lenTest + 1; + if (lenTest2 >= 2) + { + UInt32 state2 = kMatchNextStates[state]; + UInt32 posStateNext = (position + lenTest) & p->pbMask; + UInt32 curAndLenCharPrice = curAndLenPrice + + GET_PRICE_0(p->isMatch[state2][posStateNext]) + + LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), + data[lenTest], data2[lenTest], p->ProbPrices); + state2 = kLiteralNextStates[state2]; + posStateNext = (posStateNext + 1) & p->pbMask; + nextRepMatchPrice = curAndLenCharPrice + + GET_PRICE_1(p->isMatch[state2][posStateNext]) + + GET_PRICE_1(p->isRep[state2]); + + /* for (; lenTest2 >= 2; lenTest2--) */ + { + UInt32 offset = cur + lenTest + 1 + lenTest2; + UInt32 curAndLenPrice; + COptimal *opt; + while (lenEnd < offset) + p->opt[++lenEnd].price = kInfinityPrice; + curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); + opt = &p->opt[offset]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur + lenTest + 1; + opt->backPrev = 0; + opt->prev1IsChar = True; + opt->prev2 = True; + opt->posPrev2 = cur; + opt->backPrev2 = curBack + LZMA_NUM_REPS; + } + } + } + offs += 2; + if (offs == numPairs) + break; + curBack = matches[offs + 1]; + if (curBack >= kNumFullDistances) + GetPosSlot2(curBack, posSlot); + } + } + } + } +} + +#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) + +static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) +{ + UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i; + const Byte *data; + const UInt32 *matches; + + if (p->additionalOffset == 0) + mainLen = ReadMatchDistances(p, &numPairs); + else + { + mainLen = p->longestMatchLength; + numPairs = p->numPairs; + } + + numAvail = p->numAvail; + *backRes = (UInt32)-1; + if (numAvail < 2) + return 1; + if (numAvail > LZMA_MATCH_LEN_MAX) + numAvail = LZMA_MATCH_LEN_MAX; + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + + repLen = repIndex = 0; + for (i = 0; i < LZMA_NUM_REPS; i++) + { + UInt32 len; + const Byte *data2 = data - (p->reps[i] + 1); + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + for (len = 2; len < numAvail && data[len] == data2[len]; len++); + if (len >= p->numFastBytes) + { + *backRes = i; + MovePos(p, len - 1); + return len; + } + if (len > repLen) + { + repIndex = i; + repLen = len; + } + } + + matches = p->matches; + if (mainLen >= p->numFastBytes) + { + *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; + MovePos(p, mainLen - 1); + return mainLen; + } + + mainDist = 0; /* for GCC */ + if (mainLen >= 2) + { + mainDist = matches[numPairs - 1]; + while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1) + { + if (!ChangePair(matches[numPairs - 3], mainDist)) + break; + numPairs -= 2; + mainLen = matches[numPairs - 2]; + mainDist = matches[numPairs - 1]; + } + if (mainLen == 2 && mainDist >= 0x80) + mainLen = 1; + } + + if (repLen >= 2 && ( + (repLen + 1 >= mainLen) || + (repLen + 2 >= mainLen && mainDist >= (1 << 9)) || + (repLen + 3 >= mainLen && mainDist >= (1 << 15)))) + { + *backRes = repIndex; + MovePos(p, repLen - 1); + return repLen; + } + + if (mainLen < 2 || numAvail <= 2) + return 1; + + p->longestMatchLength = ReadMatchDistances(p, &p->numPairs); + if (p->longestMatchLength >= 2) + { + UInt32 newDistance = matches[p->numPairs - 1]; + if ((p->longestMatchLength >= mainLen && newDistance < mainDist) || + (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) || + (p->longestMatchLength > mainLen + 1) || + (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) + return 1; + } + + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + for (i = 0; i < LZMA_NUM_REPS; i++) + { + UInt32 len, limit; + const Byte *data2 = data - (p->reps[i] + 1); + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + limit = mainLen - 1; + for (len = 2; len < limit && data[len] == data2[len]; len++); + if (len >= limit) + return 1; + } + *backRes = mainDist + LZMA_NUM_REPS; + MovePos(p, mainLen - 2); + return mainLen; +} + +static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) +{ + UInt32 len; + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); + RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); + p->state = kMatchNextStates[p->state]; + len = LZMA_MATCH_LEN_MIN; + LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); + RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); + RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); + RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); +} + +static SRes CheckErrors(CLzmaEnc *p) +{ + if (p->result != SZ_OK) + return p->result; + if (p->rc.res != SZ_OK) + p->result = SZ_ERROR_WRITE; + if (p->matchFinderBase.result != SZ_OK) + p->result = SZ_ERROR_READ; + if (p->result != SZ_OK) + p->finished = True; + return p->result; +} + +static SRes Flush(CLzmaEnc *p, UInt32 nowPos) +{ + /* ReleaseMFStream(); */ + p->finished = True; + if (p->writeEndMark) + WriteEndMarker(p, nowPos & p->pbMask); + RangeEnc_FlushData(&p->rc); + RangeEnc_FlushStream(&p->rc); + return CheckErrors(p); +} + +static void FillAlignPrices(CLzmaEnc *p) +{ + UInt32 i; + for (i = 0; i < kAlignTableSize; i++) + p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); + p->alignPriceCount = 0; +} + +static void FillDistancesPrices(CLzmaEnc *p) +{ + UInt32 tempPrices[kNumFullDistances]; + UInt32 i, lenToPosState; + for (i = kStartPosModelIndex; i < kNumFullDistances; i++) + { + UInt32 posSlot = GetPosSlot1(i); + UInt32 footerBits = ((posSlot >> 1) - 1); + UInt32 base = ((2 | (posSlot & 1)) << footerBits); + tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices); + } + + for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) + { + UInt32 posSlot; + const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; + UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; + for (posSlot = 0; posSlot < p->distTableSize; posSlot++) + posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); + for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) + posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); + + { + UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; + UInt32 i; + for (i = 0; i < kStartPosModelIndex; i++) + distancesPrices[i] = posSlotPrices[i]; + for (; i < kNumFullDistances; i++) + distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; + } + } + p->matchPriceCount = 0; +} + +void LzmaEnc_Construct(CLzmaEnc *p) +{ + RangeEnc_Construct(&p->rc); + MatchFinder_Construct(&p->matchFinderBase); + #ifndef _7ZIP_ST + MatchFinderMt_Construct(&p->matchFinderMt); + p->matchFinderMt.MatchFinder = &p->matchFinderBase; + #endif + + { + CLzmaEncProps props; + LzmaEncProps_Init(&props); + LzmaEnc_SetProps(p, &props); + } + + #ifndef LZMA_LOG_BSR + LzmaEnc_FastPosInit(p->g_FastPos); + #endif + + LzmaEnc_InitPriceTables(p->ProbPrices); + p->litProbs = 0; + p->saveState.litProbs = 0; +} + +CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) +{ + void *p; + p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); + if (p != 0) + LzmaEnc_Construct((CLzmaEnc *)p); + return p; +} + +void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->litProbs); + alloc->Free(alloc, p->saveState.litProbs); + p->litProbs = 0; + p->saveState.litProbs = 0; +} + +void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + #ifndef _7ZIP_ST + MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); + #endif + MatchFinder_Free(&p->matchFinderBase, allocBig); + LzmaEnc_FreeLits(p, alloc); + RangeEnc_Free(&p->rc, alloc); +} + +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); + alloc->Free(alloc, p); +} + +static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) +{ + UInt32 nowPos32, startPos32; + if (p->needInit) + { + p->matchFinder.Init(p->matchFinderObj); + p->needInit = 0; + } + + if (p->finished) + return p->result; + RINOK(CheckErrors(p)); + + nowPos32 = (UInt32)p->nowPos64; + startPos32 = nowPos32; + + if (p->nowPos64 == 0) + { + UInt32 numPairs; + Byte curByte; + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) + return Flush(p, nowPos32); + ReadMatchDistances(p, &numPairs); + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); + p->state = kLiteralNextStates[p->state]; + curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); + LitEnc_Encode(&p->rc, p->litProbs, curByte); + p->additionalOffset--; + nowPos32++; + } + + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) + for (;;) + { + UInt32 pos, len, posState; + + if (p->fastMode) + len = GetOptimumFast(p, &pos); + else + len = GetOptimum(p, nowPos32, &pos); + + #ifdef SHOW_STAT2 + printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); + #endif + + posState = nowPos32 & p->pbMask; + if (len == 1 && pos == (UInt32)-1) + { + Byte curByte; + CLzmaProb *probs; + const Byte *data; + + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; + curByte = *data; + probs = LIT_PROBS(nowPos32, *(data - 1)); + if (IsCharState(p->state)) + LitEnc_Encode(&p->rc, probs, curByte); + else + LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); + p->state = kLiteralNextStates[p->state]; + } + else + { + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); + if (pos < LZMA_NUM_REPS) + { + RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); + if (pos == 0) + { + RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); + RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); + } + else + { + UInt32 distance = p->reps[pos]; + RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); + if (pos == 1) + RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); + else + { + RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); + RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); + if (pos == 3) + p->reps[3] = p->reps[2]; + p->reps[2] = p->reps[1]; + } + p->reps[1] = p->reps[0]; + p->reps[0] = distance; + } + if (len == 1) + p->state = kShortRepNextStates[p->state]; + else + { + LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); + p->state = kRepNextStates[p->state]; + } + } + else + { + UInt32 posSlot; + RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); + p->state = kMatchNextStates[p->state]; + LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); + pos -= LZMA_NUM_REPS; + GetPosSlot(pos, posSlot); + RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); + + if (posSlot >= kStartPosModelIndex) + { + UInt32 footerBits = ((posSlot >> 1) - 1); + UInt32 base = ((2 | (posSlot & 1)) << footerBits); + UInt32 posReduced = pos - base; + + if (posSlot < kEndPosModelIndex) + RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced); + else + { + RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); + RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); + p->alignPriceCount++; + } + } + p->reps[3] = p->reps[2]; + p->reps[2] = p->reps[1]; + p->reps[1] = p->reps[0]; + p->reps[0] = pos; + p->matchPriceCount++; + } + } + p->additionalOffset -= len; + nowPos32 += len; + if (p->additionalOffset == 0) + { + UInt32 processed; + if (!p->fastMode) + { + if (p->matchPriceCount >= (1 << 7)) + FillDistancesPrices(p); + if (p->alignPriceCount >= kAlignTableSize) + FillAlignPrices(p); + } + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) + break; + processed = nowPos32 - startPos32; + if (useLimits) + { + if (processed + kNumOpts + 300 >= maxUnpackSize || + RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) + break; + } + else if (processed >= (1 << 15)) + { + p->nowPos64 += nowPos32 - startPos32; + return CheckErrors(p); + } + } + } + p->nowPos64 += nowPos32 - startPos32; + return Flush(p, nowPos32); +} + +#define kBigHashDicLimit ((UInt32)1 << 24) + +static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + UInt32 beforeSize = kNumOpts; + Bool btMode; + if (!RangeEnc_Alloc(&p->rc, alloc)) + return SZ_ERROR_MEM; + btMode = (p->matchFinderBase.btMode != 0); + #ifndef _7ZIP_ST + p->mtMode = (p->multiThread && !p->fastMode && btMode); + #endif + + { + unsigned lclp = p->lc + p->lp; + if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) + { + LzmaEnc_FreeLits(p, alloc); + p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); + p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); + if (p->litProbs == 0 || p->saveState.litProbs == 0) + { + LzmaEnc_FreeLits(p, alloc); + return SZ_ERROR_MEM; + } + p->lclp = lclp; + } + } + + p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); + + if (beforeSize + p->dictSize < keepWindowSize) + beforeSize = keepWindowSize - p->dictSize; + + #ifndef _7ZIP_ST + if (p->mtMode) + { + RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); + p->matchFinderObj = &p->matchFinderMt; + MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); + } + else + #endif + { + if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) + return SZ_ERROR_MEM; + p->matchFinderObj = &p->matchFinderBase; + MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); + } + return SZ_OK; +} + +void LzmaEnc_Init(CLzmaEnc *p) +{ + UInt32 i; + p->state = 0; + for (i = 0 ; i < LZMA_NUM_REPS; i++) + p->reps[i] = 0; + + RangeEnc_Init(&p->rc); + + + for (i = 0; i < kNumStates; i++) + { + UInt32 j; + for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) + { + p->isMatch[i][j] = kProbInitValue; + p->isRep0Long[i][j] = kProbInitValue; + } + p->isRep[i] = kProbInitValue; + p->isRepG0[i] = kProbInitValue; + p->isRepG1[i] = kProbInitValue; + p->isRepG2[i] = kProbInitValue; + } + + { + UInt32 num = 0x300 << (p->lp + p->lc); + for (i = 0; i < num; i++) + p->litProbs[i] = kProbInitValue; + } + + { + for (i = 0; i < kNumLenToPosStates; i++) + { + CLzmaProb *probs = p->posSlotEncoder[i]; + UInt32 j; + for (j = 0; j < (1 << kNumPosSlotBits); j++) + probs[j] = kProbInitValue; + } + } + { + for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) + p->posEncoders[i] = kProbInitValue; + } + + LenEnc_Init(&p->lenEnc.p); + LenEnc_Init(&p->repLenEnc.p); + + for (i = 0; i < (1 << kNumAlignBits); i++) + p->posAlignEncoder[i] = kProbInitValue; + + p->optimumEndIndex = 0; + p->optimumCurrentIndex = 0; + p->additionalOffset = 0; + + p->pbMask = (1 << p->pb) - 1; + p->lpMask = (1 << p->lp) - 1; +} + +void LzmaEnc_InitPrices(CLzmaEnc *p) +{ + if (!p->fastMode) + { + FillDistancesPrices(p); + FillAlignPrices(p); + } + + p->lenEnc.tableSize = + p->repLenEnc.tableSize = + p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; + LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices); + LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); +} + +static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + UInt32 i; + for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) + if (p->dictSize <= ((UInt32)1 << i)) + break; + p->distTableSize = i * 2; + + p->finished = False; + p->result = SZ_OK; + RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); + LzmaEnc_Init(p); + LzmaEnc_InitPrices(p); + p->nowPos64 = 0; + return SZ_OK; +} + +static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + p->matchFinderBase.stream = inStream; + p->needInit = 1; + p->rc.outStream = outStream; + return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); +} + +SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, + ISeqInStream *inStream, UInt32 keepWindowSize, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + p->matchFinderBase.stream = inStream; + p->needInit = 1; + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +} + +static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) +{ + p->matchFinderBase.directInput = 1; + p->matchFinderBase.bufferBase = (Byte *)src; + p->matchFinderBase.directInputRem = srcLen; +} + +SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, + UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + LzmaEnc_SetInputBuf(p, src, srcLen); + p->needInit = 1; + + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +} + +void LzmaEnc_Finish(CLzmaEncHandle pp) +{ + #ifndef _7ZIP_ST + CLzmaEnc *p = (CLzmaEnc *)pp; + if (p->mtMode) + MatchFinderMt_ReleaseStream(&p->matchFinderMt); + #else + pp = pp; + #endif +} + +typedef struct +{ + ISeqOutStream funcTable; + Byte *data; + SizeT rem; + Bool overflow; +} CSeqOutStreamBuf; + +static size_t MyWrite(void *pp, const void *data, size_t size) +{ + CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; + if (p->rem < size) + { + size = p->rem; + p->overflow = True; + } + memcpy(p->data, data, size); + p->rem -= size; + p->data += size; + return size; +} + + +UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) +{ + const CLzmaEnc *p = (CLzmaEnc *)pp; + return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); +} + +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) +{ + const CLzmaEnc *p = (CLzmaEnc *)pp; + return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; +} + +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, + Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + UInt64 nowPos64; + SRes res; + CSeqOutStreamBuf outStream; + + outStream.funcTable.Write = MyWrite; + outStream.data = dest; + outStream.rem = *destLen; + outStream.overflow = False; + + p->writeEndMark = False; + p->finished = False; + p->result = SZ_OK; + + if (reInit) + LzmaEnc_Init(p); + LzmaEnc_InitPrices(p); + nowPos64 = p->nowPos64; + RangeEnc_Init(&p->rc); + p->rc.outStream = &outStream.funcTable; + + res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); + + *unpackSize = (UInt32)(p->nowPos64 - nowPos64); + *destLen -= outStream.rem; + if (outStream.overflow) + return SZ_ERROR_OUTPUT_EOF; + + return res; +} + +static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) +{ + SRes res = SZ_OK; + + #ifndef _7ZIP_ST + Byte allocaDummy[0x300]; + int i = 0; + for (i = 0; i < 16; i++) + allocaDummy[i] = (Byte)i; + #endif + + for (;;) + { + res = LzmaEnc_CodeOneBlock(p, False, 0, 0); + if (res != SZ_OK || p->finished != 0) + break; + if (progress != 0) + { + res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); + if (res != SZ_OK) + { + res = SZ_ERROR_PROGRESS; + break; + } + } + } + LzmaEnc_Finish(p); + return res; +} + +SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); + return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); +} + +SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + int i; + UInt32 dictSize = p->dictSize; + if (*size < LZMA_PROPS_SIZE) + return SZ_ERROR_PARAM; + *size = LZMA_PROPS_SIZE; + props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); + + for (i = 11; i <= 30; i++) + { + if (dictSize <= ((UInt32)2 << i)) + { + dictSize = (2 << i); + break; + } + if (dictSize <= ((UInt32)3 << i)) + { + dictSize = (3 << i); + break; + } + } + + for (i = 0; i < 4; i++) + props[1 + i] = (Byte)(dictSize >> (8 * i)); + return SZ_OK; +} + +SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + SRes res; + CLzmaEnc *p = (CLzmaEnc *)pp; + + CSeqOutStreamBuf outStream; + + LzmaEnc_SetInputBuf(p, src, srcLen); + + outStream.funcTable.Write = MyWrite; + outStream.data = dest; + outStream.rem = *destLen; + outStream.overflow = False; + + p->writeEndMark = writeEndMark; + + p->rc.outStream = &outStream.funcTable; + res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); + if (res == SZ_OK) + res = LzmaEnc_Encode2(p, progress); + + *destLen -= outStream.rem; + if (outStream.overflow) + return SZ_ERROR_OUTPUT_EOF; + return res; +} + +SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, + ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); + SRes res; + if (p == 0) + return SZ_ERROR_MEM; + + res = LzmaEnc_SetProps(p, props); + if (res == SZ_OK) + { + res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); + if (res == SZ_OK) + res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, + writeEndMark, progress, alloc, allocBig); + } + + LzmaEnc_Destroy(p, alloc, allocBig); + return res; +} diff --git a/StormLib/src/lzma/C/LzmaEnc.h b/StormLib/src/lzma/C/LzmaEnc.h new file mode 100644 index 000000000..200d60eb8 --- /dev/null +++ b/StormLib/src/lzma/C/LzmaEnc.h @@ -0,0 +1,80 @@ +/* LzmaEnc.h -- LZMA Encoder +2009-02-07 : Igor Pavlov : Public domain */ + +#ifndef __LZMA_ENC_H +#define __LZMA_ENC_H + +#include "Types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LZMA_PROPS_SIZE 5 + +typedef struct _CLzmaEncProps +{ + int level; /* 0 <= level <= 9 */ + UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version + (1 << 12) <= dictSize <= (1 << 30) for 64-bit version + default = (1 << 24) */ + int lc; /* 0 <= lc <= 8, default = 3 */ + int lp; /* 0 <= lp <= 4, default = 0 */ + int pb; /* 0 <= pb <= 4, default = 2 */ + int algo; /* 0 - fast, 1 - normal, default = 1 */ + int fb; /* 5 <= fb <= 273, default = 32 */ + int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ + int numHashBytes; /* 2, 3 or 4, default = 4 */ + UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ + unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ + int numThreads; /* 1 or 2, default = 2 */ +} CLzmaEncProps; + +void LzmaEncProps_Init(CLzmaEncProps *p); +void LzmaEncProps_Normalize(CLzmaEncProps *p); +UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); + + +/* ---------- CLzmaEncHandle Interface ---------- */ + +/* LzmaEnc_* functions can return the following exit codes: +Returns: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater in props + SZ_ERROR_WRITE - Write callback error. + SZ_ERROR_PROGRESS - some break from progress callback + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +typedef void * CLzmaEncHandle; + +CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); +SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); +SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); +SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, + ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); +SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); + +/* ---------- One Call Interface ---------- */ + +/* LzmaEncode +Return code: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater + SZ_ERROR_OUTPUT_EOF - output buffer overflow + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, + ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/StormLib/src/lzma/C/Threads.c b/StormLib/src/lzma/C/Threads.c new file mode 100644 index 000000000..7af1da2e2 --- /dev/null +++ b/StormLib/src/lzma/C/Threads.c @@ -0,0 +1,84 @@ +/* Threads.c -- multithreading library +2009-09-20 : Igor Pavlov : Public domain */ + +#ifndef _WIN32_WCE +#include +#endif + +#include "Threads.h" + +static WRes GetError() +{ + DWORD res = GetLastError(); + return (res) ? (WRes)(res) : 1; +} + +WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); } +WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); } + +WRes HandlePtr_Close(HANDLE *p) +{ + if (*p != NULL) + if (!CloseHandle(*p)) + return GetError(); + *p = NULL; + return 0; +} + +WRes Handle_WaitObject(HANDLE h) { return (WRes)WaitForSingleObject(h, INFINITE); } + +WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param) +{ + unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ + *p = + #ifdef UNDER_CE + CreateThread(0, 0, func, param, 0, &threadId); + #else + (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId); + #endif + /* maybe we must use errno here, but probably GetLastError() is also OK. */ + return HandleToWRes(*p); +} + +WRes Event_Create(CEvent *p, BOOL manualReset, int signaled) +{ + *p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL); + return HandleToWRes(*p); +} + +WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(*p)); } +WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(*p)); } + +WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled) { return Event_Create(p, TRUE, signaled); } +WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled) { return Event_Create(p, FALSE, signaled); } +WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) { return ManualResetEvent_Create(p, 0); } +WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) { return AutoResetEvent_Create(p, 0); } + + +WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount) +{ + *p = CreateSemaphore(NULL, (LONG)initCount, (LONG)maxCount, NULL); + return HandleToWRes(*p); +} + +static WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount) + { return BOOLToWRes(ReleaseSemaphore(*p, releaseCount, previousCount)); } +WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num) + { return Semaphore_Release(p, (LONG)num, NULL); } +WRes Semaphore_Release1(CSemaphore *p) { return Semaphore_ReleaseN(p, 1); } + +WRes CriticalSection_Init(CCriticalSection *p) +{ + /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */ + #ifdef _MSC_VER + __try + #endif + { + InitializeCriticalSection(p); + /* InitializeCriticalSectionAndSpinCount(p, 0); */ + } + #ifdef _MSC_VER + __except (EXCEPTION_EXECUTE_HANDLER) { return 1; } + #endif + return 0; +} diff --git a/StormLib/src/lzma/C/Threads.h b/StormLib/src/lzma/C/Threads.h new file mode 100644 index 000000000..d0ddd80e2 --- /dev/null +++ b/StormLib/src/lzma/C/Threads.h @@ -0,0 +1,59 @@ +/* Threads.h -- multithreading library +2009-03-27 : Igor Pavlov : Public domain */ + +#ifndef __7Z_THREADS_H +#define __7Z_THREADS_H + +#include "Types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +WRes HandlePtr_Close(HANDLE *h); +WRes Handle_WaitObject(HANDLE h); + +typedef HANDLE CThread; +#define Thread_Construct(p) *(p) = NULL +#define Thread_WasCreated(p) (*(p) != NULL) +#define Thread_Close(p) HandlePtr_Close(p) +#define Thread_Wait(p) Handle_WaitObject(*(p)) +typedef unsigned THREAD_FUNC_RET_TYPE; +#define THREAD_FUNC_CALL_TYPE MY_STD_CALL +#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE +typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *); +WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param); + +typedef HANDLE CEvent; +typedef CEvent CAutoResetEvent; +typedef CEvent CManualResetEvent; +#define Event_Construct(p) *(p) = NULL +#define Event_IsCreated(p) (*(p) != NULL) +#define Event_Close(p) HandlePtr_Close(p) +#define Event_Wait(p) Handle_WaitObject(*(p)) +WRes Event_Set(CEvent *p); +WRes Event_Reset(CEvent *p); +WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled); +WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p); +WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled); +WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p); + +typedef HANDLE CSemaphore; +#define Semaphore_Construct(p) (*p) = NULL +#define Semaphore_Close(p) HandlePtr_Close(p) +#define Semaphore_Wait(p) Handle_WaitObject(*(p)) +WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount); +WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num); +WRes Semaphore_Release1(CSemaphore *p); + +typedef CRITICAL_SECTION CCriticalSection; +WRes CriticalSection_Init(CCriticalSection *p); +#define CriticalSection_Delete(p) DeleteCriticalSection(p) +#define CriticalSection_Enter(p) EnterCriticalSection(p) +#define CriticalSection_Leave(p) LeaveCriticalSection(p) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/StormLib/src/lzma/C/Types.h b/StormLib/src/lzma/C/Types.h new file mode 100644 index 000000000..0526cb47b --- /dev/null +++ b/StormLib/src/lzma/C/Types.h @@ -0,0 +1,236 @@ +/* Types.h -- Basic types +2010-03-11 : Igor Pavlov : Public domain */ + +#ifndef __7Z_TYPES_H +#define __7Z_TYPES_H + +#include + +#ifdef _WIN32 +#include +#endif + +#ifndef EXTERN_C_BEGIN +#ifdef __cplusplus +#define EXTERN_C_BEGIN extern "C" { +#define EXTERN_C_END } +#else +#define EXTERN_C_BEGIN +#define EXTERN_C_END +#endif +#endif + +EXTERN_C_BEGIN + +#define SZ_OK 0 + +#define SZ_ERROR_DATA 1 +#define SZ_ERROR_MEM 2 +#define SZ_ERROR_CRC 3 +#define SZ_ERROR_UNSUPPORTED 4 +#define SZ_ERROR_PARAM 5 +#define SZ_ERROR_INPUT_EOF 6 +#define SZ_ERROR_OUTPUT_EOF 7 +#define SZ_ERROR_READ 8 +#define SZ_ERROR_WRITE 9 +#define SZ_ERROR_PROGRESS 10 +#define SZ_ERROR_FAIL 11 +#define SZ_ERROR_THREAD 12 + +#define SZ_ERROR_ARCHIVE 16 +#define SZ_ERROR_NO_ARCHIVE 17 + +typedef int SRes; + +#ifdef _WIN32 +typedef DWORD WRes; +#else +typedef int WRes; +#endif + +#ifndef RINOK +#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } +#endif + +typedef unsigned char Byte; +typedef short Int16; +typedef unsigned short UInt16; + +#ifdef _LZMA_UINT32_IS_ULONG +typedef long Int32; +typedef unsigned long UInt32; +#else +typedef int Int32; +typedef unsigned int UInt32; +#endif + +#ifdef _SZ_NO_INT_64 + +/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. + NOTES: Some code will work incorrectly in that case! */ + +typedef long Int64; +typedef unsigned long UInt64; + +#else + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef __int64 Int64; +typedef unsigned __int64 UInt64; +#else +typedef long long int Int64; +typedef unsigned long long int UInt64; +#endif + +#endif + +#ifdef _LZMA_NO_SYSTEM_SIZE_T +typedef UInt32 SizeT; +#else +typedef size_t SizeT; +#endif + +typedef int Bool; +#define True 1 +#define False 0 + + +#ifdef _WIN32 +#define MY_STD_CALL __stdcall +#else +#define MY_STD_CALL +#endif + +#ifdef _MSC_VER + +#if _MSC_VER >= 1300 +#define MY_NO_INLINE __declspec(noinline) +#else +#define MY_NO_INLINE +#endif + +#define MY_CDECL __cdecl +#define MY_FAST_CALL __fastcall + +#else + +#define MY_CDECL +#define MY_FAST_CALL + +#endif + + +/* The following interfaces use first parameter as pointer to structure */ + +typedef struct +{ + Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */ +} IByteIn; + +typedef struct +{ + void (*Write)(void *p, Byte b); +} IByteOut; + +typedef struct +{ + SRes (*Read)(void *p, void *buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) < input(*size)) is allowed */ +} ISeqInStream; + +/* it can return SZ_ERROR_INPUT_EOF */ +SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); +SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); +SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); + +typedef struct +{ + size_t (*Write)(void *p, const void *buf, size_t size); + /* Returns: result - the number of actually written bytes. + (result < size) means error */ +} ISeqOutStream; + +typedef enum +{ + SZ_SEEK_SET = 0, + SZ_SEEK_CUR = 1, + SZ_SEEK_END = 2 +} ESzSeek; + +typedef struct +{ + SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ + SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); +} ISeekInStream; + +typedef struct +{ + SRes (*Look)(void *p, const void **buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) > input(*size)) is not allowed + (output(*size) < input(*size)) is allowed */ + SRes (*Skip)(void *p, size_t offset); + /* offset must be <= output(*size) of Look */ + + SRes (*Read)(void *p, void *buf, size_t *size); + /* reads directly (without buffer). It's same as ISeqInStream::Read */ + SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); +} ILookInStream; + +SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); +SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); + +/* reads via ILookInStream::Read */ +SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); +SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); + +#define LookToRead_BUF_SIZE (1 << 14) + +typedef struct +{ + ILookInStream s; + ISeekInStream *realStream; + size_t pos; + size_t size; + Byte buf[LookToRead_BUF_SIZE]; +} CLookToRead; + +void LookToRead_CreateVTable(CLookToRead *p, int lookahead); +void LookToRead_Init(CLookToRead *p); + +typedef struct +{ + ISeqInStream s; + ILookInStream *realStream; +} CSecToLook; + +void SecToLook_CreateVTable(CSecToLook *p); + +typedef struct +{ + ISeqInStream s; + ILookInStream *realStream; +} CSecToRead; + +void SecToRead_CreateVTable(CSecToRead *p); + +typedef struct +{ + SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); + /* Returns: result. (result != SZ_OK) means break. + Value (UInt64)(Int64)-1 for size means unknown value. */ +} ICompressProgress; + +typedef struct +{ + void *(*Alloc)(void *p, size_t size); + void (*Free)(void *p, void *address); /* address can be 0 */ +} ISzAlloc; + +#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) +#define IAlloc_Free(p, a) (p)->Free((p), a) + +EXTERN_C_END + +#endif diff --git a/StormLib/src/lzma/info.txt b/StormLib/src/lzma/info.txt new file mode 100644 index 000000000..4cee86e35 --- /dev/null +++ b/StormLib/src/lzma/info.txt @@ -0,0 +1 @@ +Taken from LZMA SDK v 9.11 \ No newline at end of file diff --git a/StormLib/src/pklib/crc32.c b/StormLib/src/pklib/crc32.c new file mode 100644 index 000000000..cd47b1d4a --- /dev/null +++ b/StormLib/src/pklib/crc32.c @@ -0,0 +1,66 @@ +/*****************************************************************************/ +/* crc32.c Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Pkware Data Compression Library Version 1.11 */ +/* Dissassembled method crc32 - cdecl version */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 09.04.03 1.00 Lad The first version of crc32.c */ +/* 02.05.03 1.00 Lad Stress test done */ +/*****************************************************************************/ + +#include "pklib.h" + +static unsigned long crc_table[] = +{ + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +}; + + +unsigned long PKEXPORT crc32_pklib(char * buffer, unsigned int * psize, unsigned long * old_crc) +{ + unsigned int size = *psize; + unsigned long ch; + unsigned long crc_value = *old_crc; + + while(size-- != 0) + { + ch = *buffer++ ^ (char)crc_value; + crc_value >>= 8; + + crc_value = crc_table[ch & 0x0FF] ^ crc_value; + } + return crc_value; +} diff --git a/StormLib/src/pklib/explode.c b/StormLib/src/pklib/explode.c new file mode 100644 index 000000000..0f551d8ed --- /dev/null +++ b/StormLib/src/pklib/explode.c @@ -0,0 +1,522 @@ +/*****************************************************************************/ +/* explode.c Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Implode function of PKWARE Data Compression library */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 11.03.03 1.00 Lad Splitted from Pkware.cpp */ +/* 08.04.03 1.01 Lad Renamed to explode.c to be compatible with pklib */ +/* 02.05.03 1.01 Lad Stress test done */ +/* 22.04.10 1.01 Lad Documented */ +/*****************************************************************************/ + +#include +#include + +#include "pklib.h" + +#define PKDCL_OK 0 +#define PKDCL_STREAM_END 1 // All data from the input stream is read +#define PKDCL_NEED_DICT 2 // Need more data (dictionary) +#define PKDCL_CONTINUE 10 // Internal flag, not returned to user +#define PKDCL_GET_INPUT 11 // Internal flag, not returned to user + +char CopyrightPkware[] = "PKWARE Data Compression Library for Win32\r\n" + "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n" + "Patent No. 5,051,745\r\n" + "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n" + "Version 1.11\r\n"; + +//----------------------------------------------------------------------------- +// Tables + +unsigned char DistBits[0x40] = +{ + 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 +}; + +unsigned char DistCode[0x40] = +{ + 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A, + 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C, + 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08, + 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00 +}; + +unsigned char ExLenBits[0x10] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 +}; + +unsigned short LenBase[0x10] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106 +}; + +unsigned char LenBits[0x10] = +{ + 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07 +}; + +unsigned char LenCode[0x10] = +{ + 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00 +}; + +unsigned char ChBitsAsc[0x100] = +{ + 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08, + 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B, + 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06, + 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08, + 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05, + 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, + 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D +}; + +unsigned short ChCodeAsc[0x100] = +{ + 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0, + 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0, + 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360, + 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60, + 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8, + 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098, + 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C, + 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710, + 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8, + 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E, + 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8, + 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088, + 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A, + 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D, + 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078, + 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0, + 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040, + 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380, + 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180, + 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280, + 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080, + 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300, + 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0, + 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320, + 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220, + 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0, + 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0, + 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340, + 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900, + 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600, + 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200, + 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000 +}; + +//----------------------------------------------------------------------------- +// Local functions + +static void GenDecodeTabs( + unsigned char * positions, // [out] Table of positions + unsigned char * start_indexes, // [in] Table of start indexes + unsigned char * length_bits, // [in] Table of lengths. Each length is stored as number of bits + size_t elements) // [in] Number of elements in start_indexes and length_bits +{ + unsigned int index; + unsigned int length; + size_t i; + + for(i = 0; i < elements; i++) + { + length = 1 << length_bits[i]; // Get the length in bytes + + for(index = start_indexes[i]; index < 0x100; index += length) + { + positions[index] = (unsigned char)i; + } + } +} + +static void GenAscTabs(TDcmpStruct * pWork) +{ + unsigned short * pChCodeAsc = &ChCodeAsc[0xFF]; + unsigned int acc, add; + unsigned short count; + + for(count = 0x00FF; pChCodeAsc >= ChCodeAsc; pChCodeAsc--, count--) + { + unsigned char * pChBitsAsc = pWork->ChBitsAsc + count; + unsigned char bits_asc = *pChBitsAsc; + + if(bits_asc <= 8) + { + add = (1 << bits_asc); + acc = *pChCodeAsc; + + do + { + pWork->offs2C34[acc] = (unsigned char)count; + acc += add; + } + while(acc < 0x100); + } + else if((acc = (*pChCodeAsc & 0xFF)) != 0) + { + pWork->offs2C34[acc] = 0xFF; + + if(*pChCodeAsc & 0x3F) + { + bits_asc -= 4; + *pChBitsAsc = bits_asc; + + add = (1 << bits_asc); + acc = *pChCodeAsc >> 4; + do + { + pWork->offs2D34[acc] = (unsigned char)count; + acc += add; + } + while(acc < 0x100); + } + else + { + bits_asc -= 6; + *pChBitsAsc = bits_asc; + + add = (1 << bits_asc); + acc = *pChCodeAsc >> 6; + do + { + pWork->offs2E34[acc] = (unsigned char)count; + acc += add; + } + while(acc < 0x80); + } + } + else + { + bits_asc -= 8; + *pChBitsAsc = bits_asc; + + add = (1 << bits_asc); + acc = *pChCodeAsc >> 8; + do + { + pWork->offs2EB4[acc] = (unsigned char)count; + acc += add; + } + while(acc < 0x100); + } + } +} + +//----------------------------------------------------------------------------- +// Removes given number of bits in the bit buffer. New bits are reloaded from +// the input buffer, if needed. +// Returns: PKDCL_OK: Operation was successful +// PKDCL_STREAM_END: There are no more bits in the input buffer + +static int WasteBits(TDcmpStruct * pWork, unsigned int nBits) +{ + // If number of bits required is less than number of (bits in the buffer) ? + if(nBits <= pWork->extra_bits) + { + pWork->extra_bits -= nBits; + pWork->bit_buff >>= nBits; + return PKDCL_OK; + } + + // Load input buffer if necessary + pWork->bit_buff >>= pWork->extra_bits; + if(pWork->in_pos == pWork->in_bytes) + { + pWork->in_pos = sizeof(pWork->in_buff); + if((pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param)) == 0) + return PKDCL_STREAM_END; + pWork->in_pos = 0; + } + + // Update bit buffer + pWork->bit_buff |= (pWork->in_buff[pWork->in_pos++] << 8); + pWork->bit_buff >>= (nBits - pWork->extra_bits); + pWork->extra_bits = (pWork->extra_bits - nBits) + 8; + return PKDCL_OK; +} + +//----------------------------------------------------------------------------- +// Decodes next literal from the input (compressed) data. +// Returns : 0x000: One byte 0x00 +// 0x001: One byte 0x01 +// ... +// 0x0FF: One byte 0xFF +// 0x100: Repetition, length of 0x02 bytes +// 0x101: Repetition, length of 0x03 bytes +// ... +// 0x304: Repetition, length of 0x206 bytes +// 0x305: End of stream +// 0x306: Error + +static unsigned int DecodeLit(TDcmpStruct * pWork) +{ + unsigned int extra_length_bits; // Number of bits of extra literal length + unsigned int length_code; // Length code + unsigned int value; + + // Test the current bit in byte buffer. If is not set, simply return the next 8 bits. + if(pWork->bit_buff & 1) + { + // Remove one bit from the input data + if(WasteBits(pWork, 1)) + return 0x306; + + // The next 8 bits hold the index to the length code table + length_code = pWork->LengthCodes[pWork->bit_buff & 0xFF]; + + // Remove the apropriate number of bits + if(WasteBits(pWork, pWork->LenBits[length_code])) + return 0x306; + + // Are there some extra bits for the obtained length code ? + if((extra_length_bits = pWork->ExLenBits[length_code]) != 0) + { + unsigned int extra_length = pWork->bit_buff & ((1 << extra_length_bits) - 1); + + if(WasteBits(pWork, extra_length_bits)) + { + if((length_code + extra_length) != 0x10E) + return 0x306; + } + length_code = pWork->LenBase[length_code] + extra_length; + } + + // In order to distinguish uncompressed byte from repetition length, + // we have to add 0x100 to the length. + return length_code + 0x100; + } + + // Remove one bit from the input data + if(WasteBits(pWork, 1)) + return 0x306; + + // If the binary compression type, read 8 bits and return them as one byte. + if(pWork->ctype == CMP_BINARY) + { + unsigned int uncompressed_byte = pWork->bit_buff & 0xFF; + + if(WasteBits(pWork, 8)) + return 0x306; + return uncompressed_byte; + } + + // When ASCII compression ... + if(pWork->bit_buff & 0xFF) + { + value = pWork->offs2C34[pWork->bit_buff & 0xFF]; + + if(value == 0xFF) + { + if(pWork->bit_buff & 0x3F) + { + if(WasteBits(pWork, 4)) + return 0x306; + + value = pWork->offs2D34[pWork->bit_buff & 0xFF]; + } + else + { + if(WasteBits(pWork, 6)) + return 0x306; + + value = pWork->offs2E34[pWork->bit_buff & 0x7F]; + } + } + } + else + { + if(WasteBits(pWork, 8)) + return 0x306; + + value = pWork->offs2EB4[pWork->bit_buff & 0xFF]; + } + + return WasteBits(pWork, pWork->ChBitsAsc[value]) ? 0x306 : value; +} + +//----------------------------------------------------------------------------- +// Decodes the distance of the repetition, backwards relative to the +// current output buffer position + +static unsigned int DecodeDist(TDcmpStruct * pWork, unsigned int rep_length) +{ + unsigned int dist_pos_code; // Distance position code + unsigned int dist_pos_bits; // Number of bits of distance position + unsigned int distance; // Distance position + + // Next 2-8 bits in the input buffer is the distance position code + dist_pos_code = pWork->DistPosCodes[pWork->bit_buff & 0xFF]; + dist_pos_bits = pWork->DistBits[dist_pos_code]; + if(WasteBits(pWork, dist_pos_bits)) + return 0; + + if(rep_length == 2) + { + // If the repetition is only 2 bytes length, + // then take 2 bits from the stream in order to get the distance + distance = (dist_pos_code << 2) | (pWork->bit_buff & 0x03); + if(WasteBits(pWork, 2)) + return 0; + } + else + { + // If the repetition is more than 2 bytes length, + // then take "dsize_bits" bits in order to get the distance + distance = (dist_pos_code << pWork->dsize_bits) | (pWork->bit_buff & pWork->dsize_mask); + if(WasteBits(pWork, pWork->dsize_bits)) + return 0; + } + return distance + 1; +} + +static unsigned int Expand(TDcmpStruct * pWork) +{ + unsigned int next_literal; // Literal decoded from the compressed data + unsigned int result; // Value to be returned + unsigned int copyBytes; // Number of bytes to copy to the output buffer + + pWork->outputPos = 0x1000; // Initialize output buffer position + + // Decode the next literal from the input data. + // The returned literal can either be an uncompressed byte (next_literal < 0x100) + // or an encoded length of the repeating byte sequence that + // is to be copied to the current buffer position + while((result = next_literal = DecodeLit(pWork)) < 0x305) + { + // If the literal is greater than 0x100, it holds length + // of repeating byte sequence + // literal of 0x100 means repeating sequence of 0x2 bytes + // literal of 0x101 means repeating sequence of 0x3 bytes + // ... + // literal of 0x305 means repeating sequence of 0x207 bytes + if(next_literal >= 0x100) + { + unsigned char * source; + unsigned char * target; + unsigned int rep_length; // Length of the repetition, in bytes + unsigned int minus_dist; // Backward distance to the repetition, relative to the current buffer position + + // Get the length of the repeating sequence. + // Note that the repeating block may overlap the current output position, + // for example if there was a sequence of equal bytes + rep_length = next_literal - 0xFE; + + // Get backward distance to the repetition + if((minus_dist = DecodeDist(pWork, rep_length)) == 0) + { + result = 0x306; + break; + } + + // Target and source pointer + target = &pWork->out_buff[pWork->outputPos]; + source = target - minus_dist; + + // Update buffer output position + pWork->outputPos += rep_length; + + // Copy the repeating sequence + while(rep_length-- > 0) + *target++ = *source++; + } + else + { + pWork->out_buff[pWork->outputPos++] = (unsigned char)next_literal; + } + + // Flush the output buffer, if number of extracted bytes has reached the end + if(pWork->outputPos >= 0x2000) + { + // Copy decompressed data into user buffer + copyBytes = 0x1000; + pWork->write_buf((char *)&pWork->out_buff[0x1000], ©Bytes, pWork->param); + + // Now copy the decompressed data to the first half of the buffer. + // This is needed because the decompression might reuse them as repetitions. + // Note that if the output buffer overflowed previously, the extra decompressed bytes + // are stored in "out_buff_overflow", and they will now be + // within decompressed part of the output buffer. + memmove(pWork->out_buff, &pWork->out_buff[0x1000], pWork->outputPos - 0x1000); + pWork->outputPos -= 0x1000; + } + } + + // Flush any remaining decompressed bytes + copyBytes = pWork->outputPos - 0x1000; + pWork->write_buf((char *)&pWork->out_buff[0x1000], ©Bytes, pWork->param); + return result; +} + + +//----------------------------------------------------------------------------- +// Main exploding function. + +unsigned int PKEXPORT explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param) +{ + TDcmpStruct * pWork = (TDcmpStruct *)work_buf; + + // Initialize work struct and load compressed data + // Note: The caller must zero the "work_buff" before passing it to explode + pWork->read_buf = read_buf; + pWork->write_buf = write_buf; + pWork->param = param; + pWork->in_pos = sizeof(pWork->in_buff); + pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param); + if(pWork->in_bytes <= 4) + return CMP_BAD_DATA; + + pWork->ctype = pWork->in_buff[0]; // Get the compression type (CMP_BINARY or CMP_ASCII) + pWork->dsize_bits = pWork->in_buff[1]; // Get the dictionary size + pWork->bit_buff = pWork->in_buff[2]; // Initialize 16-bit bit buffer + pWork->extra_bits = 0; // Extra (over 8) bits + pWork->in_pos = 3; // Position in input buffer + + // Test for the valid dictionary size + if(4 > pWork->dsize_bits || pWork->dsize_bits > 6) + return CMP_INVALID_DICTSIZE; + + pWork->dsize_mask = 0xFFFF >> (0x10 - pWork->dsize_bits); // Shifted by 'sar' instruction + + if(pWork->ctype != CMP_BINARY) + { + if(pWork->ctype != CMP_ASCII) + return CMP_INVALID_MODE; + + memcpy(pWork->ChBitsAsc, ChBitsAsc, sizeof(pWork->ChBitsAsc)); + GenAscTabs(pWork); + } + + memcpy(pWork->LenBits, LenBits, sizeof(pWork->LenBits)); + GenDecodeTabs(pWork->LengthCodes, LenCode, pWork->LenBits, sizeof(pWork->LenBits)); + memcpy(pWork->ExLenBits, ExLenBits, sizeof(pWork->ExLenBits)); + memcpy(pWork->LenBase, LenBase, sizeof(pWork->LenBase)); + memcpy(pWork->DistBits, DistBits, sizeof(pWork->DistBits)); + GenDecodeTabs(pWork->DistPosCodes, DistCode, pWork->DistBits, sizeof(pWork->DistBits)); + if(Expand(pWork) != 0x306) + return CMP_NO_ERROR; + + return CMP_ABORT; +} diff --git a/StormLib/src/pklib/implode.c b/StormLib/src/pklib/implode.c new file mode 100644 index 000000000..90cb4821c --- /dev/null +++ b/StormLib/src/pklib/implode.c @@ -0,0 +1,676 @@ +/*****************************************************************************/ +/* implode.c Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Implode function of PKWARE Data Compression library */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 11.04.03 1.00 Lad First version of implode.c */ +/* 02.05.03 1.00 Lad Stress test done */ +/* 22.04.10 1.01 Lad Documented */ +/*****************************************************************************/ + +#include +#include + +#include "pklib.h" + +#if ((1200 < _MSC_VER) && (_MSC_VER < 1400)) +#pragma optimize("", off) // Fucking Microsoft VS.NET 2003 compiler !!! (_MSC_VER=1310) +#endif + +//----------------------------------------------------------------------------- +// Defines + +#define MAX_REP_LENGTH 0x204 // The longest allowed repetition + +//----------------------------------------------------------------------------- +// Macros + +// Macro for calculating hash of the current byte pair. +// Note that most exact byte pair hash would be buffer[0] + buffer[1] << 0x08, +// but even this way gives nice indication of equal byte pairs, with significantly +// smaller size of the array that holds numbers of those hashes +#define BYTE_PAIR_HASH(buffer) ((buffer[0] * 4) + (buffer[1] * 5)) + +//----------------------------------------------------------------------------- +// Local functions + +// Builds the "hash_to_index" table and "pair_hash_offsets" table. +// Every element of "hash_to_index" will contain lowest index to the +// "pair_hash_offsets" table, effectively giving offset of the first +// occurence of the given PAIR_HASH in the input data. +static void SortBuffer(TCmpStruct * pWork, unsigned char * buffer_begin, unsigned char * buffer_end) +{ + unsigned short * phash_to_index; + unsigned char * buffer_ptr; + unsigned short total_sum = 0; + unsigned long byte_pair_hash; // Hash value of the byte pair + unsigned short byte_pair_offs; // Offset of the byte pair, relative to "work_buff" + + // Zero the entire "phash_to_index" table + memset(pWork->phash_to_index, 0, sizeof(pWork->phash_to_index)); + + // Step 1: Count amount of each PAIR_HASH in the input buffer + // The table will look like this: + // offs 0x000: Number of occurences of PAIR_HASH 0 + // offs 0x001: Number of occurences of PAIR_HASH 1 + // ... + // offs 0x8F7: Number of occurences of PAIR_HASH 0x8F7 (the highest hash value) + for(buffer_ptr = buffer_begin; buffer_ptr < buffer_end; buffer_ptr++) + pWork->phash_to_index[BYTE_PAIR_HASH(buffer_ptr)]++; + + // Step 2: Convert the table to the array of PAIR_HASH amounts. + // Each element contains count of PAIR_HASHes that is less or equal + // to element index + // The table will look like this: + // offs 0x000: Number of occurences of PAIR_HASH 0 or lower + // offs 0x001: Number of occurences of PAIR_HASH 1 or lower + // ... + // offs 0x8F7: Number of occurences of PAIR_HASH 0x8F7 or lower + for(phash_to_index = pWork->phash_to_index; phash_to_index < &pWork->phash_to_index_end; phash_to_index++) + { + total_sum = total_sum + phash_to_index[0]; + phash_to_index[0] = total_sum; + } + + // Step 3: Convert the table to the array of indexes. + // Now, each element contains index to the first occurence of given PAIR_HASH + for(buffer_end--; buffer_end >= buffer_begin; buffer_end--) + { + byte_pair_hash = BYTE_PAIR_HASH(buffer_end); + byte_pair_offs = (unsigned short)(buffer_end - pWork->work_buff); + + pWork->phash_to_index[byte_pair_hash]--; + pWork->phash_offs[pWork->phash_to_index[byte_pair_hash]] = byte_pair_offs; + } +} + +static void FlushBuf(TCmpStruct * pWork) +{ + unsigned char save_ch1; + unsigned char save_ch2; + unsigned int size = 0x800; + + pWork->write_buf(pWork->out_buff, &size, pWork->param); + + save_ch1 = pWork->out_buff[0x800]; + save_ch2 = pWork->out_buff[pWork->out_bytes]; + pWork->out_bytes -= 0x800; + + memset(pWork->out_buff, 0, sizeof(pWork->out_buff)); + + if(pWork->out_bytes != 0) + pWork->out_buff[0] = save_ch1; + if(pWork->out_bits != 0) + pWork->out_buff[pWork->out_bytes] = save_ch2; +} + +static void OutputBits(TCmpStruct * pWork, unsigned int nbits, unsigned long bit_buff) +{ + unsigned int out_bits; + + // If more than 8 bits to output, do recursion + if(nbits > 8) + { + OutputBits(pWork, 8, bit_buff); + bit_buff >>= 8; + nbits -= 8; + } + + // Add bits to the last out byte in out_buff; + out_bits = pWork->out_bits; + pWork->out_buff[pWork->out_bytes] |= (unsigned char)(bit_buff << out_bits); + pWork->out_bits += nbits; + + // If 8 or more bits, increment number of bytes + if(pWork->out_bits > 8) + { + pWork->out_bytes++; + bit_buff >>= (8 - out_bits); + + pWork->out_buff[pWork->out_bytes] = (unsigned char)bit_buff; + pWork->out_bits &= 7; + } + else + { + pWork->out_bits &= 7; + if(pWork->out_bits == 0) + pWork->out_bytes++; + } + + // If there is enough compressed bytes, flush them + if(pWork->out_bytes >= 0x800) + FlushBuf(pWork); +} + +// This function searches for a repetition +// (a previous occurence of the current byte sequence) +// Returns length of the repetition, and stores the backward distance +// to pWork structure. +static unsigned int FindRep(TCmpStruct * pWork, unsigned char * input_data) +{ + unsigned short * phash_to_index; // Pointer into pWork->phash_to_index table + unsigned short * phash_offs; // Pointer to the table containing offsets of each PAIR_HASH + unsigned char * repetition_limit; // An eventual repetition must be at position below this pointer + unsigned char * prev_repetition; // Pointer to the previous occurence of the current PAIR_HASH + unsigned char * prev_rep_end; // End of the previous repetition + unsigned char * input_data_ptr; + unsigned short phash_offs_index; // Index to the table with PAIR_HASH positions + unsigned short min_phash_offs; // The lowest allowed hash offset + unsigned short offs_in_rep; // Offset within found repetition + unsigned int equal_byte_count; // Number of bytes that are equal to the previous occurence + unsigned int rep_length = 1; // Length of the found repetition + unsigned int rep_length2; // Secondary repetition + unsigned char pre_last_byte; // Last but one byte from a repetion + unsigned short di_val; + + // Calculate the previous position of the PAIR_HASH + phash_to_index = pWork->phash_to_index + BYTE_PAIR_HASH(input_data); + min_phash_offs = (unsigned short)((input_data - pWork->work_buff) - pWork->dsize_bytes + 1); + phash_offs_index = phash_to_index[0]; + + // If the PAIR_HASH offset is below the limit, find a next one + phash_offs = pWork->phash_offs + phash_offs_index; + if(*phash_offs < min_phash_offs) + { + while(*phash_offs < min_phash_offs) + { + phash_offs_index++; + phash_offs++; + } + *phash_to_index = phash_offs_index; + } + + // Get the first location of the PAIR_HASH, + // and thus the first eventual location of byte repetition + phash_offs = pWork->phash_offs + phash_offs_index; + prev_repetition = pWork->work_buff + phash_offs[0]; + repetition_limit = input_data - 1; + + // If the current PAIR_HASH was not encountered before, + // we haven't found a repetition. + if(prev_repetition >= repetition_limit) + return 0; + + // We have found a match of a PAIR_HASH. Now we have to make sure + // that it is also a byte match, because PAIR_HASH is not unique. + // We compare the bytes and count the length of the repetition + input_data_ptr = input_data; + for(;;) + { + // If the first byte of the repetition and the so-far-last byte + // of the repetition are equal, we will compare the blocks. + if(*input_data_ptr == *prev_repetition && input_data_ptr[rep_length-1] == prev_repetition[rep_length-1]) + { + // Skip the current byte + prev_repetition++; + input_data_ptr++; + equal_byte_count = 2; + + // Now count how many more bytes are equal + while(equal_byte_count < MAX_REP_LENGTH) + { + prev_repetition++; + input_data_ptr++; + + // Are the bytes different ? + if(*prev_repetition != *input_data_ptr) + break; + + equal_byte_count++; + } + + // If we found a repetition of at least the same length, take it. + // If there are multiple repetitions in the input buffer, this will + // make sure that we find the most recent one, which in turn allows + // us to store backward length in less amount of bits + input_data_ptr = input_data; + if(equal_byte_count >= rep_length) + { + // Calculate the backward distance of the repetition. + // Note that the distance is stored as decremented by 1 + pWork->distance = (unsigned int)(input_data - prev_repetition + equal_byte_count - 1); + + // Repetitions longer than 10 bytes will be stored in more bits, + // so they need a bit different handling + if((rep_length = equal_byte_count) > 10) + break; + } + } + + // Move forward in the table of PAIR_HASH repetitions. + // There might be a more recent occurence of the same repetition. + phash_offs_index++; + phash_offs++; + prev_repetition = pWork->work_buff + phash_offs[0]; + + // If the next repetition is beyond the minimum allowed repetition, we are done. + if(prev_repetition >= repetition_limit) + { + // A repetition must have at least 2 bytes, otherwise it's not worth it + return (rep_length >= 2) ? rep_length : 0; + } + } + + // If the repetition has max length of 0x204 bytes, we can't go any fuhrter + if(equal_byte_count == MAX_REP_LENGTH) + { + pWork->distance--; + return equal_byte_count; + } + + // Check for possibility of a repetition that occurs at more recent position + phash_offs = pWork->phash_offs + phash_offs_index; + if(pWork->work_buff + phash_offs[1] >= repetition_limit) + return rep_length; + + // + // The following part checks if there isn't a longer repetition at + // a latter offset, that would lead to better compression. + // + // Example of data that can trigger this optimization: + // + // "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEQQQQQQQQQQQQ" + // "XYZ" + // "EEEEEEEEEEEEEEEEQQQQQQQQQQQQ"; + // + // Description of data in this buffer + // [0x00] Single byte "E" + // [0x01] Single byte "E" + // [0x02] Repeat 0x1E bytes from [0x00] + // [0x20] Single byte "X" + // [0x21] Single byte "Y" + // [0x22] Single byte "Z" + // [0x23] 17 possible previous repetitions of length at least 0x10 bytes: + // - Repetition of 0x10 bytes from [0x00] "EEEEEEEEEEEEEEEE" + // - Repetition of 0x10 bytes from [0x01] "EEEEEEEEEEEEEEEE" + // - Repetition of 0x10 bytes from [0x02] "EEEEEEEEEEEEEEEE" + // ... + // - Repetition of 0x10 bytes from [0x0F] "EEEEEEEEEEEEEEEE" + // - Repetition of 0x1C bytes from [0x10] "EEEEEEEEEEEEEEEEQQQQQQQQQQQQ" + // The last repetition is the best one. + // + + pWork->offs09BC[0] = 0xFFFF; + pWork->offs09BC[1] = 0x0000; + di_val = 0; + + // Note: I failed to figure out what does the table "offs09BC" mean. + // If anyone has an idea, let me know to zezula_at_volny_dot_cz + for(offs_in_rep = 1; offs_in_rep < rep_length; ) + { + if(input_data[offs_in_rep] != input_data[di_val]) + { + di_val = pWork->offs09BC[di_val]; + if(di_val != 0xFFFF) + continue; + } + pWork->offs09BC[++offs_in_rep] = ++di_val; + } + + // + // Now go through all the repetitions from the first found one + // to the current input data, and check if any of them migh be + // a start of a greater sequence match. + // + + prev_repetition = pWork->work_buff + phash_offs[0]; + prev_rep_end = prev_repetition + rep_length; + rep_length2 = rep_length; + + for(;;) + { + rep_length2 = pWork->offs09BC[rep_length2]; + if(rep_length2 == 0xFFFF) + rep_length2 = 0; + + // Get the pointer to the previous repetition + phash_offs = pWork->phash_offs + phash_offs_index; + + // Skip those repetitions that don't reach the end + // of the first found repetition + do + { + phash_offs++; + phash_offs_index++; + prev_repetition = pWork->work_buff + *phash_offs; + if(prev_repetition >= repetition_limit) + return rep_length; + } + while(prev_repetition + rep_length2 < prev_rep_end); + + // Verify if the last but one byte from the repetition matches + // the last but one byte from the input data. + // If not, find a next repetition + pre_last_byte = input_data[rep_length - 2]; + if(pre_last_byte == prev_repetition[rep_length - 2]) + { + // If the new repetition reaches beyond the end + // of previously found repetition, reset the repetition length to zero. + if(prev_repetition + rep_length2 != prev_rep_end) + { + prev_rep_end = prev_repetition; + rep_length2 = 0; + } + } + else + { + phash_offs = pWork->phash_offs + phash_offs_index; + do + { + phash_offs++; + phash_offs_index++; + prev_repetition = pWork->work_buff + *phash_offs; + if(prev_repetition >= repetition_limit) + return rep_length; + } + while(prev_repetition[rep_length - 2] != pre_last_byte || prev_repetition[0] != input_data[0]); + + // Reset the length of the repetition to 2 bytes only + prev_rep_end = prev_repetition + 2; + rep_length2 = 2; + } + + // Find out how many more characters are equal to the first repetition. + while(*prev_rep_end == input_data[rep_length2]) + { + if(++rep_length2 >= 0x204) + break; + prev_rep_end++; + } + + // Is the newly found repetion at least as long as the previous one ? + if(rep_length2 >= rep_length) + { + // Calculate the distance of the new repetition + pWork->distance = (unsigned int)(input_data - prev_repetition - 1); + if((rep_length = rep_length2) == 0x204) + return rep_length; + + // Update the additional elements in the "offs09BC" table + // to reflect new rep length + while(offs_in_rep < rep_length2) + { + if(input_data[offs_in_rep] != input_data[di_val]) + { + di_val = pWork->offs09BC[di_val]; + if(di_val != 0xFFFF) + continue; + } + pWork->offs09BC[++offs_in_rep] = ++di_val; + } + } + } +} + +static void WriteCmpData(TCmpStruct * pWork) +{ + unsigned char * input_data_end; // Pointer to the end of the input data + unsigned char * input_data = pWork->work_buff + pWork->dsize_bytes + 0x204; + unsigned int input_data_ended = 0; // If 1, then all data from the input stream have been already loaded + unsigned int save_rep_length; // Saved length of current repetition + unsigned int save_distance = 0; // Saved distance of current repetition + unsigned int rep_length; // Length of the found repetition + unsigned int phase = 0; // + + // Store the compression type and dictionary size + pWork->out_buff[0] = (char)pWork->ctype; + pWork->out_buff[1] = (char)pWork->dsize_bits; + pWork->out_bytes = 2; + + // Reset output buffer to zero + memset(&pWork->out_buff[2], 0, sizeof(pWork->out_buff) - 2); + pWork->out_bits = 0; + + while(input_data_ended == 0) + { + unsigned int bytes_to_load = 0x1000; + int total_loaded = 0; + int bytes_loaded; + + // Load the bytes from the input stream, up to 0x1000 bytes + while(bytes_to_load != 0) + { + bytes_loaded = pWork->read_buf((char *)pWork->work_buff + pWork->dsize_bytes + 0x204 + total_loaded, + &bytes_to_load, + pWork->param); + if(bytes_loaded == 0) + { + if(total_loaded == 0 && phase == 0) + goto __Exit; + input_data_ended = 1; + break; + } + else + { + bytes_to_load -= bytes_loaded; + total_loaded += bytes_loaded; + } + } + + input_data_end = pWork->work_buff + pWork->dsize_bytes + total_loaded; + if(input_data_ended) + input_data_end += 0x204; + + // + // Warning: The end of the buffer passed to "SortBuffer" is actually 2 bytes beyond + // valid data. It is questionable if this is actually a bug or not, + // but it might cause the compressed data output to be dependent on random bytes + // that are in the buffer. + // To prevent that, the calling application must always zero the compression + // buffer before passing it to "implode" + // + + // Search the PAIR_HASHes of the loaded blocks. Also, include + // previously compressed data, if any. + switch(phase) + { + case 0: + SortBuffer(pWork, input_data, input_data_end + 1); + phase++; + if(pWork->dsize_bytes != 0x1000) + phase++; + break; + + case 1: + SortBuffer(pWork, input_data - pWork->dsize_bytes + 0x204, input_data_end + 1); + phase++; + break; + + default: + SortBuffer(pWork, input_data - pWork->dsize_bytes, input_data_end + 1); + break; + } + + // Perform the compression of the current block + while(input_data < input_data_end) + { + // Find if the current byte sequence wasn't there before. + rep_length = FindRep(pWork, input_data); + while(rep_length != 0) + { + // If we found repetition of 2 bytes, that is 0x100 or fuhrter back, + // don't bother. Storing the distance of 0x100 bytes would actually + // take more space than storing the 2 bytes as-is. + if(rep_length == 2 && pWork->distance >= 0x100) + break; + + // When we are at the end of the input data, we cannot allow + // the repetition to go past the end of the input data. + if(input_data_ended && input_data + rep_length > input_data_end) + { + // Shorten the repetition length so that it only covers valid data + rep_length = (unsigned long)(input_data_end - input_data); + if(rep_length < 2) + break; + + // If we got repetition of 2 bytes, that is 0x100 or more backward, don't bother + if(rep_length == 2 && pWork->distance >= 0x100) + break; + goto __FlushRepetition; + } + + if(rep_length >= 8 || input_data + 1 >= input_data_end) + goto __FlushRepetition; + + // Try to find better repetition 1 byte later. + // Example: "ARROCKFORT" "AROCKFORT" + // When "input_data" points to the second string, FindRep + // returns the occurence of "AR". But there is longer repetition "ROCKFORT", + // beginning 1 byte after. + save_rep_length = rep_length; + save_distance = pWork->distance; + rep_length = FindRep(pWork, input_data + 1); + + // Only use the new repetition if it's length is greater than the previous one + if(rep_length > save_rep_length) + { + // If the new repetition if only 1 byte better + // and the previous distance is less than 0x80 bytes, use the previous repetition + if(rep_length > save_rep_length + 1 || save_distance > 0x80) + { + // Flush one byte, so that input_data will point to the secondary repetition + OutputBits(pWork, pWork->nChBits[*input_data], pWork->nChCodes[*input_data]); + input_data++; + continue; + } + } + + // Revert to the previous repetition + rep_length = save_rep_length; + pWork->distance = save_distance; + + __FlushRepetition: + + OutputBits(pWork, pWork->nChBits[rep_length + 0xFE], pWork->nChCodes[rep_length + 0xFE]); + if(rep_length == 2) + { + OutputBits(pWork, pWork->dist_bits[pWork->distance >> 2], + pWork->dist_codes[pWork->distance >> 2]); + OutputBits(pWork, 2, pWork->distance & 3); + } + else + { + OutputBits(pWork, pWork->dist_bits[pWork->distance >> pWork->dsize_bits], + pWork->dist_codes[pWork->distance >> pWork->dsize_bits]); + OutputBits(pWork, pWork->dsize_bits, pWork->dsize_mask & pWork->distance); + } + + // Move the begin of the input data by the length of the repetition + input_data += rep_length; + goto _00402252; + } + + // If there was no previous repetition for the current position in the input data, + // just output the 9-bit literal for the one character + OutputBits(pWork, pWork->nChBits[*input_data], pWork->nChCodes[*input_data]); + input_data++; +_00402252:; + } + + if(input_data_ended == 0) + { + input_data -= 0x1000; + memmove(pWork->work_buff, pWork->work_buff + 0x1000, pWork->dsize_bytes + 0x204); + } + } + +__Exit: + + // Write the termination literal + OutputBits(pWork, pWork->nChBits[0x305], pWork->nChCodes[0x305]); + if(pWork->out_bits != 0) + pWork->out_bytes++; + pWork->write_buf(pWork->out_buff, &pWork->out_bytes, pWork->param); + return; +} + +//----------------------------------------------------------------------------- +// Main imploding function + +unsigned int PKEXPORT implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize) +{ + TCmpStruct * pWork = (TCmpStruct *)work_buf; + unsigned int nChCode; + unsigned int nCount; + unsigned int i; + int nCount2; + + // Fill the work buffer information + // Note: The caller must zero the "work_buff" before passing it to implode + pWork->read_buf = read_buf; + pWork->write_buf = write_buf; + pWork->dsize_bytes = *dsize; + pWork->ctype = *type; + pWork->param = param; + pWork->dsize_bits = 4; + pWork->dsize_mask = 0x0F; + + // Test dictionary size + switch(*dsize) + { + case CMP_IMPLODE_DICT_SIZE3: // 0x1000 bytes + pWork->dsize_bits++; + pWork->dsize_mask |= 0x20; + // No break here !!! + + case CMP_IMPLODE_DICT_SIZE2: // 0x800 bytes + pWork->dsize_bits++; + pWork->dsize_mask |= 0x10; + // No break here !!! + + case CMP_IMPLODE_DICT_SIZE1: // 0x400 + break; + + default: + return CMP_INVALID_DICTSIZE; + } + + // Test the compression type + switch(*type) + { + case CMP_BINARY: // We will compress data with binary compression type + for(nChCode = 0, nCount = 0; nCount < 0x100; nCount++) + { + pWork->nChBits[nCount] = 9; + pWork->nChCodes[nCount] = (unsigned short)nChCode; + nChCode = (nChCode & 0x0000FFFF) + 2; + } + break; + + + case CMP_ASCII: // We will compress data with ASCII compression type + for(nCount = 0; nCount < 0x100; nCount++) + { + pWork->nChBits[nCount] = (unsigned char )(ChBitsAsc[nCount] + 1); + pWork->nChCodes[nCount] = (unsigned short)(ChCodeAsc[nCount] * 2); + } + break; + + default: + return CMP_INVALID_MODE; + } + + for(i = 0; i < 0x10; i++) + { + for(nCount2 = 0; nCount2 < (1 << ExLenBits[i]); nCount2++) + { + pWork->nChBits[nCount] = (unsigned char)(ExLenBits[i] + LenBits[i] + 1); + pWork->nChCodes[nCount] = (unsigned short)((nCount2 << (LenBits[i] + 1)) | ((LenCode[i] & 0xFFFF00FF) * 2) | 1); + nCount++; + } + } + + // Copy the distance codes and distance bits and perform the compression + memcpy(&pWork->dist_codes, DistCode, sizeof(DistCode)); + memcpy(&pWork->dist_bits, DistBits, sizeof(DistBits)); + WriteCmpData(pWork); + return CMP_NO_ERROR; +} diff --git a/StormLib/src/pklib/pklib.h b/StormLib/src/pklib/pklib.h new file mode 100644 index 000000000..d9b2a70a8 --- /dev/null +++ b/StormLib/src/pklib/pklib.h @@ -0,0 +1,158 @@ +/*****************************************************************************/ +/* pklib.h Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Header file for PKWARE Data Compression Library */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 31.03.03 1.00 Lad The first version of pkware.h */ +/*****************************************************************************/ + +#ifndef __PKLIB_H__ +#define __PKLIB_H__ + +//----------------------------------------------------------------------------- +// Defines + +#define CMP_BINARY 0 // Binary compression +#define CMP_ASCII 1 // Ascii compression + +#define CMP_NO_ERROR 0 +#define CMP_INVALID_DICTSIZE 1 +#define CMP_INVALID_MODE 2 +#define CMP_BAD_DATA 3 +#define CMP_ABORT 4 + +#define CMP_IMPLODE_DICT_SIZE1 1024 // Dictionary size of 1024 +#define CMP_IMPLODE_DICT_SIZE2 2048 // Dictionary size of 2048 +#define CMP_IMPLODE_DICT_SIZE3 4096 // Dictionary size of 4096 + +//----------------------------------------------------------------------------- +// Define calling convention + +#ifndef PKEXPORT +#ifdef WIN32 +#define PKEXPORT __cdecl // Use for normal __cdecl calling +#else +#define PKEXPORT +#endif +#endif + +//----------------------------------------------------------------------------- +// Internal structures + +// Compression structure +typedef struct +{ + unsigned int distance; // 0000: Backward distance of the currently found repetition, decreased by 1 + unsigned int out_bytes; // 0004: # bytes available in out_buff + unsigned int out_bits; // 0008: # of bits available in the last out byte + unsigned int dsize_bits; // 000C: Number of bits needed for dictionary size. 4 = 0x400, 5 = 0x800, 6 = 0x1000 + unsigned int dsize_mask; // 0010: Bit mask for dictionary. 0x0F = 0x400, 0x1F = 0x800, 0x3F = 0x1000 + unsigned int ctype; // 0014: Compression type (CMP_ASCII or CMP_BINARY) + unsigned int dsize_bytes; // 0018: Dictionary size in bytes + unsigned char dist_bits[0x40]; // 001C: Distance bits + unsigned char dist_codes[0x40]; // 005C: Distance codes + unsigned char nChBits[0x306]; // 009C: Table of literal bit lengths to be put to the output stream + unsigned short nChCodes[0x306]; // 03A2: Table of literal codes to be put to the output stream + unsigned short offs09AE; // 09AE: + + void * param; // 09B0: User parameter + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); // 9B4 + void (*write_buf)(char *buf, unsigned int *size, void *param); // 9B8 + + unsigned short offs09BC[0x204]; // 09BC: + unsigned long offs0DC4; // 0DC4: + unsigned short phash_to_index[0x900]; // 0DC8: Array of indexes (one for each PAIR_HASH) to the "pair_hash_offsets" table + unsigned short phash_to_index_end; // 1FC8: End marker for "phash_to_index" table + char out_buff[0x802]; // 1FCA: Compressed data + unsigned char work_buff[0x2204]; // 27CC: Work buffer + // + DICT_OFFSET => Dictionary + // + UNCMP_OFFSET => Uncompressed data + unsigned short phash_offs[0x2204]; // 49D0: Table of offsets for each PAIR_HASH +} TCmpStruct; + +#define CMP_BUFFER_SIZE sizeof(TCmpStruct) // Size of compression structure. + // Defined as 36312 in pkware header file + + +// Decompression structure +typedef struct +{ + unsigned long offs0000; // 0000 + unsigned long ctype; // 0004: Compression type (CMP_BINARY or CMP_ASCII) + unsigned long outputPos; // 0008: Position in output buffer + unsigned long dsize_bits; // 000C: Dict size (4, 5, 6 for 0x400, 0x800, 0x1000) + unsigned long dsize_mask; // 0010: Dict size bitmask (0x0F, 0x1F, 0x3F for 0x400, 0x800, 0x1000) + unsigned long bit_buff; // 0014: 16-bit buffer for processing input data + unsigned long extra_bits; // 0018: Number of extra (above 8) bits in bit buffer + unsigned int in_pos; // 001C: Position in in_buff + unsigned long in_bytes; // 0020: Number of bytes in input buffer + void * param; // 0024: Custom parameter + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); // Pointer to function that reads data from the input stream + void (*write_buf)(char *buf, unsigned int *size, void *param);// Pointer to function that writes data to the output stream + + unsigned char out_buff[0x2204]; // 0030: Output circle buffer. + // 0x0000 - 0x0FFF: Previous uncompressed data, kept for repetitions + // 0x1000 - 0x1FFF: Currently decompressed data + // 0x2000 - 0x2203: Reserve space for the longest possible repetition + unsigned char in_buff[0x800]; // 2234: Buffer for data to be decompressed + unsigned char DistPosCodes[0x100]; // 2A34: Table of distance position codes + unsigned char LengthCodes[0x100]; // 2B34: Table of length codes + unsigned char offs2C34[0x100]; // 2C34: Buffer for + unsigned char offs2D34[0x100]; // 2D34: Buffer for + unsigned char offs2E34[0x80]; // 2E34: Buffer for + unsigned char offs2EB4[0x100]; // 2EB4: Buffer for + unsigned char ChBitsAsc[0x100]; // 2FB4: Buffer for + unsigned char DistBits[0x40]; // 30B4: Numbers of bytes to skip copied block length + unsigned char LenBits[0x10]; // 30F4: Numbers of bits for skip copied block length + unsigned char ExLenBits[0x10]; // 3104: Number of valid bits for copied block + unsigned short LenBase[0x10]; // 3114: Buffer for +} TDcmpStruct; + +#define EXP_BUFFER_SIZE sizeof(TDcmpStruct) // Size of decompression structure + // Defined as 12596 in pkware headers + +//----------------------------------------------------------------------------- +// Tables (in explode.c) + +extern unsigned char DistBits[0x40]; +extern unsigned char DistCode[0x40]; +extern unsigned char ExLenBits[0x10]; +extern unsigned short LenBase[0x10]; +extern unsigned char LenBits[0x10]; +extern unsigned char LenCode[0x10]; +extern unsigned char ChBitsAsc[0x100]; +extern unsigned short ChCodeAsc[0x100]; + +//----------------------------------------------------------------------------- +// Public functions + +#ifdef __cplusplus + extern "C" { +#endif + +unsigned int PKEXPORT implode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param, + unsigned int *type, + unsigned int *dsize); + + +unsigned int PKEXPORT explode( + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param); + +// The original name "crc32" was changed to "crc32pk" due +// to compatibility with zlib +unsigned long PKEXPORT crc32_pklib(char *buffer, unsigned int *size, unsigned long *old_crc); + +#ifdef __cplusplus + } // End of 'extern "C"' declaration +#endif + +#endif // __PKLIB_H__ diff --git a/StormLib/src/resource.h b/StormLib/src/resource.h new file mode 100644 index 000000000..8821947c1 --- /dev/null +++ b/StormLib/src/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by DllMain.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/StormLib/src/sparse/sparse.cpp b/StormLib/src/sparse/sparse.cpp new file mode 100644 index 000000000..6d1b621d0 --- /dev/null +++ b/StormLib/src/sparse/sparse.cpp @@ -0,0 +1,282 @@ +/*****************************************************************************/ +/* huffman.cpp Copyright (c) Ladislav Zezula 1998-2003 */ +/*---------------------------------------------------------------------------*/ +/* This module contains Huffmann (de)compression methods */ +/* */ +/* Authors : Ladislav Zezula (ladik.zezula.net) */ +/* ShadowFlare (BlakFlare@hotmail.com) */ +/* */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* xx.xx.xx 1.00 Lad The first version of dcmp.cpp */ +/* 03.05.03 1.00 Lad Added compression methods */ +/* 19.11.03 1.01 Dan Big endian handling */ +/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */ +/*****************************************************************************/ + +#include +#include + +#include "sparse.h" + +//----------------------------------------------------------------------------- +// Public functions + +void CompressSparse(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + unsigned char * pbOutBufferEnd = (unsigned char *)pvOutBuffer + *pcbOutBuffer; + unsigned char * pbInBufferEnd = (unsigned char *)pvInBuffer + cbInBuffer; + unsigned char * pbLastNonZero = (unsigned char *)pvInBuffer; + unsigned char * pbOutBuffer0 = (unsigned char *)pvOutBuffer; + unsigned char * pbInBuffPtr = (unsigned char *)pvInBuffer; + unsigned char * pbOutBuffer = (unsigned char *)pvOutBuffer; + unsigned char * pbInBuffer = (unsigned char *)pvInBuffer; + size_t NumberOfNonZeros; + size_t NumberOfZeros; + + // There must be at least 4 bytes of free space in the output buffer now + if((pbInBuffer + 4) >= pbInBufferEnd) + return; + + // Put the original data length (in little endian) + *pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x18); + *pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x10); + *pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x08); + *pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x00); + + // If there is at least 3 bytes in the input buffer, do this loop + while(pbInBuffer < (pbInBufferEnd - 3)) + { + // Reset the zero count and frontal pointer + pbLastNonZero = pbInBuffer; + pbInBuffPtr = pbInBuffer; + NumberOfZeros = 0; + + if(pbInBuffPtr < pbInBufferEnd) + { + do + { + // Count number of zeros + if(*pbInBuffPtr == 0) + { + NumberOfZeros++; + } + else + { + // Were there at least 3 zeros before? If yes, we need to flush the data + if(NumberOfZeros >= 3) + break; + pbLastNonZero = pbInBuffPtr + 1; + NumberOfZeros = 0; + } + } + while(++pbInBuffPtr < pbInBufferEnd); + } + + // Get number of nonzeros that we found so far and flush them + NumberOfNonZeros = pbLastNonZero - pbInBuffer; + if(NumberOfNonZeros != 0) + { + // Process blocks that are longer than 0x81 nonzero bytes + while(NumberOfNonZeros > 0x81) + { + // Verify if we still have enough space in output buffer + if((pbOutBuffer + 0x81) >= pbOutBufferEnd) + return; + + // Put marker that means "0x80 of nonzeros" + *pbOutBuffer++ = 0xFF; + memcpy(pbOutBuffer, pbInBuffer, 0x80); + + // Adjust counter of nonzeros and both pointers + NumberOfNonZeros -= 0x80; + pbOutBuffer += 0x80; + pbInBuffer += 0x80; + } + + // BUGBUG: The following code will be triggered if the NumberOfNonZeros + // was 0x81 before. It will copy just one byte. This seems like a bug to me, + // but since I want StormLib to be exact like Blizzard code is, I will keep + // it that way here + if(NumberOfNonZeros > 0x80) + { + // Verify if we still have enough space in output buffer + if((pbOutBuffer + 2) >= pbOutBufferEnd) + return; + + // Put marker that means "1 nonzero byte" + *pbOutBuffer++ = 0x80; + memcpy(pbOutBuffer, pbInBuffer, 1); + + // Adjust counter of nonzeros and both pointers + NumberOfNonZeros--; + pbOutBuffer++; + pbInBuffer++; + } + + // If there is 1 nonzero or more, put the block + if(NumberOfNonZeros >= 0x01) + { + // Verify if we still have enough space in output buffer + if((pbOutBuffer + NumberOfNonZeros + 1) >= pbOutBufferEnd) + return; + + // Put marker that means "Several nonzero bytes" + *pbOutBuffer++ = (unsigned char)(0x80 | (NumberOfNonZeros - 1)); + memcpy(pbOutBuffer, pbInBuffer, NumberOfNonZeros); + + // Adjust pointers + pbOutBuffer += NumberOfNonZeros; + pbInBuffer += NumberOfNonZeros; + } + } + + // Now flush all zero bytes + while(NumberOfZeros > 0x85) + { + // Do we have at least 2 bytes in the output buffer ? + if((pbOutBuffer + 1) >= pbOutBufferEnd) + return; + + // Put marker that means "0x82 zeros" + *pbOutBuffer++ = 0x7F; + + // Adjust zero counter and input pointer + NumberOfZeros -= 0x82; + pbInBuffer += 0x82; + } + + // If we got more than 0x82 zeros, flush 3 of them now + if(NumberOfZeros > 0x82) + { + // Do we have at least 2 bytes in the output buffer ? + if((pbOutBuffer + 1) >= pbOutBufferEnd) + return; + + // Put marker that means "0x03 zeros" + *pbOutBuffer++ = 0; + + // Adjust zero counter and input pointer + NumberOfZeros -= 0x03; + pbInBuffer += 0x03; + } + + // Is there at least three zeros ? + if(NumberOfZeros >= 3) + { + // Do we have at least 2 bytes in the output buffer ? + if((pbOutBuffer + 1) >= pbOutBufferEnd) + return; + + // Put marker that means "Several zeros" + *pbOutBuffer++ = (unsigned char)(NumberOfZeros - 3); + + // Adjust pointer + pbInBuffer += NumberOfZeros; + } + } + + // Flush last three bytes + if(pbInBuffer < pbInBufferEnd) + { + pbInBuffPtr = pbInBuffer; + + for(;;) + { + if(*pbInBuffPtr++ != 0) + { + // Get number of bytes remaining + NumberOfNonZeros = (pbInBufferEnd - pbInBuffer); + + // Not enough space in the output buffer ==> exit + if((pbOutBuffer + NumberOfNonZeros + 1) >= pbOutBufferEnd) + return; + + // Terminate with a marker that means "0x80 of nonzeros" + *pbOutBuffer++ = 0xFF; + memcpy(pbOutBuffer, pbInBuffer, NumberOfNonZeros); + + // Adjust pointer + pbOutBuffer += NumberOfNonZeros; + break; + } + else + { + // Is there are more chars in the input buffer + if(pbInBuffPtr < pbInBufferEnd) + continue; + + // If the compression will not compress it by even 1 byte, do nothing + if((pbOutBuffer + 1) >= pbOutBufferEnd) + return; + + // Terminate with a chunk that means "0x82 of zeros" + *pbOutBuffer++ = 0x7F; + break; + } + } + } + + // Out the length of the output buffer + *pcbOutBuffer = (int)(pbOutBuffer - pbOutBuffer0); +} + +int DecompressSparse(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + unsigned char * pbInBufferEnd = (unsigned char *)pvInBuffer + cbInBuffer; + unsigned char * pbOutBuffer = (unsigned char *)pvOutBuffer; + unsigned char * pbInBuffer = (unsigned char *)pvInBuffer; + unsigned int cbChunkSize; + unsigned int cbOutBuffer = 0; + unsigned int OneByte; + + // Don't decompress anything that is shorter than 5 bytes + if(cbInBuffer < 5) + return 0; + + // Get the 32-bits from the input stream + OneByte = *pbInBuffer++; + cbOutBuffer |= (OneByte << 0x18); + OneByte = *pbInBuffer++; + cbOutBuffer |= (OneByte << 0x10); + OneByte = *pbInBuffer++; + cbOutBuffer |= (OneByte << 0x08); + OneByte = *pbInBuffer++; + cbOutBuffer |= (OneByte << 0x00); + + // Verify the size of the stream against the output buffer size + if(cbOutBuffer > (unsigned int)*pcbOutBuffer) + return 0; + + // Put the output size to the buffer + *pcbOutBuffer = cbOutBuffer; + + // Process the input buffer + while(pbInBuffer < pbInBufferEnd) + { + // Get (next) byte from the stream + OneByte = *pbInBuffer++; + + // If highest bit, it means that that normal data follow + if(OneByte & 0x80) + { + cbChunkSize = (OneByte & 0x7F) + 1; + cbChunkSize = (cbChunkSize < cbOutBuffer) ? cbChunkSize : cbOutBuffer; + memcpy(pbOutBuffer, pbInBuffer, cbChunkSize); + pbInBuffer += cbChunkSize; + } + else + { + cbChunkSize = (OneByte & 0x7F) + 3; + cbChunkSize = (cbChunkSize < cbOutBuffer) ? cbChunkSize : cbOutBuffer; + memset(pbOutBuffer, 0, cbChunkSize); + } + + // Increment output buffer pointer + pbOutBuffer += cbChunkSize; + cbOutBuffer -= cbChunkSize; + } + + return 1; +} diff --git a/StormLib/src/sparse/sparse.h b/StormLib/src/sparse/sparse.h new file mode 100644 index 000000000..12f62b526 --- /dev/null +++ b/StormLib/src/sparse/sparse.h @@ -0,0 +1,17 @@ +/*****************************************************************************/ +/* sparse.h Copyright (c) Ladislav Zezula 2010 */ +/*---------------------------------------------------------------------------*/ +/* implementation of Sparse compression, used in Starcraft II */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 05.03.10 1.00 Lad The first version of sparse.h */ +/*****************************************************************************/ + +#ifndef __SPARSE_H__ +#define __SPARSE_H__ + +void CompressSparse(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); +int DecompressSparse(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); + +#endif // __SPARSE_H__ diff --git a/StormLib/src/wdk/sources-cpp.cpp b/StormLib/src/wdk/sources-cpp.cpp new file mode 100644 index 000000000..f2899759a --- /dev/null +++ b/StormLib/src/wdk/sources-cpp.cpp @@ -0,0 +1,26 @@ +// This is a source file for WDK build of StormLib +// It is copied to the root folder during the build process + +#include "src\adpcm\adpcm.cpp" +#include "src\huffman\huff.cpp" +#include "src\sparse\sparse.cpp" + +#include "src\FileStream.cpp" +#include "src\SBaseCommon.cpp" +#include "src\SBaseDumpData.cpp" +#include "src\SBaseFileTable.cpp" +#include "src\SBaseSubTypes.cpp" +#include "src\SCompression.cpp" +#include "src\SFileAddFile.cpp" +#include "src\SFileAttributes.cpp" +#include "src\SFileCompactArchive.cpp" +#include "src\SFileCreateArchive.cpp" +#include "src\SFileExtractFile.cpp" +#include "src\SFileFindFile.cpp" +#include "src\SFileGetFileInfo.cpp" +#include "src\SFileListFile.cpp" +#include "src\SFileOpenArchive.cpp" +#include "src\SFileOpenFileEx.cpp" +#include "src\SFilePatchArchives.cpp" +#include "src\SFileReadFile.cpp" +#include "src\SFileVerify.cpp" diff --git a/StormLib/src/wdk/sources-wdk-bzip2.c b/StormLib/src/wdk/sources-wdk-bzip2.c new file mode 100644 index 000000000..74cf92a1b --- /dev/null +++ b/StormLib/src/wdk/sources-wdk-bzip2.c @@ -0,0 +1,13 @@ +// This is a source file for WDK build of StormLib +// It is copied to the root folder during the build process + +#pragma warning(disable: 4242) // '=' : conversion from 'Int32' to 'UChar', possible loss of data +#pragma warning(disable: 4244) // '=' : conversion from '__int64' to 'Int32', possible loss of data + +#include "src\bzip2\blocksort.c" +#include "src\bzip2\bzlib.c" +#include "src\bzip2\compress.c" +#include "src\bzip2\crctable.c" +#include "src\bzip2\decompress.c" +#include "src\bzip2\huffman.c" +#include "src\bzip2\randtable.c" diff --git a/StormLib/src/wdk/sources-wdk-ltc.c b/StormLib/src/wdk/sources-wdk-ltc.c new file mode 100644 index 000000000..7a7f90cc9 --- /dev/null +++ b/StormLib/src/wdk/sources-wdk-ltc.c @@ -0,0 +1,4 @@ +// This is a source file for WDK build of StormLib +// It is copied to the root folder during the build process + +#include "src\libtomcrypt\src\math\ltm_desc.c" diff --git a/StormLib/src/wdk/sources-wdk-lzma.c b/StormLib/src/wdk/sources-wdk-lzma.c new file mode 100644 index 000000000..1fe46ee54 --- /dev/null +++ b/StormLib/src/wdk/sources-wdk-lzma.c @@ -0,0 +1,8 @@ +// This is a source file for WDK build of StormLib +// It is copied to the root folder during the build process + +#include "src\lzma\C\LzFind.c" +#include "src\lzma\C\LzFindMt.c" +#include "src\lzma\C\LzmaDec.c" +#include "src\lzma\C\LzmaEnc.c" +#include "src\lzma\C\Threads.c" diff --git a/StormLib/src/wdk/sources-wdk-misc.c b/StormLib/src/wdk/sources-wdk-misc.c new file mode 100644 index 000000000..d1c36f0ba --- /dev/null +++ b/StormLib/src/wdk/sources-wdk-misc.c @@ -0,0 +1,6 @@ +// This is a source file for WDK build of StormLib +// It is copied to the root folder during the build process + +#include "src\jenkins\lookup3.c" +#include "src\pklib\explode.c" +#include "src\pklib\implode.c" diff --git a/StormLib/src/wdk/sources-wdk-tomcrypt.c b/StormLib/src/wdk/sources-wdk-tomcrypt.c new file mode 100644 index 000000000..60453d6e4 --- /dev/null +++ b/StormLib/src/wdk/sources-wdk-tomcrypt.c @@ -0,0 +1,82 @@ +// This is a source file for WDK build of StormLib +// It is copied to the root folder during the build process + +#pragma warning(disable:4242) // der_decode_ia5_string.c(84) : warning C4242: '=' : conversion from 'int' to 'unsigned char', possible loss of data + +#include "src\libtomcrypt\src\hashes\hash_memory.c" +#include "src\libtomcrypt\src\hashes\md5.c" +#include "src\libtomcrypt\src\hashes\sha1.c" +#include "src\libtomcrypt\src\math\multi.c" +#include "src\libtomcrypt\src\math\rand_prime.c" +#include "src\libtomcrypt\src\misc\base64_decode.c" +#include "src\libtomcrypt\src\misc\crypt_argchk.c" +#include "src\libtomcrypt\src\misc\crypt_find_hash.c" +#include "src\libtomcrypt\src\misc\crypt_find_prng.c" +#include "src\libtomcrypt\src\misc\crypt_hash_descriptor.c" +#include "src\libtomcrypt\src\misc\crypt_hash_is_valid.c" +#include "src\libtomcrypt\src\misc\crypt_libc.c" +#include "src\libtomcrypt\src\misc\crypt_ltc_mp_descriptor.c" +#include "src\libtomcrypt\src\misc\crypt_prng_descriptor.c" +#include "src\libtomcrypt\src\misc\crypt_prng_is_valid.c" +#include "src\libtomcrypt\src\misc\crypt_register_hash.c" +#include "src\libtomcrypt\src\misc\crypt_register_prng.c" +#include "src\libtomcrypt\src\misc\zeromem.c" +#include "src\libtomcrypt\src\pk\asn1\der_decode_bit_string.c" +#include "src\libtomcrypt\src\pk\asn1\der_decode_boolean.c" +#include "src\libtomcrypt\src\pk\asn1\der_decode_choice.c" +#include "src\libtomcrypt\src\pk\asn1\der_decode_ia5_string.c" +#include "src\libtomcrypt\src\pk\asn1\der_decode_integer.c" +#include "src\libtomcrypt\src\pk\asn1\der_decode_object_identifier.c" +#include "src\libtomcrypt\src\pk\asn1\der_decode_octet_string.c" +#include "src\libtomcrypt\src\pk\asn1\der_decode_printable_string.c" +#include "src\libtomcrypt\src\pk\asn1\der_decode_sequence_ex.c" +#include "src\libtomcrypt\src\pk\asn1\der_decode_sequence_flexi.c" +#include "src\libtomcrypt\src\pk\asn1\der_decode_sequence_multi.c" +#include "src\libtomcrypt\src\pk\asn1\der_decode_short_integer.c" +#include "src\libtomcrypt\src\pk\asn1\der_decode_utctime.c" +#include "src\libtomcrypt\src\pk\asn1\der_decode_utf8_string.c" +#include "src\libtomcrypt\src\pk\asn1\der_encode_bit_string.c" +#include "src\libtomcrypt\src\pk\asn1\der_encode_boolean.c" +#include "src\libtomcrypt\src\pk\asn1\der_encode_ia5_string.c" +#include "src\libtomcrypt\src\pk\asn1\der_encode_integer.c" +#include "src\libtomcrypt\src\pk\asn1\der_encode_object_identifier.c" +#include "src\libtomcrypt\src\pk\asn1\der_encode_octet_string.c" +#include "src\libtomcrypt\src\pk\asn1\der_encode_printable_string.c" +#include "src\libtomcrypt\src\pk\asn1\der_encode_sequence_ex.c" +#include "src\libtomcrypt\src\pk\asn1\der_encode_sequence_multi.c" +#include "src\libtomcrypt\src\pk\asn1\der_encode_set.c" +#include "src\libtomcrypt\src\pk\asn1\der_encode_setof.c" +#include "src\libtomcrypt\src\pk\asn1\der_encode_short_integer.c" +#include "src\libtomcrypt\src\pk\asn1\der_encode_utctime.c" +#include "src\libtomcrypt\src\pk\asn1\der_encode_utf8_string.c" +#include "src\libtomcrypt\src\pk\asn1\der_length_bit_string.c" +#include "src\libtomcrypt\src\pk\asn1\der_length_boolean.c" +#include "src\libtomcrypt\src\pk\asn1\der_length_ia5_string.c" +#include "src\libtomcrypt\src\pk\asn1\der_length_integer.c" +#include "src\libtomcrypt\src\pk\asn1\der_length_object_identifier.c" +#include "src\libtomcrypt\src\pk\asn1\der_length_octet_string.c" +#include "src\libtomcrypt\src\pk\asn1\der_length_printable_string.c" +#include "src\libtomcrypt\src\pk\asn1\der_length_sequence.c" +#include "src\libtomcrypt\src\pk\asn1\der_length_short_integer.c" +#include "src\libtomcrypt\src\pk\asn1\der_length_utctime.c" +#include "src\libtomcrypt\src\pk\asn1\der_length_utf8_string.c" +#include "src\libtomcrypt\src\pk\asn1\der_sequence_free.c" +#include "src\libtomcrypt\src\pk\ecc\ltc_ecc_map.c" +#include "src\libtomcrypt\src\pk\ecc\ltc_ecc_mul2add.c" +#include "src\libtomcrypt\src\pk\ecc\ltc_ecc_mulmod.c" +#include "src\libtomcrypt\src\pk\ecc\ltc_ecc_points.c" +#include "src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_add_point.c" +#include "src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_dbl_point.c" +#include "src\libtomcrypt\src\pk\pkcs1\pkcs_1_mgf1.c" +#include "src\libtomcrypt\src\pk\pkcs1\pkcs_1_oaep_decode.c" +#include "src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_decode.c" +#include "src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_encode.c" +#include "src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_decode.c" +#include "src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_encode.c" +#include "src\libtomcrypt\src\pk\rsa\rsa_exptmod.c" +#include "src\libtomcrypt\src\pk\rsa\rsa_free.c" +#include "src\libtomcrypt\src\pk\rsa\rsa_import.c" +#include "src\libtomcrypt\src\pk\rsa\rsa_make_key.c" +#include "src\libtomcrypt\src\pk\rsa\rsa_sign_hash.c" +#include "src\libtomcrypt\src\pk\rsa\rsa_verify_hash.c" +#include "src\libtomcrypt\src\pk\rsa\rsa_verify_simple.c" diff --git a/StormLib/src/wdk/sources-wdk-tommath.c b/StormLib/src/wdk/sources-wdk-tommath.c new file mode 100644 index 000000000..78e86a2e2 --- /dev/null +++ b/StormLib/src/wdk/sources-wdk-tommath.c @@ -0,0 +1,124 @@ +// This is a source file for WDK build of StormLib +// It is copied to the root folder during the build process + +#pragma warning(disable:4334) // warning C4334: '<<' : result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?) + +#include "src\libtommath\bn_fast_mp_invmod.c" +#include "src\libtommath\bn_fast_mp_montgomery_reduce.c" +#include "src\libtommath\bn_fast_s_mp_mul_digs.c" +#include "src\libtommath\bn_fast_s_mp_mul_high_digs.c" +#include "src\libtommath\bn_fast_s_mp_sqr.c" +#include "src\libtommath\bn_mp_2expt.c" +#include "src\libtommath\bn_mp_abs.c" +#include "src\libtommath\bn_mp_add.c" +#include "src\libtommath\bn_mp_add_d.c" +#include "src\libtommath\bn_mp_addmod.c" +#include "src\libtommath\bn_mp_and.c" +#include "src\libtommath\bn_mp_clamp.c" +#include "src\libtommath\bn_mp_clear.c" +#include "src\libtommath\bn_mp_clear_multi.c" +#include "src\libtommath\bn_mp_cmp.c" +#include "src\libtommath\bn_mp_cmp_d.c" +#include "src\libtommath\bn_mp_cmp_mag.c" +#include "src\libtommath\bn_mp_cnt_lsb.c" +#include "src\libtommath\bn_mp_copy.c" +#include "src\libtommath\bn_mp_count_bits.c" +#include "src\libtommath\bn_mp_div.c" +#include "src\libtommath\bn_mp_div_2.c" +#include "src\libtommath\bn_mp_div_2d.c" +#include "src\libtommath\bn_mp_div_3.c" +#include "src\libtommath\bn_mp_div_d.c" +#include "src\libtommath\bn_mp_dr_is_modulus.c" +#include "src\libtommath\bn_mp_dr_reduce.c" +#include "src\libtommath\bn_mp_dr_setup.c" +#include "src\libtommath\bn_mp_exch.c" +#include "src\libtommath\bn_mp_expt_d.c" +#include "src\libtommath\bn_mp_exptmod.c" +#include "src\libtommath\bn_mp_exptmod_fast.c" +#include "src\libtommath\bn_mp_exteuclid.c" +#include "src\libtommath\bn_mp_fread.c" +#include "src\libtommath\bn_mp_fwrite.c" +#include "src\libtommath\bn_mp_gcd.c" +#include "src\libtommath\bn_mp_get_int.c" +#include "src\libtommath\bn_mp_grow.c" +#include "src\libtommath\bn_mp_init.c" +#include "src\libtommath\bn_mp_init_copy.c" +#include "src\libtommath\bn_mp_init_multi.c" +#include "src\libtommath\bn_mp_init_set.c" +#include "src\libtommath\bn_mp_init_set_int.c" +#include "src\libtommath\bn_mp_init_size.c" +#include "src\libtommath\bn_mp_invmod.c" +#include "src\libtommath\bn_mp_invmod_slow.c" +#include "src\libtommath\bn_mp_is_square.c" +#include "src\libtommath\bn_mp_jacobi.c" +#include "src\libtommath\bn_mp_karatsuba_mul.c" +#include "src\libtommath\bn_mp_karatsuba_sqr.c" +#include "src\libtommath\bn_mp_lcm.c" +#include "src\libtommath\bn_mp_lshd.c" +#include "src\libtommath\bn_mp_mod.c" +#include "src\libtommath\bn_mp_mod_2d.c" +#include "src\libtommath\bn_mp_mod_d.c" +#include "src\libtommath\bn_mp_montgomery_calc_normalization.c" +#include "src\libtommath\bn_mp_montgomery_reduce.c" +#include "src\libtommath\bn_mp_montgomery_setup.c" +#include "src\libtommath\bn_mp_mul.c" +#include "src\libtommath\bn_mp_mul_2.c" +#include "src\libtommath\bn_mp_mul_2d.c" +#include "src\libtommath\bn_mp_mul_d.c" +#include "src\libtommath\bn_mp_mulmod.c" +#include "src\libtommath\bn_mp_n_root.c" +#include "src\libtommath\bn_mp_neg.c" +#include "src\libtommath\bn_mp_or.c" +#include "src\libtommath\bn_mp_prime_fermat.c" +#include "src\libtommath\bn_mp_prime_is_divisible.c" +#include "src\libtommath\bn_mp_prime_is_prime.c" +#include "src\libtommath\bn_mp_prime_miller_rabin.c" +#include "src\libtommath\bn_mp_prime_next_prime.c" +#include "src\libtommath\bn_mp_prime_rabin_miller_trials.c" +#include "src\libtommath\bn_mp_prime_random_ex.c" +#include "src\libtommath\bn_mp_radix_size.c" +#include "src\libtommath\bn_mp_radix_smap.c" +#include "src\libtommath\bn_mp_rand.c" +#include "src\libtommath\bn_mp_read_radix.c" +#include "src\libtommath\bn_mp_read_signed_bin.c" +#include "src\libtommath\bn_mp_read_unsigned_bin.c" +#include "src\libtommath\bn_mp_reduce.c" +#include "src\libtommath\bn_mp_reduce_2k.c" +#include "src\libtommath\bn_mp_reduce_2k_l.c" +#include "src\libtommath\bn_mp_reduce_2k_setup.c" +#include "src\libtommath\bn_mp_reduce_2k_setup_l.c" +#include "src\libtommath\bn_mp_reduce_is_2k.c" +#include "src\libtommath\bn_mp_reduce_is_2k_l.c" +#include "src\libtommath\bn_mp_reduce_setup.c" +#include "src\libtommath\bn_mp_rshd.c" +#include "src\libtommath\bn_mp_set.c" +#include "src\libtommath\bn_mp_set_int.c" +#include "src\libtommath\bn_mp_shrink.c" +#include "src\libtommath\bn_mp_signed_bin_size.c" +#include "src\libtommath\bn_mp_sqr.c" +#include "src\libtommath\bn_mp_sqrmod.c" +#include "src\libtommath\bn_mp_sqrt.c" +#include "src\libtommath\bn_mp_sub.c" +#include "src\libtommath\bn_mp_sub_d.c" +#include "src\libtommath\bn_mp_submod.c" +#include "src\libtommath\bn_mp_to_signed_bin.c" +#include "src\libtommath\bn_mp_to_signed_bin_n.c" +#include "src\libtommath\bn_mp_to_unsigned_bin.c" +#include "src\libtommath\bn_mp_to_unsigned_bin_n.c" +#include "src\libtommath\bn_mp_toom_mul.c" +#include "src\libtommath\bn_mp_toom_sqr.c" +#include "src\libtommath\bn_mp_toradix.c" +#include "src\libtommath\bn_mp_toradix_n.c" +#include "src\libtommath\bn_mp_unsigned_bin_size.c" +#include "src\libtommath\bn_mp_xor.c" +#include "src\libtommath\bn_mp_zero.c" +#include "src\libtommath\bn_prime_tab.c" +#include "src\libtommath\bn_reverse.c" +#include "src\libtommath\bn_s_mp_add.c" +#include "src\libtommath\bn_s_mp_exptmod.c" +#include "src\libtommath\bn_s_mp_mul_digs.c" +#include "src\libtommath\bn_s_mp_mul_high_digs.c" +#include "src\libtommath\bn_s_mp_sqr.c" +#include "src\libtommath\bn_s_mp_sub.c" +#include "src\libtommath\bncore.c" + diff --git a/StormLib/src/wdk/sources-wdk-zlib.c b/StormLib/src/wdk/sources-wdk-zlib.c new file mode 100644 index 000000000..2455a9a67 --- /dev/null +++ b/StormLib/src/wdk/sources-wdk-zlib.c @@ -0,0 +1,21 @@ +// This is a source file for WDK build of StormLib +// It is copied to the root folder during the build process + +#pragma warning(disable:4242) // deflate.c(1693) : warning C4242: '=' : conversion from 'unsigned int' to 'Bytef', possible loss of data + +#define NO_DUMMY_DECL +#define NO_GZIP +#include "src\zlib\adler32.c" +#undef DO1 +#undef DO8 +#undef MIN +#include "src\zlib\compress.c" +#include "src\zlib\crc32.c" +#include "src\zlib\deflate.c" +#include "src\zlib\trees.c" +#include "src\zlib\zutil.c" + +#undef COPY // Conflicting definition +#include "src\zlib\inflate.c" +#include "src\zlib\inffast.c" +#include "src\zlib\inftrees.c" diff --git a/StormLib/src/zlib/adler32.c b/StormLib/src/zlib/adler32.c new file mode 100644 index 000000000..65ad6a5ad --- /dev/null +++ b/StormLib/src/zlib/adler32.c @@ -0,0 +1,169 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2007 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#define local static + +local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2); + +#define BASE 65521UL /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware */ +#ifdef NO_DIVIDE +# define MOD(a) \ + do { \ + if (a >= (BASE << 16)) a -= (BASE << 16); \ + if (a >= (BASE << 15)) a -= (BASE << 15); \ + if (a >= (BASE << 14)) a -= (BASE << 14); \ + if (a >= (BASE << 13)) a -= (BASE << 13); \ + if (a >= (BASE << 12)) a -= (BASE << 12); \ + if (a >= (BASE << 11)) a -= (BASE << 11); \ + if (a >= (BASE << 10)) a -= (BASE << 10); \ + if (a >= (BASE << 9)) a -= (BASE << 9); \ + if (a >= (BASE << 8)) a -= (BASE << 8); \ + if (a >= (BASE << 7)) a -= (BASE << 7); \ + if (a >= (BASE << 6)) a -= (BASE << 6); \ + if (a >= (BASE << 5)) a -= (BASE << 5); \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD4(a) \ + do { \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD4(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD4(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +local uLong adler32_combine_(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* the derivation of this formula is left as an exercise for the reader */ + rem = (unsigned)(len2 % BASE); + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} + +uLong ZEXPORT adler32_combine64(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} diff --git a/StormLib/src/zlib/compress.c b/StormLib/src/zlib/compress.c new file mode 100644 index 000000000..ea4dfbe9d --- /dev/null +++ b/StormLib/src/zlib/compress.c @@ -0,0 +1,80 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; + int level; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; +#ifdef MAXSEG_64K + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound (sourceLen) + uLong sourceLen; +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; +} diff --git a/StormLib/src/zlib/compress_zlib.c b/StormLib/src/zlib/compress_zlib.c new file mode 100644 index 000000000..46e506158 --- /dev/null +++ b/StormLib/src/zlib/compress_zlib.c @@ -0,0 +1,5 @@ +// Some compilers (e.g. Visual Studio 2012) don't like the name conflict between +// zlib\compress.c and bzip2\compress.c. This file is plain wrapper for compress.c +// in order to create obj file with a different name. + +#include "compress.c" diff --git a/StormLib/src/zlib/crc32.c b/StormLib/src/zlib/crc32.c new file mode 100644 index 000000000..91be372d2 --- /dev/null +++ b/StormLib/src/zlib/crc32.c @@ -0,0 +1,442 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2006, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Find a four-byte integer type for crc32_little() and crc32_big(). */ +#ifndef NOBYFOUR +# ifdef STDC /* need ANSI C limits.h to determine sizes */ +# include +# define BYFOUR +# if (UINT_MAX == 0xffffffffUL) + typedef unsigned int u4; +# else +# if (ULONG_MAX == 0xffffffffUL) + typedef unsigned long u4; +# else +# if (USHRT_MAX == 0xffffffffUL) + typedef unsigned short u4; +# else +# undef BYFOUR /* can't find a four-byte integer type! */ +# endif +# endif +# endif +# endif /* STDC */ +#endif /* !NOBYFOUR */ + +/* Definitions for doing the crc four data bytes at a time. */ +#ifdef BYFOUR +# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \ + (((w)&0xff00)<<8)+(((w)&0xff)<<24)) + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +# define TBLS 8 +#else +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); +local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2); + + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local unsigned long FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const unsigned long FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + unsigned long c; + int n, k; + unsigned long poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0UL; + for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) + poly |= 1UL << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (unsigned long)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = REV(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = REV(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const unsigned long FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const unsigned long FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const unsigned long FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const unsigned long FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + uInt len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + u4 endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = (u4)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = REV((u4)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + buf4--; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(REV(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + unsigned long *mat; + unsigned long vec; +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +local uLong crc32_combine_(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case (also disallow negative lengths) */ + if (len2 <= 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} + +uLong ZEXPORT crc32_combine64(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} diff --git a/StormLib/src/zlib/crc32.h b/StormLib/src/zlib/crc32.h new file mode 100644 index 000000000..8053b6117 --- /dev/null +++ b/StormLib/src/zlib/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const unsigned long FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/StormLib/src/zlib/deflate.c b/StormLib/src/zlib/deflate.c new file mode 100644 index 000000000..5c4022f3d --- /dev/null +++ b/StormLib/src/zlib/deflate.c @@ -0,0 +1,1834 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://www.ietf.org/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local block_state deflate_rle OF((deflate_state *s, int flush)); +local block_state deflate_huff OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->high_water = 0; /* nothing written to s->window yet */ + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->wrap == 2 || + (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) + return Z_STREAM_ERROR; + + s = strm->state; + if (s->wrap) + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > s->w_size) { + length = s->w_size; + dictionary += dictLength - length; /* use the tail of the dictionary */ + } + zmemcpy(s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + z_streamp strm; + gz_headerp head; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + strm->state->bi_valid = bits; + strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if ((strategy != s->strategy || func != configuration_table[level].func) && + strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_BLOCK); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) + z_streamp strm; + int good_length; + int max_lazy; + int nice_length; + int max_chain; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds for + * every combination of windowBits and memLevel. But even the conservative + * upper bound of about 14% expansion does not seem onerous for output buffer + * allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong complen, wraplen; + Bytef *str; + + /* conservative upper bound for compressed data */ + complen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; + + /* if can't get parameters, return conservative bound plus zlib wrapper */ + if (strm == Z_NULL || strm->state == Z_NULL) + return complen + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; + default: /* for compiler happiness */ + wraplen = 6; + } + + /* if not default parameters, return conservative bound */ + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return complen + wraplen; + + /* default settings: return tight bound for that case */ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_BLOCK || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == Z_NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != Z_NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } +#ifdef GZIP + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } +#endif + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + (s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush)); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0L; + } + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy(dest, source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy(ds, ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, strm->next_in, len); + } +#endif + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ + +#else /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for FASTEST only + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#endif /* FASTEST */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, last) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (last)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif /* FASTEST */ + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest encodable run. + */ + if (s->lookahead < MAX_MATCH) { + fill_window(s); + if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (int)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, s->match_length); + + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +local block_state deflate_huff(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + fill_window(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s->match_length = 0; + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} diff --git a/StormLib/src/zlib/deflate.h b/StormLib/src/zlib/deflate.h new file mode 100644 index 000000000..cbf0d1ea5 --- /dev/null +++ b/StormLib/src/zlib/deflate.h @@ -0,0 +1,342 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2010 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); +int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/StormLib/src/zlib/gzguts.h b/StormLib/src/zlib/gzguts.h new file mode 100644 index 000000000..990a4d251 --- /dev/null +++ b/StormLib/src/zlib/gzguts.h @@ -0,0 +1,218 @@ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +# endif +#endif + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include +#include "zlib.h" +#ifdef STDC +# include +# include +# include +#endif + +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif +#include + +#ifdef _WIN32 +# include +#endif + +#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) +# include +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) +# define WIDECHAR +#endif + +#ifdef WINAPI_FAMILY +# define open _open +# define read _read +# define write _write +# define close _close +#endif + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS +/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +# ifdef VMS +# define NO_vsnprintf +# endif +# ifdef __OS400__ +# define NO_vsnprintf +# endif +# ifdef __MVS__ +# define NO_vsnprintf +# endif +#endif + +/* unlike snprintf (which is required in C99), _snprintf does not guarantee + null termination of the result -- however this is only used in gzlib.c where + the result is assured to fit in the space provided */ +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +#ifndef local +# define local static +#endif +/* since "static" is used to mean two completely different things in C, we + define "local" for the non-static meaning of "static", for readability + (compile with -Dlocal if your debugger can't find static symbols) */ + +/* gz* functions always use library allocation functions */ +#ifndef STDC + extern voidp malloc OF((uInt size)); + extern void free OF((voidpf ptr)); +#endif + +/* get errno and strerror definition */ +#if defined UNDER_CE +# include +# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#else +# ifndef NO_STRERROR +# include +# define zstrerror() strerror(errno) +# else +# define zstrerror() "stdio error (consult errno)" +# endif +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading (this and + twice this must be able to fit in an unsigned type) */ +#define GZBUFSIZE 8192 + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer (double-sized when writing) */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state FAR *gz_statep; + +/* shared functions */ +void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); +#if defined UNDER_CE +char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); +#endif + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +#ifdef INT_MAX +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) +#else +unsigned ZLIB_INTERNAL gz_intmax OF((void)); +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) +#endif diff --git a/StormLib/src/zlib/inffast.c b/StormLib/src/zlib/inffast.c new file mode 100644 index 000000000..2f1d60b43 --- /dev/null +++ b/StormLib/src/zlib/inffast.c @@ -0,0 +1,340 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2008, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - M68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ +#else +# define OFF 1 +# define PUP(a) *++(a) +#endif + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void ZLIB_INTERNAL inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + unsigned char FAR *in; /* local strm->next_in */ + unsigned char FAR *last; /* while in < last, enough input available */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = lcode[hold & lmask]; + dolen: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op == 0) { /* literal */ + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + PUP(out) = (unsigned char)(here.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = dcode[hold & dmask]; + dodist: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + PUP(out) = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + PUP(out) = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + PUP(out) = PUP(from); + } while (--len); + continue; + } +#endif + } + from = window - OFF; + if (wnext == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode[here.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode[here.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/StormLib/src/zlib/inffast.h b/StormLib/src/zlib/inffast.h new file mode 100644 index 000000000..e5c1aa4ca --- /dev/null +++ b/StormLib/src/zlib/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/StormLib/src/zlib/inffixed.h b/StormLib/src/zlib/inffixed.h new file mode 100644 index 000000000..75ed4b597 --- /dev/null +++ b/StormLib/src/zlib/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. It + is part of the implementation of the compression library and + is subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/StormLib/src/zlib/inflate.c b/StormLib/src/zlib/inflate.c new file mode 100644 index 000000000..a8431abea --- /dev/null +++ b/StormLib/src/zlib/inflate.c @@ -0,0 +1,1480 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common wnext == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, unsigned out)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, + unsigned len)); + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + strm->adler = 1; /* to support ill-conceived Java test suite */ + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflateReset2(strm, windowBits) +z_streamp strm; +int windowBits; +{ + int wrap; + struct inflate_state FAR *state; + + /* get the state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + int ret; + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->window = Z_NULL; + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { + ZFREE(strm, state); + strm->state = Z_NULL; + } + return ret; +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, + state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, out) +z_streamp strm; +unsigned out; +{ + struct inflate_state FAR *state; + unsigned copy, dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + copy = out - strm->avail_out; + if (copy >= state->wsize) { + zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + state->wnext = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->wnext; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, strm->next_out - copy, copy); + state->wnext = copy; + state->whave = state->wsize; + } + else { + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Reverse the bytes in a 32-bit value */ +#define REVERSE(q) \ + ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + else if (len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = REVERSE(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + case COPY_: + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + NEEDBITS(here.bits); + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + case LEN_: + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(here.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + case DIST: + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->wnext - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( +#ifdef GUNZIP + state->flags ? hold : +#endif + REVERSE(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) + if (updatewindow(strm, out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long id; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary id */ + if (state->mode == DICT) { + id = adler32(0L, Z_NULL, 0); + id = adler32(id, dictionary, dictLength); + if (id != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window */ + if (updatewindow(strm, strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + if (dictLength > state->wsize) { + zmemcpy(state->window, dictionary + dictLength - state->wsize, + state->wsize); + state->whave = state->wsize; + } + else { + zmemcpy(state->window + state->wsize - dictLength, dictionary, + dictLength); + state->whave = dictLength; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy(dest, source, sizeof(z_stream)); + zmemcpy(copy, state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} + +int ZEXPORT inflateUndermine(strm, subvert) +z_streamp strm; +int subvert; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->sane = !subvert; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + return Z_OK; +#else + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +long ZEXPORT inflateMark(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + state = (struct inflate_state FAR *)strm->state; + return ((long)(state->back) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} diff --git a/StormLib/src/zlib/inflate.h b/StormLib/src/zlib/inflate.h new file mode 100644 index 000000000..eaef3dc08 --- /dev/null +++ b/StormLib/src/zlib/inflate.h @@ -0,0 +1,130 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef __INFLATE_H_ +#define __INFLATE_H_ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD = 16180, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* State maintained between inflate() calls -- approximately 7K bytes, not + including the allocated sliding window, which is up to 32K bytes. */ +struct inflate_state { + z_streamp strm; /* pointer back to this zlib stream */ + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip, + bit 2 true to validate check value */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ +}; + +#endif __INFLATE_H_ diff --git a/StormLib/src/zlib/inftrees.c b/StormLib/src/zlib/inftrees.c new file mode 100644 index 000000000..11e9c52ac --- /dev/null +++ b/StormLib/src/zlib/inftrees.c @@ -0,0 +1,330 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.5 Copyright 1995-2010 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + here.op = (unsigned char)0; + here.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + here.op = (unsigned char)(extra[work[sym]]); + here.val = base[work[sym]]; + } + else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* + Fill in rest of table for incomplete codes. This loop is similar to the + loop above in incrementing huff for table indices. It is assumed that + len is equal to curr + drop, so there is no loop needed to increment + through high index bits. When the current sub-table is filled, the loop + drops back to the root table to fill in any remaining entries there. + */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; + while (huff != 0) { + /* when done with sub-table, drop back to root table */ + if (drop != 0 && (huff & mask) != low) { + drop = 0; + len = root; + next = *table; + here.bits = (unsigned char)len; + } + + /* put invalid code marker in table */ + next[huff >> drop] = here; + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/StormLib/src/zlib/inftrees.h b/StormLib/src/zlib/inftrees.h new file mode 100644 index 000000000..14429f37f --- /dev/null +++ b/StormLib/src/zlib/inftrees.h @@ -0,0 +1,67 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef __INFTREES_H_ +#define __INFTREES_H_ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 30 6 15" for distance codes returns 592. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); + +#endif // __INFTREES_H_ diff --git a/StormLib/src/zlib/trees.c b/StormLib/src/zlib/trees.c new file mode 100644 index 000000000..56e9bb1c1 --- /dev/null +++ b/StormLib/src/zlib/trees.c @@ -0,0 +1,1244 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2010 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local int detect_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (ush)value << s->bi_valid; + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= (ush)value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (ush)val << s->bi_valid;\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void ZLIB_INTERNAL _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void ZLIB_INTERNAL _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+last, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+last, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ZLIB_INTERNAL _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(s) + deflate_state *s; +{ + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/StormLib/src/zlib/trees.h b/StormLib/src/zlib/trees.h new file mode 100644 index 000000000..d35639d82 --- /dev/null +++ b/StormLib/src/zlib/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/StormLib/src/zlib/zconf.h b/StormLib/src/zlib/zconf.h new file mode 100644 index 000000000..02ce56c43 --- /dev/null +++ b/StormLib/src/zlib/zconf.h @@ -0,0 +1,428 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# define uncompress z_uncompress +# define zError z_zError +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# define gzFile z_gzFile +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef STDC +# include /* for off_t */ +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define z_off64_t off64_t +#else +# define z_off64_t z_off_t +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/StormLib/src/zlib/zlib.h b/StormLib/src/zlib/zlib.h new file mode 100644 index 000000000..bfbba83e8 --- /dev/null +++ b/StormLib/src/zlib/zlib.h @@ -0,0 +1,1613 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.5, April 19th, 2010 + + Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.5" +#define ZLIB_VERNUM 0x1250 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 5 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all the uncompressed data. (The size + of the uncompressed data may have been saved by the compressor for this + purpose.) The next operation on this stream must be inflateEnd to deallocate + the decompression state. The use of Z_FINISH is never required, but can be + used to inform inflate that a faster approach may be used for the single + inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK or Z_TREES is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any call + of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. The + stream will keep the same compression level and any other attributes that + may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression level is changed, the input available so far is + compressed with the old level (and may be flushed); the new level will take + effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to be + compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if + strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been + found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the + success case, the application may save the current current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the normal + behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef voidp gzFile; /* opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) Also "a" + can be used instead of "w" to request that the gzip stream that will be + written be appended to the file. "+" will result in an error, since reading + and writing to the same gzip file is not supported. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. If + the input file was not in gzip format, gzread copies the given number of + bytes into the buffer. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream, or failing that, reading the rest + of the input file directly without decompression. The entire input file + will be read if gzread is called until it returns less than the requested + len. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. +*/ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will return an error (0) with + nothing written. In this case, there may also be a buffer overflow with + unpredictable consequences, which is possible only if zlib was compiled with + the insecure functions sprintf() or vsprintf() because the secure snprintf() + or vsnprintf() functions were not available. This can be determined using + zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); + + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. This state can change from + false to true while reading the input file if the end of a gzip stream is + reached, but is followed by data that is not another gzip stream. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the for the crc. Pre- and post-conditioning (one's + complement) is performed within this function so it shouldn't be done by the + application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# ifdef _LARGEFILE64_SOURCE + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +/* hack for buggy compilers */ +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; +#endif + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/StormLib/src/zlib/zutil.c b/StormLib/src/zlib/zutil.c new file mode 100644 index 000000000..898ed345b --- /dev/null +++ b/StormLib/src/zlib/zutil.c @@ -0,0 +1,318 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005, 2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch ((int)(sizeof(uInt))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(uLong))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(voidpf))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#ifdef STDC +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int ZLIB_INTERNAL z_verbose = verbose; + +void ZLIB_INTERNAL z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void ZLIB_INTERNAL zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int ZLIB_INTERNAL zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void ZLIB_INTERNAL zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void ZLIB_INTERNAL zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/StormLib/src/zlib/zutil.h b/StormLib/src/zlib/zutil.h new file mode 100644 index 000000000..258fa8879 --- /dev/null +++ b/StormLib/src/zlib/zutil.h @@ -0,0 +1,274 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include "zlib.h" + +#ifdef STDC +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +# include +# endif +# include +# include +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# ifdef M_I86 +# include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + +#if defined(__BORLANDC__) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS + /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 + /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +#endif +#ifdef VMS +# define NO_vsnprintf +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int ZLIB_INTERNAL z_verbose; + extern void ZLIB_INTERNAL z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); +void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H */ diff --git a/StormLib/storm_dll/Storm_dll.sln b/StormLib/storm_dll/Storm_dll.sln new file mode 100644 index 000000000..286e6135f --- /dev/null +++ b/StormLib/storm_dll/Storm_dll.sln @@ -0,0 +1,35 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "storm_dll", "storm_dll.vcproj", "{BD600973-C6FA-4CE3-8821-67F6418B7F9C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "storm_test", "storm_test_vs08.vcproj", "{5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BD600973-C6FA-4CE3-8821-67F6418B7F9C}.Debug|Win32.ActiveCfg = Debug|Win32 + {BD600973-C6FA-4CE3-8821-67F6418B7F9C}.Debug|Win32.Build.0 = Debug|Win32 + {BD600973-C6FA-4CE3-8821-67F6418B7F9C}.Debug|x64.ActiveCfg = Debug|x64 + {BD600973-C6FA-4CE3-8821-67F6418B7F9C}.Debug|x64.Build.0 = Debug|x64 + {BD600973-C6FA-4CE3-8821-67F6418B7F9C}.Release|Win32.ActiveCfg = Release|Win32 + {BD600973-C6FA-4CE3-8821-67F6418B7F9C}.Release|Win32.Build.0 = Release|Win32 + {BD600973-C6FA-4CE3-8821-67F6418B7F9C}.Release|x64.ActiveCfg = Release|x64 + {BD600973-C6FA-4CE3-8821-67F6418B7F9C}.Release|x64.Build.0 = Release|x64 + {5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}.Debug|Win32.ActiveCfg = Debug|Win32 + {5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}.Debug|Win32.Build.0 = Debug|Win32 + {5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}.Debug|x64.ActiveCfg = Debug|x64 + {5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}.Debug|x64.Build.0 = Debug|x64 + {5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}.Release|Win32.ActiveCfg = Release|Win32 + {5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}.Release|Win32.Build.0 = Release|Win32 + {5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}.Release|x64.ActiveCfg = Release|x64 + {5B0E680A-EC4E-402E-AE0D-18ADD2DC6EBE}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/StormLib/storm_dll/Storm_dll.vcproj b/StormLib/storm_dll/Storm_dll.vcproj new file mode 100644 index 000000000..6b123ff16 --- /dev/null +++ b/StormLib/storm_dll/Storm_dll.vcproj @@ -0,0 +1,363 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/StormLib/storm_dll/storm_dll.cpp b/StormLib/storm_dll/storm_dll.cpp new file mode 100644 index 000000000..2941f2a37 --- /dev/null +++ b/StormLib/storm_dll/storm_dll.cpp @@ -0,0 +1,117 @@ +/*****************************************************************************/ +/* Storm.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* This is just a dummy module for building import library for Storm.dll */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 11.04.03 1.00 Lad The first version of Storm.cpp */ +/*****************************************************************************/ + +#include + +#define BUILDING_STORM_CPP +#define STORM_ALTERNATE_NAMES +#include "storm_dll.h" + +BOOL WINAPI SFILE(OpenArchive)(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, HANDLE *hMPQ) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(CloseArchive)(HANDLE hMPQ) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(GetArchiveName)(HANDLE hMPQ, LPCSTR lpBuffer, DWORD dwBufferLength) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(OpenFile)(LPCSTR lpFileName, HANDLE *hFile) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(OpenFileEx)(HANDLE hMPQ, LPCSTR lpFileName, DWORD dwSearchScope, HANDLE *hFile) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(CloseFile)(HANDLE hFile) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +DWORD WINAPI SFILE(GetFileSize)(HANDLE hFile, LPDWORD lpFileSizeHigh) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(GetFileArchive)(HANDLE hFile, HANDLE *hMPQ) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(GetFileName)(HANDLE hFile, LPCSTR lpBuffer, DWORD dwBufferLength) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +DWORD WINAPI SFILE(SetFilePointer)(HANDLE hFile, long lDistanceToMove, PLONG lplDistanceToMoveHigh, DWORD dwMoveMethod) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(ReadFile)(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +LCID WINAPI SFILE(SetLocale)(LCID nNewLocale) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(GetBasePath)(LPCSTR lpBuffer, DWORD dwBufferLength) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(SetBasePath)(LPCSTR lpNewBasePath) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SFILE(Destroy)() +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SCOMP(Compress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int uCmp, int uCmpType, int nCmpLevel) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI SCOMP(Decompress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} diff --git a/StormLib/storm_dll/storm_dll.def b/StormLib/storm_dll/storm_dll.def new file mode 100644 index 000000000..8de88f5db --- /dev/null +++ b/StormLib/storm_dll/storm_dll.def @@ -0,0 +1,25 @@ +; Storm definition file with alternate Storm.dll names +LIBRARY "Storm" + +EXPORTS + StormCloseArchive @252 ; 0x0FC + StormCloseFile @253 ; 0x0FD + StormDestroy @262 ; 0x106 + StormGetFileArchive @264 ; 0x108 + StormGetFileSize @265 ; 0x109 + StormOpenArchive @266 ; 0x10A + StormOpenFile @267 ; 0x10B + StormOpenFileEx @268 ; 0x10C + StormReadFile @269 ; 0x10D + StormSetBasePath @270 ; 0x10E + StormSetFilePointer @271 ; 0x10F + StormSetLocale @272 ; 0x110 + StormGetBasePath @273 ; 0x111 + StormGetArchiveName @275 ; 0x113 + StormGetFileName @276 ; 0x114 + +; StormSetLastError @465 ; 0x + + StormCompress @551 ; 0x227 + StormDecompress @552 ; 0x228 + \ No newline at end of file diff --git a/StormLib/storm_dll/storm_dll.h b/StormLib/storm_dll/storm_dll.h new file mode 100644 index 000000000..75681b8c3 --- /dev/null +++ b/StormLib/storm_dll/storm_dll.h @@ -0,0 +1,65 @@ +/*****************************************************************************/ +/* Storm.h Copyright Justin Olbrantz(Quantam) 2000 */ +/*---------------------------------------------------------------------------*/ +/* Storm Interface Library v1.0 for Windows */ +/* */ +/* Author : Justin Olbrantz(Quantam) */ +/* E-mail : omega@dragonfire.net */ +/* WWW : www.campaigncreations.com/starcraft/mpq2k/inside_mopaq/ */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* xx.xx.00 1.00 Qua The first version of Storm.h */ +/* 11.04.03 1.00 Lad Added some functions */ +/*****************************************************************************/ + +#ifndef __STORM_H__ +#define __STORM_H__ + +// We need the Windows data types for the Storm prototypes +#include + +// Sometimes is necessary to change the function names so they +// will not conflict with other MPQ tools. +#ifdef STORM_ALTERNATE_NAMES + #define SFILE(Name) Storm##Name + #define SCOMP(Name) Storm##Name +#else + #define SFILE(Name) SFile##Name + #define SCOMP(Name) SComp##Name +#endif + +// Make sure the functions are exported as C functions +#ifdef __cplusplus +extern "C" { +#endif + +// Storm file function prototypes +BOOL WINAPI SFILE(OpenArchive)(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, HANDLE *hMPQ); +BOOL WINAPI SFILE(CloseArchive)(HANDLE hMPQ); +BOOL WINAPI SFILE(GetArchiveName)(HANDLE hMPQ, LPCSTR lpBuffer, DWORD dwBufferLength); +BOOL WINAPI SFILE(OpenFile)(LPCSTR lpFileName, HANDLE *hFile); +BOOL WINAPI SFILE(OpenFileEx)(HANDLE hMPQ, LPCSTR lpFileName, DWORD dwSearchScope, HANDLE *hFile); +BOOL WINAPI SFILE(CloseFile)(HANDLE hFile); +DWORD WINAPI SFILE(GetFileSize)(HANDLE hFile, LPDWORD lpFileSizeHigh); +BOOL WINAPI SFILE(GetFileArchive)(HANDLE hFile, HANDLE *hMPQ); +BOOL WINAPI SFILE(GetFileName)(HANDLE hFile, LPCSTR lpBuffer, DWORD dwBufferLength); +DWORD WINAPI SFILE(SetFilePointer)(HANDLE hFile, long lDistanceToMove, PLONG lplDistanceToMoveHigh, DWORD dwMoveMethod); +BOOL WINAPI SFILE(ReadFile)(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped); +LCID WINAPI SFILE(SetLocale)(LCID nNewLocale); +BOOL WINAPI SFILE(GetBasePath)(LPCSTR lpBuffer, DWORD dwBufferLength); +BOOL WINAPI SFILE(SetBasePath)(LPCSTR lpNewBasePath); + +// Storm (de)compression functions +BOOL WINAPI SCOMP(Compress) (char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int uCmp, int uCmpType, int nCmpLevel); +BOOL WINAPI SCOMP(Decompress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength); + +#ifdef __cplusplus +} +#endif + +#if defined(_MSC_VER) && !defined(BUILDING_STORM_CPP) +#pragma comment(lib, "Storm.lib") // Force linking Storm.lib and thus Storm.dll +#endif + +#endif // __STORM_H__ diff --git a/StormLib/storm_dll/storm_test.cpp b/StormLib/storm_dll/storm_test.cpp new file mode 100644 index 000000000..92ff061f9 --- /dev/null +++ b/StormLib/storm_dll/storm_test.cpp @@ -0,0 +1,46 @@ +/*****************************************************************************/ +/* Storm_test.cpp Copyright (c) Ladislav Zezula 2014 */ +/*---------------------------------------------------------------------------*/ +/* Test module for storm.dll (original Blizzard MPQ dynalic library */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 24.08.14 1.00 Lad The first version of Storm_test.cpp */ +/*****************************************************************************/ + +#define _CRT_NON_CONFORMING_SWPRINTFS +#define _CRT_SECURE_NO_DEPRECATE +#include + +#ifdef _MSC_VER +#include +#endif + +#define STORM_ALTERNATE_NAMES // Use Storm* prefix for functions +#include "storm_dll.h" // Header file for Storm.dll + +//----------------------------------------------------------------------------- +// Main + +int main() +{ + LPCSTR szArchiveName = "e:\\war3.mpq"; + HANDLE hMpq = NULL; + HANDLE hFile = NULL; + BYTE Buffer[0x100]; + DWORD dwBytesRead = 0; + + if(StormOpenArchive(szArchiveName, 0, 0, &hMpq)) + { + if(StormOpenFileEx(hMpq, "(1)TheDeathSheep.w3m", 0, &hFile)) + { + dwBytesRead = StormGetFileSize(hFile, NULL); + StormReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL); + StormCloseFile(hFile); + } + + StormCloseArchive(hMpq); + } + + return 0; +} diff --git a/StormLib/storm_dll/storm_test_vs08.vcproj b/StormLib/storm_dll/storm_test_vs08.vcproj new file mode 100644 index 000000000..456b11e37 --- /dev/null +++ b/StormLib/storm_dll/storm_test_vs08.vcproj @@ -0,0 +1,359 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/StormLib/test/Readme.txt b/StormLib/test/Readme.txt new file mode 100644 index 000000000..19bdf53c9 --- /dev/null +++ b/StormLib/test/Readme.txt @@ -0,0 +1,90 @@ +Testing MPQ set for StormLib test suite +======================================= + +The path to the directory could be anywhere. Path to this directory +is set on a command line. If there is no command line argument passed, +one of the hard-coded paths is used. + +The testing directory must contain the following files: + +Path File Size +------------------------------------------------- ----------- +patches\wow-update-13164.MPQ 480 028 668 // Original patch files from WoW +patches\wow-update-13205.MPQ 8 814 +patches\wow-update-13287.MPQ 333 363 917 +patches\wow-update-13329.MPQ 159 285 434 +patches\wow-update-13596.MPQ 148 022 182 +patches\wow-update-13623.MPQ 11 561 +patches\wow-update-base-13914.MPQ 293 580 556 +patches\wow-update-base-14007.MPQ 262 906 +patches\wow-update-base-14333.MPQ 368 972 365 +patches\wow-update-base-14480.MPQ 75 897 +patches\wow-update-base-14545.MPQ 1 224 415 +patches\wow-update-base-14946.MPQ 749 246 163 +patches\wow-update-base-15005.MPQ 7 121 223 +patches\wow-update-base-15050.MPQ 4 497 +patches\wow-update-enGB-16016.MPQ 17 117 318 +patches\wow-update-enGB-16048.MPQ 78 180 +patches\wow-update-enGB-16057.MPQ 4 072 +patches\wow-update-enGB-16309.MPQ 28 187 877 +patches\wow-update-enGB-16357.MPQ 3 621 +patches\wow-update-enGB-16516.MPQ 42 934 402 +patches\wow-update-enGB-16650.MPQ 426 683 +patches\wow-update-enGB-16844.MPQ 18 366 460 +patches\wow-update-enGB-16965.MPQ 305 202 +patches\wow-update-oldworld-13154.MPQ 54 068 663 +patches\wow-update-oldworld-13286.MPQ 2 328 773 + +AddFile.bin 0 // Just an empty file +AddFile.exe 432 640 // An arbitraty binary file +AddFile.wav 311 340 // An arbitrary WAVE file +ListFile_Blizzard.txt 3 904 784 // Listfile for Blizzard games (pre-WoW) +ListFile_WarOfTheImmortals.txt 3 904 858 // Listfile for War of the Immortals game +MPQ_1997_v1_Diablo1_DIABDAT.MPQ 517 501 282 // Originally DIABDAT.MPQ from Diablo I +MPQ_1997_v1_Diablo1_DIABDAT.sha 206 +MPQ_1997_v1_Diablo1_single_0.sha 201 // Single player savegame from Diablo I +MPQ_1997_v1_Diablo1_single_0.sv 98 980 +MPQ_1999_v1_WeakSignature.exe 1 031 826 // War2Patch_202.exe from Warcraft II Bnet Edition +MPQ_1999_v1_WeakSignature.sha 260 +MPQ_2002_v1_BlockTableCut.MPQ 27 498 436 // Cut file War3Patch.mpq from Warcraft III +MPQ_2002_v1_BlockTableCut.sha 250 +MPQ_2002_v1_ProtectedMap_HashTable_FakeValid.sha 1 067 +MPQ_2002_v1_ProtectedMap_HashTable_FakeValid.w3x 1 089 638 // Protected Warcraft III map +MPQ_2002_v1_ProtectedMap_InvalidMpqFormat.sha 507 +MPQ_2002_v1_ProtectedMap_InvalidMpqFormat.w3x 2 429 195 // Protected Warcraft III map +MPQ_2002_v1_ProtectedMap_InvalidUserData.sha 293 +MPQ_2002_v1_ProtectedMap_InvalidUserData.w3x 596 486 // Protected Warcraft III map +MPQ_2002_v1_StrongSignature.sha 250 +MPQ_2002_v1_StrongSignature.w3m 306 818 // (10)DustwallowKeys.w3m from Warcraft III +MPQ_2009_v2_WoW_patch.MPQ.part 31 396 380 // patch.MPQ.part from trial WoW build 10958 +MPQ_2009_v2_WoW_patch.MPQ.sha 226 +MPQ_2010_v2_HashTableCompressed.MPQ.part 14 546 972 // interface.MPQ.part from WoW build 10958 +MPQ_2010_v2_HashTableCompressed.MPQ.sha 277 +MPQ_2010_v2_HasUserData.s2ma 1 972 177 // (4) - AI - Kulas Ravine (1x).s2ma from Starcraft II Beta +MPQ_2010_v2_HasUserData.sha 261 +MPQ_2010_v3_expansion-locale-frFR.MPQ 2 980 489 // expansion-locale-frFR.MPQ from WoW 12911 +MPQ_2010_v3_expansion-locale-frFR.sha 274 +MPQ_2011_v2_EncryptedMpq.MPQE 41 631 764 // Installer UI 2 esES.MPQE from Starcraft II Installer (build 15404) +MPQ_2011_v2_EncryptedMpq.sha 255 +MPQ_2011_v4_InvalidHetEntryCount.MPQ 206 164 // An invalid MPQ created by a previous Stormlib version +MPQ_2011_v4_InvalidHetEntryCount.sha 312 +MPQ_2012_v2_EmptyMpq.MPQ 44 // Empty MPQ (Cache from WoW 11723) +MPQ_2012_v2_EmptyMpq.sha 212 +MPQ_2012_v4_OldWorld.MPQ 1 854 547 587 // OldWorld.MPQ from WoW 12911 +MPQ_2012_v4_OldWorld.sha 270 +MPQ_2013_v4_EmptyMpq.MPQ 208 // Empty MPQ created by StormLib +MPQ_2013_v4_EmptyMpq.sha 183 +MPQ_2013_v4_expansion1.MPQ 1 426 926 736 // expansion1.MPQ from WoW build 17538 +MPQ_2013_v4_expansion1.sha 221 +MPQ_2013_v4_locale-enGB.MPQ 446 491 866 // locale-enGB.MPQ from WoW build 16965 +MPQ_2013_v4_locale-enGB.sha 273 +MPQ_2013_v4_patch-base-16357.MPQ 249 // patch-base-16357.MPQ from WoW build 17538 +MPQ_2013_v4_patch-base-16357.sha 229 +MPQ_2013_v4_SC2_EmptyMap.SC2Map 25 058 // Custom Starcraft II Map +MPQ_2013_v4_SC2_EmptyMap.sha 243 +MPQ_2013_v4_world.MPQ 2 617 175 835 // world.MPQ from WoW build 12911 +MPQ_2013_v4_world.sha 252 +MPx_2013_v1_LongwuOnline.mpk 2 146 549 // Scp.mpk from Longwu Online +MPx_2013_v1_LongwuOnline.sha 277 +MPx_2013_v1_WarOfTheImmortals.sha 248 +MPx_2013_v1_WarOfTheImmortals.sqp 56 775 675 // Modified Other.sqp from War of the Immortals diff --git a/StormLib/test/StormTest.cpp b/StormLib/test/StormTest.cpp new file mode 100644 index 000000000..f046b9146 --- /dev/null +++ b/StormLib/test/StormTest.cpp @@ -0,0 +1,4580 @@ +/*****************************************************************************/ +/* StormTest.cpp Copyright (c) Ladislav Zezula 2003 */ +/*---------------------------------------------------------------------------*/ +/* Test module for StormLib */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 25.03.03 1.00 Lad The first version of StormTest.cpp */ +/*****************************************************************************/ + +#define _CRT_NON_CONFORMING_SWPRINTFS +#define _CRT_SECURE_NO_DEPRECATE +#define __INCLUDE_CRYPTOGRAPHY__ +#define __STORMLIB_SELF__ // Don't use StormLib.lib +#include + +#ifdef _MSC_VER +#include +#endif + +#include "../src/StormLib.h" +#include "../src/StormCommon.h" + +#include "TLogHelper.cpp" // Helper class for showing test results + +#ifdef _MSC_VER +#pragma warning(disable: 4505) // 'XXX' : unreferenced local function has been removed +#pragma comment(lib, "winmm.lib") +#endif + +#ifndef STORMLIB_WINDOWS +#include +#endif + +//------------------------------------------------------------------------------ +// Local structures + +#define TEST_FLAG_PROTECTED 0x01000000 +#define TEST_FLAG_FILE_COUNT 0x00FFFFFF + +typedef struct _TEST_INFO +{ + LPCTSTR szMpqName1; + LPCTSTR szMpqName2; + DWORD dwFlags; + LPCSTR szFileName1; + LPCSTR szFileName2; +} TEST_INFO, *PTEST_INFO; + +typedef struct _LINE_INFO +{ + LONG nLinePos; + DWORD nLineLen; + const char * szLine; +} LINE_INFO, *PLINE_INFO; + +//------------------------------------------------------------------------------ +// Local variables + +#ifdef STORMLIB_WINDOWS +#define WORK_PATH_ROOT _T("\\Multimedia\\MPQs") +static const TCHAR szListFileDir[] = { '1', '9', '9', '5', ' ', '-', ' ', 'T', 'e', 's', 't', ' ', 'M', 'P', 'Q', 's', '\\', 'l', 'i', 's', 't', 'f', 'i', 'l', 'e', 's', '-', (TCHAR)0x65B0, (TCHAR)0x5EFA, (TCHAR)0x6587, (TCHAR)0x4EF6, (TCHAR)0x5939, 0 }; +#endif + +#ifdef STORMLIB_LINUX +#define WORK_PATH_ROOT "/media/ladik/CascStorages/MPQs" +static const TCHAR szListFileDir[] = { '1', '9', '9', '5', ' ', '-', ' ', 'T', 'e', 's', 't', ' ', 'M', 'P', 'Q', 's', '\\', 'l', 'i', 's', 't', 'f', 'i', 'l', 'e', 's', '-', (TCHAR)0xe6, (TCHAR)0x96, (TCHAR)0xB0, (TCHAR)0xE5, (TCHAR)0xBB, (TCHAR)0xBA, (TCHAR)0xE6, (TCHAR)0x96, (TCHAR)0x87, (TCHAR)0xE4, (TCHAR)0xBB, (TCHAR)0xB6, (TCHAR)0xE5, (TCHAR)0xA4, (TCHAR)0xB9, 0 }; +#endif + +#ifdef STORMLIB_MAC +#define WORK_PATH_ROOT "/home/sam/StormLib/test" +static const TCHAR szListFileDir[] = { '1', '9', '9', '5', ' ', '-', ' ', 'T', 'e', 's', 't', ' ', 'M', 'P', 'Q', 's', '\\', 'l', 'i', 's', 't', 'f', 'i', 'l', 'e', 's', '-', (TCHAR)0xe6, (TCHAR)0x96, (TCHAR)0xB0, (TCHAR)0xE5, (TCHAR)0xBB, (TCHAR)0xBA, (TCHAR)0xE6, (TCHAR)0x96, (TCHAR)0x87, (TCHAR)0xE4, (TCHAR)0xBB, (TCHAR)0xB6, (TCHAR)0xE5, (TCHAR)0xA4, (TCHAR)0xB9, 0 }; +#endif + +#ifdef STORMLIB_HAIKU +#define WORK_PATH_ROOT "~/StormLib/test" +static const TCHAR szListFileDir[] = { '1', '9', '9', '5', ' ', '-', ' ', 'T', 'e', 's', 't', ' ', 'M', 'P', 'Q', 's', '\\', 'l', 'i', 's', 't', 'f', 'i', 'l', 'e', 's', '-', (TCHAR)0xe6, (TCHAR)0x96, (TCHAR)0xB0, (TCHAR)0xE5, (TCHAR)0xBB, (TCHAR)0xBA, (TCHAR)0xE6, (TCHAR)0x96, (TCHAR)0x87, (TCHAR)0xE4, (TCHAR)0xBB, (TCHAR)0xB6, (TCHAR)0xE5, (TCHAR)0xA4, (TCHAR)0xB9, 0 }; +#endif + +// Global for the work MPQ +static LPCTSTR szMpqSubDir = _T("1995 - Test MPQs"); +static LPCTSTR szMpqPatchDir = _T("1995 - Test MPQs\\patches"); + +typedef DWORD (*FIND_FILE_CALLBACK)(LPCTSTR szFullPath); + +#define ERROR_UNDETERMINED_RESULT 0xC000FFFF + +//----------------------------------------------------------------------------- +// Testing data + +static DWORD AddFlags[] = +{ +// Compression Encryption Fixed key Single Unit Sector CRC + 0 | 0 | 0 | 0 | 0, + 0 | MPQ_FILE_ENCRYPTED | 0 | 0 | 0, + 0 | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY | 0 | 0, + 0 | 0 | 0 | MPQ_FILE_SINGLE_UNIT | 0, + 0 | MPQ_FILE_ENCRYPTED | 0 | MPQ_FILE_SINGLE_UNIT | 0, + 0 | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY | MPQ_FILE_SINGLE_UNIT | 0, + MPQ_FILE_IMPLODE | 0 | 0 | 0 | 0, + MPQ_FILE_IMPLODE | MPQ_FILE_ENCRYPTED | 0 | 0 | 0, + MPQ_FILE_IMPLODE | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY | 0 | 0, + MPQ_FILE_IMPLODE | 0 | 0 | MPQ_FILE_SINGLE_UNIT | 0, + MPQ_FILE_IMPLODE | MPQ_FILE_ENCRYPTED | 0 | MPQ_FILE_SINGLE_UNIT | 0, + MPQ_FILE_IMPLODE | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY | MPQ_FILE_SINGLE_UNIT | 0, + MPQ_FILE_IMPLODE | 0 | 0 | 0 | MPQ_FILE_SECTOR_CRC, + MPQ_FILE_IMPLODE | MPQ_FILE_ENCRYPTED | 0 | 0 | MPQ_FILE_SECTOR_CRC, + MPQ_FILE_IMPLODE | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY | 0 | MPQ_FILE_SECTOR_CRC, + MPQ_FILE_COMPRESS | 0 | 0 | 0 | 0, + MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | 0 | 0 | 0, + MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY | 0 | 0, + MPQ_FILE_COMPRESS | 0 | 0 | MPQ_FILE_SINGLE_UNIT | 0, + MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | 0 | MPQ_FILE_SINGLE_UNIT | 0, + MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY | MPQ_FILE_SINGLE_UNIT | 0, + MPQ_FILE_COMPRESS | 0 | 0 | 0 | MPQ_FILE_SECTOR_CRC, + MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | 0 | 0 | MPQ_FILE_SECTOR_CRC, + MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY | 0 | MPQ_FILE_SECTOR_CRC, + 0xFFFFFFFF +}; + +static DWORD WaveCompressions[] = +{ + MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_HUFFMANN, + MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN, + MPQ_COMPRESSION_PKWARE, + MPQ_COMPRESSION_ZLIB, + MPQ_COMPRESSION_BZIP2 +}; + +static const wchar_t szUnicodeName1[] = { // Czech + 0x010C, 0x0065, 0x0073, 0x006B, 0x00FD, _T('.'), _T('m'), _T('p'), _T('q'), 0 +}; + +static const wchar_t szUnicodeName2[] = { // Russian + 0x0420, 0x0443, 0x0441, 0x0441, 0x043A, 0x0438, 0x0439, _T('.'), _T('m'), _T('p'), _T('q'), 0 +}; + +static const wchar_t szUnicodeName3[] = { // Greek + 0x03B5, 0x03BB, 0x03BB, 0x03B7, 0x03BD, 0x03B9, 0x03BA, 0x03AC, _T('.'), _T('m'), _T('p'), _T('q'), 0 +}; + +static const wchar_t szUnicodeName4[] = { // Chinese + 0x65E5, 0x672C, 0x8A9E, _T('.'), _T('m'), _T('p'), _T('q'), 0 +}; + +static const wchar_t szUnicodeName5[] = { // Japanese + 0x7B80, 0x4F53, 0x4E2D, 0x6587, _T('.'), _T('m'), _T('p'), _T('q'), 0 +}; + +static const wchar_t szUnicodeName6[] = { // Arabic + 0x0627, 0x0644, 0x0639, 0x0639, 0x0631, 0x0628, 0x064A, 0x0629, _T('.'), _T('m'), _T('p'), _T('q'), 0 +}; + +static LPCTSTR PatchList_StarCraft[] = +{ + _T("MPQ_1998_v1_StarCraft.mpq"), + _T("s1-1998-BroodWar.mpq"), + NULL +}; + +static LPCTSTR PatchList_WoW_OldWorld13286[] = +{ + _T("MPQ_2012_v4_OldWorld.MPQ"), + _T("wow-update-oldworld-13154.MPQ"), + _T("wow-update-oldworld-13286.MPQ"), + NULL +}; + +static LPCTSTR PatchList_WoW_15050[] = +{ + _T("MPQ_2013_v4_world.MPQ"), + _T("wow-update-13164.MPQ"), + _T("wow-update-13205.MPQ"), + _T("wow-update-13287.MPQ"), + _T("wow-update-13329.MPQ"), + _T("wow-update-13596.MPQ"), + _T("wow-update-13623.MPQ"), + _T("wow-update-base-13914.MPQ"), + _T("wow-update-base-14007.MPQ"), + _T("wow-update-base-14333.MPQ"), + _T("wow-update-base-14480.MPQ"), + _T("wow-update-base-14545.MPQ"), + _T("wow-update-base-14946.MPQ"), + _T("wow-update-base-15005.MPQ"), + _T("wow-update-base-15050.MPQ"), + NULL +}; + +static LPCTSTR PatchList_WoW_16965[] = +{ + _T("MPQ_2013_v4_locale-enGB.MPQ"), + _T("wow-update-enGB-16016.MPQ"), + _T("wow-update-enGB-16048.MPQ"), + _T("wow-update-enGB-16057.MPQ"), + _T("wow-update-enGB-16309.MPQ"), + _T("wow-update-enGB-16357.MPQ"), + _T("wow-update-enGB-16516.MPQ"), + _T("wow-update-enGB-16650.MPQ"), + _T("wow-update-enGB-16844.MPQ"), + _T("wow-update-enGB-16965.MPQ"), + NULL +}; + +static LPCTSTR PatchList_SC2_32283[] = +{ + _T("MPQ_2013_v4_Base1.SC2Data"), + _T("s2-update-base-23258.MPQ"), + _T("s2-update-base-24540.MPQ"), + _T("s2-update-base-26147.MPQ"), + _T("s2-update-base-28522.MPQ"), + _T("s2-update-base-30508.MPQ"), + _T("s2-update-base-32283.MPQ"), + NULL +}; + +static LPCTSTR PatchList_SC2_34644[] = +{ + _T("MPQ_2013_v4_Base1.SC2Data"), + _T("s2-update-base-23258.MPQ"), + _T("s2-update-base-24540.MPQ"), + _T("s2-update-base-26147.MPQ"), + _T("s2-update-base-28522.MPQ"), + _T("s2-update-base-32384.MPQ"), + _T("s2-update-base-34644.MPQ"), + NULL +}; + +static LPCTSTR PatchList_SC2_34644_Maps[] = +{ + _T("MPQ_2013_v4_Base3.SC2Maps"), + _T("s2-update-base-23258.MPQ"), + _T("s2-update-base-24540.MPQ"), + _T("s2-update-base-26147.MPQ"), + _T("s2-update-base-28522.MPQ"), + _T("s2-update-base-32384.MPQ"), + _T("s2-update-base-34644.MPQ"), + NULL +}; + +static LPCTSTR PatchList_SC2_32283_enGB[] = +{ + _T("MPQ_2013_v4_Mods#Core.SC2Mod#enGB.SC2Assets"), + _T("s2-update-enGB-23258.MPQ"), + _T("s2-update-enGB-24540.MPQ"), + _T("s2-update-enGB-26147.MPQ"), + _T("s2-update-enGB-28522.MPQ"), + _T("s2-update-enGB-30508.MPQ"), + _T("s2-update-enGB-32283.MPQ"), + NULL +}; + +static LPCTSTR PatchList_SC2_36281_enGB[] = +{ + _T("MPQ_2013_v4_Mods#Liberty.SC2Mod#enGB.SC2Data"), + _T("s2-update-enGB-23258.MPQ"), + _T("s2-update-enGB-24540.MPQ"), + _T("s2-update-enGB-26147.MPQ"), + _T("s2-update-enGB-28522.MPQ"), + _T("s2-update-enGB-32384.MPQ"), + _T("s2-update-enGB-34644.MPQ"), + _T("s2-update-enGB-36281.MPQ"), + NULL +}; + +static LPCTSTR PatchList_HS_3604_enGB[] = +{ + _T("MPQ_2014_v4_base-Win.MPQ"), + _T("hs-0-3604-Win-final.MPQ"), + NULL +}; + +static LPCTSTR PatchList_HS_6898_enGB[] = +{ + _T("MPQ_2014_v4_base-Win.MPQ"), + _T("hs-0-5314-Win-final.MPQ"), + _T("hs-5314-5435-Win-final.MPQ"), + _T("hs-5435-5506-Win-final.MPQ"), + _T("hs-5506-5834-Win-final.MPQ"), + _T("hs-5834-6024-Win-final.MPQ"), + _T("hs-6024-6141-Win-final.MPQ"), + _T("hs-6141-6187-Win-final.MPQ"), + _T("hs-6187-6284-Win-final.MPQ"), + _T("hs-6284-6485-Win-final.MPQ"), + _T("hs-6485-6898-Win-final.MPQ"), + NULL +}; + +//----------------------------------------------------------------------------- +// Local file functions + +// Definition of the path separator +#ifdef STORMLIB_WINDOWS +static LPCTSTR g_szPathSeparator = _T("\\"); +static const TCHAR PATH_SEPARATOR = _T('\\'); // Path separator for Windows platforms +#else +static LPCSTR g_szPathSeparator = "/"; +static const TCHAR PATH_SEPARATOR = '/'; // Path separator for Non-Windows platforms +#endif + +// This must be the directory where our test MPQs are stored. +// We also expect a subdirectory named +static TCHAR szMpqDirectory[MAX_PATH+1]; +size_t cchMpqDirectory = 0; + +template +static bool IsFullPath(const XCHAR * szFileName) +{ +#ifdef STORMLIB_WINDOWS + if(('A' <= szFileName[0] && szFileName[0] <= 'Z') || ('a' <= szFileName[0] && szFileName[0] <= 'z')) + { + return (szFileName[1] == ':' && szFileName[2] == PATH_SEPARATOR); + } +#endif + + szFileName = szFileName; + return false; +} + +static bool IsMpqExtension(LPCTSTR szFileName) +{ + LPCTSTR szExtension = _tcsrchr(szFileName, '.'); + + if(szExtension != NULL) + { + if(!_tcsicmp(szExtension, _T(".mpq"))) + return true; + if(!_tcsicmp(szExtension, _T(".w3m"))) + return true; + if(!_tcsicmp(szExtension, _T(".w3x"))) + return true; + if(!_tcsicmp(szExtension, _T(".asi"))) + return true; + if(!_tcsicmp(szExtension, _T(".mpqe"))) + return true; + if(!_tcsicmp(szExtension, _T(".part"))) + return true; + if(!_tcsicmp(szExtension, _T(".sv"))) + return true; + if(!_tcsicmp(szExtension, _T(".s2ma"))) + return true; + if(!_tcsicmp(szExtension, _T(".SC2Map"))) + return true; + if(!_tcsicmp(szExtension, _T(".SC2Mod"))) + return true; + if(!_tcsicmp(szExtension, _T(".SC2Replay"))) + return true; + if(!_tcsicmp(szExtension, _T(".0"))) // .MPQ.0 + return true; +// if(!_tcsicmp(szExtension, ".link")) +// return true; + } + + return false; +} + +static void BinaryFromString(LPCSTR szBinary, LPBYTE pbBuffer, DWORD cbBuffer) +{ + LPBYTE pbBufferEnd = pbBuffer + cbBuffer; + char * szTemp; + char szHexaDigit[4]; + + while(szBinary[0] != 0 && pbBuffer < pbBufferEnd) + { + // Get the 2-byte chunk + szHexaDigit[0] = szBinary[0]; + szHexaDigit[1] = szBinary[1]; + szHexaDigit[2] = 0; + + // Convert to integer + *pbBuffer++ = (BYTE)strtoul(szHexaDigit, &szTemp, 16); + szBinary += 2; + } +} + +static void AddStringBeforeExtension(char * szBuffer, LPCSTR szFileName, LPCSTR szExtraString) +{ + LPCSTR szExtension; + size_t nLength; + + // Get the extension + szExtension = strrchr(szFileName, '.'); + if(szExtension == NULL) + szExtension = szFileName + strlen(szFileName); + nLength = (size_t)(szExtension - szFileName); + + // Copy the part before extension + memcpy(szBuffer, szFileName, nLength); + szFileName += nLength; + szBuffer += nLength; + + // Append the extra data + if(szExtraString != NULL) + strcpy(szBuffer, szExtraString); + + // Append the rest of the file name + strcat(szBuffer, szFileName); +} + +static bool CompareBlocks(LPBYTE pbBlock1, LPBYTE pbBlock2, DWORD dwLength, DWORD * pdwDifference) +{ + for(DWORD i = 0; i < dwLength; i++) + { + if(pbBlock1[i] != pbBlock2[i]) + { + pdwDifference[0] = i; + return false; + } + } + + return true; +} + +static int GetPathSeparatorCount(LPCSTR szPath) +{ + int nSeparatorCount = 0; + + while(szPath[0] != 0) + { + if(szPath[0] == '\\' || szPath[0] == '/') + nSeparatorCount++; + szPath++; + } + + return nSeparatorCount; +} + +template +static const XCHAR * FindNextPathPart(const XCHAR * szPath, size_t nPartCount) +{ + const XCHAR * szPathPart = szPath; + + while(szPath[0] != 0 && nPartCount > 0) + { + // Is there path separator? + if(szPath[0] == '\\' || szPath[0] == '/') + { + szPathPart = szPath + 1; + nPartCount--; + } + + // Move to the next letter + szPath++; + } + + return szPathPart; +} + +template +size_t StringLength(const XCHAR * szString) +{ + size_t nLength; + + for(nLength = 0; szString[nLength] != 0; nLength++); + + return nLength; +} + +template +static const XCHAR * GetShortPlainName(const XCHAR * szFileName) +{ + const XCHAR * szPlainName = FindNextPathPart(szFileName, 1000); + const XCHAR * szPlainEnd = szFileName + StringLength(szFileName); + + // If the name is still too long, cut it + if((szPlainEnd - szPlainName) > 50) + szPlainName = szPlainEnd - 50; + + return szPlainName; +} + +static void CopyPathPart(char * szBuffer, LPCSTR szPath) +{ + while(szPath[0] != 0) + { + szBuffer[0] = (szPath[0] == '\\' || szPath[0] == '/') ? '/' : szPath[0]; + szBuffer++; + szPath++; + } + + *szBuffer = 0; +} + +static bool CopyStringAndVerifyConversion( + LPCTSTR szFoundFile, + TCHAR * szBufferT, + char * szBufferA, + size_t cchMaxChars) +{ + // Convert the TCHAR name to ANSI name + StringCopy(szBufferA, cchMaxChars, szFoundFile); + StringCopy(szBufferT, cchMaxChars, szBufferA); + + // Compare both TCHAR strings + return (_tcsicmp(szBufferT, szFoundFile) == 0) ? true : false; +} + +static size_t ConvertSha1ToText(const unsigned char * sha1_digest, TCHAR * szSha1Text) +{ + LPCSTR szTable = "0123456789abcdef"; + + for(size_t i = 0; i < SHA1_DIGEST_SIZE; i++) + { + *szSha1Text++ = szTable[(sha1_digest[0] >> 0x04)]; + *szSha1Text++ = szTable[(sha1_digest[0] & 0x0F)]; + sha1_digest++; + } + + *szSha1Text = 0; + return (SHA1_DIGEST_SIZE * 2); +} + +static void CreateFullPathName(TCHAR * szBuffer, size_t cchBuffer, LPCTSTR szSubDir, LPCTSTR szNamePart1, LPCTSTR szNamePart2 = NULL) +{ + TCHAR * szSaveBuffer = szBuffer; + size_t nPrefixLength = 0; + size_t nLength; + DWORD dwProvider = 0; + bool bIsFullPath = false; + char chSeparator = PATH_SEPARATOR; + + // Pre-initialize the buffer + szBuffer[0] = 0; + + // Determine the path prefix + if(szNamePart1 != NULL) + { + nPrefixLength = FileStream_Prefix(szNamePart1, &dwProvider); + if((dwProvider & BASE_PROVIDER_MASK) == BASE_PROVIDER_HTTP) + { + bIsFullPath = true; + chSeparator = '/'; + } + else + bIsFullPath = IsFullPath(szNamePart1 + nPrefixLength); + } + + // Copy the MPQ prefix, if any + if(nPrefixLength > 0) + { + StringCat(szBuffer, cchBuffer, szNamePart1); + szBuffer[nPrefixLength] = 0; + szSaveBuffer += nPrefixLength; + szNamePart1 += nPrefixLength; + } + + // If the given name is not a full path, copy the MPQ directory + if(bIsFullPath == false) + { + // Copy the master MPQ directory + StringCat(szBuffer, cchBuffer, szMpqDirectory); + + // Append the subdirectory, if any + if(szSubDir != NULL && (nLength = _tcslen(szSubDir)) != 0) + { + // No leading or trailing separator are allowed + assert(szSubDir[0] != '/' && szSubDir[0] != '\\'); + assert(szSubDir[nLength - 1] != '/' && szSubDir[nLength - 1] != '\\'); + + // Append the subdirectory + StringCat(szBuffer, cchBuffer, g_szPathSeparator); + StringCat(szBuffer, cchBuffer, szSubDir); + } + } + + // Copy the file name, if any + if(szNamePart1 != NULL && (nLength = _tcslen(szNamePart1)) != 0) + { + // Path separators are not allowed in the name part + assert(szNamePart1[0] != '\\' && szNamePart1[0] != '/'); + assert(szNamePart1[nLength - 1] != '/' && szNamePart1[nLength - 1] != '\\'); + + // Append file path separator and the name part + if(bIsFullPath == false) + StringCat(szBuffer, cchBuffer, g_szPathSeparator); + StringCat(szBuffer, cchBuffer, szNamePart1); + } + + // Append the second part of the name + if(szNamePart2 != NULL && (nLength = _tcslen(szNamePart2)) != 0) + { + // Copy the file name + StringCat(szBuffer, cchBuffer, szNamePart2); + } + + // Normalize the path separators + for(; szSaveBuffer[0] != 0; szSaveBuffer++) + { + szSaveBuffer[0] = (szSaveBuffer[0] != '/' && szSaveBuffer[0] != '\\') ? szSaveBuffer[0] : chSeparator; + } +} + +#ifdef _UNICODE +static void CreateFullPathName(char * szBuffer, size_t cchBuffer, LPCTSTR szSubDir, LPCTSTR szNamePart1, LPCTSTR szNamePart2 = NULL) +{ + TCHAR szFullPathT[MAX_PATH]; + + CreateFullPathName(szFullPathT, _countof(szFullPathT), szSubDir, szNamePart1, szNamePart2); + StringCopy(szBuffer, cchBuffer, szFullPathT); +} +#endif + +static DWORD CalculateFileSha1(TLogHelper * pLogger, LPCTSTR szFullPath, TCHAR * szFileSha1) +{ + TFileStream * pStream; + unsigned char sha1_digest[SHA1_DIGEST_SIZE]; + LPCTSTR szShortPlainName = GetShortPlainName(szFullPath); + hash_state sha1_state; + ULONGLONG ByteOffset = 0; + ULONGLONG FileSize = 0; + BYTE * pbFileBlock; + DWORD cbBytesToRead; + DWORD cbFileBlock = 0x100000; + DWORD dwErrCode = ERROR_SUCCESS; + + // Notify the user + pLogger->PrintProgress(_T("Hashing file %s"), szShortPlainName); + szFileSha1[0] = 0; + + // Open the file to be verified + pStream = FileStream_OpenFile(szFullPath, STREAM_FLAG_READ_ONLY); + if(pStream != NULL) + { + // Retrieve the size of the file + FileStream_GetSize(pStream, &FileSize); + + // Allocate the buffer for loading file parts + pbFileBlock = STORM_ALLOC(BYTE, cbFileBlock); + if(pbFileBlock != NULL) + { + // Initialize SHA1 calculation + sha1_init(&sha1_state); + + // Calculate the SHA1 of the file + while(ByteOffset < FileSize) + { + // Notify the user + pLogger->PrintProgress(_T("Hashing file %s (%I64u of %I64u)"), szShortPlainName, ByteOffset, FileSize); + + // Load the file block + cbBytesToRead = ((FileSize - ByteOffset) > cbFileBlock) ? cbFileBlock : (DWORD)(FileSize - ByteOffset); + if(!FileStream_Read(pStream, &ByteOffset, pbFileBlock, cbBytesToRead)) + { + dwErrCode = GetLastError(); + break; + } + + // Add to SHA1 + sha1_process(&sha1_state, pbFileBlock, cbBytesToRead); + ByteOffset += cbBytesToRead; + } + + // Notify the user + pLogger->PrintProgress(_T("Hashing file %s (%I64u of %I64u)"), szShortPlainName, ByteOffset, FileSize); + + // Finalize SHA1 + sha1_done(&sha1_state, sha1_digest); + + // Convert the SHA1 to ANSI text + ConvertSha1ToText(sha1_digest, szFileSha1); + STORM_FREE(pbFileBlock); + } + + FileStream_Close(pStream); + } + + // If we calculated something, return OK + if(dwErrCode == ERROR_SUCCESS && szFileSha1[0] == 0) + dwErrCode = ERROR_CAN_NOT_COMPLETE; + return dwErrCode; +} + +//----------------------------------------------------------------------------- +// Directory search + +static HANDLE InitDirectorySearch(LPCTSTR szDirectory) +{ +#ifdef STORMLIB_WINDOWS + + WIN32_FIND_DATA wf; + HANDLE hFind; + TCHAR szSearchMask[MAX_PATH]; + + // Construct the directory mask + _stprintf(szSearchMask, _T("%s\\*"), szDirectory); + + // Perform the search + hFind = FindFirstFile(szSearchMask, &wf); + return (hFind != INVALID_HANDLE_VALUE) ? hFind : NULL; + +#endif + +#if defined(STORMLIB_LINUX) || defined(STORMLIB_MAC) + + // Keep compilers happy + return (HANDLE)opendir(szDirectory); + +#endif +} + +static bool SearchDirectory(HANDLE hFind, TCHAR * szDirEntry, size_t cchDirEntry, bool & IsDirectory) +{ +#ifdef STORMLIB_WINDOWS + + WIN32_FIND_DATA wf; + TCHAR szDirEntryT[MAX_PATH]; + char szDirEntryA[MAX_PATH]; + + __SearchNextEntry: + + // Search for the hnext entry. + if(FindNextFile(hFind, &wf)) + { + // Verify if the directory entry is an UNICODE name that would be destroyed + // by Unicode->ANSI->Unicode conversion + if(CopyStringAndVerifyConversion(wf.cFileName, szDirEntryT, szDirEntryA, _countof(szDirEntryA)) == false) + goto __SearchNextEntry; + + IsDirectory = (wf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? true : false; + StringCopy(szDirEntry, cchDirEntry, wf.cFileName); + return true; + } + + return false; + +#endif + +#if defined(STORMLIB_LINUX) || defined(STORMLIB_MAC) + + struct dirent * directory_entry; + + directory_entry = readdir((DIR *)hFind); + if(directory_entry != NULL) + { + IsDirectory = (directory_entry->d_type == DT_DIR) ? true : false; + strcpy(szDirEntry, directory_entry->d_name); + return true; + } + + return false; + +#endif +} + +static void FreeDirectorySearch(HANDLE hFind) +{ +#ifdef STORMLIB_WINDOWS + FindClose(hFind); +#endif + +#if defined(STORMLIB_LINUX) || defined(STORMLIB_MAC) + closedir((DIR *)hFind); +#endif +} + +static DWORD FindFilesInternal(FIND_FILE_CALLBACK pfnTest, TCHAR * szDirectory) +{ + TCHAR * szPlainName; + HANDLE hFind; + size_t nLength; + TCHAR szDirEntry[MAX_PATH]; + bool IsDirectory = false; + DWORD dwErrCode = ERROR_SUCCESS; + + if(szDirectory != NULL) + { + // Initiate directory search + hFind = InitDirectorySearch(szDirectory); + if(hFind != NULL) + { + // Append slash at the end of the directory name + nLength = _tcslen(szDirectory); + szDirectory[nLength++] = PATH_SEPARATOR; + szPlainName = szDirectory + nLength; + + // Skip the first entry, since it's always "." or ".." + while(SearchDirectory(hFind, szDirEntry, _countof(szDirEntry), IsDirectory) && dwErrCode == ERROR_SUCCESS) + { + // Copy the directory entry name to both names + _tcscpy(szPlainName, szDirEntry); + + // Found a directory? + if(IsDirectory) + { + if(szDirEntry[0] != '.') + { + dwErrCode = FindFilesInternal(pfnTest, szDirectory); + } + } + else + { + if(pfnTest != NULL) + { + dwErrCode = pfnTest(szDirectory); + } + } + } + + FreeDirectorySearch(hFind); + } + } + + // Free the path buffer, if any + return dwErrCode; +} + +static DWORD FindFiles(FIND_FILE_CALLBACK pfnFindFile, LPCTSTR szSubDirectory) +{ + TCHAR szWorkBuff[MAX_PATH]; + + CreateFullPathName(szWorkBuff, _countof(szWorkBuff), szSubDirectory, NULL); + return FindFilesInternal(pfnFindFile, szWorkBuff); +} + +static DWORD InitializeMpqDirectory(TCHAR * argv[], int argc) +{ + TLogHelper Logger("InitWorkDir"); + TFileStream * pStream; + TCHAR szFullPath[MAX_PATH]; + LPCTSTR szWhereFrom = _T("default"); + LPCTSTR szDirName = WORK_PATH_ROOT; + + // Retrieve the first argument + if(argc > 1 && argv[1] != NULL) + { + // Check if it's a directory + pStream = FileStream_OpenFile(argv[1], STREAM_FLAG_READ_ONLY); + if(pStream == NULL) + { + szWhereFrom = _T("command line"); + szDirName = argv[1]; + } + else + { + FileStream_Close(pStream); + } + } + + // Copy the name of the MPQ directory. + StringCopy(szMpqDirectory, _countof(szMpqDirectory), szDirName); + cchMpqDirectory = _tcslen(szMpqDirectory); + + // Cut trailing slashes and/or backslashes + while((cchMpqDirectory > 0) && (szMpqDirectory[cchMpqDirectory - 1] == '/' || szMpqDirectory[cchMpqDirectory - 1] == '\\')) + cchMpqDirectory--; + szMpqDirectory[cchMpqDirectory] = 0; + + // Print the work directory info + Logger.PrintMessage(_T("Work directory %s (%s)"), szMpqDirectory, szWhereFrom); + + // Verify if the work MPQ directory is writable + CreateFullPathName(szFullPath, _countof(szFullPath), NULL, _T("TestFile.bin")); + pStream = FileStream_CreateFile(szFullPath, 0); + if(pStream == NULL) + return Logger.PrintError(_T("MPQ subdirectory doesn't exist or is not writable")); + + // Close the stream + FileStream_Close(pStream); + _tremove(szFullPath); + + // Verify if the working directory exists and if there is a subdirectory with the file name + CreateFullPathName(szFullPath, _countof(szFullPath), szListFileDir, _T("ListFile_Blizzard.txt")); + pStream = FileStream_OpenFile(szFullPath, STREAM_FLAG_READ_ONLY); + if(pStream == NULL) + return Logger.PrintError(_T("The main listfile (%s) was not found. Check your paths"), GetShortPlainName(szFullPath)); + + // Close the stream + FileStream_Close(pStream); + return ERROR_SUCCESS; +} + +static DWORD GetFilePatchCount(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileName) +{ + TCHAR * szPatchName; + HANDLE hFile; + TCHAR szPatchChain[0x400]; + DWORD dwErrCode = ERROR_SUCCESS; + int nPatchCount = 0; + + // Open the MPQ file + if(SFileOpenFileEx(hMpq, szFileName, 0, &hFile)) + { + // Notify the user + pLogger->PrintProgress("Verifying patch chain for %s ...", GetShortPlainName(szFileName)); + + // Query the patch chain + if(!SFileGetFileInfo(hFile, SFileInfoPatchChain, szPatchChain, sizeof(szPatchChain), NULL)) + dwErrCode = pLogger->PrintError("Failed to retrieve the patch chain on %s", szFileName); + + // Is there anything at all in the patch chain? + if(dwErrCode == ERROR_SUCCESS && szPatchChain[0] == 0) + { + pLogger->PrintError("The patch chain for %s is empty", szFileName); + dwErrCode = ERROR_FILE_CORRUPT; + } + + // Now calculate the number of patches + if(dwErrCode == ERROR_SUCCESS) + { + // Get the pointer to the patch + szPatchName = szPatchChain; + + // Skip the base name + for(;;) + { + // Skip the current name + szPatchName = szPatchName + _tcslen(szPatchName) + 1; + if(szPatchName[0] == 0) + break; + + // Increment number of patches + nPatchCount++; + } + } + + SFileCloseFile(hFile); + } + else + { + pLogger->PrintError("Open failed: %s", szFileName); + } + + return nPatchCount; +} + +static DWORD VerifyFilePatchCount(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileName, int nExpectedPatchCount) +{ + int nPatchCount = 0; + + // Retrieve the patch count + pLogger->PrintProgress(_T("Verifying patch count for %s ..."), szFileName); + nPatchCount = GetFilePatchCount(pLogger, hMpq, szFileName); + + // Check if there are any patches at all + if(nExpectedPatchCount != 0 && nPatchCount == 0) + { + pLogger->PrintMessage("There are no patches for %s", szFileName); + return ERROR_FILE_CORRUPT; + } + + // Check if the number of patches fits + if(nPatchCount != nExpectedPatchCount) + { + pLogger->PrintMessage("Unexpected number of patches for %s", szFileName); + return ERROR_FILE_CORRUPT; + } + + return ERROR_SUCCESS; +} + +static DWORD CreateEmptyFile(TLogHelper * pLogger, LPCTSTR szPlainName, ULONGLONG FileSize, TCHAR * szBuffer) +{ + TFileStream * pStream; + TCHAR szFullPath[MAX_PATH]; + + // Notify the user + pLogger->PrintProgress(_T("Creating empty file %s ..."), szPlainName); + + // Construct the full path and crete the file + CreateFullPathName(szFullPath, _countof(szFullPath), NULL, szPlainName); + pStream = FileStream_CreateFile(szFullPath, STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE); + if(pStream == NULL) + return pLogger->PrintError(_T("Failed to create file %s"), szBuffer); + + // Write the required size + FileStream_SetSize(pStream, FileSize); + FileStream_Close(pStream); + + // Give the caller the full file name + if(szBuffer != NULL) + _tcscpy(szBuffer, szFullPath); + return ERROR_SUCCESS; +} + +static DWORD VerifyFilePosition( + TLogHelper * pLogger, + TFileStream * pStream, + ULONGLONG ExpectedPosition) +{ + ULONGLONG ByteOffset = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Retrieve the file position + if(FileStream_GetPos(pStream, &ByteOffset)) + { + if(ByteOffset != ExpectedPosition) + { + pLogger->PrintMessage(_T("The file position is different than expected (expected: ") I64u_t _T(", current: ") I64u_t, ExpectedPosition, ByteOffset); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + else + { + dwErrCode = pLogger->PrintError(_T("Failed to retrieve the file offset")); + } + + return dwErrCode; +} + +static DWORD VerifyFileMpqHeader(TLogHelper * pLogger, TFileStream * pStream, ULONGLONG * pByteOffset) +{ + TMPQHeader Header; + DWORD dwErrCode = ERROR_SUCCESS; + + memset(&Header, 0xFE, sizeof(TMPQHeader)); + if(FileStream_Read(pStream, pByteOffset, &Header, sizeof(TMPQHeader))) + { + if(Header.dwID != g_dwMpqSignature) + { + pLogger->PrintMessage(_T("Read error - the data is not a MPQ header")); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + else + { + dwErrCode = pLogger->PrintError(_T("Failed to read the MPQ header")); + } + + return dwErrCode; +} + +static DWORD WriteMpqUserDataHeader( + TLogHelper * pLogger, + TFileStream * pStream, + ULONGLONG ByteOffset, + DWORD dwByteCount) +{ + TMPQUserData UserData; + DWORD dwErrCode = ERROR_SUCCESS; + + // Notify the user + pLogger->PrintProgress("Writing user data header..."); + + // Fill the user data header + UserData.dwID = ID_MPQ_USERDATA; + UserData.cbUserDataSize = dwByteCount; + UserData.dwHeaderOffs = (dwByteCount + sizeof(TMPQUserData)); + UserData.cbUserDataHeader = dwByteCount / 2; + if(!FileStream_Write(pStream, &ByteOffset, &UserData, sizeof(TMPQUserData))) + dwErrCode = GetLastError(); + return dwErrCode; +} + +static DWORD WriteFileData( + TLogHelper * pLogger, + TFileStream * pStream, + ULONGLONG ByteOffset, + ULONGLONG ByteCount) +{ + ULONGLONG SaveByteCount = ByteCount; + ULONGLONG BytesWritten = 0; + LPBYTE pbDataBuffer; + DWORD cbDataBuffer = 0x10000; + DWORD dwErrCode = ERROR_SUCCESS; + + // Write some data + pbDataBuffer = new BYTE[cbDataBuffer]; + if(pbDataBuffer != NULL) + { + memset(pbDataBuffer, 0, cbDataBuffer); + strcpy((char *)pbDataBuffer, "This is a test data written to a file."); + + // Perform the write + while(ByteCount > 0) + { + DWORD cbToWrite = (ByteCount > cbDataBuffer) ? cbDataBuffer : (DWORD)ByteCount; + + // Notify the user + pLogger->PrintProgress("Writing file data (%I64u of %I64u) ...", BytesWritten, SaveByteCount); + + // Write the data + if(!FileStream_Write(pStream, &ByteOffset, pbDataBuffer, cbToWrite)) + { + dwErrCode = GetLastError(); + break; + } + + BytesWritten += cbToWrite; + ByteOffset += cbToWrite; + ByteCount -= cbToWrite; + } + + delete [] pbDataBuffer; + } + return dwErrCode; +} + +static DWORD CopyFileData( + TLogHelper * pLogger, + TFileStream * pStream1, + TFileStream * pStream2, + ULONGLONG ByteOffset, + ULONGLONG ByteCount) +{ + ULONGLONG BytesCopied = 0; + ULONGLONG EndOffset = ByteOffset + ByteCount; + LPBYTE pbCopyBuffer; + DWORD BytesToRead; + DWORD BlockLength = 0x100000; + DWORD dwErrCode = ERROR_SUCCESS; + + // Allocate copy buffer + pbCopyBuffer = STORM_ALLOC(BYTE, BlockLength); + if(pbCopyBuffer != NULL) + { + while(ByteOffset < EndOffset) + { + // Read source + BytesToRead = ((EndOffset - ByteOffset) > BlockLength) ? BlockLength : (DWORD)(EndOffset - ByteOffset); + if(!FileStream_Read(pStream1, &ByteOffset, pbCopyBuffer, BytesToRead)) + { + dwErrCode = GetLastError(); + break; + } + + // Write to the destination file + if(!FileStream_Write(pStream2, NULL, pbCopyBuffer, BytesToRead)) + { + dwErrCode = GetLastError(); + break; + } + + // Increment the byte counts + BytesCopied += BytesToRead; + ByteOffset += BytesToRead; + + // Notify the user + pLogger->PrintProgress("Copying (%I64u of %I64u complete) ...", BytesCopied, ByteCount); + } + + STORM_FREE(pbCopyBuffer); + } + + return dwErrCode; +} + +// Support function for copying file +static DWORD CreateFileCopy( + TLogHelper * pLogger, + LPCTSTR szPlainName, + LPCTSTR szFileCopy, + TCHAR * szBuffer = NULL, + size_t cchBuffer = 0, + ULONGLONG PreMpqDataSize = 0, + ULONGLONG UserDataSize = 0) +{ + TFileStream * pStream1; // Source file + TFileStream * pStream2; // Target file + ULONGLONG ByteOffset = 0; + ULONGLONG FileSize = 0; + TCHAR szFileName1[MAX_PATH]; + TCHAR szFileName2[MAX_PATH]; + DWORD dwErrCode = ERROR_SUCCESS; + + // Notify the user + szPlainName += FileStream_Prefix(szPlainName, NULL); + pLogger->PrintProgress(_T("Creating copy of %s ..."), szPlainName); + + // Construct both file names. Check if they are not the same + CreateFullPathName(szFileName1, _countof(szFileName1), szMpqSubDir, szPlainName); + CreateFullPathName(szFileName2, _countof(szFileName2), NULL, szFileCopy + FileStream_Prefix(szFileCopy, NULL)); + if(!_tcsicmp(szFileName1, szFileName2)) + { + pLogger->PrintError("Failed to create copy of MPQ (the copy name is the same like the original name)"); + return ERROR_CAN_NOT_COMPLETE; + } + + // Open the source file + pStream1 = FileStream_OpenFile(szFileName1, STREAM_FLAG_READ_ONLY); + if(pStream1 == NULL) + { + pLogger->PrintError(_T("Failed to open the source file %s"), szFileName1); + return ERROR_CAN_NOT_COMPLETE; + } + + // Create the destination file + pStream2 = FileStream_CreateFile(szFileName2, 0); + if(pStream2 != NULL) + { + // If we should write some pre-MPQ data to the target file, do it + if(PreMpqDataSize != 0) + { + dwErrCode = WriteFileData(pLogger, pStream2, ByteOffset, PreMpqDataSize); + ByteOffset += PreMpqDataSize; + } + + // If we should write some MPQ user data, write the header first + if(UserDataSize != 0) + { + dwErrCode = WriteMpqUserDataHeader(pLogger, pStream2, ByteOffset, (DWORD)UserDataSize); + ByteOffset += sizeof(TMPQUserData); + + dwErrCode = WriteFileData(pLogger, pStream2, ByteOffset, UserDataSize); + ByteOffset += UserDataSize; + } + + // Copy the file data from the source file to the destination file + FileStream_GetSize(pStream1, &FileSize); + if(FileSize != 0) + { + dwErrCode = CopyFileData(pLogger, pStream1, pStream2, 0, FileSize); + ByteOffset += FileSize; + } + FileStream_Close(pStream2); + } + + // Close the source file + FileStream_Close(pStream1); + + // Create the full file name of the target file, including prefix + if(szBuffer && cchBuffer) + CreateFullPathName(szBuffer, cchBuffer, NULL, szFileCopy); + + // Report error, if any + if(dwErrCode != ERROR_SUCCESS) + pLogger->PrintError("Failed to create copy of MPQ"); + return dwErrCode; +} + +static DWORD CreateMasterAndMirrorPaths( + TLogHelper * pLogger, + TCHAR * szMirrorPath, + TCHAR * szMasterPath, + LPCTSTR szMirrorName, + LPCTSTR szMasterName, + bool bCopyMirrorFile) +{ + TCHAR szCopyPath[MAX_PATH]; + DWORD dwErrCode = ERROR_SUCCESS; + + // Always delete the mirror file + CreateFullPathName(szMasterPath, MAX_PATH, szMpqSubDir, szMasterName); + CreateFullPathName(szCopyPath, _countof(szCopyPath), NULL, szMirrorName); + _tremove(szCopyPath + FileStream_Prefix(szCopyPath, NULL)); + + // Copy the mirrored file from the source to the work directory + if(bCopyMirrorFile) + dwErrCode = CreateFileCopy(pLogger, szMirrorName, szMirrorName); + + // Create the mirror*master path + if(dwErrCode == ERROR_SUCCESS) + _stprintf(szMirrorPath, _T("%s*%s"), szCopyPath, szMasterPath); + + return dwErrCode; +} + +static void WINAPI AddFileCallback(void * pvUserData, DWORD dwBytesWritten, DWORD dwTotalBytes, bool bFinalCall) +{ + TLogHelper * pLogger = (TLogHelper *)pvUserData; + + // Keep compiler happy + bFinalCall = bFinalCall; + + pLogger->PrintProgress("Adding file (%s) (%u of %u) (%u of %u) ...", pLogger->UserString, + pLogger->UserCount, + pLogger->UserTotal, + dwBytesWritten, + dwTotalBytes); +} + +static void WINAPI CompactCallback(void * pvUserData, DWORD dwWork, ULONGLONG BytesDone, ULONGLONG TotalBytes) +{ + TLogHelper * pLogger = (TLogHelper *)pvUserData; + LPCSTR szWork = NULL; + + switch(dwWork) + { + case CCB_CHECKING_FILES: + szWork = "Checking files in archive"; + break; + + case CCB_CHECKING_HASH_TABLE: + szWork = "Checking hash table"; + break; + + case CCB_COPYING_NON_MPQ_DATA: + szWork = "Copying non-MPQ data"; + break; + + case CCB_COMPACTING_FILES: + szWork = "Compacting files"; + break; + + case CCB_CLOSING_ARCHIVE: + szWork = "Closing archive"; + break; + } + + if(szWork != NULL) + { + if(pLogger != NULL) + pLogger->PrintProgress("%s (%I64u of %I64u) ...", szWork, BytesDone, TotalBytes); + else + printf("%s (" I64u_a " of " I64u_a ") ... \r", szWork, BytesDone, TotalBytes); + } +} + +//----------------------------------------------------------------------------- +// MPQ file utilities + +#define SEARCH_FLAG_LOAD_FILES 0x00000001 // Test function should load all files in the MPQ +#define SEARCH_FLAG_HASH_FILES 0x00000002 // Test function should load all files in the MPQ +#define SEARCH_FLAG_PLAY_WAVES 0x00000004 // Play extracted WAVE files +#define SEARCH_FLAG_MOST_PATCHED 0x00000008 // Find the most patched file +#define SEARCH_FLAG_IGNORE_ERRORS 0x00000010 // Ignore files that failed to open + +struct TFileData +{ + DWORD dwBlockIndex; + DWORD dwFileSize; + DWORD dwFlags; + DWORD dwCrc32; + BYTE FileData[1]; +}; + +static bool CheckIfFileIsPresent(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileName, bool bShouldExist) +{ + HANDLE hFile = NULL; + + if(SFileOpenFileEx(hMpq, szFileName, 0, &hFile)) + { + if(bShouldExist == false) + pLogger->PrintMessage("The file %s is present, but it should not be", szFileName); + SFileCloseFile(hFile); + return true; + } + else + { + if(bShouldExist) + pLogger->PrintMessage("The file %s is not present, but it should be", szFileName); + return false; + } +} + +static TFileData * LoadLocalFile(TLogHelper * pLogger, LPCTSTR szFileName, bool bMustSucceed) +{ + TFileStream * pStream; + TFileData * pFileData = NULL; + ULONGLONG FileSize = 0; + size_t nAllocateBytes; + + // Notify the user + if(pLogger != NULL) + pLogger->PrintProgress("Loading local file ..."); + + // Attempt to open the file + pStream = FileStream_OpenFile(szFileName, STREAM_FLAG_READ_ONLY); + if(pStream == NULL) + { + if(pLogger != NULL && bMustSucceed == true) + pLogger->PrintError(_T("Open failed: %s"), szFileName); + return NULL; + } + + // Verify the size + FileStream_GetSize(pStream, &FileSize); + if((FileSize >> 0x20) == 0) + { + // Allocate space for the file + nAllocateBytes = sizeof(TFileData) + (size_t)FileSize; + pFileData = (TFileData *)STORM_ALLOC(BYTE, nAllocateBytes); + if(pFileData != NULL) + { + // Make sure it;s properly zeroed + memset(pFileData, 0, nAllocateBytes); + pFileData->dwFileSize = (DWORD)FileSize; + + // Load to memory + if(!FileStream_Read(pStream, NULL, pFileData->FileData, pFileData->dwFileSize)) + { + STORM_FREE(pFileData); + pFileData = NULL; + } + } + } + + FileStream_Close(pStream); + return pFileData; +} + +static DWORD CompareTwoLocalFilesRR( + TLogHelper * pLogger, + TFileStream * pStream1, // Master file + TFileStream * pStream2, // Mirror file + int nIterations) // Number of iterations +{ + ULONGLONG RandomNumber = 0x12345678; // We need pseudo-random number that will repeat each run of the program + ULONGLONG RandomSeed; + ULONGLONG ByteOffset; + ULONGLONG FileSize1 = 1; + ULONGLONG FileSize2 = 2; + DWORD BytesToRead; + DWORD Difference; + LPBYTE pbBuffer1; + LPBYTE pbBuffer2; + DWORD cbBuffer = 0x100000; + DWORD dwErrCode = ERROR_SUCCESS; + + // Compare file sizes + FileStream_GetSize(pStream1, &FileSize1); + FileStream_GetSize(pStream2, &FileSize2); + if(FileSize1 != FileSize2) + { + pLogger->PrintMessage("The files have different size"); + return ERROR_CAN_NOT_COMPLETE; + } + + // Allocate both buffers + pbBuffer1 = STORM_ALLOC(BYTE, cbBuffer); + pbBuffer2 = STORM_ALLOC(BYTE, cbBuffer); + if(pbBuffer1 && pbBuffer2) + { + // Perform many random reads + for(int i = 0; i < nIterations; i++) + { + // Generate psudo-random offsrt and data size + ByteOffset = (RandomNumber % FileSize1); + BytesToRead = (DWORD)(RandomNumber % cbBuffer); + + // Show the progress message + pLogger->PrintProgress("Comparing file: Offset: " I64u_a ", Length: %u", ByteOffset, BytesToRead); + + // Only perform read if the byte offset is below + if(ByteOffset < FileSize1) + { + if((ByteOffset + BytesToRead) > FileSize1) + BytesToRead = (DWORD)(FileSize1 - ByteOffset); + + memset(pbBuffer1, 0xEE, cbBuffer); + memset(pbBuffer2, 0xAA, cbBuffer); + + FileStream_Read(pStream1, &ByteOffset, pbBuffer1, BytesToRead); + FileStream_Read(pStream2, &ByteOffset, pbBuffer2, BytesToRead); + + if(!CompareBlocks(pbBuffer1, pbBuffer2, BytesToRead, &Difference)) + { + pLogger->PrintMessage("Difference at %u (Offset " I64X_a ", Length %X)", Difference, ByteOffset, BytesToRead); + dwErrCode = ERROR_FILE_CORRUPT; + break; + } + + // Shuffle the random number + memcpy(&RandomSeed, pbBuffer1, sizeof(RandomSeed)); + RandomNumber = ((RandomNumber >> 0x11) | (RandomNumber << 0x29)) ^ (RandomNumber + RandomSeed); + } + } + } + + // Free both buffers + if(pbBuffer2 != NULL) + STORM_FREE(pbBuffer2); + if(pbBuffer1 != NULL) + STORM_FREE(pbBuffer1); + return dwErrCode; +} + +static TFileData * LoadMpqFile(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileName, LCID lcLocale = 0, bool bIgnoreOpedwErrCodes = false) +{ + TFileData * pFileData = NULL; + HANDLE hFile; + DWORD dwFileSizeHi = 0xCCCCCCCC; + DWORD dwFileSizeLo = 0; + DWORD dwBytesRead; + DWORD dwCrc32 = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Notify the user that we are loading a file from MPQ + pLogger->PrintProgress("Loading file %s ...", GetShortPlainName(szFileName)); + +#if defined(_MSC_VER) && defined(_DEBUG) +// if(!_stricmp(szFileName, "File00000733.wav")) +// __debugbreak(); +#endif + + // Make sure that we open the proper locale file + SFileSetLocale(lcLocale); + + // Open the file from MPQ + if(SFileOpenFileEx(hMpq, szFileName, 0, &hFile)) + { + // Get the CRC32 of the file + SFileGetFileInfo(hFile, SFileInfoCRC32, &dwCrc32, sizeof(dwCrc32), NULL); + + // Get the size of the file + if(dwErrCode == ERROR_SUCCESS) + { + dwFileSizeLo = SFileGetFileSize(hFile, &dwFileSizeHi); + if(dwFileSizeLo == SFILE_INVALID_SIZE || dwFileSizeHi != 0) + dwErrCode = pLogger->PrintError("Failed to query the file size"); + } + + // Spazzler protector: Creates fake files with size of 0x7FFFE7CA + if(dwErrCode == ERROR_SUCCESS) + { + if(dwFileSizeLo > 0x1FFFFFFF) + dwErrCode = ERROR_FILE_CORRUPT; + } + + // Allocate buffer for the file content + if(dwErrCode == ERROR_SUCCESS) + { + pFileData = (TFileData *)STORM_ALLOC(BYTE, sizeof(TFileData) + dwFileSizeLo); + if(pFileData == NULL) + { + pLogger->PrintError("Failed to allocate buffer for the file content"); + dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + } + } + + // get the file index of the MPQ file + if(dwErrCode == ERROR_SUCCESS) + { + // Store the file size + memset(pFileData, 0, sizeof(TFileData) + dwFileSizeLo); + pFileData->dwFileSize = dwFileSizeLo; + pFileData->dwCrc32 = dwCrc32; + + // Retrieve the block index and file flags + if(!SFileGetFileInfo(hFile, SFileInfoFileIndex, &pFileData->dwBlockIndex, sizeof(DWORD), NULL)) + dwErrCode = pLogger->PrintError("Failed retrieve the file index of %s", szFileName); + if(!SFileGetFileInfo(hFile, SFileInfoFlags, &pFileData->dwFlags, sizeof(DWORD), NULL)) + dwErrCode = pLogger->PrintError("Failed retrieve the file flags of %s", szFileName); + } + + // Load the entire file + if(dwErrCode == ERROR_SUCCESS) + { + //if(!stricmp(szFileName, "replay.game.events")) + // __debugbreak(); + + // Read the file data + SFileReadFile(hFile, pFileData->FileData, dwFileSizeLo, &dwBytesRead, NULL); + if(dwBytesRead != dwFileSizeLo) + dwErrCode = ERROR_FILE_CORRUPT; + } + + // If failed, free the buffer + if(dwErrCode != ERROR_SUCCESS) + { + SetLastError(dwErrCode); + if(pFileData != NULL) + STORM_FREE(pFileData); + pFileData = NULL; + } + + SFileCloseFile(hFile); + } + else + { + if(bIgnoreOpedwErrCodes == false) + { + dwErrCode = pLogger->PrintError("Open failed: %s", szFileName); + } + } + + // Return what we got + return pFileData; +} + +static bool CompareTwoFiles(TLogHelper * pLogger, TFileData * pFileData1, TFileData * pFileData2) +{ + // Compare the file size + if(pFileData1->dwFileSize != pFileData2->dwFileSize) + { + pLogger->PrintErrorVa(_T("The files have different size (%u vs %u)"), pFileData1->dwFileSize, pFileData2->dwFileSize); + SetLastError(ERROR_FILE_CORRUPT); + return false; + } + + // Compare the files + for(DWORD i = 0; i < pFileData1->dwFileSize; i++) + { + if(pFileData1->FileData[i] != pFileData2->FileData[i]) + { + pLogger->PrintErrorVa(_T("Files are different at offset %08X"), i); + SetLastError(ERROR_FILE_CORRUPT); + return false; + } + } + + // The files are identical + return true; +} + +static DWORD SearchArchive( + TLogHelper * pLogger, + HANDLE hMpq, + DWORD dwSearchFlags = 0, + DWORD * pdwFileCount = NULL, + LPBYTE pbFileHash = NULL) +{ + SFILE_FIND_DATA sf; + TFileData * pFileData; + HANDLE hFind; + DWORD dwFileCount = 0; + hash_state md5state; + TCHAR szListFile[MAX_PATH] = _T(""); + char szMostPatched[MAX_PATH] = ""; + DWORD dwErrCode = ERROR_SUCCESS; + bool bIgnoreOpedwErrCodes = (dwSearchFlags & SEARCH_FLAG_IGNORE_ERRORS) ? true : false; + bool bFound = true; + int nMaxPatchCount = 0; + int nPatchCount = 0; + + // Construct the full name of the listfile + CreateFullPathName(szListFile, _countof(szListFile), szListFileDir, _T("ListFile_Blizzard.txt")); + + // Prepare hashing + md5_init(&md5state); + + // Initiate the MPQ search + pLogger->PrintProgress("Searching the archive (initializing) ..."); + hFind = SFileFindFirstFile(hMpq, "*", &sf, szListFile); + if(hFind == NULL) + { + dwErrCode = GetLastError(); + dwErrCode = (dwErrCode == ERROR_NO_MORE_FILES) ? ERROR_SUCCESS : dwErrCode; + return dwErrCode; + } + + // Perform the search + pLogger->PrintProgress("Searching the archive ..."); + while(bFound == true) + { + // Increment number of files + dwFileCount++; + +// if(!_stricmp(sf.cFileName, "war3map.j")) +// DebugBreak(); + + if(dwSearchFlags & SEARCH_FLAG_MOST_PATCHED) + { + // Load the patch count + nPatchCount = GetFilePatchCount(pLogger, hMpq, sf.cFileName); + + // Check if it's greater than maximum + if(nPatchCount > nMaxPatchCount) + { + strcpy(szMostPatched, sf.cFileName); + nMaxPatchCount = nPatchCount; + } + } + + // Load the file to memory, if required + if(dwSearchFlags & SEARCH_FLAG_LOAD_FILES) + { + // Load the entire file to the MPQ + pFileData = LoadMpqFile(pLogger, hMpq, sf.cFileName, sf.lcLocale, bIgnoreOpedwErrCodes); + if(pFileData != NULL) + { + // Hash the file data, if needed + if((dwSearchFlags & SEARCH_FLAG_HASH_FILES) && !IsInternalMpqFileName(sf.cFileName)) + md5_process(&md5state, pFileData->FileData, pFileData->dwFileSize); + + // Play sound files, if required + if((dwSearchFlags & SEARCH_FLAG_PLAY_WAVES) && strstr(sf.cFileName, ".wav") != NULL) + { +#ifdef _MSC_VER + pLogger->PrintProgress("Playing sound %s", sf.cFileName); + PlaySound((LPCTSTR)pFileData->FileData, NULL, SND_MEMORY); +#endif + } + + STORM_FREE(pFileData); + } + } + + bFound = SFileFindNextFile(hFind, &sf); + } + SFileFindClose(hFind); + + // Give the file count, if required + if(pdwFileCount != NULL) + pdwFileCount[0] = dwFileCount; + + // Give the hash, if required + if(pbFileHash != NULL && (dwSearchFlags & SEARCH_FLAG_HASH_FILES)) + md5_done(&md5state, pbFileHash); + + return dwErrCode; +} + +static DWORD CreateNewArchive(TLogHelper * pLogger, LPCTSTR szPlainName, DWORD dwCreateFlags, DWORD dwMaxFileCount, HANDLE * phMpq) +{ + HANDLE hMpq = NULL; + TCHAR szMpqName[MAX_PATH]; + TCHAR szFullPath[MAX_PATH]; + + // Make sure that the MPQ is deleted + CreateFullPathName(szFullPath, _countof(szFullPath), NULL, szPlainName); + _tremove(szFullPath); + + // Create the new MPQ + StringCopy(szMpqName, _countof(szMpqName), szFullPath); + if(!SFileCreateArchive(szMpqName, dwCreateFlags, dwMaxFileCount, &hMpq)) + return pLogger->PrintError(_T("Failed to create archive %s"), szMpqName); + + // Shall we close it right away? + if(phMpq == NULL) + SFileCloseArchive(hMpq); + else + *phMpq = hMpq; + + return ERROR_SUCCESS; +} + +static DWORD CreateNewArchive_V2(TLogHelper * pLogger, LPCTSTR szPlainName, DWORD dwCreateFlags, DWORD dwMaxFileCount, HANDLE * phMpq) +{ + SFILE_CREATE_MPQ CreateInfo; + HANDLE hMpq = NULL; + TCHAR szMpqName[MAX_PATH]; + TCHAR szFullPath[MAX_PATH]; + + // Make sure that the MPQ is deleted + CreateFullPathName(szFullPath, _countof(szFullPath), NULL, szPlainName); + StringCopy(szMpqName, _countof(szMpqName), szFullPath); + _tremove(szFullPath); + + // Fill the create structure + memset(&CreateInfo, 0, sizeof(SFILE_CREATE_MPQ)); + CreateInfo.cbSize = sizeof(SFILE_CREATE_MPQ); + CreateInfo.dwMpqVersion = (dwCreateFlags & MPQ_CREATE_ARCHIVE_VMASK) >> FLAGS_TO_FORMAT_SHIFT; + CreateInfo.dwStreamFlags = STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE; +// CreateInfo.dwFileFlags1 = (dwCreateFlags & MPQ_CREATE_LISTFILE) ? MPQ_FILE_EXISTS : 0; +// CreateInfo.dwFileFlags2 = (dwCreateFlags & MPQ_CREATE_ATTRIBUTES) ? MPQ_FILE_EXISTS : 0; + CreateInfo.dwFileFlags1 = (dwCreateFlags & MPQ_CREATE_LISTFILE) ? MPQ_FILE_DEFAULT_INTERNAL : 0; + CreateInfo.dwFileFlags2 = (dwCreateFlags & MPQ_CREATE_ATTRIBUTES) ? MPQ_FILE_DEFAULT_INTERNAL : 0; + CreateInfo.dwFileFlags3 = (dwCreateFlags & MPQ_CREATE_SIGNATURE) ? MPQ_FILE_DEFAULT_INTERNAL : 0; + CreateInfo.dwAttrFlags = (dwCreateFlags & MPQ_CREATE_ATTRIBUTES) ? (MPQ_ATTRIBUTE_CRC32 | MPQ_ATTRIBUTE_FILETIME | MPQ_ATTRIBUTE_MD5) : 0; + CreateInfo.dwSectorSize = (CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_3) ? 0x4000 : 0x1000; + CreateInfo.dwRawChunkSize = (CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_4) ? 0x4000 : 0; + CreateInfo.dwMaxFileCount = dwMaxFileCount; + + // Create the new MPQ + if(!SFileCreateArchive2(szMpqName, &CreateInfo, &hMpq)) + return pLogger->PrintError(_T("Failed to create archive %s"), szMpqName); + + // Shall we close it right away? + if(phMpq == NULL) + SFileCloseArchive(hMpq); + else + *phMpq = hMpq; + + return ERROR_SUCCESS; +} + +// Creates new archive with UNICODE name. Adds prefix to the name +static DWORD CreateNewArchiveU(TLogHelper * pLogger, const wchar_t * szPlainName, DWORD dwCreateFlags, DWORD dwMaxFileCount) +{ +#ifdef _UNICODE + HANDLE hMpq = NULL; + TCHAR szMpqName[MAX_PATH+1]; + TCHAR szFullPath[MAX_PATH]; + + // Construct the full UNICODE name + CreateFullPathName(szFullPath, _countof(szFullPath), NULL, _T("StormLibTest_")); + StringCopy(szMpqName, _countof(szMpqName), szFullPath); + StringCat(szMpqName, _countof(szMpqName), szPlainName); + + // Make sure that the MPQ is deleted + _tremove(szMpqName); + + // Create the archive + pLogger->PrintProgress("Creating new archive with UNICODE name ..."); + if(!SFileCreateArchive(szMpqName, dwCreateFlags, dwMaxFileCount, &hMpq)) + return pLogger->PrintError(_T("Failed to create archive %s"), szMpqName); + + SFileCloseArchive(hMpq); +#else + pLogger = pLogger; + szPlainName = szPlainName; + dwCreateFlags = dwCreateFlags; + dwMaxFileCount = dwMaxFileCount; +#endif + return ERROR_SUCCESS; +} + +static DWORD OpenExistingArchive(TLogHelper * pLogger, LPCTSTR szFullPath, DWORD dwFlags, HANDLE * phMpq) +{ + HANDLE hMpq = NULL; +// bool bReopenResult; + DWORD dwErrCode = ERROR_SUCCESS; + + // Is it an encrypted MPQ ? + if(_tcsstr(szFullPath, _T(".MPQE")) != NULL) + dwFlags |= STREAM_PROVIDER_MPQE; + if(_tcsstr(szFullPath, _T(".MPQ.part")) != NULL) + dwFlags |= STREAM_PROVIDER_PARTIAL; + if(_tcsstr(szFullPath, _T(".mpq.part")) != NULL) + dwFlags |= STREAM_PROVIDER_PARTIAL; + if(_tcsstr(szFullPath, _T(".MPQ.0")) != NULL) + dwFlags |= STREAM_PROVIDER_BLOCK4; + + // Open the copied archive + pLogger->PrintProgress(_T("Opening archive %s ..."), GetShortPlainName(szFullPath)); + if(!SFileOpenArchive(szFullPath, 0, dwFlags, &hMpq)) + { + switch(dwErrCode = GetLastError()) + { +// case ERROR_BAD_FORMAT: // If the error is ERROR_BAD_FORMAT, try to open with MPQ_OPEN_FORCE_MPQ_V1 +// bReopenResult = SFileOpenArchive(szMpqName, 0, dwFlags | MPQ_OPEN_FORCE_MPQ_V1, &hMpq); +// dwErrCode = (bReopenResult == false) ? GetLastError() : ERROR_SUCCESS; +// break; + + case ERROR_AVI_FILE: // Ignore the error if it's an AVI file or if the file is incomplete + case ERROR_FILE_INCOMPLETE: + return dwErrCode; + } + + // Show the open error to the user + return pLogger->PrintError(_T("Failed to open archive %s"), szFullPath); + } + + // Store the archive handle or close the archive + if(phMpq == NULL) + SFileCloseArchive(hMpq); + else + *phMpq = hMpq; + return dwErrCode; +} + +static DWORD OpenPatchArchive(TLogHelper * pLogger, HANDLE hMpq, LPCTSTR szFullPath) +{ + TCHAR szPatchName[MAX_PATH]; + DWORD dwErrCode = ERROR_SUCCESS; + + pLogger->PrintProgress(_T("Adding patch %s ..."), GetShortPlainName(szFullPath)); + StringCopy(szPatchName, _countof(szPatchName), szFullPath); + if(!SFileOpenPatchArchive(hMpq, szPatchName, NULL, 0)) + dwErrCode = pLogger->PrintError(_T("Failed to add patch %s ..."), szFullPath); + + return dwErrCode; +} + +static DWORD OpenExistingArchiveWithCopy(TLogHelper * pLogger, LPCTSTR szFileName, LPCTSTR szCopyName, HANDLE * phMpq) +{ + DWORD dwFlags = 0; + TCHAR szFullPath[MAX_PATH]; + DWORD dwErrCode = ERROR_SUCCESS; + + // We expect MPQ directory to be already prepared by InitializeMpqDirectory + assert(szMpqDirectory[0] != 0); + + // At least one name must be entered + assert(szFileName != NULL || szCopyName != NULL); + + // If both names entered, create a copy + if(szFileName != NULL && szCopyName != NULL) + { + dwErrCode = CreateFileCopy(pLogger, szFileName, szCopyName, szFullPath, _countof(szFullPath)); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + } + + // If only source name entered, open it for read-only access + else if(szFileName != NULL && szCopyName == NULL) + { + CreateFullPathName(szFullPath, _countof(szFullPath), szMpqSubDir, szFileName); + dwFlags |= MPQ_OPEN_READ_ONLY; + } + + // If only target name entered, open it directly + else if(szFileName == NULL && szCopyName != NULL) + { + CreateFullPathName(szFullPath, _countof(szFullPath), NULL, szCopyName); + } + + // Open the archive + return OpenExistingArchive(pLogger, szFullPath, dwFlags, phMpq); +} + +static DWORD OpenPatchedArchive(TLogHelper * pLogger, HANDLE * phMpq, LPCTSTR PatchList[]) +{ + HANDLE hMpq = NULL; + TCHAR szFullPath[MAX_PATH]; + DWORD dwErrCode = ERROR_SUCCESS; + + // The first file is expected to be valid + assert(PatchList[0] != NULL); + + // Open the primary MPQ + CreateFullPathName(szFullPath, _countof(szFullPath), szMpqSubDir, PatchList[0]); + dwErrCode = OpenExistingArchive(pLogger, szFullPath, MPQ_OPEN_READ_ONLY, &hMpq); + + // Add all patches + if(dwErrCode == ERROR_SUCCESS) + { + for(size_t i = 1; PatchList[i] != NULL; i++) + { + CreateFullPathName(szFullPath, _countof(szFullPath), szMpqPatchDir, PatchList[i]); + dwErrCode = OpenPatchArchive(pLogger, hMpq, szFullPath); + if(dwErrCode != ERROR_SUCCESS) + break; + } + } + + // If anything failed, close the MPQ handle + if(dwErrCode != ERROR_SUCCESS) + { + SFileCloseArchive(hMpq); + hMpq = NULL; + } + + // Give the archive handle to the caller + if(phMpq != NULL) + *phMpq = hMpq; + return dwErrCode; +} + +static DWORD AddFileToMpq( + TLogHelper * pLogger, + HANDLE hMpq, + LPCSTR szFileName, + LPCSTR szFileData, + DWORD dwFlags = 0, + DWORD dwCompression = 0, + DWORD dwExpectedError = ERROR_SUCCESS) +{ + HANDLE hFile = NULL; + DWORD dwFileSize = (DWORD)strlen(szFileData); + DWORD dwErrCode = ERROR_SUCCESS; + + // Notify the user + pLogger->PrintProgress("Adding file %s ...", szFileName); + + // Get the default flags + if(dwFlags == 0) + dwFlags = MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED; + if(dwCompression == 0) + dwCompression = MPQ_COMPRESSION_ZLIB; + + // Create the file within the MPQ + if(SFileCreateFile(hMpq, szFileName, 0, dwFileSize, 0, dwFlags, &hFile)) + { + // Write the file + if(!SFileWriteFile(hFile, szFileData, dwFileSize, dwCompression)) + dwErrCode = pLogger->PrintError("Failed to write data to the MPQ"); + SFileCloseFile(hFile); + } + else + { + dwErrCode = GetLastError(); + } + + // Check the expected error code + if(dwExpectedError != ERROR_UNDETERMINED_RESULT && dwErrCode != dwExpectedError) + return pLogger->PrintError("Unexpected result from SFileCreateFile(%s)", szFileName); + return dwErrCode; +} + +static DWORD AddLocalFileToMpq( + TLogHelper * pLogger, + HANDLE hMpq, + LPCSTR szArchivedName, + LPCTSTR szLocalFileName, + DWORD dwFlags = 0, + DWORD dwCompression = 0, + bool bMustSucceed = false) +{ + TCHAR szFileName[MAX_PATH]; + DWORD dwVerifyResult; + + // Notify the user + pLogger->PrintProgress("Adding file %s (%u of %u)...", GetShortPlainName(szLocalFileName), pLogger->UserCount, pLogger->UserTotal); + pLogger->UserString = szArchivedName; + + // Get the default flags + if(dwFlags == 0) + dwFlags = MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED; + if(dwCompression == 0) + dwCompression = MPQ_COMPRESSION_ZLIB; + + // Set the notification callback + SFileSetAddFileCallback(hMpq, AddFileCallback, pLogger); + + // Add the file to the MPQ + StringCopy(szFileName, _countof(szFileName), szLocalFileName); + if(!SFileAddFileEx(hMpq, szFileName, szArchivedName, dwFlags, dwCompression, MPQ_COMPRESSION_NEXT_SAME)) + { + if(bMustSucceed) + return pLogger->PrintError("Failed to add the file %s", szArchivedName); + return GetLastError(); + } + + // Verify the file unless it was lossy compression + if((dwCompression & (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO)) == 0) + { + // Notify the user + pLogger->PrintProgress("Verifying file %s (%u of %u) ...", szArchivedName, pLogger->UserCount, pLogger->UserTotal); + + // Perform the verification + dwVerifyResult = SFileVerifyFile(hMpq, szArchivedName, MPQ_ATTRIBUTE_CRC32 | MPQ_ATTRIBUTE_MD5); + if(dwVerifyResult & (VERIFY_OPEN_ERROR | VERIFY_READ_ERROR | VERIFY_FILE_SECTOR_CRC_ERROR | VERIFY_FILE_CHECKSUM_ERROR | VERIFY_FILE_MD5_ERROR)) + return pLogger->PrintError("CRC error on %s", szArchivedName); + } + + return ERROR_SUCCESS; +} + +static DWORD RenameMpqFile(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szOldFileName, LPCSTR szNewFileName, DWORD dwExpectedError) +{ + DWORD dwErrCode = ERROR_SUCCESS; + + // Notify the user + pLogger->PrintProgress("Renaming %s to %s ...", szOldFileName, szNewFileName); + + // Perform the deletion + if(!SFileRenameFile(hMpq, szOldFileName, szNewFileName)) + dwErrCode = GetLastError(); + + if(dwErrCode != dwExpectedError) + return pLogger->PrintErrorVa("Unexpected result from SFileRenameFile(%s -> %s)", szOldFileName, szNewFileName); + return ERROR_SUCCESS; +} + +static DWORD RemoveMpqFile(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileName, DWORD dwExpectedError) +{ + DWORD dwErrCode = ERROR_SUCCESS; + + // Notify the user + pLogger->PrintProgress("Removing file %s ...", szFileName); + + // Perform the deletion + if(!SFileRemoveFile(hMpq, szFileName, 0)) + dwErrCode = GetLastError(); + + if(dwErrCode != dwExpectedError) + return pLogger->PrintError("Unexpected result from SFileRemoveFile(%s)", szFileName); + return ERROR_SUCCESS; +} + +static ULONGLONG SFileGetFilePointer(HANDLE hFile) +{ + LONG FilePosHi = 0; + DWORD FilePosLo; + + FilePosLo = SFileSetFilePointer(hFile, 0, &FilePosHi, FILE_CURRENT); + return MAKE_OFFSET64(FilePosHi, FilePosLo); +} + +//----------------------------------------------------------------------------- +// Tests + +static DWORD TestSetFilePointer( + HANDLE hFile, + LONGLONG DeltaPos, + ULONGLONG ExpectedPos, + DWORD dwMoveMethod, + bool bUseFilePosHigh, + DWORD dwErrCode) +{ + ULONGLONG NewPos = 0; + LONG DeltaPosHi = (LONG)(DeltaPos >> 32); + LONG DeltaPosLo = (LONG)(DeltaPos); + + // If there was an error before, do nothing + if(dwErrCode == ERROR_SUCCESS) + { + SFileSetFilePointer(hFile, DeltaPosLo, bUseFilePosHigh ? &DeltaPosHi : NULL, dwMoveMethod); + NewPos = SFileGetFilePointer(hFile); + if(NewPos != ExpectedPos) + dwErrCode = ERROR_HANDLE_EOF; + } + + return dwErrCode; +} + +static DWORD TestSetFilePointers(HANDLE hFile, bool bUseFilePosHigh) +{ + LONGLONG FileSize; + DWORD dwErrCode = ERROR_SUCCESS; + + // We expect the file to be at least 2 pages long + FileSize = SFileGetFileSize(hFile, NULL); + if(FileSize < 0x2000) + return ERROR_NOT_SUPPORTED; + + // Move 0x20 bytes from the beginning. Expected new pos is 0x20 + dwErrCode = TestSetFilePointer(hFile, 0x20, 0x20, FILE_BEGIN, bUseFilePosHigh, dwErrCode); + + // Move 0x20 bytes from the current position. Expected new pos is 0x20 + dwErrCode = TestSetFilePointer(hFile, 0x20, 0x40, FILE_CURRENT, bUseFilePosHigh, dwErrCode); + + // Move 0x40 bytes back. Because the offset can't be moved to negative position, it will be zero + dwErrCode = TestSetFilePointer(hFile, -64, 0x00, FILE_CURRENT, bUseFilePosHigh, dwErrCode); + + // Move 0x40 bytes before the end of the file + dwErrCode = TestSetFilePointer(hFile, -64, FileSize-64, FILE_END, bUseFilePosHigh, dwErrCode); + + // Move 0x80 bytes forward. Should be at end of file + dwErrCode = TestSetFilePointer(hFile, 0x80, FileSize, FILE_CURRENT, bUseFilePosHigh, dwErrCode); + + return dwErrCode; +} + + +static void TestGetFileInfo( + TLogHelper * pLogger, + HANDLE hMpqOrFile, + SFileInfoClass InfoClass, + void * pvFileInfo, + DWORD cbFileInfo, + DWORD * pcbLengthNeeded, + bool bExpectedResult, + DWORD dwExpectedErrCode) +{ + DWORD dwErrCode = ERROR_SUCCESS; + bool bResult; + + // Call the get file info + bResult = SFileGetFileInfo(hMpqOrFile, InfoClass, pvFileInfo, cbFileInfo, pcbLengthNeeded); + if(!bResult) + dwErrCode = GetLastError(); + + if(bResult != bExpectedResult) + pLogger->PrintMessage("Different result of SFileGetFileInfo."); + if(dwErrCode != dwExpectedErrCode) + pLogger->PrintMessage("Different error from SFileGetFileInfo (expected %u, returned %u)", dwExpectedErrCode, dwErrCode); +} + +// StormLib is able to open local files (as well as the original Storm.dll) +// I want to keep this for occasional use + +static LINE_INFO Lines[] = +{ + {0x000, 18, "accountbilling.url"}, + {0x013, 45, "alternate/character/goblin/male/goblinmale.m2"}, + {0x9ab, 54, "alternate/character/goblin/male/goblinmale0186-00.anim"} +}; + +static DWORD TestOnLocalListFile_Read(TLogHelper & Logger, HANDLE hFile) +{ + for(size_t i = 0; i < _countof(Lines); i++) + { + DWORD dwBytesRead = 0; + char szFileLine[0x100] = {0}; + + SFileSetFilePointer(hFile, Lines[i].nLinePos, NULL, FILE_BEGIN); + SFileReadFile(hFile, szFileLine, Lines[i].nLineLen, &dwBytesRead, NULL); + + if(dwBytesRead != Lines[i].nLineLen) + { + Logger.PrintMessage("Line %u length mismatch", i); + return false; + } + + if(strcmp(szFileLine, Lines[i].szLine)) + { + Logger.PrintMessage("Line %u content mismatch", i); + return false; + } + } + + return true; +} + +static DWORD TestOnLocalListFile(LPCTSTR szPlainName) +{ + TLogHelper Logger("LocalListFile", szPlainName); + SFILE_FIND_DATA sf; + HANDLE hFile; + HANDLE hFind; + DWORD dwFileSizeHi = 0; + DWORD dwFileSizeLo = 0; + TCHAR szFullPath[MAX_PATH]; + char szFileName1[MAX_PATH]; + char szFileName2[MAX_PATH]; + int nFileCount = 0; + + // Get the full name of the local file + CreateFullPathName(szFileName1, _countof(szFileName1), szMpqSubDir, szPlainName); + + // Test opening the local file + if(SFileOpenFileEx(NULL, szFileName1, SFILE_OPEN_LOCAL_FILE, &hFile)) + { + // Retrieve the file name. It must match the name under which the file was open + if(FileStream_Prefix(szPlainName, NULL) == 0) + { + SFileGetFileName(hFile, szFileName2); + if(strcmp(szFileName2, szFileName1)) + Logger.PrintMessage("The retrieved name does not match the open name"); + } + + // Retrieve the file size + dwFileSizeLo = SFileGetFileSize(hFile, &dwFileSizeHi); + if(dwFileSizeHi != 0 || dwFileSizeLo != 0x04385a4e) + Logger.PrintMessage("Local file size mismatch"); + + // Read few lines, check their content + TestOnLocalListFile_Read(Logger, hFile); + SFileCloseFile(hFile); + } + else + return Logger.PrintError("Failed to open local listfile"); + + // We need unicode listfile name + StringCopy(szFullPath, _countof(szFullPath), szFileName1); + + // Start searching in the listfile + hFind = SListFileFindFirstFile(NULL, szFullPath, "*", &sf); + if(hFind != NULL) + { + for(;;) + { + Logger.PrintProgress("Found file (%04u): %s", nFileCount++, GetShortPlainName(sf.cFileName)); + if(!SListFileFindNextFile(hFind, &sf)) + break; + } + + SListFileFindClose(hFind); + } + else + return Logger.PrintError("Failed to search local listfile"); + + return ERROR_SUCCESS; +} + +static void WINAPI TestReadFile_DownloadCallback( + void * UserData, + ULONGLONG ByteOffset, + DWORD DataLength) +{ + TLogHelper * pLogger = (TLogHelper *)UserData; + + if(ByteOffset != 0 && DataLength != 0) + pLogger->PrintProgress("Downloading data (offset: " I64X_a ", length: %X)", ByteOffset, DataLength); + else + pLogger->PrintProgress("Download complete."); +} + +// Open a file stream with mirroring a master file +static DWORD TestReadFile_MasterMirror(LPCTSTR szMirrorName, LPCTSTR szMasterName, bool bCopyMirrorFile) +{ + TFileStream * pStream1; // Master file + TFileStream * pStream2; // Mirror file + TLogHelper Logger("OpenMirrorFile", szMirrorName); + TCHAR szMirrorPath[MAX_PATH + MAX_PATH]; + TCHAR szMasterPath[MAX_PATH]; + DWORD dwProvider = 0; + int nIterations = 0x10000; + DWORD dwErrCode; + + // Retrieve the provider + FileStream_Prefix(szMasterName, &dwProvider); + +#ifndef STORMLIB_WINDOWS + if((dwProvider & BASE_PROVIDER_MASK) == BASE_PROVIDER_HTTP) + return ERROR_SUCCESS; +#endif + + // Create copy of the file to serve as mirror, keep master there + dwErrCode = CreateMasterAndMirrorPaths(&Logger, szMirrorPath, szMasterPath, szMirrorName, szMasterName, bCopyMirrorFile); + if(dwErrCode == ERROR_SUCCESS) + { + // Open both master and mirror file + pStream1 = FileStream_OpenFile(szMasterPath, STREAM_FLAG_READ_ONLY); + pStream2 = FileStream_OpenFile(szMirrorPath, STREAM_FLAG_READ_ONLY | STREAM_FLAG_USE_BITMAP); + if(pStream1 && pStream2) + { + // For internet based files, we limit the number of operations + if((dwProvider & BASE_PROVIDER_MASK) == BASE_PROVIDER_HTTP) + nIterations = 0x80; + + FileStream_SetCallback(pStream2, TestReadFile_DownloadCallback, &Logger); + dwErrCode = CompareTwoLocalFilesRR(&Logger, pStream1, pStream2, nIterations); + } + + if(pStream2 != NULL) + FileStream_Close(pStream2); + if(pStream1 != NULL) + FileStream_Close(pStream1); + } + + return dwErrCode; +} + +// Test of the TFileStream object +static DWORD TestFileStreamOperations(LPCTSTR szPlainName, DWORD dwStreamFlags) +{ + TFileStream * pStream = NULL; + TLogHelper Logger("FileStreamTest", szPlainName); + ULONGLONG ByteOffset; + ULONGLONG FileSize = 0; + TCHAR szFullPath[MAX_PATH]; + DWORD dwRequiredFlags = 0; + BYTE Buffer[0x10]; + DWORD dwErrCode = ERROR_SUCCESS; + + // Copy the file so we won't screw up + if((dwStreamFlags & STREAM_PROVIDER_MASK) == STREAM_PROVIDER_BLOCK4) + CreateFullPathName(szFullPath, _countof(szFullPath), szMpqSubDir, szPlainName); + else + dwErrCode = CreateFileCopy(&Logger, szPlainName, szPlainName, szFullPath, _countof(szFullPath)); + + // Open the file stream + if(dwErrCode == ERROR_SUCCESS) + { + pStream = FileStream_OpenFile(szFullPath, dwStreamFlags); + if(pStream == NULL) + return Logger.PrintError(_T("Open failed: %s"), szFullPath); + } + + // Get the size of the file stream + if(dwErrCode == ERROR_SUCCESS) + { + if(!FileStream_GetFlags(pStream, &dwStreamFlags)) + dwErrCode = Logger.PrintError("Failed to retrieve the stream flags"); + + if(!FileStream_GetSize(pStream, &FileSize)) + dwErrCode = Logger.PrintError("Failed to retrieve the file size"); + + // Any other stream except STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE should be read-only + if((dwStreamFlags & STREAM_PROVIDERS_MASK) != (STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE)) + dwRequiredFlags |= STREAM_FLAG_READ_ONLY; +// if(pStream->BlockPresent) +// dwRequiredFlags |= STREAM_FLAG_READ_ONLY; + + // Check the flags there + if((dwStreamFlags & dwRequiredFlags) != dwRequiredFlags) + { + Logger.PrintMessage("The stream should be read-only but it isn't"); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + + // After successful open, the stream position must be zero + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = VerifyFilePosition(&Logger, pStream, 0); + + // Read the MPQ header from the current file offset. + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = VerifyFileMpqHeader(&Logger, pStream, NULL); + + // After successful open, the stream position must sizeof(TMPQHeader) + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = VerifyFilePosition(&Logger, pStream, sizeof(TMPQHeader)); + + // Now try to read the MPQ header from the offset 0 + if(dwErrCode == ERROR_SUCCESS) + { + ByteOffset = 0; + dwErrCode = VerifyFileMpqHeader(&Logger, pStream, &ByteOffset); + } + + // After successful open, the stream position must sizeof(TMPQHeader) + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = VerifyFilePosition(&Logger, pStream, sizeof(TMPQHeader)); + + // Try a write operation + if(dwErrCode == ERROR_SUCCESS) + { + bool bExpectedResult = (dwStreamFlags & STREAM_FLAG_READ_ONLY) ? false : true; + bool bResult; + + // Attempt to write to the file + ByteOffset = 0; + bResult = FileStream_Write(pStream, &ByteOffset, Buffer, sizeof(Buffer)); + + // If the result is not expected + if(bResult != bExpectedResult) + { + Logger.PrintMessage("FileStream_Write result is different than expected"); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + + // Move the position 9 bytes from the end and try to read 10 bytes. + // This must fail, because stream reading functions are "all or nothing" + if(dwErrCode == ERROR_SUCCESS) + { + ByteOffset = FileSize - 9; + if(FileStream_Read(pStream, &ByteOffset, Buffer, 10)) + { + Logger.PrintMessage("FileStream_Read succeeded, but it shouldn't"); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + + // Try again with 9 bytes. This must succeed, unless the file block is not available + if(dwErrCode == ERROR_SUCCESS) + { + ByteOffset = FileSize - 9; + if(!FileStream_Read(pStream, &ByteOffset, Buffer, 9)) + { + Logger.PrintMessage("FileStream_Read from the end of the file failed"); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + + // Verify file position - it must be at the end of the file + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = VerifyFilePosition(&Logger, pStream, FileSize); + + // Close the stream + if(pStream != NULL) + FileStream_Close(pStream); + return dwErrCode; +} + +static DWORD TestArchive_LoadFiles(TLogHelper * pLogger, HANDLE hMpq, bool bIgnoreOpedwErrCodes, ...) +{ + TFileData * pFileData; + const char * szFileName; + va_list argList; + DWORD dwErrCode = ERROR_SUCCESS; + + va_start(argList, bIgnoreOpedwErrCodes); + while((szFileName = va_arg(argList, const char *)) != NULL) + { + if(SFileHasFile(hMpq, szFileName)) + { + pFileData = LoadMpqFile(pLogger, hMpq, szFileName); + if(pFileData == NULL && bIgnoreOpedwErrCodes == false) + { + pLogger->PrintError("Error loading the file %s", szFileName); + dwErrCode = ERROR_FILE_CORRUPT; + break; + } + else + { + STORM_FREE(pFileData); + pFileData = NULL; + } + } + } + va_end(argList); + + return dwErrCode; +} + +static DWORD TestArchive_SetPos(HANDLE hMpq, const char * szFileName) +{ + HANDLE hFile = NULL; + DWORD dwErrCode = ERROR_SUCCESS; + + if(SFileOpenFileEx(hMpq, szFileName, 0, &hFile)) + { + // First, use the SFileSetFilePointer WITHOUT the high-dword position + dwErrCode = TestSetFilePointers(hFile, false); + + // First, use the SFileSetFilePointer WITH the high-dword position + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestSetFilePointers(hFile, true); + + // Close the file + SFileCloseFile(hFile); + } + + return dwErrCode; +} + +static DWORD TestArchive( + LPCTSTR szPlainName, // Plain name of the MPQ + LPCTSTR szListFile, // Listfile name (NULL if none) + DWORD dwFlags, // Flags + LPCSTR szFileName1, + LPCSTR szFileName2) +{ + TFileData * pFileData1 = NULL; + TFileData * pFileData2 = NULL; + TLogHelper Logger("TestMpq", szPlainName); + LPCSTR szExpectedMD5 = NULL; + HANDLE hMpq = NULL; + DWORD dwFileCount = 0; + DWORD dwSearchFlags = 0; + DWORD dwErrCode; + DWORD dwCrc32 = 0; + DWORD dwExpectedFileCount = 0; + DWORD dwMpqFlags = 0; + TCHAR szFullName[MAX_PATH]; + BYTE ExpectedMD5[MD5_DIGEST_SIZE]; + BYTE OverallMD5[MD5_DIGEST_SIZE]; + bool bIgnoreOpedwErrCodes = false; + + // If the file is a partial MPQ, don't load all files + if(_tcsstr(szPlainName, _T(".MPQ.part")) == NULL) + dwSearchFlags |= SEARCH_FLAG_LOAD_FILES; + + // If the MPQ is a protected MPQ, do different tests + if(dwFlags & TEST_FLAG_PROTECTED) + { + dwExpectedFileCount = (dwFlags & TEST_FLAG_FILE_COUNT); + if((szExpectedMD5 = szFileName1) != NULL) + dwSearchFlags |= SEARCH_FLAG_HASH_FILES; + szFileName2 = szFileName1 = NULL; + } + + // Copy the archive so we won't fuck up the original one + dwErrCode = OpenExistingArchiveWithCopy(&Logger, szPlainName, NULL, &hMpq); + while(dwErrCode == ERROR_SUCCESS) + { + // Check for malformed MPQs + SFileGetFileInfo(hMpq, SFileMpqFlags, &dwMpqFlags, sizeof(dwMpqFlags), NULL); + if(dwMpqFlags & MPQ_FLAG_MALFORMED) + { + dwSearchFlags |= SEARCH_FLAG_IGNORE_ERRORS; + bIgnoreOpedwErrCodes = true; + } + + // If the listfile was given, add it to the MPQ + if(szListFile && szListFile[0]) + { + Logger.PrintProgress(_T("Adding listfile %s ..."), szListFile); + CreateFullPathName(szFullName, _countof(szFullName), szListFileDir, szListFile); + if((dwErrCode = SFileAddListFile(hMpq, szFullName)) != ERROR_SUCCESS) + Logger.PrintMessage("Failed to add the listfile to the MPQ"); + } + + // Attempt to open the (listfile), (attributes), (signature) + dwErrCode = TestArchive_LoadFiles(&Logger, hMpq, bIgnoreOpedwErrCodes, LISTFILE_NAME, ATTRIBUTES_NAME, SIGNATURE_NAME, NULL); + if(dwErrCode != ERROR_SUCCESS) + break; + + // If szFileName1 was given, load it and check its CRC + if(szFileName1 && szFileName1[0]) + { + // Test setting position + dwErrCode = TestArchive_SetPos(hMpq, szFileName1); + if(dwErrCode != ERROR_SUCCESS) + break; + + // Load the entire file 1 + pFileData1 = LoadMpqFile(&Logger, hMpq, szFileName1); + if(pFileData1 == NULL) + { + dwErrCode = Logger.PrintError("Failed to load the file %s", szFileName1); + break; + } + + // Check the CRC of file1, if available + if(pFileData1->dwCrc32) + { + // Compare the CRC32, if available + dwCrc32 = crc32(0, (Bytef *)pFileData1->FileData, (uInt)pFileData1->dwFileSize); + if(dwCrc32 != pFileData1->dwCrc32) + Logger.PrintError("Warning: CRC32 error on %s", szFileName1); + } + } + + // If szFileName2 was given, load it + if(szFileName2 && szFileName2[0]) + { + // Load the entire file 2 + pFileData2 = LoadMpqFile(&Logger, hMpq, szFileName2); + if(pFileData2 == NULL) + { + dwErrCode = Logger.PrintError("Failed to load the file %s", szFileName2); + break; + } + } + + // If two files were given, compare them + if(pFileData1 && pFileData2) + { + // Compare both files + if(!CompareTwoFiles(&Logger, pFileData1, pFileData2)) + { + dwErrCode = Logger.PrintError("The file has different size/content of files"); + break; + } + } + + // Search the archive + dwErrCode = SearchArchive(&Logger, hMpq, dwSearchFlags, &dwFileCount, OverallMD5); + + // Shall we check the file count and overall MD5? + if(dwExpectedFileCount != 0) + { + if(dwFileCount != dwExpectedFileCount) + { + Logger.PrintMessage("File count mismatch(expected: %u, found:%u)", dwExpectedFileCount, dwFileCount); + dwErrCode = ERROR_CAN_NOT_COMPLETE; + break; + } + } + + // Shall we check overall MD5? + if(szExpectedMD5 && szExpectedMD5[0]) + { + BinaryFromString(szExpectedMD5, ExpectedMD5, MD5_DIGEST_SIZE); + if(memcmp(ExpectedMD5, OverallMD5, MD5_DIGEST_SIZE)) + { + Logger.PrintMessage("Extracted files MD5 mismatch"); + dwErrCode = ERROR_CAN_NOT_COMPLETE; + break; + } + } + break; + } + + // Common cleanup + if(pFileData2 != NULL) + STORM_FREE(pFileData2); + if(pFileData1 != NULL) + STORM_FREE(pFileData1); + if(hMpq != NULL) + SFileCloseArchive(hMpq); + return dwErrCode; +} + +// Open an empty archive (found in WoW cache - it's just a header) +static DWORD TestOpenArchive_WillFail(LPCTSTR szPlainName) +{ + TLogHelper Logger("FailMpqTest", szPlainName); + HANDLE hMpq = NULL; + TCHAR szMpqName[MAX_PATH]; + char szFullPath[MAX_PATH]; + + // Create the full path name for the archive + CreateFullPathName(szFullPath, _countof(szFullPath), szMpqSubDir, szPlainName); + StringCopy(szMpqName, _countof(szFullPath), szFullPath); + + // Try to open the archive. It is expected to fail + Logger.PrintProgress("Opening archive %s", szPlainName); + if(!SFileOpenArchive(szMpqName, 0, MPQ_OPEN_READ_ONLY, &hMpq)) + return ERROR_SUCCESS; + + Logger.PrintError(_T("Archive %s succeeded to open, even if it should not."), szPlainName); + SFileCloseArchive(hMpq); + return ERROR_CAN_NOT_COMPLETE; +} + +static DWORD TestOpenArchive_Corrupt(LPCTSTR szPlainName) +{ + TLogHelper Logger("OpenCorruptMpqTest", szPlainName); + HANDLE hMpq = NULL; + TCHAR szFullPath[MAX_PATH]; + + // Copy the archive so we won't fuck up the original one + CreateFullPathName(szFullPath, _countof(szFullPath), szMpqSubDir, szPlainName); + if(SFileOpenArchive(szFullPath, 0, STREAM_FLAG_READ_ONLY, &hMpq)) + { + SFileCloseArchive(hMpq); + Logger.PrintMessage(_T("Opening archive %s succeeded, but it shouldn't"), szFullPath); + return ERROR_CAN_NOT_COMPLETE; + } + + return ERROR_SUCCESS; +} + + +// Opens a patched MPQ archive +static DWORD TestOpenArchive_Patched(LPCTSTR PatchList[], LPCSTR szPatchedFile, int nExpectedPatchCount, bool bExpectedToFail = false) +{ + TLogHelper Logger("OpenPatchedMpqTest", PatchList[0]); + HANDLE hMpq; + HANDLE hFile; + BYTE Buffer[0x100]; + DWORD dwFileCount = 0; + DWORD BytesRead = 0; + DWORD dwErrCode; + + // Open a patched MPQ archive + dwErrCode = OpenPatchedArchive(&Logger, &hMpq, PatchList); + if(dwErrCode == ERROR_SUCCESS) + { + // Check patch count + if(szPatchedFile != NULL) + dwErrCode = VerifyFilePatchCount(&Logger, hMpq, szPatchedFile, nExpectedPatchCount); + + // Try to open and read the file + if(dwErrCode == ERROR_SUCCESS) + { + if(SFileOpenFileEx(hMpq, szPatchedFile, 0, &hFile)) + { + SFileReadFile(hFile, Buffer, sizeof(Buffer), &BytesRead, NULL); + SFileCloseFile(hFile); + } + } + + // Search the archive and load every file + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = SearchArchive(&Logger, hMpq, SEARCH_FLAG_LOAD_FILES | SEARCH_FLAG_IGNORE_ERRORS, &dwFileCount); + + // Close the archive + SFileCloseArchive(hMpq); + } + + // Clear the error if patch prefix was not found + if(dwErrCode == ERROR_CANT_FIND_PATCH_PREFIX && bExpectedToFail) + dwErrCode = ERROR_SUCCESS; + return dwErrCode; +} + +// Open an archive for read-only access +static DWORD TestOpenArchive_ReadOnly(LPCTSTR szPlainName, bool bReadOnly) +{ + TLogHelper Logger("ReadOnlyTest", szPlainName); + LPCTSTR szCopyName; + HANDLE hMpq = NULL; + TCHAR szFullPath[MAX_PATH]; + DWORD dwFlags = bReadOnly ? MPQ_OPEN_READ_ONLY : 0;; + int nExpectedError; + DWORD dwErrCode; + + // Copy the fiel so we wont screw up something + szCopyName = bReadOnly ? _T("StormLibTest_ReadOnly.mpq") : _T("StormLibTest_ReadWrite.mpq"); + dwErrCode = CreateFileCopy(&Logger, szPlainName, szCopyName, szFullPath, _countof(szFullPath)); + + // Now open the archive for read-only access + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = OpenExistingArchive(&Logger, szFullPath, dwFlags, &hMpq); + + // Now try to add a file. This must fail if the MPQ is read only + if(dwErrCode == ERROR_SUCCESS) + { + nExpectedError = (bReadOnly) ? ERROR_ACCESS_DENIED : ERROR_SUCCESS; + AddFileToMpq(&Logger, hMpq, "AddedFile.txt", "This is an added file.", MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED, 0, nExpectedError); + } + + // Now try to rename a file in the MPQ. This must only succeed if the MPQ is not read only + if(dwErrCode == ERROR_SUCCESS) + { + nExpectedError = (bReadOnly) ? ERROR_ACCESS_DENIED : ERROR_SUCCESS; + RenameMpqFile(&Logger, hMpq, "spawn.mpq", "spawn-renamed.mpq", nExpectedError); + } + + // Now try to delete a file in the MPQ. This must only succeed if the MPQ is not read only + if(dwErrCode == ERROR_SUCCESS) + { + nExpectedError = (bReadOnly) ? ERROR_ACCESS_DENIED : ERROR_SUCCESS; + RemoveMpqFile(&Logger, hMpq, "spawn-renamed.mpq", nExpectedError); + } + + // Close the archive + if(hMpq != NULL) + SFileCloseArchive(hMpq); + return dwErrCode; +} + +static DWORD TestOpenArchive_GetFileInfo(LPCTSTR szPlainName1, LPCTSTR szPlainName4) +{ + TLogHelper Logger("GetFileInfoTest", szPlainName1, szPlainName4); + HANDLE hFile; + HANDLE hMpq4; + HANDLE hMpq1; + DWORD cbLength; + BYTE DataBuff[0x400]; + DWORD dwErrCode1; + DWORD dwErrCode4; + + // Copy the archive so we won't fuck up the original one + dwErrCode1 = OpenExistingArchiveWithCopy(&Logger, szPlainName1, NULL, &hMpq1); + dwErrCode4 = OpenExistingArchiveWithCopy(&Logger, szPlainName4, NULL, &hMpq4); + if(dwErrCode1 == ERROR_SUCCESS && dwErrCode4 == ERROR_SUCCESS) + { + // Invalid handle - expected (false, ERROR_INVALID_HANDLE) + TestGetFileInfo(&Logger, NULL, SFileMpqBetHeader, NULL, 0, NULL, false, ERROR_INVALID_HANDLE); + + // Valid handle but invalid value of file info class (false, ERROR_INVALID_PARAMETER) + TestGetFileInfo(&Logger, NULL, (SFileInfoClass)0xFFF, NULL, 0, NULL, false, ERROR_INVALID_HANDLE); + + // Invalid archive handle and file info class is for file (false, ERROR_INVALID_HANDLE) + TestGetFileInfo(&Logger, NULL, SFileInfoNameHash1, NULL, 0, NULL, false, ERROR_INVALID_HANDLE); + + // Valid handle and all parameters NULL + // Returns (true, ERROR_SUCCESS), if BET table is present, otherwise (false, ERROR_FILE_NOT_FOUND) + TestGetFileInfo(&Logger, hMpq1, SFileMpqBetHeader, NULL, 0, NULL, false, ERROR_FILE_NOT_FOUND); + TestGetFileInfo(&Logger, hMpq4, SFileMpqBetHeader, NULL, 0, NULL, false, ERROR_INSUFFICIENT_BUFFER); + + // Now try to retrieve the required size of the BET table header + TestGetFileInfo(&Logger, hMpq4, SFileMpqBetHeader, NULL, 0, &cbLength, false, ERROR_INSUFFICIENT_BUFFER); + + // When we call SFileInfo with buffer = NULL and nonzero buffer size, it is ignored + TestGetFileInfo(&Logger, hMpq4, SFileMpqBetHeader, NULL, 3, &cbLength, false, ERROR_INSUFFICIENT_BUFFER); + + // When we call SFileInfo with buffer != NULL and nonzero buffer size, it should return error + TestGetFileInfo(&Logger, hMpq4, SFileMpqBetHeader, DataBuff, 3, &cbLength, false, ERROR_INSUFFICIENT_BUFFER); + + // Request for bet table header should also succeed if we want header only + TestGetFileInfo(&Logger, hMpq4, SFileMpqBetHeader, DataBuff, sizeof(TMPQBetHeader), &cbLength, true, ERROR_SUCCESS); + + // Request for bet table header should also succeed if we want header+flag table only + TestGetFileInfo(&Logger, hMpq4, SFileMpqBetHeader, DataBuff, sizeof(DataBuff), &cbLength, true, ERROR_SUCCESS); + + // Try to retrieve strong signature from the MPQ + TestGetFileInfo(&Logger, hMpq1, SFileMpqStrongSignature, NULL, 0, NULL, false, ERROR_INSUFFICIENT_BUFFER); + TestGetFileInfo(&Logger, hMpq4, SFileMpqStrongSignature, NULL, 0, NULL, false, ERROR_FILE_NOT_FOUND); + + // Strong signature is returned including the signature ID + TestGetFileInfo(&Logger, hMpq1, SFileMpqStrongSignature, NULL, 0, &cbLength, false, ERROR_INSUFFICIENT_BUFFER); + assert(cbLength == MPQ_STRONG_SIGNATURE_SIZE + 4); + + // Retrieve the signature + TestGetFileInfo(&Logger, hMpq1, SFileMpqStrongSignature, DataBuff, sizeof(DataBuff), &cbLength, true, ERROR_SUCCESS); + assert(memcmp(DataBuff, "NGIS", 4) == 0); + + // Check SFileGetFileInfo on + if(SFileOpenFileEx(hMpq4, LISTFILE_NAME, 0, &hFile)) + { + // Valid parameters but the handle should be file handle + TestGetFileInfo(&Logger, hMpq4, SFileInfoFileTime, DataBuff, sizeof(DataBuff), &cbLength, false, ERROR_INVALID_HANDLE); + + // Valid parameters + TestGetFileInfo(&Logger, hFile, SFileInfoFileTime, DataBuff, sizeof(DataBuff), &cbLength, true, ERROR_SUCCESS); + + SFileCloseFile(hFile); + } + } + + if(hMpq4 != NULL) + SFileCloseArchive(hMpq4); + if(hMpq1 != NULL) + SFileCloseArchive(hMpq1); + return ERROR_SUCCESS; +} + +static DWORD TestOpenArchive_MasterMirror(LPCTSTR szMirrorName, LPCTSTR szMasterName, LPCSTR szFileToExtract, bool bCopyMirrorFile) +{ + TFileData * pFileData; + TLogHelper Logger("OpenServerMirror", szMirrorName); + HANDLE hFile = NULL; + HANDLE hMpq = NULL; + DWORD dwVerifyResult; + TCHAR szMirrorPath[MAX_PATH + MAX_PATH]; // Combined name + TCHAR szMasterPath[MAX_PATH]; // Original (server) name + DWORD dwErrCode; + + // Create both paths + dwErrCode = CreateMasterAndMirrorPaths(&Logger, szMirrorPath, szMasterPath, szMirrorName, szMasterName, bCopyMirrorFile); + + // Now open both archives as local-server pair + if(dwErrCode == ERROR_SUCCESS) + { + dwErrCode = OpenExistingArchive(&Logger, szMirrorPath, 0, &hMpq); + } + + // The MPQ must be read-only. Writing to mirrored MPQ is not allowed + if(dwErrCode == ERROR_SUCCESS) + { + if(SFileCreateFile(hMpq, "AddedFile.bin", 0, 0x10, 0, MPQ_FILE_COMPRESS, &hFile)) + { + SFileCloseFile(hFile); + Logger.PrintMessage("The archive is writable, although it should not be"); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + + // Verify the file + if(dwErrCode == ERROR_SUCCESS && szFileToExtract != NULL) + { + dwVerifyResult = SFileVerifyFile(hMpq, szFileToExtract, SFILE_VERIFY_ALL); + if(dwVerifyResult & VERIFY_FILE_ERROR_MASK) + { + Logger.PrintMessage("File verification failed"); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + + // Load the file to memory + if(dwErrCode == ERROR_SUCCESS && szFileToExtract) + { + pFileData = LoadMpqFile(&Logger, hMpq, szFileToExtract); + if(pFileData != NULL) + STORM_FREE(pFileData); + } + + if(hMpq != NULL) + SFileCloseArchive(hMpq); + return dwErrCode; +} + + +static DWORD TestOpenArchive_VerifySignature(LPCTSTR szPlainName, LPCTSTR szOriginalName) +{ + TLogHelper Logger("VerifySignatureTest", szPlainName); + HANDLE hMpq; + DWORD dwSignatures = 0; + DWORD dwErrCode = ERROR_SUCCESS; + int nVerifyError; + + // We need original name for the signature check + dwErrCode = OpenExistingArchiveWithCopy(&Logger, szPlainName, szOriginalName, &hMpq); + if(dwErrCode == ERROR_SUCCESS) + { + // Query the signature types + Logger.PrintProgress("Retrieving signatures ..."); + TestGetFileInfo(&Logger, hMpq, SFileMpqSignatures, &dwSignatures, sizeof(DWORD), NULL, true, ERROR_SUCCESS); + + // Verify any of the present signatures + Logger.PrintProgress("Verifying archive signature ..."); + nVerifyError = SFileVerifyArchive(hMpq); + + // Verify the result + if((dwSignatures & SIGNATURE_TYPE_STRONG) && (nVerifyError != ERROR_STRONG_SIGNATURE_OK)) + { + Logger.PrintMessage("Strong signature verification error"); + dwErrCode = ERROR_FILE_CORRUPT; + } + + // Verify the result + if((dwSignatures & SIGNATURE_TYPE_WEAK) && (nVerifyError != ERROR_WEAK_SIGNATURE_OK)) + { + Logger.PrintMessage("Weak signature verification error"); + dwErrCode = ERROR_FILE_CORRUPT; + } + + SFileCloseArchive(hMpq); + } + return dwErrCode; +} + +static DWORD TestOpenArchive_ModifySigned(LPCTSTR szPlainName, LPCTSTR szOriginalName) +{ + TLogHelper Logger("ModifySignedTest", szPlainName); + HANDLE hMpq = NULL; + int nVerifyError; + DWORD dwErrCode = ERROR_SUCCESS; + + // We need original name for the signature check + dwErrCode = OpenExistingArchiveWithCopy(&Logger, szPlainName, szOriginalName, &hMpq); + if(dwErrCode == ERROR_SUCCESS) + { + // Verify the weak signature + Logger.PrintProgress("Verifying archive signature ..."); + nVerifyError = SFileVerifyArchive(hMpq); + + // Check the result signature + if(nVerifyError != ERROR_WEAK_SIGNATURE_OK) + { + Logger.PrintMessage("Weak signature verification error"); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + + // Add a file and verify the signature again + if(dwErrCode == ERROR_SUCCESS) + { + // Verify any of the present signatures + Logger.PrintProgress("Modifying signed archive ..."); + dwErrCode = AddFileToMpq(&Logger, hMpq, "AddedFile01.txt", "This is a file added to signed MPQ", 0, 0, ERROR_SUCCESS); + } + + // Verify the signature again + if(dwErrCode == ERROR_SUCCESS) + { + // Verify the weak signature + Logger.PrintProgress("Verifying archive signature ..."); + nVerifyError = SFileVerifyArchive(hMpq); + + // Check the result signature + if(nVerifyError != ERROR_WEAK_SIGNATURE_OK) + { + Logger.PrintMessage("Weak signature verification error"); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + + // Close the MPQ + if(hMpq != NULL) + SFileCloseArchive(hMpq); + return dwErrCode; +} + +static DWORD TestOpenArchive_SignExisting(LPCTSTR szPlainName) +{ + TLogHelper Logger("SignExistingMpq", szPlainName); + HANDLE hMpq = NULL; + int nVerifyError; + DWORD dwErrCode = ERROR_SUCCESS; + + // We need original name for the signature check + dwErrCode = OpenExistingArchiveWithCopy(&Logger, szPlainName, szPlainName, &hMpq); + if(dwErrCode == ERROR_SUCCESS) + { + // Verify the weak signature + Logger.PrintProgress("Verifying archive signature ..."); + nVerifyError = SFileVerifyArchive(hMpq); + + // Check the result signature + if(nVerifyError != ERROR_NO_SIGNATURE) + { + Logger.PrintMessage("There already is a signature in the MPQ"); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + + // Add a file and verify the signature again + if(dwErrCode == ERROR_SUCCESS) + { + // Verify any of the present signatures + Logger.PrintProgress("Signing the MPQ ..."); + if(!SFileSignArchive(hMpq, SIGNATURE_TYPE_WEAK)) + { + Logger.PrintMessage("Failed to create archive signature"); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + + // Verify the signature again + if(dwErrCode == ERROR_SUCCESS) + { + // Verify the weak signature + Logger.PrintProgress("Verifying archive signature ..."); + nVerifyError = SFileVerifyArchive(hMpq); + + // Check the result signature + if(nVerifyError != ERROR_WEAK_SIGNATURE_OK) + { + Logger.PrintMessage("Weak signature verification error"); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + + // Close the MPQ + if(hMpq != NULL) + SFileCloseArchive(hMpq); + return dwErrCode; +} + +static DWORD TestOpenArchive_CompactArchive(LPCTSTR szPlainName, LPCTSTR szCopyName, bool bAddUserData) +{ + TLogHelper Logger("CompactMpqTest", szPlainName); + ULONGLONG PreMpqDataSize = (bAddUserData) ? 0x400 : 0; + ULONGLONG UserDataSize = (bAddUserData) ? 0x531 : 0; + HANDLE hMpq; + DWORD dwFileCount1 = 0; + DWORD dwFileCount2 = 0; + TCHAR szFullPath[MAX_PATH]; + BYTE FileHash1[MD5_DIGEST_SIZE]; + BYTE FileHash2[MD5_DIGEST_SIZE]; + DWORD dwErrCode; + + // Create copy of the archive, with interleaving some user data + dwErrCode = CreateFileCopy(&Logger, szPlainName, szCopyName, szFullPath, _countof(szFullPath), PreMpqDataSize, UserDataSize); + + // Open the archive and load some files + if(dwErrCode == ERROR_SUCCESS) + { + // Open the archive + dwErrCode = OpenExistingArchive(&Logger, szFullPath, 0, &hMpq); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + // Verify presence of (listfile) and (attributes) + CheckIfFileIsPresent(&Logger, hMpq, LISTFILE_NAME, true); + CheckIfFileIsPresent(&Logger, hMpq, ATTRIBUTES_NAME, true); + + // Search the archive and load every file + dwErrCode = SearchArchive(&Logger, hMpq, SEARCH_FLAG_LOAD_FILES | SEARCH_FLAG_HASH_FILES, &dwFileCount1, FileHash1); + SFileCloseArchive(hMpq); + } + + // Try to compact the MPQ + if(dwErrCode == ERROR_SUCCESS) + { + // Open the archive again + dwErrCode = OpenExistingArchive(&Logger, szFullPath, 0, &hMpq); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + // Compact the archive + Logger.PrintProgress("Compacting archive %s ...", GetShortPlainName(szFullPath)); + if(!SFileSetCompactCallback(hMpq, CompactCallback, &Logger)) + dwErrCode = Logger.PrintError(_T("Failed to compact archive %s"), szFullPath); + + SFileCompactArchive(hMpq, NULL, false); + SFileCloseArchive(hMpq); + } + + // Open the archive and load some files + if(dwErrCode == ERROR_SUCCESS) + { + // Open the archive + dwErrCode = OpenExistingArchive(&Logger, szFullPath, 0, &hMpq); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + // Verify presence of (listfile) and (attributes) + CheckIfFileIsPresent(&Logger, hMpq, LISTFILE_NAME, true); + CheckIfFileIsPresent(&Logger, hMpq, ATTRIBUTES_NAME, true); + + // Search the archive and load every file + dwErrCode = SearchArchive(&Logger, hMpq, SEARCH_FLAG_LOAD_FILES | SEARCH_FLAG_HASH_FILES, &dwFileCount2, FileHash2); + SFileCloseArchive(hMpq); + } + + // Compare the file counts and their hashes + if(dwErrCode == ERROR_SUCCESS) + { + if(dwFileCount2 != dwFileCount1) + Logger.PrintMessage("Different file count after compacting archive: %u vs %u", dwFileCount2, dwFileCount1); + + if(memcmp(FileHash2, FileHash1, MD5_DIGEST_SIZE)) + Logger.PrintMessage("Different file hash after compacting archive"); + } + + return dwErrCode; +} + +static DWORD ForEachFile_VerifyFileChecksum(LPCTSTR szFullPath) +{ + TFileData * pFileData; + TCHAR * szExtension; + TCHAR szShaFileName[MAX_PATH+1]; + TCHAR szSha1Text[0x40]; + char szSha1TextA[0x40]; + DWORD dwErrCode = ERROR_SUCCESS; + + // Try to load the file with the SHA extension + StringCopy(szShaFileName, _countof(szShaFileName), szFullPath); + szExtension = _tcsrchr(szShaFileName, '.'); + if(szExtension == NULL) + return ERROR_SUCCESS; + + // Skip .SHA and .TXT files + if(!_tcsicmp(szExtension, _T(".sha")) || !_tcsicmp(szExtension, _T(".txt"))) + return ERROR_SUCCESS; + + // Load the local file to memory + _tcscpy(szExtension, _T(".sha")); + pFileData = LoadLocalFile(NULL, szShaFileName, false); + if(pFileData != NULL) + { + TLogHelper Logger("VerifyFileHash"); + + // Calculate SHA1 of the entire file + dwErrCode = CalculateFileSha1(&Logger, szFullPath, szSha1Text); + if(dwErrCode == ERROR_SUCCESS) + { + // Compare with what we loaded from the file + if(pFileData->dwFileSize >= (SHA1_DIGEST_SIZE * 2)) + { + // Compare the SHA1 + StringCopy(szSha1TextA, _countof(szSha1TextA), szSha1Text); + if(_strnicmp(szSha1TextA, (char *)pFileData->FileData, (SHA1_DIGEST_SIZE * 2))) + { + SetLastError(dwErrCode = ERROR_FILE_CORRUPT); + Logger.PrintError(_T("File CRC check failed: %s"), szFullPath); + } + } + } + + STORM_FREE(pFileData); + } + + return dwErrCode; +} + +// Opens a found archive +static DWORD ForEachFile_OpenArchive(LPCTSTR szFullPath) +{ + HANDLE hMpq = NULL; + DWORD dwFileCount = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Check if it's a MPQ file type + if(IsMpqExtension(szFullPath)) + { + TLogHelper Logger("OpenEachMpqTest", GetShortPlainName(szFullPath)); + + // Open the MPQ name + dwErrCode = OpenExistingArchive(&Logger, szFullPath, 0, &hMpq); + if(dwErrCode == ERROR_AVI_FILE || dwErrCode == ERROR_FILE_CORRUPT || dwErrCode == ERROR_BAD_FORMAT) + return ERROR_SUCCESS; + + // Search the archive and load every file + if(dwErrCode == ERROR_SUCCESS) + { + dwErrCode = SearchArchive(&Logger, hMpq, 0, &dwFileCount); + SFileCloseArchive(hMpq); + } + + // Show warning if no files found + if(dwFileCount == 0) + { + Logger.PrintMessage("Warning: no files in the archive"); + } + } + + // Correct some errors + if(dwErrCode == ERROR_FILE_CORRUPT || dwErrCode == ERROR_FILE_INCOMPLETE) + return ERROR_SUCCESS; + return dwErrCode; +} + +// Adding a file to MPQ that had size of the file table equal +// or greater than hash table, but has free entries +static DWORD TestAddFile_FullTable(LPCTSTR szFullMpqName) +{ + TLogHelper Logger("FullMpqTest", szFullMpqName); + LPCSTR szFileName = "AddedFile001.txt"; + LPCSTR szFileData = "0123456789ABCDEF"; + HANDLE hMpq = NULL; + DWORD dwErrCode = ERROR_SUCCESS; + + // Copy the archive so we won't fuck up the original one + dwErrCode = OpenExistingArchiveWithCopy(&Logger, szFullMpqName, szFullMpqName, &hMpq); + if(dwErrCode == ERROR_SUCCESS) + { + // Attempt to add a file + dwErrCode = AddFileToMpq(&Logger, hMpq, szFileName, szFileData, MPQ_FILE_IMPLODE, MPQ_COMPRESSION_PKWARE, ERROR_SUCCESS); + SFileCloseArchive(hMpq); + } + + return dwErrCode; +} + +// Adding a file to MPQ that had no (listfile) and no (attributes). +// We expect that neither of these will be present after the archive is closed +static DWORD TestAddFile_ListFileTest(LPCTSTR szSourceMpq, bool bShouldHaveListFile, bool bShouldHaveAttributes) +{ + TLogHelper Logger("ListFileTest", szSourceMpq); + TFileData * pFileData = NULL; + LPCTSTR szBackupMpq = bShouldHaveListFile ? _T("StormLibTest_HasListFile.mpq") : _T("StormLibTest_NoListFile.mpq"); + LPCSTR szFileName = "AddedFile001.txt"; + LPCSTR szFileData = "0123456789ABCDEF"; + HANDLE hMpq = NULL; + DWORD dwFileSize = (DWORD)strlen(szFileData); + DWORD dwErrCode = ERROR_SUCCESS; + + // Copy the archive so we won't fuck up the original one + dwErrCode = OpenExistingArchiveWithCopy(&Logger, szSourceMpq, szBackupMpq, &hMpq); + + // Add a file + if(dwErrCode == ERROR_SUCCESS) + { + // Now add a file + dwErrCode = AddFileToMpq(&Logger, hMpq, szFileName, szFileData, MPQ_FILE_IMPLODE, MPQ_COMPRESSION_PKWARE); + SFileCloseArchive(hMpq); + hMpq = NULL; + } + + // Now reopen the archive + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = OpenExistingArchiveWithCopy(&Logger, NULL, szBackupMpq, &hMpq); + + // Now the file has been written and the MPQ has been saved. + // We Reopen the MPQ and check if there is no (listfile) nor (attributes). + if(dwErrCode == ERROR_SUCCESS) + { + // Verify presence of (listfile) and (attributes) + CheckIfFileIsPresent(&Logger, hMpq, LISTFILE_NAME, bShouldHaveListFile); + CheckIfFileIsPresent(&Logger, hMpq, ATTRIBUTES_NAME, bShouldHaveAttributes); + + // Try to open the file that we recently added + pFileData = LoadMpqFile(&Logger, hMpq, szFileName); + if(pFileData != NULL) + { + // Verify if the file size matches + if(pFileData->dwFileSize == dwFileSize) + { + // Verify if the file data match + if(memcmp(pFileData->FileData, szFileData, dwFileSize)) + { + Logger.PrintError("The data of the added file does not match"); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + else + { + Logger.PrintError("The size of the added file does not match"); + dwErrCode = ERROR_FILE_CORRUPT; + } + + // Delete the file data + STORM_FREE(pFileData); + } + else + { + dwErrCode = Logger.PrintError("Failed to open the file previously added"); + } + } + + // Close the MPQ archive + if(hMpq != NULL) + SFileCloseArchive(hMpq); + return dwErrCode; +} +/* +static DWORD TestCreateArchive_Deprotect(LPCSTR szPlainName) +{ + TLogHelper Logger("DeprotectTest", szPlainName); + HANDLE hMpq1 = NULL; + HANDLE hMpq2 = NULL; + char szMpqName1[MAX_PATH]; + char szMpqName2[MAX_PATH]; + BYTE FileHash1[MD5_DIGEST_SIZE]; + BYTE FileHash2[MD5_DIGEST_SIZE]; + DWORD dwFileCount1 = 0; + DWORD dwFileCount2 = 0; + DWORD dwTestFlags = SEARCH_FLAG_LOAD_FILES | SEARCH_FLAG_HASH_FILES; + DWORD dwErrCode = ERROR_SUCCESS; + + // First copy: The original (untouched) file + if(dwErrCode == ERROR_SUCCESS) + { + AddStringBeforeExtension(szMpqName1, szPlainName, "_original"); + dwErrCode = OpenExistingArchiveWithCopy(&Logger, szPlainName, szMpqName1, &hMpq1); + if(dwErrCode != ERROR_SUCCESS) + Logger.PrintMessage("Open failed: %s", szMpqName1); + } + + // Second copy: Will be deprotected + if(dwErrCode == ERROR_SUCCESS) + { + AddStringBeforeExtension(szMpqName2, szPlainName, "_deprotected"); + dwErrCode = OpenExistingArchiveWithCopy(&Logger, szPlainName, szMpqName2, &hMpq2); + if(dwErrCode != ERROR_SUCCESS) + Logger.PrintMessage("Open failed: %s", szMpqName2); + } + + // Deprotect the second map + if(dwErrCode == ERROR_SUCCESS) + { + SFileSetCompactCallback(hMpq2, CompactCallback, &Logger); + if(!SFileCompactArchive(hMpq2, NULL, false)) + dwErrCode = Logger.PrintError("Failed to deprotect archive %s", szMpqName2); + } + + // Calculate number of files and compare their hash (archive 1) + if(dwErrCode == ERROR_SUCCESS) + { + memset(FileHash1, 0, sizeof(FileHash1)); + dwErrCode = SearchArchive(&Logger, hMpq1, dwTestFlags, &dwFileCount1, FileHash1); + } + + // Calculate number of files and compare their hash (archive 2) + if(dwErrCode == ERROR_SUCCESS) + { + memset(FileHash1, 0, sizeof(FileHash2)); + dwErrCode = SearchArchive(&Logger, hMpq2, dwTestFlags, &dwFileCount2, FileHash2); + } + + if(dwErrCode == ERROR_SUCCESS) + { + if(dwFileCount1 != dwFileCount2) + Logger.PrintMessage("Different file count (%u in %s; %u in %s)", dwFileCount1, szMpqName1, dwFileCount2, szMpqName2); + if(memcmp(FileHash1, FileHash2, MD5_DIGEST_SIZE)) + Logger.PrintMessage("Different file hash (%s vs %s)", szMpqName1, szMpqName2); + } + + // Close both MPQs + if(hMpq2 != NULL) + SFileCloseArchive(hMpq2); + if(hMpq1 != NULL) + SFileCloseArchive(hMpq1); + return dwErrCode; +} +*/ + +static DWORD TestCreateArchive_EmptyMpq(LPCTSTR szPlainName, DWORD dwCreateFlags) +{ + TLogHelper Logger("CreateEmptyMpq", szPlainName); + HANDLE hMpq = NULL; + DWORD dwFileCount = 0; + DWORD dwErrCode; + + // Create the full path name + dwErrCode = CreateNewArchive(&Logger, szPlainName, dwCreateFlags, 0, &hMpq); + if(dwErrCode == ERROR_SUCCESS) + { + SearchArchive(&Logger, hMpq); + SFileCloseArchive(hMpq); + } + + // Reopen the empty MPQ + if(dwErrCode == ERROR_SUCCESS) + { + dwErrCode = OpenExistingArchiveWithCopy(&Logger, NULL, szPlainName, &hMpq); + if(dwErrCode == ERROR_SUCCESS) + { + SFileGetFileInfo(hMpq, SFileMpqNumberOfFiles, &dwFileCount, sizeof(dwFileCount), NULL); + + CheckIfFileIsPresent(&Logger, hMpq, "File00000000.xxx", false); + CheckIfFileIsPresent(&Logger, hMpq, LISTFILE_NAME, false); + SearchArchive(&Logger, hMpq); + SFileCloseArchive(hMpq); + } + } + + return dwErrCode; +} + +static DWORD TestCreateArchive_TestGaps(LPCTSTR szPlainName) +{ + TLogHelper Logger("CreateGapsTest", szPlainName); + ULONGLONG ByteOffset1 = 0xFFFFFFFF; + ULONGLONG ByteOffset2 = 0xEEEEEEEE; + HANDLE hMpq = NULL; + HANDLE hFile = NULL; + TCHAR szFullPath[MAX_PATH]; + DWORD dwErrCode = ERROR_SUCCESS; + + // Create new MPQ + dwErrCode = CreateNewArchive_V2(&Logger, szPlainName, MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES | MPQ_FORMAT_VERSION_4, 4000, &hMpq); + if(dwErrCode == ERROR_SUCCESS) + { + // Add one file and flush the archive + dwErrCode = AddFileToMpq(&Logger, hMpq, "AddedFile01.txt", "This is the file data.", MPQ_FILE_COMPRESS); + SFileCloseArchive(hMpq); + hMpq = NULL; + } + + // Reopen the MPQ and add another file. + // The new file must be added to the position of the (listfile) + if(dwErrCode == ERROR_SUCCESS) + { + CreateFullPathName(szFullPath, _countof(szFullPath), NULL, szPlainName); + dwErrCode = OpenExistingArchive(&Logger, szFullPath, 0, &hMpq); + if(dwErrCode == ERROR_SUCCESS) + { + // Retrieve the position of the (listfile) + if(SFileOpenFileEx(hMpq, LISTFILE_NAME, 0, &hFile)) + { + SFileGetFileInfo(hFile, SFileInfoByteOffset, &ByteOffset1, sizeof(ULONGLONG), NULL); + SFileCloseFile(hFile); + } + else + dwErrCode = GetLastError(); + } + } + + // Add another file and check its position. It must be at the position of the former listfile + if(dwErrCode == ERROR_SUCCESS) + { + LPCSTR szAddedFile = "AddedFile02.txt"; + + // Add another file + dwErrCode = AddFileToMpq(&Logger, hMpq, szAddedFile, "This is the second added file.", MPQ_FILE_COMPRESS); + + // Retrieve the position of the (listfile) + if(SFileOpenFileEx(hMpq, szAddedFile, 0, &hFile)) + { + SFileGetFileInfo(hFile, SFileInfoByteOffset, &ByteOffset2, sizeof(ULONGLONG), NULL); + SFileCloseFile(hFile); + } + else + dwErrCode = GetLastError(); + } + + // Now check the positions + if(dwErrCode == ERROR_SUCCESS) + { + if(ByteOffset1 != ByteOffset2) + { + Logger.PrintError("The added file was not written to the position of (listfile)"); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + + // Close the archive if needed + if(hMpq != NULL) + SFileCloseArchive(hMpq); + return dwErrCode; +} + +static DWORD TestCreateArchive_NonStdNames(LPCTSTR szPlainName) +{ + TLogHelper Logger("NonStdNamesTest", szPlainName); + HANDLE hMpq = NULL; + DWORD dwErrCode = ERROR_SUCCESS; + + // Create new MPQ + dwErrCode = CreateNewArchive(&Logger, szPlainName, MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES | MPQ_FORMAT_VERSION_1, 4000, &hMpq); + if(dwErrCode == ERROR_SUCCESS) + { + // Add few files and close the archive + AddFileToMpq(&Logger, hMpq, "AddedFile000.txt", "This is the file data 000.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "\\/\\/\\/\\AddedFile001.txt", "This is the file data 001.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "\\\\\\\\\\\\\\\\", "This is the file data 002.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "////////////////", "This is the file data 003.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "//\\//\\//\\//\\", "This is the file data 004.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "................", "This is the file data 005.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "//****//****//****//****.***", "This is the file data 006.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "//*??*//*??*//*??*//?**?.?*?", "This is the file data 007.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "\\/\\/File.txt", "This is the file data 008.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "\\/\\/File.txt..", "This is the file data 009.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "Dir1\\Dir2\\Dir3\\File.txt..", "This is the file data 010.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "\\Dir1\\Dir2\\Dir3\\File.txt..", "This is the file data 011.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "\\\\Dir1\\\\Dir2\\\\Dir3\\\\File.txt..", "This is the file data 012.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "/Dir1/Dir2/Dir3/File.txt..", "This is the file data 013.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "////Dir1////Dir2////Dir3////File.txt..", "This is the file data 014.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "\\//\\Dir1\\//\\Dir2\\//\\File.txt..", "This is the file data 015.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "\x10\x11\x12\x13\\\x14\x15\x16\x17\\\x18\x19\x1a\x1b\\\x1c\x1D\x1E\x1F.txt", "This is the file data 016.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "\x09\x20\x09\x20\\\x20\x09\x20\x09\\\x09\x20\x09\x20\\\x20\x09\x20\x09.txt", "This is the file data 017.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "\x80\x91\xA2\xB3\\\xC4\xD5\xE6\xF7\\\x80\x91\xA2\xB3.txt", "This is the file data 018.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "Dir1\x20\x09\x20\\Dir2\x20\x09\x20\\File.txt\x09\x09\x20\x2e", "This is the file data 019.", MPQ_FILE_COMPRESS); + AddFileToMpq(&Logger, hMpq, "Dir1\x20\x09\x20\\Dir2\x20\x09\x20\\\x09\x20\x2e\x09\x20\x2e", "This is the file data 020.", MPQ_FILE_COMPRESS); + + SFileCloseArchive(hMpq); + } + + return ERROR_SUCCESS; +} + +static DWORD TestCreateArchive_Signed(LPCTSTR szPlainName, bool bSignAtCreate) +{ + TLogHelper Logger("CreateSignedMpq", szPlainName); + HANDLE hMpq = NULL; + DWORD dwCreateFlags = MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES | MPQ_FORMAT_VERSION_1; + DWORD dwSignatures = 0; + DWORD nVerifyError = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Method 1: Create the archive as signed + if(bSignAtCreate) + dwCreateFlags |= MPQ_CREATE_SIGNATURE; + + // Create new MPQ + dwErrCode = CreateNewArchive_V2(&Logger, szPlainName, dwCreateFlags, 4000, &hMpq); + if(dwErrCode == ERROR_SUCCESS) + { + // Add one file and flush the archive + dwErrCode = AddFileToMpq(&Logger, hMpq, "AddedFile01.txt", "This is the file data.", MPQ_FILE_COMPRESS); + } + + // Sign the archive with weak signature + if(dwErrCode == ERROR_SUCCESS) + { + if(!SFileSignArchive(hMpq, SIGNATURE_TYPE_WEAK)) + dwErrCode = ERROR_SUCCESS; + } + + // Reopen the MPQ and add another file. + // The new file must be added to the position of the (listfile) + if(dwErrCode == ERROR_SUCCESS) + { + // Query the signature types + Logger.PrintProgress("Retrieving signatures ..."); + TestGetFileInfo(&Logger, hMpq, SFileMpqSignatures, &dwSignatures, sizeof(DWORD), NULL, true, ERROR_SUCCESS); + + // Verify any of the present signatures + Logger.PrintProgress("Verifying archive signature ..."); + nVerifyError = SFileVerifyArchive(hMpq); + + // Verify the result + if((dwSignatures != SIGNATURE_TYPE_WEAK) && (nVerifyError != ERROR_WEAK_SIGNATURE_OK)) + { + Logger.PrintMessage("Weak signature verification error"); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + + // Close the archive + if(hMpq != NULL) + SFileCloseArchive(hMpq); + return dwErrCode; +} + +static DWORD TestCreateArchive_MpqEditor(LPCTSTR szPlainName, LPCSTR szFileName) +{ + TLogHelper Logger("CreateMpqEditor", szPlainName); + HANDLE hMpq = NULL; + DWORD dwErrCode = ERROR_SUCCESS; + + // Create new MPQ + dwErrCode = CreateNewArchive_V2(&Logger, szPlainName, MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES, 4000, &hMpq); + if(dwErrCode == ERROR_SUCCESS) + { + // Flush the archive first + SFileFlushArchive(hMpq); + + // Add one file + dwErrCode = AddFileToMpq(&Logger, hMpq, szFileName, "This is the file data.", MPQ_FILE_COMPRESS); + + // Flush the archive again + SFileFlushArchive(hMpq); + SFileCloseArchive(hMpq); + } + else + { + dwErrCode = GetLastError(); + } + + return dwErrCode; +} + +static DWORD TestCreateArchive_FillArchive(LPCTSTR szPlainName, DWORD dwCreateFlags) +{ + TLogHelper Logger("CreateFullMpq", szPlainName); + LPCSTR szFileData = "TestCreateArchive_FillArchive: Testing file data"; + char szFileName[MAX_PATH]; + HANDLE hMpq = NULL; + DWORD dwMaxFileCount = 6; + DWORD dwCompression = MPQ_COMPRESSION_ZLIB; + DWORD dwFlags = MPQ_FILE_ENCRYPTED | MPQ_FILE_COMPRESS; + DWORD dwErrCode; + + // + // Note that StormLib will round the maxfile count + // up to hash table size (nearest power of two) + // + if((dwCreateFlags & MPQ_CREATE_LISTFILE) == 0) + dwMaxFileCount++; + if((dwCreateFlags & MPQ_CREATE_ATTRIBUTES) == 0) + dwMaxFileCount++; + + // Create the new MPQ archive + dwErrCode = CreateNewArchive_V2(&Logger, szPlainName, dwCreateFlags, dwMaxFileCount, &hMpq); + if(dwErrCode == ERROR_SUCCESS) + { + // Flush the archive first + SFileFlushArchive(hMpq); + + // Add all files + for(unsigned int i = 0; i < dwMaxFileCount; i++) + { + sprintf(szFileName, "AddedFile%03u.txt", i); + dwErrCode = AddFileToMpq(&Logger, hMpq, szFileName, szFileData, dwFlags, dwCompression); + if(dwErrCode != ERROR_SUCCESS) + break; + } + + // Flush the archive again + SFileFlushArchive(hMpq); + } + + // Now the MPQ should be full. It must not be possible to add another file + if(dwErrCode == ERROR_SUCCESS) + { + dwErrCode = AddFileToMpq(&Logger, hMpq, "ShouldNotBeHere.txt", szFileData, MPQ_FILE_COMPRESS, MPQ_COMPRESSION_ZLIB, ERROR_DISK_FULL); + assert(dwErrCode != ERROR_SUCCESS); + dwErrCode = ERROR_SUCCESS; + } + + // Close the archive to enforce saving all tables + if(hMpq != NULL) + SFileCloseArchive(hMpq); + hMpq = NULL; + + // Reopen the archive again + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = OpenExistingArchiveWithCopy(&Logger, NULL, szPlainName, &hMpq); + + // The archive should still be full + if(dwErrCode == ERROR_SUCCESS) + { + CheckIfFileIsPresent(&Logger, hMpq, LISTFILE_NAME, (dwCreateFlags & MPQ_CREATE_LISTFILE) ? true : false); + CheckIfFileIsPresent(&Logger, hMpq, ATTRIBUTES_NAME, (dwCreateFlags & MPQ_CREATE_ATTRIBUTES) ? true : false); + dwErrCode = AddFileToMpq(&Logger, hMpq, "ShouldNotBeHere.txt", szFileData, MPQ_FILE_COMPRESS, MPQ_COMPRESSION_ZLIB, ERROR_DISK_FULL); + assert(dwErrCode != ERROR_SUCCESS); + dwErrCode = ERROR_SUCCESS; + } + + // The (listfile) and (attributes) must be present + if(dwErrCode == ERROR_SUCCESS) + { + CheckIfFileIsPresent(&Logger, hMpq, LISTFILE_NAME, (dwCreateFlags & MPQ_CREATE_LISTFILE) ? true : false); + CheckIfFileIsPresent(&Logger, hMpq, ATTRIBUTES_NAME, (dwCreateFlags & MPQ_CREATE_ATTRIBUTES) ? true : false); + dwErrCode = RemoveMpqFile(&Logger, hMpq, szFileName, ERROR_SUCCESS); + } + + // Now add the file again. This time, it should be possible OK + if(dwErrCode == ERROR_SUCCESS) + { + dwErrCode = AddFileToMpq(&Logger, hMpq, szFileName, szFileData, dwFlags, dwCompression, ERROR_SUCCESS); + assert(dwErrCode == ERROR_SUCCESS); + } + + // Now add the file again. This time, it should fail + if(dwErrCode == ERROR_SUCCESS) + { + dwErrCode = AddFileToMpq(&Logger, hMpq, szFileName, szFileData, dwFlags, dwCompression, ERROR_ALREADY_EXISTS); + assert(dwErrCode != ERROR_SUCCESS); + dwErrCode = ERROR_SUCCESS; + } + + // Now add the file again. This time, it should fail + if(dwErrCode == ERROR_SUCCESS) + { + dwErrCode = AddFileToMpq(&Logger, hMpq, "ShouldNotBeHere.txt", szFileData, dwFlags, dwCompression, ERROR_DISK_FULL); + assert(dwErrCode != ERROR_SUCCESS); + dwErrCode = ERROR_SUCCESS; + } + + // Close the archive and return + if(hMpq != NULL) + SFileCloseArchive(hMpq); + hMpq = NULL; + + // Reopen the archive for the third time to verify that both internal files are there + if(dwErrCode == ERROR_SUCCESS) + { + dwErrCode = OpenExistingArchiveWithCopy(&Logger, NULL, szPlainName, &hMpq); + if(dwErrCode == ERROR_SUCCESS) + { + CheckIfFileIsPresent(&Logger, hMpq, LISTFILE_NAME, (dwCreateFlags & MPQ_CREATE_LISTFILE) ? true : false); + CheckIfFileIsPresent(&Logger, hMpq, ATTRIBUTES_NAME, (dwCreateFlags & MPQ_CREATE_ATTRIBUTES) ? true : false); + SFileCloseArchive(hMpq); + } + } + + return dwErrCode; +} + +static DWORD TestCreateArchive_IncMaxFileCount(LPCTSTR szPlainName) +{ + TLogHelper Logger("IncMaxFileCount", szPlainName); + LPCSTR szFileData = "TestCreateArchive_IncMaxFileCount: Testing file data"; + char szFileName[MAX_PATH]; + HANDLE hMpq = NULL; + DWORD dwMaxFileCount = 1; + DWORD dwErrCode; + + // Create the new MPQ + dwErrCode = CreateNewArchive(&Logger, szPlainName, MPQ_CREATE_ARCHIVE_V4 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES, dwMaxFileCount, &hMpq); + + // Now add exactly one file + if(dwErrCode == ERROR_SUCCESS) + { + dwErrCode = AddFileToMpq(&Logger, hMpq, "AddFile_base.txt", szFileData); + SFileFlushArchive(hMpq); + SFileCloseArchive(hMpq); + } + + // Now add 10 files. Each time we cannot add the file due to archive being full, + // we increment the max file count + if(dwErrCode == ERROR_SUCCESS) + { + for(unsigned int i = 0; i < 10; i++) + { + // Open the archive again + dwErrCode = OpenExistingArchiveWithCopy(&Logger, NULL, szPlainName, &hMpq); + if(dwErrCode != ERROR_SUCCESS) + break; + + // Add one file + sprintf(szFileName, "AddFile_%04u.txt", i); + dwErrCode = AddFileToMpq(&Logger, hMpq, szFileName, szFileData, 0, 0, ERROR_UNDETERMINED_RESULT); + if(dwErrCode != ERROR_SUCCESS) + { + // Increment the max file count by one + dwMaxFileCount = SFileGetMaxFileCount(hMpq) + 1; + Logger.PrintProgress("Increasing max file count to %u ...", dwMaxFileCount); + SFileSetMaxFileCount(hMpq, dwMaxFileCount); + + // Attempt to create the file again + dwErrCode = AddFileToMpq(&Logger, hMpq, szFileName, szFileData, 0, 0, ERROR_SUCCESS); + } + + // Compact the archive and close it + SFileSetCompactCallback(hMpq, CompactCallback, &Logger); + SFileCompactArchive(hMpq, NULL, false); + SFileCloseArchive(hMpq); + if(dwErrCode != ERROR_SUCCESS) + break; + } + } + + return dwErrCode; +} + +static DWORD TestCreateArchive_UnicodeNames() +{ + TLogHelper Logger("MpqUnicodeName"); + DWORD dwCreateFlags = MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES; + DWORD dwErrCode = ERROR_SUCCESS; + + dwErrCode = CreateNewArchiveU(&Logger, szUnicodeName1, dwCreateFlags | MPQ_CREATE_ARCHIVE_V1, 15); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + dwErrCode = CreateNewArchiveU(&Logger, szUnicodeName2, dwCreateFlags | MPQ_CREATE_ARCHIVE_V2, 58); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + dwErrCode = CreateNewArchiveU(&Logger, szUnicodeName3, dwCreateFlags | MPQ_CREATE_ARCHIVE_V3, 15874); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + dwErrCode = CreateNewArchiveU(&Logger, szUnicodeName4, dwCreateFlags | MPQ_CREATE_ARCHIVE_V4, 87541); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + dwErrCode = CreateNewArchiveU(&Logger, szUnicodeName5, dwCreateFlags | MPQ_CREATE_ARCHIVE_V3, 87541); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + dwErrCode = CreateNewArchiveU(&Logger, szUnicodeName5, dwCreateFlags | MPQ_CREATE_ARCHIVE_V2, 87541); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + return dwErrCode; +} + +static DWORD TestCreateArchive_FileFlagTest(LPCTSTR szPlainName) +{ + TLogHelper Logger("FileFlagTest", szPlainName); + HANDLE hMpq = NULL; // Handle of created archive + TCHAR szFileName1[MAX_PATH]; + TCHAR szFileName2[MAX_PATH]; + TCHAR szFullPath[MAX_PATH]; + LPCSTR szMiddleFile = "FileTest_10.exe"; + LCID LocaleIDs[] = {0x000, 0x405, 0x406, 0x407, 0xFFFF}; + char szArchivedName[MAX_PATH]; + DWORD dwMaxFileCount = 0; + DWORD dwFileCount = 0; + DWORD dwErrCode; + + // Create paths for local file to be added + CreateFullPathName(szFileName1, _countof(szFileName1), szMpqSubDir, _T("AddFile.exe")); + CreateFullPathName(szFileName2, _countof(szFileName2), szMpqSubDir, _T("AddFile.bin")); + + // Create an empty file that will serve as holder for the MPQ + dwErrCode = CreateEmptyFile(&Logger, szPlainName, 0x100000, szFullPath); + + // Create new MPQ archive over that file + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = CreateNewArchive(&Logger, szPlainName, MPQ_CREATE_ARCHIVE_V1 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES, 17, &hMpq); + + // Add the same file multiple times + if(dwErrCode == ERROR_SUCCESS) + { + dwMaxFileCount = SFileGetMaxFileCount(hMpq); + for(size_t i = 0; AddFlags[i] != 0xFFFFFFFF; i++) + { + sprintf(szArchivedName, "FileTest_%02u.exe", (unsigned int)i); + dwErrCode = AddLocalFileToMpq(&Logger, hMpq, szArchivedName, szFileName1, AddFlags[i], 0); + if(dwErrCode != ERROR_SUCCESS) + break; + + dwFileCount++; + } + } + + // Delete a file in the middle of the file table + if(dwErrCode == ERROR_SUCCESS) + { + Logger.PrintProgress("Removing file %s ...", szMiddleFile); + dwErrCode = RemoveMpqFile(&Logger, hMpq, szMiddleFile, ERROR_SUCCESS); + dwFileCount--; + } + + // Add one more file + if(dwErrCode == ERROR_SUCCESS) + { + dwErrCode = AddLocalFileToMpq(&Logger, hMpq, "FileTest_xx.exe", szFileName1); + dwFileCount++; + } + + // Try to decrement max file count. This must succeed + if(dwErrCode == ERROR_SUCCESS) + { + Logger.PrintProgress("Attempting to decrement max file count ..."); + if(SFileSetMaxFileCount(hMpq, 5)) + dwErrCode = Logger.PrintError("Max file count decremented, even if it should fail"); + } + + // Add ZeroSize.txt several times under a different locale + if(dwErrCode == ERROR_SUCCESS) + { + for(size_t i = 0; LocaleIDs[i] != 0xFFFF; i++) + { + bool bMustSucceed = ((dwFileCount + 2) < dwMaxFileCount); + + SFileSetLocale(LocaleIDs[i]); + dwErrCode = AddLocalFileToMpq(&Logger, hMpq, "ZeroSize_1.txt", szFileName2); + if(dwErrCode != ERROR_SUCCESS) + { + if(bMustSucceed == false) + dwErrCode = ERROR_SUCCESS; + break; + } + + dwFileCount++; + } + } + + // Add ZeroSize.txt again several times under a different locale + if(dwErrCode == ERROR_SUCCESS) + { + for(size_t i = 0; LocaleIDs[i] != 0xFFFF; i++) + { + bool bMustSucceed = ((dwFileCount + 2) < dwMaxFileCount); + + SFileSetLocale(LocaleIDs[i]); + dwErrCode = AddLocalFileToMpq(&Logger, hMpq, "ZeroSize_2.txt", szFileName2, 0, 0, bMustSucceed); + if(dwErrCode != ERROR_SUCCESS) + { + if(bMustSucceed == false) + dwErrCode = ERROR_SUCCESS; + break; + } + + dwFileCount++; + } + } + + // Verify how many files did we add to the MPQ + if(dwErrCode == ERROR_SUCCESS) + { + if(dwFileCount + 2 != dwMaxFileCount) + { + Logger.PrintErrorVa("Number of files added to MPQ was unexpected (expected %u, added %u)", dwFileCount, dwMaxFileCount - 2); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + + // Test rename function + if(dwErrCode == ERROR_SUCCESS) + { + Logger.PrintProgress("Testing rename files ..."); + SFileSetLocale(LANG_NEUTRAL); + if(!SFileRenameFile(hMpq, "FileTest_08.exe", "FileTest_08a.exe")) + dwErrCode = Logger.PrintError("Failed to rename the file"); + } + + if(dwErrCode == ERROR_SUCCESS) + { + if(!SFileRenameFile(hMpq, "FileTest_08a.exe", "FileTest_08.exe")) + dwErrCode = Logger.PrintError("Failed to rename the file"); + } + + if(dwErrCode == ERROR_SUCCESS) + { + if(SFileRenameFile(hMpq, "FileTest_10.exe", "FileTest_10a.exe")) + { + Logger.PrintError("Rename test succeeded even if it shouldn't"); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + + if(dwErrCode == ERROR_SUCCESS) + { + if(SFileRenameFile(hMpq, "FileTest_10a.exe", "FileTest_10.exe")) + { + Logger.PrintError("Rename test succeeded even if it shouldn't"); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + + // Close the archive + if(hMpq != NULL) + SFileCloseArchive(hMpq); + hMpq = NULL; + + // Try to reopen the archive + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = OpenExistingArchive(&Logger, szFullPath, 0, NULL); + return dwErrCode; +} + +static DWORD TestCreateArchive_WaveCompressionsTest(LPCTSTR szPlainName, LPCTSTR szWaveFile) +{ + TLogHelper Logger("CompressionsTest", szPlainName); + HANDLE hMpq = NULL; // Handle of created archive + TCHAR szFileName[MAX_PATH]; // Source file to be added + char szArchivedName[MAX_PATH]; + DWORD dwCmprCount = sizeof(WaveCompressions) / sizeof(DWORD); + DWORD dwAddedFiles = 0; + DWORD dwFoundFiles = 0; + DWORD dwErrCode; + + // Create paths for local file to be added + CreateFullPathName(szFileName, _countof(szFileName), szMpqSubDir, szWaveFile); + + // Create new archive + dwErrCode = CreateNewArchive(&Logger, szPlainName, MPQ_CREATE_ARCHIVE_V1 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES, 0x40, &hMpq); + + // Add the same file multiple times + if(dwErrCode == ERROR_SUCCESS) + { + Logger.UserTotal = dwCmprCount; + for(unsigned int i = 0; i < dwCmprCount; i++) + { + sprintf(szArchivedName, "WaveFile_%02u.wav", i + 1); + dwErrCode = AddLocalFileToMpq(&Logger, hMpq, szArchivedName, szFileName, MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | MPQ_FILE_SECTOR_CRC, WaveCompressions[i]); + if(dwErrCode != ERROR_SUCCESS) + break; + + Logger.UserCount++; + dwAddedFiles++; + } + + SFileCloseArchive(hMpq); + } + + // Reopen the archive extract each WAVE file and try to play it + if(dwErrCode == ERROR_SUCCESS) + { + dwErrCode = OpenExistingArchiveWithCopy(&Logger, NULL, szPlainName, &hMpq); + if(dwErrCode == ERROR_SUCCESS) + { + SearchArchive(&Logger, hMpq, SEARCH_FLAG_LOAD_FILES | SEARCH_FLAG_PLAY_WAVES, &dwFoundFiles, NULL); + SFileCloseArchive(hMpq); + } + + // Check if the number of found files is the same like the number of added files + // DOn;t forget that there will be (listfile) and (attributes) + if(dwFoundFiles != (dwAddedFiles + 2)) + { + Logger.PrintError("Number of found files does not match number of added files."); + dwErrCode = ERROR_FILE_CORRUPT; + } + } + + return dwErrCode; +} + +static DWORD TestCreateArchive_ListFilePos(LPCTSTR szPlainName) +{ + TFileData * pFileData; + LPCSTR szReaddedFile = "AddedFile_##.txt"; + LPCSTR szFileMask = "AddedFile_%02u.txt"; + TLogHelper Logger("ListFilePos", szPlainName); + HANDLE hMpq = NULL; // Handle of created archive + char szArchivedName[MAX_PATH]; + DWORD dwMaxFileCount = 0x0E; + DWORD dwFileCount = 0; + size_t i; + DWORD dwErrCode; + + // Create a new archive with the limit of 0x20 files + dwErrCode = CreateNewArchive(&Logger, szPlainName, MPQ_CREATE_ARCHIVE_V4 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES, dwMaxFileCount, &hMpq); + + // Add maximum files files + if(dwErrCode == ERROR_SUCCESS) + { + for(i = 0; i < dwMaxFileCount; i++) + { + sprintf(szArchivedName, szFileMask, i); + dwErrCode = AddFileToMpq(&Logger, hMpq, szArchivedName, "This is a text data.", 0, 0, ERROR_SUCCESS); + if(dwErrCode != ERROR_SUCCESS) + break; + + dwFileCount++; + } + } + + // Delete few middle files + if(dwErrCode == ERROR_SUCCESS) + { + for(i = 0; i < (dwMaxFileCount / 2); i++) + { + sprintf(szArchivedName, szFileMask, i); + dwErrCode = RemoveMpqFile(&Logger, hMpq, szArchivedName, ERROR_SUCCESS); + if(dwErrCode != ERROR_SUCCESS) + break; + + dwFileCount--; + } + } + + // Close the archive + if(hMpq != NULL) + SFileCloseArchive(hMpq); + hMpq = NULL; + + // Reopen the archive to catch any asserts + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = OpenExistingArchiveWithCopy(&Logger, NULL, szPlainName, &hMpq); + + // Check that (listfile) is at the end + if(dwErrCode == ERROR_SUCCESS) + { + pFileData = LoadMpqFile(&Logger, hMpq, LISTFILE_NAME); + if(pFileData != NULL) + { + if(pFileData->dwBlockIndex < dwFileCount) + Logger.PrintMessage("Unexpected file index of %s", LISTFILE_NAME); + STORM_FREE(pFileData); + } + + pFileData = LoadMpqFile(&Logger, hMpq, ATTRIBUTES_NAME); + if(pFileData != NULL) + { + if(pFileData->dwBlockIndex <= dwFileCount) + Logger.PrintMessage("Unexpected file index of %s", ATTRIBUTES_NAME); + STORM_FREE(pFileData); + } + + // Add new file to the archive. It should be added to the last position + dwErrCode = AddFileToMpq(&Logger, hMpq, szReaddedFile, "This is a re-added file.", 0, 0, ERROR_SUCCESS); + if(dwErrCode == ERROR_SUCCESS) + { + // Force update of the tables + SFileFlushArchive(hMpq); + + // Load the file + pFileData = LoadMpqFile(&Logger, hMpq, szReaddedFile); + if(pFileData != NULL) + { + if(pFileData->dwBlockIndex != dwFileCount) + Logger.PrintMessage("Unexpected file index of %s", szReaddedFile); + STORM_FREE(pFileData); + } + } + + SFileCloseArchive(hMpq); + } + + return dwErrCode; +} + +static DWORD TestCreateArchive_BigArchive(LPCTSTR szPlainName) +{ + TLogHelper Logger("BigMpqTest", szPlainName); + HANDLE hMpq = NULL; // Handle of created archive + TCHAR szLocalFileName[MAX_PATH]; + char szArchivedName[MAX_PATH]; + DWORD dwMaxFileCount = 0x20; + DWORD dwAddedCount = 0; + size_t i; + DWORD dwErrCode; + + // Create a new archive with the limit of 0x20 files + dwErrCode = CreateNewArchive(&Logger, szPlainName, MPQ_CREATE_ARCHIVE_V3 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES, dwMaxFileCount, &hMpq); + if(dwErrCode == ERROR_SUCCESS) + { + LPCSTR szFileMask = "AddedFile_%02u.txt"; + + // Now add few really big files + CreateFullPathName(szLocalFileName, _countof(szLocalFileName), szMpqSubDir, _T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ")); + Logger.UserTotal = (dwMaxFileCount / 2); + + for(i = 0; i < dwMaxFileCount / 2; i++) + { + sprintf(szArchivedName, szFileMask, i + 1); + dwErrCode = AddLocalFileToMpq(&Logger, hMpq, szArchivedName, szLocalFileName, 0, 0, true); + if(dwErrCode != ERROR_SUCCESS) + break; + + Logger.UserCount++; + dwAddedCount++; + } + } + + // Close the archive + if(hMpq != NULL) + SFileCloseArchive(hMpq); + hMpq = NULL; + + // Reopen the archive to catch any asserts + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = OpenExistingArchiveWithCopy(&Logger, NULL, szPlainName, &hMpq); + + // Check that (listfile) is at the end + if(dwErrCode == ERROR_SUCCESS) + { + CheckIfFileIsPresent(&Logger, hMpq, LISTFILE_NAME, true); + CheckIfFileIsPresent(&Logger, hMpq, ATTRIBUTES_NAME, true); + + SFileCloseArchive(hMpq); + } + + return dwErrCode; +} + +// "MPQ_2014_v4_Heroes_Replay.MPQ", "AddFile-replay.message.events" +static DWORD TestModifyArchive_ReplaceFile(LPCTSTR szMpqPlainName, LPCTSTR szFileName) +{ + TLogHelper Logger("ModifyTest", szMpqPlainName); + HANDLE hMpq = NULL; + TCHAR szLocalFileName[MAX_PATH]; + char szArchivedName[MAX_PATH]; + size_t nOffset = 0; + DWORD dwErrCode; + + // Open an existing archive + dwErrCode = OpenExistingArchiveWithCopy(&Logger, szMpqPlainName, szMpqPlainName, &hMpq); + + // Add the given file + if(dwErrCode == ERROR_SUCCESS) + { + // Get the name of archived file + if(!_tcsnicmp(szFileName, _T("AddFile-"), 8)) + nOffset = 8; + StringCopy(szArchivedName, _countof(szArchivedName), szFileName + nOffset); + + // Create the local file name + CreateFullPathName(szLocalFileName, _countof(szLocalFileName), szMpqSubDir, szFileName); + + // Add the file to MPQ + dwErrCode = AddLocalFileToMpq(&Logger, hMpq, + szArchivedName, + szLocalFileName, + MPQ_FILE_REPLACEEXISTING | MPQ_FILE_COMPRESS | MPQ_FILE_SINGLE_UNIT, + MPQ_COMPRESSION_ZLIB, + true); + } + + // Reopen the MPQ and compact it + if(dwErrCode == ERROR_SUCCESS) + { + // Compact the archive + Logger.PrintProgress("Compacting archive %s ...", szMpqPlainName); + if(!SFileSetCompactCallback(hMpq, CompactCallback, &Logger)) + dwErrCode = Logger.PrintError(_T("Failed to compact archive %s"), szMpqPlainName); + + if(!SFileCompactArchive(hMpq, NULL, 0)) + dwErrCode = GetLastError(); + + SFileCloseArchive(hMpq); + } + + // Try to open the archive again + if(dwErrCode == ERROR_SUCCESS) + { + CreateFullPathName(szLocalFileName, _countof(szLocalFileName), NULL, szMpqPlainName); + dwErrCode = OpenExistingArchive(&Logger, szLocalFileName, 0, &hMpq); + if(dwErrCode == ERROR_SUCCESS) + SFileCloseArchive(hMpq); + } + + return dwErrCode; +} + +//----------------------------------------------------------------------------- +// Tables + +static const TEST_INFO TestList_StreamOps[] = +{ + {_T("MPQ_2013_v4_alternate-original.MPQ"), NULL, 0}, + {_T("MPQ_2013_v4_alternate-original.MPQ"), NULL, STREAM_FLAG_READ_ONLY}, + {_T("MPQ_2013_v4_alternate-complete.MPQ"), NULL, STREAM_FLAG_USE_BITMAP}, + {_T("part-file://MPQ_2009_v2_WoW_patch.MPQ.part"), NULL, 0}, + {_T("blk4-file://streaming/model.MPQ.0"), NULL, STREAM_PROVIDER_BLOCK4}, + {_T("mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE"), NULL, STREAM_PROVIDER_MPQE} +}; + +static const TEST_INFO TestList_MasterMirror[] = +{ + {_T("part-file://MPQ_2009_v1_patch-created.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), 0}, + {_T("part-file://MPQ_2009_v1_patch-partial.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), 1}, + {_T("part-file://MPQ_2009_v1_patch-complete.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), 1}, + {_T("MPQ_2013_v4_alternate-created.MPQ"), _T("MPQ_2013_v4_alternate-original.MPQ"), 0}, + {_T("MPQ_2013_v4_alternate-incomplete.MPQ"), _T("MPQ_2013_v4_alternate-incomplete.MPQ"), 1}, + {_T("MPQ_2013_v4_alternate-complete.MPQ"), _T("MPQ_2013_v4_alternate-original.MPQ"), 1}, + + // Takes hell a lot of time!!! +// {_T("MPQ_2013_v4_alternate-downloaded.MPQ"), _T("http://www.zezula.net\\mpqs\\alternate.zip"), 0} +}; + +static const TEST_INFO Test_Mpqs[] = +{ + + // Correct or damaged archives + {_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), NULL, 0, "music\\dintro.wav", "File00000023.xxx"}, + {_T("MPQ_2016_v1_D2XP_IX86_1xx_114a.mpq"), NULL, 0, "waitingroombkgd.dc6"}, // Update MPQ from Diablo II (patch 2016) + {_T("MPQ_2018_v1_icon_error.w3m"), NULL, 0, "file00000002.blp"}, + {_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), _T("ListFile_Blizzard.txt")}, // File whose archive's (signature) file has flags = 0x90000000 + {_T("MPQ_2012_v2_EmptyMpq.MPQ") }, // Empty archive (found in WoW cache - it's just a header) + {_T("MPQ_2013_v4_EmptyMpq.MPQ") }, // Empty archive (created artificially - it's just a header) + {_T("MPQ_2013_v4_patch-base-16357.MPQ") }, // Empty archive (found in WoW cache - it's just a header) + {_T("MPQ_2011_v4_InvalidHetEntryCount.MPQ") }, // Empty archive (A buggy MPQ with invalid HET entry count) + {_T("MPQ_2002_v1_BlockTableCut.MPQ") }, // Truncated archive + {_T("MPQ_2010_v2_HasUserData.s2ma") }, // MPQ that actually has user data + {_T("MPQ_2014_v1_AttributesOneEntryLess.w3x") }, // Warcraft III map whose "(attributes)" file has (BlockTableSize-1) entries + {_T("MPQ_2020_v1_AHF04patch.mix") }, // MIX file + {_T("MPQ_2010_v3_expansion-locale-frFR.MPQ") }, // MPQ archive v 3.0 + {_T("mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE") }, // Encrypted archive from Starcraft II installer + {_T("MPx_2013_v1_LongwuOnline.mpk") }, // MPK archive from Longwu online + {_T("MPx_2013_v1_WarOfTheImmortals.sqp"), _T("ListFile_WarOfTheImmortals.txt") }, // SQP archive from War of the Immortals + {_T("part-file://MPQ_2010_v2_HashTableCompressed.MPQ.part") }, // Partial MPQ with compressed hash table + {_T("blk4-file://streaming/model.MPQ.0")}, // Archive that is merged with multiple files + {_T("MPQ_2002_v1_ProtectedMap_InvalidUserData.w3x")}, + {_T("MPQ_2002_v1_ProtectedMap_InvalidMpqFormat.w3x")}, + {_T("MPQ_2002_v1_ProtectedMap_Spazzler.w3x")}, // Warcraft III map locked by the Spazzler protector + {_T("MPQ_2014_v1_ProtectedMap_Spazzler2.w3x")}, // Warcraft III map locked by the Spazzler protector + {_T("MPQ_2014_v1_ProtectedMap_Spazzler3.w3x")}, // Warcraft III map locked by the Spazzler protector + {_T("MPQ_2002_v1_ProtectedMap_BOBA.w3m")}, // Warcraft III map locked by the BOBA protector + {_T("MPQ_2015_v1_ProtectedMap_KangTooJee.w3x")}, + {_T("MPQ_2015_v1_ProtectedMap_Somj2hM16.w3x")}, + {_T("MPQ_2015_v1_ProtectedMap_Spazy.w3x")}, // Warcraft III map locked by Spazy protector + {_T("MPQ_2015_v1_MessListFile.mpq")}, + {_T("MPQ_2016_v1_ProtectedMap_TableSizeOverflow.w3x")}, + {_T("MPQ_2016_v1_ProtectedMap_HashOffsIsZero.w3x")}, + {_T("MPQ_2016_v1_ProtectedMap_Somj2.w3x")}, // Something like Somj 2.0 + {_T("MPQ_2016_v1_WME4_4.w3x")}, // Protector from China (2016-05-27) + {_T("MPQ_2016_v1_SP_(4)Adrenaline.w3x")}, + {_T("MPQ_2016_v1_ProtectedMap_1.4.w3x")}, + {_T("MPQ_2016_v1_KoreanFile.w3m")}, + {_T("MPQ_2017_v1_Eden_RPG_S2_2.5J.w3x")}, // Load map protected by PG1.11.973 + {_T("MPQ_2017_v1_BigDummyFiles.w3x")}, + {_T("MPQ_2017_v1_TildeInFileName.mpq")}, + {_T("MPQ_2018_v1_EWIX_v8_7.w3x"), NULL, 0, "BlueCrystal.mdx"}, + {_T("MPQ_2020_v4_FakeMpqHeaders.SC2Mod")}, // Archive that has two fake headers before the real one + {_T("MPQ_2020_v4_NP_Protect_1.s2ma")}, // SC2 map that is protected by the NP_Protect + {_T("MPQ_2020_v4_NP_Protect_2.s2ma")}, // SC2 map that is protected by the NP_Protect + + // Protected archives + {_T("MPQ_2015_v1_flem1.w3x"), NULL, TEST_FLAG_PROTECTED | 20, "1c4c13e627658c473e84d94371e31f37"}, + {_T("MPQ_2002_v1_ProtectedMap_HashTable_FakeValid.w3x"), NULL, TEST_FLAG_PROTECTED | 114, "5250975ed917375fc6540d7be436d4de"}, +}; + +//----------------------------------------------------------------------------- +// Main + +int _tmain(int argc, TCHAR * argv[]) +{ + DWORD dwErrCode = ERROR_SUCCESS; + +#if defined(_MSC_VER) && defined(_DEBUG) + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); +#endif // defined(_MSC_VER) && defined(_DEBUG) + + // Initialize storage and mix the random number generator + printf("==== Test Suite for StormLib version %s ====\n", STORMLIB_VERSION_STRING); + dwErrCode = InitializeMpqDirectory(argv, argc); + + // + // Tests on a local listfile + // + /* + if(dwErrCode == ERROR_SUCCESS) + { + TestOnLocalListFile(_T("FLAT-MAP:ListFile_Blizzard.txt")); + dwErrCode = TestOnLocalListFile(_T("ListFile_Blizzard.txt")); + } + */ + // + // Open all files from the command line + // + + TestArchive(_T("ProblemMpqArchive.SC2Replay"), NULL, 0, "replay.game.events", NULL); + for(int i = 1; i < argc; i++) + { + TestOpenArchive_CompactArchive(argv[i], _T("TestArchiveCopy.mpq"), false); + } + + // + // Search all testing archives and verify their SHA1 hash + // + + if(dwErrCode == ERROR_SUCCESS) + { + dwErrCode = FindFiles(ForEachFile_VerifyFileChecksum, szMpqSubDir); + } + + // + // Test file stream operations + // + + if(dwErrCode == ERROR_SUCCESS) + { + for(size_t i = 0; i < _countof(TestList_StreamOps); i++) + { + dwErrCode = TestFileStreamOperations(TestList_StreamOps[i].szMpqName1, TestList_StreamOps[i].dwFlags); + if(dwErrCode != ERROR_SUCCESS) + break; + } + } + + // + // Test master-mirror reading operations + // + + if(dwErrCode == ERROR_SUCCESS) + { + for(size_t i = 0; i < _countof(TestList_MasterMirror); i++) + { + dwErrCode = TestReadFile_MasterMirror(TestList_MasterMirror[i].szMpqName1, + TestList_MasterMirror[i].szMpqName2, + TestList_MasterMirror[i].dwFlags != 0); + if(dwErrCode != ERROR_SUCCESS) + break; + } + } + + // + // Test opening various archives - correct, damaged, protected + // + + if(dwErrCode == ERROR_SUCCESS) + { + for(size_t i = 0; i < _countof(Test_Mpqs); i++) + { + dwErrCode = TestArchive(Test_Mpqs[i].szMpqName1, // Plain archive name + Test_Mpqs[i].szMpqName2, // List file (NULL if none) + Test_Mpqs[i].dwFlags, // What exactly to do + Test_Mpqs[i].szFileName1, // The first name of the open file + Test_Mpqs[i].szFileName2); // The second name of the open file + if(dwErrCode != ERROR_SUCCESS) + break; + } + } + + // Open the multi-file archive with wrong prefix to see how StormLib deals with it + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_WillFail(_T("flat-file://streaming/model.MPQ.0")); + + // Open every MPQ that we have in the storage + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = FindFiles(ForEachFile_OpenArchive, NULL); + + // Test on an archive that has been invalidated by extending an old valid MPQ + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_Corrupt(_T("MPQ_2013_vX_Battle.net.MPQ")); + + // Open a patched archive + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_Patched(PatchList_StarCraft, "music\\terran1.wav", 0); + + // Open a patched archive + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_Patched(PatchList_WoW_OldWorld13286, "OldWorld\\World\\Model.blob", 2); + + // Open a patched archive + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_Patched(PatchList_WoW_15050, "World\\Model.blob", 8); + + // Open a patched archive + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_Patched(PatchList_WoW_16965, "DBFilesClient\\BattlePetNPCTeamMember.db2", 0); + + // Open a patched archive + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_Patched(PatchList_SC2_32283, "TriggerLibs\\natives.galaxy", 6); + + // Open a patched archive + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_Patched(PatchList_SC2_34644, "TriggerLibs\\GameData\\GameData.galaxy", 2); + + // Open a patched archive with new format of BSDIFF patch + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_Patched(PatchList_SC2_34644_Maps, "Maps\\Campaign\\THorner03.SC2Map\\BankList.xml", 3); + + // Open a patched archive + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_Patched(PatchList_SC2_32283_enGB, "Assets\\Textures\\startupimage.dds", 0, true); + + // Open a patched archive where the "StreamingBuckets.txt" in the patch doesn't contain MPQ_FILE_PATCH_FILE + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_Patched(PatchList_SC2_36281_enGB, "LocalizedData\\GameHotkeys.txt", 6); + + // Open a patched archive + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_Patched(PatchList_HS_3604_enGB, "Hearthstone.exe", 1); + + // Open a patched archive + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_Patched(PatchList_HS_6898_enGB, "Hearthstone_Data\\Managed\\Assembly-Csharp.dll", 10); + + // Check the opening archive for read-only + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_ReadOnly(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), true); + + // Check the opening archive for read-only + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_ReadOnly(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), false); + + // Check the SFileGetFileInfo function + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_GetFileInfo(_T("MPQ_2002_v1_StrongSignature.w3m"), _T("MPQ_2013_v4_SC2_EmptyMap.SC2Map")); + + // Downloadable MPQ archive + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_MasterMirror(_T("part-file://MPQ_2009_v1_patch-partial.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), "world\\Azeroth\\DEADMINES\\PASSIVEDOODADS\\GOBLINMELTINGPOT\\DUST2.BLP", false); + + // Downloadable MPQ archive + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_MasterMirror(_T("MPQ_2013_v4_alternate-downloaded.MPQ"), _T("MPQ_2013_v4_alternate-original.MPQ"), "alternate\\DUNGEONS\\TEXTURES\\ICECROWN\\GATE\\jlo_IceC_Floor_Thrown.blp", false); + + // Check archive signature + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_VerifySignature(_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), _T("STANDARD.SNP")); + + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_VerifySignature(_T("MPQ_1999_v1_WeakSignature.exe"), _T("War2Patch_202.exe")); + + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_VerifySignature(_T("MPQ_2003_v1_WeakSignatureEmpty.exe"), _T("WoW-1.2.3.4211-enUS-patch.exe")); + + // Check archive signature + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_VerifySignature(_T("MPQ_2002_v1_StrongSignature.w3m"), _T("(10)DustwallowKeys.w3m")); + + // Compact the archive + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_CompactArchive(_T("MPQ_2010_v3_expansion-locale-frFR.MPQ"), _T("StormLibTest_CraftedMpq1_v3.mpq"), true); + + // Compact the archive + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_CompactArchive(_T("MPQ_2016_v1_00000.pak"), _T("MPQ_2016_v1_00000.pak"), false); + + // Open a MPQ (add custom user data to it) + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_CompactArchive(_T("MPQ_2013_v4_SC2_EmptyMap.SC2Map"), _T("StormLibTest_CraftedMpq2_v4.mpq"), true); + + // Open a MPQ (add custom user data to it) + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_CompactArchive(_T("MPQ_2013_v4_expansion1.MPQ"), _T("StormLibTest_CraftedMpq3_v4.mpq"), true); + + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestAddFile_FullTable(_T("MPQ_2014_v1_out1.w3x")); + + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestAddFile_FullTable(_T("MPQ_2014_v1_out2.w3x")); + + // Test modifying file with no (listfile) and no (attributes) + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestAddFile_ListFileTest(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), false, false); + + // Test modifying an archive that contains (listfile) and (attributes) + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestAddFile_ListFileTest(_T("MPQ_2013_v4_SC2_EmptyMap.SC2Map"), true, true); + + // Create an empty archive v2 + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_EmptyMpq(_T("StormLibTest_EmptyMpq_v2.mpq"), MPQ_CREATE_ARCHIVE_V2 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES); + + // Create an empty archive v4 + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_EmptyMpq(_T("StormLibTest_EmptyMpq_v4.mpq"), MPQ_CREATE_ARCHIVE_V4 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES); + + // Test creating of an archive the same way like MPQ Editor does + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_TestGaps(_T("StormLibTest_GapsTest.mpq")); + + // Test creating of an archive with non standard file names + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_NonStdNames(_T("StormLibTest_NonStdNames.mpq")); + + // Sign an existing non-signed archive + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_SignExisting(_T("MPQ_1998_v1_StarDat.mpq")); + + // Open a signed archive, add a file and verify the signature + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestOpenArchive_ModifySigned(_T("MPQ_1999_v1_WeakSignature.exe"), _T("War2Patch_202.exe")); + + // Create new archive and sign it + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_Signed(_T("MPQ_1999_v1_WeakSigned1.mpq"), true); + + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_Signed(_T("MPQ_1999_v1_WeakSigned2.mpq"), false); + + // Test creating of an archive the same way like MPQ Editor does + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_MpqEditor(_T("StormLibTest_MpqEditorTest.mpq"), "AddedFile.exe"); + + // Create an archive and fill it with files up to the max file count + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), 0); + + // Create an archive and fill it with files up to the max file count + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), MPQ_CREATE_LISTFILE); + + // Create an archive and fill it with files up to the max file count + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), MPQ_CREATE_ATTRIBUTES); + + // Create an archive and fill it with files up to the max file count + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), MPQ_CREATE_ATTRIBUTES | MPQ_CREATE_LISTFILE); + + // Create an archive, and increment max file count several times + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_IncMaxFileCount(_T("StormLibTest_IncMaxFileCount.mpq")); + + // Create a MPQ archive with UNICODE names + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_UnicodeNames(); + + // Create a MPQ file, add files with various flags + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_FileFlagTest(_T("StormLibTest_FileFlagTest.mpq")); + + // Create a MPQ file, add a mono-WAVE file with various compressions + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_WaveCompressionsTest(_T("StormLibTest_AddWaveMonoTest.mpq"), _T("AddFile-Mono.wav")); + + // Create a MPQ file, add a mono-WAVE with 8 bits per sample file with various compressions + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_WaveCompressionsTest(_T("StormLibTest_AddWaveMonoBadTest.mpq"), _T("AddFile-MonoBad.wav")); + + // Create a MPQ file, add a stereo-WAVE file with various compressions + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_WaveCompressionsTest(_T("StormLibTest_AddWaveStereoTest.mpq"), _T("AddFile-Stereo.wav")); + + // Check if the listfile is always created at the end of the file table in the archive + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_ListFilePos(_T("StormLibTest_ListFilePos.mpq")); + + // Open a MPQ (add custom user data to it) + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestCreateArchive_BigArchive(_T("StormLibTest_BigArchive_v4.mpq")); + + // Test replacing a file with zero size file + if(dwErrCode == ERROR_SUCCESS) + dwErrCode = TestModifyArchive_ReplaceFile(_T("MPQ_2014_v4_Base.StormReplay"), _T("AddFile-replay.message.events")); + +#ifdef _MSC_VER + _CrtDumpMemoryLeaks(); +#endif // _MSC_VER + + return dwErrCode; +} diff --git a/StormLib/test/TLogHelper.cpp b/StormLib/test/TLogHelper.cpp new file mode 100644 index 000000000..003b0f532 --- /dev/null +++ b/StormLib/test/TLogHelper.cpp @@ -0,0 +1,441 @@ +/*****************************************************************************/ +/* TLogHelper.cpp Copyright (c) Ladislav Zezula 2013 */ +/*---------------------------------------------------------------------------*/ +/* Helper class for reporting StormLib tests */ +/* This file should be included directly from StormTest.cpp using #include */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 26.11.13 1.00 Lad The first version of TLogHelper.cpp */ +/*****************************************************************************/ + +//----------------------------------------------------------------------------- +// Definition of the TLogHelper class + +class TLogHelper +{ + public: + + TLogHelper(const char * szNewMainTitle = NULL, const TCHAR * szNewSubTitle1 = NULL, const TCHAR * szNewSubTitle2 = NULL); + ~TLogHelper(); + +#if defined(UNICODE) || defined(UNICODE) + // TCHAR-based functions. They are only needed on UNICODE builds. + // On ANSI builds is TCHAR = char, so we don't need them at all + int PrintWithClreol(const TCHAR * szFormat, va_list argList, bool bPrintPrefix, bool bPrintLastError, bool bPrintEndOfLine); + void PrintProgress(const TCHAR * szFormat, ...); + void PrintMessage(const TCHAR * szFormat, ...); + int PrintErrorVa(const TCHAR * szFormat, ...); + int PrintError(const TCHAR * szFormat, const TCHAR * szFileName = NULL); +#endif // defined(UNICODE) || defined(UNICODE) + + // ANSI functions + DWORD PrintWithClreol(const char * szFormat, va_list argList, bool bPrintPrefix, bool bPrintLastError, bool bPrintEndOfLine); + void PrintProgress(const char * szFormat, ...); + void PrintMessage(const char * szFormat, ...); + DWORD PrintErrorVa(const char * szFormat, ...); + DWORD PrintError(const char * szFormat, const char * szFileName = NULL); + + const char * UserString; + unsigned int UserCount; + unsigned int UserTotal; + bool bDontPrintResult; + + protected: + +#if defined(UNICODE) || defined(UNICODE) + TCHAR * CopyFormatCharacter(TCHAR * szBuffer, const TCHAR *& szFormat); +#endif + char * CopyFormatCharacter(char * szBuffer, const char *& szFormat); + int GetConsoleWidth(); + + const char * szMainTitle; // Title of the text (usually name) + const TCHAR * szSubTitle1; // Title of the text (can be name of the tested file) + const TCHAR * szSubTitle2; // Title of the text (can be name of the tested file) + size_t nTextLength; // Length of the previous progress message + bool bMessagePrinted; +}; + +//----------------------------------------------------------------------------- +// String replacements for format strings + +#ifdef _MSC_VER +#define I64u_t _T("%I64u") +#define I64u_a "%I64u" +#define I64X_t _T("%I64X") +#define I64X_a "%I64X" +#else +#define I64u_t _T("%llu") +#define I64u_a "%llu" +#define I64X_t _T("%llX") +#define I64X_a "%llX" +#endif + +//----------------------------------------------------------------------------- +// Constructor and destructor + + +TLogHelper::TLogHelper(const char * szNewMainTitle, const TCHAR * szNewSubTitle1, const TCHAR * szNewSubTitle2) +{ + TCHAR szMainTitleT[0x80]; + + UserString = ""; + UserCount = 1; + UserTotal = 1; + + // Fill the test line structure + szMainTitle = szNewMainTitle; + szSubTitle1 = szNewSubTitle1; + szSubTitle2 = szNewSubTitle2; + nTextLength = 0; + bMessagePrinted = false; + bDontPrintResult = false; + + // Copy the UNICODE main title + StringCopy(szMainTitleT, _countof(szMainTitleT), szMainTitle); + + // Print the initial information + if(szMainTitle != NULL) + { + if(szSubTitle1 != NULL && szSubTitle2 != NULL) + _tprintf(_T("Running %s (%s+%s) ..."), szMainTitleT, szSubTitle1, szSubTitle2); + else if(szSubTitle1 != NULL) + _tprintf(_T("Running %s (%s) ..."), szMainTitleT, szSubTitle1); + else + _tprintf(_T("Running %s ..."), szMainTitleT); + } +} + +TLogHelper::~TLogHelper() +{ + const TCHAR * szSaveSubTitle1 = szSubTitle1; + const TCHAR * szSaveSubTitle2 = szSubTitle2; + TCHAR szSaveMainTitle[0x80]; + + // Set both to NULL so they won't be printed + StringCopy(szSaveMainTitle, _countof(szSaveMainTitle), szMainTitle); + szSubTitle1 = NULL; + szSubTitle2 = NULL; + szMainTitle = NULL; + + // Print the final information + if(szSaveMainTitle != NULL && bMessagePrinted == false) + { + if(bDontPrintResult == false) + { + if(szSaveSubTitle1 != NULL && szSaveSubTitle2 != NULL) + PrintMessage(_T("%s (%s+%s) succeeded."), szSaveMainTitle, szSaveSubTitle1, szSaveSubTitle2); + else if(szSaveSubTitle1 != NULL) + PrintMessage(_T("%s (%s) succeeded."), szSaveMainTitle, szSaveSubTitle1); + else + PrintMessage(_T("%s succeeded."), szSaveMainTitle); + } + else + { + PrintProgress(" "); + printf("\r"); + } + } + +#if defined(_MSC_VER) && defined(_DEBUG) + if(_CrtDumpMemoryLeaks()) + { + PrintMessage(_T("Memory leak(s) detected after %s.\n"), szSaveMainTitle); + } +#endif // _MSC_VER +} + +//----------------------------------------------------------------------------- +// TCHAR-based functions. They are only needed on UNICODE builds. +// On ANSI builds is TCHAR = char, so we don't need them at all + +#if defined(UNICODE) || defined(UNICODE) +int TLogHelper::PrintWithClreol(const TCHAR * szFormat, va_list argList, bool bPrintPrefix, bool bPrintLastError, bool bPrintEndOfLine) +{ + TCHAR szFormatBuff[0x200]; + TCHAR szMessage[0x200]; + TCHAR * szBuffer = szFormatBuff; + int nRemainingWidth; + int nConsoleWidth = GetConsoleWidth(); + int nLength = 0; + int nError = GetLastError(); + + // Always start the buffer with '\r' + *szBuffer++ = '\r'; + + // Print the prefix, if needed + if(szMainTitle != NULL && bPrintPrefix) + { + while(szMainTitle[nLength] != 0) + *szBuffer++ = szMainTitle[nLength++]; + + *szBuffer++ = ':'; + *szBuffer++ = ' '; + } + + // Copy the message format itself. Replace %s with "%s", unless it's (%s) + if(szFormat != NULL) + { + while(szFormat[0] != 0) + { + szBuffer = CopyFormatCharacter(szBuffer, szFormat); + } + } + + // Append the last error + if(bPrintLastError) + { + nLength = _stprintf(szBuffer, _T(" (error code: %u)"), nError); + szBuffer += nLength; + } + + // Create the result string + szBuffer[0] = 0; + nLength = _vstprintf(szMessage, szFormatBuff, argList); + szBuffer = szMessage + nLength; + + // Shall we pad the string? + if(nLength < nConsoleWidth) + { + // Calculate the remaining width + nRemainingWidth = nConsoleWidth - nLength - 1; + + // Pad the string with spaces to fill it up to the end of the line + for(int i = 0; i < nRemainingWidth; i++) + *szBuffer++ = 0x20; + } + + // Put the newline, if requested + *szBuffer++ = bPrintEndOfLine ? '\n' : 0; + *szBuffer = 0; + + // Remember if we printed a message + if(bPrintEndOfLine) + bMessagePrinted = true; + + // Spit out the text in one single printf + _tprintf(_T("%s"), szMessage); + return nError; +} + +void TLogHelper::PrintProgress(const TCHAR * szFormat, ...) +{ + va_list argList; + + va_start(argList, szFormat); + PrintWithClreol(szFormat, argList, true, false, false); + va_end(argList); +} + +void TLogHelper::PrintMessage(const TCHAR * szFormat, ...) +{ + va_list argList; + + va_start(argList, szFormat); + PrintWithClreol(szFormat, argList, true, false, true); + va_end(argList); +} + +int TLogHelper::PrintErrorVa(const TCHAR * szFormat, ...) +{ + va_list argList; + int nResult; + + va_start(argList, szFormat); + nResult = PrintWithClreol(szFormat, argList, true, true, true); + va_end(argList); + + return nResult; +} + +int TLogHelper::PrintError(const TCHAR * szFormat, const TCHAR * szFileName) +{ + return PrintErrorVa(szFormat, szFileName); +} +#endif // defined(UNICODE) || defined(UNICODE) + +//----------------------------------------------------------------------------- +// ANSI functions + +DWORD TLogHelper::PrintWithClreol(const char * szFormat, va_list argList, bool bPrintPrefix, bool bPrintLastError, bool bPrintEndOfLine) +{ + char szFormatBuff[0x200]; + char szMessage[0x200]; + char * szBuffer = szFormatBuff; + int nRemainingWidth; + int nConsoleWidth = GetConsoleWidth(); + int nLength = 0; + DWORD dwErrCode = GetLastError(); + + // Always start the buffer with '\r' + *szBuffer++ = '\r'; + + // Print the prefix, if needed + if(szMainTitle != NULL && bPrintPrefix) + { + while(szMainTitle[nLength] != 0) + *szBuffer++ = (char)szMainTitle[nLength++]; + + *szBuffer++ = ':'; + *szBuffer++ = ' '; + } + + // Copy the message format itself. Replace %s with "%s", unless it's (%s) + if(szFormat != NULL) + { + while(szFormat[0] != 0) + { + szBuffer = CopyFormatCharacter(szBuffer, szFormat); + } + } + + // Append the last error + if(bPrintLastError) + { + nLength = sprintf(szBuffer, " (error code: %u)", dwErrCode); + szBuffer += nLength; + } + + // Create the result string + szBuffer[0] = 0; + nLength = vsprintf(szMessage, szFormatBuff, argList); + + // Shall we pad the string? + szBuffer = szMessage + nLength; + if(nLength < nConsoleWidth) + { + // Calculate the remaining width + nRemainingWidth = nConsoleWidth - nLength - 1; + + // Pad the string with spaces to fill it up to the end of the line + for(int i = 0; i < nRemainingWidth; i++) + *szBuffer++ = 0x20; + } + + // Put the newline, if requested + *szBuffer++ = bPrintEndOfLine ? '\n' : '\r'; + *szBuffer = 0; + + // Remember if we printed a message + if(bPrintEndOfLine) + bMessagePrinted = true; + + // Spit out the text in one single printf + printf("%s", szMessage); + return dwErrCode; +} + +void TLogHelper::PrintProgress(const char * szFormat, ...) +{ + va_list argList; + + va_start(argList, szFormat); + PrintWithClreol(szFormat, argList, true, false, false); + va_end(argList); +} + +void TLogHelper::PrintMessage(const char * szFormat, ...) +{ + va_list argList; + + va_start(argList, szFormat); + PrintWithClreol(szFormat, argList, true, false, true); + va_end(argList); +} + +DWORD TLogHelper::PrintErrorVa(const char * szFormat, ...) +{ + va_list argList; + DWORD dwErrCode; + + va_start(argList, szFormat); + dwErrCode = PrintWithClreol(szFormat, argList, true, true, true); + va_end(argList); + + return dwErrCode; +} + +DWORD TLogHelper::PrintError(const char * szFormat, const char * szFileName) +{ + return PrintErrorVa(szFormat, szFileName); +} + +//----------------------------------------------------------------------------- +// Protected functions + +#ifdef _UNICODE +TCHAR * TLogHelper::CopyFormatCharacter(TCHAR * szBuffer, const TCHAR *& szFormat) +{ + static const TCHAR * szStringFormat = _T("\"%s\""); + static const TCHAR * szUint64Format = I64u_t; + + // String format + if(szFormat[0] == '%') + { + if(szFormat[1] == 's' && szFormat[2] != ')') + { + _tcscpy(szBuffer, szStringFormat); + szFormat += 2; + return szBuffer + _tcslen(szStringFormat); + } + + // Replace %I64u with the proper platform-dependent suffix + if(szFormat[1] == 'I' && szFormat[2] == '6' && szFormat[3] == '4' && szFormat[4] == 'u') + { + _tcscpy(szBuffer, szUint64Format); + szFormat += 5; + return szBuffer + _tcslen(szUint64Format); + } + } + + // Copy the character as-is + *szBuffer++ = *szFormat++; + return szBuffer; +} +#endif + +char * TLogHelper::CopyFormatCharacter(char * szBuffer, const char *& szFormat) +{ + static const char * szStringFormat = "\"%s\""; + static const char * szUint64Format = I64u_a; + + // String format + if(szFormat[0] == '%') + { + if(szFormat[1] == 's' && szFormat[2] != ')') + { + strcpy(szBuffer, szStringFormat); + szFormat += 2; + return szBuffer + strlen(szStringFormat); + } + + // Replace %I64u with the proper platform-dependent suffix + if(szFormat[1] == 'I' && szFormat[2] == '6' && szFormat[3] == '4' && szFormat[4] == 'u') + { + strcpy(szBuffer, szUint64Format); + szFormat += 5; + return szBuffer + strlen(szUint64Format); + } + } + + // Copy the character as-is + *szBuffer++ = *szFormat++; + return szBuffer; +} + +int TLogHelper::GetConsoleWidth() +{ +#ifdef STORMLIB_WINDOWS + + CONSOLE_SCREEN_BUFFER_INFO ScreenInfo; + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ScreenInfo); + return (int)(ScreenInfo.srWindow.Right - ScreenInfo.srWindow.Left); + +#else + + // On non-Windows platforms, we assume that width of the console line + // is 80 characters + return 120; + +#endif +} diff --git a/ZAPDTR/ZAPD/ZAPD.vcxproj b/ZAPDTR/ZAPD/ZAPD.vcxproj index 940d3b2ed..ad3c3e08c 100644 --- a/ZAPDTR/ZAPD/ZAPD.vcxproj +++ b/ZAPDTR/ZAPD/ZAPD.vcxproj @@ -72,15 +72,15 @@ - $(OutDir);$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\..\OTRExporter\packages\libpng-v142.1.6.37.2\build\native\lib\x64\v142\Debug\;$(ProjectDir)..\..\libultraship\libultraship\;$(LibraryPath) - $(ProjectDir)..\ZAPDUtils;$(ProjectDir)..\lib\tinyxml2;$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\lib\elfio;$(ProjectDir)..\lib\stb;$(ProjectDir);$(IncludePath) + $(OutDir);$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\..\OTRExporter\packages\libpng-v142.1.6.37.2\build\native\lib\x64\v142\Debug\;$(ProjectDir)..\..\libultraship\libultraship\;$(ProjectDir)..\..\StormLib\bin\StormLib\x64\DebugUS\;$(LibraryPath) + $(ProjectDir)..\ZAPDUtils;$(ProjectDir)..\lib\tinyxml2;$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\lib\elfio;$(ProjectDir)..\lib\stb;$(ProjectDir);$(ProjectDir)..\..\StormLib\src\;$(IncludePath) MinimumRecommendedRules.ruleset - $(ProjectDir)..\ZAPDUtils;$(ProjectDir)..\lib\tinyxml2;$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\lib\elfio;$(ProjectDir)..\lib\stb;$(ProjectDir);$(IncludePath) - $(OutDir);$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\..\OTRExporter\packages\libpng-v142.1.6.37.2\build\native\lib\x64\v142\Debug\;$(ProjectDir)..\..\libultraship\libultraship\;$(LibraryPath) + $(ProjectDir)..\ZAPDUtils;$(ProjectDir)..\lib\tinyxml2;$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\lib\elfio;$(ProjectDir)..\lib\stb;$(ProjectDir);$(ProjectDir)..\..\StormLib\src\;$(IncludePath) + $(OutDir);$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\..\OTRExporter\packages\libpng-v142.1.6.37.2\build\native\lib\x64\v142\Debug\;$(ProjectDir)..\..\libultraship\libultraship\;$(ProjectDir)..\..\StormLib\bin\StormLib\x64\ReleaseUS\;$(LibraryPath) false MinimumRecommendedRules.ruleset diff --git a/libultraship/libultraship/Archive.cpp b/libultraship/libultraship/Archive.cpp index 8bc4948b2..c81355d9a 100644 --- a/libultraship/libultraship/Archive.cpp +++ b/libultraship/libultraship/Archive.cpp @@ -59,8 +59,16 @@ namespace Ship { FileToLoad->path = filePath; } - if (!SFileOpenFileEx(mainMPQ, filePath.c_str(), 0, &fileHandle)) { - SPDLOG_ERROR("({}) Failed to open file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str()); + bool attempt = SFileOpenFileEx(mainMPQ, filePath.c_str(), 0, &fileHandle); + + /*if (!attempt) + { + std::string filePathAlt = StringHelper::Replace(filePath, "/", "\\"); + attempt |= SFileOpenFileEx(mainMPQ, filePathAlt.c_str(), 0, &fileHandle); + }*/ + + if (!attempt) { + printf("({%i}) Failed to open file {%s} from mpq archive {%s}", GetLastError(), filePath.c_str(), MainPath.c_str()); std::unique_lock Lock(FileToLoad->FileLoadMutex); FileToLoad->bHasLoadError = true; return FileToLoad; @@ -339,11 +347,13 @@ namespace Ship { std::vector lines = StringHelper::Split(std::string(listFile->buffer.get(), listFile->dwBufferSize), "\n"); for (size_t i = 0; i < lines.size(); i++) { - std::string line = StringHelper::Strip(lines[i], "\r"); - //uint64_t hash = StringHelper::StrToL(lines[i], 16); + std::string line = StringHelper::Replace(StringHelper::Strip(lines[i], "\r"), "/", "\\"); + std::string line2 = StringHelper::Replace(line, "\\", "/"); - uint64_t hash = CRC64(line.c_str()); + uint64_t hash = CRC64(StringHelper::Replace(line, "/", "\\").c_str()); + uint64_t hash2 = CRC64(StringHelper::Replace(line, "\\", "/").c_str()); hashes[hash] = line; + hashes[hash2] = line2; } } diff --git a/libultraship/libultraship/Archive.h b/libultraship/libultraship/Archive.h index b21ad9c73..6294606ac 100644 --- a/libultraship/libultraship/Archive.h +++ b/libultraship/libultraship/Archive.h @@ -10,7 +10,7 @@ #include #include "Resource.h" //#include "Lib/StrHash64.h" -#include "Lib/StormLib/StormLib.h" +#include "StormLib.h" namespace Ship diff --git a/libultraship/libultraship/ResourceMgr.cpp b/libultraship/libultraship/ResourceMgr.cpp index 32b1428b6..bd2b6e142 100644 --- a/libultraship/libultraship/ResourceMgr.cpp +++ b/libultraship/libultraship/ResourceMgr.cpp @@ -5,7 +5,7 @@ #include "Archive.h" #include "GameVersions.h" #include -#include "Lib/StormLib/StormLib.h" +#include "StormLib.h" namespace Ship { diff --git a/libultraship/libultraship/StormLibDUS32.lib b/libultraship/libultraship/StormLibDUS32.lib deleted file mode 100644 index 35259b775de16a75ea908d19da85bc6a5b65ff63..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2619046 zcmeEP31C#!)jlB*l1Tzd07XR&id0208whA62?-ELB$7mwqQfMaBx5EsVP?YS(kO0- zwrZ`l)+)9B)~dC(^+#)6h`&{9QBl!fEh^&5($)oA`j^)KJLlfF&V-F?ZM@4WNw zzMOmSx%b^W_GDkArQ;OO35Cw9c=DvOqRCUr%BDE^Mf$OL%H%1Ng0-wbmQ)MfztV2 z^D(7Ax*@sycgIrte%yoSw9?=D9&+;^D49EB=6w3Q-@kp2GCqfU==Ua*zT(X>opH$y*rb#KHg4QpXHG! z<6`oRnnRv1-9etx>&Y``F?kl%lBaVgd6sV>&!yeuxo$jpZaJAeKUqhfN3JB#ueXxt z)mzE)-g5HnY9-HSD=B-}O_Y7et&~0fV9GAJgR-YTLfLaartF0sl-<3QvR5BV**7ky z?7P8#@@UF_;d;t`V;E(Bu$!_!*+@Bb2IXXrr6O>DEBUydEiRQeR4GAz6d+7|CDk+c#m@b z+)Bf8kEUUVZKq+SBWYO888pn>Ov5g^gNChrg@*NwqhZfg(y$%lY1p38G<@_r8eUdJ z!)q4O@aP9L{LV|&{qyZKeCr*Qm%W?vj{F+smA#|xS)(cM^b*SRFQvRymDYXZNXolo ztGXX5q`ZxTto!{S<$c;n`GaRu{^$(KpR|SYXVy~wS#v1=ii;@!XYWz|6Wb~O)oGN! z^9?FUpF#x(WKzM2yQpB+1yrzbJ{5GdQNgm^RB+iNRPfC_D!BPsD!Aj;#P`ERRPgjV zD%f-f6}-Kc3O?T8xJP6jO(PE3P9uui)LprpMm&E;{QcQ=G{SX{oE)N&bEf@$?%TK0 z$gS(md(`o3Y1A8|>3~sxweAg>bim)?KJc-}i0{#zBlmvaauJOl;67-2J(>3nOX;9~ z?t{mVr?~s9Bk17%?zM$1aaBOR>oL(Xm^$9?k!bjXjNQ1{CnbcpR9b4(`1-RC?= zWA^p_=qVbL!hPuKUP|hI`UyJppXffkEQ9_N?!qI+Q(@(?RM=EVh0({T@QU}S@cUz^ zaNQIt+;BD(zS~BHf2pLg$2~%0D;jBR)73OKSW9ECm_}o7zLv(`GmgeS*714V-VR^1 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
W7t=EaGzdBtl+R%tD4#UZo&WdATDC? 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%0D;J1NK0#^ZF1g-|Y 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

eVxSX8!SxQl+6GnS=&tB z&FX%^@=XIb57&${$wRkjB?b$d_S@;auu{OzyZ%iin$<+Nb!9DrEk7Vw-V}FUa_Cp3 zPDoG9PB-HXZu>hhSTr+tR9b5GINDyX>30j-pkO(*0`$_<-)xk0Tk65Vl4giXV}NGZ z2BqD`Wk?e#^R{e0U+U$eF-%u_XcK7-yD~D?>@nrm=V8IpLk5kaUqgwsUkLO*r|Qr| zM&tNi!5JQWHN6zYEhR6}^B)n`zrW`{GOYgq&;OLL{sTS#Q^WcX^88N=>p$4@KRvAf z5YIm;tp8BYKRK-bFwcKfSpVUk|LCy($)0~oSpQL;zdx-1XwQF4SpO8ye{5L)#(w6w zu>NDbmL)Z;fB!^J;EeDB{XK#4;RObG0%_p|2AcQyjl<0QZutd8m73(8ox z*>q3U=5DH31&E+&*sUa=vkOy z8~HMZsF*QgOfaMPnr#O1Z{-b^fw0OF)qWanMuL+^W%FL7r(;&C$qmUI(p1LGEii*M zda_F(uBpH{O&c(SLrNJ59NJVs1AQhdCz$a8#lT$Sj&y0HRbC9lxn3y~vP}-lnGrwN zIW=?AAkUrgz99D@q)n6=&&~@s=*?A83Htn9oj=|E_MJ1YqKLRgneklQH9AX9PBLy9 ze8x?BX~cn4iAty;{VJ= z6~%A7joa_N9g);W*gWo+nVqX|NsL~{;mX_wi`Un&CVYu$wgXb?&*@7VuY+zpay_{O zsa7NDp6F(cI*Y!tPTW*8k|*F}(uTRDx{toh zD52dkV&@wv&-omagUZuvCO72e@P-_fps5jAMHQv_1w~b(%PYqfYUX26Wl2FwQE^Eb zGdq=XUO6x!Bq*lYOisw*3xw@SiFDc-M&RsH8n%$CkZJsu!AkR)Mdwn$6fzW05mO<| zW&SB+Y4Y}QN)@N)IKh+!4Yi`4J=SU>pwW6<2-6f~ML1GXoRq=ntb(W}h@#5MvT`y| zzUOm(rYQ)jG+Vh`31+4OWSB84N>`Mrv2J-%MWh_rF;eo=^~`1zm*zAoLF1*a;Mk(- zQB0s6$5hnPBD?5GClc9|b5vB>(}*y4Y#b8yQrYArZAp}w=7LPn3>QLdW_BDw@C9;$X6mXn=!~<;O@=)Aw3m{dZi*w-QSs6kpyK5X@|pD2XeO=< zdz$oBgQBl2IB7iExJgH)x&2DXGb+lAq&6K#WhgAyZ}QM9v!=W&vDK=&Y3L+&f3Gw+ zEs`1xHzCc1U2xE#BQY79mNANfFy_Sh$MM;L8)cg`rFL3&QB^@WOvOT%k`HQE^i4j!B@N0SCy+E9IwPIV;+iW%QRocY0Z=>4aAO%-C=xBRa3f6j0t5A z$BYO)4EXFE@yevfKAzO~zME@L>9FX5YrZP8SHQ+cd~sXVV=ujV*e^dvN1yZ7$-^mf z*BbdT6AF&{Z1SEy2Ui@k_0qw6pR=s3#(nJ_Kdn2h*1!9UGyXRGqc?w|6+4L=#78`r zIdtUcbEAK0Gx(#^+O7NJ1*~!~?jO9l^r8Dr4{z5Tlvk~Z)j*+${yUV6^^51w$?t~+|S-?iho5AU+9a^rs6+(VWO7?Ck>^-G@WO3(osfCc$X@qNy7LEWT!%=7bH!1AK6&(}4>ulp+u8ANo%;sK zdZuwNsJ$U@%Fm0E@9)`W?x1ytC0f?)#{I2}-hTPl@2=T1ul~3r9=+`>6EFYel(F|ebWhBWtWzd$<0C4^oO{#8l^-l@fAmZL{OQU*zgX6{q|Y_@X##L& zW%=~V{Mo)S%)+hm^_)9w$Vplz$F%Y)-}sX1sww>wr=*q@l-3j$VeOmPw?FF)`u9zo zQZswX?4sG_mGkl|O8U-dZBQ4Kl$BMtGMFl!M@5BGrZGXjx~j01fz_~tV2W8b@V^MC zpq#aOtVy`we;%T{vZ1WFWO{33I(te*WjPPMs_GdmXDF=tU*)WFq_uIgvxAlAt=3W@ zx%oi}E~uE7SJm3s&7ML5E-5dlE^Tc{CU(_4ms%N+QyHqNEAvZBrkAxcG*cVgM57S@ z5Awl@An8Uwq`Z;{nl%7g3Dw?8OE}xd`Z(+dbHrGWIX11DvaBb%tZiF1^0I^f+I@6~ zEpyr)Hfz?4M?8{##Zm1t#~!=-%c$;gyI=15?z@Zo<-a<&53)Z(Vi5jb}cv?e|wNxntSzrBj!mvZhCU{YRf) zll9Zxm;LSY!Yd}9)B7*~81uzbL#E#M#QfSBk6wOqzlR1Ues$j$ogTXD+?dkam(Cur zxktsf8~-(Fh%)c%JTy80e_WBI8yuk;Lz_~y1-fBJsR)2n~_`kr~e z?)m<-Pe(WW`nQ{3e`d$Y8*6u6P;teeHM7Si9yz}4sehXE;_wIBU)JN8qeq|c;;Agv z@~!Rl=B-yBIyaEf>5hA1kM8vJ>&G3|usGtb@5i^R-53@1%Ih!39`wKsb62jKbaBbj z!_WVC$>y35Ke~2S>6)za$3IV)*5;>;#m|ko?YyXS&O3WkZI?5Pr*6qENW3L|^T}tY zc8EDL<*82ZC*APU-4FUcEL`#9FFo#_u=Vph#;?5Nxt|}J`t*tQC#?G2_1hll*ZZNx zHx4PiIyt`Ig6}(gb>+9`-gi?<(u`YgE$+Rv*F|4k_xCQ3ZOyc5w%2tZvh%c&KYTfI z*2-_MnsfdSxtRn0xh?(Mf936d=A|89);{0=)zjX*;@w|gU2w(fcLv=uZ_}60j@WYc z?LWQ$)z;XOvwnGfcHqOSrw)B7qj13WQ5P<(fBBLr4=t{0SULWJNgdi|d>a4a_+dk? z7;{bUv7;7WWKB7>cUwG5f#pm{2GXAU| z9*D|GTJ>_K|MROSeDhPr8NEM>9sBz=ua7>y_OgqvpE~+dKF?R~J!kElUt+G9aYm=H zrPn65&F^;di$y!f-;!|Nq_Ypdvf{|jiL>87X7H)EwYki9Ui)*}cZu0`^p?1Z_gp*l z^QW^0o_=e>X^R3IM=aTRL$?vHPx5`%aQMkN-)}x?UibT6d}HK{wMTU6{o3u;7aQ)* zeCXXn(@WoabymMmE}rw%hihNG3$@G^-1U7#7)8+5fKXdc6>udk;^vct&jeY3X8y=2d`RDc>&VS&O z-UIHLG347n&MtoJnGY_iSsi)qkjEcO`r%=9TmEnC36S~E^L8vKKJ;cQ`|IOhf91#T z{%@|~*UB}zltCtV%^ICSR!;IM*qEBG=L9W=a~v7!QV78-*yPjFnoO2+Bct_eO$~j2 zdx>DsQmuZ&hYbi`(C4l43tsx?V|Aai%5M;>0Q+<9^J$e|y!8&N{4RKizOZwvaI5^T zYnljr3vRy3Z^t-xEkW*s@peGjAW5tIsvCDbkk2=nd^5}-h}(5$S+{ZctjwvQa(V(K z-NOI}hYYU>mMN`5ZDzqHy79FNB52Jbb?qYYZ=F9kYCV9G^KdIya_GB4wv>RkGZs z5?8S%0bBL%m8vfgvc?+z@lLOKe#%R)s>a>=Ucrx^E*(s8+zv^bX!bNZmTnyiV_3%@871YL<%ixdjT6j2m(mDqE!{sm& zUJr}m4UjlkH$t_bH$mmeEig2nk0bsv%2%1te4dWm;E;UQHOl8M9O*uOj4}B>1rh>8QB%aa_Aw_TE!Hpz^XOR6I_Cp}HyVGW*i42)}{W7!8+s zM%PF;`AzWgV@$-fsxiF&Rn7P>HRI_+IFp^w1l>ovsi3FH0n-m1bniqM2m8Zbkde>8 za5xZ7fP-KG91IoDAuv>T9!$o>Ita^TIh*~ZpNH}PKpapJEJ3M6u5@-bg1}|4$X9~GFRGZ zDr>0D49JnDP4ipV=sq(!GJX6QgU*>X)y{zYf1|s!t+BPW^M0HYvY>lP-}cbiIK;|9 zAH^dVsyt7Estfdv0@;wV6Hpw_f}wfs)?t+;nNYnea7zr)+pWV4{aO=!{21ftJ(_X0 z|0>IUgi>JCR(Yo!d&aHH(y^Q4nujhrp9&R^{4ly{uLsp%9Wv6*J^z~XaJsqIXd{#? zA3w%Kc)NAjO_Lj<>+i7H14sqf-G;5i(=E6z>we15;JQ2uU37=p@DNxAX``%iI201^ zKq{n61{78$RD3BL&GL6V6=N9TyD@IZd3Vlqt~B@nzo8-dt82RBCuaMw7!xtQh`|`P z4N1=#Gbz8chEH88-3r__?oBvfcxZgIHNq(03B^0G(W5H`fBUrQLp+`|)W7KY2;F{o z%Vh^HY9ubqWOoxjTE!%6bzJ-zqfEoG+c_^WXSd0p<7gkmrSU13V4h2x&{Ln;~tAbqg$lx5B&NZSYUzsV(#^IVr#@Jgx zBWBD*HKSsfmlNOGrFb+eqxRfi!l*Z)VQW?zz)|Bx(^bpt!V>(yM+kxZQ5Yy zjQ?sg%|o@Rm|NYm^6COppSL&;)2jJk8J{IOLaB z%*fAXhKUhdf$M2J`U=XK<{&+_@uy-whc+T6VWV?amR(fJ?vLe_Rm{NcNjw3dpkuGqqr0zTZ3JCvyYjY`>8k` zk5fs(93xU1B*Od^T{R=fi5=tAI0oP2T(15{SAI0ZDJEe`P=KML+mPv@rqOQb$0O>) z?zPruI1V({n(`2nklN^A&NDf`;cy-}Y^EL>_ywfo$UzF*Ds~bpWD~HWQXOuF_rzBzs)ryC zu%o#^f2!s)7nBy21;}$* zU0@MB7FNRJ;6g||16RZ2p`J%w;lq$;S3v(b&<*M<|A|oV)XWeF#PWRT1y6*%VPDu6 zj)46j@6XmC_%Iv{*TNz2GdL8squuAdKF|@ezgVCP90~iuQ{W&t3TDC-cmbrU1(w0F z@Buguz5*w}%@AD!-@r_0{-q8sC)cvz=P(;Kz)A2McqaT2PKJ7MItzAyQ=ku?3r~Wi zU0@6>go|M@ya&#N8z5;JxP$h-3SJb$OB>8R#OzQQ=ttjU4(A6`k}2SU&pI)N0iQjR zP8Gc282WDT{Nv0Fi@^AEK;e7ZmTmavPtKl3-pD1uOTnksg=izR+4t@vM!zfy(4N$GrMwkidI|a(%TTmUlx8ap=GrR#( zrUUoEci|)OJ@^;+K70fI6@CmqfLq~*@H@B#wjF3$AHjp+r?3ay2K&O#;9$5NX28F} zE8*wxIrw+D4(@>O!JY66_yuI5k+ln|LHrtK!*3w}x@vt3^)Co};A8MRxC;INpM!hh zd+2OjE4Pa zfn(t5kTxNZ3_HMdcnBrbKqE54adRv;CT2~m;tvz#vua@a3b6dvtT=(Cpj(4{Z9km2^0;>7Q209@zAcj)c|>9oY1bHD?Dl{bP%s1DpOiyX+m<^v|pu zJ+SE?pOx%2V)oiiZMSh?)4v0o{xJr1VADTmv(*Ee{vFu#@4%*i&L)HhHvK!W>0h?_ z;~RF|U=s^(QuGci*i8oBnBY=*Atv4s80TzoxhM!*ModwD$%) zu<74nS_%=AGMNW9{X4MfAN%sy|4?yY(?4yYWtt3cQ^NzB{<)jC9@z9RWM9AooBlQ3 z)9=8he+M@GJFw}W*}04f?@G_&p6;N2m7STJ{gAZsXpt!z0lWfz#tRo!2UygC!3&K6V^Zz)_{R-SYGf01|_<| zYYm5%3u{Nm$v)OiVQ1YZyJ78dY%$he#};k&kdkkV)}tA@XlrR3{kx5>&^m6}Vyvx> zE!yhC^Tl>cbZpU9DK_<54zgA|wixRf#};ix@r03Yj1}wHqOBR&x|%Bz7t-x#a2V~e(?U^~HFvBI&%SPwe3Xsc~|+m}wCV~e(Ouyr$6-0s+7th*drw6)iB z``L3#JV?Xb(&J*s7Gnh*TeP*=b9>)&8$?ofH&+B4Ta0zNV~e(4#m3S#^mx;;MOzkh{jZN2EZz3jOqM7wf_JGN*m#d90yxt$Vg zuRA};TIASbtg9SbwDl%77NHTVw;fxw^)WUUkm0t?u|->7Vq-BFZeKgLXzOQeEa1Y8 zS1@CXwqmfchz_?n#};iJg)Pyz9qZVlt>vt2>|xw)a%|Do51!jkp4&Nbu3VmDi?*)t z+!lLopLuS7_uRBmj(v|#jxE|c&2t;&x!vWtt?=A(>vz@rqZZ6fvEr_#b7j@1N7XNz zN@e)rE!^vt%4*!$n#$U=4Y&G5vaa2ET+AjTp)*P3M%B-kec)xzHFf3`_XSUt;vR8H zH1g|{(zuH*Sn%WwT-#iHs;(TBlIh(g%iKhPOqADUx;S%&uA13qhp=E>+f2vOnX4wc zjwYavxI`wWV6Pk1hmaPmHaD-y2$q~V3jZwUx~Q3FBj<(~HFHLgq*3d#3SzKeO`@Xc z-b@|~E>x=BtBCb)5<+sY;LNj{+^c&N$?SbgB3Hl2O@+p|vW_+=gjlYxpLk5x%+4W> zZamut-MnqwDu3+4HF1}lC?C<})|EkWQ8WEPp+(Ic)Omn z#nsL3u3TP!nI!g=r_#xb{>WV>m(G3RHQU(bb$wt80mvY`e*R?V1SzLHuQvXdOfu1t z_u4O%LiOX)^qbUYQO78GO-x(xypppnGp$i_Ta;Xu>MG-?pcZ^#JIdbh2QN0SHMw8Z z#s7!yM>L-Dp=|GEx_|H7*m{3_{VQ*8#XZI-Pny1h7SH!OUB7Xihd1c|%n1kd=?Ao1C^FNi>M7$cS50Qxt7g%V{dHJVO z7;@uAS@Lfp_g$Zq!;P%<{-1@0gX`0OUa&TzF8$~EwLk04xwbzsh|K*tZq=yC3)fU1 zj~0>XKjXG|RL-LLlaauseqxTBy*Ulf*8ffEK=|`_4a5J;CC_eP7n~<25dLb#?b`?L z(7gt}Sm*zl7}SsR)h*GEKLlDos$1Pc?IvUb?OC^6JO2cwPFwG0b<4G((E5eiMo6JG z#MK-7f;AC!#!|mTUL%)C?9xv4%XKDwFJC&BoHCcZzJ8&04w8NSLhV>&+k%2LVJJO} zMG-V%j~ta#d$@gr#U|iI*LBdAL=A8JR)k0=BRq0qO5Bp)5eYl6dRzI9^A~&(QMX(h zABcW#%9ghV8yMnV-mM&p`1r< ztm#<4M5-AjWZB7bXKTT;M%}opzu>a^j?OB%|ASw%UvGPQGUV=2J?FP}Py5;->-~E7le>Sf8eRY1`t-dc(_gDS zsw8($8&o5ZC0E6FyH=^P_ocQ8aSiV@JdNXm)rx|3X@?n4($6<(K|hmZo&TgfHsDu# z@Ou9<5^BgmjrmW>eKLn}=WWnx7)n6%O+YJY6O6mshKA$3aHjHJW88VOvl z$}@G#wf&J)T%>U8mT0G=^?o}d&&rR!CVP0$*2(9lABj)u{7u|>YZvT_`X(-+Z8uvXipX{f%#N)3 zg^Jp~x{$ucVvxSqbR71Q+aq&dtIeTYpxed0OtIL0Y1ewA49QpWyeS^(QA@6iFvY`9 z@n~Z;`0P|5{Yo~4FF?20k&%ifR>aZVb4UGhWmRvJs&&S`vp;ocy??WmRT^(hM%nJc&LQ*3yn<{=fJ3l%^k6?O%f z`mj=a@A|gOOn`4StXfd}O#8TnN06!e3Ls6wmW`t+`Znk#df{eXLj}?*EemgTX+oRXu-4kjjd|a(9Ya?;LG*PlC@y(fVhPNa9O`ld!Z@X^-E-{TcTag>X+-cZn-u=tM~7yPY)E= zcT6s>TdrNw;+|M2tlerSNQ9Tf>isO#C6R5T>x?Dti6utV&fd#S_L{U?`zgIR-6OJN zRGqQxGgPwJ#4IwlO`WljaP@v7l$P11xXy$h_k@X6U9KIn-{o5TewS;9?svJ? zalgy8PWxT1b>8oC?Wp}O*N)lma_!jtF4uhfU9NTA?{cl%ewShlul+99 z`s{bP)_1?lwZ#1{*9Po&xi)CO%e5i9E57;K($_)h37yk;Qd6a@F@TW;P;iJl1aIvto|ImWLbmtmoUA zJ2uSWV_#kRZcQ)QZKg}?uJ`XA>EC|ox%KJ0%~!y-bO#nr;o5zEyG<~7V)^{MC+>-q+!c{)>(loT@$?l9&o%sRz5o4RU%q+ddjA&0f+1fm;OGX*5z(#c(dNWHPZinouBXKTk3O`EYegg|CYL( zg^T#Q9htsyaqgBy%L2?isrPR*GY~e~Uys)@)1BE1z0-Fv_h7+~d_8_dF6L8g+!L{x zCAnMNDFoNWn<)fs7jwP+WfXxkT!9+Cp?8u%UE9U>S4!fW+@{2DUvIwVo9knjawqo& zIhmdW0bJhR1Q5H_4W19LCFynmW*UJBfC-9HPG7G{&}2`70IoX31kiE58-7}5dpCl7 zK@O)u+8Lficom{rRKb%7uR?T-DtHp%Rfug-1y3Tp3Wv0)f+rDPh4>a#@Fc>kaA=Dv zcoN}N=-8qPokkkz6Jo_Nm-%^CrI7Z^!Xh-+icbZOx6vU)eLc01vIN0_P2yn{z>a2E*1H{82( z+$Lrs*FF<S_xM!_a8-W%hV+`{$d?REEJ^Xj^2x&Bajy?>ViuJ`X+YzMJu ziT*{I=<;*)Jy04^yqekYg zyX5F*;|Zjl#uDn%*EP#Ll2>!`NBTF^9=)$X>vA{jypX6bs9l#pemxVEUkhqCMAUYe z@obP&z5g|e^g32wY*0BeOCh|G4R@iRU5?x_f~(>aZ*ph)2bZIcJKr<&=|juJg4*5j zwFN}IZn>5cEiem;;=Kv)^$X?t(&g>+XV)a6$$1qiCubMb?uxHveerIlh)3q`qH@Nq zN{gSo@a5_l9ACQpa9tPC@Mgo+nv6d#tuB3a^PDho7-&-VDsv+)KXhgUtFD8Vyf(zo z3|WWW@R!D*+#+s*nr3pszBemXC+;KK!^1`U-?{JVhHEH}?y4HJXSHftZ~y9jEse2P zjHlJ*uCDh#lQ}bzi{0wY`rnONGpUi@!tL1RN)gYIxf^T8HR|EtWty5@cCCn8W$MK6 z++DSH^n*fcc-tgf&>b7@CBp84FcuIgTY9Ij-dCfkHO;73=O^RBuak*e@(mSipXF0) zQRNj61Z)=IDx`+zLQCDw9GrLlNM+)(|E3JA_pd=Q>XKPe;;pgm z#J&`S$hg_aWm=5IVwOlbX;n#odmR@KLdQ=9#$L3>8mYSU?c`Bp?wYt&muY~J;Yywq ze+g#r0;`wkHm(-4N=R8{f8zGd%}|P1_kwYZqKKf|sM%0W3EGEHnYcE}h5{58J^G zAU0kr8{Lf?SS4>Su*peg^@tH;=ok^ahXVE1U4Fu14|Am#P2reC*C1!haPP6bVFZdEQY7rAvRFmsVrpmQS1!lIjP6Z~SwN3@i8*7ycO!I1;3e3uCoeG*n)hZR3^VB*On4;7= z6*Qx$RVpw6sC6n#ZLJELUh`k5&~OQF40V1@L2<_u%&YhION)N<#RnnQ&Br~_F|)qy zGQGk?rt^+uM$DS;aIxDN>(nSxled)yW^HUYul2mOtT6*;Yj%G0HSbHgYk2*y?l9xI zpjSE~DdN&wsg;Sj%O?JY!`U8g`VwN&vqX+?fywzuyr-I zH$2-1*t#3H&#`H*$Bt~B=*Hy`&vuMw>*d*odA3x~mWR#0TP?P+gxB7>9GjgQOR(9g zaTB)V&E4+A*2~!1lO0`+?Rd|2if7CAZ0BOLuej86tMlACu-}WeUTbfij_pJf-aikv zcL{B8{fe!paf@Yt&y$SpNNjd^J+ZM>3fB(8*3a0^!)AxK9NVeJ?f2Mhjqb)~Yt)%y zd$b8}F-0lM$gRP4nz60NW?!)pn|;L-?6axOk~&%iBQ5K6BR3P9Emwujmb(>OlJULE z^L@zkeF9su@%@YEyWaEdaf)U6@a{Z|rh2w`B4@ju;MvNt9cScLV6)@bkI30M zlkC~<^=waiwhyt5;@bAsHf**Y4cKfw+9$c8boOk;o^7sYyAj)HOQGC`%?@P+HanDq zP}Yu1u4lX6vpwP2KEak^Lirq<9m+qj*`drLnzrW0b1OT%X`by)&$ivOok(D|T(M`n z*R$>LY$y3$xtX5r0nfI}vz<&+VTV`d+5YU=c6+w|R3clh(z8A4+4gw0!Q))HIiBqa z&$idI4NrCDF7#|qd$ylF+o@-`a+i3v=RBJ=-t|rPY?pbq7d%_rG*`~=*{<+x>pfdk zx+|CJ*%o`YS3O%SRnbn3bkBCRXM5AL#b>y36FuASJX?IG>w6kDyBtixM&?lJ3b5Jb zr4*Z8Uglv-G`^Q$>xr$SbrrUgjO`|Dy^L)Iw*E%$F>KlwxV^Oon|1?kZ@q?Xkg>gw zO*{X#x7g=wH5T^LY|HNm<0jj89Njov6YW|YzJ^dFcFBItaXH5*Yit7WjINPP6vq}l ze2huXv;R+mKZ9Yn{Je@v{#2qkue_qVq`a((XOwpR4QG6TL*tLJViQjAJo7T_i?mgG z{`4Xq92p53B~SDuEK6~i%b|F<`kc-FUOJxw6}NL?EbPQ_kTuz{#mL{dMO%NwrnHH% z?s06<);h;G#_XY{YonE#^?rIN=^7)AZ5-yTAJ=wbeY`tn+S%I{l&77!Lr2SpP0#&~ zCMWIORN98-gR7gHNTKOOIt|xL#>zuCDh5>H80!# z4}wo^C}UsaU8*U z#nap5)k3KFUjcR7BRTB6lFiO5*`m!BcedLuN6zF6`>nD6m-hB!^HpJqKi=L&Z{keG z=Yuk9!8$yCb~X#E_y4?LT~tuNO;t|8cQg-)eP$`D`;lZTy?$}S@=+ur5hA}4=`bx@t)A*~JS$%w*>w<9_Ju{h(xS5I)iYctdxFw@n}5o}HDXQa#f; z{P1f3KkrFh6EXVc2Tpsl;dfoGQB~%DX#TA~x*)QR|9Wv|N!h>wQ&Nhi)lARL_MB64 zv-?&QPP4vl({1Jt?>zeWH&6He$9HWXzV7M=9$#={%^R<*zhm{yx8LyTgweexe0%y~ z7uyG#yB;mC+@GA-*iY@ghJ?xf2u+iv&cQ~ePf$2fUWn4iHa-&q^}soAi%ntLFFv-T>q7s_F|NxD=e)hSD$i|a zagFlAsc|pzT&`;7a*N{<>B;;Fmz6}M(dD^jSH0EDWhX8hovR|PylGWuN+gNIRyay? zHml{>-NdC`g#C1Flu5v4DT&nR(gl~@O6SKOV1I(`X6~i?$wg(TPq52?;kXP7cIiJDr@JWE(%W3sfABENda$X>Aj|r)sSEwu z9Zg+^Sl0HYE<@>%dM@wk5=+|B&4wE(3=B9O5!?;3;Th^s@R^Ru^HS}Iae7O+70I_$tb@}+nd7)|KO*qDr9Y9`WDQXRW*cShf!&Wj0niu#As+LFE6jM zsG^*I&#TNYn_g5fqo`n3aehf@O=Xe%%wOt-e+9xfU;nztU-;z}*OV1V-2Ef4*|W>b zynZ_#L0$N~QD+ax<3Bd@lB@Vzsp@fgdAgltJF8oiO=Rp-_m8AT$=Q*pN~HsIW@QQg z$7wE^F^zCark9PT2U6uarRUEol0%x^BT*AIhK^I!4ClgWRhc!_`U}K?1LUU@^Jj^9 zv$-%mzoIIS(5Dxb6;<-TpY+Wp<(Jkd^s1t=!p762ysVtjd83tL{6T2JtV#KmRY}9F zB$A=1poS>U%QMNDS5RI)tE4Dt5DDR3;jgN2PNmSO{3<24e6wfNR2PORZ)puG|m3u1cKA|RH#jo*7q2sAWx0>+g zI$;tGD=9uP$t#vYa+e`|0tgt?R$#%q64Kb5cTtGtyEfB&YkcyZWT<*BmN**;Yh??*2b` z*_d`AG3;ADZ6-rLrzBWD6|ckii?yfd3c5@$DX1*3Dle|~^~^fSr*Wv+B^T;FZZz)& zC8b4`ipzH#-DGjh36XZ^K)EiHMi2RLy4kKCnPk_nkRbtGb2zex!XtgUN+!Z?>vglr zqAJsLHya&LsE%QDAdVM&Jp%tg6TrVP&t|a69>1x^(Y!%s^X^K!GK&!idlW}LbBZdb zl~>W?5(#@8N3Iu?SI!!fulH0Q_KgDvW#&v{3%BYn{PXhggx@1BlhV^N=aDLsLFfHL z&d&-t*Y_itG0ydyL(YEMBj^(N0KNgY!#Ckqa3kCcH^H`%mc0f}_?f*tw~rmzM(3=26QN=xARs}5dJQe7~EP(o^10uJiys@70p z7~&48BN~mTm;?U^d8k`=!^_|bxCm0e0yn_>;S=xyNO`j!f_i2B6MPl^8NLHo!VloXP%jOS z!fo&|_!Xqw2KK^L@E7<5{1x)`H*hdY+6>q>SnsWwdnn`S>v=q>TE@3QaL}1C~sXJzO*Gwy%vX>I^$*uSL8z z%aBhs78ty;F+Z zHyphK{HIB-=bwU>T8+=YcwE)I$hB&AerYMUw;z4$&T}7jsz@?=*x5;K>hNyc)%+^n zN^5=f+wQo3O`7P2d*E^Kd)N>D0R3<;JO}<0mcgIkd`Ni?@JzD)1$lN@ze1Dyd?TT4 zw;~{Iv(*NE2zhA^{0&n618Q5^LA}&d4+8Cp(?KvEM!}=t!SDna4HF^Hpunjx7M=k+ zK(#~6(+Hdke^ z-pXUumqCtuFFt)pmy=;{*cT3h{a^~@KY0U_;Q&|!2f{gU5L^HU!>i#CsCqUO{s|6) zYv6FW1CD^o(~(fm(o32hgi!EJa*nb9>W3(>H<4~sF)%1kR-;>PN(x+vqew8|G5_k5#$>Yb~c$jIO8 zo7zt1S8-RlQT$6C_o<|d&Zj}O!v#>~st^u_MNsYVbg1Y13`jrJDuG+zEch?TKRpMc z2)hg_ZOUP2dQT-EqLA&(A)`9l5i0#vM}Oo9?VITu$z;MlJ}kyK>77-SUzkx*RAy?Z zLJni7q3)N`!lKGb=emrg{tr4p+0?P!i!-Ryc_1g$6+q~7@i5gf|KDMcoytJnCHOLA+yc`sqj2F5$3`3 z;8dvoQa-GK)8J*W0BRt<2rh@k@Hsdg(r42Dcn9eFSS9dnI18%3R0_X=vtd{CD~E$1 zUyB2yVI@q5RZw|Oo;52+8;HNkjGN;sM=_3@%27SX;E;N&Yb3Lp<76K{#srn4(WT`K z*P(RNGcvTjbFX;^zkWV`j0sA& zu|?HRsc&uCsd6c5oA?Q;Tpe*z%?++xno8hSrtp1E#an5tI$p{l^D1c~U70EoVDQL# z9qNW}z@hL>I2vw*)8Qsq1>b_|dToY!cXEvy$*X~ zNEy{Nl4%3``mh)il-4cuM1HHCYb>6MkvXeTL)6&9F$=()2RB@97t}Ov##jB5;FMR{ z?nyekMmi|nyW((+<9-e4BfXZv+avH$ z_$V9>S3&(5`V&xp^!p^d5%O1j0d1}LG~586ft%s8@F(~jRQtXbDo>w>q2+|WuxZCs z%4Jk1We28CDt$xSGF>AX`t4Rv9~NVra$>%e{7)W=8o^UxQRX)v!BYg})A$CX5j;H{ z^=-t#@te*hv6ptnm!Dr_YUJ~|43(*tD`tozeDDhNc&lMD^&Tq4eD8V zC!7iIhI)Iw7v2e1z}MjYP+>d(x4{Qt3}OEXo(%sChr*Rm<>_IV1|NZw;G?hrJ_gmt zeH_-pC*WeZ8m@p(LB=<%r=j|?&%y@y7x*1~4k{1V=$v?T<8Vz5`YQ2t$f#T#0o`)3 z8GGnFJY6H16nK&ki!s6F!ZaXmkgkBkfBX5S>m!NBw0$%n-YX0}pXLq7?x3viK#6gi zo3a6>8>D>S8x%9?qq2x8ZYe zGyELB3l-*j@G$Q2S9l!!0QQDk;4t_R^uv##-bX)y>Jx2+W$;sYE&L4r5pIW%!oNZF zf&LDa?>k@|`ZU0!;VyVO{1Ph9zJj6Upf~Z8>1e~01DX=A96XCX^u1QsNXEy}OFza0 zmxIR6j_Vu3f2%O)d85Lhnw>u_zpRkaM-6T$t~C^pGBXD)ucXWj?yG4CaxJfMX8@Xh zZz8^~QT&zX(xIECe+rXUZ4pp>R90j{>x{-0Lcf3L8kMCzqXH9T_gQ_;%0dZFz+xSxH&mj1s(#!b>_fO-=hU`T3grnd{UNx2kdy zuIi`CzH5|z%Bx;DOmW=X^PE$fva^J#pV9CH&ST&iFcwaR9pI(#5V#D+!PPJUs(*DT zd>0-D{{}n4J+KozgnJzU_1y0a)dx8es@*;cj)zCXGvP5%W4y=0dUzcCJ@mn+U{|;q zo&bM>-JvFc^niNq^nyN>52!JRJ}?QM45!0HI2-nd7r_B=J{$Az#VWTRCzoFhPDTKM>~ZyaLf1&?KH!?aqM^w{-=fXD|JmLt`QS`Sd4MX z_^6uV;+%5*x?lTDN!LAGqi2p|DCr?zI)3}KW8+s0-n(beM(Eq+k&Ui20~IyZdF6B? zic8Bc@V;%ECpXi_&c=6;_YrZ8(pz;yF;KrlW(Rqyyx0vh z;Medh_$@4kd*E#N9n|f|QS{9RWS2>Y>GNEO0D*j0!Wl`5i zf3d$$SIIOhi;W}f|L04iZ=as^sJ!@pTqrfHq$E@J+QUkEXf`j5YOY%>b!v~5 zf38uws?4cByxnm;n!Hn*cZEst1gLiSM5z8!cQ_gLfO)Vd)O+tqa6aq}uY`Tz5_mFH zS?mjMfr;>5*dP8G4uDU1^zw{Ulu@nJA6{K7NdG$|7?#CKXjy>5J;V*9`HV z$VZ8AYfTik@{N^=}HIO+BZ?19^>Q15TA!SV2QmWkVwV8&0LhoNOj*GNVj>f^^4C!H@aQ&d&u-5^~7hyUjj zI!v;fa;Y?NjpD9!JqV^aj_;B_((A7<5qEre)C^GnWpo(LJQE?$gb2+)n&;{yEgW z{~ku4cX5yB2-Zh+Oy^&7Jj@ZQkFJr7INZmNF^)b3-gg288^*M*e5jdHMKj-}Doni# zR~$@vm>YC=#Z~E}LR;#%?;<^<$8LBW{2HpheFF!>Z{aw&2Tp+BK|TL}fcbDQEQ9}q zSHYj)jqn#3T5g8mt~6CWmr=RVxtq=!hY3w*_ZsE%2p>PjIO%MEru*%03Qfz6Hy4U~ za&=kFZ0~c7nk}4yo@3J6HHwGQu03?$dyZ^xe=9f&Dx;5q8f)qTPlU%p#rrrInii9A zmyzx=p>;@otC1o7VqK%MoX!#Ji34BUr3^!u)^kxVMb2|j*|F?yGj6&B59 zu7CL$(|o98hcQ$)xBsGC=AyZ#)=0dXI~NpJ=TEa#t=#peW%j9Ct;+Jf4;u<#c8ONh zsY_?-Sn#t+iojuTD%5i)ANt@l7+NR#;jVJv=Av{{7;f2k2>aj=-E@s)j_2s;$)UzqC$UncPsIhq9%zBjBRi-znTCM`1^{YhF zE-$)j4&~##1S#6|6NM=s!;G{2qxdS#6q!Db`wY@TI+Va;;Y=ufX2H-jlD~|iD-)Xk z7vnZ4B#m^9^5k$GK7Nb|N~7Y+BKxzp>lecCNu(;Jtdjoug@ty@slJ`sJlE*n(pUHI z<~Ww4m(DAo;&gr(J(01LMml7qr+fZ2=NE7c4bjuRhIF$!`S>v=f~m0;tbficE4m=h z4Dhs28r&y_J>AjGWo3IwV;dP<=XGD{s627&Jn;)CzVqNAka;nI&hR3rdP6>$`E|8W zb@mddcwY)b^ZZEMWrEW}>8Eq0g`USJhoptBk&K@0NBHZjeJR5^n6Q#T#xNU)P@FS>v{}^iA0 znm38uPbN5Tl)rA?OvTQ4{{oE zuPLi8DP`ejd4*{)bb~OaS()oZnWM;=GUqNRus`uN&T0J{0jc4_=s}{MRt@$G3uesV zLDeXy#x=l!QBnS(u_)VOWJ3sn#O@qsQ+jlYEb`z52!&gvp6#Nj5hF`%H7=a#q zuMQjs$H2aDEM(5Fz5xYPCYWE{temYU-YR3k<;*=-IlGeMl#p`fUh@KeU3~l)W0y1M z+fGP9b3=D!9X2ayN04`9UDJZ*eKl4cTN)IE;-S1#`*peFo{5gS+eE16cQ!m6GKa&w z+nfcJhv&dkAm1;|IMcbXkaOlg26)zM4S;Fyrovk}&xcRLX>biJgwnqVhSuH3iBmj& zuGZ@7=((wLrK#SDLi@eCMl$!pV|`eRiLk$((XY1`<(XQmpu-pv(|sxO7Ub#Cp_*uS zeU!TV{Xz58-B7e+RLbYwQ?dDyGxe{jmTLm19dnFtN ztKiwN8qS7%!wmcmUI1@^bK#wE9()K=e*$kozUi9p2$#a`oCl!dFdyps@MTcz3>LuC z;N@@}TnH)u)|GHFTm&^|y$%vLi#a@IZ4h(E%)Fi@kb79mAYoY7LgmeMFf_kAM%(?w z;QZFJ)y?nYsH3Nc)FE9XnRwXMhsBtPnzF1ke_lD$Y}7k&D$|(c>>QKxX|7yTlJh~| zv#My{SqZO;^BBg>D>^@~ysU^;)mvM}=ggYQvb?hLYJ07v>WMuAU2UgZ|7P`X(h@V_ z$vR6hwp-#Ih^fy}kT**U-C`29;is!$ty% zBVPt%67(0o`mkG2MX!D?pN4Vog8K&Ng6i_>d?RfpJmi&^7Mi&d-oqnEW%@+=0=$bW z?f8|McZ57Mar9o8+$05(v~v+tXkY5d%A^n#$6YK+}m@S(PidG?-B`A{93iOUqn{V2u{ zlmlJh;gE7=-aU?o{WxcCbs!m@05f1WsOQp&Q0-=ScpGFbMc@(G6TS#fg6~82K{e~D zdc&VMXWm2LNaD~RCc*(wb1eozo<-JRm=1@)U2rJmp4Kp!1er%^){c&ZMVy}kHFxAx z$QlysG{~9_i}_H2Dwqsw;V8&F4r?^bhAFTd`r%?Y7V@3a8VB=XDlCI%z(Yx(@h}6X z!5laNs_0IHMKBAN!EAT|%z+DFF1!j(f;Yl5;T>=?d=Q=mpMYn>HSk>c5@fAO;2oF` zx4}ZV3!-!2J6H@gXwSTnKopz-<6#Nx182g)a27lbGVe4n7BasikP0hc20S001FK*G ztcI7u8n_6~fy>~9@FvK-l)&xq61W0h3Lk^>;ZyK3_&rAe*csNr zC~R9C z^emoAU2=`$pmrh^2g(Ec}S`Yicm*H^uDjWk}gOlOwuo%7p=fF4Ny>KI31vkN$ z;ahMEd>j4)ZiXGW=R5FF_&!woK%X=~pVQg`C%})Pp0%IALbw(7A&#Hw9BzXF_!%V6 zt-nF?&iWkArXBdZ&LQ)o0&C$;$ox#J0e%j5!9S5fU+Nrw1+|{*AFvDjTJG>0$k@I0 zE$j{Vz#rgua1iDGdpI2Kg{pu5gyZ4Qa5DS_&V>JhbK$R0^^F(Ez>|=^cVGi#zIWh5 z7zw|Ev~>aP5!4Q<{>rMSR436adaOj7f z;9Kwr_!aC752kz{1rLKq!`tC8@EOm5#9hZ9bqZE6ekouu(Br}AghmRj)B4*Dk)&!e>?=z3RR!jX@cPPKWQdQ9Na-0*Q zpnItvkgeX>^;PJh`!9idpSv1%gV(@8a4A&WmcdYcFQ9yFW&GFeY;U6+^+H>vf!c$2 zxL4?SrLO6PpE%Hm#TdrrHB~|Lil$xIIBP+HyGDUJX5pciZq5fx^}nV#BF$&u z4Rd@NXW(gC!8ly^o@Y-z89>J~CSi~x7c?hNDx89IBnifvx(YJ`Fwv1S)2h<-;Y(5M zmxEuZs9!wj29gKlD!fx;u zI0)Vf>AzXG!Ay8NEP!`F`T^FRkmtX37knPx3wiEXDP{Ws+qjB%q#GOq^2M)-|pH`~(nu8LqJXBXq$Vl>nOjhz(bM-L@ zyxU0$I5|B{>7>i@+ypz)@r`KWYm&#kuuT)M(N1K$I2T4X@%7@|+3{}M)H^4|WRc?2 zu8B`(s>zNo$ms}cRO*BjQcKA;&Yzs(&&sxZgeT87!Jf&ZNBc8#^3qe;+KHZ;EfE`_r<$i=#rkM`xsEWKk#V8y_6(n~`mbpY)9mc2|V*h%Na;ZCYXY#s;K)M8Z0$AB`Yr@ zD|Kw@1g~ry7VMvrapr`yjO3Ke!`YynVdxoMki0mn2~flAQ_M^Kz$6vyg=Be7Mh zQ->;bc)q{2_c{08G%fnbJpbqUpHI`@I%}`}zV_OCuYK-0k=;=76)@fhBpR!08768m zu_t)8sW=VQnrd%MwpJ&+A(Ti_m}HVsU?N^XV_X6gy?`_$wWy`3A+iq&jrmZj-~vs7 zPV{k$eW(qLu&gDX$>^kEZE8|V$A#?b+GIn5mp{4ej}O^(OiN)BrJh;S)Q~`R1hp_Pqtiw_y!ZO^Z_X_$yP@wb)KK{YYl4m$5P1*p>=ykg0(L3P%Xo9r-bjm|UVU)tFdXw^#+1$|<=bAIP9=O*JOlFw>Vu zX-@Qk=uUNluBkEmp=hyeh-Pax^vN1VWy=+2CM8jvm2hz}K@6hiW>V2iDw&ep%uOoF z`nYU#8!AaN|B7^cPDo-=()3;Y(%i&q>ss5ITCP~c+YC`NP5e)qvtdy((bnEV*O*bY zT4DVofr20uxU#9yX8xsFWl{=bA_1v&ijJ+RR|2xT3Ll#v-r88VXpzEYG!yUk6_?ad8|M&>hHr^u)&wegW$RkD_zZDRHhbD9u^ z)zq~ns&J(@T%N)Jw>2@FMmZHlQW`h)4fHaqlj7!b%?dVQE2oK(TxhtesCqEX7bF%1 zhxJJ%sMFHqa<3gxhQ*PjElyFzNGHvva|ExJWKhQ)6a2Y9&oC z5;;B+39Fy2--TYLG?J-pYio|Cs8l!)rF3@`+B0WZD~f zL2hDcvPN}aAXQ%;ggKuO2`x^xsR>fpC!0sj=wh?AMDasUIiDCsXiHR8C2LYuElta` zZnhC3iSkIIwY9!|Ih!@t5GO_aP$j%M(EQfg)XqvWIN!^je1vR$a&e;i3RXi6&2)+8 z#Hdr>5D718YN<}9=n58JEMKq;ZSAc#s8z7ZksRx5HFTsvZ;V31qO~RKF-KXAmHks1 zr$myAl1U02>iek?ze?K6CZf6BqBk_RIjPeo$$rzjD0+QW0vVPNtc#e08=G2iN(N_> zhor`iE){O5G(8RLWG`sDT#K}1V|zoO=|oI&FlGyLDl6WQJ;t*enrhnXlhz`VCMT1w z(~4$Mg3XfVGldlT5ZVJpsIIl%RlqnOP~B9`?9ytxEAhvBJ`0gVmOH_7+Z)wklSus4 zsVZbOZ-A~zR@Ykr#bUKnooZ;UM&oH8+XO~z&r@B*8*8G8P*lw!cA?mVU=qX-=CYgjF1?@y?o6UA-tvlz*gV?`ND~Kr&c)ETNyiK^Go@K# z=IN42=SCZT|N16=bcwI2&+4qm1yN-5s3pO;u{tPdOccbHy0y(uz6u!|g_!awk`@IQ z>G8KPs3o~LS^}vR6&Pivz}m~}8!)gFCVhv>(g1C#y4lhFSi7H#t#sib%OuCO&mv6Z;FuBM^2 z&d(a5QC0~Q%zi6BIJqo}%62O+j2Wt)Pt9o?qo{1U@`7tx5{ufbF%`Z;bJ<3YP7QW}V!=!n&9lw;|b3#adV19|dFLZQEhNHTbaFSUZ}83ML6G zepaG2*(MEhGo?Z?@_C`*w$rVLWho?u&Cg1qq{$Xcv22sYSRU>-qfNgh}PIO?{ax>l0UC zgBR5;PBFPOvN~tAk1m^w%q(3!(`=0`bo9yBg5a{Is&GG`6$jfoHud;ZTAJ#a+O>4% zX9rAi2#-0Ya6@8wO3UJ9bu~CrF7R;*j~S&&ud4umFOb&%!y{R9#ssm(95Z{BrD@aIqVpoP3^2TP1z(AdOJ;s?rW5D+HdU? z9{M^hyoCYG9AE-k^hqG}cA7v{5^q_!*^qxPDop71G_g>EjPis+@23f2=R!FX(h^%4 zhEC8UGn93u7aCc(YKJA^&?RcZep5xRIg;mk$F+5YNaxWwIp$au*}ioTQZ^3)MRW~T33@;%2>A16Si>ZIW?(pip+{>o1(-* z=c!9feuvPjn3dHwQL>>w)nu*HTCZTg#G1|7sjz^dd)4HqL%vkl9-(hFn_7Fb9HZ84 zntPRH=vp-)7an$hC=z;C!`yOG39|~_t0ofeOMT1P)S;|G7pqUlxvI^uC^U4fS}5MM zx(>!LH7?g16Yc)wW3FaZU&7ML-H>-uJb*Q~^#gy07 zGXcqVOYRi!j&=FTKi$}-rCw7juHvRf&YS4kNWV|bm8QSh4z(nkn_Ak!3fYoc=}yU& zw1pXF-mTDaK{LIC>ULVLV4YtlW>rYDl+rsrSIn6OEmq7Yr0_T8hPNb^MFo<7K?3ny z0lISe6*Ww@&bVl*lgt^pGVbhwb^2oFTluCWab~WBJ91!;z-l)%7iZ-QG&JL3!862i zOJ{A>NxUsJQQfEJ3+n(Q)!N={J9orFoj7|mF?Kb{Xj!fE2^H_nN0oH7iMr>UqYAbp z?I0seaoSM@X+t*ck;0vORKfaW0uN|tH_kh%oXqdy7M90RYoDJh>l=|3^rC1wnVu&w zr`eybMZIxBZaBVEJ0tMj7WKvq-*_`}g|SVocqi#vf3lSAy|Ak<%$3hi+$PtiW%OaF zS~GKn&3^mE3qSO5eK#vl;)szLT30@N;N)lL%A2~g$zfep*Vs_U!&`Djg!Xq%u4r?6 zRefD+Ew(o@{h^}G&6SfCV3nrzW>zw^)bnyB&3`2aq4{*EbZA^I%9FCKw4H5gZ<0+j zl)gAmT0U9aW=Bj@;drjdmA+_h73&%_(rpN|pVM&2laZ4@Qk?m@vBMo@YGxFE$*AG8 zqVNTyhR=?|7mgY}CklVdsNr*?@VAZ{J}(Ntbky*RqVUR5!!M4)6QhP#MB!DVhR=_} zt49q_MBz1~hF3-5$x*|rqwqzehSx;li$@L5t}|;#4PO*lmby{HXU&WRE*o87RwQuw z=mN7Nf%?$}=GZ>|nF`zQ_T1FftIxtVbZqEe%c}t7ZnzN!(SRI#!!w~dm*!KjkqP9~Wuj=Igu|50|ZIKq0nHTp5y zxQP>0t?Y|5JGRtWZ%F3&d>MQ2z??Oj*(Fe#FHoyz3d}jAmXW{-`2z9+T30rje?TR$ zIH9LYZde83hzo;i8e6T0#m3_ovg?|c&W-r^`*Qdf(Kbcq>`sm55hqrWosFkEt_=^y z+iqUp#d%B7q<`Zvu@xH^@f|LTUSz&s#N^4PW0x9F4rzF*rW_D7QqiP-nv*w5ZR|>= zacdM!I+ObvJr}&GnySyJ>R^oQ|N3fE{8vpRmbB9GYRQ0| z4clXNjLLdrM{12e9j`p&YNjh#N$VzTM3X#=5NjJ=2&#N^Aft8DuJvm=R(ADO_w?3w>Y=u--tLt(U3?{*FIB4LBDJvI&^rcsn*$#2 zu8y^q=BLoUBpDb7~JNz{GFHPj(*C3PzUAeF*DESnZ~ zfTemG47o`u^y2!aDqMFw;+L%DpoCJiT7j_`fg29$eqJT(#y$Nf4c8Hs+R4tR%;xKH zLpXZ=5qGhhr&J8Joj#e%%h4jGkad$5-oaBgW_|TMl()ZX&wUh@w8HZSn{g&9os_=6 z%TLKV)^w%T_jIpI^QOV5(QG_f^(gv5{xSuc>o{^R`1aC=|841v&wP0E!sE7m?tQ=J zC;sVhEcUkVT`(V$^#S8AYFv5B|6G1>`o#59_P%r8p>OaUyYV0U z_$#~Lx;c5^mzVu~{*S-=3TBw!Gn4)|nlD~ZeRb?lW9I$%t>boo;wJm8CHxA|NT!?K4rfvL%#i;Z+rg1vrgRq z@$<*;f9Xv>x}S%}$0+@eZ8(0%>`R*F?0j-^>l5EvJcW1Z8^7?Xv!3|a{bx0QXu)}( zS^BpxGsgKH1oH1X7Kl`I+-uSUA%f5H@KQR)Q8Gq&G4`vn~-j?|6v@sjz?mls5 z5Zq_{rQ7E|w{%A9hVS()_}H7ju>}q1UEZYgy?1>7Td)59eFtwIdea-e^q#lz!+>ch zLRrD-AMAW$%fThL{b}Li&wl<>#ebl_#_wHp^@pB$=!aX!pZeqej7X)8E+zIb-IGS@UPk zoi$_TRsCzPTHCd@r}yTL_1!a8|Fuco)V*$9`mao;kBPRc^Qskm#yH*A`Bx^^k5*r0 zUy^=365?Z7T^c4gz3wT7AG_B3k^b6}uDyzvATXQvrB~~bG$46s?q3&5sS2rHGI?jb*WHR{a=S3 z^aZ5FSxfcwQoyNgGviacR;-V|1?XNM*Zti1`SG_K1HKsUrqA6}5c-z*|8~Uq)Y)?^ z(Tey5mhfMn(yZC9LsE0CP#4X8-IAI&bAD7V`+XQc-($C4KdC;>Z(pDn@;AX|c2ULl zy$eyX;C^OR$9uq2F@5>e^L9qO-4XApi1%E?dp_d581Y_;cn2fip@>(=EbQ_v@>DD+ zk9d^2bp2tVm0C$4Mr6QhdmY3yYGV@t7V0!V!@?Qea5Ty6c18E^%}3u zQ!#yWEYNblSYH`4Di&ym%rXF;UN9gk7HolHDFkn;r($}~x-ZLqPmu@nw|u_h7_(DB|7E?>j3kl>?qC4i0)M7IgEgPK6c+YdsYUZjX3(M!e^X`IWt; zGL>Kci7F1Jc`9Zf1$4aIBHrzh+?^5czKC~!#Cs^>Jsk0#ig-^)yxQZ~9a;(Q^i*+h zx2Iyk)x26wp~XRmr((f|h_@-?-CoL~%u;#5Q^mnvPtoUPF0?pk^HeN&3aZ9pl(Rb! zRUAzA6yq)8?TmPHSy3k~M#fXc!EK(31=CsPE3`P6>8V(76DFC!Ujp9#X;OtvEV&Z@WNP(=RH*%yx^%=a5_IX z-(WG$^i(Xk0E*27sm$_JELaG2qwy*|6$=(a^&9VUPoW1;Y2$TxDi&0n?n+P`Ec8?? znEWQ*_JG`kpwm;u!D>&%f(M~CTPhEEDi(YdYLoH4;i*{gZK!t`@1Hys3w{8#(Rlyr zsaUWN>Sp8p##7`GcO@te9`Y0x{S3E9n-CoE6l2v>SjRJ6XmL>CsaUWEs)3Xz1Uo%d z96ahNYI&9mEe@u53LS@Pv>5kz3cKd1Sa3Mv@w9@;kuOw}#mIOHefCr=*a?*(lzcrE z3-&<0(|G^GQ?cNmp>8qW4?RV%@^d1kTpUz-Di+)W)eLV!@RFyBgZ-Y01!ugOw@z4$ zvpp3HWMpo{9wtsCQW&Nl($@P+N`H=BZeag1XIkD?LT;Ln-Cr-~ms?f~n`?kbpNK zSnnxDqo-oQ-iY^N#G82@&tY1OO`c-Jdny(@AMsv@c+=SVF0~kGPZb9nJQWLyrn^vT z>8V(-8fv-4c-T|L!A?)bf`bw7P{gabfVZGnjN3g`9Ng)tSa9477g`)l@>DFC7V)M> zywy;8_tS*nVNa2-r_lBbT`1b_DcTFqfji+M4(-H5Pi1*+e96^@H zAy2Vx@>DFSoa;i1gBnjUCqrFhF`o8Raqx_%V!>PHxzOSu;i*{A74f2+zin%f3Js9!Is&PmM(%7p!MNfMw7CaR39*%fgVq9x6>OI9z13eWB zJ_t2LXmRinPsM^yLA}R#pY>EM_y?#R#{06TV!>{x?Z$h`Q?cOtP=m(%7f;24l0~ir ztTsJ`C0y*jG*KLE^AwgE>H`+{K2ODh9n1Jdzwz$yR4iz^92=%b;5bk5531`&goy@! zBhRUOex3D|ekt#7vNX^4FXpEMTpZ$rq5(hlSL=tclzHH_pr9S9JBp&+eQNYg^sj7w2C`d`17Y z$i?%cPLH46HzU@(rVEEmoVN}4^rqw8>3F&)zP2mgk-j8;U0>Ht9lf2EiZ-LC_u3ip zc-^XaTB)w?SkK!&x;kSwt?pVEzqzMB&Y^TyyuS~ZOuVm$1ndo(xDsz#-Mw-(0r(Tc zGRHe8Q%rCBOm(>YmfU8`29Iz;pp3)5NVF}_4lQHN0U=ed}VJ>U*82QS9h(v-nyf=tB;qJ_bJ2G z{nvJR&C`9%XJmfE3+=ljebcSQ>D-Q$#F^H=PI}9G@H^Mse6A@(TnB-DeX%q(Q<^AM zZ&>2KoBMd1IgMBs*4;|5s)yI4xXL6GzT{Oyqq8f`tNP+Mb*EQb+zW2JF}`X|$F<~np40j+KfqRYtfSZBD{Rd4 z_H_2I?CP}2T}ZpSae;cLeZO*2TzF=mkKxkx7%5wwd& zfLhqU*hYgMJ<;pb zyN&A{8%O45GAH)E?I-=alP=6p3s|y)qIhPY2108Q{8)e7;9_e7hGW4q@nF>Acg5(vqp94UuVOS zVsx*&krwK{Rz|2>m6wf(zhmZxvu9Rpm>zei-JRBKBp#Ont-#mW8RuP%eU~t3=!?$y zTfFFWQ?P#C=NPegvmpmH^JJ4Qz$RTFbL94{y`-rX%I9?WP$wES6{_5*X;3E_H602E0=dnE zdV^7V@7ZLd+K2WJ>@QlnCwb^;u06@af|m#iw(jbW?bJIqhkrSS{o3ZDAbsk<=8}R< zC-MKpca{!pE)O(_a1F!0sa77-0euZ8$Wvq&%-e z(^R2I)Mb&DDD71>Ij=U;)Wo5v+Bf|slRJ8PuKAx=d1>}7Yv>1Eq`jv~o@CeZ@-91p z&aA*tvSjeq_1ya|85lm1XoHv4s=5tjgWGsBrt8%5!K#_6mV7bJU@&3lfEn|1aV<6fFsx zmSQ3?u(2e#>5SYaFMZ^xt=~!?Z}}b?x~zFYZT;rhPU+3?ol3&Wpj(}W1j8BrQ%Td~ z$b4V_h@6di&4_GEA8CJe>-YLCtcC~!8>|cshoZ8TKJv`g?@?4{Vt1M6r-dCLev| z%hq6=f{xFkN5Jd93gI;UTJr3u+n z<%|oVnNG7kmd~C|y7l3WGM?_zrF13O z%p;n;BrtnbvL|^^3YkC4=eG46nO;r0BW>0x-X`bTtnu)^tnsk*Tcx-CR4uPzU0Bd> z=0N9;HpU9aly21r*cnl!k1UzS_?iSivb30keWip&W6;c)1}a^x*L@D(>rxupR!Mga zJjUdGX#Vy}#$f5ze^Yb1fn2)vS=}&f@3@AhdHH+r2X7Y%Z{X&cV>eBgX}MJ##tdT1 zp;}g}<*pkO8mF*WWtQs9F`FhIMW9GYklq%hx8PQ#6_)qcVL8*hPH`(Z1_#Z z&swQ;7seMo$4UifaEk?*sngUp8G&pRF~?;h|e~cWkTo6&ooQA$fRc zo9>Qn`*zwmvj~{KJ9Kvp`}R6mKpT%m`2&&ZfeM@LOHX7J?$I5$hi!?7G1#ruy|GGy z^n5M6(^$Xqf_|p#vS8CW{9pLaGX^$K4*KCw3Hn*0W7I1|Yl%K(8wuQUuKI%vutH z%g~#{nG(NYNzb%OVKuZo8k}U6FR^?M4Q^BY$tPOL&DphYhK2d^4BmdXE7icR zLMwyPkJ_LB(fq~gWZC;Aez~DJ!L3Z`bTz(OXhh?Otp2I5-S+$5M$V;=+^Y6PE5aB` znJygJtzzvvmlBpfvP~Vv60el_TOL;xT!je?&2Ayf@El806fPH@R(-;Xpi8K_>98`* z(cw^+%%V86d3a!_TDS1eD(5CD|Hm4hNjZk*k5lX*igz z0R!$fo7oR$J2Z@z?a;ie)S*OcAet;tG_13uH7^&H4Dr)lES^0L7@ z?uWMZ{MKEix4mpO=itz!XdvWR9i{KAPG0)n>U>>M+Yb(WMeWSO;6DCm-WtkoJ8WrR zy7k>rz-n1TxdILjJYE>)SjJGvkC#&fb#qP;k_Vl|^hMyqO|Dvp2fYzto;c_XN;rTI z+5kQ{xWx_NgSo>Xv=kWgLxpLl;p}F$&=@RYCm5vJhsh@}X!epu{T6kxjb*Dc%C=hR zBfBUy=Ir3Wm#sbeXItB-;e#9BoHNA#KxbOg_#nJmh=u)GuTu0otL5ejZF;y$ch42!esO0HB4rjldDNv&qG@tlPbGqf}iQ5xlYcQ!-Hd_qUf%2XK2`5m$Uvy z*G{o=n5MdNxY9GP9m=2A%5&#~f&EANU(8k>IKoyQFk5*b*H*&HwUyz7A}w;Z(&986 z$lA)`r_IJ3h%9BK;aN+Wmys;x@COwsc_7CSF*L*6vIfN>CJ$r{%JAEXXa+VERxawN zfz5fjh&4RR=h9FAUn|zCd zy`edhlbiWJTGy3m*Wn877b#ai?p4z4)6wm^?r(Eg}4GCSte49p{!cxf=SKo>> zOqG{9ji`)iSid4!+lDLd91Y9Pnx-_NKFb;n^Cc$JFzp4(!v)M_Z4Hu>!@b88-8M`K zH7~B)_IM~<#!MS?s^^wj+{>ayDkpn&OqClms>+Q`pO4}d{uzq5LAmEC-ul-|@xpO; z48e6^;CLt~;fZ%%hSh#G*=G|Y`(Um#M|KoFJN9N$L3(~e_l_8vLlk#Mnl-Z`TWt~!}Q>D0VS>sZt z(7X2~Xa#64ifb;yyUqW=K?k-TpoWaoDNIt6TXrO$4!2>u2R85KLmWfN-TT(*n4#fm zcEE$}FK9`ce1<*b(4@ikz1NKy5oIi0dnQo}(_{9XXHw_4@6|L@wxi)`XA79YrtD~c z+ASe>>f>?yN}^QAuVv^v%{z1m=eESluS^Z>UYN7XnS$RKHMZ+%V$bw62mWirMmA@25$jFZz~RVH(O!(OdBVo{sWU~>mH?+tD|A!@^&T6XR`eP3CW z+W$sFP7YqP9i^MPXwRK$=BuBG?q%;wny-5`vhi8{zWVX(PBbge`ozr$*M+{0@HAjl z`O()aMSg$UUr4LWKrzwV5@yMw<{hD@j{_!KLeZ5h$tN%b_l?^(mQ#--6f0X|Z7oZ3 z^h#Q()w(YC+OM=oj*)Lg@|7c|) z|2ey^emwVlV6^s<0YSfR*0u=UJ3yJDeAkgS3~Gv00T`Es0Tl*jqLi{f4uv{-gS^uN!NLgo_zJ7F5PiAFMoV zyVQA9V)vz&9<##V(aT2Q!s6Fby{RAJwEHh+UUH9T}a{-#3({r^M^3a(_Wf78{o+tubsQC;gxLpIOCHeQs+{XbwO>#=9!d`V-8C4*k1ED-eL4FCzn3b@XDNL z=M>&$)n)QCAsm-Pt({A(Cu?HMHA;qRD+ci$Xz7om^5B^CEdC#x?j3ecdd`h&DDcpd zsoNV~*;c|5P8@TO77Zq9hF42hjCTyF*Ay5&<8?{qwe$Hh&0$g%6!*!Rf;L=2uTjPS zQvwwOFX8W{rLDc|rfw^ofBDt>u52rFC{B`6y&m+1+}%C#tpZ6))>V3y4f%vBM(S`{aw+}q@gjT zk6@(P+7ai_f~vXcjquU)g8m!eZLgZUE%~w}or3<%Qr>3DI*hU=U!L>SoN{OVSaz6@ zlB$|Z9Qp}W&FiO^k5omM^I+B7eR#;^cwew&Zofv+mJJoJ((U~hz}|AR8-yC!QA4Sc z_}y$+?5V1tS^=k&HZ=TLzpO&HRFm;%6pj_jGlnN728OL@V+L!j_a+Th6}b*$iCJZ} zq!pORc<#j_l(-~^h)^=TgPrNH)-h4L^A+on?Y`c#!gjw#_i9_72^lxs!kzVkCC?1W z%9hPKH9D}MR=uDnudElmJ^76aauk#Cn_C!VxW z&a@@HfK>7Tsz5KO<-=ZRFWRy(>;)#Y(9~O}9T;3Pmn8O7hP|KxQQ=yBuvvpvsunfy z7-fe<;lM9_zbxSl$J)6l+sM-J)N>WiN~Nk zyKc{!Ep2{VqLE{hnS9xwlT}gC26zO6KKY35)euEP_E-snXB#Z*CfK#jmgRK)f5K2p z+4jPsZ9LINJ(|OsvItX6tIA!mq)X+#u4UPxm-)I*&eoNUp_KzC9uKit<4nm$m@-_; zgh%B_3AMs^^0GIaUkTnY)Rs=Yqx!J6}S$uCvFr z_EfrO&FrLl>}$mTyb7fZiZE=hJMuEo(?P}0ZfoaZDV?>CNhc|)ji`l0%drd!E$kov zWb);LeTDoVFtNVO@;H(~$9Yt!h?)g*O<@43Z_R?L+D)fuc^b8gEE12)nH;A^hlUuy zm{Iu>?nmML<4Tj%bUYrThq_47J=CQ*+u0Z7K7f>~kk)_o^mgeZwPkufqlV{Aqt2Sm zO{A$$la$vGJ+L`@*YJ0FQkAHBJPOTyFbp56DnoAjlA>*8Qlo8p^5LXwKtvO7tr^r7~!8%3w)}8pvvc<%2pnG zR73~1Mf11lQ4y=x%SF-vN;@+2mI)6P4F9VO<jemQ-x{ndTT%D2Y8btfm^Yc|*^A_B%0jy=bV!)?|aV zR^_V6;qm$g&^2_5+xK#_3f^5?Ls>z zT)VuVXNuJjt`+XEcA>oGw+=3`8MC%x%TKLc8my~v9o8(a!EYDsnE2ydFU&V4 z&GM;N)GXE%3of%}u>=Ma3x|gYBD*7%WbL^B3zftyq8^#unN^aVM^h3h0_VooMKWhc zcKD!gGpF`P?Qo_yng}H#ssBS(LN6AvY2;y5)YNL>oaDpQf=<)z5kq45G5mAG|A2B^ zu&lk#Y}{C2LZgY7RV)T%$&@S$47cA()p3MqZ>C#is6D5u*7Hb1WkOK%(_w19~;G1UIT z_Td<4_2eY+!W{$VHOwSx14YS9`oAd&@Z9d`W?WvyU_x-J_ zMj2{&VSD?_+jNX-8|*`mX}8k;@|OZ)ku_WcXmpSFoc&%O^O z_b*63-LHhz2g6?_`RxraZEJYByZt%MH1pf{+B8#b!Zg>5L*-j=P!A>dX6?jY<`g`z zq;2KiFRQ&E`BJ(><8iRzrQx^Qe5jmhms#f6I6#6ychY5&bea4cxeqCw7l#VBTj%V} zG17Z6MV9k^s}mi&e?fy1T;mrh3)(Hq062A9hQ<)RwAI8<`G z6?<>a6uFmqz_Q-Y95vXm-!&MyjJI4yRP47*L?c@2jY?jM_2;$}XP<0*M-=k=lzY@d zmOk=0)uWY0wE6HV&55YECaA&orySY-%=zulk6j{*jH41{RIxRjyrAK!zHr+&CA&oD zoJNa5Ho00xuq$hLd0VZmtoU(3l`WUr_Yay$R*DTT4c6K~O};p2k3(AYy?%xz-V1|E z{DP|ed8UckyYd$I&L20hf3n~Izr<+Gbpen?xNJOu**sb{>IX~F7<^g{r9o_Sww8^b z=f_M${r}yv@drHL?X03KQO=^$M)N4M=wTVIa4V7NnLN$WYcz8r1cz1VF|{vT~Xy@Sgd&`vB}10MWK8}NEt zh>qHT&02_B1KL7#v<4jSHZK2ccH{#7F}Hvpy)~>demx64WItT_zs;2C_bE0K zUs8iue=eNU@RG{z*5XI(mxup@lgr^fbbmAneubOJPir%x=6T!QYexJC!SuIx%RZ=l z+&VyBy6sg(+ssjJlm26&`x^t#f|Bx-K2ljU!UIm263FpPhUsOO67ta;#ZBn<&)Efu ze)EM-&_$TyrZ)K%rwp4T1sy-qKcIR&p^d<3p*ACa(uJ}aRue0ARd(UFgl4TH_enQO zoc;V`8d$i|G>k$IunjB{@OvmfCECepZN*6T3!hYI#>K5DrL7_54|Z0M2gJ3OCxZeaK1qa0`GJTd$Gk?ettd&2kCewFq8o-mHG-`KgAN6yUHF5B_7`2JU4{qiB&%Rd?RaT(z`-z5D#TdyLFMP9IH z>vAXs+^7GxZLQ^Y&bJ14)PaLL8u)+PjwSrRXKN+@OJ>j3g%MQ|QFEc}aj~s4Bi?jR z>9MJP{mO2I#%+69>DR~bJl-ZA#MwS++g;O;%6v`#_omAo(U(5U5jUle-#0Z|#(kGK zS~hRrj6If>(P#3MOzGFN=dmQuFJP3>z)Ld+t+wQ5o8B_}1@^$#tlsI8JzJ;xQtpdo z>7l#CZP{VX5gE$Ws{W20YNBXWqNfE*x4wq}d+_cglR>ef4F{(ROT*kw$UgNlxK-V= zuPpmmjN=R$f6!Wcb&#RGcBtXQ{0gJO?0e&myHpZ;j>)>5=eS)wf?Of>m{Wexz}KuB ztv8-ip?y2F4tz~2QLvdtFv7x2OK$Njsmst-^>g#k4t4yJp}Qo|GGvA2S*nAsl!K-q z`(_W_B?X`nJ6#+p25}ViC~*e9wvfP}|Ke<`%(ukTXJlK>b4rKqQdPqG>9LpbLzeRq z&kv<|YGclKtRc4S)(FWNkvuac!>sEdz8gl1T`IDktk$Jg*3XZ1t>p_5vxEM1dfSbE z$V)H$Sk7O$y^8k=sPXoC#Vd`vpZ~A3&|);zQS&3JBclF3qF#uo2@Dq(V|qmW3F<0K zZzAP>n^A9sa&n)7>VY>t_!`s-3+<#%j@ksJm$;M%KZQ!(C>MHrS(x6Bpt?+M4DYC!W7LUIF1L3=RT}R}C?~g#H`usTDo|`E z*9+xJl_+;FpDqvjpj^K9Lb({7CxtO4q3&<7ly8EXYt-#fF1;n zb#Fv{4(c72%0o~tx359D+@6NoWTATb?`ES8LVd`nveVp)2Frs}pj-^S-uGHU%Y(}z z-rZ11<9!wC7K^(J%H{TSB=-W;J1z7jsEkq5nZy@El?RKUwixenC>M7bl*@ND)U6hp zh8i&HIjCBTyDy^t2vu#of;WX@wJf5}fSPWhGoWs>ROUdr+%AQ3xiv#=wa}}e-euH1 zP#-tyVW@hj^5E-GcN*`TP|h;wRl^k)`V%M}0*?>=JqpzehF$0%pw2b9ARgv>Kh!ki z{bR)YCn%?N&quspo#9^XI6ippEcdF?@?bC2RTlS`P_7;yo*K$cJUf(&zd7W+59;j} zV>%hQ7|Y1M!+3W>U2W8ZP;WEpxrp}%sB4UO7L`aDwHT`1sGf-W8k9@9^}I0OEi}~o zksBX;h|X}-Ll=b9*BP>o_i2Wrqkca#j9WV^q_#7RKVYfcGS9sNw>5+F+b#e1j_LiT@vyhgmS!l7KFLou`moxy(OeBcxy=gE~2(y8uDI& za%~W=4D=>jH0Lc)6c(x;%7u1Atu@{js0X0N2OopF$EeOkz!%IF<0DWXHQuM8?ltNw zP!yKX$DuxEynl*#{|99{hLSKYh zWYpwp_hR?*U?JpeUilwQ92 z9;0?a?J$bX%uWcNzGZ0<++jRXzvmC7kFHomIpSLgjfIr#Z~428zp7yIBp|vJM>0kH z=~d|NN~GLJp7?rOXLnC(J?~RYuS)f-*NY?j_!`s+%#fp9@yrQjQ-Tuvx|$15HMvOo zeo4o*U7YPVP5K={(v0v@88+~za)kA{5~HbmMtMeMV{~Rp!1MT`x3%`B9Yd&*NWy;^|Z%y4#*{i(uB1O`0#xMZj-T=RxI%d4L#_c6wALgsUR5HS2Gc- zlVm$zTtI zF>(I0tH5`YbyApI80b)AMom88Xo64yB@%%0H z{N&gmqjJ}Rr+{^!mbRCHGNzYf^m~r^3jx)~~x^w4@@9!CV+hgBe`u?S#WRc;npIq8;cj0F){85OvYD zoyi#cc>Y&kWjT|%lMZD$XL1+M<4osHe_0usOle7$Q^{R@9_KRdmgjNWxLcjaQT;dM zaTLBSkJHQDd-6D&xVt@%^Dgf0%;PBh?mW(ixw|Lg%t&`_NKak64u)%yf`6$Ff?sg= z#&7)HIC0rt<;aLNwjjp;>Wa>m`)+XkliOb!6=Mqy@;}{S*EsnL^3qYr*aDecwcW2P z9)0(b=@gmFWHRyvA-$35Of(r;1!>8inSb-4Bhyi7#}-V_NoS&^lhTWW33FGR6jEz> zUvAIJTu#@9?sO=EJ}8$UxZiWeMV!YyM><0~t5&Y*=?l{~PHI(W4=)~fVot_hd+y^o z&Z;&2ed>8#j&p5SIxLRkq*n26=ymeeL^9cQ!&rKKwUY=r_9|=7vXuMRbRuJ3yZ z7fUz$J!gV1kDIc^oai{+eVyIchD~HC^W)f+%*O7DIBVDEa76yW-xpdsx+yDQ@q{{L zIcLJThAz)?E{3xn1Cc8qJSx0c{kKnxR2+nnR96oQm`ue`K7A;(1 z%KWAwxQ#MNbbK(izHyE$vK+bMj1@;~+2FIeGMey$FXnP)X$w4`C{a4ImChp(M={>b zU8QMwxNg!Jd~?JhuUWH@%Xp6EK1=Cr%jIbA9NZakboW`(xxq$CnDRH_d??~5WvvIF z@*J1)Y&g&4ag@6@ibQsGx4fRW(d0Q+_r19sYoGl`a5`-?`B+*e1Z#3RYOr8KF2`zG zZ{sUB_qJS)<$g`XQ5w%t*f&yemD#OEe*<}`>0#KXs{7s5IrW;Oy5E<}nXRfmo69jx z_;wyg?Xx@L%wS!YUapv-8-SL;usEZ=%;)tqL}-V;ea!d9Q>*&dt(189)na|bB=Tnv zkmK4&Rb4qdwPItn|9VCp6IUglO&`IotQg5juIsFv8#4L&L0xmYr-a0 zpp~ml#Q0e*-F{UJA2z}b&1;0md2H{qI+9} zXPeVj^4VKkv}e;wr4shpnc7rJp9gW(3_Giey~Op7#rH$HHq@<4_bhVvol%blXh&*g zk3M{z>Os1*YgGqdr-AGCA~_7(ui&!mTF*CpQtP^IO094?boX_wU7x<06;Y7t=*7v7V{p-@*YtZ1H^#R$#=6fF_`FtLwb4?e)YsnO|NTinf zWU6OH|0*T#V=PLvwjCv?wINYYnNobpTxZ~_tGXuD(+lM`M3t$Qw(3;1KF-sc<^$17 zJ9_(Q-%3T|BS(C;h@}gGl%nVQ?k@F2Hb%0K(%Y>DRu$ia^0%$4`_p{7?)g0EKDEG$M;Xv4k3l!#Tc62u5^Fzx)k5r>79CUMR4f|XL04Fvo5{#Smvg(a(?A}rz*XT{cCA@ z4YHNJE9cB^(awU35`AK6lQ{IZpnXSbafh z@PqOXuDIl5?x0?iMXp~+_iyJUpudBM` z%>MrF&Kb-aXZ~4iqEt7u)r=5ss;_BGG$dQkjB7RaTmJ6iZ&^?<33xqxy=K|__!QiX zo)y<|Cb)1?5SNObhzH;+{ra4c!-j5s-Hh+L#izBL8`qK4+U|||rjsU8Tt&Sq&+qx0 zD#BkEqB2^qsqDJG1938UVO?tJvN!kPs&iHx24&;YB!Sz~PH` zoxL6F(tN1N9WC_3T%Ydc(@e#a4)}!Dxp-o|;8`pBJMoLL7%!gmjAwQ8nWo}N&*ced zwqZS7JV{S~Dd|;w;L8|1^<~ExOfV~g@JP^JB;aeV_KVZLr*nVU^NI?CjM{c0$o4LX zfw&ujVsI8%0$u_h2QC7S2b;ih5aSn|1a1UR2Hy!z0k?stfigO$gP#D;0lxrF10My? z1)l}a1OEk_4!#0j02WZj8Q^m10;sp1^5ytUCpZt>1YQi@3oZa302hMa1m6Na3%(W9 zFBmI9{k|pvj?~2p_}Vq-PuJVo`Ak3)X;d3mKL#s;MY)O-D2_bHdL{kXID}mVt5`9u zU|VYu1F!nlqIB8{e?oR2c=`ygKIn1n|5d;CPvrFHGEQ#{ggXZOv7H&W4Gmy zx?SCEiV~h&xjX5k0F#r^rGs6YoGH?d?Zty}-Y0Lya1ENov&w+EnJ>Wd>`yft=%um3J z!BXwq{p(;Tz0jlzm`c$@~n=@b56V1w55JZv`&^Zv*v+@>VbjVtX=r z-PJbmZQvl-1#Sm7f<2@ZpF zL*~E0zX7FUEXXr6LF$yL0-66ZHQ-0UdJtQfX$LTv^1_3rS(*}MP>;fMIHC=ojyc_&G@T(y6Z02j=L*QQU@4>P3*O$N|@L}-x zwBuC%!s|-RTMd8Zo*^IOn}h6J_#NswdxRZToHrvc92XB$itK1K3o704qB!C8f7ps@ zXvvDI#a67=qDix&>YL`zFUT~UCVQ5xqs+4MrAx{5+OU4g->qCZ%h@P@Uu$=J{hhP8 zFZjFbEbKXdx5l0g+U@VwHTI-y*t}bDc7@C;E1}kv`(eEgORjZZHQo|ut-ajJm1bQZ ze+`^&4S!909^Ijj%vVY#kxjuL9Z${6;OZ})Zy%>h{R@c9xE9ztB=M3|C@N-aO z`rp9@@E0KCO;4?4{tX-k&mfIof;WKs!4HDJ0yWlt4L%P32K)hd0Q?2`TTo-_KR}JC zgW!D1fSzVP3H}%O9q?7~I9aR$#yH4YF|!OT1UtZS;5u*ums+`gRDO?Gr>vVCEy8Q4R|8B1UwnM27CkfQE)Q&b?}YgPr*~b z6B#>Gz%#+qz}evGpgizz0&fRt=ggNt+A8yN@GS5k$hs#}IG*(hcrrK*)SJ1^1)D*3 z)|o3o>|SOoI0O7Bcp><6a3=T*a5gCa|6K5Q;5=~B1lCyKn?TlinRy^~Gjj=8308s$ za5-27t^ljSZD0-f84&xLc@kU%{uEpc{!g$LJPg)>BW=qEC(>zjnFf}w$flih&>Y~o_gHrSCE82DezYC2JklU-QZU6AHjEl-vYORKLH29QpVzT@C@)h;Kkq$@LG^3 zCNejJw}X11?GEr8;QPU6!8^fUfOmm!plkjHWPcgl4bBGd0c*jJg1nM6xEH(={1~_! zybt_m5HC|^Klr!c6m;}{umb!fsP)dLz>VMopvLfLz+K>H!52V2kCrK6tUU;x4*nfD z7o_bno!~=Y2K;;QA@GafYw}9UUo4}{R zYryY-H-O&-H-gWA?*_jI-T^)bYP|jc9BBiF=x2?lIDfigl=pNj0L^VSKu2WP;^8~m~en)dzR z*GN}BVzH^wt=R%@*+OZZ5ci>-HkD7+opQ3Y7-9)!^q9MQV#c5tJml4lvZ?K z+h}pMm6Kt*F?TL!yhfMWF3$aQIM@Tbenr2iJ%0dYg$1)2AQabN*?^G(o948&I0x}EoPW|$X) ziQu_l44e%f2VM#u4_*$If=j?M@ZI2vAY(b;gI?G*}^K`F2);ijw;6KUtEroIF2rG*7pIrrO*>pR1gd&e}q2^LQ zsd=2g4$}}*a_&~xoy~XLt+YFo$7UV>Ji6wbX8yuU<&f?$M1va7tfh|1{xa}P@N!Ul zJoYu2xgei@Gyh-{sPeO}JfclnV~hyeAx^li&tUU%eKog`!ORhDqB!RuE1VctEL~;; za{M$(HN4ae{(2pE7{~VF96R*&vq8DrlgJa4wL*A;lvkYUYut8nuT{)c-P5)?mMHWv zciQ&heoRs1oWXx1ZOV5R$^WAyv2@BI^bW}#By;tG55`-hB8JxM=-#2w`Gg^rcWB{X z>>X0QN?1Kb#jY{a{tRoe54|0m&9lWdR{0lmIKFCGuaZ(Zlp}!KDc8?3lN#U6K;Y86 z@f4D3grhr};#dPOy!$nUZ_5hrI;JrGhv2QOZ@ARDk9y(A(e!Y{aPFR+(fugyo-UV= z>hsVMxsK*&8mnRNa(*zIuyZusA2D3c4@CE)%b3zec*?|&EQ8s*0{kvpw#oDAZxeaUhoC*KJZ2G;~;Z>@ClH)KKNUZIXt)@WNr@F zS7(?D1AI>zY3`>%`2!vRJHgL_ItBk6NS%WR!HwYOK`HOwflq>80RIQbv%Hz_gX~i> z<59DJ0QD3uzO2kM;Fm%9slEz+8hjMo34R^?HTVs1Dt*2Syas$6+(gel0p3o(?FJvj zyt8-6Xmj{&uni>d%qPL8!Ow!<0Y}cqJ;khpj$}e}+enN;ACvznFQB55`UM`ETs%?J?`Da>&c|7p!+>SIT`fJ5UUFzp{5ZzOitw zG2fVE;)LhSEgFI0%+a?3V_H0E*YBLwT-U$WW^ASm%`c&^-_17R%J@1P!{PkF8JI*L zC51D{r_bh!r@50qOivE+n3+k0CkfZ%zvQsuKeG}%*u&wl=9m{4?wfg9mNm4w+ui{0 zMP?AC)!V;r9VgdKy`7v|s}6g}L{-DbmpdU$WAxlh%W|n;5BsXEwm3We-Hlq5A8Dg% zvo`9%FrGUqdC1=~8IFvoW%IqLG?(h|fR|jc!qrPXaDSH9z0r9Q@AIs_)!nPoeR(x_ z8!4TQP2-Yt@g6VPF}r^~&s=ob1amh`wf7B6JJwiibehw@G9|w6+h@AK1e`=( z`2RAegU5pxf%pz=zfcA)=YA51uR~`l8GH`GiQsmy9Q+7)68LHGWRN{`@CNYv;AD`! zYryXW%x+Er3$SOWfo0(7;0a(HoC%%rx zB3Jf^l6fz9 z3;0cN3;0`bD|j69%)7u-z(H^}I0Rk{?f_fC4}$AJPKPr)zz=~Bfgc9H2z~_I3*H0% z5ybDDDZ(h<3!Vyo3|s=<2QCFa4sHiO0p1V(E%-(7e(;;%C&5?1Pl1~EJ_9B}`abh6 z@JFEhFFyulEdC9A1pEp3FW_GAr{K@PBE~+tk&zAfId}>9?_fQM4=r;I_!8I+qC1%k z_)G9sa3A;p_-pX<-~sSU;BUdb;D3Nx*SzOE##k_6(z{RKCTMJ`Nv7%=mnQ1#Y9e-l zV<+pA4avr~;0<1SjAJL-+FI(W+S`&CJ(tW_7toem-WHtdd4-NwU6W`_q*{~JZFNnJ z_={YGaXy2_wz{?}QZ30v$(Ceeb&~nPg^$k-52kwV1jlV|X{t`Pw$?Q+rr@n@E$uGt zuuerjyBU2 z(*;3QU1JTcrDm&5CTfx`twEgh6gVa~Fi~BdY;H?6)bSJ>&yqQbvAGg-b4w!C&O^nj zjS?u#4X#f#E^bdOPDY{Qazoo&lP!8eE(#r=8`_*`ZC%#XQWIr7Avd%=k!r46o~&<; zA{UJau5PMtYTGHZ{aHdb@xFZB?FsNm%!<5MJxiV@}4K@Xo<_6R;IM49`Ww`;1>Jy7o z>e*CVQ>v-zGR9d{i%GeH&224CuDYqw6j4J_`J9j|wY;V!)znhAxUMnMjT3XjYnqld z);A?;niFlcQ9G39O0+aJwV|)39bt2xlq*ozSl3pUs821bt52F9gspXQt`uW@`4y>1 zS3;RL94QlN%o)BylXGS0)nrR^OI<5Qt|l4`Z_E`5OFM~&5WlF6qFvqVR`vy_kmRLv zb>G_6%c455e*Kzme#6R73d~mCcDBOmcoaT-EZX$;(1{vS)lDs_rHnG{UaBE+neJv= z3GQGiUl24WS}0U?qOqy5t{UrmrPB!oj`4wuTI!OGHT73SvBvrU%xQazETM0Avb8$lZKFhr!X%Rn z3={DJG71uy=mn%KsYNYK4Ux%EXv~LF1s7;Kb)t`3>_cs=gk>%9Oa?3sYdxTpjtkk< zwaJDA3ul-8@gcj8nJP@8)H7?E8WJdZ*gR#PUEfrlh$bqfJt<5iY;hkkOz#9A?yIi( z>sJZu-q!Y%f411n&fb&6UDBRxxgwQZ-dxvW`J^xi&R!^dj1OE*lA91F zmuO5iCYIJMR)M8*O0LKUGEQ4ljmb7F_vKNV6MZ1MQ=On|YRsf4S}Yr)37lVoBx@L` zEmxT3ltgh>!o|fZF^HO*Nkx;ZWJ+=~H>oJ=XK^H)-TBLBo`M-#JANVfIdjJ0(8!$gZ zH*^}M=|nUY#qn1V&5i8?O!tAw_7OC64YtXWKXZRnOmv(7@BJRLbT>Bp#@=pY8s)9%QZ9o(fbTv=+Mwld`4Mqb?KGS za^-=JRCYPf?z+?+A9|V=tx*xwqMvMNHKmKr)~v^(HXf0L2e2f_lnxQ6MZJk;P8y5Ow%B_M98_)+smmq01(Mr@&vc*dO zNydjlpHrhz5*)PmlSBR#wO-a0RdEX*tEzFnK8zhN%cFK_=#^7S@x!cwsS<qfKF_lShz#ibUV>8R+l~F4Z z`6edwU7<6iDO#gb${~H!C_V zoaLyX#?YaIhyINGkjI+ZiZS7Rw%w0I9Xj`1-A`divpQ9XW5fv?u^OPb z5pkolW-(t?nTj<;EDF4$lx1ANJXXy3jLT8P!B#Lr6d)vV>o+L7D_B;6=$bJA==PT5H(WlW0R=6iC> zNxD_UswykWDr%U@G2VF^?8cs>NVSHw36YgcHLa?OwGYGBRW^;tLkuR&it<=>g+DL^ zdRHlsGfS#;=jiM(C@ZQoHwK}~ikMju6qI#UnsfQA(y298m~v%dmFCLeKvifMvkoCI zEU(hMM9V8`!pK=-r8!EskTxxo6qcn{nlr*@PPOLv+(>1*`l{+$=6jqCAYCC|R>0%D z4)q=J1{jZyZ_&PH3dk)ToL(<4k40lsn9j=PBWJX@tt`yB9LrS=(?j#2gvkd=J?W!5 zTB8=`21B``$J1Pcm8F~VN>j)eYCY+TMjD-kww2nFBkDcr=#P(DUIa-*%_rR*Iki;t zIG&ptJT!K?WnyM*TICd$R5Ds=D#AQ&W{sO$M{B2Ie5~Y+#lb@h$5``aJgh9e3N<^m zVp=WZ#|$RmOz3ILW*9R~SIJ0PZgZJ;3KYdGGSFflR*|$I449wYa%*W+es&-T`yL((;fQ%uVZnU3x`GtP9<8k;-?Hcse}g62(RqtS4mE3lkF>Hu9E446#xv3UW@*EgK&9lF5BGwe2=lDJYqiAN_DPE976Myh(yvy6@*7xD&97Bj^;Im1n3g#`6(le)s+vFYknSrekHDguloqd& zIn=66W3QqN465eIxd+uBcnNH(L2M~ff~W$cs(A^Po_@*M(4nXT!>TXG8K_OM$Tcvi znkxpgim4UR^1j6yw4lJYYTjK;&N!nvr5VLEFi3Dp8gw##M7w>5zNH ziYhO!WB`)xmcI}AMpzf0tkN@TG}W6~je&UP40f5Q+OU0}oa&qUX2mlrS~YW4O^_j* zHB0U(sXlFDhMISia1753FF|wraH_`&f1a3ZLK>wc@6=RpPAzD%VrCz?pO)%At8{jl zAej*4p(xb@RXOLXat2$cTr||l&*`at+>QhD^l6N@GC#@3@Khgeqk&}rv)w>loRRJ! zR)rA-;}6pc^{GPS=$!1)$uA@oZ~HM6KD44jfG1zoK|aBLdiSpkUm{* z!s_|RAwABD+V({t@$5r-qzqY?hYjwWLwc-?mSW@#^v1b|^e6Q@Z5Gqxu(U^}`t=Ku z8T8a}I5{uP!`Lc+Pc5vC^Hbe1kJ>hXUu|J+jPeU_RH|omQ#A%is@C66O4eRb)fc4t zPZw^3>&)5IVbHXSQ$3sh_9rhqQRV7xbefMoJu%R(e9pl6ACv0enmdae=2aClVig?h zBYQ)jf5)bJt%^^ntf-!j?hRFc(9p)E`jZx5mZte;(r2Kl$EW%<6P0X$X0{>IfpVFU z=F3*gwxg-FNm6Fu`@%HeGP`0K>oZIR{dr=l?+N3kFt4FSx&?vObLtLheq_fF8_uNE z(7}qbwm5XZs9*Qdq5I^1-N%IP7x(KvHgvzFU-xmL`$zkAA0N73+OPYB(7mKz_X|V! z(th11hVE1Pb)OWvm-Xvj8oHPF>pmrPkM`?c7P?RE*S$P+pVqH?a-KQ8U-zk@W~u1c zol_nIMSofU9!7^AF7MyNn9xII{~pHLI)3{^TkkHpsi8&3j>qb5Zd%m7$jkya6luL# zR#7FB%jLCG<4n`Fx)z`1B7A@T&bpkbge{Qe#zGOd8PVBnqz5~m81Ji@o@&M;FRT{v zVjC)%UV<1{DoP5SUaPCAj9WFFN#TOCQpC+HR0_^a#!X4gplmZ?dbd3iVhUI>vUns& zbPnTMv~nssbefc^zwM?Swwdu7n@GtswnIF}XP7yjo%GTv%q+}oBUfyQN*NYo#7tp> z+YI?%W(AAkt))r5AEk{YxO7T2>mrSgvns4MaGj+zH62?H;~p`v**H>b(WgE(s(j5!&AOwaiCOkhqhCGoX>Yl zL#&?>Kq0LG=Rts4(b8S!vW73q@N=5ckZQH0yX`xmsm^Hkc<}aw@ zpgz`CxkGhtkHqjmw5`!oN}$hr*%tn%;!)k)cA}i&So;*3++k3QTI!Bh>Xb)|Q)#`i zu6Ch5f}uFcn>Xbu=E}MWO3i$pfs2(5=Xxq0?W(At0~@iwdBiwhV>PHct>)o|+8S2K zxkL46#H@zqg>~~ATFaKSOt04=b`32}^UE6=n-(|diQ<%YV6`#*Y@RW^g%kBSo^g@M z{3cInM0v!P2V&JohAJ!7JiSoE7KIBt+H}87T1_yY7UmB7RHIZQ zmHiiEr)|^dUIk!{lmbxfYQ%94aKsiT=OS)V5zIViSn6e}rFfjJ*3u_yKOAIQM^J{d zm4hp1V%?R9Hbiis;Nm5uK(04%Kie9TI^Ax9tHAA1f|+LXqIKq4j}O|TIx_9hrAXDs z)U_HbFzPth?5%-EPV}6@36#^_agNq>l_x66`UzQ7+m%I`7?URDu$HVPpo?M>XWnVxQYRYPbEz>Aou%TLEOFL=H29}K5##4q>0d9S2SyK(TD*X_SGSa4-XtA=z zqgK6Pcd)LcdXT~nir23Prw@t{8ZV>@^AH`*u} zDmxuy+umqJ*^Jn*;eD3JVN9j!!6jd*syus1EV6>#1RFPoNe-t{a{Q%zZl|_+Nz>vs z4r2`q&AO0fZ$FWAWNEl!V?668S8n{xm80(e(z1(>UG=TcyuO%*X#78ZwRPju&zzUS{-KDsQr?~j-LZql!x z`#XA8@3IzTJyCVxyHlH^0k|I{@D1xdT#9}e^qta-}CDKdeMlHzxqAj zJTQLrrBS7u#{c^H&wcWt7w>$kXTpb{cPF@Lmo4oVjN__0@aNsQTjMbML?M>wlw9^PD{VPkrdS z=a)VI()JI2_3DBbuK777&hysr=P&z0$HfO%mHzwL18yF-<%D8S&m+Ts=;V%{O}^~7 zZ%^;K^Q|dHV?F0X@=3_iBt!Ky!vQGU%{Zq^LU$Nrt zi>Lkjx4)V9Cg=4Szh&w*U)=uSuT~B^`RTX*{^|4HwzECFIL|}tkix2#CD*moEh?JI zL4mDBXWu+=!Z~yKhR?VtLjx=qqI&^I9(U26>2Q7F$=N`8n zsmw)lX~0cO=C>_8Qc23^{5Iy-PSAV$UQ}z#{JHaPX=)xb*G^JsUBZ!}^N*-U`dx{c zSlz;=>lPoCOeMR(QK&^fft0$P#!Ui8)D#zuXqeYrbP3SZT%`MPMI(!@H3ob!+)b;y znTYEpMMWdVj5D|K6N=6^5C62Ne>z~8hB2eZ6d!3S5H{8_G6k29e>QEbLRY01xHkUqtev{1az1267V5uJqL%RA4fB6{15Cj%7Q z3ZKgJR{2!Kt7J|fS020esfc$F>QoCcowvC}<$3ymx2TAx6LxgsSf01ery`!-7Gt6U z@9RDl@${`Qy@j3Uecz`d-s4c`8*j5u5gRiW7Y9l7<2c8s^1Smy-jyNm>X6qN@;)8% zwuQXyA@A*wmqkUmd`$JJJnyoQ*B0__4teFgL3J8w9_+34DRS;p5%0gC##)Yk&w zcTnSu*W*(WZ$A{PAxh(bPer`!JUe?8-e8}Kc+;8JDK<*nry}+Zsv>xUy}ieIo~S%; zpHD@+UHJiTw@*d9dzmGlZXx#hRGzorry^b<^Le@EdBc1v;;m!xGTcIFnJFsI(<)08 z5A3sQaJ(9yig@=yonayN`xJTeDOw$N6BfWox!9*7-ZUtT6YwtgDW2zonq<7IeJbKL zK>8B3>KRWaHiJQxUHd>SE)4+NUDkolp~u_j#X+c=te!H{LgVia1yoDD}kQ zQ-lq9pAUIYguJIh-rkV6FXWB?P#|xTPer`OkoSp@_uY{9A0cmd$a^j1MOeAH^d09@ z5pP_`(}&3A8u8|aypM;x5p?JgxDNK3eJamu^QnmUeW()4`9nSx@is%18t=zG74f!1 zO)=gMpNe=dLzNltw>}l|UWdBWcz^M!i1#+sM~#<7XA>3ia-l9U-VmRPcsJ72mC`)# z7N0_IguL&Eyg!7z-jFx3C|i3Eo0u}fKE|4xxMEmWe7`xBcg6O}>0cHM;3d@P-b4)7;;#6f z<;(UJe1!K`Kaz;<1x72T1D@92u}>W=Or`n|-tkLdS9zXp8(`e2ZNQ#zOJ&AxSZ=dyiX`!QRi z+a$hs5DDsvZ9~Y&_^vnd&wY|#Y}*_8*KU3z|LRSAsP-@ULvuzXqWh4zV`OaC6$=RE zePV#0shmLgu+C+>yk#XsG2qr=hwzh|i0>sq61CqIjy_LJL55!=E~MnPmYkx)khVs* zE2iFK60z-_o3pIMaw)9IQ_7cp5MCmFu=C>8UVEMjn{u0eO7DQ)7b)`2TTXeW{n!P( z8EfBdrQ~yFC4N@bjYji1bFQxK+%j(RUduz`ch_(To4a&o4g;WF{>ePs_>6Mr-hwL= z(Spg*!uElFB^Hj16?DFtoqxwFJSXCXoqx>fiXSAge4=*`wRtcRJ2*L3aO*;nsRRyL z+ZEeS(?~>z7)@h3*!d)34k*ll&P_S)`@fT8g}0wWy}2-a3Yg-WoU{7I6KNf4PJAS| zJvWi_sjl+X`+A=anEUOvGZ8E7?4hKT4#fX4izJbt$x)@lHSL_$UD5p%za)#^2j5Cp z>4+cbe3CFket^7^4i{(6>O^b^?P_x2a?+vC6jPCwj>6A()hs_qI(+7SyY0MIWvYIq zi}G8(m)EkrD`$5L5Kbh~?0)MI~apE$Pa-WuI4RwBBa?^buMS*bIs6Y<@A z$hvFAdL5vhi0!uY?(ST++snV>n^YIn{9BJ*us5Z`31ZnN;O>Nz(iPh!K~73nbY~*A zljhv{W@Ooi67iihOZA^2YL>yLu?u?twJEw?T9FPq_Jv2h4tm|6yW-nvh1^;v`NHd)mvx zhSb%q6S@6cG#PDZ$Q@ln)>5lVw7I%lYXLB6k~HH3y?3I3Jfb*`#^4%C&#m+l&OIbS zFOUYc6_*CJs$>pFN-Zf3YH!M9*LofF?cc`tDh;$BCE2v8xw>2HK`{4QYu@kDuuN%) z@3(5*Z)pglo)$LLu9Z3;JnR;JUs0i3+RU{}w|-ud0>7k&7Tr5Jx^LOQo(*qH$UfQ! zMK+R_|C43MQ7I#%ySi2`B!b={NEnIY?ABdkz5bI~+ECX@ojGo-BNt(u7 zPBHI%T>q61-PMQ>fPem@yC-!G(vG$~fQ^5+CG(k&aESg$l> zTk!mc2B4}XfjBZ8s3tk|{vb_ke+kl#!m?9bf)W<5FSKjTdL7%{`>Ye85+zR-vo*tv zJe`vk*!jy|vwk0`a4tcT9y?5uT(HUU!ez4(R@&K?qWp()ySjI&B-Y!1S8mdJD|H}v z!gmu*Yg5J(&OwSm=|mCqu47F6V&|);Wk0$3z`)K;1G-jj!X+&+{T6$-ye&K431U{W zHD|5W*z;*Y4_UNPKcGu9QM=kqtg&=f|>oYg|nHEIAB=JxeWPI`!TqZab7Ne}<92f@AHd1F@}-m;e)IiPLSL#L@SR|LSRN zLtP52bo+smbx8TQ#giVQ1)UeKeW!h>?{jlemj&tlb<#`!GKTsI(AZ+J z{@hQ7`j^i8Pju@)`sdbxJ*v!i5!iktIcm?$k@x;{LOQRiyB~wI+Ist{!mQrJ^2aSHG+mZG|C6%p z={v_ronmNGkTS){KaHot+@&EV$6xp=c3yk2EBwBNoj>Si7`C44z!_bh9nD>xyDIkg zM7$t7K4kTPRnfQdABz1w|DpI>lYi1SBLAT%bnLCkn{UJ3pktoBUQ8K#C3|&rZ%;V~ zV6kMd`4~&vAvU36YF&^W%UwNmRs8Q3#Sle-+&HqLZ%y7Vxj`I~Yi1J3Rm(^2o}RsA zlqPKAuni2cIU*}q5}B(+{@tP&q9~9Xq)~E%I3)MAAib|Sxv%xCliXOYiDL;o#1hUd z`u&x|?m+HtCwF(x#gco(<)C9mt$cSmxx0E^!}NXR<*+l5yVJ?t*|SD+kGLE-n%<>% zhm*UbXPo37aXD-c{yOwyK?IMv2p;P> z*(DtNR%4>Dw9$;R=!xKNU;YoH`}2Po+c$YLo%n}wXsl-2)roC-A?5I}ll5@VbLh7I z68ru-v7I|Cxf`9_jXgI>E(2baR1K+WG;<%iA-E%rLAsR27-^JUL1}z2$nS$r)`LAG zCF_V4*aLyw2b|modR}C#An({K8xuK~HJT|9y%^k)#volvV^F3_<9&gw`<$%%dOj^# zN8Cv74dmYIv~-vcb${FuICSM{<*p~3xnFWEeuyj*Y@ay)+4X$H9;EJ zxHPWmDU;lPs;*ZBvQ{}+t9t$hapZNqB9Obn$z9R&RmpvC{rdD||52am2xN6QSslIX zBJ`b=0cVu)}mkMLZ=|-G0TeE6w8572U&L6;^(FI>ub-;^-+vV>6?DYy=I!*g1^`=ugTp6ebG0 zmDoHE8-UOD+)j+M&0jG9GzQ+ zhPUO@gQmb_RbzN&mXil zK~hF^PV%tIM|w`cMA`E@)??RFH7P3$TQIO*xPnP`E|c~lECh~U9nW1Ae`j@c$SM{O zv3FL*hA{2s$Nt*(+lH-<6*vz5qeI{fS{-BhKLr1NE4TGW8xsQUC#|9VKcaK_`xrR4 zMr|65NuJzbtJCK!FbS*gtXQv)Yp^Smh!UCjJDrm!%9n#b}=hc)}< zmqQTi1O(j0Mv_F@M$)dtx^9VNQ%CWwSt*gWVYy>ud}rrdg|`msT(mF>0 z!pn&ucBgB@+1gcxSC|#F0d6*R$sW$$5_^#QtipHLhW1|iZfM)8QPq10owNfAD@Nd~*O!iA6%uSf9wQ)AW*{p==Z#(wh5$-hw z+fO|=llNf1>vnv){jT;zu&I}{|m6*Aj8t~N_ zGHv5&ze|VhHw9ZzmX0v`X>>5ZC$86LLi}6QO|qlgrkA-|r}4Mb*oSg^T0M7Kd)zBM zJJA~H&eTS_BW$GF`_@**n)PYzw5K}QqN1wPwy1Wp2S%EbTU5GBtk-|j8@TIhC8h+} zqSA*+Y>P@?Ea`k)|80xP`EgrR`X~wZYyFo6+Jb~RU1_)C%bRUc$)~!L3t~~Is$E>` zEh24EiO?3+j*KlTIt^P?>e|UID%~Zz^*`96dO#e7bz4;W%!zGL>H8<0kL$l}Q8{mJ zi%Oq3Nvsbz-4=v=xK^>=Zq+d4&9gORTV@ zjZBZ-IA|(x3d3{O%Vh znPf<-6!zuu<5x=3%@s_V)Wk~p%xnX$0d%dGn;&o3KGs>ir4|c`viMS4o9b}IiI#DT z!EX#<{kld$yz=5ZCM>?xf}%Q;b?&!_WE)Q{u|B1u_F_r5CSh%XCk2B1(5zD$q8dtO z5tv`nBDWMd)+7!k#~fE!{e;C8$dOx$94nba$uY;2qEWXDRPI?HJW;dEJpV1J!%Wr@-dGXtxO_S03S;7k%fKoy$%+ z+`f7AfZlC$&vxl~umhdT4tTfb+pMT?YmW9dz1~-ChNX7zCT^Q|v&_@%+vW)V6Ipt& zOrf*$*Ypx->?V^@(Abr888ep62ee?!jvdHx*E*0_>y*%IbE>*30 za*F8XR5g`<`>9sqst8A9^Q@essE^+5HrKWZfz8kwbU#rS#uGK zwX^D3g+Loq1>ciwbis0lmZ6>Y+b2=4UENYH%T2}5TD(@aA#I__2!g}YD^A>nHe=#P z^E|-lpzmVo`4@fQN)7J%^`f$EekyADUTS-5s&;T?&U5`Zc|JtVqC z%LA^Y&cL4QZ8f~#iS^5+ z=UkX9UWh0wf8{@@+^sA1jWcqEX)Ckq`?Zk&nIAE6R{6R-@UZ39=zaxJ%h+!N+5Y9r z_Df3sXHKDD$@S#u-uxAOu%6P|OP;c2Xu^brJw|GC`754RaQ5m$=7Tb~|dS;GIx>*Xo`jynl&TIa&VO7Tao6rb{BlV15^)vt%l_a17` zdsqTn*(U}#p*(t|&{zeA5iT&Vr5GD5>X8<8!io)(8Oc&aSV){9;%T$WV-b@&TmBPe zlZVl{rKR`$oC3!xnE#M#vzQEyUBCy4Lc2+_SXusR!Vwhf?L48npXQX!h$9xWvaLp zCUDt}@SSnQbnL#Rc-)tbiAaVBMzwux5UM*6s*KJ29r4pt5W~5YX zI#n{IVgxA-a-w41JJ}U;+j+{uW0pm){dfjRQ~G-+`Oe2K_|to;@v|~({8?*DDb0XU zsrMNodwPWxd{)q1yY=BcipbQD>upxq-TDF_{6I4$okp4y3v@heU8yhd(XW`H>z-vk z|6hD-`CI>hdmE2u=-!t1B6@$Buwc$w;}n9a{LW?jy<4wItW>1gPTlL#W_`4eR_04R zz>uLY_9eQFA1`QR`Nq8_ZJm#cH+peErTn&I7x2}uuv7J% zho&?oaXu4S5Td1Q9uXZf)rNU7axPKJf?lwu@w=g@hkMCdPf*lis&n$26@w=cy9|=z4FK#Qcw+0 zv(0s3=-M8-egVqK(`QzBFNzRvL7i(MG;*G4ydi8`@ZJute45-|upFe1jN40>gSXd-mA5!xvT32enfpX3wr=+xKYh`*QB>UJD%L-3N7{Q5&Hq8np>(l2O~BE;4E-)MTSxgSyzLkDeW* zY6jFSdgmO{_Q7s=e*E}d!LLY>3C3F@P*&{9Epe{9k zB~T?sRYH{-H3w>nQGD{=UI85Bu?h1qEbp49q#iCaS5bfEr#>89k$~`V*g%~Mr(>1f ztI;dKDc&^NP4ZG0`N`$Ci}vBJ(pq<_3`auMH!Z1c=HP&~#@Z##`Ycx~FFqen8}08Z z>NvjO6h88GM(9{O(*>$-ThdZ@T>}rn%^dm{T#G{=dS#JMSMpOjg8W?Vc^$f+3o32b zfOJES*3s*hb9^dK?#7FFUxQNFg?`9F>rcbDD>VJ)YExyKSr0+pfUxMm;Eu@++wa!+OZ7y|K|R z{DtpQ?D{&c3hI1ft*v$^d5Nb&`-FH?m$WRZb6)~h!c>K|m3DLxUvtPCs%+|vvf9#? z>ne3fS@Lt>#W)3*=;{1Y>xxfdTV1X6KYRNrP|@TY8a*iJ<_UINl3no$nQfSbCm)q%f8AegXwQC2Zpt`%jxV&(I?$mj>T>+4%=FWx zic&eKQvb|PP3ruNic%Q)xrE<EM8kNOffs?7gUXY>ZL7+YAJ@@D zxyln2@m}*?^Q;;jk7VfsG1h(Gpg-&W4FCRd23Or{q9ERJl#lKiTg?B-lzNeW&1;{3 zeM4K3PEz5-nW9mnMnyum`iADV1x060s4rSj*II;%g=$~i($KnO;f)RTMVy&Jkk+Js zPX0k#wY9X*H(7Q>i<9V1!cr|W|Kiv~zL?8T6Pzf_?PUK3w02Fa=e^Avs)7HdcEv*fK?DvwF8Hjr^s$a6Wq3Fzd zsI~=7tx(Clzzxp#I!|5{yrJHa^XnEbZV3J2c+--W>&?lsd|pwDKBri8=J-)#8l`HL zzP2Sxidq_)8`?NX-IA83wgrn6&Rr@kwJUe2rwy|H z@(J(66WgM1eY0XyR@s-n_0i{g@BHv*q$D`%>OGyMGp}j!Tn!S7Dx2o%Agr-t=9V|i zYrigD9kR>g)uWp0=Xrk~Fya$``^A6!;4f=${oehre)*~i1=r8qQahph?Ry^n(uOa* zGNbIlL7zDL#p`#Jefo*E8(#T*^~A!}*Tlx}8&pxZ@w=lA&aE51?1nR+`P77uPrvN6 z+SwaUS@Y;KXI0+$gWT62c=^)0yK?To;H3bMeX#s@Cl4*J@H6X`%wMvoc~n#VqwP6a zS|nt9C5;VrZKH~dKbw`+;d5?WvT)R*dVAX2aYohC65DQUkQADjmz{NOATY#H^~&pr zYB2`z%g!odjOz~FMT~00u0CSXV$mwu?5xkwfoq}ez5C7E#ZC94_MM%jnp3Rxvo_q| zWT(bO*Tc_#{txD-E5{QrH7?b5c9s;sVtsw$W1sFTN1?N`h7plM>l)NY4&5F<(oM?Y z*5c29v9BCd1%A#;k&_!rRDRr5WD;n}{(TOVWV#8MV+Nd=?w0=nXMxWdWSrVSbHmLI z{j~Q9wZ`XUhkpJQj=q8}j!MS!zRRx}GRb)Y&Tca9IJHt6)7s)COu>?VekMPt(ZJ85 z22K5RqD0cquko`fjnf0Ch|ZYw^9CGu1v%9kKAm%BAI`WwoU$~|h{_pbRQH9JQ^f~o z^dvZ^q;V#~(WyArGUaC+Gh^>Q%exiCfNhaj_h(oH6l2{1oFcOyNW=r6#6vB>7*`IFfuz8b|qR zPU9%=3qsB)bX42Ch49?uJ3FhyXf(w&$Nt!nwfI4e*+gABB-;x(Mck!x3i@zh_cGlPY7B{u=gr&}5MD?^u6DLekvYC4*cAs;h=EfxP`I&{HyV%v`v&@fYp=w+x%})*$YJ(rj{Fs~{CPn+Qf0D-W zHGhpfA7_$PF6q~(`3tUZZ`}Qn&cJhWQH`=3n1f z*R-&`r9p0XC~5!8M_lW4CL@QS);6{;o-gmgX^M*$Em<6{d2mQs{?tyndQ2^+6xWuv za;SRS^x9fQ=Q%dfU0+RNJeY0{Q{A+vnU6-N@vhMA*c3nJDy5w2TlaxabCa)<+F3Px zgig7{zBd2*E9+WXOD4juZEcv}&KzlJtrbD-{3T1SZ)zwRN8-Z}(bi`Fwu0H>6i#LI zZ>txyw{ha6yfQ%C>-%v&iMJnl z>gJE)@6q9hm#6jFUf<8*rnDk zu4l3uO1=7%r}Wk0?-%v& z)m}kR){nf_dRG2JPz(wuXBKYmcxPE+)! z_#60b%kZb6k*;%r|Ml|9iYXTj=U-W@rhIrhm(MxaHvxwiDgA%u_fvk=o=n3>Wo=bg z-#mZOs3r40K?k~cXjYLH0w-X3f3#g+GIkhin%}adbxC7e(b==kDUv~NQPVA2FP5Gw6B{Re%& zjl2!xr|S}aC$TCC^1p9@4B+WTOodUu6z(6PP`a{|Jj?^FrR7y+F|*7_aBxYWe{~#R zaI8%+0|s^h%{asBDBhlg6$jPjWfOn%jWgTZrnEOUQiS4b{8tj^&r9-8gkKQ)uUPDR z7rQX@9ju=9p$>SPXnxnRt#Y`C#uAx84Nq4!~tkz;w2 zlGCtweuE|H8Q4t?G`Y5h=8DDj4L4J>lC{IVdD#p34nHkVq<_`QAzKGQ-1V|A_9!`6oy-E{--up@^c z|8C!RlQ)1ioa*suG>RS>;!;BH@;ycu&*!Lpzj)FDl;HDbS~J&B0<7}`kccbm7MgfP z5g5#OI??7`?OfMHe%pNhgPzx+KJYzI>iYYjRuBIHUJ7moHI_aJUIRV_UI#u6t^>D% z%I8nO7eH2}9lryA4*oCrJUD>3c7P{=zW_f1{uiio-+u{?0e68ahTniy;47fs89`RZ zV(|B1GsxV!<7Ti2Tn@eteh&N-xB>h#_yG79a1*#6{2BOH@CEQKa2I$G>;c~fdqEU? z$3MUJop-4 z3i;{k;+LueKaafe89Gp5RR6*^LSb3u7(p|&phO4P|B)6vyh8my(vgZ*YNu~xmRnbTzebv>UG*Y0ro6?j^91o8;PfDS5 zO2b;h~P&(;4@J?_6_yrKR zj<12N@H>70E&`tf(Q6&gfvuo)QX8l;yb0_9(Q_UD3-TR|j^Xs(PVgdd1$Z&|X)q41 z2CoL!f{oy3!A#vSj{ND;975MG_^F81kjp32{ti%ch|hqUBisq94Cr%x%5@!lT?G#Ml&j_rV=~HBVU(@}za7bP)tFS@ z;On5nx4D0=IHkChP8DaUxKd}#{gm-q{03K$S4+3oHb`1ZrZ< zZh*DXFM}%EuYi-m4PY5~4>%M2Iyf7=7n~1%6TBY$H&D9weo*E0@1XkgTz(&7HL|Dy z!mgmt*3`{g*kEpee+9X9ZYS{VAWfKSYz5>$6rhg~sk8c@M%oXlzJ_|@TQ-b$$P#_RGa zPK<}r=$Pl-&w>rfXO@85ii^Twg174y7@e2VkNp++0;$3Df`-85sDJ~e2UzHfxQ z`$OJ;g}h&dJe^zR!shxE&jSo}`}%{u;z5qe^Tzp9#9IU<8&aNkgHMqHDD{mzufwMz zUIOZ3<9)`bBHovvE-~I$d@ADI5A{*wecPuZ-osGRUz|MdQxR_~REhC^>Qj6}0BVx) ze&thqLjX!TFwg7psfazHaE9@Yr;0`KwFsZe^DYc|3qxLW$kYCo3%fDo$=-7=QU-gK zKE+ocd@AB?3VB;XUJ)v0q=i`MQ+ZyqPvMEdO|E%fj!#9ro1xCL5LY;?=WB zAlE!^flo!eoa5-!#>@4oh*tzvZoCmbI?p(GuCwx0YZ$qu+ zRj3npm_J_L8v6q8R2}PXH}krpGKGhM&pfKYdXqNfY>nOx%ib@z+ukp@I}yEma&*|T z+1;_nNViL;9d5yaaXeWRB&|p5#6;}w#zg!vVvFtIbe_jT*ZhY#a)JOHT^$B^lg`z9 zSMVy)gMH-ZulOlGwniB=kQ{xGC!fFgw`H6+@?icG(Z>=ofM`bYKG_3HNy-C%+X*pP^CNW@Ng@vTYm2bPUNUj7r6Q5}TAn=ubICh*$G?)5vv!H`W!=!57OYrAkCG2h21YtYhoOA1d-Wfqm93>Tm4p|50+;;3EbCiDK=&B?+ ze!Tu6CSCCj3znzE)cZvap?H}#@GvoYFLG|dy`9VMEz(&nYl`6LF#LPFV!X<|rYnB0 z{3fCsUgRy9`}}jBwnnA-yk3&Bju)n5>k{#GljHZ^&f)(Xv!fd(M<2NT_(W`Dc5Fje zY-1vRS6+NwSDZ@N@H|2`^gf%2-IpEP$Xgh9@!Xgd(T?EE2aaJ<*~E8n?!{dhH9Mep zcuJ6Gf*`z0U_qYgIaM!Uq%@bl&v)H`ca{DQ2r|V_4nv>|A*9_-NJ7+kNx+s-EmWTcXYR@-Em`| z?zpi#{u~{~b-M28bCkNHIqph1)H@{i+50N@CF1vSN)O#Mx*_z{U$4^;nTX!kn22ql zK}I)m$k&FjPjd7I`ei6@h=nSuXAS}AruH^PSNwtQ=u7GH^H-c}A|D9*=L6`hmzKZP zK?2)n&@t7~HoA`XfI8Yn*U=tON23iskpIK-_@;~om98pwAgbp_{G;i;bjflFzBmy> za7}Du=aalTf~=b8#*pJeXiD;WZ&IWvhmBp)yHFTmUtC9rdM*)N_u>Jb zbX~`pF!7h@1(yCzL6a^Zta`yFIsA|U3`@!>#R0viDv=1dD+od_upk?Io_G(vpgE-% zG_D;?UUeO+AIOSA@!KUsNkGf=67&g~X98L_jb#5wwQC%N>{APAGFOc~`3*bcyHXq1I30vfc9TNA2I5G_Ay3QBbB%Wjl#A^wD9wcjc_X3DH&=bL zYm`ytP?|jt@~WW58Z{S6GxR~;0w~SP2YGE!nvD;#<)G%^gS=Paxia`mNDayfay}D^ z1p?{&SV%30a=Baw< z1!XWC%7xHjmlG|-Xed_(ABA#dPzj~^@gQ#wlxFRNym~0j)dzXaP@16+viZB_<%7Ic z@H87AE;jnf75WBHlvfUEp$EG-dPjF%Q*w0p z*6*%)GS?&f-e38R;1^t?#Yd1`zu>=gi+EZwf0bWJhIL$FlU0JCM?Wdl|Q9@aHmsS@P2_54jb*&&9&Z09$Bp3gM1*k9nN9)e5h z)1??ykGg1O9ZEC)I*tdanU0e|>cyVWc6pKx66K!I78UV!hrHK(%4YGdv=1gqaz=9U z4(021RWr-?B*NtQKfo+KspTt6Nm)kuDvbQd>hk=d%D1v%@pWwr`0(v~Hf4F_M5Z4_ z)c5MQh!3?Z5Ln5IQ{*T;y6BE!+i9ZQl*UhhO6T={IjU#4C*4K4aumgvx%lsR8nqoS zY_*)ua4=DoGkIuB&X`TT96xZ7H%QRxtFu-Okkb`8EIM>@Tvg74S%)rd^{B&@_8quq zzOT53gMT4!@wz^bSiqGL+LLE)kl;KR|}$CEr@cp;CQM9$4jq;f{_&VTLW5E5hb?V zuwy<9p@C+adc22 zD_`{?I}YVw*JX$8HX57`R~MhbJyS_3%wT?Mem_4{UCicLzJ`<*|2``t=r={gks>8j z`l;PU>Cu(iZKhGSN@E3B2vYvmZ7M-cPhz0bKLb=9oW;-8fhbo8qFfy~p6bBy((53t z+hB;uJ@XxWx(o(U=1*)oAP~GO^pt{X`a57jAs@u>lt=lw$s7MpBjF3H(mv zr;_*}zf<^~#&0-3RiH*s%{SGEFXX2&gRwvj-AY>X7}YwXvUelDf8nQ2{AGUM=BFj| z^Zb6#?`?iOZ((2X)vN04yP9oW*6!E&6_KGU`Q6EH2S2R=7V>+FpI$7#gWmuOtCL>= znf(?&ef3t>-rfA3BD0T^+3jRjM_g5s(MR(^GCG)yzD~~^L`G}K=q{@K8%!%7I-UHJ z(Vv{{c`u)b!XM2$bqsKi&=kI3in5)~p#n2`vurl|-5*B*HL>s9hWy*fjDKAKs_flW z3>^C1s)M-xfAMbBv&AQ8kGt{Ag`YgIYRn@yT=eY=pE&u9vQ=OB{kOWdSJdpDS9a2v z)t|cd%Qvt1&p*EO(hsIz@#8(YEnj$abM(!PrI81}@gLKFJ@c4jw(TA9)_Ws+ao|*e!FMr`vTMO>_!K43r$(<8RW=}ZjSErtQ?vw#{-S);c zS6+J0hDWdXe#zV458k~B@T_0G{khYRdGbqsp`^TnHSmbu!BXj_U#U+7(`b0|UC$z` zeI~Eer;F9gva|FYvK0CEzy7PcoWE2*>QUKQBbEFV5R0unjkx?&QH(g z58d#3Updkg*;z#?>4{j%QsqdKWM>5f;Wx_fdZn)%X`1x%8PZ3NG*L1=7Yy8aZeKZ6 zW=49B3rkA%vi^z##+!)}W& z`3;|QT*x^&%drN9oN_q(P!5V+Est>rPBE39%4y6{#GPJl*mh z#HA6WDvcw_+QB2BOW_zv{(Txpl6R(Yl#A!mILhgd(m3Pcd_Rq&b<4dWC-r@%0$j4Q zUh~WEw|~2BGYtRwwa+y_#(M)!2bANaKC#X~gB-O=KM<5_g^a{LVSduy7CQbgp^E%a z<|oiUH3YDcJ3FgcWZISbCQuFVY zUUIc}X~xrusqS*Vv^doyQ&Mt8X|#mk6>>{o-j?+7SUaN>-+0WJ(D&!l{G~6#`tw#= zIyDrSoObr-)BI(aJNo)lQAl9sb66^dsnac&{XT+Z#gtNl!Lu|0UqyR}_m$q?OG#-@ znv|4`tty>f>Rp=lj7h+Cf`iwa!lrzPH<2Q|Z8T|2QSy4Xw~fXXPaHSNyz6bFk-1lPwB~SI1@%D|h+K)5*X&FOPx?pN) zMPwD9J} z#WyaxZb7`Q<+|3!rSS#VEo@r6q-AM*Y0IMIO?}Iv^0N3%H!f{#Yg`a-Z&`BVg6o=Y zyk+ssg-dTJ88>B2aq+~d<&!3sjV>=Am;MUTdwsF!3l!B=yjb+o|2AKJG!_<9c{AwB zhL)zrrAPdFQJ*b<&yZH;-8OIn-Xz-7iAF*_BnT zbfSR;_IhV)`yzM5ks=5#3HC4F`Y+dP*b8FKHz3y;`mbXoZ@opLX4LV(Uho{^aQrpb z-&EEzf9x1us!blY(;O=w&uZE2C7?RI`kP#l`NzBHiBX*clj<~eVcm7DEWIZU)lym4 z$5@6Y4YM~pru|o*b!nO{6``v!+v`v{u%*?Z?)wQ)@~;O+f-ICfMuUq$P0W{oSAjQz z_2A8*;#dma3f>B;OqYRw1xN4;uCshX@!Lf`p>4x@S`VH1B7?%nk4z~~Wz>@^9F?za z9^j+D>wVOa&eWmK%t}#zlPlU3%V}|n_#iJzTad@)>Uc2H^Cj?zkz=P z?*snAWCf={()5W^@JjjqWx> zCvNb$0_8)Odcr!RJnv1)NQrnGR6qU)c)HwjoYkF`n6-t0;H9t!gH>QIs5R6Oa2|LZ z*b3%@H-RUBo!|$+e+7qu_kkY-9|unXRh}OPGwZ0Dx~t+Bl;2Y7=&Y1F+CsQYy`eDD zQ^FqyMdi6M&ULZWT9WkO3S!}YruqP?MIDf5Z27gQ{6Tw)zc5%hDJig)VO zFVW-t?$k|rH&<7fMwLFyP@U4K`@)HZRI0sxE4CibI)k{PH@CIaX$z~>X;GEO&XhDL z54wi&+h!E?Gr%1##|w}hGWNd=UIM-fvMTa^3tj{M9@HG-58$2P9`GKp7gW8x4*nec z6Zi}8&!Fms7b)#!)HlGlxqlNpk#xKTo(;YYs#X63tO2vAFFhbX0Q?r118xEbf?L32 zK-ED6%&gaM!mlTepl7V$z9^;t?ZYi|?xHY7@P*5h^;)e8RUwzPa9o&EkrEwTK@{8{ zN$2a+HPc##wu$c!t32A$QpQU-Hu=;W(3dw*5Bsk&F+yk6ll#yN#ix`iG6 z)ZtW4{A*ocy;7osEA0M9xenjgIRt4HE>$oLUHiafGTN||j>@~H+z%(ot-&~3yRc!g zTc_aCh6`saE~ss)zuBrkMRP0kT>Pk^%xKy666I_Z#LKp&H>feuL3^@@(^Ih!{9Zb z9z?7Ke+qsa%xrHTgRgU~gT_D~NNaCpxL=s@lAOXQzrr6T+grW8Bv(6+!-6J^t5yAJ zsxRTe6-2`QQPdj2Q&w&YetE-E9aqG8P{F|Ry~|x|(k%WpK8vT;H%0+oRIV#w8?$&U2HC@DGk>(Ev8B24c(jJ5?!ow6?w~8?WluaaH;HcX{$($ zSXVnACpAYLQbM8UEJEFp~DOchkh7^ zM+6HrdMoB*QO7A(2$kdz*g8zM^%fIq!u0OBrUuS?$ggolY-Ox81((vPYY;ys7j}J? zGEmwX!#gyeSr3i?KMzg;u_<*(24hB_vYJELoRZR4ehi&Dzf~P)zNo7(ngqcIXPCTLRR^eWZK7nR97S0tv(;!lfu;r2;VMel2AXMv+FdclRmr|u8E%K z20=eS>fsH;XpoCsA;>ydPl(~%*56dKL>o{xUtbuCVUTs&P|}-WpMhVSlh10<(R3Wb zWP|sD)DTWf4nkvJJ9NB7HP9;pQ|ww3{Wc|6)t#;p{Lb_F|4I8$y)v$L6oXHKW#Cg_ zCAbCDe10of3;qODuC{|(_dX9U2VVfumwJS_gSKgh#XJuFH}@K=cY^q_!(-st;W4s} z{09E9q~&F>5d1BuvHJJmt>7O(4o9#MkdcV=! zV{AshQ5co4@IRCNrnJ7khBFOomQ*jO8*M#Cf`f}T8(c@Cztq^3*3B2t2U>~9Z@@Z( zNW+91ij@u<$YpmcBI@RO#*#kMusj@}oE~N4y(I33r@_7TmUuHqewFEr!=yf&6C@l| zo^>e=YD>BXQLZYF!Qgq|G2jG{HqcQ5>JXkAzyh!pJOS(mX&Zg&<8vx9euaRpgCssx zk7ePOIR-0?;uk)atdDS9@%30(Es`HxN2yx+EZz=3@jvXKld9&dhTEvkV$&@u6;)@* z9&PMlnd~vxC!A80noBm5+BOC;8^H>g@;`c_YCN1e7(W>8QWdEZR768cmt{J0SlGS} zsWUf|xMo+}(wQC+59c=2nNp59FwcOQp&WI>&0+K)?J2yh-EemrKdlpVokIIkyC?#s z2SEVxjs~ZJ$nvlgcU%tg>(Jac1~!A(jXUlDXM*>DRp9qP?8s*4 zz_!-$-`ryx>G%UU8~k68IY!3;@G3A$queShjMSGt;6?$4A-GNkVICR;5IWeeIDU+<=MA)lSS(w3IGrK63n_kEof z4ftb>zcY-~WQ2*?5%TeGTs89DA=jFD#bOt+Ci1&NC*!$8|57I&-z3Ms=Eqfl|84jW z6GX8j54_ue55`+vI$la|B&%55fp9yr0coEBL3_C2f7XKCk=go#-%H? z1h_rg1wLC&YAd?V!v>Md7&%l1Z3qkeAC14XsU$Fjn1K7!Z z8^{{PYX|QFZv?*vE(MtzdmO;gu?hSnxD8~E(eWa9JE%fi4ysH#LFNG7r$F_~E>O0E z1Q-R^fb>y2z)AfQ`#}e3(-9sW#O!%5KFL?_3Tyu8% zI9Y*v=6qjaqz{EZ%Iw$aRv|4_B|f;MF8u3AW-mu`n3PGQjpiK~$TYZU?%hT@Lo=AB zMVh6H$zh`U=!&$(23Y9^FZIHQ;dTy3-!|Nsw2!6CyVnLq0ICdiwDB(>fwVY5pGJxd{$vj;wO9}vt4lR(2~X1h2=4u?}=bm zvgvKA?oVkT?_c+)4Fw;jCe*5>-}w1t-qYg+@0r`bW3Ia7ai^&HMwTkmX^((D@M z+!VN~ecr;R`AVu9iZpf5P}C-*KvUX8a<01o0l}s6&=uh~*C^ILl)1|4m*9uNUEnzI zH{eY0W$;Syx8SYdYoK%(rU-&7rPBU??A2+t{VoO=*{#>IIB6%zu9|C?xVeCivE9YA@$KU=2D1)w z^Uqp0S5~mQ3AT(XYEEk;3bv{LV550xC2y!ccifN6F`TB15fn$s?5ABy{jBqsR`oae zPXHy`RWWrJT&gQwXYgZAYS-(u2h}6tJ4|r^ zsI@rbN5>v;5U9E5VDJnu7d#JSUEOgZ$hRErd4yxZ#oQkUeiqCJ8PB`|ka5d90o($z zgtbEvPXzzL{YfCQJ;osSbW7;Fbm1($)RgLi|&!HwV<;D3Xd z#5;C_XM*e_daUz1{s-h^Bz^kFQ?%DD^zcIRscZT`y_TMw%Qh0OI77E7%t-tSH)r+_ zS!S(MNNR8ey^s6MtPXj**a%q0$F9z=dmw+muHjp`~cN56mL&sis zF#dVBfPVr%2}(EI3d*+90it)j<={wg1vnO536d9Y6<7;)f%V`TP&(rd@ay1b!0&_W z!6(4Gz~{h!1*J2-0`e?^w*lmt0`DF$8=d+!@Obdwz*E702iYI=u>Ey3f!_gn-qCvy zAxxJeTGD2;2#7244f81b+`c4f0Hh_Y?5%;7>sv z9I_4MnIi9J;OQV~@AwF~9mIyIbqrc(@X%A~m04aTUnbG7>hiMc+R?RFj;WT z;rMjdb+rrUt2g-Hdps3K4MOfJZJpoLRI|kFcJAEBGdXWkio#v3w@g{sbjvMuE%ln= zSG6?Vh`n3Wq7jGl7EYedI)pDbElf_bGNsL~Ynk6t*Vs0e4U(j`PD&+Cj@@cv@dH~HRo$oKj+zxfOP>9axq>3~He z#*8f*QBzzrdQ8#zMb{QxQgkGu{4+(1#~lS(E?MJ?i+x$7)QKN|6vazJYh5Pep8@akKHx zf+vcjb)jxD-i1CD@yelYG~RTdirCJBmhpMs9C)H4-d-q|=6yZ|Zy-A+xDNIv4sukU zcd<`JyzhiOz0^C^r09iTQF-2zA@AoQ?}d=JC*;f0#10T%X1vMpL`A%*P_p*qd6)TA#9IX=$$8!ypNe=BkHJz7Z?Lz*r}Dg2J{9qb zsR+4p0JBd;yn;MCqJ$80eJaoUxKBmAZ$K@#5cm63#M=nQfQ# z1*qGN_g_90@y20Ut2N$4pNe=ppgs<7uvc`fqiBCV74e#&R$7QfKE+|iP@gj1tv(g; zJ`MG0<0X75;(Z=!mGQphQ{)J$%Xs(u6gh%gVZ4WZiX1_88gHvlMZAw47o@M&ry^ck z$h$e@m1DG>N7%vMTA#}E*7;P#d+GnN_a*RgmF3+nA~q zix%yb@BcjSd(NDh35!?mcfarVeW#uL|K~aHzMuD;^E_a;a>&1u%%J=hY?@`im&~BN z2Nq!2e@bRh;;`(#g=Gnn8I@N0kpJWE*5wI;RdrUHe@(kFWEc?D>2IU7}cd+a= z$qb6~Oc7hWGA5Zp`8Q4WmL@x)$xdpre60F=5FUD&Wawp*8I&J_-OaK6STck1bFeS7 z?3a=mlsT|3vFvw}85GA-5pujTAelkg1Lok^lFtz=URf%cL1_p3Du>c7nL!x^yO(7i z$qcY?B9!ICE1M)UC|?Aly}o$mPRR_)*TBBQvIiwID362P!?GtOGbj(AtET1Kl0jLz zCY#e_xYgv;W8|02pe$WR4-BdNIwgbRamftIgJ2JEY!6FjP@V+a%Ce^(66=*WECbMcXyC!SVWL=u9SCe@)*(ObP>;hIM zh+M8t5iDLQl+2*`!5-q2PD_Sf0rm}+-7A?v`6k%IEPGTkgYq=kH(BMu8I%oR+gP?yGJ|p}*pn=~O)`V>Rj}`}?0(4%%D2HDXW0{y8I+x1kFji*WCrE2 zi`DdPlMJh%OT=4yFmZ6HV3=Vg!wdoT6o)b)nL+V^J;?@MM-&bwTgri@oEkj$VIf$e2?rIKO%1ACoi zWGt4LLAed=M=ZNbGV}njAG7RP$qdQ?uzf5$C>hcM_6Ez|m&~ACK}V6f%vzOFQ)g{7 zHJDQ>%q=XnS*=CYwbmk&sl3QkUf$a|UZ3u!%UngJ{X^E~rl!8y@~+JO z?#^y=e^yy~UvBPrc16EqO-5sGMx8r*ePx@ivAAWV#50svS~*_V*KaGS?;5Gj7|kr{ zC^n6oO{Us%QUPvOS_W%I-J_25_F8MEy}8tBbPhG+WoCER8cU@!y*M+?n&}mX%QD!q0 zk7wkkI~yCj?al^=s~{t1xU-_jl3^NfW{uez8`rNf^_oqdB1=tuZGX>rM|*B%wymkH zx587se$<#hSU*`cTGLgPKU_bVkw2QBonLIVblHZ|vRr9h)q|cqmnXyCQag}4Y00a0 zb{2JJjAq#zI?-7?Sv_GX8)&!Xwbf^pRQF_cjOMgW4p(J%jJX^0 z92s@l?)>V(#&K&;X~M@mO*6`c(Oqk}c2 znYCAOWtpo=A}SD79a6vcqDpIVuzE|!$4hEk$}5J~SRG>>Ri;{VQBkd_q<-8qUjN@- z&OjYY^)smWAbY^u#S(e>h<3UIT@Rl6o_ zeQ!giBj1r$p5AM#9qH+GTQV$dxqHqh&Y?HasWYrKM?BPf50=q;#O5y16Q&zI4(vQr}~n$S{|!8R%&*H4P6A zwT~9qYRe~WqqT0Eqt4V<+S8NWFw|L}*HYDqsubfTVHEk z(_K(wYRN70jAxcKglqaAhiJ++mM!#Vx6c!FP=WVGaMzhk1orz+sZ#~KoR#5d=d#=ZQO^R|M3=^fWQS(o#p2w?Qwnk%R zTaT%!#_TrN+H%_qa!W0x{r1VS_V&rnw#@XB?v8@a$$`uab3yG`b6U%I-e^Ug%~Vmd z-jvxeP+MEMredslWT>LKG`+=Iku%Yj;~DQMC^lP)&8C*&fy%P%i6LXDz1nOvryFZL zo=LaWIAXLGcjY?!jmDbZ?ltQhocTj-nd8><g&7N{oeU_=+=9s8z>NGnV$MU+Wb22(6%lhgnCktx( zhI`gjm#k@MF?QFR`&~UnqqP%N#ltO) zWVG1(T87$l+bjA8dOMqkE#_uxW)O+URg9zF`3r4#@I92(J)w^SKrpqS!6QXFxWNbSZl1!X7})D z%TRA;W=C#T!(ew=iM=3mxFf5^kx|oRUz1tWG*RSeFy>lXCh9udojsQEf^=(U!AMn2 zZ+fmVZz64AeNA|HQDV$*<=0XRXs!XJ;QyD?ELiR+Ulb8 z4%5I;p2?Ll)K!z4Q8n1uJ2+ffmt8d8o3-A(zPrb{rp-Pw*;Q3+cUHHQ4_b@`E!MvF zqRILOcXPG9w{y70(pT!Vxr&=coVgRO{E2pRL%S=_R$f|}+cwr=?`~+w%^U5ut|_Q< zc`CYxn#&uk&PHSZcu9Rz6SlJTmiGSq5$iy~aBo}A$e1l}xO+|8V7;Zo zF)=VQnLE*zT~?kqQBh^gXeq85>mO*S%qYq83=d?D_m6j2I`YPxrTMkvp7P%H9#c+x zeNXntu(`}_$;~WUQ{B>=X0J?NZ_LVQsYvTDC~mKvv>BU?Bjv;8!!7GG8YsDzv(E}V7nl~PCs z;Ik1wCwMpZr&r?I2!CJj|605blywu=<8kjMk<-7!%tt{&~>%y3jf&F|JWxR7-lHKHQ+Rps!P_ zZo*%aQUTXD;9m;-eKO%vKdDoyx#krGHVAx2;~HnpC&*aVtofvX6VwQN8TO=5)efbF<% zazODc&YGFKjxQwm?Z*P0KwypTeQ}cBklSK0!&u z_Wg$()GX;Bn;B@W+)Q;XE(SI1+i+6xpt1Eeg|)P~n-H*XLqe4M%muE__mho{+bdB) zzPC?dC#Qr3FmFM2eLG6vMDbjyIp6r&A}`g!N&ju+8}iwW>;?~KsZrgSO<~T!^yf+c zM&jJyV|3Y$qyD$?XbrA4P46OATss>OhcpWL0H~7nifqDDbUC6G!>2O$GX4a%@bw!x zABPrEN0klUQ3yw{`?`hn$EeLHVS0*AYXZ~cO>GKs!qnj69Te>Ruy4b0#S?=D(FGRe zJ|BM+m&$kooL;pb#KDXwU61;}>x;5xB29Oqb*PhtTeLc%$kow3}e5PNfbz&?8b?k7ITKA{S{xxhNR~@7v z=W*$`XgYEJ+la#w^N004-|o&}$9uW^HX7yWps#Ub1XW0DnMLw2&1KM57OXKI?~WnP zMhtjK=(sy?fUk%FZ+41wV-?~Omx}D5G5#s?LJe~>k8>Dr&UQc*)dD3AM;pb6jWUL- zq6J-j_}Hk9pjf4d=5N?R3z@k^NI#E=^86j7b9#!jZq-ar(`ba6(W()xe1;bs@TAPm zlGEv>?1tAvY6T(&owKcQ#BDEo*-wOlV$3y1C`2~mT>-FO`RkE(x zV17r@@u45DDdlP#qC{Av8!F5s$tllxAj}7;slvA{;_I+5)o0qK1*=gLGXb}^RJ2%X zZ=?omryt=g(B4RUmI8MUibgG(X!MXN(uft{ziOex1dc^NMdA?0X~+CekunZBz@d)l zEb;k-B;R{ixM}2U4{RY(+7|Nb-$Kcmo}!3R^sJ97z_Pl~*pjAZ*mo)h#oE9Ya$h$+ zMefz~BuEz+DI@!FNTpCo=qe@Hmnk^PJ{=T;S|?%3#MD!&2JX}--`a(jV`vMB&n%gG z(+y*cWKi^$C7YALupaXBx$nhAus1q?0K+~$yzuSTt&4OcJl7xTjY9QNx^~`-1V&U} zV$)1_;u&VF)e%!%pf(A!u|LUgiE&V#rniuOr@CqLv4v(;cdJ@qiO+93lU({vSUlw{ z#C(?c{9UKA@UJ#c4$pjV97=rt)>ByaUY6%VdKVO??xTakCJ)WREuo#h2f6Y?AWf{-8DWRPX3+C5rrg?bame{8ik7%AEk8S(&hYAU7p)+(ON*XMHZw@VB zIjWr%*h1IUAsAhB?#twPiack%8g1TuhV54W6n&cJw|P;g{w?dk15^ChcIzrj!g#gw zw1AMBH?Jy+8@~qG@K3KLXIuDhQNk*-cYK9&NkB+z<5q2<5M5_dYqh{6_2%elN``-$ zN{3@DoMtRx0_*4!fciu6eWH zcI(`)(OT)QQrC3iq+jj;7#$WG+Vq`*+OV!updIpYH{xF>`DSpnf9Un$VCPP1UE=%8 zjYpH=8~uR?^C@_a=nvF;%_nAgfTzH5$D8;xjdfYL=}mk(PK@)nY@}jnPB$>25J5F6Z0>Nc>+@aYi-i696o#)pj7H|+^yXYQ8>ZAAJhOveV+R}T}1v! zbe!izR^JX=pm}!#GvNx-~u{+P5$UmQ7b5SUEBflQXb`Gv}k}Kng6KHLk&XL zl(1G)=l^5KeH_JxgZj@pW{N`PrgF*y-9FNx*FP21Qx&1IO5gp|sfZEn(|2?=7Hb=J z?@UB^vT4$i-;xwfH?zrS*ppB%=sGMk25JZV_5-tKdKV3=@?^1p_amgox8VTY(m@T) zg7*i>*w)K>^DmwQyd*goupNByEo^M=57-Z=b&74JqrMGC6^~&D6~f#Ef(n@TtM!M= z*tgrSRyIx#`!*a=+_An5hmj1ViG2As>{Ak_=%vzt{fOU=P1Zf&$~<;f_i)sE0=7M? zYzGs4H?o@ptL(|HxPbY9-@JQ17VW`r+a0j)_VbP&Rxn4=KEz#Q_}%%Z5F_27%&!iZ z_rm2N^o*lwUa$jkh?@5CGi=xu#U3GcaFf&Qhy3&c>gVOJ4D z@^OR|xfgMIAoPyFZ{EiqFHk*VPg5-?TAxyBP}-soDa{L{5rou(+YeQiAY5Xu?jA5G6YF9VMl{~QqNRyi~k&hp$x zat!{ynH5^n#0`>x_de%-hU?Szt?2IwRBCD-aSuqlCk9?W&e2pg&Fh*Pxubf7!qwen zQfHc@4dy;!K>Ni*(O6bYH$<&Kee6)9PQaa=ZHF2M1`}E&;nsjwFSs=f$hkSHFNu-_ z$3d^D)6?Ww^&2BsPws@-DJm5V2g zDsTnO*G*#xm_`?JV3|ql(po`+H}y-YMGMClQ!KIq(Q^0V8Of}9H|1p>ZGJc1^ajkk zBg-zd@luJ?aX?oldlxQ~VCKPiJ|BT^v}aPRvh!X9649Qgryjx>T_bPsr?-%zmGCy2 z9MVQ_N06Lp&g6@SXh%-8zo`=xl+17fyTRQnWLh!LPEksZA|Zh-#OfUMtYUhKG`MIU z)tjy#Y&w(V@qNkDQ^`qooOuEiA)n#$U8lEj+He!DFN%d@vxwNHsRC*j z43%PAD9>>Zpwtvp8fSQV3q_`t$HI~Q0v`VR3o=d=3L?pk=C z-a?tC9Z&s?%0pG+rfurmgog!s2T(-*eG;vG_sI=)V1K_w53C7~v#ZEn! zhAoe-IvpQ{coGBCRIa{PKZLTF#@GGK=S);AB2T3vPk1I9s7=8G4}2x;&J;4=#A?NT$xfQI`rkmQaba3k z`&Q#~nnckSe6PibhTz-9O)hcDfVQD}H)4f5N6m;D+9I?9t^nWqRK=Yxs@b$4R%#($BjY~PF6V4-d@kEC(idufG#3kd>K z^w)2`ZF-t^SZa0q4p>j$rgn!IUb4BbR5Mm6GS-Lf$=gr^>{XrL&`wWRJA)S)6iyMd zOmv}0Gz79{7m1q1o)D5EYB1+x8bh*Iz`;a4lp#5zrMTe=5S6Cfgr9Qi`F zb!i0A4Sl-3_PbFI>yU0bC}Zl{i<+6LM3z#juDz)Bs=RYNs5wcfZ<5-d=vAlSrb#t| z9>g!1|K@?k;-wd8uwvPi#vTF_?r0biSAP%If?u+-3ayEJ#gf`vyy`+SDAtq=>e3`j zN1vyMD6z^_U~AZ2KbY|Gc`y+&ln~*?8*)ecqxA85ta2CFI5Vgq;?Lb<6;fh0$+E3r z>zUCf`k!S66+tq6q^L;b?U!I8j(0WLNlmsC1DS9K6FSn}n8xk{JHR26(m0XxUx8f> zSuz>8f^u?Vq$==QW(8muvyZF6@Z}rwQ4E&NSKGh_m~8~>V|EAF4eajAU_&f>2yB?y zlVBqCGhiFo-CnTIF^k2VDN=A2SQq<90b9yfF9Q=Lz7=d0UtJ!nvd6$g$o~o^a(U)r zm>6Qe=YruYRiyp`Fp>IIVCS){5NsJUvv&1*u=82g0fz59;n$&Ey%p>NmTduB3zn=r z0VY!a64-StdjsrxW~ar859DK&Gr&Z-q=1QX`3#syeLk2MK4O&;u#L=Wz;0yr1u&7f z2fS>=+Q-2|tsQtBI-Efzz zYykTq`|yFav+SE-BEJX0YFYL>ur_8V!D^VDi?6*`GrJrt7c5rE0u%W)f%#Zg3MR^> z0Zf!jo91o=Y!kb?0c?udX0V%>-34|tv#ns8nLP&PXZCk6QEI2h3+2_Z%GqE!xSFh_ zYwQ}ZCG4X_lideqXLm1v)iWa%2e+`hUx0};&w+_F{~1i=EhYhT61z(RyOr58FuJ#n zRcgRG!IG6PfC(SFz(h*_3?|z67f%(6q>`0;!M?zL9{>~aJ^?1;{XUooWe?aF+1-Ay z+n5~!yPetjr>Sw|f)zlPtTcmFGCKw);*Cutqk?p`CP}U7J}?{0?gXo1_8^#W_aqp7 zdLOGi4K~DAUj`HD+XptnvV&lEvb!T-cQHE-wuRXhr~*+2*Mse0*_Xh|!IG7)gVBfd zvC1Q0B95oPL>w=Hi8%IweVN@I1iPErsi&(UUjim_UIAw1koSU#oWBhwauj=p8gDjO zCc7&Et6_cAL4yN?;ETlgBYBVY&;Dfk^2{)4>($OcPR zmY%7WP@cw0H8uk#%IYv!GyAywELCc3yA=W0~0lq0oDLnvSI-fsTu-%gx$HoM5;&$gh#tP8a6Od8cwh*zWRW6b*FaqC9u~yl%In2v%AFe z)KD%36QLNve#Gudz=XREn!7EUyZgX?%L>~!R~I++j~uqT-< z1N$yBKbQ+FS$Pmll=H8^L`i-I3yWEHw+d_xyBh`TW%gaLYnc58tdQBeU}B_>#sb8` zvPv)$v+KZe!D5w8Fp>JNY3_aiCPweKQ`FJ>_h60e_nZsW9=Z;!h-F^^6D9dL*!Lid zRlW-*%4!Bol-28CBDRBI+u7X_u&0>VUNv&eTM-9xXJiZ?hQ^S!jlZ;zYbOD{d*{k#|i^)7y?_^F2( zgyi(&BPw|QM+ok~@0u{%kE$ONuFYP|zVIhXwZ%p%G|6<@>hTUoo3qt@HCB+PCutF= z?gc`LIVs(Z!`T7`*-qllD9rF0b|qlij_t0k(*;FoO2O|__|XtR2iZTMXnTQJ=a3ys zZ!&NY_!%JdGJC19;X#ylHE;xYHP8v9yt#l0z)t)Y^H5GKo)@*mpjkv-jpyboWTL9* zeHZM@zVEl6oIf2k#SfJ55b>mME()*LpmJ8(Pr6p2X6Ugrs_*GVSueuR<|uIjmw0lW zwGR&PdJdmZeLo$S^%@*(Hq1ZzK{YynG{xXYMaoB5jd~%xJWPAD>W7B7r-L;**fj_Z z+#gYWq$HT)NV6ZhQl-ru4;H@y~r<=9gh*KB*?f}2MI zuRd^ao^}Wq|uY2#5ceb3Led_L?<}JGak*wp-ZhZXnSN_}Il9&DKtGj=7P21fu z-%9_5ikt5Hw5M-9-NK2Zuw!^|WMyyXvz}9;Xk#&2DeQ(V;+00@?NL!)DH$6cSUE^K ztEslg&B{(^SBD!$-EmMAMMuR))YQt(u69pPDm7g886CA5L(hdF?p8WGVJ3%MP^c8n z*D%u2@xyPtNL>R*YJFKjL0*0iadx9h@(v-a5J|x{BvCIZ$k>dA5hBSNK^2Eca*XKA zA(FfkC?B09KO>JeY(gaY1EC=oWEe|ALoUcFm_b9-`6|dZR))FB%_RMQdN+Bwq#-Xv zl6O=~50wJ7b<)Kr+>nG?^ft{GNvL(NK$8!;Sx#<3B$tyLcn!Lt<-$maq!1E!h_7-; z9tx4r>~kc<*Y%Ll&0{cR8bKV1dI|Nf9U+n%ATcKC-P{DpM2O@zNRDZemF}(yck18} zgj_1oQN_sSO0p}VC53##w#T;iW&}CnV|L&lso~+Oo-$aNNAJ@ zy7?I-UNlr8Y3*=!WM#^z6g6bhMK2Cj^4ACn>7@^K14|cSlJg@ZpNWuUM@X)TkXR!m z*G5Q&BP7tKAC?~I#SfF*7a`dmA$cQ0@|Ot7Mb!2AP)n>Gl0z7}f+hd$2sgirkeo+@ zT}U`)NM_JUgW(K8GJ@_Fl+boF9ndVwV-Rk1AvuHv0=W^9?1!WfV`fltLi#!dZbXL8 z#}KeJ#7!p+3K-dfz8;4p3A0vE@)Jmog-9+$dT+zhBj~0Il4ED-C3iwHgJC=9<^_`A zhCC>V#lSmB#iE36;h+y@b<4i(4(HoaQ*agli{VFUdnNN{U{>zIJ0a z*TP{pd-W1tc^%VBIOM~6NhYQ6K$0$;Ov=Tf5DDcyW{KVn<^6=-jfh?EhU40=mvDLx z=_OnjOSymP>mnsYl7YC!LnIV?Pl$xlyf#FV4GHO@)yju+y7w%-gnaD}kxnoCZIgqqaK5D8^|MTms5u}qV!#Ql!DeE>4CyAmC>jXCc2|8(RPL0jPl zw?xWT)s3P`Zi|q3BP1gcl64W1ng~f@gv1yjNr{joMMxmvT_Z6MPH7{*B4@p?gh*Bf zZ_)S;J30ytK+!p&;Bai0A`DYkUG|(A_M1(U!G~`%G(`hdC9&xX>kQ;h9i+kM+qtTd?tFpX&jTNXY->9(+ zjb&;qOJmuRAxMp>J~E7|j|`*gBg3fq$jwuIbMjSC`Wb);l=T+KPS8$~Ko9 z_Hc)tg+^6cua{;kt+Xo&V?JGNgXBToBMp(WX?wjxC@^(*g*bs%wsYIcCT>axJT8aH z+2QCN>ncPXEUX^s8lvFM6NQ)wgiOXrUJH=}c1N+1yF#pFgrs<2*ww`%H7x0`*wNL| z@A3?~f*}g)I_wx@x9~4yb!}`hxKI<5O-nVAYUIMHDn)esO+xQbuUpa)=Ws`t%O%e` zhlfxO^lFQ6LQHc(C&EE@?@(te*(6n3ovt=~;3c0A6 zNvBuei*S$GZ$V1QNpp>wIouBdK?+*ytz}iF278^k)ml|rU06ur zaBDI_btD>7s})s9VIV)@K@^p=R^X`7^24nsG6-(NgpbYBJmRLkC zQDJNa-ZbRurBu;V5)o8UYg3J>gxp+{s=Cr#v^J5W8ghdlInvsaOj}(Wv>(evg%|sW z)SMO!H#e8V)~U7Uj~R+=wW$4uw%&n;VR{i)rlWzHxA=Y!jj)I_7apPNoO;m5k1;co z%0L@!ka+4+6m4YXqR9mvhuB_T*gd7=gBrSsabZKfGBmSM=5#@~|J5i(gXZitBm5f5 zC->pP);d_U8@P)0duC5LbW{*kSx?=2Z?HC^J@8vln=)>$9!DK}N zP^T@z2q#bL9Ugb*@c58&O{hh@!osWylX6XjB|ON{4shjzY~YcDqLQKr2deeE1+ItL zz0p#7Y5L+5mG`RSImBx}a+_hIg6jgBf!FEv>!t)(_=z0K56Y`JoIYjIseYkfnB zwYt?>U)|bdEit#&*O-f~rB-uY{Z+>0Dd{CpXl}1;sI(Scx!mLF?OZv~+x~&#E38$; zmG%L)vh;i*H4Vt#|I|5hsFkb9Co*}$JIS)ck~SO z4h=ge?UT;I;7O-*u%y^NJ~r9y?snKc&fzgfPw&|Jq3VIj(ZcMaOrtTsw4@-vIHRN_ zJ2ah0Y_YAOBrKWLl_gaso4I~@3KjVu@w*4VYn7-azxeaWnor_6A`O`8`gY}Tdmr9F zTfHPIg>KZ&z@yb?J@kH;KwEEzbJ#W9?M_)ycUemHh`V>NcYW_rPYSF#jvyE(k{0pS zL=@T(-GiyOK6}8=LjzLtGl%osu(u}258l#I2vaWx;UkI{Gjb)zOM7}*g2Gl03R50< zS>jaK?Nm>JAAU-9ekqC32t&Lmel8?*>$V&cSTd$^qDU>hJr0ye{F38%{Cp9vs}~SK z{F0*(O3T4yr1wc&r{mgl=!TD8#^ARxcCb+Vp*+$-`FM;O+$@5%T=3(-3xU`r_htb9 z3Z#+aKY=_lL@Qnk&ZB`Xz*t~Aa51nG7zgYICIIPq&uKs}FcEko5SD4Zw*k)vehG*d zzu6KzG)Q?L$N4hg^T6|gF9Kn~Ho^k-b&JFcL^QCzq!O(e?j3TYMNt(~7S)65NFM)a75}3RfGU|9!0Gr6h%~vdc_8dtpH8hp zm2#UPQ`J<7%kk?Rw+)YV*}B}0;ZANW`@$OwnRh-Wh1CO{HN&o6ckl2JHzIlgL^dLF zc1Sv_>KfOaQQCG(c}drRyA4;^EHpI}I;h1_3p^jiuRq6&J=!_9$aioWe2ymSgj~>U zM%v5hxDfSD^|c&`8Bw_mcm*&Gh*?Ux99Rl80;_$tHS;m~%?t^tn~N6SFic57?~u)&Ty~DLjJg6PZ3dYh7^%hv z!9d%{NLMEcK@5>11Z)Ep4|jI4sdE}lg*5oV4h^WfzCg|STA4$&c~6F&|1|9Ua+D+; z!2y`s`#O}ldQe%@aT$KJjHBZojIUJwUjb5GeifJo#D_NCOyK>%eBf4~3HSi842X|z zyiLG|fezp|f%IzQw}I6D9|PV5d>l9pBx~Q>fZqeY2;2_b2Yed%Yv41$-vXZl9tXYv zJPCXeNN+g31iT3N3h*l6EU*>02T1Mxhd{iU$5y|$0DpvY(hh{@u--?2{{nmsxF1N% z;hzD25BxXae*zByqftI@0po%H4m=0=8(<1>4tNRhx4;76Jg^RU6d2wQ%A(Z|IFJDx z@i^Dd6BN&?uy^gq4~;v7-wE~uYGb&Q6%+4J&p?-*Hp6J9Sj|C;KcD1GA=UOaelnc1fndoKEBe-yd z5f>;%-rZucx;DWEqnZ?Tb#f70JKDG>(!?S{l^c=p8%=8zK4?I`4vhc@#YA87yTLo! ztwVA=pvh^!Ca(6lrJRO@JyJeY*X8mIxUu?)#e8)Ak{38YdQdLrr_)6Y%7r$$LZbdj zW2|~m-P4hW-)<@YC5BvT7f7O)=BY!#bl_V+>X&Z=uK^wg(!7K@#aj);TGM+y5Pix! z2%HB}zx)I6bHHQ3yMTWL-UmdV^L`un7vK)yUxBXyF(+|9MPKy(9OwTDJOspA&KrX? z;%!B55)j;*3XB8Nyo9;STM5K9FBL5^@9hR+&EzE&FUdes=e!)~1EOzxZv|cgya#w0 zklswW9JmX31@Py71^p=pNc}VqxEh!byc&oP6}g{ce)kUGyb$OF znt-1JmH;;ct-vn>k!J6Mz$)OQz-r)kfc3y#K#ZH-SAk8yUjy+rrWa#@ay{_(K#WNd z;{o|cQ`F|g4xH=9g9FG%_;^5msNM<5mYz7G#CXuZz<59rsK@^w53qpxC&mMs;M!0r zI6kQ3tDXEu>?+vFFBIOiPELJ%vy_ojs!uvr;&+3Tx1-HaU3UO42X+E;fL*|=f#^40 zGq49pYfcBy4(ta~pB@5IpB@3yTssQ97w7~&1jM|^_c-G~dedz^a2B`$_%q<=fHVYR zedwioR4)+Ygt7^U{;J#rya0GJFbfy}qW>ths%ywEB4lSPFa=SOxq(kml$YfK9*|;Je6IDt_v581h1#(9}i849?F|f@{`EoQL;K z@`D!_6v8LN`=*$y@#gQalX@x7)rAzYJTSGX$3MDujkv4(ug=wUXGa-cj-UK&{G%pp z+9IGke&L13AI>A)j4eEwp9ddw+b4X~vuoN_u(i4Rxm(dpuS)?hr)d>&0`e3T(@49V zWGSTJqPbz%-8K+hNvJDlIoa!{^?k_R)1t5`T$-mvd=10J!+4jJmK!wJ%S3p(yStp# z-Q6yH`7CC8UFxhuA_od}e0?Nq5y4$(q&O%%x>J?j=wTkGGs4eCIHrb;gAz8Q`H=~u zICOg`hlEphPi>Bl0{r$%`EImpYLBk~F97}kNX-)WaXg;v0j|RNkASpB*axIF!W+Ow zAo`xS6Nvjf?+EZ`z|R5?0yhDF3A_{dE8v4bq=(lEhk;bSzX84k{14y{f#|#5p8|gm z{5$Xuz!;?U7%&0&C*YaDxDT{#^s}!u?y;LQq0`CVV0iOph0ivwvojJY-I1@05D5*fY2e=qW@10%(ECF5yv;nUG+JP&9*8($uwC2bLeioPy z^Z^lucM5nVFnnA>oym{YP=Gj)CM88TF3~u9W!OCg`ALCW!tX9PF4eTTJH(b>_-2!C zSeiOL$)H@xx1(pF8Agmc|G-uwbxvB0{O`D(cuwm@>g@#0-Maob>F#pzAVZ6GTFn0< z75gnzBG`PRAyGFLkXtz<2EQyjhMcGel`$RX;dhuB-YP{srhubO@LIhPcm>W)z-%De zh?jQ$%YfGdEx=Bo6*vH_1Wo{}ft!Ifz;6OEhk17c(WZD!-Uy_CG8xxbAP#lD z#2kxpFSrLv{V}{%5PomLcFFH4XwxNyuO8HT@wxkzsIg;Huu5XLM z8{XjbMeU9z!i(UV3P9cV%;XlS-rVZ1WbkIEQx=MPGs){rDI=h=rsFjHZeWHzKGY}G z!#I#qhqVovtyb0pjldg#G%sLm;(6dEAhko>A9=q5^aH;R3;@3Y`~vV%;O)Tg0q+3P zd~hf5IFRa*l93d(C;p!9{O_cWz4Ff2zxJoB8v^JfkkdiyS33TL-z?q#e%uE=E@#Ku zkT;fAc8rXCY~S@*o(*DyVQ_e8rQ>7!`nVsdbvTsN24hNUSNllHRe;`+6gtmNNlUq& z1(1_KoVdhEKCWJsl9HO4#n&>kQ?6hK|9nt+xiTmOp3Q;h8$YqYGxI;Opt990Yw5&8 z@PED#M3%Ke_~*+rCo{Y}bJP<4X95@L%>5*?ESgYmM0tLKfoEhyltM;^Rt)?+jK=O* zrE4@e>7X%91l zvI?w(Wq7i~%s|g_6cfv;Br_;2V1+EZPBMdXX^cogypkrFLCMo(t29}eCach7>oi%X zCfjz3cy@v^l?-JXD`W^6j5adjl~s}%lv1!#mX%9pQ0!o4mbFM`Q0N<)PqWM*nL#;A zlaX>Lx@u79%NpVCGny<{lU=FFYBX7cCLLNWt%LaT91N@h@IHQ5g}*}rPCUud#pn(VkH z+k?lYnTTVtl6EW#$sigWbw*&$qdS$z#2KWzer|K z7GblziDj{p8I&bpc9xwfnL$YbYhYQbWCo@3bP-#;QX`o`c~X--rOEzXlg(+eWXC$ad3D62JDp(gw9w`E!fC39^`C&mzA3pi;1*8x>Q zWDj=)ZI`TQc0e(X6>3kqp_w5?+Jdb@YpLX(i45ZSKO?H$>j!W2_w4Zn~

ocw7mLZ9qjmg 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

    y`=bm?Xh^k&{7R_#PH$^G~|Ch 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 z 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

    qYdZ6G2zOiN6M?WaQx*y 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�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

    o6&xKRuJXuGq3U6KXK){)#*fx3F> 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

    ;6QotN)B3a=q?IYnz9}|3_08OPDj|wPnJ&LRhY| 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¬ZQQqM?@0% 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

    gPOLqy1AxUm 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

    #>WeSi{38ne>H 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 z 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 diff --git a/libultraship/libultraship/StormLibRUS32.lib b/libultraship/libultraship/StormLibRUS32.lib deleted file mode 100644 index aab5f12a0e7f0278f2151c33a6463793088ff10f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3042768 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%0DBh6$c>cb~?VYixzaVo+-; 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 jD}|-`*qbFw7dClOgbdBA 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%0DIEW8r5ZPCNN616GkT%>-#EHuDwSpu2dZRK9b|i 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

    qJ%I&$9(O4@NK0Ri>&P&lOC@rHWM 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¬|V(%%oSFwL8_Pt^r93(dUrIlk! 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

    QWxO%xXmtojw_qo15M%^wTz;mY9A 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

      _y2o0}HCXNj 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

      K7c7*pkg?e^@6?Q)aON-=C+0uvKuTn&b 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

      Y0aw7Z!CN+WOubMtty>=`WVQ^wbU2pI)DrRzGD$ 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 z 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�nZKB|FJxlr#)`O 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

      |Vth6nk1R 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

      |EKe*}O9< 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 diff --git a/libultraship/libultraship/StormLibRUS64.lib b/libultraship/libultraship/StormLibRUS64.lib deleted file mode 100644 index 6803e946277cc711b266ca79bbd01efe821a7597..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3233804 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

    n^oLz=+`f@EwuKs`f^68!Sns#q- zOS89nVRM7eYF%Wja@#!R{F64mHgC-;tJS(#;aJ37FxKp{ym_gq^U}?VhAbkbtETl5 z5~jhrh=gh85VA-vTSFNc5@m@3@_oKbDZz}9FG?_{rAd@7k(RI7oT_oMCT6o%6SG;S z$kgg&&eBp?EL!s|7A=LvqNT7{v@$FiT3sv|T3sv|GA(pP)YOtC<7LTsSu$Q$D4r}M zODiMYqSY@wU8`R@9)2rwPS4a*q-V+$nVB*)OCl|o3@NpYG_3|1c&x6-FC$IMFT{P8q*{NF3WMe)TJ(w*=em2%KDkpm@TlQAAlzp}) zdl(!w7cxB}?YvYi7a+A(Kxz%c0aEJ>B;#q4oR_Lea$ah-%r9F@F)vli zWnQYPlk?`u8qC95LXVU^bkH(ZTcil2|AxK`9drOLcMoVB~Fj%k@E zSR&jlID6=A)8$av)*vdN%Oa<#rQMs4o8ytO%mEcBs%iH*+uB;%toqVItc)9KET)N8 zoSa6RW#C<{-e#(c41!$Mx`V1{@UBrSA8M1Qd6gkV=7mbRT53D+JGxxkN<($sZ7s`f zwK)IM-X4;pt7Wy?3sSUe+FNnD+gDeqRRc%9y=~22AJr5!myOl(8X|rexV=)>brhk@+pNXV*OY?zNtO$n>ss^y zT2&yp98pnkZJ7_6NfM%7!AW;`2s(8&&|2RaNL4k9YgTy;yt~a?*Ra+=K@D@T*R%|$ zvWgu8t4Gc0YYglhA7nw!k+%4^fq=-hNX*`$PRI|buvDDkzRI}U| zkySvsQ`{F&-U6|bpH=9#JIJ*X`cDF>Z1B~W;qZRLTGbD$u3YH0GAwF*?it0`cwR z;+J~c(K(S5R2#EaJ1uft$RjK^y7LkvtNj-_cB(-h+^rNbqQ_k7#cd#7VLw#sMT(|n zTxGMBS9^+VrFqWkg~jF0JZEXh(?GH=^z zZyRYR)tr=q|Dbc4EI9Th)|TU5dUZMaMe2*|iH)iqGG=TKg;=em6jDP&0o9kLNyY>h zS0-J2W9q5!s_C2C0#_S zx)OwSbv3XjBJH7}A>;DaRC&DJlm>BOySt{%C+1k$&}z4>w7fcZVUe>s-)VDbqnTn} zdVlF+Us8YR;$KpKafj&=U1EogPjRUorb~B`4l_<}jzSWv+vdRkg@rt`>9cAh=lG&M zs!MUv9xZKYGN)0Qg@ruIgwhmx*X6dgtg?0Z>T_CZd6;1oIMr#};a%Rgu9Y3-ocfMt zR(S+tAUdl>F0R&lG!MxE$9*}+MW#|`%AL)e2YFR!l)BZTOUC_Uly+DW!w}J>y=bF3 zbBn5+5lUi8tC*n_L&}TvtRe2j>SV1hEzhZD3j#lLd1D3cSA?%=t*&nOF7LqNV_o%f zGB4H3TUr_$#Ck)faJIuC%)Ygv7VueN1PGrrbzG&R*WtX5H*ca@6TanOkT zGjswa6kB0tx6PdqX>zwIcebxbN0xh6!P$d5Y&AnE?6Bsls@U4vYS7J;f!$$KtD)6O VZfJ_iYPFL)me>LewU*nd{6G8!bE^OV diff --git a/libultraship/libultraship/StormLibDUS64.lib b/libultraship/libultraship/StormLibDUS64.lib deleted file mode 100644 index 79de4e0f4277dd6859d7a3b29e30f4a6ac9b1552..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2923852 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�yINBo;_=rk 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%0A#YcEV4t3t}RSDgnLdy>Cgi?F@OU!A@A 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

#iEua}{=d_o_2B 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