aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLadislav Zezula <ladislav.zezula@avg.com>2013-01-11 14:55:08 +0100
committerLadislav Zezula <ladislav.zezula@avg.com>2013-01-11 14:55:08 +0100
commit3a926f0228c68d7d91cf3946624d7859976440ec (patch)
treec4e7d36dc8157576929988cdfcf5bfd8262cd09c
parentdf4b0c085478389c9a21a09521d46735a0109c8a (diff)
Initial creation
-rw-r--r--.gitignore185
-rw-r--r--CMakeLists.txt304
-rw-r--r--Info.plist22
-rw-r--r--Makefile.linux275
-rw-r--r--Makefile.mac253
-rw-r--r--Publish.bat22
-rw-r--r--Publish_beta.bat22
-rw-r--r--README1
-rw-r--r--Storm.libbin0 -> 5238 bytes
-rw-r--r--StormLib.bat22
-rw-r--r--StormLib.kdev43
-rw-r--r--StormLib.sln140
-rw-r--r--StormLib.vcproj21605
-rw-r--r--StormLib.xcodeproj/project.pbxproj1992
-rw-r--r--StormLib_dll.vcproj2499
-rw-r--r--StormLib_test.vcproj1997
-rw-r--r--Storm_dll.bat18
-rw-r--r--Storm_dll.vcproj206
-rw-r--r--doc/History.txt62
-rw-r--r--doc/Sector Offset MD5.txt25
-rw-r--r--doc/The MoPaQ File Format 0.9.txt318
-rw-r--r--doc/The MoPaQ File Format 1.0.txt433
-rw-r--r--doc/d3-authenticationcode-deDE.txt1
-rw-r--r--doc/d3-authenticationcode-enGB.txt1
-rw-r--r--doc/d3-authenticationcode-enSG.txt1
-rw-r--r--doc/d3-authenticationcode-enUS.txt1
-rw-r--r--doc/d3-authenticationcode-esES.txt1
-rw-r--r--doc/d3-authenticationcode-esMX.txt1
-rw-r--r--doc/d3-authenticationcode-frFR.txt1
-rw-r--r--doc/d3-authenticationcode-itIT.txt1
-rw-r--r--doc/d3-authenticationcode-koKR.txt1
-rw-r--r--doc/d3-authenticationcode-plPL.txt1
-rw-r--r--doc/d3-authenticationcode-ptBR.txt1
-rw-r--r--doc/d3-authenticationcode-zhTW.txt1
-rw-r--r--doc/diablo3_ruru_disk_encrypted_win.blob49
-rw-r--r--doc/diablo3_urls.txt14
-rw-r--r--makefile.w32268
-rw-r--r--src/FileStream.cpp2294
-rw-r--r--src/FileStream.h189
-rw-r--r--src/SBaseCommon.cpp1736
-rw-r--r--src/SBaseDumpData.cpp144
-rw-r--r--src/SBaseFileTable.cpp2552
-rw-r--r--src/SCompression.cpp1065
-rw-r--r--src/SFileAddFile.cpp1277
-rw-r--r--src/SFileAttributes.cpp472
-rw-r--r--src/SFileCompactArchive.cpp765
-rw-r--r--src/SFileCreateArchive.cpp255
-rw-r--r--src/SFileExtractFile.cpp67
-rw-r--r--src/SFileFindFile.cpp446
-rw-r--r--src/SFileListFile.cpp636
-rw-r--r--src/SFileOpenArchive.cpp480
-rw-r--r--src/SFileOpenFileEx.cpp473
-rw-r--r--src/SFilePatchArchives.cpp587
-rw-r--r--src/SFileReadFile.cpp1186
-rw-r--r--src/SFileVerify.cpp922
-rw-r--r--src/StormCommon.h281
-rw-r--r--src/StormLib.h988
-rw-r--r--src/StormPort.h243
-rw-r--r--src/adpcm/adpcm.cpp398
-rw-r--r--src/adpcm/adpcm.h26
-rw-r--r--src/adpcm/adpcm_old.cpp358
-rw-r--r--src/adpcm/adpcm_old.h22
-rw-r--r--src/bzip2/blocksort.c1094
-rw-r--r--src/bzip2/bzlib.c1573
-rw-r--r--src/bzip2/bzlib.h282
-rw-r--r--src/bzip2/bzlib_private.h509
-rw-r--r--src/bzip2/compress.c672
-rw-r--r--src/bzip2/crctable.c104
-rw-r--r--src/bzip2/decompress.c626
-rw-r--r--src/bzip2/huffman.c205
-rw-r--r--src/bzip2/randtable.c84
-rw-r--r--src/huffman/HuffTree.xlsbin0 -> 361472 bytes
-rw-r--r--src/huffman/huff.cpp869
-rw-r--r--src/huffman/huff.h143
-rw-r--r--src/huffman/huff_old.cpp1303
-rw-r--r--src/huffman/huff_old.h142
-rw-r--r--src/jenkins/lookup.h24
-rw-r--r--src/jenkins/lookup3.c1003
-rw-r--r--src/libtomcrypt/src/hashes/hash_memory.c69
-rw-r--r--src/libtomcrypt/src/hashes/md5.c368
-rw-r--r--src/libtomcrypt/src/hashes/sha1.c288
-rw-r--r--src/libtomcrypt/src/headers/tomcrypt.h87
-rw-r--r--src/libtomcrypt/src/headers/tomcrypt_argchk.h38
-rw-r--r--src/libtomcrypt/src/headers/tomcrypt_cfg.h136
-rw-r--r--src/libtomcrypt/src/headers/tomcrypt_cipher.h891
-rw-r--r--src/libtomcrypt/src/headers/tomcrypt_custom.h424
-rw-r--r--src/libtomcrypt/src/headers/tomcrypt_hash.h378
-rw-r--r--src/libtomcrypt/src/headers/tomcrypt_mac.h384
-rw-r--r--src/libtomcrypt/src/headers/tomcrypt_macros.h424
-rw-r--r--src/libtomcrypt/src/headers/tomcrypt_math.h500
-rw-r--r--src/libtomcrypt/src/headers/tomcrypt_misc.h23
-rw-r--r--src/libtomcrypt/src/headers/tomcrypt_pk.h558
-rw-r--r--src/libtomcrypt/src/headers/tomcrypt_pkcs.h89
-rw-r--r--src/libtomcrypt/src/headers/tomcrypt_prng.h199
-rw-r--r--src/libtomcrypt/src/math/ltm_desc.c483
-rw-r--r--src/libtomcrypt/src/math/multi.c61
-rw-r--r--src/libtomcrypt/src/math/rand_prime.c87
-rw-r--r--src/libtomcrypt/src/misc/base64_decode.c104
-rw-r--r--src/libtomcrypt/src/misc/crypt_argchk.c30
-rw-r--r--src/libtomcrypt/src/misc/crypt_find_hash.c40
-rw-r--r--src/libtomcrypt/src/misc/crypt_find_prng.c41
-rw-r--r--src/libtomcrypt/src/misc/crypt_hash_descriptor.c27
-rw-r--r--src/libtomcrypt/src/misc/crypt_hash_is_valid.c36
-rw-r--r--src/libtomcrypt/src/misc/crypt_libc.c43
-rw-r--r--src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c13
-rw-r--r--src/libtomcrypt/src/misc/crypt_prng_descriptor.c26
-rw-r--r--src/libtomcrypt/src/misc/crypt_prng_is_valid.c36
-rw-r--r--src/libtomcrypt/src/misc/crypt_register_hash.c54
-rw-r--r--src/libtomcrypt/src/misc/crypt_register_prng.c54
-rw-r--r--src/libtomcrypt/src/misc/zeromem.c34
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c102
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_decode_boolean.c47
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_decode_choice.c182
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c96
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_decode_integer.c110
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c99
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c91
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c96
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c287
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c386
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c139
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c68
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_decode_utctime.c127
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c111
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_length_bit_string.c54
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_length_boolean.c35
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c194
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_length_integer.c82
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c89
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_length_octet_string.c53
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_length_printable_string.c166
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_length_sequence.c169
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_length_short_integer.c70
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_length_utctime.c46
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c83
-rw-r--r--src/libtomcrypt/src/pk/asn1/der_sequence_free.c65
-rw-r--r--src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c76
-rw-r--r--src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c207
-rw-r--r--src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c222
-rw-r--r--src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c60
-rw-r--r--src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c196
-rw-r--r--src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c147
-rw-r--r--src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c108
-rw-r--r--src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c189
-rw-r--r--src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c177
-rw-r--r--src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c110
-rw-r--r--src/libtomcrypt/src/pk/rsa/rsa_exptmod.c113
-rw-r--r--src/libtomcrypt/src/pk/rsa/rsa_free.c34
-rw-r--r--src/libtomcrypt/src/pk/rsa/rsa_import.c143
-rw-r--r--src/libtomcrypt/src/pk/rsa/rsa_make_key.c112
-rw-r--r--src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c167
-rw-r--r--src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c87
-rw-r--r--src/libtommath/bn_fast_mp_invmod.c148
-rw-r--r--src/libtommath/bn_fast_mp_montgomery_reduce.c172
-rw-r--r--src/libtommath/bn_fast_s_mp_mul_digs.c107
-rw-r--r--src/libtommath/bn_fast_s_mp_mul_high_digs.c98
-rw-r--r--src/libtommath/bn_fast_s_mp_sqr.c114
-rw-r--r--src/libtommath/bn_mp_2expt.c48
-rw-r--r--src/libtommath/bn_mp_abs.c43
-rw-r--r--src/libtommath/bn_mp_add.c53
-rw-r--r--src/libtommath/bn_mp_add_d.c112
-rw-r--r--src/libtommath/bn_mp_addmod.c41
-rw-r--r--src/libtommath/bn_mp_and.c57
-rw-r--r--src/libtommath/bn_mp_clamp.c44
-rw-r--r--src/libtommath/bn_mp_clear.c44
-rw-r--r--src/libtommath/bn_mp_clear_multi.c34
-rw-r--r--src/libtommath/bn_mp_cmp.c43
-rw-r--r--src/libtommath/bn_mp_cmp_d.c44
-rw-r--r--src/libtommath/bn_mp_cmp_mag.c55
-rw-r--r--src/libtommath/bn_mp_cnt_lsb.c53
-rw-r--r--src/libtommath/bn_mp_copy.c68
-rw-r--r--src/libtommath/bn_mp_count_bits.c45
-rw-r--r--src/libtommath/bn_mp_div.c292
-rw-r--r--src/libtommath/bn_mp_div_2.c68
-rw-r--r--src/libtommath/bn_mp_div_2d.c97
-rw-r--r--src/libtommath/bn_mp_div_3.c79
-rw-r--r--src/libtommath/bn_mp_div_d.c115
-rw-r--r--src/libtommath/bn_mp_dr_is_modulus.c43
-rw-r--r--src/libtommath/bn_mp_dr_reduce.c94
-rw-r--r--src/libtommath/bn_mp_dr_setup.c32
-rw-r--r--src/libtommath/bn_mp_exch.c34
-rw-r--r--src/libtommath/bn_mp_expt_d.c57
-rw-r--r--src/libtommath/bn_mp_exptmod.c112
-rw-r--r--src/libtommath/bn_mp_exptmod_fast.c321
-rw-r--r--src/libtommath/bn_mp_exteuclid.c82
-rw-r--r--src/libtommath/bn_mp_fread.c67
-rw-r--r--src/libtommath/bn_mp_fwrite.c52
-rw-r--r--src/libtommath/bn_mp_gcd.c105
-rw-r--r--src/libtommath/bn_mp_get_int.c45
-rw-r--r--src/libtommath/bn_mp_grow.c57
-rw-r--r--src/libtommath/bn_mp_init.c46
-rw-r--r--src/libtommath/bn_mp_init_copy.c32
-rw-r--r--src/libtommath/bn_mp_init_multi.c59
-rw-r--r--src/libtommath/bn_mp_init_set.c32
-rw-r--r--src/libtommath/bn_mp_init_set_int.c31
-rw-r--r--src/libtommath/bn_mp_init_size.c48
-rw-r--r--src/libtommath/bn_mp_invmod.c43
-rw-r--r--src/libtommath/bn_mp_invmod_slow.c175
-rw-r--r--src/libtommath/bn_mp_is_square.c109
-rw-r--r--src/libtommath/bn_mp_jacobi.c105
-rw-r--r--src/libtommath/bn_mp_karatsuba_mul.c167
-rw-r--r--src/libtommath/bn_mp_karatsuba_sqr.c121
-rw-r--r--src/libtommath/bn_mp_lcm.c60
-rw-r--r--src/libtommath/bn_mp_lshd.c67
-rw-r--r--src/libtommath/bn_mp_mod.c48
-rw-r--r--src/libtommath/bn_mp_mod_2d.c55
-rw-r--r--src/libtommath/bn_mp_mod_d.c27
-rw-r--r--src/libtommath/bn_mp_montgomery_calc_normalization.c59
-rw-r--r--src/libtommath/bn_mp_montgomery_reduce.c118
-rw-r--r--src/libtommath/bn_mp_montgomery_setup.c59
-rw-r--r--src/libtommath/bn_mp_mul.c66
-rw-r--r--src/libtommath/bn_mp_mul_2.c82
-rw-r--r--src/libtommath/bn_mp_mul_2d.c85
-rw-r--r--src/libtommath/bn_mp_mul_d.c79
-rw-r--r--src/libtommath/bn_mp_mulmod.c40
-rw-r--r--src/libtommath/bn_mp_n_root.c132
-rw-r--r--src/libtommath/bn_mp_neg.c40
-rw-r--r--src/libtommath/bn_mp_or.c50
-rw-r--r--src/libtommath/bn_mp_prime_fermat.c62
-rw-r--r--src/libtommath/bn_mp_prime_is_divisible.c50
-rw-r--r--src/libtommath/bn_mp_prime_is_prime.c83
-rw-r--r--src/libtommath/bn_mp_prime_miller_rabin.c103
-rw-r--r--src/libtommath/bn_mp_prime_next_prime.c170
-rw-r--r--src/libtommath/bn_mp_prime_rabin_miller_trials.c52
-rw-r--r--src/libtommath/bn_mp_prime_random_ex.c125
-rw-r--r--src/libtommath/bn_mp_radix_size.c78
-rw-r--r--src/libtommath/bn_mp_radix_smap.c24
-rw-r--r--src/libtommath/bn_mp_rand.c55
-rw-r--r--src/libtommath/bn_mp_read_radix.c85
-rw-r--r--src/libtommath/bn_mp_read_signed_bin.c41
-rw-r--r--src/libtommath/bn_mp_read_unsigned_bin.c55
-rw-r--r--src/libtommath/bn_mp_reduce.c100
-rw-r--r--src/libtommath/bn_mp_reduce_2k.c61
-rw-r--r--src/libtommath/bn_mp_reduce_2k_l.c62
-rw-r--r--src/libtommath/bn_mp_reduce_2k_setup.c47
-rw-r--r--src/libtommath/bn_mp_reduce_2k_setup_l.c44
-rw-r--r--src/libtommath/bn_mp_reduce_is_2k.c52
-rw-r--r--src/libtommath/bn_mp_reduce_is_2k_l.c44
-rw-r--r--src/libtommath/bn_mp_reduce_setup.c34
-rw-r--r--src/libtommath/bn_mp_rshd.c72
-rw-r--r--src/libtommath/bn_mp_set.c29
-rw-r--r--src/libtommath/bn_mp_set_int.c48
-rw-r--r--src/libtommath/bn_mp_shrink.c35
-rw-r--r--src/libtommath/bn_mp_signed_bin_size.c27
-rw-r--r--src/libtommath/bn_mp_sqr.c58
-rw-r--r--src/libtommath/bn_mp_sqrmod.c41
-rw-r--r--src/libtommath/bn_mp_sqrt.c81
-rw-r--r--src/libtommath/bn_mp_sub.c59
-rw-r--r--src/libtommath/bn_mp_sub_d.c93
-rw-r--r--src/libtommath/bn_mp_submod.c42
-rw-r--r--src/libtommath/bn_mp_to_signed_bin.c33
-rw-r--r--src/libtommath/bn_mp_to_signed_bin_n.c31
-rw-r--r--src/libtommath/bn_mp_to_unsigned_bin.c48
-rw-r--r--src/libtommath/bn_mp_to_unsigned_bin_n.c31
-rw-r--r--src/libtommath/bn_mp_toom_mul.c284
-rw-r--r--src/libtommath/bn_mp_toom_sqr.c226
-rw-r--r--src/libtommath/bn_mp_toradix.c75
-rw-r--r--src/libtommath/bn_mp_toradix_n.c88
-rw-r--r--src/libtommath/bn_mp_unsigned_bin_size.c28
-rw-r--r--src/libtommath/bn_mp_xor.c51
-rw-r--r--src/libtommath/bn_mp_zero.c36
-rw-r--r--src/libtommath/bn_prime_tab.c61
-rw-r--r--src/libtommath/bn_reverse.c39
-rw-r--r--src/libtommath/bn_s_mp_add.c109
-rw-r--r--src/libtommath/bn_s_mp_exptmod.c252
-rw-r--r--src/libtommath/bn_s_mp_mul_digs.c90
-rw-r--r--src/libtommath/bn_s_mp_mul_high_digs.c81
-rw-r--r--src/libtommath/bn_s_mp_sqr.c84
-rw-r--r--src/libtommath/bn_s_mp_sub.c89
-rw-r--r--src/libtommath/bncore.c36
-rw-r--r--src/libtommath/tommath.h584
-rw-r--r--src/libtommath/tommath_class.h999
-rw-r--r--src/libtommath/tommath_superclass.h76
-rw-r--r--src/lzma/C/LzFind.c761
-rw-r--r--src/lzma/C/LzFind.h115
-rw-r--r--src/lzma/C/LzFindMt.c793
-rw-r--r--src/lzma/C/LzFindMt.h105
-rw-r--r--src/lzma/C/LzHash.h54
-rw-r--r--src/lzma/C/LzmaDec.c999
-rw-r--r--src/lzma/C/LzmaDec.h231
-rw-r--r--src/lzma/C/LzmaEnc.c2268
-rw-r--r--src/lzma/C/LzmaEnc.h80
-rw-r--r--src/lzma/C/Threads.c84
-rw-r--r--src/lzma/C/Threads.h59
-rw-r--r--src/lzma/C/Types.h236
-rw-r--r--src/lzma/info.txt1
-rw-r--r--src/pklib/crc32.c66
-rw-r--r--src/pklib/explode.c522
-rw-r--r--src/pklib/implode.c769
-rw-r--r--src/pklib/pklib.h148
-rw-r--r--src/sparse/sparse.cpp296
-rw-r--r--src/sparse/sparse.h19
-rw-r--r--src/zlib/adler32.c149
-rw-r--r--src/zlib/compress2.c79
-rw-r--r--src/zlib/crc32.c423
-rw-r--r--src/zlib/crc32.h441
-rw-r--r--src/zlib/deflate.c1736
-rw-r--r--src/zlib/deflate.h331
-rw-r--r--src/zlib/inffast.c318
-rw-r--r--src/zlib/inffast.h11
-rw-r--r--src/zlib/inffixed.h94
-rw-r--r--src/zlib/inflate.c1368
-rw-r--r--src/zlib/inflate.h115
-rw-r--r--src/zlib/inftrees.c329
-rw-r--r--src/zlib/inftrees.h55
-rw-r--r--src/zlib/trees.c1219
-rw-r--r--src/zlib/trees.h128
-rw-r--r--src/zlib/zconf.h332
-rw-r--r--src/zlib/zlib.h1357
-rw-r--r--src/zlib/zutil.c318
-rw-r--r--src/zlib/zutil.h269
-rw-r--r--storm.dllbin0 -> 327680 bytes
-rw-r--r--storm_dll/storm_dll.cpp117
-rw-r--r--storm_dll/storm_dll.def25
-rw-r--r--storm_dll/storm_dll.h67
-rw-r--r--stormlib_dll/DllMain.c24
-rw-r--r--stormlib_dll/StormLib.def76
-rw-r--r--stormlib_dll/StormLib.exp75
-rw-r--r--test/Test.cpp2263
319 files changed, 98414 insertions, 26 deletions
diff --git a/.gitignore b/.gitignore
index 08b9dd2..5ebd21a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,30 +1,163 @@
-# Compiled Object files
-*.slo
-*.lo
-*.o
-
-# Compiled Dynamic libraries
-*.so
-*.dylib
-
-# Compiled Static libraries
-*.lai
-*.lib
-*.la
-*.a
-
-# Temporary work files for MS Visual Studio
-BuildLog.htm
-*.dep
-*.dll
-*.embed.manifest
-*.intermediate.manifest
-*.exe
-*.idb
+#################
+## 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
-*.res
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.vspscc
+.builds
+*.dotCover
+
+## TODO: If you have NuGet Package Restore enabled, uncomment this
+#packages/
+
+# Visual C++ cache files
+ipch/
+*.aps
*.ncb
-*.suo
-*.user
+*.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
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..d78825f
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,304 @@
+project(StormLib)
+cmake_minimum_required(VERSION 2.6)
+
+set(SRC_FILES
+ src/adpcm/adpcm.cpp
+ src/huffman/huff.cpp
+ src/jenkins/lookup3.c
+ src/lzma/C/LzFind.c
+ src/lzma/C/LzmaDec.c
+ src/lzma/C/LzmaEnc.c
+ src/pklib/explode.c
+ src/pklib/implode.c
+ src/sparse/sparse.cpp
+ src/FileStream.cpp
+ src/SBaseCommon.cpp
+ src/SBaseFileTable.cpp
+ src/SCompression.cpp
+ src/SFileAddFile.cpp
+ src/SFileAttributes.cpp
+ src/SFileCompactArchive.cpp
+ src/SFileCreateArchive.cpp
+ src/SFileExtractFile.cpp
+ src/SFileFindFile.cpp
+ src/SFileListFile.cpp
+ src/SFileOpenArchive.cpp
+ src/SFileOpenFileEx.cpp
+ src/SFilePatchArchives.cpp
+ src/SFileReadFile.cpp
+ src/SFileVerify.cpp
+ src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c
+)
+
+set(TOMCRYPT_FILES
+ src/libtomcrypt/src/hashes/hash_memory.c
+ src/libtomcrypt/src/hashes/md5.c
+ src/libtomcrypt/src/hashes/sha1.c
+ src/libtomcrypt/src/math/ltm_desc.c
+ src/libtomcrypt/src/math/multi.c
+ src/libtomcrypt/src/math/rand_prime.c
+ src/libtomcrypt/src/misc/base64_decode.c
+ src/libtomcrypt/src/misc/crypt_argchk.c
+ src/libtomcrypt/src/misc/crypt_find_hash.c
+ src/libtomcrypt/src/misc/crypt_find_prng.c
+ src/libtomcrypt/src/misc/crypt_hash_descriptor.c
+ src/libtomcrypt/src/misc/crypt_hash_is_valid.c
+ src/libtomcrypt/src/misc/crypt_libc.c
+ src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c
+ src/libtomcrypt/src/misc/crypt_prng_descriptor.c
+ src/libtomcrypt/src/misc/crypt_prng_is_valid.c
+ src/libtomcrypt/src/misc/crypt_register_hash.c
+ src/libtomcrypt/src/misc/crypt_register_prng.c
+ src/libtomcrypt/src/misc/zeromem.c
+ src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c
+ src/libtomcrypt/src/pk/asn1/der_decode_boolean.c
+ src/libtomcrypt/src/pk/asn1/der_decode_choice.c
+ src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c
+ src/libtomcrypt/src/pk/asn1/der_decode_integer.c
+ src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c
+ src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c
+ src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c
+ src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c
+ src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c
+ src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c
+ src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c
+ src/libtomcrypt/src/pk/asn1/der_decode_utctime.c
+ src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c
+ src/libtomcrypt/src/pk/asn1/der_length_bit_string.c
+ src/libtomcrypt/src/pk/asn1/der_length_boolean.c
+ src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c
+ src/libtomcrypt/src/pk/asn1/der_length_integer.c
+ src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c
+ src/libtomcrypt/src/pk/asn1/der_length_octet_string.c
+ src/libtomcrypt/src/pk/asn1/der_length_printable_string.c
+ src/libtomcrypt/src/pk/asn1/der_length_sequence.c
+ src/libtomcrypt/src/pk/asn1/der_length_utctime.c
+ src/libtomcrypt/src/pk/asn1/der_sequence_free.c
+ src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c
+ src/libtomcrypt/src/pk/asn1/der_length_short_integer.c
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c
+ src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c
+ src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c
+ src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c
+ src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c
+ src/libtomcrypt/src/pk/rsa/rsa_exptmod.c
+ src/libtomcrypt/src/pk/rsa/rsa_free.c
+ src/libtomcrypt/src/pk/rsa/rsa_import.c
+ src/libtomcrypt/src/pk/rsa/rsa_make_key.c
+ src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c
+)
+
+set(TOMMATH_FILES
+ src/libtommath/bncore.c
+ src/libtommath/bn_fast_mp_invmod.c
+ src/libtommath/bn_fast_mp_montgomery_reduce.c
+ src/libtommath/bn_fast_s_mp_mul_digs.c
+ src/libtommath/bn_fast_s_mp_mul_high_digs.c
+ src/libtommath/bn_fast_s_mp_sqr.c
+ src/libtommath/bn_mp_2expt.c
+ src/libtommath/bn_mp_abs.c
+ src/libtommath/bn_mp_add.c
+ src/libtommath/bn_mp_addmod.c
+ src/libtommath/bn_mp_add_d.c
+ src/libtommath/bn_mp_and.c
+ src/libtommath/bn_mp_clamp.c
+ src/libtommath/bn_mp_clear.c
+ src/libtommath/bn_mp_clear_multi.c
+ src/libtommath/bn_mp_cmp.c
+ src/libtommath/bn_mp_cmp_d.c
+ src/libtommath/bn_mp_cmp_mag.c
+ src/libtommath/bn_mp_cnt_lsb.c
+ src/libtommath/bn_mp_copy.c
+ src/libtommath/bn_mp_count_bits.c
+ src/libtommath/bn_mp_div.c
+ src/libtommath/bn_mp_div_2.c
+ src/libtommath/bn_mp_div_2d.c
+ src/libtommath/bn_mp_div_3.c
+ src/libtommath/bn_mp_div_d.c
+ src/libtommath/bn_mp_dr_is_modulus.c
+ src/libtommath/bn_mp_dr_reduce.c
+ src/libtommath/bn_mp_dr_setup.c
+ src/libtommath/bn_mp_exch.c
+ src/libtommath/bn_mp_exptmod.c
+ src/libtommath/bn_mp_exptmod_fast.c
+ src/libtommath/bn_mp_expt_d.c
+ src/libtommath/bn_mp_exteuclid.c
+ src/libtommath/bn_mp_fread.c
+ src/libtommath/bn_mp_fwrite.c
+ src/libtommath/bn_mp_gcd.c
+ src/libtommath/bn_mp_get_int.c
+ src/libtommath/bn_mp_grow.c
+ src/libtommath/bn_mp_init.c
+ src/libtommath/bn_mp_init_copy.c
+ src/libtommath/bn_mp_init_multi.c
+ src/libtommath/bn_mp_init_set.c
+ src/libtommath/bn_mp_init_set_int.c
+ src/libtommath/bn_mp_init_size.c
+ src/libtommath/bn_mp_invmod.c
+ src/libtommath/bn_mp_invmod_slow.c
+ src/libtommath/bn_mp_is_square.c
+ src/libtommath/bn_mp_jacobi.c
+ src/libtommath/bn_mp_karatsuba_mul.c
+ src/libtommath/bn_mp_karatsuba_sqr.c
+ src/libtommath/bn_mp_lcm.c
+ src/libtommath/bn_mp_lshd.c
+ src/libtommath/bn_mp_mod.c
+ src/libtommath/bn_mp_mod_2d.c
+ src/libtommath/bn_mp_mod_d.c
+ src/libtommath/bn_mp_montgomery_calc_normalization.c
+ src/libtommath/bn_mp_montgomery_reduce.c
+ src/libtommath/bn_mp_montgomery_setup.c
+ src/libtommath/bn_mp_mul.c
+ src/libtommath/bn_mp_mulmod.c
+ src/libtommath/bn_mp_mul_2.c
+ src/libtommath/bn_mp_mul_2d.c
+ src/libtommath/bn_mp_mul_d.c
+ src/libtommath/bn_mp_neg.c
+ src/libtommath/bn_mp_n_root.c
+ src/libtommath/bn_mp_or.c
+ src/libtommath/bn_mp_prime_fermat.c
+ src/libtommath/bn_mp_prime_is_divisible.c
+ src/libtommath/bn_mp_prime_is_prime.c
+ src/libtommath/bn_mp_prime_miller_rabin.c
+ src/libtommath/bn_mp_prime_next_prime.c
+ src/libtommath/bn_mp_prime_rabin_miller_trials.c
+ src/libtommath/bn_mp_prime_random_ex.c
+ src/libtommath/bn_mp_radix_size.c
+ src/libtommath/bn_mp_radix_smap.c
+ src/libtommath/bn_mp_rand.c
+ src/libtommath/bn_mp_read_radix.c
+ src/libtommath/bn_mp_read_signed_bin.c
+ src/libtommath/bn_mp_read_unsigned_bin.c
+ src/libtommath/bn_mp_reduce.c
+ src/libtommath/bn_mp_reduce_2k.c
+ src/libtommath/bn_mp_reduce_2k_l.c
+ src/libtommath/bn_mp_reduce_2k_setup.c
+ src/libtommath/bn_mp_reduce_2k_setup_l.c
+ src/libtommath/bn_mp_reduce_is_2k.c
+ src/libtommath/bn_mp_reduce_is_2k_l.c
+ src/libtommath/bn_mp_reduce_setup.c
+ src/libtommath/bn_mp_rshd.c
+ src/libtommath/bn_mp_set.c
+ src/libtommath/bn_mp_set_int.c
+ src/libtommath/bn_mp_shrink.c
+ src/libtommath/bn_mp_signed_bin_size.c
+ src/libtommath/bn_mp_sqr.c
+ src/libtommath/bn_mp_sqrmod.c
+ src/libtommath/bn_mp_sqrt.c
+ src/libtommath/bn_mp_sub.c
+ src/libtommath/bn_mp_submod.c
+ src/libtommath/bn_mp_sub_d.c
+ src/libtommath/bn_mp_toom_mul.c
+ src/libtommath/bn_mp_toom_sqr.c
+ src/libtommath/bn_mp_toradix.c
+ src/libtommath/bn_mp_toradix_n.c
+ src/libtommath/bn_mp_to_signed_bin.c
+ src/libtommath/bn_mp_to_signed_bin_n.c
+ src/libtommath/bn_mp_to_unsigned_bin.c
+ src/libtommath/bn_mp_to_unsigned_bin_n.c
+ src/libtommath/bn_mp_unsigned_bin_size.c
+ src/libtommath/bn_mp_xor.c
+ src/libtommath/bn_mp_zero.c
+ src/libtommath/bn_prime_tab.c
+ src/libtommath/bn_reverse.c
+ src/libtommath/bn_s_mp_add.c
+ src/libtommath/bn_s_mp_exptmod.c
+ src/libtommath/bn_s_mp_mul_digs.c
+ src/libtommath/bn_s_mp_mul_high_digs.c
+ src/libtommath/bn_s_mp_sqr.c
+ src/libtommath/bn_s_mp_sub.c
+)
+
+set(ZLIB_BZIP2_FILES
+ src/bzip2/blocksort.c
+ src/bzip2/bzlib.c
+ src/bzip2/compress.c
+ src/bzip2/crctable.c
+ src/bzip2/decompress.c
+ src/bzip2/huffman.c
+ src/bzip2/randtable.c
+ src/zlib/adler32.c
+ src/zlib/compress2.c
+ src/zlib/crc32.c
+ src/zlib/deflate.c
+ src/zlib/inffast.c
+ src/zlib/inflate.c
+ src/zlib/inftrees.c
+ src/zlib/trees.c
+ src/zlib/zutil.c
+)
+
+set(TEST_SRC_FILES
+ test/Test.cpp
+)
+
+add_definitions(-D_7ZIP_ST -DBZ_STRICT_ANSI)
+
+if(WIN32)
+ if(MSVC)
+ message(STATUS "Using MSVC")
+ add_definitions(-D_7ZIP_ST -DWIN32)
+ else()
+ message(STATUS "Using mingw")
+ endif()
+ set(SRC_ADDITIONAL_FILES ${ZLIB_BZIP2_FILES} ${TOMCRYPT_FILES} ${TOMMATH_FILES})
+ set(LINK_LIBS wininet)
+endif()
+
+if(APPLE)
+ message(STATUS "Using Mac OS X port")
+ set(LINK_LIBS z bz2)
+ set(SRC_ADDITIONAL_FILES ${TOMCRYPT_FILES} ${TOMMATH_FILES})
+endif()
+
+if (${CMAKE_SYSTEM_NAME} STREQUAL Linux)
+ message(STATUS "Using Linux port")
+ option(WITH_LIBTOMCRYPT "Use system LibTomCrypt library" OFF)
+ if(WITH_LIBTOMCRYPT)
+ set(LINK_LIBS z bz2 tomcrypt)
+ else()
+ set(LINK_LIBS z bz2)
+ set(SRC_ADDITIONAL_FILES ${TOMCRYPT_FILES} ${TOMMATH_FILES})
+ endif()
+endif()
+
+add_library(storm SHARED ${SRC_FILES} ${SRC_ADDITIONAL_FILES})
+target_link_libraries(storm ${LINK_LIBS})
+
+option(WITH_TEST "Compile Test application" OFF)
+if(WITH_TEST)
+ add_executable(storm_test ${TEST_SRC_FILES})
+ target_link_libraries(storm_test storm)
+endif()
+
+option(WITH_STATIC "Compile static linked library" OFF)
+if(WITH_STATIC)
+ add_library(StormLib_static STATIC ${SRC_FILES} ${SRC_ADDITIONAL_FILES})
+ target_link_libraries(StormLib_static ${LINK_LIBS})
+ set_target_properties(StormLib_static PROPERTIES OUTPUT_NAME StormLib)
+endif()
+
+if(APPLE)
+ set_target_properties(storm PROPERTIES FRAMEWORK true)
+ set_target_properties(storm PROPERTIES PUBLIC_HEADER "src/StormLib.h src/StormPort.h")
+ set_target_properties(storm PROPERTIES LINK_FLAGS "-framework Carbon")
+endif()
+
+if(UNIX)
+ set_target_properties(storm PROPERTIES VERSION 8.10.0)
+ set_target_properties(storm PROPERTIES SOVERSION 8.10)
+endif()
+
+# On Win32, build StormLib.dll since we don't want to clash with Storm.dll
+if(WIN32)
+ set_target_properties(storm PROPERTIES OUTPUT_NAME StormLib)
+endif()
+
+install(TARGETS storm RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib FRAMEWORK DESTINATION /Library/Frameworks)
+install(FILES src/StormLib.h src/StormPort.h DESTINATION include)
+
diff --git a/Info.plist b/Info.plist
new file mode 100644
index 0000000..0e1ae01
--- /dev/null
+++ b/Info.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>net.zezula.${PRODUCT_NAME:rfc1034Identifier}</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>FMWK</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>8.01</string>
+</dict>
+</plist>
diff --git a/Makefile.linux b/Makefile.linux
new file mode 100644
index 0000000..e9d89c7
--- /dev/null
+++ b/Makefile.linux
@@ -0,0 +1,275 @@
+#####################################################################
+###
+#
+# Makefile for compiling StormLib under linux
+#
+# Author: Marko Friedemann <marko.friedemann@bmx-chemnitz.de>
+# Created at: Mon Jan 29 18:26:01 CEST 2001
+# Computer: whiplash.flachland-chemnitz.de
+# System: Linux 2.4.0 on i686
+#
+# Copyright (c) 2001 BMX-Chemnitz.DE All rights reserved.
+#
+#####################################################################
+###
+
+##############################################################
+# updated on Monday 3, 2010 by Christopher Chedeau aka vjeux #
+# updated on April 24, 2010 by Ivan Komissarov aka Nevermore #
+##############################################################
+
+C++ = g++
+CC = gcc
+AR = ar
+DFLAGS = -D__SYS_ZLIB
+OFLAGS =
+LFLAGS = -lbz2 -lz
+CFLAGS = -fPIC -D_7ZIP_ST
+CFLAGS += $(OFLAGS) $(DFLAGS)
+
+OBJS = src/adpcm/adpcm.o \
+ src/FileStream.o \
+ src/huffman/huff.o \
+ src/SBaseCommon.o \
+ src/SBaseFileTable.o \
+ src/SCompression.o \
+ src/SFileAddFile.o \
+ src/SFileAttributes.o \
+ src/SFileCompactArchive.o \
+ src/SFileCreateArchive.o \
+ src/SFileExtractFile.o \
+ src/SFileFindFile.o \
+ src/SFileListFile.o \
+ src/SFileOpenArchive.o \
+ src/SFileOpenFileEx.o \
+ src/SFilePatchArchives.o \
+ src/SFileReadFile.o \
+ src/SFileVerify.o \
+ src/sparse/sparse.o
+
+COBJS = src/libtomcrypt/src/hashes/sha1.o \
+ src/libtomcrypt/src/hashes/hash_memory.o \
+ src/libtomcrypt/src/hashes/md5.o \
+ src/libtomcrypt/src/misc/crypt_hash_is_valid.o \
+ src/libtomcrypt/src/misc/crypt_prng_descriptor.o \
+ src/libtomcrypt/src/misc/crypt_register_prng.o \
+ src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.o \
+ src/libtomcrypt/src/misc/crypt_find_hash.o \
+ src/libtomcrypt/src/misc/zeromem.o \
+ src/libtomcrypt/src/misc/base64_decode.o \
+ src/libtomcrypt/src/misc/crypt_register_hash.o \
+ src/libtomcrypt/src/misc/crypt_find_prng.o \
+ src/libtomcrypt/src/misc/crypt_prng_is_valid.o \
+ src/libtomcrypt/src/misc/crypt_hash_descriptor.o \
+ src/libtomcrypt/src/misc/crypt_libc.o \
+ src/libtomcrypt/src/misc/crypt_argchk.o \
+ src/libtomcrypt/src/math/multi.o \
+ src/libtomcrypt/src/math/ltm_desc.o \
+ src/libtomcrypt/src/math/rand_prime.o \
+ src/libtomcrypt/src/pk/asn1/der_length_ia5_string.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_utctime.o \
+ src/libtomcrypt/src/pk/asn1/der_length_boolean.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_octet_string.o \
+ src/libtomcrypt/src/pk/asn1/der_length_object_identifier.o \
+ src/libtomcrypt/src/pk/asn1/der_length_bit_string.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.o \
+ src/libtomcrypt/src/pk/asn1/der_length_integer.o \
+ src/libtomcrypt/src/pk/asn1/der_length_sequence.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_choice.o \
+ src/libtomcrypt/src/pk/asn1/der_length_octet_string.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_printable_string.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_bit_string.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_short_integer.o \
+ src/libtomcrypt/src/pk/asn1/der_length_utctime.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_integer.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_boolean.o \
+ src/libtomcrypt/src/pk/asn1/der_sequence_free.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.o \
+ src/libtomcrypt/src/pk/asn1/der_length_short_integer.o \
+ src/libtomcrypt/src/pk/asn1/der_length_printable_string.o \
+ src/libtomcrypt/src/pk/asn1/der_length_utf8_string.o \
+ src/libtomcrypt/src/pk/rsa/rsa_make_key.o \
+ src/libtomcrypt/src/pk/rsa/rsa_free.o \
+ src/libtomcrypt/src/pk/rsa/rsa_verify_simple.o \
+ src/libtomcrypt/src/pk/rsa/rsa_import.o \
+ src/libtomcrypt/src/pk/rsa/rsa_verify_hash.o \
+ src/libtomcrypt/src/pk/rsa/rsa_exptmod.o \
+ src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.o \
+ src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.o \
+ src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.o \
+ src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.o \
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.o \
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.o \
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.o \
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_map.o \
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_points.o \
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.o \
+ src/libtommath/bn_mp_exptmod_fast.o \
+ src/libtommath/bn_mp_jacobi.o \
+ src/libtommath/bn_mp_mod.o \
+ src/libtommath/bn_mp_signed_bin_size.o \
+ src/libtommath/bn_mp_invmod.o \
+ src/libtommath/bn_mp_is_square.o \
+ src/libtommath/bn_mp_neg.o \
+ src/libtommath/bn_mp_reduce_2k.o \
+ src/libtommath/bn_mp_xor.o \
+ src/libtommath/bn_mp_karatsuba_mul.o \
+ src/libtommath/bn_mp_dr_setup.o \
+ src/libtommath/bn_mp_mul.o \
+ src/libtommath/bn_mp_init_multi.o \
+ src/libtommath/bn_mp_clear.o \
+ src/libtommath/bn_s_mp_sqr.o \
+ src/libtommath/bn_mp_rshd.o \
+ src/libtommath/bn_s_mp_sub.o \
+ src/libtommath/bn_mp_sub.o \
+ src/libtommath/bn_mp_toradix.o \
+ src/libtommath/bn_mp_reduce.o \
+ src/libtommath/bn_mp_prime_is_prime.o \
+ src/libtommath/bn_mp_prime_next_prime.o \
+ src/libtommath/bn_mp_exptmod.o \
+ src/libtommath/bn_mp_mod_2d.o \
+ src/libtommath/bn_reverse.o \
+ src/libtommath/bn_mp_init.o \
+ src/libtommath/bn_fast_s_mp_sqr.o \
+ src/libtommath/bn_mp_sqr.o \
+ src/libtommath/bn_mp_cnt_lsb.o \
+ src/libtommath/bn_mp_clear_multi.o \
+ src/libtommath/bn_mp_exch.o \
+ src/libtommath/bn_fast_s_mp_mul_digs.o \
+ src/libtommath/bn_mp_grow.o \
+ src/libtommath/bn_mp_read_radix.o \
+ src/libtommath/bn_mp_mul_2.o \
+ src/libtommath/bn_mp_shrink.o \
+ src/libtommath/bn_mp_div_2.o \
+ src/libtommath/bn_fast_mp_invmod.o \
+ src/libtommath/bn_mp_prime_miller_rabin.o \
+ src/libtommath/bn_mp_to_unsigned_bin.o \
+ src/libtommath/bn_mp_prime_rabin_miller_trials.o \
+ src/libtommath/bn_mp_2expt.o \
+ src/libtommath/bn_mp_cmp_mag.o \
+ src/libtommath/bn_mp_to_signed_bin.o \
+ src/libtommath/bn_mp_get_int.o \
+ src/libtommath/bn_mp_montgomery_reduce.o \
+ src/libtommath/bn_mp_dr_reduce.o \
+ src/libtommath/bn_mp_fwrite.o \
+ src/libtommath/bn_mp_and.o \
+ src/libtommath/bn_mp_exteuclid.o \
+ src/libtommath/bn_fast_mp_montgomery_reduce.o \
+ src/libtommath/bn_s_mp_mul_high_digs.o \
+ src/libtommath/bn_mp_reduce_setup.o \
+ src/libtommath/bn_mp_lcm.o \
+ src/libtommath/bn_mp_abs.o \
+ src/libtommath/bn_mp_cmp.o \
+ src/libtommath/bn_mp_submod.o \
+ src/libtommath/bn_mp_div_d.o \
+ src/libtommath/bn_s_mp_mul_digs.o \
+ src/libtommath/bn_mp_mul_d.o \
+ src/libtommath/bn_mp_to_unsigned_bin_n.o \
+ src/libtommath/bn_mp_prime_random_ex.o \
+ src/libtommath/bn_mp_rand.o \
+ src/libtommath/bn_mp_div_2d.o \
+ src/libtommath/bn_mp_addmod.o \
+ src/libtommath/bn_mp_init_copy.o \
+ src/libtommath/bn_mp_read_unsigned_bin.o \
+ src/libtommath/bn_mp_toradix_n.o \
+ src/libtommath/bn_fast_s_mp_mul_high_digs.o \
+ src/libtommath/bn_mp_toom_sqr.o \
+ src/libtommath/bn_mp_to_signed_bin_n.o \
+ src/libtommath/bn_mp_reduce_2k_setup_l.o \
+ src/libtommath/bn_mp_div.o \
+ src/libtommath/bn_prime_tab.o \
+ src/libtommath/bn_mp_karatsuba_sqr.o \
+ src/libtommath/bn_mp_gcd.o \
+ src/libtommath/bn_mp_prime_is_divisible.o \
+ src/libtommath/bn_mp_set_int.o \
+ src/libtommath/bn_mp_prime_fermat.o \
+ src/libtommath/bn_mp_cmp_d.o \
+ src/libtommath/bn_mp_add.o \
+ src/libtommath/bn_mp_sub_d.o \
+ src/libtommath/bn_s_mp_exptmod.o \
+ src/libtommath/bn_mp_init_size.o \
+ src/libtommath/bncore.o \
+ src/libtommath/bn_mp_radix_smap.o \
+ src/libtommath/bn_mp_reduce_2k_l.o \
+ src/libtommath/bn_mp_montgomery_calc_normalization.o \
+ src/libtommath/bn_mp_mod_d.o \
+ src/libtommath/bn_mp_set.o \
+ src/libtommath/bn_mp_or.o \
+ src/libtommath/bn_mp_sqrt.o \
+ src/libtommath/bn_mp_invmod_slow.o \
+ src/libtommath/bn_mp_count_bits.o \
+ src/libtommath/bn_mp_read_signed_bin.o \
+ src/libtommath/bn_mp_div_3.o \
+ src/libtommath/bn_mp_unsigned_bin_size.o \
+ src/libtommath/bn_mp_mulmod.o \
+ src/libtommath/bn_mp_clamp.o \
+ src/libtommath/bn_mp_reduce_2k_setup.o \
+ src/libtommath/bn_mp_toom_mul.o \
+ src/libtommath/bn_mp_montgomery_setup.o \
+ src/libtommath/bn_mp_expt_d.o \
+ src/libtommath/bn_mp_copy.o \
+ src/libtommath/bn_mp_dr_is_modulus.o \
+ src/libtommath/bn_mp_sqrmod.o \
+ src/libtommath/bn_mp_reduce_is_2k_l.o \
+ src/libtommath/bn_mp_mul_2d.o \
+ src/libtommath/bn_mp_fread.o \
+ src/libtommath/bn_mp_init_set.o \
+ src/libtommath/bn_mp_add_d.o \
+ src/libtommath/bn_mp_zero.o \
+ src/libtommath/bn_s_mp_add.o \
+ src/libtommath/bn_mp_radix_size.o \
+ src/libtommath/bn_mp_init_set_int.o \
+ src/libtommath/bn_mp_n_root.o \
+ src/libtommath/bn_mp_lshd.o \
+ src/libtommath/bn_mp_reduce_is_2k.o \
+ src/pklib/implode.o \
+ src/pklib/crc32.o \
+ src/pklib/explode.o \
+ src/zlib/crc32.o \
+ src/zlib/trees.o \
+ src/zlib/compress2.o \
+ src/zlib/adler32.o \
+ src/zlib/inftrees.o \
+ src/zlib/inffast.o \
+ src/zlib/deflate.o \
+ src/zlib/inflate.o \
+ src/zlib/zutil.o \
+ src/lzma/C/LzFind.o \
+ src/lzma/C/LzmaEnc.o \
+ src/lzma/C/LzmaDec.o \
+ src/jenkins/lookup3.o
+
+LIB = libStorm.so
+SLIB = libStorm.a
+
+all: $(OBJS) $(COBJS) $(LIB) $(SLIB)
+
+$(LIB): $(OBJS) $(COBJS)
+ $(C++) $(ARCH) -shared -o $(LIB) $(OBJS) $(COBJS) $(LFLAGS)
+
+$(SLIB): $(OBJS) $(COBJS)
+ $(AR) rcs $(SLIB) $(OBJS) $(COBJS)
+
+clean:
+ rm -f $(OBJS) $(COBJS) $(LIB)
+
+$(OBJS): %.o: %.cpp
+ $(C++) -o $@ $(CFLAGS) -c $<
+
+$(COBJS): %.o: %.c
+ $(CC) -o $@ $(CFLAGS) -c $<
+
+$(LIB): $(OBJS) $(COBJS)
+
+all: $(LIB)
+
+install: $(LIB)
+ install $(LIB) /usr/local/lib
+ mkdir -p /usr/local/include/StormLib
+ cp src/StormLib.h /usr/local/include/StormLib
+ cp src/StormPort.h /usr/local/include/StormLib
+ ldconfig
diff --git a/Makefile.mac b/Makefile.mac
new file mode 100644
index 0000000..0ca7834
--- /dev/null
+++ b/Makefile.mac
@@ -0,0 +1,253 @@
+#####################################################################
+#
+# Makefile for compiling StormLib with g++ on Mac
+#
+# Author: Ladislav Zezula
+# Created: Mon May 10 14:13:00 CEST 2010
+# System: Mac OS X (64bit)
+#
+#####################################################################
+
+CPP = g++
+CC = gcc
+CFLAGS = -Wall
+LFLAGS = -lbz2 -lz -framework Carbon
+ARCH = -arch x86_64
+DFLAGS = -D__SYS_BZLIB -D__SYS_ZLIB -D_7ZIP_ST
+AR = ar
+ARFLAGS= rcs
+
+LIBRARY = libStorm.dylib
+
+OBJS_CPP = src/adpcm/adpcm.obj \
+ src/huffman/huff.obj \
+ src/sparse/sparse.obj \
+ src/FileStream.obj \
+ src/SBaseCommon.o \
+ src/SBaseFileTable.o \
+ src/SCompression.obj \
+ src/SFileAddFile.obj \
+ src/SFileAttributes.obj \
+ src/SFileCompactArchive.obj \
+ src/SFileCreateArchive.obj \
+ src/SFileExtractFile.obj \
+ src/SFileFindFile.obj \
+ src/SFileListFile.obj \
+ src/SFileOpenArchive.obj \
+ src/SFileOpenFileEx.obj \
+ src/SFilePatchArchives.obj \
+ src/SFileReadFile.obj \
+ src/SFileVerify.obj
+
+
+OBJS_C = src/jenkins/lookup3.o \
+ src/libtomcrypt/src/hashes/hash_memory.obj \
+ src/libtomcrypt/src/hashes/md5.obj \
+ src/libtomcrypt/src/hashes/sha1.obj\
+ src/libtomcrypt/src/math/ltm_desc.obj \
+ src/libtomcrypt/src/math/multi.obj \
+ src/libtomcrypt/src/math/rand_prime.obj \
+ src/libtomcrypt/src/misc/base64_decode.obj \
+ src/libtomcrypt/src/misc/crypt_argchk.obj \
+ src/libtomcrypt/src/misc/crypt_find_hash.obj \
+ src/libtomcrypt/src/misc/crypt_find_prng.obj \
+ src/libtomcrypt/src/misc/crypt_hash_descriptor.obj \
+ src/libtomcrypt/src/misc/crypt_hash_is_valid.obj \
+ src/libtomcrypt/src/misc/crypt_libc.obj \
+ src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.obj \
+ src/libtomcrypt/src/misc/crypt_prng_descriptor.obj \
+ src/libtomcrypt/src/misc/crypt_prng_is_valid.obj \
+ src/libtomcrypt/src/misc/crypt_register_hash.obj \
+ src/libtomcrypt/src/misc/crypt_register_prng.obj \
+ src/libtomcrypt/src/misc/zeromem.obj \
+ src/libtomcrypt/src/pk/asn1/der_decode_bit_string.obj \
+ src/libtomcrypt/src/pk/asn1/der_decode_boolean.obj \
+ src/libtomcrypt/src/pk/asn1/der_decode_choice.obj \
+ src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.obj \
+ src/libtomcrypt/src/pk/asn1/der_decode_integer.obj \
+ src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.obj \
+ src/libtomcrypt/src/pk/asn1/der_decode_octet_string.obj \
+ src/libtomcrypt/src/pk/asn1/der_decode_printable_string.obj \
+ src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.obj \
+ src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.obj \
+ src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.obj \
+ src/libtomcrypt/src/pk/asn1/der_decode_short_integer.obj \
+ src/libtomcrypt/src/pk/asn1/der_decode_utctime.obj \
+ src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.obj \
+ src/libtomcrypt/src/pk/asn1/der_length_bit_string.obj \
+ src/libtomcrypt/src/pk/asn1/der_length_boolean.obj \
+ src/libtomcrypt/src/pk/asn1/der_length_ia5_string.obj \
+ src/libtomcrypt/src/pk/asn1/der_length_integer.obj \
+ src/libtomcrypt/src/pk/asn1/der_length_object_identifier.obj \
+ src/libtomcrypt/src/pk/asn1/der_length_octet_string.obj \
+ src/libtomcrypt/src/pk/asn1/der_length_printable_string.obj \
+ src/libtomcrypt/src/pk/asn1/der_length_sequence.obj \
+ src/libtomcrypt/src/pk/asn1/der_length_short_integer.obj \
+
+ src/libtomcrypt/src/pk/asn1/der_length_utctime.obj \
+
+ src/libtomcrypt/src/pk/asn1/der_length_utf8_string.obj \
+
+ src/libtomcrypt/src/pk/asn1/der_sequence_free.obj \
+
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_map.obj \
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.obj \
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.obj \
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_points.obj \
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.obj \
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.obj \
+ src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.obj \
+ src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.obj \
+ src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.obj \
+ src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.obj \
+ src/libtomcrypt/src/pk/rsa/rsa_exptmod.obj \
+ src/libtomcrypt/src/pk/rsa/rsa_free.obj \
+ src/libtomcrypt/src/pk/rsa/rsa_import.obj \
+ src/libtomcrypt/src/pk/rsa/rsa_make_key.obj \
+ src/libtomcrypt/src/pk/rsa/rsa_verify_hash.obj \
+ src/libtomcrypt/src/pk/rsa/rsa_verify_simple.obj \
+ src/libtommath/bncore.obj \
+ src/libtommath/bn_fast_mp_invmod.obj \
+ src/libtommath/bn_fast_mp_montgomery_reduce.obj \
+ src/libtommath/bn_fast_s_mp_mul_digs.obj \
+ src/libtommath/bn_fast_s_mp_mul_high_digs.obj \
+ src/libtommath/bn_fast_s_mp_sqr.obj \
+ src/libtommath/bn_mp_2expt.obj \
+ src/libtommath/bn_mp_abs.obj \
+ src/libtommath/bn_mp_add.obj \
+ src/libtommath/bn_mp_addmod.obj \
+ src/libtommath/bn_mp_add_d.obj \
+ src/libtommath/bn_mp_and.obj \
+ src/libtommath/bn_mp_clamp.obj \
+ src/libtommath/bn_mp_clear.obj \
+ src/libtommath/bn_mp_clear_multi.obj \
+ src/libtommath/bn_mp_cmp.obj \
+ src/libtommath/bn_mp_cmp_d.obj \
+ src/libtommath/bn_mp_cmp_mag.obj \
+ src/libtommath/bn_mp_cnt_lsb.obj \
+ src/libtommath/bn_mp_copy.obj \
+ src/libtommath/bn_mp_count_bits.obj \
+ src/libtommath/bn_mp_div.obj \
+ src/libtommath/bn_mp_div_2.obj \
+ src/libtommath/bn_mp_div_2d.obj \
+ src/libtommath/bn_mp_div_3.obj \
+ src/libtommath/bn_mp_div_d.obj \
+ src/libtommath/bn_mp_dr_is_modulus.obj \
+ src/libtommath/bn_mp_dr_reduce.obj \
+ src/libtommath/bn_mp_dr_setup.obj \
+ src/libtommath/bn_mp_exch.obj \
+ src/libtommath/bn_mp_exptmod.obj \
+ src/libtommath/bn_mp_exptmod_fast.obj \
+ src/libtommath/bn_mp_expt_d.obj \
+ src/libtommath/bn_mp_exteuclid.obj \
+ src/libtommath/bn_mp_fread.obj \
+ src/libtommath/bn_mp_fwrite.obj \
+ src/libtommath/bn_mp_gcd.obj \
+ src/libtommath/bn_mp_get_int.obj \
+ src/libtommath/bn_mp_grow.obj \
+ src/libtommath/bn_mp_init.obj \
+ src/libtommath/bn_mp_init_copy.obj \
+ src/libtommath/bn_mp_init_multi.obj \
+ src/libtommath/bn_mp_init_set.obj \
+ src/libtommath/bn_mp_init_set_int.obj \
+ src/libtommath/bn_mp_init_size.obj \
+ src/libtommath/bn_mp_invmod.obj \
+ src/libtommath/bn_mp_invmod_slow.obj \
+ src/libtommath/bn_mp_is_square.obj \
+ src/libtommath/bn_mp_jacobi.obj \
+ src/libtommath/bn_mp_karatsuba_mul.obj \
+ src/libtommath/bn_mp_karatsuba_sqr.obj \
+ src/libtommath/bn_mp_lcm.obj \
+ src/libtommath/bn_mp_lshd.obj \
+ src/libtommath/bn_mp_mod.obj \
+ src/libtommath/bn_mp_mod_2d.obj \
+ src/libtommath/bn_mp_mod_d.obj \
+ src/libtommath/bn_mp_montgomery_calc_normalization.obj \
+ src/libtommath/bn_mp_montgomery_reduce.obj \
+ src/libtommath/bn_mp_montgomery_setup.obj \
+ src/libtommath/bn_mp_mul.obj \
+ src/libtommath/bn_mp_mulmod.obj \
+ src/libtommath/bn_mp_mul_2.obj \
+ src/libtommath/bn_mp_mul_2d.obj \
+ src/libtommath/bn_mp_mul_d.obj \
+ src/libtommath/bn_mp_neg.obj \
+ src/libtommath/bn_mp_n_root.obj \
+ src/libtommath/bn_mp_or.obj \
+ src/libtommath/bn_mp_prime_fermat.obj \
+ src/libtommath/bn_mp_prime_is_divisible.obj \
+ src/libtommath/bn_mp_prime_is_prime.obj \
+ src/libtommath/bn_mp_prime_miller_rabin.obj \
+ src/libtommath/bn_mp_prime_next_prime.obj \
+ src/libtommath/bn_mp_prime_rabin_miller_trials.obj \
+ src/libtommath/bn_mp_prime_random_ex.obj \
+ src/libtommath/bn_mp_radix_size.obj \
+ src/libtommath/bn_mp_radix_smap.obj \
+ src/libtommath/bn_mp_rand.obj \
+ src/libtommath/bn_mp_read_radix.obj \
+ src/libtommath/bn_mp_read_signed_bin.obj \
+ src/libtommath/bn_mp_read_unsigned_bin.obj \
+ src/libtommath/bn_mp_reduce.obj \
+ src/libtommath/bn_mp_reduce_2k.obj \
+ src/libtommath/bn_mp_reduce_2k_l.obj \
+ src/libtommath/bn_mp_reduce_2k_setup.obj \
+ src/libtommath/bn_mp_reduce_2k_setup_l.obj \
+ src/libtommath/bn_mp_reduce_is_2k.obj \
+ src/libtommath/bn_mp_reduce_is_2k_l.obj \
+ src/libtommath/bn_mp_reduce_setup.obj \
+ src/libtommath/bn_mp_rshd.obj \
+ src/libtommath/bn_mp_set.obj \
+ src/libtommath/bn_mp_set_int.obj \
+ src/libtommath/bn_mp_shrink.obj \
+ src/libtommath/bn_mp_signed_bin_size.obj \
+ src/libtommath/bn_mp_sqr.obj \
+ src/libtommath/bn_mp_sqrmod.obj \
+ src/libtommath/bn_mp_sqrt.obj \
+ src/libtommath/bn_mp_sub.obj \
+ src/libtommath/bn_mp_submod.obj \
+ src/libtommath/bn_mp_sub_d.obj \
+ src/libtommath/bn_mp_toom_mul.obj \
+ src/libtommath/bn_mp_toom_sqr.obj \
+ src/libtommath/bn_mp_toradix.obj \
+ src/libtommath/bn_mp_toradix_n.obj \
+ src/libtommath/bn_mp_to_signed_bin.obj \
+ src/libtommath/bn_mp_to_signed_bin_n.obj \
+ src/libtommath/bn_mp_to_unsigned_bin.obj \
+ src/libtommath/bn_mp_to_unsigned_bin_n.obj \
+ src/libtommath/bn_mp_unsigned_bin_size.obj \
+ src/libtommath/bn_mp_xor.obj \
+ src/libtommath/bn_mp_zero.obj \
+ src/libtommath/bn_prime_tab.obj \
+ src/libtommath/bn_reverse.obj \
+ src/libtommath/bn_s_mp_add.obj \
+ src/libtommath/bn_s_mp_exptmod.obj \
+ src/libtommath/bn_s_mp_mul_digs.obj \
+ src/libtommath/bn_s_mp_mul_high_digs.obj \
+ src/libtommath/bn_s_mp_sqr.obj \
+ src/libtommath/bn_s_mp_sub.obj \
+ src/lzma/C/LzFind.obj \
+ src/lzma/C/LzmaDec.obj \
+ src/lzma/C/LzmaEnc.obj \
+ src/pklib/explode.obj \
+ src/pklib/implode.obj
+
+all: $(LIBRARY)
+
+#clean:
+# rm -f $(OBJS) $(LIBRARY)
+
+#install: $(LIBRARY)
+# install $(LIBRARY) /usr/local/lib
+# mkdir -p /usr/local/include/StormLib
+# cp StormLib.h /usr/local/include/StormLib
+# cp StormPort.h /usr/local/include/StormLib
+
+$(LIBRARY): $(OBJS_C) $(OBJS_CPP)
+ $(CPP) $(CFLAGS) $(DFLAGS) $(ARCH) $(LFLAGS) -shared -o $(LIBRARY) $(OBJS_C) $(OBJS_CPP)
+# $(AR) $(ARFLAGS) $(LIBRARY) $(OBJS_C) $(OBJS_CPP)
+
+$(OBJS_C): %.obj: %.c
+ $(CC) -o $@ $(CFLAGS) $(DFLAGS) -c $<
+
+$(OBJS_CPP): %.obj: %.cpp
+ $(CC) -o $@ $(CFLAGS) $(DFLAGS) -c $<
+
diff --git a/Publish.bat b/Publish.bat
new file mode 100644
index 0000000..59db0b1
--- /dev/null
+++ b/Publish.bat
@@ -0,0 +1,22 @@
+@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
+
+echo Creating stormlib.zip ...
+cd \Ladik\Appdir
+zip.exe -ur9 ..\WWW\web\download\stormlib.zip StormLib\doc\*
+zip.exe -ur9 ..\WWW\web\download\stormlib.zip StormLib\src\*
+zip.exe -ur9 ..\WWW\web\download\stormlib.zip StormLib\storm_dll\*
+zip.exe -ur9 ..\WWW\web\download\stormlib.zip StormLib\StormLib.xcodeproj\*
+zip.exe -ur9 ..\WWW\web\download\stormlib.zip StormLib\stormlib_dll\*
+zip.exe -ur9 ..\WWW\web\download\stormlib.zip StormLib\test\*
+zip.exe -u9 ..\WWW\web\download\stormlib.zip StormLib\CMakeLists.txt
+zip.exe -u9 ..\WWW\web\download\stormlib.zip StormLib\makefile.*
+zip.exe -u9 ..\WWW\web\download\stormlib.zip StormLib\Info.plist
+zip.exe -u9 ..\WWW\web\download\stormlib.zip StormLib\*.bat
+zip.exe -u9 ..\WWW\web\download\stormlib.zip StormLib\*.sln
+zip.exe -u9 ..\WWW\web\download\stormlib.zip StormLib\*.vcproj
+echo.
+
+echo Press any key to exit ...
+pause >nul
diff --git a/Publish_beta.bat b/Publish_beta.bat
new file mode 100644
index 0000000..380ea1c
--- /dev/null
+++ b/Publish_beta.bat
@@ -0,0 +1,22 @@
+@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
+
+echo Creating stormlib_beta.zip ...
+cd \Ladik\Appdir
+zip.exe -ur9 ..\WWW\web\download\stormlib_beta.zip StormLib\doc\*
+zip.exe -ur9 ..\WWW\web\download\stormlib_beta.zip StormLib\src\*
+zip.exe -ur9 ..\WWW\web\download\stormlib_beta.zip StormLib\storm_dll\*
+zip.exe -ur9 ..\WWW\web\download\stormlib_beta.zip StormLib\StormLib.xcodeproj\*
+zip.exe -ur9 ..\WWW\web\download\stormlib_beta.zip StormLib\stormlib_dll\*
+zip.exe -ur9 ..\WWW\web\download\stormlib_beta.zip StormLib\test\*
+zip.exe -u9 ..\WWW\web\download\stormlib_beta.zip StormLib\CMakeLists.txt
+zip.exe -u9 ..\WWW\web\download\stormlib_beta.zip StormLib\makefile.*
+zip.exe -u9 ..\WWW\web\download\stormlib_beta.zip StormLib\Info.plist
+zip.exe -u9 ..\WWW\web\download\stormlib_beta.zip StormLib\*.bat
+zip.exe -u9 ..\WWW\web\download\stormlib_beta.zip StormLib\*.sln
+zip.exe -u9 ..\WWW\web\download\stormlib_beta.zip StormLib\*.vcproj
+echo.
+
+echo Press any key to exit ...
+pause >nul
diff --git a/README b/README
new file mode 100644
index 0000000..332ea35
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+This is the sources of StomLib library, an open-source project that can extract and add data from/to Blizzard MPQ archives. \ No newline at end of file
diff --git a/Storm.lib b/Storm.lib
new file mode 100644
index 0000000..6ff47b1
--- /dev/null
+++ b/Storm.lib
Binary files differ
diff --git a/StormLib.bat b/StormLib.bat
new file mode 100644
index 0000000..5228a26
--- /dev/null
+++ b/StormLib.bat
@@ -0,0 +1,22 @@
+@echo off
+rem Post-build batch for StormLib project
+rem Called as StormLib.bat $(PlatformName) $(ConfigurationName)
+rem Example: StormLib.bat x64 Debug
+
+copy src\StormPort.h ..\aaa\inc
+copy src\StormLib.h ..\aaa\inc
+
+if x%1 == xWin32 goto PlatformWin32
+if x%1 == xx64 goto PlatformWin64
+goto exit
+
+:PlatformWin32
+copy .\bin\Stormlib\%1\%2\*.lib ..\aaa\lib32
+goto exit
+
+:PlatformWin64
+copy .\bin\Stormlib\%1\%2\*.lib ..\aaa\lib64
+goto exit
+
+:exit
+
diff --git a/StormLib.kdev4 b/StormLib.kdev4
new file mode 100644
index 0000000..c9a6ab5
--- /dev/null
+++ b/StormLib.kdev4
@@ -0,0 +1,3 @@
+[Project]
+Manager=KDevCMakeManager
+Name=StormLib
diff --git a/StormLib.sln b/StormLib.sln
new file mode 100644
index 0000000..758f29c
--- /dev/null
+++ b/StormLib.sln
@@ -0,0 +1,140 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib", "StormLib.vcproj", "{78424708-1F6E-4D4B-920C-FB6D26847055}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib_dll", "StormLib_dll.vcproj", "{CB385198-50B1-4CF4-883B-11F042DED6AA}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib_test", "StormLib_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
+ {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
+ {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
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/StormLib.vcproj b/StormLib.vcproj
new file mode 100644
index 0000000..cccd638
--- /dev/null
+++ b/StormLib.vcproj
@@ -0,0 +1,21605 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="StormLib"
+ ProjectGUID="{78424708-1F6E-4D4B-920C-FB6D26847055}"
+ RootNamespace="StormLib"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="DebugAD|Win32"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)DAD.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="StormLib.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ <Configuration
+ Name="DebugAD|x64"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)DAD.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="StormLib.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ <Configuration
+ Name="DebugAS|Win32"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)DAS.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="StormLib.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ <Configuration
+ Name="DebugAS|x64"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)DAS.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="StormLib.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseAD|Win32"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)RAD.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="StormLib.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseAD|x64"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)RAD.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="StormLib.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseAS|Win32"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)RAS.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="StormLib.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseAS|x64"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)RAS.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="StormLib.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ <Configuration
+ Name="DebugUD|Win32"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)DUD.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="StormLib.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ <Configuration
+ Name="DebugUD|x64"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)DUD.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="StormLib.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ <Configuration
+ Name="DebugUS|Win32"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)DUS.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="StormLib.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ <Configuration
+ Name="DebugUS|x64"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)DUS.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="StormLib.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseUD|Win32"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)RUD.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="StormLib.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseUD|x64"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)RUD.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="StormLib.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseUS|Win32"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)RUS.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="StormLib.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseUS|x64"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)RUS.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="StormLib.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Doc Files"
+ >
+ <File
+ RelativePath=".\doc\History.txt"
+ >
+ </File>
+ <File
+ RelativePath=".\doc\The MoPaQ File Format 0.9.txt"
+ >
+ </File>
+ <File
+ RelativePath=".\doc\The MoPaQ File Format 1.0.txt"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ >
+ <File
+ RelativePath=".\src\StormCommon.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\StormLib.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\StormPort.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Source Files"
+ >
+ <File
+ RelativePath=".\src\FileStream.cpp"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SBaseCommon.cpp"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SBaseFileTable.cpp"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SCompression.cpp"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileAddFile.cpp"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileAttributes.cpp"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileCompactArchive.cpp"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileCreateArchive.cpp"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileExtractFile.cpp"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileFindFile.cpp"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileListFile.cpp"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileOpenArchive.cpp"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileOpenFileEx.cpp"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFilePatchArchives.cpp"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileReadFile.cpp"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileVerify.cpp"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StormCommon.h"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <Filter
+ Name="adpcm"
+ >
+ <File
+ RelativePath=".\src\adpcm\adpcm.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\src\adpcm\adpcm.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="bzip2"
+ >
+ <File
+ RelativePath=".\src\bzip2\blocksort.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\bzlib.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\compress.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\crctable.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\decompress.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\huffman.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\randtable.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="huffman"
+ >
+ <File
+ RelativePath=".\src\huffman\huff.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\src\huffman\huff.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="libtomcrypt"
+ >
+ <Filter
+ Name="hashes"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\hashes\hash_memory.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\hashes\md5.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\hashes\sha1.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="math"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\math\ltm_desc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\math\multi.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\math\rand_prime.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="misc"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\base64_decode.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_argchk.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_find_hash.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_find_prng.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_hash_descriptor.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_hash_is_valid.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_libc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_ltc_mp_descriptor.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_prng_descriptor.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_prng_is_valid.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_register_hash.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_register_prng.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\zeromem.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="pk"
+ >
+ <Filter
+ Name="asn1"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_bit_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_boolean.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_choice.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_ia5_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_integer.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_object_identifier.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_octet_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_printable_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_sequence_ex.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_sequence_flexi.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_sequence_multi.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_short_integer.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_utctime.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_utf8_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_bit_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_boolean.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_ia5_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_integer.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_object_identifier.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_octet_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_printable_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_sequence.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_short_integer.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_utctime.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_utf8_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_sequence_free.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="ecc"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_map.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_mul2add.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_mulmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_points.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_add_point.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_dbl_point.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="pkcs1"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\pkcs1\pkcs_1_mgf1.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\pkcs1\pkcs_1_oaep_decode.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_decode.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_decode.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="rsa"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_exptmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_free.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_import.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_make_key.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_verify_hash.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_verify_simple.c"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="libtommath"
+ >
+ <File
+ RelativePath=".\src\libtommath\bn_fast_mp_invmod.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_fast_mp_montgomery_reduce.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_fast_s_mp_mul_digs.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_fast_s_mp_mul_high_digs.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_fast_s_mp_sqr.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_2expt.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_abs.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_add.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_add_d.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_addmod.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_and.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_clamp.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_clear.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_clear_multi.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_cmp.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_cmp_d.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_cmp_mag.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_cnt_lsb.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_copy.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_count_bits.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_div.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_div_2.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_div_2d.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_div_3.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_div_d.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_dr_is_modulus.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_dr_reduce.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_dr_setup.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_exch.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_expt_d.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_exptmod.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_exptmod_fast.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_exteuclid.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_fread.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_fwrite.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_gcd.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_get_int.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_grow.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init_copy.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init_multi.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init_set.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init_set_int.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init_size.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_invmod.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_invmod_slow.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_is_square.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_jacobi.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_karatsuba_mul.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_karatsuba_sqr.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_lcm.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_lshd.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mod.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mod_2d.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mod_d.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_montgomery_calc_normalization.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_montgomery_reduce.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_montgomery_setup.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mul.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mul_2.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mul_2d.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mul_d.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mulmod.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_n_root.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_neg.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_or.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_fermat.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_is_divisible.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_is_prime.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_miller_rabin.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_next_prime.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_rabin_miller_trials.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_random_ex.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_radix_size.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_radix_smap.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_rand.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_read_radix.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_read_signed_bin.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_read_unsigned_bin.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_2k.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_2k_l.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_2k_setup.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_2k_setup_l.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_is_2k.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_is_2k_l.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_setup.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_rshd.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_set.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_set_int.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_shrink.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_signed_bin_size.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_sqr.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_sqrmod.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_sqrt.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_sub.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_sub_d.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_submod.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_to_signed_bin.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_to_signed_bin_n.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_to_unsigned_bin.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_to_unsigned_bin_n.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_toom_mul.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_toom_sqr.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_toradix.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_toradix_n.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_unsigned_bin_size.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_xor.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_zero.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_prime_tab.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_reverse.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_add.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_exptmod.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_mul_digs.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_mul_high_digs.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_sqr.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_sub.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bncore.c"
+ >
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough="tommath.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseUS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderThrough=""
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="lzma"
+ >
+ <File
+ RelativePath=".\src\lzma\C\LzFind.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\lzma\C\LzFindMt.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\lzma\C\LzmaDec.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\lzma\C\LzmaEnc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\lzma\C\Threads.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="pklib"
+ >
+ <File
+ RelativePath=".\src\pklib\explode.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\pklib\implode.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\pklib\pklib.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="sparse"
+ >
+ <File
+ RelativePath=".\src\sparse\sparse.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\src\sparse\sparse.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="zlib"
+ >
+ <File
+ RelativePath=".\src\zlib\adler32.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\compress2.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\crc32.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\deflate.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\inffast.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\inflate.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\inftrees.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\trees.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\zutil.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="jenkins"
+ >
+ <File
+ RelativePath=".\src\jenkins\lookup.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\jenkins\lookup3.c"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/StormLib.xcodeproj/project.pbxproj b/StormLib.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..319e263
--- /dev/null
+++ b/StormLib.xcodeproj/project.pbxproj
@@ -0,0 +1,1992 @@
+// !$*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, ); }; };
+ 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 */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 2229F62E11D4653600118914 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 225530D31056BAC800FA646A;
+ remoteInfo = StormLib;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 221F6A721168529C0026C852 /* LzmaDec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LzmaDec.h; path = C/LzmaDec.h; sourceTree = "<group>"; };
+ 221F6A731168529C0026C852 /* LzmaEnc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LzmaEnc.h; path = C/LzmaEnc.h; sourceTree = "<group>"; };
+ 221F6A7A116852AA0026C852 /* LzmaEnc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = LzmaEnc.c; path = C/LzmaEnc.c; sourceTree = "<group>"; };
+ 221F6A7D116852B20026C852 /* LzmaDec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = LzmaDec.c; path = C/LzmaDec.c; sourceTree = "<group>"; };
+ 221F6AB31168545B0026C852 /* LzFind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = LzFind.c; path = C/LzFind.c; sourceTree = "<group>"; };
+ 221F6AB41168545B0026C852 /* LzFind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LzFind.h; path = C/LzFind.h; sourceTree = "<group>"; };
+ 221F6AB9116854730026C852 /* LzHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LzHash.h; path = C/LzHash.h; sourceTree = "<group>"; };
+ 221F6ABC116854870026C852 /* Types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Types.h; path = C/Types.h; sourceTree = "<group>"; };
+ 2253A19F10568A83001909F9 /* StormLib.exp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.exports; name = StormLib.exp; path = stormlib_dll/StormLib.exp; sourceTree = "<group>"; };
+ 225530D41056BAC800FA646A /* libStormLib.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libStormLib.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ 225C734B1257CCC70009E8DA /* lookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lookup.h; sourceTree = "<group>"; };
+ 225C734C1257CCC70009E8DA /* lookup3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lookup3.c; sourceTree = "<group>"; };
+ 225C73531257CD0C0009E8DA /* SBaseFileTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBaseFileTable.cpp; path = src/SBaseFileTable.cpp; sourceTree = "<group>"; };
+ 225FAC940E53B7F800DA2CAE /* StormLib.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = StormLib.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 225FAC950E53B7F800DA2CAE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 228B538311BF7D0D001A58DA /* FileStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FileStream.cpp; path = src/FileStream.cpp; sourceTree = "<group>"; };
+ 2295488911D45A820064B264 /* Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Test.cpp; path = test/Test.cpp; sourceTree = "<group>"; };
+ 22954ACE11D463A30064B264 /* StormLib_Test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = StormLib_Test; sourceTree = BUILT_PRODUCTS_DIR; };
+ 2299D9D51167EFA8005C19BF /* adpcm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = adpcm.cpp; sourceTree = "<group>"; };
+ 2299D9D61167EFA8005C19BF /* adpcm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = adpcm.h; sourceTree = "<group>"; };
+ 2299D9DC1167EFC6005C19BF /* sparse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sparse.cpp; sourceTree = "<group>"; };
+ 2299D9DD1167EFC6005C19BF /* sparse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sparse.h; sourceTree = "<group>"; };
+ 2299DA4D1167FD16005C19BF /* SFileAddFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileAddFile.cpp; path = src/SFileAddFile.cpp; sourceTree = "<group>"; };
+ 22AEA121123125D800359B16 /* SFilePatchArchives.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFilePatchArchives.cpp; path = src/SFilePatchArchives.cpp; sourceTree = "<group>"; };
+ 22C9182B11933FCF0083AC69 /* hash_memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hash_memory.c; sourceTree = "<group>"; };
+ 22C9182C11933FCF0083AC69 /* md5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = md5.c; sourceTree = "<group>"; };
+ 22C9182D11933FCF0083AC69 /* sha1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sha1.c; sourceTree = "<group>"; };
+ 22C9182F11933FCF0083AC69 /* tomcrypt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt.h; sourceTree = "<group>"; };
+ 22C9183011933FCF0083AC69 /* tomcrypt_argchk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_argchk.h; sourceTree = "<group>"; };
+ 22C9183111933FCF0083AC69 /* tomcrypt_cfg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_cfg.h; sourceTree = "<group>"; };
+ 22C9183211933FCF0083AC69 /* tomcrypt_cipher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_cipher.h; sourceTree = "<group>"; };
+ 22C9183311933FCF0083AC69 /* tomcrypt_custom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_custom.h; sourceTree = "<group>"; };
+ 22C9183411933FCF0083AC69 /* tomcrypt_hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_hash.h; sourceTree = "<group>"; };
+ 22C9183511933FCF0083AC69 /* tomcrypt_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_mac.h; sourceTree = "<group>"; };
+ 22C9183611933FCF0083AC69 /* tomcrypt_macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_macros.h; sourceTree = "<group>"; };
+ 22C9183711933FCF0083AC69 /* tomcrypt_math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_math.h; sourceTree = "<group>"; };
+ 22C9183811933FCF0083AC69 /* tomcrypt_misc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_misc.h; sourceTree = "<group>"; };
+ 22C9183911933FCF0083AC69 /* tomcrypt_pk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_pk.h; sourceTree = "<group>"; };
+ 22C9183A11933FCF0083AC69 /* tomcrypt_pkcs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_pkcs.h; sourceTree = "<group>"; };
+ 22C9183B11933FCF0083AC69 /* tomcrypt_prng.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tomcrypt_prng.h; sourceTree = "<group>"; };
+ 22C9183D11933FCF0083AC69 /* ltm_desc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltm_desc.c; sourceTree = "<group>"; };
+ 22C9183E11933FCF0083AC69 /* multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = multi.c; sourceTree = "<group>"; };
+ 22C9183F11933FCF0083AC69 /* rand_prime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rand_prime.c; sourceTree = "<group>"; };
+ 22C9184111933FCF0083AC69 /* base64_decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = base64_decode.c; sourceTree = "<group>"; };
+ 22C9184211933FCF0083AC69 /* crypt_argchk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_argchk.c; sourceTree = "<group>"; };
+ 22C9184311933FCF0083AC69 /* crypt_find_hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_find_hash.c; sourceTree = "<group>"; };
+ 22C9184411933FCF0083AC69 /* crypt_find_prng.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_find_prng.c; sourceTree = "<group>"; };
+ 22C9184511933FCF0083AC69 /* crypt_hash_descriptor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_hash_descriptor.c; sourceTree = "<group>"; };
+ 22C9184611933FCF0083AC69 /* crypt_hash_is_valid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_hash_is_valid.c; sourceTree = "<group>"; };
+ 22C9184711933FCF0083AC69 /* crypt_libc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_libc.c; sourceTree = "<group>"; };
+ 22C9184811933FCF0083AC69 /* crypt_ltc_mp_descriptor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_ltc_mp_descriptor.c; sourceTree = "<group>"; };
+ 22C9184911933FCF0083AC69 /* crypt_prng_descriptor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_prng_descriptor.c; sourceTree = "<group>"; };
+ 22C9184A11933FCF0083AC69 /* crypt_prng_is_valid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_prng_is_valid.c; sourceTree = "<group>"; };
+ 22C9184B11933FCF0083AC69 /* crypt_register_hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_register_hash.c; sourceTree = "<group>"; };
+ 22C9184C11933FCF0083AC69 /* crypt_register_prng.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypt_register_prng.c; sourceTree = "<group>"; };
+ 22C9184D11933FCF0083AC69 /* zeromem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = zeromem.c; sourceTree = "<group>"; };
+ 22C9185011933FCF0083AC69 /* der_decode_bit_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_bit_string.c; sourceTree = "<group>"; };
+ 22C9185111933FCF0083AC69 /* der_decode_boolean.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_boolean.c; sourceTree = "<group>"; };
+ 22C9185211933FCF0083AC69 /* der_decode_choice.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_choice.c; sourceTree = "<group>"; };
+ 22C9185311933FCF0083AC69 /* der_decode_ia5_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_ia5_string.c; sourceTree = "<group>"; };
+ 22C9185411933FCF0083AC69 /* der_decode_integer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_integer.c; sourceTree = "<group>"; };
+ 22C9185511933FCF0083AC69 /* der_decode_object_identifier.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_object_identifier.c; sourceTree = "<group>"; };
+ 22C9185611933FCF0083AC69 /* der_decode_octet_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_octet_string.c; sourceTree = "<group>"; };
+ 22C9185711933FCF0083AC69 /* der_decode_printable_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_printable_string.c; sourceTree = "<group>"; };
+ 22C9185811933FCF0083AC69 /* der_decode_sequence_ex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_sequence_ex.c; sourceTree = "<group>"; };
+ 22C9185911933FCF0083AC69 /* der_decode_sequence_flexi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_sequence_flexi.c; sourceTree = "<group>"; };
+ 22C9185A11933FCF0083AC69 /* der_decode_sequence_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_sequence_multi.c; sourceTree = "<group>"; };
+ 22C9185B11933FCF0083AC69 /* der_decode_short_integer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_short_integer.c; sourceTree = "<group>"; };
+ 22C9185C11933FCF0083AC69 /* der_decode_utctime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_utctime.c; sourceTree = "<group>"; };
+ 22C9185D11933FCF0083AC69 /* der_decode_utf8_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_decode_utf8_string.c; sourceTree = "<group>"; };
+ 22C9185E11933FCF0083AC69 /* der_length_bit_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_bit_string.c; sourceTree = "<group>"; };
+ 22C9185F11933FCF0083AC69 /* der_length_boolean.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_boolean.c; sourceTree = "<group>"; };
+ 22C9186011933FCF0083AC69 /* der_length_ia5_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_ia5_string.c; sourceTree = "<group>"; };
+ 22C9186111933FCF0083AC69 /* der_length_integer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_integer.c; sourceTree = "<group>"; };
+ 22C9186211933FCF0083AC69 /* der_length_object_identifier.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_object_identifier.c; sourceTree = "<group>"; };
+ 22C9186311933FCF0083AC69 /* der_length_octet_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_octet_string.c; sourceTree = "<group>"; };
+ 22C9186411933FCF0083AC69 /* der_length_printable_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_printable_string.c; sourceTree = "<group>"; };
+ 22C9186511933FCF0083AC69 /* der_length_sequence.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_sequence.c; sourceTree = "<group>"; };
+ 22C9186611933FCF0083AC69 /* der_length_short_integer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_short_integer.c; sourceTree = "<group>"; };
+ 22C9186711933FCF0083AC69 /* der_length_utctime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_utctime.c; sourceTree = "<group>"; };
+ 22C9186811933FCF0083AC69 /* der_length_utf8_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_length_utf8_string.c; sourceTree = "<group>"; };
+ 22C9186911933FCF0083AC69 /* der_sequence_free.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_sequence_free.c; sourceTree = "<group>"; };
+ 22C9186B11933FCF0083AC69 /* ltc_ecc_map.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_map.c; sourceTree = "<group>"; };
+ 22C9186C11933FCF0083AC69 /* ltc_ecc_mul2add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_mul2add.c; sourceTree = "<group>"; };
+ 22C9186D11933FCF0083AC69 /* ltc_ecc_mulmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_mulmod.c; sourceTree = "<group>"; };
+ 22C9186E11933FCF0083AC69 /* ltc_ecc_points.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_points.c; sourceTree = "<group>"; };
+ 22C9186F11933FCF0083AC69 /* ltc_ecc_projective_add_point.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_projective_add_point.c; sourceTree = "<group>"; };
+ 22C9187011933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ltc_ecc_projective_dbl_point.c; sourceTree = "<group>"; };
+ 22C9187211933FCF0083AC69 /* pkcs_1_mgf1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs_1_mgf1.c; sourceTree = "<group>"; };
+ 22C9187311933FCF0083AC69 /* pkcs_1_oaep_decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs_1_oaep_decode.c; sourceTree = "<group>"; };
+ 22C9187411933FCF0083AC69 /* pkcs_1_pss_decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs_1_pss_decode.c; sourceTree = "<group>"; };
+ 22C9187511933FCF0083AC69 /* pkcs_1_v1_5_decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs_1_v1_5_decode.c; sourceTree = "<group>"; };
+ 22C9187711933FCF0083AC69 /* rsa_exptmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_exptmod.c; sourceTree = "<group>"; };
+ 22C9187811933FCF0083AC69 /* rsa_free.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_free.c; sourceTree = "<group>"; };
+ 22C9187911933FCF0083AC69 /* rsa_import.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_import.c; sourceTree = "<group>"; };
+ 22C9187A11933FCF0083AC69 /* rsa_make_key.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_make_key.c; sourceTree = "<group>"; };
+ 22C9187B11933FCF0083AC69 /* rsa_verify_hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_verify_hash.c; sourceTree = "<group>"; };
+ 22C9187C11933FCF0083AC69 /* rsa_verify_simple.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rsa_verify_simple.c; sourceTree = "<group>"; };
+ 22C919111193400A0083AC69 /* bn_fast_mp_invmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_mp_invmod.c; sourceTree = "<group>"; };
+ 22C919121193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_mp_montgomery_reduce.c; sourceTree = "<group>"; };
+ 22C919131193400A0083AC69 /* bn_fast_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_mul_digs.c; sourceTree = "<group>"; };
+ 22C919141193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_mul_high_digs.c; sourceTree = "<group>"; };
+ 22C919151193400A0083AC69 /* bn_fast_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_sqr.c; sourceTree = "<group>"; };
+ 22C919161193400A0083AC69 /* bn_mp_2expt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_2expt.c; sourceTree = "<group>"; };
+ 22C919171193400A0083AC69 /* bn_mp_abs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_abs.c; sourceTree = "<group>"; };
+ 22C919181193400A0083AC69 /* bn_mp_add_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add_d.c; sourceTree = "<group>"; };
+ 22C919191193400A0083AC69 /* bn_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add.c; sourceTree = "<group>"; };
+ 22C9191A1193400A0083AC69 /* bn_mp_addmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_addmod.c; sourceTree = "<group>"; };
+ 22C9191B1193400A0083AC69 /* bn_mp_and.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_and.c; sourceTree = "<group>"; };
+ 22C9191C1193400A0083AC69 /* bn_mp_clamp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clamp.c; sourceTree = "<group>"; };
+ 22C9191D1193400A0083AC69 /* bn_mp_clear_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear_multi.c; sourceTree = "<group>"; };
+ 22C9191E1193400A0083AC69 /* bn_mp_clear.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear.c; sourceTree = "<group>"; };
+ 22C9191F1193400A0083AC69 /* bn_mp_cmp_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_d.c; sourceTree = "<group>"; };
+ 22C919201193400A0083AC69 /* bn_mp_cmp_mag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_mag.c; sourceTree = "<group>"; };
+ 22C919211193400A0083AC69 /* bn_mp_cmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp.c; sourceTree = "<group>"; };
+ 22C919221193400A0083AC69 /* bn_mp_cnt_lsb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cnt_lsb.c; sourceTree = "<group>"; };
+ 22C919231193400A0083AC69 /* bn_mp_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_copy.c; sourceTree = "<group>"; };
+ 22C919241193400A0083AC69 /* bn_mp_count_bits.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_count_bits.c; sourceTree = "<group>"; };
+ 22C919251193400A0083AC69 /* bn_mp_div_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2.c; sourceTree = "<group>"; };
+ 22C919261193400A0083AC69 /* bn_mp_div_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2d.c; sourceTree = "<group>"; };
+ 22C919271193400A0083AC69 /* bn_mp_div_3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_3.c; sourceTree = "<group>"; };
+ 22C919281193400A0083AC69 /* bn_mp_div_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_d.c; sourceTree = "<group>"; };
+ 22C919291193400A0083AC69 /* bn_mp_div.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div.c; sourceTree = "<group>"; };
+ 22C9192A1193400A0083AC69 /* bn_mp_dr_is_modulus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_dr_is_modulus.c; sourceTree = "<group>"; };
+ 22C9192B1193400A0083AC69 /* bn_mp_dr_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_dr_reduce.c; sourceTree = "<group>"; };
+ 22C9192C1193400A0083AC69 /* bn_mp_dr_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_dr_setup.c; sourceTree = "<group>"; };
+ 22C9192D1193400A0083AC69 /* bn_mp_exch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exch.c; sourceTree = "<group>"; };
+ 22C9192E1193400A0083AC69 /* bn_mp_expt_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_expt_d.c; sourceTree = "<group>"; };
+ 22C9192F1193400A0083AC69 /* bn_mp_exptmod_fast.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exptmod_fast.c; sourceTree = "<group>"; };
+ 22C919301193400A0083AC69 /* bn_mp_exptmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exptmod.c; sourceTree = "<group>"; };
+ 22C919311193400A0083AC69 /* bn_mp_exteuclid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exteuclid.c; sourceTree = "<group>"; };
+ 22C919321193400A0083AC69 /* bn_mp_fread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_fread.c; sourceTree = "<group>"; };
+ 22C919331193400A0083AC69 /* bn_mp_fwrite.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_fwrite.c; sourceTree = "<group>"; };
+ 22C919341193400A0083AC69 /* bn_mp_gcd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_gcd.c; sourceTree = "<group>"; };
+ 22C919351193400A0083AC69 /* bn_mp_get_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_get_int.c; sourceTree = "<group>"; };
+ 22C919361193400A0083AC69 /* bn_mp_grow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_grow.c; sourceTree = "<group>"; };
+ 22C919371193400A0083AC69 /* bn_mp_init_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_copy.c; sourceTree = "<group>"; };
+ 22C919381193400A0083AC69 /* bn_mp_init_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_multi.c; sourceTree = "<group>"; };
+ 22C919391193400A0083AC69 /* bn_mp_init_set_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_set_int.c; sourceTree = "<group>"; };
+ 22C9193A1193400A0083AC69 /* bn_mp_init_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_set.c; sourceTree = "<group>"; };
+ 22C9193B1193400A0083AC69 /* bn_mp_init_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_size.c; sourceTree = "<group>"; };
+ 22C9193C1193400A0083AC69 /* bn_mp_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init.c; sourceTree = "<group>"; };
+ 22C9193D1193400A0083AC69 /* bn_mp_invmod_slow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_invmod_slow.c; sourceTree = "<group>"; };
+ 22C9193E1193400A0083AC69 /* bn_mp_invmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_invmod.c; sourceTree = "<group>"; };
+ 22C9193F1193400A0083AC69 /* bn_mp_is_square.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_is_square.c; sourceTree = "<group>"; };
+ 22C919401193400A0083AC69 /* bn_mp_jacobi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_jacobi.c; sourceTree = "<group>"; };
+ 22C919411193400A0083AC69 /* bn_mp_karatsuba_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_mul.c; sourceTree = "<group>"; };
+ 22C919421193400A0083AC69 /* bn_mp_karatsuba_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_sqr.c; sourceTree = "<group>"; };
+ 22C919431193400A0083AC69 /* bn_mp_lcm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_lcm.c; sourceTree = "<group>"; };
+ 22C919441193400A0083AC69 /* bn_mp_lshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_lshd.c; sourceTree = "<group>"; };
+ 22C919451193400A0083AC69 /* bn_mp_mod_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod_2d.c; sourceTree = "<group>"; };
+ 22C919461193400A0083AC69 /* bn_mp_mod_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod_d.c; sourceTree = "<group>"; };
+ 22C919471193400A0083AC69 /* bn_mp_mod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod.c; sourceTree = "<group>"; };
+ 22C919481193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_montgomery_calc_normalization.c; sourceTree = "<group>"; };
+ 22C919491193400A0083AC69 /* bn_mp_montgomery_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_montgomery_reduce.c; sourceTree = "<group>"; };
+ 22C9194A1193400A0083AC69 /* bn_mp_montgomery_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_montgomery_setup.c; sourceTree = "<group>"; };
+ 22C9194B1193400A0083AC69 /* bn_mp_mul_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2.c; sourceTree = "<group>"; };
+ 22C9194C1193400A0083AC69 /* bn_mp_mul_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2d.c; sourceTree = "<group>"; };
+ 22C9194D1193400A0083AC69 /* bn_mp_mul_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_d.c; sourceTree = "<group>"; };
+ 22C9194E1193400A0083AC69 /* bn_mp_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul.c; sourceTree = "<group>"; };
+ 22C9194F1193400A0083AC69 /* bn_mp_mulmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mulmod.c; sourceTree = "<group>"; };
+ 22C919501193400A0083AC69 /* bn_mp_n_root.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_n_root.c; sourceTree = "<group>"; };
+ 22C919511193400A0083AC69 /* bn_mp_neg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_neg.c; sourceTree = "<group>"; };
+ 22C919521193400A0083AC69 /* bn_mp_or.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_or.c; sourceTree = "<group>"; };
+ 22C919531193400A0083AC69 /* bn_mp_prime_fermat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_fermat.c; sourceTree = "<group>"; };
+ 22C919541193400A0083AC69 /* bn_mp_prime_is_divisible.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_is_divisible.c; sourceTree = "<group>"; };
+ 22C919551193400A0083AC69 /* bn_mp_prime_is_prime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_is_prime.c; sourceTree = "<group>"; };
+ 22C919561193400A0083AC69 /* bn_mp_prime_miller_rabin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_miller_rabin.c; sourceTree = "<group>"; };
+ 22C919571193400A0083AC69 /* bn_mp_prime_next_prime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_next_prime.c; sourceTree = "<group>"; };
+ 22C919581193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_rabin_miller_trials.c; sourceTree = "<group>"; };
+ 22C919591193400A0083AC69 /* bn_mp_prime_random_ex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_prime_random_ex.c; sourceTree = "<group>"; };
+ 22C9195A1193400A0083AC69 /* bn_mp_radix_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_size.c; sourceTree = "<group>"; };
+ 22C9195B1193400A0083AC69 /* bn_mp_radix_smap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_smap.c; sourceTree = "<group>"; };
+ 22C9195C1193400A0083AC69 /* bn_mp_rand.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_rand.c; sourceTree = "<group>"; };
+ 22C9195D1193400A0083AC69 /* bn_mp_read_radix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_radix.c; sourceTree = "<group>"; };
+ 22C9195E1193400A0083AC69 /* bn_mp_read_signed_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_signed_bin.c; sourceTree = "<group>"; };
+ 22C9195F1193400A0083AC69 /* bn_mp_read_unsigned_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_unsigned_bin.c; sourceTree = "<group>"; };
+ 22C919601193400A0083AC69 /* bn_mp_reduce_2k_l.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k_l.c; sourceTree = "<group>"; };
+ 22C919611193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k_setup_l.c; sourceTree = "<group>"; };
+ 22C919621193400A0083AC69 /* bn_mp_reduce_2k_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k_setup.c; sourceTree = "<group>"; };
+ 22C919631193400A0083AC69 /* bn_mp_reduce_2k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_2k.c; sourceTree = "<group>"; };
+ 22C919641193400A0083AC69 /* bn_mp_reduce_is_2k_l.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_is_2k_l.c; sourceTree = "<group>"; };
+ 22C919651193400A0083AC69 /* bn_mp_reduce_is_2k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_is_2k.c; sourceTree = "<group>"; };
+ 22C919661193400A0083AC69 /* bn_mp_reduce_setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce_setup.c; sourceTree = "<group>"; };
+ 22C919671193400A0083AC69 /* bn_mp_reduce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_reduce.c; sourceTree = "<group>"; };
+ 22C919681193400A0083AC69 /* bn_mp_rshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_rshd.c; sourceTree = "<group>"; };
+ 22C919691193400A0083AC69 /* bn_mp_set_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_set_int.c; sourceTree = "<group>"; };
+ 22C9196A1193400A0083AC69 /* bn_mp_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_set.c; sourceTree = "<group>"; };
+ 22C9196B1193400A0083AC69 /* bn_mp_shrink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_shrink.c; sourceTree = "<group>"; };
+ 22C9196C1193400A0083AC69 /* bn_mp_signed_bin_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_signed_bin_size.c; sourceTree = "<group>"; };
+ 22C9196D1193400A0083AC69 /* bn_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqr.c; sourceTree = "<group>"; };
+ 22C9196E1193400A0083AC69 /* bn_mp_sqrmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqrmod.c; sourceTree = "<group>"; };
+ 22C9196F1193400A0083AC69 /* bn_mp_sqrt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqrt.c; sourceTree = "<group>"; };
+ 22C919701193400A0083AC69 /* bn_mp_sub_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub_d.c; sourceTree = "<group>"; };
+ 22C919711193400A0083AC69 /* bn_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub.c; sourceTree = "<group>"; };
+ 22C919721193400A0083AC69 /* bn_mp_submod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_submod.c; sourceTree = "<group>"; };
+ 22C919731193400A0083AC69 /* bn_mp_to_signed_bin_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_signed_bin_n.c; sourceTree = "<group>"; };
+ 22C919741193400A0083AC69 /* bn_mp_to_signed_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_signed_bin.c; sourceTree = "<group>"; };
+ 22C919751193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin_n.c; sourceTree = "<group>"; };
+ 22C919761193400A0083AC69 /* bn_mp_to_unsigned_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin.c; sourceTree = "<group>"; };
+ 22C919771193400A0083AC69 /* bn_mp_toom_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_mul.c; sourceTree = "<group>"; };
+ 22C919781193400A0083AC69 /* bn_mp_toom_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_sqr.c; sourceTree = "<group>"; };
+ 22C919791193400A0083AC69 /* bn_mp_toradix_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toradix_n.c; sourceTree = "<group>"; };
+ 22C9197A1193400A0083AC69 /* bn_mp_toradix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toradix.c; sourceTree = "<group>"; };
+ 22C9197B1193400A0083AC69 /* bn_mp_unsigned_bin_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_unsigned_bin_size.c; sourceTree = "<group>"; };
+ 22C9197C1193400A0083AC69 /* bn_mp_xor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_xor.c; sourceTree = "<group>"; };
+ 22C9197D1193400A0083AC69 /* bn_mp_zero.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_zero.c; sourceTree = "<group>"; };
+ 22C9197E1193400A0083AC69 /* bn_prime_tab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_prime_tab.c; sourceTree = "<group>"; };
+ 22C9197F1193400A0083AC69 /* bn_reverse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_reverse.c; sourceTree = "<group>"; };
+ 22C919801193400A0083AC69 /* bn_s_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_add.c; sourceTree = "<group>"; };
+ 22C919811193400A0083AC69 /* bn_s_mp_exptmod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_exptmod.c; sourceTree = "<group>"; };
+ 22C919821193400A0083AC69 /* bn_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_mul_digs.c; sourceTree = "<group>"; };
+ 22C919831193400A0083AC69 /* bn_s_mp_mul_high_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_mul_high_digs.c; sourceTree = "<group>"; };
+ 22C919841193400A0083AC69 /* bn_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sqr.c; sourceTree = "<group>"; };
+ 22C919851193400A0083AC69 /* bn_s_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sub.c; sourceTree = "<group>"; };
+ 22C919861193400A0083AC69 /* bncore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bncore.c; sourceTree = "<group>"; };
+ 22C919871193400A0083AC69 /* tommath_class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_class.h; sourceTree = "<group>"; };
+ 22C919881193400A0083AC69 /* tommath_superclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_superclass.h; sourceTree = "<group>"; };
+ 22C919891193400A0083AC69 /* tommath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath.h; sourceTree = "<group>"; };
+ 22EC6043154B28A000679228 /* FileStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FileStream.h; path = src/FileStream.h; sourceTree = "<group>"; };
+ 22F5A9C41193DFBA00F8B121 /* SFileVerify.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileVerify.cpp; path = src/SFileVerify.cpp; sourceTree = "<group>"; };
+ 32D20A8A0CF3902D00230E7A /* libbz2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbz2.dylib; path = /usr/lib/libbz2.dylib; sourceTree = "<absolute>"; };
+ 32D20A8B0CF3902D00230E7A /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
+ 32ED009C0D03542A00AB0B4E /* huff.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = huff.cpp; sourceTree = "<group>"; };
+ 32ED009D0D03542A00AB0B4E /* huff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = huff.h; sourceTree = "<group>"; };
+ 32ED00A60D03542A00AB0B4E /* explode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = explode.c; sourceTree = "<group>"; };
+ 32ED00A70D03542A00AB0B4E /* implode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = implode.c; sourceTree = "<group>"; };
+ 32ED00A80D03542A00AB0B4E /* pklib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pklib.h; sourceTree = "<group>"; };
+ 32ED00A90D03542A00AB0B4E /* SFileAttributes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileAttributes.cpp; path = src/SFileAttributes.cpp; sourceTree = "<group>"; };
+ 32ED00AA0D03542A00AB0B4E /* SBaseCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBaseCommon.cpp; path = src/SBaseCommon.cpp; sourceTree = "<group>"; };
+ 32ED00AB0D03542A00AB0B4E /* StormCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StormCommon.h; path = src/StormCommon.h; sourceTree = "<group>"; };
+ 32ED00AC0D03542A00AB0B4E /* SCompression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SCompression.cpp; path = src/SCompression.cpp; sourceTree = "<group>"; };
+ 32ED00AD0D03542A00AB0B4E /* SFileCompactArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileCompactArchive.cpp; path = src/SFileCompactArchive.cpp; sourceTree = "<group>"; };
+ 32ED00AE0D03542A00AB0B4E /* SFileCreateArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileCreateArchive.cpp; path = src/SFileCreateArchive.cpp; sourceTree = "<group>"; };
+ 32ED00AF0D03542A00AB0B4E /* SFileExtractFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileExtractFile.cpp; path = src/SFileExtractFile.cpp; sourceTree = "<group>"; };
+ 32ED00B00D03542A00AB0B4E /* SFileFindFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileFindFile.cpp; path = src/SFileFindFile.cpp; sourceTree = "<group>"; };
+ 32ED00B10D03542A00AB0B4E /* SFileOpenArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileOpenArchive.cpp; path = src/SFileOpenArchive.cpp; sourceTree = "<group>"; };
+ 32ED00B20D03542A00AB0B4E /* SFileOpenFileEx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileOpenFileEx.cpp; path = src/SFileOpenFileEx.cpp; sourceTree = "<group>"; };
+ 32ED00B30D03542A00AB0B4E /* SFileReadFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileReadFile.cpp; path = src/SFileReadFile.cpp; sourceTree = "<group>"; };
+ 32ED00B40D03542A00AB0B4E /* SFileListFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SFileListFile.cpp; path = src/SFileListFile.cpp; sourceTree = "<group>"; };
+ 32ED00B60D03542A00AB0B4E /* StormLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StormLib.h; path = src/StormLib.h; sourceTree = "<group>"; };
+ 32ED00B70D03542A00AB0B4E /* StormPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StormPort.h; path = src/StormPort.h; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 225530D21056BAC800FA646A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 225FAC920E53B7F800DA2CAE /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 225FADD40E53C06600DA2CAE /* libbz2.dylib in Frameworks */,
+ 225FADD50E53C06600DA2CAE /* libz.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 22954ACC11D463A30064B264 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 22954AD611D463BE0064B264 /* libbz2.dylib in Frameworks */,
+ 22954AD711D463BE0064B264 /* libz.dylib in Frameworks */,
+ 22954AD311D463B50064B264 /* libStormLib.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 034768DDFF38A45A11DB9C8B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 225FAC940E53B7F800DA2CAE /* StormLib.framework */,
+ 225530D41056BAC800FA646A /* libStormLib.a */,
+ 22954ACE11D463A30064B264 /* StormLib_Test */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 0867D691FE84028FC02AAC07 /* stormlib */ = {
+ isa = PBXGroup;
+ children = (
+ 32DBEE830D00E58F00DB1E81 /* Source */,
+ 2295488711D45A520064B264 /* Test */,
+ 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */,
+ 22B54B321054B287001D6436 /* Resources */,
+ 034768DDFF38A45A11DB9C8B /* Products */,
+ 2253A19F10568A83001909F9 /* StormLib.exp */,
+ );
+ name = stormlib;
+ sourceTree = "<group>";
+ };
+ 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = {
+ isa = PBXGroup;
+ children = (
+ 32D20A8A0CF3902D00230E7A /* libbz2.dylib */,
+ 32D20A8B0CF3902D00230E7A /* libz.dylib */,
+ );
+ name = "External Frameworks and Libraries";
+ sourceTree = "<group>";
+ };
+ 221F652D116851D70026C852 /* lzma */ = {
+ isa = PBXGroup;
+ children = (
+ 221F6AB31168545B0026C852 /* LzFind.c */,
+ 221F6AB41168545B0026C852 /* LzFind.h */,
+ 221F6AB9116854730026C852 /* LzHash.h */,
+ 221F6A7D116852B20026C852 /* LzmaDec.c */,
+ 221F6A721168529C0026C852 /* LzmaDec.h */,
+ 221F6A7A116852AA0026C852 /* LzmaEnc.c */,
+ 221F6A731168529C0026C852 /* LzmaEnc.h */,
+ 221F6ABC116854870026C852 /* Types.h */,
+ );
+ name = lzma;
+ path = src/lzma;
+ sourceTree = "<group>";
+ };
+ 225C734A1257CCC70009E8DA /* jenkins */ = {
+ isa = PBXGroup;
+ children = (
+ 225C734B1257CCC70009E8DA /* lookup.h */,
+ 225C734C1257CCC70009E8DA /* lookup3.c */,
+ );
+ name = jenkins;
+ path = src/jenkins;
+ sourceTree = "<group>";
+ };
+ 2295488711D45A520064B264 /* Test */ = {
+ isa = PBXGroup;
+ children = (
+ 2295488911D45A820064B264 /* Test.cpp */,
+ );
+ name = Test;
+ sourceTree = "<group>";
+ };
+ 2299D9D41167EFA8005C19BF /* adpcm */ = {
+ isa = PBXGroup;
+ children = (
+ 2299D9D51167EFA8005C19BF /* adpcm.cpp */,
+ 2299D9D61167EFA8005C19BF /* adpcm.h */,
+ );
+ name = adpcm;
+ path = src/adpcm;
+ sourceTree = "<group>";
+ };
+ 2299D9DB1167EFC6005C19BF /* sparse */ = {
+ isa = PBXGroup;
+ children = (
+ 2299D9DC1167EFC6005C19BF /* sparse.cpp */,
+ 2299D9DD1167EFC6005C19BF /* sparse.h */,
+ );
+ name = sparse;
+ path = src/sparse;
+ sourceTree = "<group>";
+ };
+ 22B54B321054B287001D6436 /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 225FAC950E53B7F800DA2CAE /* Info.plist */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 22C9181D11933E3A0083AC69 /* libtomcrypt */ = {
+ isa = PBXGroup;
+ children = (
+ 22C9182A11933FCF0083AC69 /* hashes */,
+ 22C9182E11933FCF0083AC69 /* headers */,
+ 22C9183C11933FCF0083AC69 /* math */,
+ 22C9184011933FCF0083AC69 /* misc */,
+ 22C9184E11933FCF0083AC69 /* pk */,
+ );
+ name = libtomcrypt;
+ path = src/libtomcrypt;
+ sourceTree = "<group>";
+ };
+ 22C9181E11933E470083AC69 /* libtommath */ = {
+ isa = PBXGroup;
+ children = (
+ 22C919111193400A0083AC69 /* bn_fast_mp_invmod.c */,
+ 22C919121193400A0083AC69 /* bn_fast_mp_montgomery_reduce.c */,
+ 22C919131193400A0083AC69 /* bn_fast_s_mp_mul_digs.c */,
+ 22C919141193400A0083AC69 /* bn_fast_s_mp_mul_high_digs.c */,
+ 22C919151193400A0083AC69 /* bn_fast_s_mp_sqr.c */,
+ 22C919161193400A0083AC69 /* bn_mp_2expt.c */,
+ 22C919171193400A0083AC69 /* bn_mp_abs.c */,
+ 22C919181193400A0083AC69 /* bn_mp_add_d.c */,
+ 22C919191193400A0083AC69 /* bn_mp_add.c */,
+ 22C9191A1193400A0083AC69 /* bn_mp_addmod.c */,
+ 22C9191B1193400A0083AC69 /* bn_mp_and.c */,
+ 22C9191C1193400A0083AC69 /* bn_mp_clamp.c */,
+ 22C9191D1193400A0083AC69 /* bn_mp_clear_multi.c */,
+ 22C9191E1193400A0083AC69 /* bn_mp_clear.c */,
+ 22C9191F1193400A0083AC69 /* bn_mp_cmp_d.c */,
+ 22C919201193400A0083AC69 /* bn_mp_cmp_mag.c */,
+ 22C919211193400A0083AC69 /* bn_mp_cmp.c */,
+ 22C919221193400A0083AC69 /* bn_mp_cnt_lsb.c */,
+ 22C919231193400A0083AC69 /* bn_mp_copy.c */,
+ 22C919241193400A0083AC69 /* bn_mp_count_bits.c */,
+ 22C919251193400A0083AC69 /* bn_mp_div_2.c */,
+ 22C919261193400A0083AC69 /* bn_mp_div_2d.c */,
+ 22C919271193400A0083AC69 /* bn_mp_div_3.c */,
+ 22C919281193400A0083AC69 /* bn_mp_div_d.c */,
+ 22C919291193400A0083AC69 /* bn_mp_div.c */,
+ 22C9192A1193400A0083AC69 /* bn_mp_dr_is_modulus.c */,
+ 22C9192B1193400A0083AC69 /* bn_mp_dr_reduce.c */,
+ 22C9192C1193400A0083AC69 /* bn_mp_dr_setup.c */,
+ 22C9192D1193400A0083AC69 /* bn_mp_exch.c */,
+ 22C9192E1193400A0083AC69 /* bn_mp_expt_d.c */,
+ 22C9192F1193400A0083AC69 /* bn_mp_exptmod_fast.c */,
+ 22C919301193400A0083AC69 /* bn_mp_exptmod.c */,
+ 22C919311193400A0083AC69 /* bn_mp_exteuclid.c */,
+ 22C919321193400A0083AC69 /* bn_mp_fread.c */,
+ 22C919331193400A0083AC69 /* bn_mp_fwrite.c */,
+ 22C919341193400A0083AC69 /* bn_mp_gcd.c */,
+ 22C919351193400A0083AC69 /* bn_mp_get_int.c */,
+ 22C919361193400A0083AC69 /* bn_mp_grow.c */,
+ 22C919371193400A0083AC69 /* bn_mp_init_copy.c */,
+ 22C919381193400A0083AC69 /* bn_mp_init_multi.c */,
+ 22C919391193400A0083AC69 /* bn_mp_init_set_int.c */,
+ 22C9193A1193400A0083AC69 /* bn_mp_init_set.c */,
+ 22C9193B1193400A0083AC69 /* bn_mp_init_size.c */,
+ 22C9193C1193400A0083AC69 /* bn_mp_init.c */,
+ 22C9193D1193400A0083AC69 /* bn_mp_invmod_slow.c */,
+ 22C9193E1193400A0083AC69 /* bn_mp_invmod.c */,
+ 22C9193F1193400A0083AC69 /* bn_mp_is_square.c */,
+ 22C919401193400A0083AC69 /* bn_mp_jacobi.c */,
+ 22C919411193400A0083AC69 /* bn_mp_karatsuba_mul.c */,
+ 22C919421193400A0083AC69 /* bn_mp_karatsuba_sqr.c */,
+ 22C919431193400A0083AC69 /* bn_mp_lcm.c */,
+ 22C919441193400A0083AC69 /* bn_mp_lshd.c */,
+ 22C919451193400A0083AC69 /* bn_mp_mod_2d.c */,
+ 22C919461193400A0083AC69 /* bn_mp_mod_d.c */,
+ 22C919471193400A0083AC69 /* bn_mp_mod.c */,
+ 22C919481193400A0083AC69 /* bn_mp_montgomery_calc_normalization.c */,
+ 22C919491193400A0083AC69 /* bn_mp_montgomery_reduce.c */,
+ 22C9194A1193400A0083AC69 /* bn_mp_montgomery_setup.c */,
+ 22C9194B1193400A0083AC69 /* bn_mp_mul_2.c */,
+ 22C9194C1193400A0083AC69 /* bn_mp_mul_2d.c */,
+ 22C9194D1193400A0083AC69 /* bn_mp_mul_d.c */,
+ 22C9194E1193400A0083AC69 /* bn_mp_mul.c */,
+ 22C9194F1193400A0083AC69 /* bn_mp_mulmod.c */,
+ 22C919501193400A0083AC69 /* bn_mp_n_root.c */,
+ 22C919511193400A0083AC69 /* bn_mp_neg.c */,
+ 22C919521193400A0083AC69 /* bn_mp_or.c */,
+ 22C919531193400A0083AC69 /* bn_mp_prime_fermat.c */,
+ 22C919541193400A0083AC69 /* bn_mp_prime_is_divisible.c */,
+ 22C919551193400A0083AC69 /* bn_mp_prime_is_prime.c */,
+ 22C919561193400A0083AC69 /* bn_mp_prime_miller_rabin.c */,
+ 22C919571193400A0083AC69 /* bn_mp_prime_next_prime.c */,
+ 22C919581193400A0083AC69 /* bn_mp_prime_rabin_miller_trials.c */,
+ 22C919591193400A0083AC69 /* bn_mp_prime_random_ex.c */,
+ 22C9195A1193400A0083AC69 /* bn_mp_radix_size.c */,
+ 22C9195B1193400A0083AC69 /* bn_mp_radix_smap.c */,
+ 22C9195C1193400A0083AC69 /* bn_mp_rand.c */,
+ 22C9195D1193400A0083AC69 /* bn_mp_read_radix.c */,
+ 22C9195E1193400A0083AC69 /* bn_mp_read_signed_bin.c */,
+ 22C9195F1193400A0083AC69 /* bn_mp_read_unsigned_bin.c */,
+ 22C919601193400A0083AC69 /* bn_mp_reduce_2k_l.c */,
+ 22C919611193400A0083AC69 /* bn_mp_reduce_2k_setup_l.c */,
+ 22C919621193400A0083AC69 /* bn_mp_reduce_2k_setup.c */,
+ 22C919631193400A0083AC69 /* bn_mp_reduce_2k.c */,
+ 22C919641193400A0083AC69 /* bn_mp_reduce_is_2k_l.c */,
+ 22C919651193400A0083AC69 /* bn_mp_reduce_is_2k.c */,
+ 22C919661193400A0083AC69 /* bn_mp_reduce_setup.c */,
+ 22C919671193400A0083AC69 /* bn_mp_reduce.c */,
+ 22C919681193400A0083AC69 /* bn_mp_rshd.c */,
+ 22C919691193400A0083AC69 /* bn_mp_set_int.c */,
+ 22C9196A1193400A0083AC69 /* bn_mp_set.c */,
+ 22C9196B1193400A0083AC69 /* bn_mp_shrink.c */,
+ 22C9196C1193400A0083AC69 /* bn_mp_signed_bin_size.c */,
+ 22C9196D1193400A0083AC69 /* bn_mp_sqr.c */,
+ 22C9196E1193400A0083AC69 /* bn_mp_sqrmod.c */,
+ 22C9196F1193400A0083AC69 /* bn_mp_sqrt.c */,
+ 22C919701193400A0083AC69 /* bn_mp_sub_d.c */,
+ 22C919711193400A0083AC69 /* bn_mp_sub.c */,
+ 22C919721193400A0083AC69 /* bn_mp_submod.c */,
+ 22C919731193400A0083AC69 /* bn_mp_to_signed_bin_n.c */,
+ 22C919741193400A0083AC69 /* bn_mp_to_signed_bin.c */,
+ 22C919751193400A0083AC69 /* bn_mp_to_unsigned_bin_n.c */,
+ 22C919761193400A0083AC69 /* bn_mp_to_unsigned_bin.c */,
+ 22C919771193400A0083AC69 /* bn_mp_toom_mul.c */,
+ 22C919781193400A0083AC69 /* bn_mp_toom_sqr.c */,
+ 22C919791193400A0083AC69 /* bn_mp_toradix_n.c */,
+ 22C9197A1193400A0083AC69 /* bn_mp_toradix.c */,
+ 22C9197B1193400A0083AC69 /* bn_mp_unsigned_bin_size.c */,
+ 22C9197C1193400A0083AC69 /* bn_mp_xor.c */,
+ 22C9197D1193400A0083AC69 /* bn_mp_zero.c */,
+ 22C9197E1193400A0083AC69 /* bn_prime_tab.c */,
+ 22C9197F1193400A0083AC69 /* bn_reverse.c */,
+ 22C919801193400A0083AC69 /* bn_s_mp_add.c */,
+ 22C919811193400A0083AC69 /* bn_s_mp_exptmod.c */,
+ 22C919821193400A0083AC69 /* bn_s_mp_mul_digs.c */,
+ 22C919831193400A0083AC69 /* bn_s_mp_mul_high_digs.c */,
+ 22C919841193400A0083AC69 /* bn_s_mp_sqr.c */,
+ 22C919851193400A0083AC69 /* bn_s_mp_sub.c */,
+ 22C919861193400A0083AC69 /* bncore.c */,
+ 22C919871193400A0083AC69 /* tommath_class.h */,
+ 22C919881193400A0083AC69 /* tommath_superclass.h */,
+ 22C919891193400A0083AC69 /* tommath.h */,
+ );
+ name = libtommath;
+ path = src/libtommath;
+ sourceTree = "<group>";
+ };
+ 22C9182A11933FCF0083AC69 /* hashes */ = {
+ isa = PBXGroup;
+ children = (
+ 22C9182B11933FCF0083AC69 /* hash_memory.c */,
+ 22C9182C11933FCF0083AC69 /* md5.c */,
+ 22C9182D11933FCF0083AC69 /* sha1.c */,
+ );
+ name = hashes;
+ path = src/hashes;
+ sourceTree = "<group>";
+ };
+ 22C9182E11933FCF0083AC69 /* headers */ = {
+ isa = PBXGroup;
+ children = (
+ 22C9182F11933FCF0083AC69 /* tomcrypt.h */,
+ 22C9183011933FCF0083AC69 /* tomcrypt_argchk.h */,
+ 22C9183111933FCF0083AC69 /* tomcrypt_cfg.h */,
+ 22C9183211933FCF0083AC69 /* tomcrypt_cipher.h */,
+ 22C9183311933FCF0083AC69 /* tomcrypt_custom.h */,
+ 22C9183411933FCF0083AC69 /* tomcrypt_hash.h */,
+ 22C9183511933FCF0083AC69 /* tomcrypt_mac.h */,
+ 22C9183611933FCF0083AC69 /* tomcrypt_macros.h */,
+ 22C9183711933FCF0083AC69 /* tomcrypt_math.h */,
+ 22C9183811933FCF0083AC69 /* tomcrypt_misc.h */,
+ 22C9183911933FCF0083AC69 /* tomcrypt_pk.h */,
+ 22C9183A11933FCF0083AC69 /* tomcrypt_pkcs.h */,
+ 22C9183B11933FCF0083AC69 /* tomcrypt_prng.h */,
+ );
+ name = headers;
+ path = src/headers;
+ sourceTree = "<group>";
+ };
+ 22C9183C11933FCF0083AC69 /* math */ = {
+ isa = PBXGroup;
+ children = (
+ 22C9183D11933FCF0083AC69 /* ltm_desc.c */,
+ 22C9183E11933FCF0083AC69 /* multi.c */,
+ 22C9183F11933FCF0083AC69 /* rand_prime.c */,
+ );
+ name = math;
+ path = src/math;
+ sourceTree = "<group>";
+ };
+ 22C9184011933FCF0083AC69 /* misc */ = {
+ isa = PBXGroup;
+ children = (
+ 22C9184111933FCF0083AC69 /* base64_decode.c */,
+ 22C9184211933FCF0083AC69 /* crypt_argchk.c */,
+ 22C9184311933FCF0083AC69 /* crypt_find_hash.c */,
+ 22C9184411933FCF0083AC69 /* crypt_find_prng.c */,
+ 22C9184511933FCF0083AC69 /* crypt_hash_descriptor.c */,
+ 22C9184611933FCF0083AC69 /* crypt_hash_is_valid.c */,
+ 22C9184711933FCF0083AC69 /* crypt_libc.c */,
+ 22C9184811933FCF0083AC69 /* crypt_ltc_mp_descriptor.c */,
+ 22C9184911933FCF0083AC69 /* crypt_prng_descriptor.c */,
+ 22C9184A11933FCF0083AC69 /* crypt_prng_is_valid.c */,
+ 22C9184B11933FCF0083AC69 /* crypt_register_hash.c */,
+ 22C9184C11933FCF0083AC69 /* crypt_register_prng.c */,
+ 22C9184D11933FCF0083AC69 /* zeromem.c */,
+ );
+ name = misc;
+ path = src/misc;
+ sourceTree = "<group>";
+ };
+ 22C9184E11933FCF0083AC69 /* pk */ = {
+ isa = PBXGroup;
+ children = (
+ 22C9184F11933FCF0083AC69 /* asn1 */,
+ 22C9186A11933FCF0083AC69 /* ecc */,
+ 22C9187111933FCF0083AC69 /* pkcs1 */,
+ 22C9187611933FCF0083AC69 /* rsa */,
+ );
+ name = pk;
+ path = src/pk;
+ sourceTree = "<group>";
+ };
+ 22C9184F11933FCF0083AC69 /* asn1 */ = {
+ isa = PBXGroup;
+ children = (
+ 22C9185011933FCF0083AC69 /* der_decode_bit_string.c */,
+ 22C9185111933FCF0083AC69 /* der_decode_boolean.c */,
+ 22C9185211933FCF0083AC69 /* der_decode_choice.c */,
+ 22C9185311933FCF0083AC69 /* der_decode_ia5_string.c */,
+ 22C9185411933FCF0083AC69 /* der_decode_integer.c */,
+ 22C9185511933FCF0083AC69 /* der_decode_object_identifier.c */,
+ 22C9185611933FCF0083AC69 /* der_decode_octet_string.c */,
+ 22C9185711933FCF0083AC69 /* der_decode_printable_string.c */,
+ 22C9185811933FCF0083AC69 /* der_decode_sequence_ex.c */,
+ 22C9185911933FCF0083AC69 /* der_decode_sequence_flexi.c */,
+ 22C9185A11933FCF0083AC69 /* der_decode_sequence_multi.c */,
+ 22C9185B11933FCF0083AC69 /* der_decode_short_integer.c */,
+ 22C9185C11933FCF0083AC69 /* der_decode_utctime.c */,
+ 22C9185D11933FCF0083AC69 /* der_decode_utf8_string.c */,
+ 22C9185E11933FCF0083AC69 /* der_length_bit_string.c */,
+ 22C9185F11933FCF0083AC69 /* der_length_boolean.c */,
+ 22C9186011933FCF0083AC69 /* der_length_ia5_string.c */,
+ 22C9186111933FCF0083AC69 /* der_length_integer.c */,
+ 22C9186211933FCF0083AC69 /* der_length_object_identifier.c */,
+ 22C9186311933FCF0083AC69 /* der_length_octet_string.c */,
+ 22C9186411933FCF0083AC69 /* der_length_printable_string.c */,
+ 22C9186511933FCF0083AC69 /* der_length_sequence.c */,
+ 22C9186611933FCF0083AC69 /* der_length_short_integer.c */,
+ 22C9186711933FCF0083AC69 /* der_length_utctime.c */,
+ 22C9186811933FCF0083AC69 /* der_length_utf8_string.c */,
+ 22C9186911933FCF0083AC69 /* der_sequence_free.c */,
+ );
+ path = asn1;
+ sourceTree = "<group>";
+ };
+ 22C9186A11933FCF0083AC69 /* ecc */ = {
+ isa = PBXGroup;
+ children = (
+ 22C9186B11933FCF0083AC69 /* ltc_ecc_map.c */,
+ 22C9186C11933FCF0083AC69 /* ltc_ecc_mul2add.c */,
+ 22C9186D11933FCF0083AC69 /* ltc_ecc_mulmod.c */,
+ 22C9186E11933FCF0083AC69 /* ltc_ecc_points.c */,
+ 22C9186F11933FCF0083AC69 /* ltc_ecc_projective_add_point.c */,
+ 22C9187011933FCF0083AC69 /* ltc_ecc_projective_dbl_point.c */,
+ );
+ path = ecc;
+ sourceTree = "<group>";
+ };
+ 22C9187111933FCF0083AC69 /* pkcs1 */ = {
+ isa = PBXGroup;
+ children = (
+ 22C9187211933FCF0083AC69 /* pkcs_1_mgf1.c */,
+ 22C9187311933FCF0083AC69 /* pkcs_1_oaep_decode.c */,
+ 22C9187411933FCF0083AC69 /* pkcs_1_pss_decode.c */,
+ 22C9187511933FCF0083AC69 /* pkcs_1_v1_5_decode.c */,
+ );
+ path = pkcs1;
+ sourceTree = "<group>";
+ };
+ 22C9187611933FCF0083AC69 /* rsa */ = {
+ isa = PBXGroup;
+ children = (
+ 22C9187711933FCF0083AC69 /* rsa_exptmod.c */,
+ 22C9187811933FCF0083AC69 /* rsa_free.c */,
+ 22C9187911933FCF0083AC69 /* rsa_import.c */,
+ 22C9187A11933FCF0083AC69 /* rsa_make_key.c */,
+ 22C9187B11933FCF0083AC69 /* rsa_verify_hash.c */,
+ 22C9187C11933FCF0083AC69 /* rsa_verify_simple.c */,
+ );
+ path = rsa;
+ sourceTree = "<group>";
+ };
+ 32DBEE830D00E58F00DB1E81 /* Source */ = {
+ isa = PBXGroup;
+ children = (
+ 2299D9D41167EFA8005C19BF /* adpcm */,
+ 32ED009B0D03542A00AB0B4E /* huffman */,
+ 225C734A1257CCC70009E8DA /* jenkins */,
+ 22C9181D11933E3A0083AC69 /* libtomcrypt */,
+ 22C9181E11933E470083AC69 /* libtommath */,
+ 221F652D116851D70026C852 /* lzma */,
+ 32ED00A40D03542A00AB0B4E /* pklib */,
+ 2299D9DB1167EFC6005C19BF /* sparse */,
+ 228B538311BF7D0D001A58DA /* FileStream.cpp */,
+ 22EC6043154B28A000679228 /* FileStream.h */,
+ 32ED00AA0D03542A00AB0B4E /* SBaseCommon.cpp */,
+ 225C73531257CD0C0009E8DA /* SBaseFileTable.cpp */,
+ 32ED00AC0D03542A00AB0B4E /* SCompression.cpp */,
+ 2299DA4D1167FD16005C19BF /* SFileAddFile.cpp */,
+ 32ED00A90D03542A00AB0B4E /* SFileAttributes.cpp */,
+ 32ED00AD0D03542A00AB0B4E /* SFileCompactArchive.cpp */,
+ 32ED00AE0D03542A00AB0B4E /* SFileCreateArchive.cpp */,
+ 32ED00AF0D03542A00AB0B4E /* SFileExtractFile.cpp */,
+ 32ED00B00D03542A00AB0B4E /* SFileFindFile.cpp */,
+ 32ED00B40D03542A00AB0B4E /* SFileListFile.cpp */,
+ 32ED00B10D03542A00AB0B4E /* SFileOpenArchive.cpp */,
+ 32ED00B20D03542A00AB0B4E /* SFileOpenFileEx.cpp */,
+ 22AEA121123125D800359B16 /* SFilePatchArchives.cpp */,
+ 32ED00B30D03542A00AB0B4E /* SFileReadFile.cpp */,
+ 22F5A9C41193DFBA00F8B121 /* SFileVerify.cpp */,
+ 32ED00AB0D03542A00AB0B4E /* StormCommon.h */,
+ 32ED00B60D03542A00AB0B4E /* StormLib.h */,
+ 32ED00B70D03542A00AB0B4E /* StormPort.h */,
+ );
+ name = Source;
+ sourceTree = "<group>";
+ };
+ 32ED009B0D03542A00AB0B4E /* huffman */ = {
+ isa = PBXGroup;
+ children = (
+ 32ED009C0D03542A00AB0B4E /* huff.cpp */,
+ 32ED009D0D03542A00AB0B4E /* huff.h */,
+ );
+ name = huffman;
+ path = src/huffman;
+ sourceTree = "<group>";
+ };
+ 32ED00A40D03542A00AB0B4E /* pklib */ = {
+ isa = PBXGroup;
+ children = (
+ 32ED00A60D03542A00AB0B4E /* explode.c */,
+ 32ED00A70D03542A00AB0B4E /* implode.c */,
+ 32ED00A80D03542A00AB0B4E /* pklib.h */,
+ );
+ name = pklib;
+ path = src/pklib;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ 225530D01056BAC800FA646A /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 225530DB1056BC7900FA646A /* huff.h in Headers */,
+ 225530DE1056BC7900FA646A /* pklib.h in Headers */,
+ 225530DF1056BC7900FA646A /* StormCommon.h in Headers */,
+ 225530E01056BC7900FA646A /* StormLib.h in Headers */,
+ 225530E11056BC7900FA646A /* StormPort.h in Headers */,
+ 2299D9DA1167EFA8005C19BF /* adpcm.h in Headers */,
+ 2299D9E11167EFC6005C19BF /* sparse.h in Headers */,
+ 221F6A761168529C0026C852 /* LzmaDec.h in Headers */,
+ 221F6A771168529C0026C852 /* LzmaEnc.h in Headers */,
+ 221F6AB81168545B0026C852 /* LzFind.h in Headers */,
+ 221F6ABB116854730026C852 /* LzHash.h in Headers */,
+ 221F6ABE116854870026C852 /* Types.h in Headers */,
+ 22C9188011933FCF0083AC69 /* tomcrypt.h in Headers */,
+ 22C9188111933FCF0083AC69 /* tomcrypt_argchk.h in Headers */,
+ 22C9188211933FCF0083AC69 /* tomcrypt_cfg.h in Headers */,
+ 22C9188311933FCF0083AC69 /* tomcrypt_cipher.h in Headers */,
+ 22C9188411933FCF0083AC69 /* tomcrypt_custom.h in Headers */,
+ 22C9188511933FCF0083AC69 /* tomcrypt_hash.h in Headers */,
+ 22C9188611933FCF0083AC69 /* tomcrypt_mac.h in Headers */,
+ 22C9188711933FCF0083AC69 /* tomcrypt_macros.h in Headers */,
+ 22C9188811933FCF0083AC69 /* tomcrypt_math.h in Headers */,
+ 22C9188911933FCF0083AC69 /* tomcrypt_misc.h in Headers */,
+ 22C9188A11933FCF0083AC69 /* tomcrypt_pk.h in Headers */,
+ 22C9188B11933FCF0083AC69 /* tomcrypt_pkcs.h in Headers */,
+ 22C9188C11933FCF0083AC69 /* tomcrypt_prng.h in Headers */,
+ 22C91A001193400A0083AC69 /* tommath_class.h in Headers */,
+ 22C91A011193400A0083AC69 /* tommath_superclass.h in Headers */,
+ 22C91A021193400A0083AC69 /* tommath.h in Headers */,
+ 225C734F1257CCC70009E8DA /* lookup.h in Headers */,
+ 22EC6044154B28A000679228 /* FileStream.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 225FAC8F0E53B7F800DA2CAE /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 225FAC9C0E53BAA100DA2CAE /* huff.h in Headers */,
+ 225FAC9F0E53BAA100DA2CAE /* pklib.h in Headers */,
+ 225FACA00E53BAA100DA2CAE /* StormCommon.h in Headers */,
+ 225FACA10E53BAA100DA2CAE /* StormLib.h in Headers */,
+ 225FACA20E53BAA100DA2CAE /* StormPort.h in Headers */,
+ 2299D9D81167EFA8005C19BF /* adpcm.h in Headers */,
+ 2299D9DF1167EFC6005C19BF /* sparse.h in Headers */,
+ 221F6A741168529C0026C852 /* LzmaDec.h in Headers */,
+ 221F6A751168529C0026C852 /* LzmaEnc.h in Headers */,
+ 221F6AB61168545B0026C852 /* LzFind.h in Headers */,
+ 221F6ABA116854730026C852 /* LzHash.h in Headers */,
+ 221F6ABD116854870026C852 /* Types.h in Headers */,
+ 22C918CA11933FCF0083AC69 /* tomcrypt.h in Headers */,
+ 22C918CB11933FCF0083AC69 /* tomcrypt_argchk.h in Headers */,
+ 22C918CC11933FCF0083AC69 /* tomcrypt_cfg.h in Headers */,
+ 22C918CD11933FCF0083AC69 /* tomcrypt_cipher.h in Headers */,
+ 22C918CE11933FCF0083AC69 /* tomcrypt_custom.h in Headers */,
+ 22C918CF11933FCF0083AC69 /* tomcrypt_hash.h in Headers */,
+ 22C918D011933FCF0083AC69 /* tomcrypt_mac.h in Headers */,
+ 22C918D111933FCF0083AC69 /* tomcrypt_macros.h in Headers */,
+ 22C918D211933FCF0083AC69 /* tomcrypt_math.h in Headers */,
+ 22C918D311933FCF0083AC69 /* tomcrypt_misc.h in Headers */,
+ 22C918D411933FCF0083AC69 /* tomcrypt_pk.h in Headers */,
+ 22C918D511933FCF0083AC69 /* tomcrypt_pkcs.h in Headers */,
+ 22C918D611933FCF0083AC69 /* tomcrypt_prng.h in Headers */,
+ 22C91A791193400A0083AC69 /* tommath_class.h in Headers */,
+ 22C91A7A1193400A0083AC69 /* tommath_superclass.h in Headers */,
+ 22C91A7B1193400A0083AC69 /* tommath.h in Headers */,
+ 225C734D1257CCC70009E8DA /* lookup.h in Headers */,
+ 22EC6045154B28A000679228 /* FileStream.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ 225530D31056BAC800FA646A /* StormLib */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 225530D71056BB1600FA646A /* Build configuration list for PBXNativeTarget "StormLib" */;
+ buildPhases = (
+ 225530D01056BAC800FA646A /* Headers */,
+ 225530D11056BAC800FA646A /* Sources */,
+ 225530D21056BAC800FA646A /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = StormLib;
+ productName = StormLib;
+ productReference = 225530D41056BAC800FA646A /* libStormLib.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+ 225FAC930E53B7F800DA2CAE /* StormLibFramework */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 225FAC980E53B7F900DA2CAE /* Build configuration list for PBXNativeTarget "StormLibFramework" */;
+ buildPhases = (
+ 225FAC8F0E53B7F800DA2CAE /* Headers */,
+ 225FAC900E53B7F800DA2CAE /* Resources */,
+ 225FAC910E53B7F800DA2CAE /* Sources */,
+ 225FAC920E53B7F800DA2CAE /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = StormLibFramework;
+ productName = StormLib;
+ productReference = 225FAC940E53B7F800DA2CAE /* StormLib.framework */;
+ productType = "com.apple.product-type.framework";
+ };
+ 22954ACD11D463A30064B264 /* StormLib_Test */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 22954AD911D463E00064B264 /* Build configuration list for PBXNativeTarget "StormLib_Test" */;
+ buildPhases = (
+ 22954ACB11D463A30064B264 /* Sources */,
+ 22954ACC11D463A30064B264 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 2229F62F11D4653600118914 /* PBXTargetDependency */,
+ );
+ name = StormLib_Test;
+ productName = StormLib_Test;
+ productReference = 22954ACE11D463A30064B264 /* StormLib_Test */;
+ productType = "com.apple.product-type.tool";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 0867D690FE84028FC02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0430;
+ };
+ 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 */,
+ 225530E71056BC8700FA646A /* implode.c in Sources */,
+ 225530E81056BC8700FA646A /* SFileAttributes.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 */,
+ 225530EE1056BC8700FA646A /* SFileFindFile.cpp in Sources */,
+ 225530EF1056BC8700FA646A /* SFileOpenArchive.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 */,
+ 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 */,
+ 22C9198C1193400A0083AC69 /* bn_fast_s_mp_mul_digs.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 */,
+ 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 */,
+ 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 */,
+ 22C919C31193400A0083AC69 /* bn_mp_montgomery_setup.c in Sources */,
+ 22C919C41193400A0083AC69 /* bn_mp_mul_2.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 */,
+ 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 */,
+ 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 */,
+ 22C919DC1193400A0083AC69 /* bn_mp_reduce_2k.c in Sources */,
+ 22C919DD1193400A0083AC69 /* bn_mp_reduce_is_2k_l.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 */,
+ 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 */,
+ 225FACAA0E53BAB400DA2CAE /* implode.c in Sources */,
+ 225FACAB0E53BAB400DA2CAE /* SFileAttributes.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 */,
+ 225FACB10E53BAB400DA2CAE /* SFileFindFile.cpp in Sources */,
+ 225FACB20E53BAB400DA2CAE /* SFileOpenArchive.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 */,
+ 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 */,
+ 22C91A051193400A0083AC69 /* bn_fast_s_mp_mul_digs.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 */,
+ 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 */,
+ 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 */,
+ 22C91A3C1193400A0083AC69 /* bn_mp_montgomery_setup.c in Sources */,
+ 22C91A3D1193400A0083AC69 /* bn_mp_mul_2.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 */,
+ 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 */,
+ 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 */,
+ 22C91A551193400A0083AC69 /* bn_mp_reduce_2k.c in Sources */,
+ 22C91A561193400A0083AC69 /* bn_mp_reduce_is_2k_l.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 */,
+ 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_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+ _7ZIP_ST,
+ _DEBUG,
+ );
+ GCC_VERSION = com.apple.compilers.llvmgcc42;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.4;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = macosx;
+ SKIP_INSTALL = YES;
+ 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_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = _7ZIP_ST;
+ GCC_VERSION = com.apple.compilers.llvmgcc42;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.4;
+ SDKROOT = macosx;
+ SKIP_INSTALL = YES;
+ STRIP_INSTALLED_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 225530D51056BAC900FA646A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INSTALL_PATH = /usr/local/lib;
+ PRODUCT_NAME = StormLib;
+ };
+ name = Debug;
+ };
+ 225530D61056BAC900FA646A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ INSTALL_PATH = /usr/local/lib;
+ PRODUCT_NAME = StormLib;
+ };
+ name = Release;
+ };
+ 225FAC960E53B7F900DA2CAE /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ EXPORTED_SYMBOLS_FILE = "$(PROJECT_DIR)/stormlib_dll/StormLib.exp";
+ FRAMEWORK_VERSION = A;
+ GCC_DYNAMIC_NO_PIC = NO;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ /usr/lib/clang/3.1/lib/darwin,
+ );
+ PRODUCT_NAME = StormLib;
+ };
+ name = Debug;
+ };
+ 225FAC970E53B7F900DA2CAE /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ EXPORTED_SYMBOLS_FILE = "$(PROJECT_DIR)/stormlib_dll/StormLib.exp";
+ FRAMEWORK_VERSION = A;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ /usr/lib/clang/3.1/lib/darwin,
+ );
+ 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__,
+ );
+ INSTALL_PATH = /usr/local/bin;
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ /usr/lib/clang/3.1/lib/darwin,
+ );
+ 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";
+ INSTALL_PATH = /usr/local/bin;
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ /usr/lib/clang/3.1/lib/darwin,
+ );
+ 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_dll.vcproj b/StormLib_dll.vcproj
new file mode 100644
index 0000000..f56cd84
--- /dev/null
+++ b/StormLib_dll.vcproj
@@ -0,0 +1,2499 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="StormLib_dll"
+ ProjectGUID="{CB385198-50B1-4CF4-883B-11F042DED6AA}"
+ RootNamespace="StormLib_dll"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\StormLib.dll"
+ LinkIncremental="2"
+ ModuleDefinitionFile=".\StormLib_dll\StormLib.def"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\StormLib.dll"
+ LinkIncremental="2"
+ ModuleDefinitionFile=".\StormLib_dll\StormLib.def"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\StormLib.dll"
+ LinkIncremental="1"
+ ModuleDefinitionFile=".\StormLib_dll\StormLib.def"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\StormLib.dll"
+ LinkIncremental="1"
+ ModuleDefinitionFile=".\StormLib_dll\StormLib.def"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Doc Files"
+ >
+ <File
+ RelativePath=".\doc\History.txt"
+ >
+ </File>
+ <File
+ RelativePath=".\doc\The MoPaQ File Format 0.9.txt"
+ >
+ </File>
+ <File
+ RelativePath=".\doc\The MoPaQ File Format 1.0.txt"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ >
+ <File
+ RelativePath=".\src\StormCommon.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\StormLib.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\StormPort.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Source Files"
+ >
+ <File
+ RelativePath=".\stormlib_dll\DllMain.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\FileStream.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SBaseCommon.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SBaseFileTable.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SCompression.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileAddFile.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileAttributes.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileCompactArchive.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileCreateArchive.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileExtractFile.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileFindFile.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileListFile.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileOpenArchive.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileOpenFileEx.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFilePatchArchives.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileReadFile.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileVerify.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="DebugAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAD|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseAS|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\stormlib_dll\StormLib.def"
+ >
+ </File>
+ <Filter
+ Name="adpcm"
+ >
+ <File
+ RelativePath=".\src\adpcm\adpcm.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\src\adpcm\adpcm.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="bzip2"
+ >
+ <File
+ RelativePath=".\src\bzip2\blocksort.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\bzlib.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\compress.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\crctable.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\decompress.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\huffman.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\randtable.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="huffman"
+ >
+ <File
+ RelativePath=".\src\huffman\huff.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\src\huffman\huff.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="libtomcrypt"
+ >
+ <Filter
+ Name="hashes"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\hashes\hash_memory.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\hashes\md5.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\hashes\sha1.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="math"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\math\ltm_desc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\math\multi.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\math\rand_prime.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="misc"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\base64_decode.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_argchk.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_find_hash.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_find_prng.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_hash_descriptor.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_hash_is_valid.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_libc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_ltc_mp_descriptor.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_prng_descriptor.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_prng_is_valid.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_register_hash.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_register_prng.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\zeromem.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="pk"
+ >
+ <Filter
+ Name="asn1"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_bit_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_boolean.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_choice.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_ia5_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_integer.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_object_identifier.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_octet_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_printable_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_sequence_ex.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_sequence_flexi.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_sequence_multi.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_short_integer.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_utctime.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_utf8_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_bit_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_boolean.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_ia5_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_integer.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_object_identifier.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_octet_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_printable_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_sequence.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_short_integer.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_utctime.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_utf8_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_sequence_free.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="ecc"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_map.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_mul2add.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_mulmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_points.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_add_point.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_dbl_point.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="pkcs1"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\pkcs1\pkcs_1_mgf1.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\pkcs1\pkcs_1_oaep_decode.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_decode.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_decode.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="rsa"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_exptmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_free.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_import.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_make_key.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_verify_hash.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_verify_simple.c"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="libtommath"
+ >
+ <File
+ RelativePath=".\src\libtommath\bn_fast_mp_invmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_fast_mp_montgomery_reduce.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_fast_s_mp_mul_digs.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_fast_s_mp_mul_high_digs.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_fast_s_mp_sqr.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_2expt.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_abs.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_add.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_add_d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_addmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_and.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_clamp.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_clear.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_clear_multi.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_cmp.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_cmp_d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_cmp_mag.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_cnt_lsb.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_copy.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_count_bits.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_div.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_div_2.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_div_2d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_div_3.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_div_d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_dr_is_modulus.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_dr_reduce.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_dr_setup.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_exch.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_expt_d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_exptmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_exptmod_fast.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_exteuclid.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_fread.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_fwrite.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_gcd.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_get_int.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_grow.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init_copy.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init_multi.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init_set.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init_set_int.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init_size.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_invmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_invmod_slow.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_is_square.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_jacobi.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_karatsuba_mul.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_karatsuba_sqr.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_lcm.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_lshd.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mod_2d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mod_d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_montgomery_calc_normalization.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_montgomery_reduce.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_montgomery_setup.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mul.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mul_2.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mul_2d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mul_d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mulmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_n_root.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_neg.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_or.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_fermat.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_is_divisible.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_is_prime.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_miller_rabin.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_next_prime.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_rabin_miller_trials.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_random_ex.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_radix_size.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_radix_smap.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_rand.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_read_radix.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_read_signed_bin.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_read_unsigned_bin.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_2k.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_2k_l.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_2k_setup.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_2k_setup_l.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_is_2k.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_is_2k_l.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_setup.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_rshd.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_set.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_set_int.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_shrink.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_signed_bin_size.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_sqr.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_sqrmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_sqrt.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_sub.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_sub_d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_submod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_to_signed_bin.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_to_signed_bin_n.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_to_unsigned_bin.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_to_unsigned_bin_n.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_toom_mul.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_toom_sqr.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_toradix.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_toradix_n.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_unsigned_bin_size.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_xor.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_zero.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_prime_tab.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_reverse.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_add.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_exptmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_mul_digs.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_mul_high_digs.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_sqr.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_sub.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bncore.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="lzma"
+ >
+ <File
+ RelativePath=".\src\lzma\C\LzFind.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\lzma\C\LzFindMt.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\lzma\C\LzmaDec.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\lzma\C\LzmaEnc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\lzma\C\Threads.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="pklib"
+ >
+ <File
+ RelativePath=".\src\pklib\explode.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\pklib\implode.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\pklib\pklib.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="sparse"
+ >
+ <File
+ RelativePath=".\src\sparse\sparse.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\src\sparse\sparse.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="zlib"
+ >
+ <File
+ RelativePath=".\src\zlib\adler32.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\compress2.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\crc32.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\deflate.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\inffast.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\inflate.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\inftrees.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\trees.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\zutil.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="jenkins"
+ >
+ <File
+ RelativePath=".\src\jenkins\lookup.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\jenkins\lookup3.c"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/StormLib_test.vcproj b/StormLib_test.vcproj
new file mode 100644
index 0000000..f7273b1
--- /dev/null
+++ b/StormLib_test.vcproj
@@ -0,0 +1,1997 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="StormLib_test"
+ ProjectGUID="{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}"
+ RootNamespace="StormLib_test"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ <DefaultToolFile
+ FileName="masm.rules"
+ />
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="MASM"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="./src/libtomcrypt/src/headers"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;__STORMLIB_TEST__"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ VerboseOutput="false"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="MASM"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="./src/libtomcrypt/src/headers"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;__STORMLIB_TEST__"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ IntermediateDirectory="./bin/$(ProjectName)/$(PlatformName)/$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="MASM"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="./src/libtomcrypt/src/headers"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;__STORMLIB_TEST__"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="MASM"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="./src/libtomcrypt/src/headers"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;__STORMLIB_TEST__"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="1"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Doc Files"
+ >
+ <File
+ RelativePath=".\doc\History.txt"
+ >
+ </File>
+ <File
+ RelativePath=".\doc\The MoPaQ File Format 0.9.txt"
+ >
+ </File>
+ <File
+ RelativePath=".\doc\The MoPaQ File Format 1.0.txt"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ >
+ <File
+ RelativePath=".\src\FileStream.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\StormCommon.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\StormLib.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\StormPort.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Source Files"
+ >
+ <File
+ RelativePath=".\src\FileStream.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SBaseCommon.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SBaseDumpData.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SBaseFileTable.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SCompression.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileAddFile.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileAttributes.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileCompactArchive.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileCreateArchive.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileExtractFile.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileFindFile.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileListFile.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileOpenArchive.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileOpenFileEx.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFilePatchArchives.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileReadFile.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\SFileVerify.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\test\Test.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <Filter
+ Name="adpcm"
+ >
+ <File
+ RelativePath=".\src\adpcm\adpcm.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\adpcm\adpcm.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="bzip2"
+ >
+ <File
+ RelativePath=".\src\bzip2\blocksort.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\bzlib.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\compress.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\crctable.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\decompress.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\huffman.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\bzip2\randtable.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="huffman"
+ >
+ <File
+ RelativePath=".\src\huffman\huff.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="4"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\src\huffman\huff.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="libtomcrypt"
+ >
+ <Filter
+ Name="hashes"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\hashes\hash_memory.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\hashes\md5.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\hashes\sha1.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="math"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\math\ltm_desc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\math\multi.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\math\rand_prime.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="misc"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\base64_decode.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_argchk.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_find_hash.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_find_prng.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_hash_descriptor.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_hash_is_valid.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_libc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_ltc_mp_descriptor.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_prng_descriptor.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_prng_is_valid.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_register_hash.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\crypt_register_prng.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\misc\zeromem.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="pk"
+ >
+ <Filter
+ Name="asn1"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_bit_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_boolean.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_choice.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_ia5_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_integer.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_object_identifier.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_octet_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_printable_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_sequence_ex.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_sequence_flexi.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_sequence_multi.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_short_integer.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_utctime.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_decode_utf8_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_bit_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_boolean.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_ia5_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_integer.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_object_identifier.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_octet_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_printable_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_sequence.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_short_integer.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_utctime.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_length_utf8_string.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\asn1\der_sequence_free.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="ecc"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_map.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_mul2add.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_mulmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_points.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_add_point.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\ecc\ltc_ecc_projective_dbl_point.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="pkcs1"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\pkcs1\pkcs_1_mgf1.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\pkcs1\pkcs_1_oaep_decode.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\pkcs1\pkcs_1_pss_decode.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\pkcs1\pkcs_1_v1_5_decode.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="rsa"
+ >
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_exptmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_free.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_import.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_make_key.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_verify_hash.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtomcrypt\src\pk\rsa\rsa_verify_simple.c"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="libtommath"
+ >
+ <File
+ RelativePath=".\src\libtommath\bn_fast_mp_invmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_fast_mp_montgomery_reduce.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_fast_s_mp_mul_digs.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_fast_s_mp_mul_high_digs.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_fast_s_mp_sqr.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_2expt.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_abs.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_add.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_add_d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_addmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_and.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_clamp.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_clear.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_clear_multi.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_cmp.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_cmp_d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_cmp_mag.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_cnt_lsb.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_copy.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_count_bits.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_div.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_div_2.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_div_2d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_div_3.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_div_d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_dr_is_modulus.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_dr_reduce.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_dr_setup.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_exch.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_expt_d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_exptmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_exptmod_fast.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_exteuclid.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_fread.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_fwrite.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_gcd.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_get_int.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_grow.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init_copy.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init_multi.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init_set.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init_set_int.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_init_size.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_invmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_invmod_slow.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_is_square.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_jacobi.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_karatsuba_mul.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_karatsuba_sqr.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_lcm.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_lshd.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mod_2d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mod_d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_montgomery_calc_normalization.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_montgomery_reduce.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_montgomery_setup.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mul.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mul_2.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mul_2d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mul_d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_mulmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_n_root.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_neg.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_or.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_fermat.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_is_divisible.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_is_prime.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_miller_rabin.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_next_prime.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_rabin_miller_trials.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_prime_random_ex.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_radix_size.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_radix_smap.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_rand.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_read_radix.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_read_signed_bin.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_read_unsigned_bin.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_2k.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_2k_l.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_2k_setup.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_2k_setup_l.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_is_2k.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_is_2k_l.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_reduce_setup.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_rshd.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_set.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_set_int.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_shrink.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_signed_bin_size.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_sqr.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_sqrmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_sqrt.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_sub.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_sub_d.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_submod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_to_signed_bin.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_to_signed_bin_n.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_to_unsigned_bin.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_to_unsigned_bin_n.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_toom_mul.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_toom_sqr.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_toradix.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_toradix_n.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_unsigned_bin_size.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_xor.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_mp_zero.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_prime_tab.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_reverse.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_add.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_exptmod.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_mul_digs.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_mul_high_digs.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_sqr.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bn_s_mp_sub.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\libtommath\bncore.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="lzma"
+ >
+ <File
+ RelativePath=".\src\lzma\C\LzFind.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\lzma\C\LzFindMt.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\lzma\C\LzmaDec.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\lzma\C\LzmaEnc.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\lzma\C\Threads.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="pklib"
+ >
+ <File
+ RelativePath=".\src\pklib\explode.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\pklib\implode.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\pklib\pklib.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="sparse"
+ >
+ <File
+ RelativePath=".\src\sparse\sparse.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\src\sparse\sparse.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="zlib"
+ >
+ <File
+ RelativePath=".\src\zlib\adler32.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\compress2.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\crc32.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\deflate.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\inffast.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\inflate.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\inftrees.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\trees.c"
+ >
+ </File>
+ <File
+ RelativePath=".\src\zlib\zutil.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="jenkins"
+ >
+ <File
+ RelativePath=".\src\jenkins\lookup.h"
+ >
+ </File>
+ <File
+ RelativePath=".\src\jenkins\lookup3.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WarningLevel="1"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/Storm_dll.bat b/Storm_dll.bat
new file mode 100644
index 0000000..466a3d3
--- /dev/null
+++ b/Storm_dll.bat
@@ -0,0 +1,18 @@
+@echo off
+rem Post-build batch for StormDll project
+rem Called as StormDll.bat $(PlatformName) $(ConfigurationName)
+rem Example: StormDll.bat x64 Debug
+
+if x%1 == xWin32 goto PlatformWin32
+if x%1 == xx64 goto PlatformWin64
+goto exit
+
+:PlatformWin32
+copy .\bin\Storm_dll\%1\%2\*.lib .
+goto exit
+
+:PlatformWin64
+copy .\bin\Storm_dll\%1\%2\*.lib .
+goto exit
+
+:exit
diff --git a/Storm_dll.vcproj b/Storm_dll.vcproj
new file mode 100644
index 0000000..4eb8902
--- /dev/null
+++ b/Storm_dll.vcproj
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="Storm_dll"
+ ProjectGUID="{BD600973-C6FA-4CE3-8821-67F6418B7F9C}"
+ RootNamespace="Storm_dll"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\bin\Storm_dll\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory=".\bin\Storm_dll\$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;Storm_dll_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\storm.dll"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ ModuleDefinitionFile=".\Storm_dll\Storm_dll.def"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ BaseAddress="0x15000000"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="Storm_dll.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\bin\Storm_dll\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory=".\bin\Storm_dll\$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;Storm_dll_EXPORTS"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\storm.dll"
+ LinkIncremental="1"
+ GenerateManifest="false"
+ ModuleDefinitionFile=".\Storm_dll\storm_dll.def"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ BaseAddress="0x15000000"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="Storm_dll.bat $(PlatformName) $(ConfigurationName)"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\Storm_dll\storm_dll.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\storm_dll\storm_dll.def"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\Storm_dll\storm_dll.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/doc/History.txt b/doc/History.txt
new file mode 100644
index 0000000..5e32894
--- /dev/null
+++ b/doc/History.txt
@@ -0,0 +1,62 @@
+
+ StormLib history
+ ================
+
+ 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/doc/Sector Offset MD5.txt b/doc/Sector Offset MD5.txt
new file mode 100644
index 0000000..a22506a
--- /dev/null
+++ b/doc/Sector Offset MD5.txt
@@ -0,0 +1,25 @@
+
+ After sector offset table
+ =========================
+
+FileSize CmpSize DWORDs
+00007588 000075A4 0x01
+0000A9EA 000095EC 0x01
+0000E51D 0000E20D 0x02
+00015C00 00015C40 0x02
+0001C578 000186C4 0x02
+0002A9D4 0002A9EA 0x04
+00037BAC 00037A42 0x06
+0003C3C1 00034084 0x06
+0003D224 0003B30F 0x06
+00045105 0004195A 0x07
+00045D9C 0003D87D 0x07
+0004AAB8 0004860A 0x08
+0004D18E 00048E0C 0x07
+00056B4C 00056BDD 0x09
+0005DC08 00059426 0x09
+00061EC0 00057711 0x0A
+0006CEC4 00062561 0x0B
+000778EE 00066736 0x0C
+000AD0CB 0007F32E 0x11
+00327EAC 00303395 0x53
diff --git a/doc/The MoPaQ File Format 0.9.txt b/doc/The MoPaQ File Format 0.9.txt
new file mode 100644
index 0000000..ce8d8f7
--- /dev/null
+++ b/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/doc/The MoPaQ File Format 1.0.txt b/doc/The MoPaQ File Format 1.0.txt
new file mode 100644
index 0000000..2f13945
--- /dev/null
+++ b/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/doc/d3-authenticationcode-deDE.txt b/doc/d3-authenticationcode-deDE.txt
new file mode 100644
index 0000000..cac6671
--- /dev/null
+++ b/doc/d3-authenticationcode-deDE.txt
@@ -0,0 +1 @@
+UCMXF6EJY352EFH4XFRXCFH2XC9MQRZK \ No newline at end of file
diff --git a/doc/d3-authenticationcode-enGB.txt b/doc/d3-authenticationcode-enGB.txt
new file mode 100644
index 0000000..2bc9c83
--- /dev/null
+++ b/doc/d3-authenticationcode-enGB.txt
@@ -0,0 +1 @@
+MMKVHY48RP7WXP4GHYBQ7SL9J9UNPHBP \ No newline at end of file
diff --git a/doc/d3-authenticationcode-enSG.txt b/doc/d3-authenticationcode-enSG.txt
new file mode 100644
index 0000000..e6f1ec2
--- /dev/null
+++ b/doc/d3-authenticationcode-enSG.txt
@@ -0,0 +1 @@
+8MXLWHQ7VGGLTZ9MQZQSFDCLJYET3CPP \ No newline at end of file
diff --git a/doc/d3-authenticationcode-enUS.txt b/doc/d3-authenticationcode-enUS.txt
new file mode 100644
index 0000000..8d73e61
--- /dev/null
+++ b/doc/d3-authenticationcode-enUS.txt
@@ -0,0 +1 @@
+EJ2R5TM6XFE2GUNG5QDGHKQ9UAKPWZSZ \ No newline at end of file
diff --git a/doc/d3-authenticationcode-esES.txt b/doc/d3-authenticationcode-esES.txt
new file mode 100644
index 0000000..6b1b0a1
--- /dev/null
+++ b/doc/d3-authenticationcode-esES.txt
@@ -0,0 +1 @@
+PBGFBE42Z6LNK65UGJQ3WZVMCLP4HQQT \ No newline at end of file
diff --git a/doc/d3-authenticationcode-esMX.txt b/doc/d3-authenticationcode-esMX.txt
new file mode 100644
index 0000000..504759e
--- /dev/null
+++ b/doc/d3-authenticationcode-esMX.txt
@@ -0,0 +1 @@
+X7SEJJS9TSGCW5P28EBSC47AJPEY8VU2 \ No newline at end of file
diff --git a/doc/d3-authenticationcode-frFR.txt b/doc/d3-authenticationcode-frFR.txt
new file mode 100644
index 0000000..bb35a2b
--- /dev/null
+++ b/doc/d3-authenticationcode-frFR.txt
@@ -0,0 +1 @@
+5KVBQA8VYE6XRY3DLGC5ZDE4XS4P7YA2 \ No newline at end of file
diff --git a/doc/d3-authenticationcode-itIT.txt b/doc/d3-authenticationcode-itIT.txt
new file mode 100644
index 0000000..a62031d
--- /dev/null
+++ b/doc/d3-authenticationcode-itIT.txt
@@ -0,0 +1 @@
+478JD2K56EVNVVY4XX8TDWYT5B8KB254 \ No newline at end of file
diff --git a/doc/d3-authenticationcode-koKR.txt b/doc/d3-authenticationcode-koKR.txt
new file mode 100644
index 0000000..296ffcc
--- /dev/null
+++ b/doc/d3-authenticationcode-koKR.txt
@@ -0,0 +1 @@
+8TS4VNFQRZTN6YWHE9CHVDH9NVWD474A \ No newline at end of file
diff --git a/doc/d3-authenticationcode-plPL.txt b/doc/d3-authenticationcode-plPL.txt
new file mode 100644
index 0000000..a92563c
--- /dev/null
+++ b/doc/d3-authenticationcode-plPL.txt
@@ -0,0 +1 @@
+LJ52Z32DF4LZ4ZJJXVKK3AZQA6GABLJB \ No newline at end of file
diff --git a/doc/d3-authenticationcode-ptBR.txt b/doc/d3-authenticationcode-ptBR.txt
new file mode 100644
index 0000000..e6e5c35
--- /dev/null
+++ b/doc/d3-authenticationcode-ptBR.txt
@@ -0,0 +1 @@
+K6BDHY2ECUE2545YKNLBJPVYWHE7XYAG \ No newline at end of file
diff --git a/doc/d3-authenticationcode-zhTW.txt b/doc/d3-authenticationcode-zhTW.txt
new file mode 100644
index 0000000..138a544
--- /dev/null
+++ b/doc/d3-authenticationcode-zhTW.txt
@@ -0,0 +1 @@
+6VWCQTN8V3ZZMRUCZXV8A8CGUX2TAA8H \ No newline at end of file
diff --git a/doc/diablo3_ruru_disk_encrypted_win.blob b/doc/diablo3_ruru_disk_encrypted_win.blob
new file mode 100644
index 0000000..7972b2d
--- /dev/null
+++ b/doc/diablo3_ruru_disk_encrypted_win.blob
@@ -0,0 +1,49 @@
+{
+"config":{
+ "product": "D3",
+ "install_progress_percent": 70.0,
+ "install_progress_info": [8000000000.0, 0.0, 0.0],
+ "download_progress_info": [10000000.0, 500000000.0, 500000000.0],
+ "install_progress_speed": 5000000.0,
+ "tome_download_progress_percent": 0.0,
+ "updater_product": "d3_patch",
+ "expansion_level": 0,
+ "ptr": false,
+ "beta": false,
+ "update_method": "patch on demand",
+ "supports_multibox": false,
+ "data_dir": "Data_D3/PC/MPQs/",
+ "patch_url": "http://ruRU.patch.battle.net:1119/patch",
+ "update_regex": "(?P<prefix>d3-update-(?P<dataset>\\w+))-(?P<build>\\d+)\\.mpq$",
+ "update_identifier": "d3-update-",
+ "torrent_file_path": "Diablo III.tfil",
+ "manifest_file_path": "Diablo III.mfil",
+ "priority_file_path": "Diablo III.pfil",
+ "priority_file_layout": "Retail",
+ "binary_version_path": "Diablo III.exe",
+ "binary_launch_path": "Diablo III.exe",
+ "display_locales":["ruRU"],
+ "supported_locales" : ["enUS", "esMX", "ptBR", "enGB", "deDE", "esES", "frFR", "itIT", "plPL", "enSG", "ptPT", "ruRU", "koKR", "zhTW", "zhCN"],
+ "launch_arguments":["-launch","-uid","diablo3_ruru"],
+ "form": {
+ "eula": {
+ "eula":false
+ },
+ "game_dir": {
+ "default": "Program Files",
+ "dirname": "Diablo III",
+ "required_space": 15032385536
+ },
+ "language": {
+ "default":["ruRU"],
+ "list":["ruRU"]
+ },
+ "authentication_key": {
+ "url": [
+ "http://ruru.nydus.battle.net/D3/ruRU/setup/mediakey",
+ "http://dist.blizzard.com/mediakey/d3-authenticationcode-ruRU.txt"
+ ]
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/doc/diablo3_urls.txt b/doc/diablo3_urls.txt
new file mode 100644
index 0000000..d89f489
--- /dev/null
+++ b/doc/diablo3_urls.txt
@@ -0,0 +1,14 @@
+http://dist.blizzard.com/mediakey/d3-authenticationcode-deDE.txt
+http://dist.blizzard.com/mediakey/d3-authenticationcode-enGB.txt
+http://dist.blizzard.com/mediakey/d3-authenticationcode-enSG.txt
+http://dist.blizzard.com/mediakey/d3-authenticationcode-enUS.txt
+http://dist.blizzard.com/mediakey/d3-authenticationcode-esES.txt
+http://dist.blizzard.com/mediakey/d3-authenticationcode-esMX.txt
+http://dist.blizzard.com/mediakey/d3-authenticationcode-frFR.txt
+http://dist.blizzard.com/mediakey/d3-authenticationcode-itIT.txt
+http://dist.blizzard.com/mediakey/d3-authenticationcode-koKR.txt
+http://dist.blizzard.com/mediakey/d3-authenticationcode-plPL.txt
+http://dist.blizzard.com/mediakey/d3-authenticationcode-ptBR.txt
+http://dist.blizzard.com/mediakey/d3-authenticationcode-ruRU.txt <====
+http://dist.blizzard.com/mediakey/d3-authenticationcode-zhTW.txt
+http://dist.blizzard.com/mediakey/d3-authenticationcode-zhCN.txt <====
diff --git a/makefile.w32 b/makefile.w32
new file mode 100644
index 0000000..8826ccd
--- /dev/null
+++ b/makefile.w32
@@ -0,0 +1,268 @@
+#####################################################################
+#
+# Makefile for compiling StormLib with MINGW
+#
+# Author: Ladislav Zezula
+# Created: Mon May 10 14:13:00 CEST 2010
+# System: Windows Seven
+#
+#####################################################################
+
+PATH = C:\TOOLS32\MINGW\bin
+CPP = g++
+CC = gcc
+CFLAGS = -Wall
+DFLAGS = -D_7ZIP_ST
+LFLAGS = -shared
+#LFLAGS = -lbz2 -lz
+AR = ar
+ARFLAGS= rcs
+
+LIBRARY = StormLib.dll
+#LIBRARY = StormLib.lib
+
+OBJS_CPP = src/adpcm/adpcm.o \
+ src/huffman/huff.o \
+ src/sparse/sparse.o \
+ src/FileStream.o \
+ src/SBaseCommon.o \
+ src/SBaseFileTable.o \
+ src/SCompression.o \
+ src/SFileAddFile.o \
+ src/SFileAttributes.o \
+ src/SFileCompactArchive.o \
+ src/SFileCreateArchive.o \
+ src/SFileExtractFile.o \
+ src/SFileFindFile.o \
+ src/SFileListFile.o \
+ src/SFileOpenArchive.o \
+ src/SFileOpenFileEx.o \
+ src/SFilePatchArchives.o \
+ src/SFileReadFile.o \
+ src/SFileVerify.o
+
+
+OBJS_C = src/bzip2/blocksort.o \
+ src/bzip2/bzlib.o \
+ src/bzip2/compress.o \
+ src/bzip2/crctable.o \
+ src/bzip2/decompress.o \
+ src/bzip2/huffman.o \
+ src/bzip2/randtable.o \
+ src/jenkins/lookup3.o \
+ src/libtomcrypt/src/hashes/hash_memory.o \
+ src/libtomcrypt/src/hashes/md5.o \
+ src/libtomcrypt/src/hashes/sha1.o\
+ src/libtomcrypt/src/math/ltm_desc.o \
+ src/libtomcrypt/src/math/multi.o \
+ src/libtomcrypt/src/math/rand_prime.o \
+ src/libtomcrypt/src/misc/base64_decode.o \
+ src/libtomcrypt/src/misc/crypt_argchk.o \
+ src/libtomcrypt/src/misc/crypt_find_hash.o \
+ src/libtomcrypt/src/misc/crypt_find_prng.o \
+ src/libtomcrypt/src/misc/crypt_hash_descriptor.o \
+ src/libtomcrypt/src/misc/crypt_hash_is_valid.o \
+ src/libtomcrypt/src/misc/crypt_libc.o \
+ src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.o \
+ src/libtomcrypt/src/misc/crypt_prng_descriptor.o \
+ src/libtomcrypt/src/misc/crypt_prng_is_valid.o \
+ src/libtomcrypt/src/misc/crypt_register_hash.o \
+ src/libtomcrypt/src/misc/crypt_register_prng.o \
+ src/libtomcrypt/src/misc/zeromem.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_bit_string.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_boolean.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_choice.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_integer.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_octet_string.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_printable_string.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_short_integer.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_utctime.o \
+ src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.o \
+ src/libtomcrypt/src/pk/asn1/der_length_bit_string.o \
+ src/libtomcrypt/src/pk/asn1/der_length_boolean.o \
+ src/libtomcrypt/src/pk/asn1/der_length_ia5_string.o \
+ src/libtomcrypt/src/pk/asn1/der_length_integer.o \
+ src/libtomcrypt/src/pk/asn1/der_length_object_identifier.o \
+ src/libtomcrypt/src/pk/asn1/der_length_octet_string.o \
+ src/libtomcrypt/src/pk/asn1/der_length_printable_string.o \
+ src/libtomcrypt/src/pk/asn1/der_length_sequence.o \
+ src/libtomcrypt/src/pk/asn1/der_length_short_integer.o \
+ src/libtomcrypt/src/pk/asn1/der_length_utctime.o \
+ src/libtomcrypt/src/pk/asn1/der_length_utf8_string.o \
+ src/libtomcrypt/src/pk/asn1/der_sequence_free.o \
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_map.o \
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.o \
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.o \
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_points.o \
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.o \
+ src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.o \
+ src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.o \
+ src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.o \
+ src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.o \
+ src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.o \
+ src/libtomcrypt/src/pk/rsa/rsa_exptmod.o \
+ src/libtomcrypt/src/pk/rsa/rsa_free.o \
+ src/libtomcrypt/src/pk/rsa/rsa_import.o \
+ src/libtomcrypt/src/pk/rsa/rsa_make_key.o \
+ src/libtomcrypt/src/pk/rsa/rsa_verify_hash.o \
+ src/libtomcrypt/src/pk/rsa/rsa_verify_simple.o \
+ src/libtommath/bncore.o \
+ src/libtommath/bn_fast_mp_invmod.o \
+ src/libtommath/bn_fast_mp_montgomery_reduce.o \
+ src/libtommath/bn_fast_s_mp_mul_digs.o \
+ src/libtommath/bn_fast_s_mp_mul_high_digs.o \
+ src/libtommath/bn_fast_s_mp_sqr.o \
+ src/libtommath/bn_mp_2expt.o \
+ src/libtommath/bn_mp_abs.o \
+ src/libtommath/bn_mp_add.o \
+ src/libtommath/bn_mp_addmod.o \
+ src/libtommath/bn_mp_add_d.o \
+ src/libtommath/bn_mp_and.o \
+ src/libtommath/bn_mp_clamp.o \
+ src/libtommath/bn_mp_clear.o \
+ src/libtommath/bn_mp_clear_multi.o \
+ src/libtommath/bn_mp_cmp.o \
+ src/libtommath/bn_mp_cmp_d.o \
+ src/libtommath/bn_mp_cmp_mag.o \
+ src/libtommath/bn_mp_cnt_lsb.o \
+ src/libtommath/bn_mp_copy.o \
+ src/libtommath/bn_mp_count_bits.o \
+ src/libtommath/bn_mp_div.o \
+ src/libtommath/bn_mp_div_2.o \
+ src/libtommath/bn_mp_div_2d.o \
+ src/libtommath/bn_mp_div_3.o \
+ src/libtommath/bn_mp_div_d.o \
+ src/libtommath/bn_mp_dr_is_modulus.o \
+ src/libtommath/bn_mp_dr_reduce.o \
+ src/libtommath/bn_mp_dr_setup.o \
+ src/libtommath/bn_mp_exch.o \
+ src/libtommath/bn_mp_exptmod.o \
+ src/libtommath/bn_mp_exptmod_fast.o \
+ src/libtommath/bn_mp_expt_d.o \
+ src/libtommath/bn_mp_exteuclid.o \
+ src/libtommath/bn_mp_fread.o \
+ src/libtommath/bn_mp_fwrite.o \
+ src/libtommath/bn_mp_gcd.o \
+ src/libtommath/bn_mp_get_int.o \
+ src/libtommath/bn_mp_grow.o \
+ src/libtommath/bn_mp_init.o \
+ src/libtommath/bn_mp_init_copy.o \
+ src/libtommath/bn_mp_init_multi.o \
+ src/libtommath/bn_mp_init_set.o \
+ src/libtommath/bn_mp_init_set_int.o \
+ src/libtommath/bn_mp_init_size.o \
+ src/libtommath/bn_mp_invmod.o \
+ src/libtommath/bn_mp_invmod_slow.o \
+ src/libtommath/bn_mp_is_square.o \
+ src/libtommath/bn_mp_jacobi.o \
+ src/libtommath/bn_mp_karatsuba_mul.o \
+ src/libtommath/bn_mp_karatsuba_sqr.o \
+ src/libtommath/bn_mp_lcm.o \
+ src/libtommath/bn_mp_lshd.o \
+ src/libtommath/bn_mp_mod.o \
+ src/libtommath/bn_mp_mod_2d.o \
+ src/libtommath/bn_mp_mod_d.o \
+ src/libtommath/bn_mp_montgomery_calc_normalization.o \
+ src/libtommath/bn_mp_montgomery_reduce.o \
+ src/libtommath/bn_mp_montgomery_setup.o \
+ src/libtommath/bn_mp_mul.o \
+ src/libtommath/bn_mp_mulmod.o \
+ src/libtommath/bn_mp_mul_2.o \
+ src/libtommath/bn_mp_mul_2d.o \
+ src/libtommath/bn_mp_mul_d.o \
+ src/libtommath/bn_mp_neg.o \
+ src/libtommath/bn_mp_n_root.o \
+ src/libtommath/bn_mp_or.o \
+ src/libtommath/bn_mp_prime_fermat.o \
+ src/libtommath/bn_mp_prime_is_divisible.o \
+ src/libtommath/bn_mp_prime_is_prime.o \
+ src/libtommath/bn_mp_prime_miller_rabin.o \
+ src/libtommath/bn_mp_prime_next_prime.o \
+ src/libtommath/bn_mp_prime_rabin_miller_trials.o \
+ src/libtommath/bn_mp_prime_random_ex.o \
+ src/libtommath/bn_mp_radix_size.o \
+ src/libtommath/bn_mp_radix_smap.o \
+ src/libtommath/bn_mp_rand.o \
+ src/libtommath/bn_mp_read_radix.o \
+ src/libtommath/bn_mp_read_signed_bin.o \
+ src/libtommath/bn_mp_read_unsigned_bin.o \
+ src/libtommath/bn_mp_reduce.o \
+ src/libtommath/bn_mp_reduce_2k.o \
+ src/libtommath/bn_mp_reduce_2k_l.o \
+ src/libtommath/bn_mp_reduce_2k_setup.o \
+ src/libtommath/bn_mp_reduce_2k_setup_l.o \
+ src/libtommath/bn_mp_reduce_is_2k.o \
+ src/libtommath/bn_mp_reduce_is_2k_l.o \
+ src/libtommath/bn_mp_reduce_setup.o \
+ src/libtommath/bn_mp_rshd.o \
+ src/libtommath/bn_mp_set.o \
+ src/libtommath/bn_mp_set_int.o \
+ src/libtommath/bn_mp_shrink.o \
+ src/libtommath/bn_mp_signed_bin_size.o \
+ src/libtommath/bn_mp_sqr.o \
+ src/libtommath/bn_mp_sqrmod.o \
+ src/libtommath/bn_mp_sqrt.o \
+ src/libtommath/bn_mp_sub.o \
+ src/libtommath/bn_mp_submod.o \
+ src/libtommath/bn_mp_sub_d.o \
+ src/libtommath/bn_mp_toom_mul.o \
+ src/libtommath/bn_mp_toom_sqr.o \
+ src/libtommath/bn_mp_toradix.o \
+ src/libtommath/bn_mp_toradix_n.o \
+ src/libtommath/bn_mp_to_signed_bin.o \
+ src/libtommath/bn_mp_to_signed_bin_n.o \
+ src/libtommath/bn_mp_to_unsigned_bin.o \
+ src/libtommath/bn_mp_to_unsigned_bin_n.o \
+ src/libtommath/bn_mp_unsigned_bin_size.o \
+ src/libtommath/bn_mp_xor.o \
+ src/libtommath/bn_mp_zero.o \
+ src/libtommath/bn_prime_tab.o \
+ src/libtommath/bn_reverse.o \
+ src/libtommath/bn_s_mp_add.o \
+ src/libtommath/bn_s_mp_exptmod.o \
+ src/libtommath/bn_s_mp_mul_digs.o \
+ src/libtommath/bn_s_mp_mul_high_digs.o \
+ src/libtommath/bn_s_mp_sqr.o \
+ src/libtommath/bn_s_mp_sub.o \
+ src/lzma/C/LzFind.o \
+ src/lzma/C/LzmaDec.o \
+ src/lzma/C/LzmaEnc.o \
+ src/pklib/explode.o \
+ src/pklib/implode.o \
+ src/zlib/adler32.o \
+ src/zlib/compress2.o \
+ src/zlib/crc32.o \
+ src/zlib/deflate.o \
+ src/zlib/inffast.o \
+ src/zlib/inflate.o \
+ src/zlib/inftrees.o \
+ src/zlib/trees.o \
+ src/zlib/zutil.o \
+ stormlib_dll/DllMain.o
+
+all: $(LIBRARY)
+
+#clean:
+# rm -f $(OBJS) $(LIBRARY)
+
+#install: $(LIBRARY)
+# install $(LIBRARY) /usr/local/lib
+# mkdir -p /usr/local/include/StormLib
+# cp StormLib.h /usr/local/include/StormLib
+# cp StormPort.h /usr/local/include/StormLib
+
+$(LIBRARY): $(OBJS_C) $(OBJS_CPP)
+ $(CPP) $(CFLAGS) $(DFLAGS) -o $(LIBRARY) $(OBJS_C) $(OBJS_CPP) $(LFLAGS)
+ $(AR) $(ARFLAGS) $(LIBRARY) $(OBJS_C) $(OBJS_CPP)
+
+$(OBJS_C): %.o: %.c
+ $(CC) -o $@ $(CFLAGS) $(DFLAGS) -c $<
+
+$(OBJS_CPP): %.o: %.cpp
+ $(CC) -o $@ $(CFLAGS) $(DFLAGS) -c $<
+
diff --git a/src/FileStream.cpp b/src/FileStream.cpp
new file mode 100644
index 0000000..1a21170
--- /dev/null
+++ b/src/FileStream.cpp
@@ -0,0 +1,2294 @@
+/*****************************************************************************/
+/* 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")
+#endif
+
+//-----------------------------------------------------------------------------
+// Local defines
+
+#ifndef INVALID_HANDLE_VALUE
+#define INVALID_HANDLE_VALUE ((HANDLE)-1)
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4800) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
+#endif
+
+//-----------------------------------------------------------------------------
+// Local functions - platform-specific functions
+
+#ifndef PLATFORM_WINDOWS
+static int nLastError = ERROR_SUCCESS;
+
+int GetLastError()
+{
+ return nLastError;
+}
+
+void SetLastError(int nError)
+{
+ nLastError = nError;
+}
+#endif
+
+#ifndef PLATFORM_LITTLE_ENDIAN
+void ConvertPartHeader(void * partHeader)
+{
+ PPART_FILE_HEADER theHeader = (PPART_FILE_HEADER)partHeader;
+
+ theHeader->PartialVersion = SwapUInt32(theHeader->PartialVersion);
+ theHeader->Flags = SwapUInt32(theHeader->Flags);
+ theHeader->FileSizeLo = SwapUInt32(theHeader->FileSizeLo);
+ theHeader->FileSizeHi = SwapUInt32(theHeader->FileSizeHi);
+ theHeader->BlockSize = SwapUInt32(theHeader->BlockSize);
+}
+#endif
+
+//-----------------------------------------------------------------------------
+// Preparing file bitmap for a complete file of a given size
+
+#define DEFAULT_BLOCK_SIZE 0x4000
+
+static bool Dummy_GetBitmap(
+ TFileStream * pStream,
+ TFileBitmap * pBitmap,
+ DWORD Length,
+ LPDWORD LengthNeeded)
+{
+ ULONGLONG FileSize = 0;
+ DWORD TotalLength;
+ DWORD BlockCount;
+ DWORD BitmapSize;
+ DWORD LastByte;
+ bool bResult = false;
+
+ // Get file size and calculate bitmap length
+ FileStream_GetSize(pStream, &FileSize);
+ BlockCount = (DWORD)(((FileSize - 1) / DEFAULT_BLOCK_SIZE) + 1);
+ BitmapSize = (DWORD)(((BlockCount - 1) / 8) + 1);
+
+ // Calculate and give the total length
+ TotalLength = sizeof(TFileBitmap) + BitmapSize;
+ if(LengthNeeded != NULL)
+ *LengthNeeded = TotalLength;
+
+ // Has the caller given enough space for storing the structure?
+ if(Length >= sizeof(TFileBitmap))
+ {
+ memset(pBitmap, 0, sizeof(TFileBitmap));
+ pBitmap->EndOffset = FileSize;
+ pBitmap->IsComplete = 1;
+ pBitmap->BitmapSize = BitmapSize;
+ pBitmap->BlockSize = DEFAULT_BLOCK_SIZE;
+ bResult = true;
+ }
+
+ // Do we have enough space to fill the bitmap as well?
+ if(Length >= TotalLength)
+ {
+ LPBYTE pbBitmap = (LPBYTE)(pBitmap + 1);
+
+ // Fill the full blocks
+ memset(pbBitmap, 0xFF, (BlockCount / 8));
+ pbBitmap += (BlockCount / 8);
+ bResult = true;
+
+ // Supply the last block
+ if(BlockCount & 7)
+ {
+ LastByte = (1 << (BlockCount & 7)) - 1;
+ pbBitmap[0] = (BYTE)LastByte;
+ }
+ }
+
+ return bResult;
+}
+
+//-----------------------------------------------------------------------------
+// Local functions - base file support
+
+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 PLATFORM_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;
+ }
+/*
+ // If the byte offset is different from the current file position,
+ // we have to update the file position
+ if(ByteOffset != pStream->Base.File.FilePos)
+ {
+ LONG ByteOffsetHi = (LONG)(ByteOffset >> 32);
+
+ SetFilePointer(pStream->Base.File.hFile, (LONG)ByteOffset, &ByteOffsetHi, FILE_BEGIN);
+ pStream->Base.File.FilePos = ByteOffset;
+ }
+
+ // Read the data
+ if(dwBytesToRead != 0)
+ {
+ if(!ReadFile(pStream->Base.File.hFile, pvBuffer, dwBytesToRead, &dwBytesRead, NULL))
+ return false;
+ }
+*/
+ }
+#endif
+
+#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ {
+ ssize_t bytes_read;
+
+ // If the byte offset is different from the current file position,
+ // we have to update the file position
+ if(ByteOffset != pStream->Base.File.FilePos)
+ {
+ lseek((intptr_t)pStream->Base.File.hFile, (off_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)
+ {
+ nLastError = 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 PLATFORM_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;
+ }
+/*
+ // If the byte offset is different from the current file position,
+ // we have to update the file position
+ if(ByteOffset != pStream->Base.File.FilePos)
+ {
+ LONG ByteOffsetHi = (LONG)(ByteOffset >> 32);
+
+ SetFilePointer(pStream->Base.File.hFile, (LONG)ByteOffset, &ByteOffsetHi, FILE_BEGIN);
+ pStream->Base.File.FilePos = ByteOffset;
+ }
+
+ // Read the data
+ if(dwBytesToWrite != 0)
+ {
+ if(!WriteFile(pStream->Base.File.hFile, pvBuffer, dwBytesToWrite, &dwBytesWritten, NULL))
+ return false;
+ }
+*/
+ }
+#endif
+
+#if defined(PLATFORM_MAC) || defined(PLATFORM_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)
+ {
+ lseek((intptr_t)pStream->Base.File.hFile, (off_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)
+ {
+ nLastError = 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);
+}
+
+static bool BaseFile_GetPos(
+ TFileStream * pStream, // Pointer to an open stream
+ ULONGLONG * pByteOffset) // Pointer to file byte offset
+{
+ *pByteOffset = pStream->Base.File.FilePos;
+ return true;
+}
+
+static bool BaseFile_GetSize(
+ TFileStream * pStream, // Pointer to an open stream
+ ULONGLONG * pFileSize) // Pointer where to store file size
+{
+ *pFileSize = pStream->Base.File.FileSize;
+ return true;
+}
+
+/**
+ * \a pStream Pointer to an open stream
+ * \a NewFileSize New size of the file
+ */
+static bool BaseFile_SetSize(TFileStream * pStream, ULONGLONG NewFileSize)
+{
+#ifdef PLATFORM_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);
+
+ // 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(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ {
+ if(ftruncate((intptr_t)pStream->Base.File.hFile, (off_t)NewFileSize) == -1)
+ {
+ nLastError = errno;
+ return false;
+ }
+
+ return true;
+ }
+#endif
+}
+
+static bool BaseFile_GetTime(TFileStream * pStream, ULONGLONG * pFileTime)
+{
+ *pFileTime = pStream->Base.File.FileTime;
+ return true;
+}
+
+// Renames the file pointed by pStream so that it contains data from pNewStream
+static bool BaseFile_Switch(TFileStream * pStream, TFileStream * pNewStream)
+{
+#ifdef PLATFORM_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(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ // "rename" on Linux also works if the target file exists
+ if(rename(pNewStream->szFileName, pStream->szFileName) == -1)
+ {
+ nLastError = errno;
+ return false;
+ }
+
+ return true;
+#endif
+}
+
+static void BaseFile_Close(TFileStream * pStream)
+{
+ if(pStream->Base.File.hFile != INVALID_HANDLE_VALUE)
+ {
+#ifdef PLATFORM_WINDOWS
+ CloseHandle(pStream->Base.File.hFile);
+#endif
+
+#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ close((intptr_t)pStream->Base.File.hFile);
+#endif
+ }
+
+ // Also invalidate the handle
+ pStream->Base.File.hFile = INVALID_HANDLE_VALUE;
+}
+
+static bool BaseFile_Create(
+ TFileStream * pStream,
+ const TCHAR * szFileName,
+ DWORD dwStreamFlags)
+{
+#ifdef PLATFORM_WINDOWS
+ {
+ DWORD dwWriteShare = (dwStreamFlags & STREAM_FLAG_WRITE_SHARE) ? FILE_SHARE_WRITE : 0;
+
+ pStream->Base.File.hFile = CreateFile(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(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ {
+ intptr_t handle;
+
+ handle = open(szFileName, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ if(handle == -1)
+ {
+ nLastError = errno;
+ return false;
+ }
+
+ pStream->Base.File.hFile = (HANDLE)handle;
+ }
+#endif
+
+ // Fill-in the entry points
+ pStream->BaseRead = BaseFile_Read;
+ pStream->BaseWrite = BaseFile_Write;
+ pStream->BaseGetPos = BaseFile_GetPos;
+ pStream->BaseGetSize = BaseFile_GetSize;
+ pStream->BaseSetSize = BaseFile_SetSize;
+ pStream->BaseSetSize = BaseFile_SetSize;
+ pStream->BaseGetTime = BaseFile_GetTime;
+ pStream->BaseClose = BaseFile_Close;
+
+ // Reset the file position
+ pStream->Base.File.FileSize = 0;
+ pStream->Base.File.FilePos = 0;
+ pStream->dwFlags = dwStreamFlags;
+ return true;
+}
+
+static bool BaseFile_Open(
+ TFileStream * pStream,
+ const TCHAR * szFileName,
+ DWORD dwStreamFlags)
+{
+#ifdef PLATFORM_WINDOWS
+ {
+ ULARGE_INTEGER FileSize;
+ DWORD dwDesiredAccess = (dwStreamFlags & STREAM_FLAG_READ_ONLY) ? GENERIC_READ : GENERIC_ALL;
+ DWORD dwWriteShare = (dwStreamFlags & STREAM_FLAG_WRITE_SHARE) ? FILE_SHARE_WRITE : 0;
+
+ // Open the file
+ pStream->Base.File.hFile = CreateFile(szFileName,
+ dwDesiredAccess,
+ dwWriteShare | FILE_SHARE_READ,
+ 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(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ {
+ struct stat fileinfo;
+ int oflag = (dwStreamFlags & STREAM_FLAG_READ_ONLY) ? O_RDONLY : O_RDWR;
+ intptr_t handle;
+
+ // Open the file
+ handle = open(szFileName, oflag);
+ if(handle == -1)
+ {
+ nLastError = errno;
+ return false;
+ }
+
+ // Get the file size
+ if(fstat(handle, &fileinfo) == -1)
+ {
+ nLastError = errno;
+ 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
+
+ // Fill-in the entry points
+ pStream->BaseRead = BaseFile_Read;
+ pStream->BaseWrite = BaseFile_Write;
+ pStream->BaseGetPos = BaseFile_GetPos;
+ pStream->BaseGetSize = BaseFile_GetSize;
+ pStream->BaseSetSize = BaseFile_SetSize;
+ pStream->BaseGetTime = BaseFile_GetTime;
+ pStream->BaseClose = BaseFile_Close;
+
+ // Reset the file position
+ pStream->Base.File.FilePos = 0;
+ pStream->dwFlags = dwStreamFlags;
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Local functions - base memory-mapped file support
+
+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 bool BaseMap_GetPos(
+ TFileStream * pStream, // Pointer to an open stream
+ ULONGLONG * pByteOffset) // Pointer to file byte offset
+{
+ *pByteOffset = pStream->Base.Map.FilePos;
+ return true;
+}
+
+static bool BaseMap_GetSize(
+ TFileStream * pStream, // Pointer to an open stream
+ ULONGLONG * pFileSize) // Pointer where to store file size
+{
+ *pFileSize = pStream->Base.Map.FileSize;
+ return true;
+}
+
+static bool BaseMap_GetTime(TFileStream * pStream, ULONGLONG * pFileTime)
+{
+ *pFileTime = pStream->Base.Map.FileTime;
+ return true;
+}
+
+static void BaseMap_Close(TFileStream * pStream)
+{
+#ifdef PLATFORM_WINDOWS
+ if(pStream->Base.Map.pbFile != NULL)
+ UnmapViewOfFile(pStream->Base.Map.pbFile);
+#endif
+
+#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ if(pStream->Base.Map.pbFile != NULL)
+ munmap(pStream->Base.Map.pbFile, (size_t )pStream->Base.Map.FileSize);
+#endif
+
+ pStream->Base.Map.pbFile = NULL;
+}
+
+static bool BaseMap_Open(
+ TFileStream * pStream,
+ const TCHAR * szFileName,
+ DWORD dwStreamFlags)
+{
+#ifdef PLATFORM_WINDOWS
+
+ ULARGE_INTEGER FileSize;
+ HANDLE hFile;
+ HANDLE hMap;
+ bool bResult = false;
+
+ // Open the file for read access
+ hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if(hFile != NULL)
+ {
+ // Retrieve file size. Don't allow mapping file of a zero size.
+ FileSize.LowPart = GetFileSize(hFile, &FileSize.HighPart);
+ if(FileSize.QuadPart != 0)
+ {
+ // Retrieve file time
+ GetFileTime(hFile, NULL, NULL, (LPFILETIME)&pStream->Base.Map.FileTime);
+
+ // Now create mapping object
+ hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+ 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)
+ {
+ pStream->Base.Map.FileSize = FileSize.QuadPart;
+ pStream->Base.Map.FilePos = 0;
+ bResult = true;
+ }
+
+ // Close the map handle
+ CloseHandle(hMap);
+ }
+ }
+
+ // Close the file handle
+ CloseHandle(hFile);
+ }
+
+ // If the file is not there and is not available for random access,
+ // report error
+ if(bResult == false)
+ return false;
+#endif
+
+#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ struct stat fileinfo;
+ intptr_t handle;
+ bool bResult = false;
+
+ // Open the file
+ handle = open(szFileName, O_RDONLY);
+ if(handle != -1)
+ {
+ // Get the file size
+ if(fstat(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)
+ {
+ nLastError = errno;
+ return false;
+ }
+#endif
+
+ // Fill-in entry points
+ pStream->BaseRead = BaseMap_Read;
+ pStream->BaseGetPos = BaseMap_GetPos;
+ pStream->BaseGetSize = BaseMap_GetSize;
+ pStream->BaseGetTime = BaseMap_GetTime;
+ pStream->BaseClose = BaseMap_Close;
+ pStream->dwFlags = dwStreamFlags;
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// 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_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 PLATFORM_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;
+ BYTE Buffer[0x200];
+
+ // 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
+ _stprintf(szRangeRequest, _T("Range: bytes=%d-%d"), dwStartOffset, 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 > sizeof(Buffer))
+ dwBlockBytesToRead = sizeof(Buffer);
+ 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 bool BaseHttp_GetPos(
+ TFileStream * pStream, // Pointer to an open stream
+ ULONGLONG * pByteOffset) // Pointer to file byte offset
+{
+ *pByteOffset = pStream->Base.Http.FilePos;
+ return true;
+}
+
+static bool BaseHttp_GetSize(
+ TFileStream * pStream, // Pointer to an open stream
+ ULONGLONG * pFileSize) // Pointer where to store file size
+{
+ *pFileSize = pStream->Base.Http.FileSize;
+ return true;
+}
+
+static bool BaseHttp_GetTime(TFileStream * pStream, ULONGLONG * pFileTime)
+{
+ *pFileTime = pStream->Base.Http.FileTime;
+ return true;
+}
+
+static void BaseHttp_Close(TFileStream * pStream)
+{
+#ifdef PLATFORM_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
+}
+
+static bool BaseHttp_Open(
+ TFileStream * pStream,
+ const TCHAR * szFileName,
+ DWORD dwStreamFlags)
+{
+#ifdef PLATFORM_WINDOWS
+
+ HINTERNET hRequest;
+ DWORD dwTemp = 0;
+ bool bFileAvailable = false;
+ int nError = ERROR_SUCCESS;
+
+ // Don't connect to the internet
+ if(!InternetGetConnectedState(&dwTemp, 0))
+ nError = GetLastError();
+
+ // Initiate the connection to the internet
+ if(nError == ERROR_SUCCESS)
+ {
+ pStream->Base.Http.hInternet = InternetOpen(_T("StormLib HTTP MPQ reader"),
+ INTERNET_OPEN_TYPE_PRECONFIG,
+ NULL,
+ NULL,
+ 0);
+ if(pStream->Base.Http.hInternet == NULL)
+ nError = GetLastError();
+ }
+
+ // Connect to the server
+ if(nError == ERROR_SUCCESS)
+ {
+ 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)
+ nError = GetLastError();
+ }
+
+ // Now try to query the file size
+ if(nError == ERROR_SUCCESS)
+ {
+ // 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;
+
+ // 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)
+ {
+ pStream->Base.Http.FileSize = dwFileSize;
+ pStream->Base.Http.FilePos = 0;
+ bFileAvailable = true;
+ }
+ }
+ }
+ InternetCloseHandle(hRequest);
+ }
+ }
+
+ // If the file is not there and is not available for random access,
+ // report error
+ if(bFileAvailable == false)
+ {
+ BaseHttp_Close(pStream);
+ return false;
+ }
+
+ // Fill-in entry points
+ pStream->BaseRead = BaseHttp_Read;
+ pStream->BaseGetPos = BaseHttp_GetPos;
+ pStream->BaseGetSize = BaseHttp_GetSize;
+ pStream->BaseGetTime = BaseHttp_GetTime;
+ pStream->BaseClose = BaseHttp_Close;
+ pStream->dwFlags = dwStreamFlags;
+ return true;
+
+#else
+
+ // Not supported
+ pStream = pStream;
+ szFileName = szFileName;
+ SetLastError(ERROR_NOT_SUPPORTED);
+ return false;
+
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Local functions - linear stream support
+
+static bool LinearStream_Read(
+ TLinearStream * 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;
+ ULONGLONG EndOffset;
+ LPBYTE pbBitmap;
+ DWORD BlockIndex;
+ DWORD ByteIndex;
+ DWORD BitMask;
+
+ // At this point, we must have a bitmap set
+ assert(pStream->pBitmap != NULL);
+
+ // If we have data map, we must check if the data block is present in the MPQ
+ if(dwBytesToRead != 0)
+ {
+ DWORD BlockSize = pStream->pBitmap->BlockSize;
+
+ // Get the offset where we read it from
+ if(pByteOffset == NULL)
+ pStream->BaseGetPos(pStream, &ByteOffset);
+ else
+ ByteOffset = *pByteOffset;
+ EndOffset = ByteOffset + dwBytesToRead;
+
+ // If the start of the area is within the region
+ // protected by data map, check each block
+ if(ByteOffset < pStream->pBitmap->EndOffset)
+ {
+ // Cut the end of the stream protected by the data map
+ EndOffset = STORMLIB_MIN(EndOffset, pStream->pBitmap->EndOffset);
+
+ // Calculate the initial block index
+ BlockIndex = (DWORD)(ByteOffset / BlockSize);
+ pbBitmap = (LPBYTE)(pStream->pBitmap + 1);
+
+ // Parse each block
+ while(ByteOffset < EndOffset)
+ {
+ // Prepare byte index and bit mask
+ ByteIndex = BlockIndex / 8;
+ BitMask = 1 << (BlockIndex & 0x07);
+
+ // If that bit is not set, it means that the block is not present
+ if((pbBitmap[ByteIndex] & BitMask) == 0)
+ {
+ SetLastError(ERROR_FILE_CORRUPT);
+ return false;
+ }
+
+ // Move to tne next block
+ ByteOffset += BlockSize;
+ BlockIndex++;
+ }
+ }
+ }
+
+ // Now if all tests passed, we can call the base read function
+ return pStream->BaseRead(pStream, pByteOffset, pvBuffer, dwBytesToRead);
+}
+
+static bool LinearStream_Switch(TLinearStream * pStream, TLinearStream * pNewStream)
+{
+ // Sanity checks
+ assert((pNewStream->dwFlags & STREAM_PROVIDER_MASK) == STREAM_PROVIDER_LINEAR);
+ assert((pNewStream->dwFlags & BASE_PROVIDER_MASK) == BASE_PROVIDER_FILE);
+ assert((pStream->dwFlags & STREAM_PROVIDER_MASK) == STREAM_PROVIDER_LINEAR);
+ assert((pStream->dwFlags & BASE_PROVIDER_MASK) == BASE_PROVIDER_FILE);
+
+ // Close the new stream
+ pNewStream->BaseClose(pNewStream);
+
+ // Close the source stream
+ pStream->BaseClose(pStream);
+
+ // Rename the new data source file to the existing file
+ if(!BaseFile_Switch(pStream, pNewStream))
+ return false;
+
+ // Now we have to open the "pStream" again
+ if(!BaseFile_Open(pStream, pStream->szFileName, pNewStream->dwFlags))
+ return false;
+
+ // We need to cleanup the new data stream
+ FileStream_Close(pNewStream);
+ return true;
+}
+
+static bool LinearStream_GetBitmap(
+ TLinearStream * pStream,
+ TFileBitmap * pBitmap,
+ DWORD Length,
+ LPDWORD LengthNeeded)
+{
+ DWORD TotalLength;
+ bool bResult = false;
+
+ // Assumed that we have bitmap now
+ assert(pStream->pBitmap != NULL);
+
+ // Give the bitmap length
+ TotalLength = sizeof(TFileBitmap) + pStream->pBitmap->BitmapSize;
+ if(LengthNeeded != NULL)
+ *LengthNeeded = TotalLength;
+
+ // Do we have enough space to fill at least the bitmap structure?
+ if(Length >= sizeof(TFileBitmap))
+ {
+ // Enough space for complete bitmap?
+ if(Length >= TotalLength)
+ {
+ memcpy(pBitmap, pStream->pBitmap, TotalLength);
+ bResult = true;
+ }
+ else
+ {
+ memcpy(pBitmap, pStream->pBitmap, sizeof(TFileBitmap));
+ bResult = true;
+ }
+ }
+
+ return bResult;
+}
+
+static void LinearStream_Close(TLinearStream * pStream)
+{
+ // Free the data map, if any
+ if(pStream->pBitmap != NULL)
+ STORM_FREE(pStream->pBitmap);
+ pStream->pBitmap = NULL;
+
+ // Call the base class for closing the stream
+ return pStream->BaseClose(pStream);
+}
+
+static bool LinearStream_Open(TLinearStream * pStream)
+{
+ // No extra work here really; just set entry points
+ pStream->StreamRead = pStream->BaseRead;
+ pStream->StreamWrite = pStream->BaseWrite;
+ pStream->StreamGetPos = pStream->BaseGetPos;
+ pStream->StreamGetSize = pStream->BaseGetSize;
+ pStream->StreamSetSize = pStream->BaseSetSize;
+ pStream->StreamGetTime = pStream->BaseGetTime;
+ pStream->StreamGetBmp = (STREAM_GETBMP)Dummy_GetBitmap;
+ pStream->StreamSwitch = (STREAM_SWITCH)LinearStream_Switch;
+ pStream->StreamClose = (STREAM_CLOSE)LinearStream_Close;
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// 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 bool PartialStream_Read(
+ TPartialStream * pStream,
+ ULONGLONG * pByteOffset,
+ void * pvBuffer,
+ DWORD dwBytesToRead)
+{
+ ULONGLONG RawByteOffset;
+ LPBYTE pbBuffer = (LPBYTE)pvBuffer;
+ DWORD dwBytesRemaining = dwBytesToRead;
+ DWORD dwPartOffset;
+ DWORD dwPartIndex;
+ DWORD dwBytesRead = 0;
+ DWORD dwBlockSize = pStream->BlockSize;
+ bool bResult = false;
+ int nFailReason = ERROR_HANDLE_EOF; // Why it failed if not enough bytes was read
+
+ // If the byte offset is not entered, use the current position
+ if(pByteOffset == NULL)
+ pByteOffset = &pStream->VirtualPos;
+
+ // Check if the file position is not at or beyond end of the file
+ if(*pByteOffset >= pStream->VirtualSize)
+ {
+ SetLastError(ERROR_HANDLE_EOF);
+ return false;
+ }
+
+ // Get the part index where the read offset is
+ // Note that the part index should now be within the range,
+ // as read requests beyond-EOF are handled by the previous test
+ dwPartIndex = (DWORD)(*pByteOffset / pStream->BlockSize);
+ assert(dwPartIndex < pStream->BlockCount);
+
+ // If the number of bytes remaining goes past
+ // the end of the file, cut them
+ if((*pByteOffset + dwBytesRemaining) > pStream->VirtualSize)
+ dwBytesRemaining = (DWORD)(pStream->VirtualSize - *pByteOffset);
+
+ // Calculate the offset in the current part
+ dwPartOffset = (DWORD)(*pByteOffset) & (pStream->BlockSize - 1);
+
+ // Read all data, one part at a time
+ while(dwBytesRemaining != 0)
+ {
+ PPART_FILE_MAP_ENTRY PartMap = pStream->PartMap + dwPartIndex;
+ DWORD dwBytesInPart;
+
+ // If the part is not present in the file, we fail the read
+ if((PartMap->Flags & 3) == 0)
+ {
+ nFailReason = ERROR_FILE_CORRUPT;
+ bResult = false;
+ break;
+ }
+
+ // If we are in the last part, we have to cut the number of bytes in the last part
+ if(dwPartIndex == pStream->BlockCount - 1)
+ dwBlockSize = (DWORD)pStream->VirtualSize & (pStream->BlockSize - 1);
+
+ // Get the number of bytes reamining in the current part
+ dwBytesInPart = dwBlockSize - dwPartOffset;
+
+ // Compute the raw file offset of the file part
+ RawByteOffset = MAKE_OFFSET64(PartMap->BlockOffsHi, PartMap->BlockOffsLo);
+ if(RawByteOffset == 0)
+ {
+ nFailReason = ERROR_FILE_CORRUPT;
+ bResult = false;
+ break;
+ }
+
+ // If the number of bytes in part is too big, cut it
+ if(dwBytesInPart > dwBytesRemaining)
+ dwBytesInPart = dwBytesRemaining;
+
+ // Append the offset within the part
+ RawByteOffset += dwPartOffset;
+ if(!pStream->BaseRead(pStream, &RawByteOffset, pbBuffer, dwBytesInPart))
+ {
+ nFailReason = ERROR_FILE_CORRUPT;
+ bResult = false;
+ break;
+ }
+
+ // Increment the file position
+ dwBytesRemaining -= dwBytesInPart;
+ dwBytesRead += dwBytesInPart;
+ pbBuffer += dwBytesInPart;
+
+ // Move to the next file part
+ dwPartOffset = 0;
+ dwPartIndex++;
+ }
+
+ // Move the file position by the number of bytes read
+ pStream->VirtualPos = *pByteOffset + dwBytesRead;
+ if(dwBytesRead != dwBytesToRead)
+ SetLastError(nFailReason);
+ return (dwBytesRead == dwBytesToRead);
+}
+
+static bool PartialStream_GetPos(
+ TPartialStream * pStream,
+ ULONGLONG & ByteOffset)
+{
+ ByteOffset = pStream->VirtualPos;
+ return true;
+}
+
+static bool PartialStream_GetSize(
+ TPartialStream * pStream, // Pointer to an open stream
+ ULONGLONG & FileSize) // Pointer where to store file size
+{
+ FileSize = pStream->VirtualSize;
+ return true;
+}
+
+static bool PartialStream_GetBitmap(
+ TPartialStream * pStream,
+ TFileBitmap * pBitmap,
+ DWORD Length,
+ LPDWORD LengthNeeded)
+{
+ LPBYTE pbBitmap;
+ DWORD TotalLength;
+ DWORD BitmapSize = 0;
+ DWORD ByteOffset;
+ DWORD BitMask;
+ bool bResult = false;
+
+ // Do we have stream bitmap?
+ BitmapSize = ((pStream->BlockCount - 1) / 8) + 1;
+
+ // Give the bitmap length
+ TotalLength = sizeof(TFileBitmap) + BitmapSize;
+ if(LengthNeeded != NULL)
+ *LengthNeeded = TotalLength;
+
+ // Do we have enough to fill at least the header?
+ if(Length >= sizeof(TFileBitmap))
+ {
+ // Fill the bitmap header
+ pBitmap->StartOffset = 0;
+ pBitmap->EndOffset = pStream->VirtualSize;
+ pBitmap->IsComplete = 1;
+ pBitmap->BitmapSize = BitmapSize;
+ pBitmap->BlockSize = pStream->BlockSize;
+ pBitmap->Reserved = 0;
+
+ // Is there at least one incomplete block?
+ for(DWORD i = 0; i < pStream->BlockCount; i++)
+ {
+ if(pStream->PartMap[i].Flags != 3)
+ {
+ pBitmap->IsComplete = 0;
+ break;
+ }
+ }
+
+ bResult = true;
+ }
+
+ // Do we have enough space for supplying the bitmap?
+ if(Length >= TotalLength)
+ {
+ // Fill the file bitmap
+ pbBitmap = (LPBYTE)(pBitmap + 1);
+ for(DWORD i = 0; i < pStream->BlockCount; i++)
+ {
+ // Is the block there?
+ if(pStream->PartMap[i].Flags == 3)
+ {
+ ByteOffset = i / 8;
+ BitMask = 1 << (i & 7);
+ pbBitmap[ByteOffset] |= BitMask;
+ }
+ }
+ bResult = true;
+ }
+
+ return bResult;
+}
+
+static void PartialStream_Close(TPartialStream * pStream)
+{
+ // Free the part map
+ if(pStream->PartMap != NULL)
+ STORM_FREE(pStream->PartMap);
+ pStream->PartMap = NULL;
+
+ // Clear variables
+ pStream->VirtualSize = 0;
+ pStream->VirtualPos = 0;
+
+ // Close the base stream
+ assert(pStream->BaseClose != NULL);
+ pStream->BaseClose(pStream);
+}
+
+static bool PartialStream_Open(TPartialStream * pStream)
+{
+ PART_FILE_HEADER PartHdr;
+ ULONGLONG VirtualSize; // Size of the file stored in part file
+ ULONGLONG ByteOffset = {0};
+ DWORD BlockCount;
+
+ // Sanity check
+ assert(pStream->BaseRead != NULL);
+
+ // 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_PART_HEADER(&PartHdr);
+
+ // Verify the PART file header
+ if(IsPartHeader(&PartHdr))
+ {
+ // Calculate the number of parts in the file
+ VirtualSize = MAKE_OFFSET64(PartHdr.FileSizeHi, PartHdr.FileSizeLo);
+ assert(VirtualSize != 0);
+ BlockCount = (DWORD)((VirtualSize + PartHdr.BlockSize - 1) / PartHdr.BlockSize);
+
+ // Allocate the map entry array
+ pStream->PartMap = STORM_ALLOC(PART_FILE_MAP_ENTRY, BlockCount);
+ if(pStream->PartMap != NULL)
+ {
+ // Load the block map
+ if(pStream->BaseRead(pStream, NULL, pStream->PartMap, BlockCount * sizeof(PART_FILE_MAP_ENTRY)))
+ {
+ // Swap the array of file map entries
+ BSWAP_ARRAY32_UNSIGNED(pStream->PartMap, BlockCount * sizeof(PART_FILE_MAP_ENTRY));
+
+ // Fill the members of PART file stream
+ pStream->VirtualSize = ((ULONGLONG)PartHdr.FileSizeHi) + PartHdr.FileSizeLo;
+ pStream->VirtualPos = 0;
+ pStream->BlockCount = BlockCount;
+ pStream->BlockSize = PartHdr.BlockSize;
+
+ // Set new function pointers
+ pStream->StreamRead = (STREAM_READ)PartialStream_Read;
+ pStream->StreamGetPos = (STREAM_GETPOS)PartialStream_GetPos;
+ pStream->StreamGetSize = (STREAM_GETSIZE)PartialStream_GetSize;
+ pStream->StreamGetTime = pStream->BaseGetTime;
+ pStream->StreamGetTime = pStream->BaseGetTime;
+ pStream->StreamGetBmp = (STREAM_GETBMP)PartialStream_GetBitmap;
+ pStream->StreamClose = (STREAM_CLOSE)PartialStream_Close;
+ return true;
+ }
+
+ // Free the part map
+ STORM_FREE(pStream->PartMap);
+ pStream->PartMap = NULL;
+ }
+ }
+ }
+
+ SetLastError(ERROR_BAD_FORMAT);
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Local functions - encrypted stream support
+
+static const char * szKeyTemplate = "expand 32-byte k000000000000000000000000000000000000000000000000";
+
+static const char * AuthCodeArray[] =
+{
+ // 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"
+
+ // Note: 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 DetectFileKey(LPBYTE pbKeyBuffer, LPBYTE pbEncryptedHeader)
+{
+ ULONGLONG ByteOffset = 0;
+ BYTE FileHeader[MPQE_CHUNK_SIZE];
+
+ // 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(pbKeyBuffer, AuthCodeArray[i]);
+
+ // Try to decrypt with the given key
+ memcpy(FileHeader, pbEncryptedHeader, MPQE_CHUNK_SIZE);
+ DecryptFileChunk((LPDWORD)FileHeader, pbKeyBuffer, 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')
+ return true;
+ }
+
+ // Key not found, sorry
+ return false;
+}
+
+static bool EncryptedStream_Read(
+ TEncryptedStream * 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 StartOffset; // Offset of the first byte to be read from the file
+ ULONGLONG ByteOffset; // Offset that the caller wants
+ ULONGLONG EndOffset; // End offset that is to be read from the file
+ DWORD dwBytesToAllocate;
+ DWORD dwBytesToDecrypt;
+ DWORD dwOffsetInCache;
+ LPBYTE pbMpqData = NULL;
+ bool bResult = false;
+
+ // Get the byte offset
+ if(pByteOffset == NULL)
+ pStream->BaseGetPos(pStream, &ByteOffset);
+ else
+ ByteOffset = *pByteOffset;
+
+ // Cut it down to MPQE chunk size
+ StartOffset = ByteOffset;
+ StartOffset = StartOffset & ~(MPQE_CHUNK_SIZE - 1);
+ EndOffset = ByteOffset + dwBytesToRead;
+
+ // Calculate number of bytes to decrypt
+ dwBytesToDecrypt = (DWORD)(EndOffset - StartOffset);
+ dwBytesToAllocate = (dwBytesToDecrypt + (MPQE_CHUNK_SIZE - 1)) & ~(MPQE_CHUNK_SIZE - 1);
+
+ // Allocate buffers for encrypted and decrypted data
+ pbMpqData = STORM_ALLOC(BYTE, dwBytesToAllocate);
+ if(pbMpqData)
+ {
+ // Get the offset of the desired data in the cache
+ dwOffsetInCache = (DWORD)(ByteOffset - StartOffset);
+
+ // Read the file from the stream as-is
+ if(pStream->BaseRead(pStream, &StartOffset, pbMpqData, dwBytesToDecrypt))
+ {
+ // Decrypt the data
+ DecryptFileChunk((LPDWORD)pbMpqData, pStream->Key, StartOffset, dwBytesToAllocate);
+
+ // Copy the decrypted data
+ memcpy(pvBuffer, pbMpqData + dwOffsetInCache, dwBytesToRead);
+ bResult = true;
+ }
+ else
+ {
+ assert(false);
+ }
+
+ // Free decryption buffer
+ STORM_FREE(pbMpqData);
+ }
+
+ // Free buffers and exit
+ return bResult;
+}
+
+static bool EncryptedStream_Open(TEncryptedStream * pStream)
+{
+ ULONGLONG ByteOffset = 0;
+ BYTE EncryptedHeader[MPQE_CHUNK_SIZE];
+
+ // Sanity check
+ assert(pStream->BaseRead != NULL);
+
+ // Load one MPQE chunk and try to detect the file key
+ if(pStream->BaseRead(pStream, &ByteOffset, EncryptedHeader, sizeof(EncryptedHeader)))
+ {
+ // Attempt to decrypt the MPQ header with all known keys
+ if(DetectFileKey(pStream->Key, EncryptedHeader))
+ {
+ // Assign functions
+ pStream->StreamRead = (STREAM_READ)EncryptedStream_Read;
+ pStream->StreamGetPos = pStream->BaseGetPos;
+ pStream->StreamGetSize = pStream->BaseGetSize;
+ pStream->StreamGetTime = pStream->BaseGetTime;
+ pStream->StreamGetBmp = (STREAM_GETBMP)Dummy_GetBitmap;
+ pStream->StreamClose = pStream->BaseClose;
+
+ // We need to reset the position back to the begin of the file
+ pStream->BaseRead(pStream, &ByteOffset, EncryptedHeader, 0);
+ return true;
+ }
+
+ // An unknown key
+ SetLastError(ERROR_UNKNOWN_FILE_KEY);
+ }
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// 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 linear, local file
+ if((dwStreamFlags & (STREAM_PROVIDER_MASK | BASE_PROVIDER_MASK)) != (STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE))
+ {
+ SetLastError(ERROR_NOT_SUPPORTED);
+ return NULL;
+ }
+
+ // Allocate file stream structure for linear stream
+ pStream = STORM_ALLOC(TFileStream, 1);
+ if(pStream != NULL)
+ {
+ // Reset entire structure to zero
+ memset(pStream, 0, sizeof(TFileStream));
+ _tcscpy(pStream->szFileName, szFileName);
+
+ // Attempt to create the disk file
+ if(BaseFile_Create(pStream, szFileName, dwStreamFlags))
+ {
+ // Fill the stream provider functions
+ pStream->StreamRead = pStream->BaseRead;
+ pStream->StreamWrite = pStream->BaseWrite;
+ pStream->StreamGetPos = pStream->BaseGetPos;
+ pStream->StreamGetSize = pStream->BaseGetSize;
+ pStream->StreamSetSize = pStream->BaseSetSize;
+ pStream->StreamGetTime = pStream->BaseGetTime;
+ pStream->StreamGetBmp = (STREAM_GETBMP)Dummy_GetBitmap;;
+ pStream->StreamSwitch = (STREAM_SWITCH)LinearStream_Switch;
+ 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 check if the file is a PART file,
+ * and create TPartialStream object if so.
+ * - 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)
+{
+ TFileStream * pStream = NULL;
+ size_t StreamSize = 0;
+ bool bStreamResult = false;
+ bool bBaseResult = false;
+
+ // Allocate file stream for each stream provider
+ switch(dwStreamFlags & STREAM_PROVIDER_MASK)
+ {
+ case STREAM_PROVIDER_LINEAR: // Allocate structure for linear stream
+ StreamSize = sizeof(TLinearStream);
+ break;
+
+ case STREAM_PROVIDER_PARTIAL:
+ dwStreamFlags |= STREAM_FLAG_READ_ONLY;
+ StreamSize = sizeof(TPartialStream);
+ break;
+
+ case STREAM_PROVIDER_ENCRYPTED:
+ dwStreamFlags |= STREAM_FLAG_READ_ONLY;
+ StreamSize = sizeof(TEncryptedStream);
+ break;
+
+ default:
+ return NULL;
+ }
+
+ // Allocate the stream for each type
+ pStream = (TFileStream *)STORM_ALLOC(BYTE, StreamSize);
+ if(pStream == NULL)
+ return NULL;
+
+ // Fill the stream structure with zeros
+ memset(pStream, 0, StreamSize);
+ _tcscpy(pStream->szFileName, szFileName);
+
+ // Now initialize the respective base provider
+ switch(dwStreamFlags & BASE_PROVIDER_MASK)
+ {
+ case BASE_PROVIDER_FILE:
+ bBaseResult = BaseFile_Open(pStream, szFileName, dwStreamFlags);
+ break;
+
+ case BASE_PROVIDER_MAP:
+ dwStreamFlags |= STREAM_FLAG_READ_ONLY;
+ bBaseResult = BaseMap_Open(pStream, szFileName, dwStreamFlags);
+ break;
+
+ case BASE_PROVIDER_HTTP:
+ dwStreamFlags |= STREAM_FLAG_READ_ONLY;
+ bBaseResult = BaseHttp_Open(pStream, szFileName, dwStreamFlags);
+ break;
+ }
+
+ // If we failed to open the base storage, fail the operation
+ if(bBaseResult == false)
+ {
+ STORM_FREE(pStream);
+ return NULL;
+ }
+
+ // Now initialize the stream provider
+ switch(dwStreamFlags & STREAM_PROVIDER_MASK)
+ {
+ case STREAM_PROVIDER_LINEAR:
+ bStreamResult = LinearStream_Open((TLinearStream *)pStream);
+ break;
+
+ case STREAM_PROVIDER_PARTIAL:
+ bStreamResult = PartialStream_Open((TPartialStream *)pStream);
+ break;
+
+ case STREAM_PROVIDER_ENCRYPTED:
+ bStreamResult = EncryptedStream_Open((TEncryptedStream *)pStream);
+ break;
+ }
+
+ // If the operation failed, free the stream and set it to NULL
+ if(bStreamResult == false)
+ {
+ // Only close the base stream
+ pStream->BaseClose(pStream);
+ STORM_FREE(pStream);
+ pStream = NULL;
+ }
+
+ return pStream;
+}
+
+/**
+ * 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)
+ return false;
+
+ assert(pStream->StreamWrite != NULL);
+ return pStream->StreamWrite(pStream, pByteOffset, pvBuffer, dwBytesToWrite);
+}
+
+/**
+ * This function returns the current file position
+ * \a pStream
+ * \a ByteOffset
+ */
+bool FileStream_GetPos(TFileStream * pStream, ULONGLONG * pByteOffset)
+{
+ assert(pStream->StreamGetPos != NULL);
+ return pStream->StreamGetPos(pStream, pByteOffset);
+}
+
+/**
+ * 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)
+ return false;
+
+ assert(pStream->StreamSetSize != NULL);
+ return pStream->StreamSetSize(pStream, NewFileSize);
+}
+
+/**
+ * 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)
+{
+ assert(pStream->StreamGetTime != NULL);
+ return pStream->StreamGetTime(pStream, pFileTime);
+}
+
+/**
+ * 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 pTempStream Temporary ("working") stream (created during archive compacting)
+ */
+bool FileStream_Switch(TFileStream * pStream, TFileStream * pNewStream)
+{
+ if(pStream->dwFlags & STREAM_FLAG_READ_ONLY)
+ return false;
+
+ assert(pStream->StreamSwitch != NULL);
+ return pStream->StreamSwitch(pStream, pNewStream);
+}
+
+/**
+ * Returns the file name of the stream
+ *
+ * \a pStream Pointer to an open stream
+ */
+TCHAR * FileStream_GetFileName(TFileStream * pStream)
+{
+ assert(pStream != NULL);
+ return pStream->szFileName;
+}
+
+/**
+ * Returns true if the stream is read-only
+ *
+ * \a pStream Pointer to an open stream
+ */
+bool FileStream_IsReadOnly(TFileStream * pStream)
+{
+ return (pStream->dwFlags & STREAM_FLAG_READ_ONLY) ? true : false;
+}
+
+/**
+ * This function enabled a linear stream to include data bitmap.
+ * Used by MPQs v 4.0 from WoW. Each file block is represented by
+ * a bit in the bitmap. 1 means the block is present, 0 means it's not.
+ *
+ * \a pStream Pointer to an open stream
+ * \a pBitmap Pointer to file bitmap
+ */
+
+bool FileStream_SetBitmap(TFileStream * pStream, TFileBitmap * pBitmap)
+{
+ TLinearStream * pLinearStream;
+
+ // It must be a linear stream.
+ if((pStream->dwFlags & STREAM_PROVIDER_MASK) != STREAM_PROVIDER_LINEAR)
+ return false;
+ pLinearStream = (TLinearStream *)pStream;
+
+ // Two bitmaps are not allowed
+ if(pLinearStream->pBitmap != NULL)
+ return false;
+
+ // We need to change some entry points
+ pLinearStream->StreamRead = (STREAM_READ)LinearStream_Read;
+ pLinearStream->StreamGetBmp = (STREAM_GETBMP)LinearStream_GetBitmap;
+
+ // Using data bitmap renders the stream to be read only.
+ pLinearStream->dwFlags |= STREAM_FLAG_READ_ONLY;
+ pLinearStream->pBitmap = pBitmap;
+ return true;
+}
+
+/**
+ * This function retrieves the file bitmap. A file bitmap is an array
+ * of bits, each bit representing one file block. A value of 1 means
+ * that the block is present in the file, a value of 0 means that the
+ * block is not present.
+ *
+ * \a pStream Pointer to an open stream
+ * \a pBitmap Pointer to buffer where to store the file bitmap
+ * \a Length Size of buffer pointed by pBitmap, in bytes
+ * \a LengthNeeded If non-NULL, the function supplies the necessary byte size of the buffer
+ */
+bool FileStream_GetBitmap(TFileStream * pStream, TFileBitmap * pBitmap, DWORD Length, LPDWORD LengthNeeded)
+{
+ assert(pStream->StreamGetBmp != NULL);
+ return pStream->StreamGetBmp(pStream, pBitmap, Length, LengthNeeded);
+}
+
+/**
+ * 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)
+ {
+ // Close the stream provider.
+ // This will also close the base stream
+ assert(pStream->StreamClose != NULL);
+ pStream->StreamClose(pStream);
+
+ // Free the stream itself
+ STORM_FREE(pStream);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// main - for testing purposes
+
+#ifdef __STORMLIB_TEST__
+int FileStream_Test(const TCHAR * szFileName, DWORD dwStreamFlags)
+{
+ TFileStream * pStream;
+ TMPQHeader MpqHeader;
+ ULONGLONG FilePos;
+ TMPQBlock * pBlock;
+ TMPQHash * pHash;
+
+ InitializeMpqCryptography();
+
+ pStream = FileStream_OpenFile(szFileName, dwStreamFlags);
+ if(pStream == NULL)
+ return GetLastError();
+
+ // Read the MPQ header
+ FileStream_Read(pStream, NULL, &MpqHeader, MPQ_HEADER_SIZE_V2);
+ if(MpqHeader.dwID != ID_MPQ)
+ return ERROR_FILE_CORRUPT;
+
+ // Read the hash table
+ pHash = STORM_ALLOC(TMPQHash, MpqHeader.dwHashTableSize);
+ if(pHash != NULL)
+ {
+ FilePos = MpqHeader.dwHashTablePos;
+ FileStream_Read(pStream, &FilePos, pHash, MpqHeader.dwHashTableSize * sizeof(TMPQHash));
+ DecryptMpqBlock(pHash, MpqHeader.dwHashTableSize * sizeof(TMPQHash), MPQ_KEY_HASH_TABLE);
+ STORM_FREE(pHash);
+ }
+
+ // Read the block table
+ pBlock = STORM_ALLOC(TMPQBlock, MpqHeader.dwBlockTableSize);
+ if(pBlock != NULL)
+ {
+ FilePos = MpqHeader.dwBlockTablePos;
+ FileStream_Read(pStream, &FilePos, pBlock, MpqHeader.dwBlockTableSize * sizeof(TMPQBlock));
+ DecryptMpqBlock(pBlock, MpqHeader.dwBlockTableSize * sizeof(TMPQBlock), MPQ_KEY_BLOCK_TABLE);
+ STORM_FREE(pBlock);
+ }
+
+ FileStream_Close(pStream);
+ return ERROR_SUCCESS;
+}
+#endif
+
+/*
+int FileStream_Test()
+{
+ TFileStream * pStream;
+
+ InitializeMpqCryptography();
+
+ //
+ // Test 1: Write to a stream
+ //
+
+ pStream = FileStream_CreateFile("E:\\Stream.bin", 0);
+ if(pStream != NULL)
+ {
+ char szString1[100] = "This is a single line\n\r";
+ DWORD dwLength = strlen(szString1);
+
+ for(int i = 0; i < 10; i++)
+ {
+ if(!FileStream_Write(pStream, NULL, szString1, dwLength))
+ {
+ printf("Failed to write to the stream\n");
+ return ERROR_CAN_NOT_COMPLETE;
+ }
+ }
+ FileStream_Close(pStream);
+ }
+
+ //
+ // Test2: Read from the stream
+ //
+
+ pStream = FileStream_OpenFile("E:\\Stream.bin", STREAM_FLAG_READ_ONLY | STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
+ if(pStream != NULL)
+ {
+ char szString1[100] = "This is a single line\n\r";
+ char szString2[100];
+ DWORD dwLength = strlen(szString1);
+
+ // This call must end with an error
+ if(FileStream_Write(pStream, NULL, "aaa", 3))
+ {
+ printf("Write succeeded while it should fail\n");
+ return -1;
+ }
+
+ for(int i = 0; i < 10; i++)
+ {
+ if(!FileStream_Read(pStream, NULL, szString2, dwLength))
+ {
+ printf("Failed to read from the stream\n");
+ return -1;
+ }
+
+ szString2[dwLength] = 0;
+ if(strcmp(szString1, szString2))
+ {
+ printf("Data read from file are different from data written\n");
+ return -1;
+ }
+ }
+ FileStream_Close(pStream);
+ }
+
+ //
+ // Test3: Open the temp stream, write some data and switch it to the original stream
+ //
+
+ pStream = FileStream_OpenFile("E:\\Stream.bin", STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
+ if(pStream != NULL)
+ {
+ TFileStream * pTempStream;
+ ULONGLONG FileSize;
+
+ pTempStream = FileStream_CreateFile("E:\\TempStream.bin", 0);
+ if(pTempStream == NULL)
+ {
+ printf("Failed to create temp stream\n");
+ return -1;
+ }
+
+ // Copy the original stream to the temp
+ if(!FileStream_GetSize(pStream, FileSize))
+ {
+ printf("Failed to get the file size\n");
+ return -1;
+ }
+
+ while(FileSize != 0)
+ {
+ DWORD dwBytesToRead = (DWORD)FileSize;
+ char Buffer[0x80];
+
+ if(dwBytesToRead > sizeof(Buffer))
+ dwBytesToRead = sizeof(Buffer);
+
+ if(!FileStream_Read(pStream, NULL, Buffer, dwBytesToRead))
+ {
+ printf("CopyStream: Read source file failed\n");
+ return -1;
+ }
+
+ if(!FileStream_Write(pTempStream, NULL, Buffer, dwBytesToRead))
+ {
+ printf("CopyStream: Write target file failed\n");
+ return -1;
+ }
+
+ FileSize -= dwBytesToRead;
+ }
+
+ // Switch the streams
+ // Note that the pTempStream is closed by the operation
+ FileStream_Switch(pStream, pTempStream);
+ FileStream_Close(pStream);
+ }
+
+ //
+ // Test4: Read from the stream again
+ //
+
+ pStream = FileStream_OpenFile("E:\\Stream.bin", STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
+ if(pStream != NULL)
+ {
+ char szString1[100] = "This is a single line\n\r";
+ char szString2[100];
+ DWORD dwLength = strlen(szString1);
+
+ for(int i = 0; i < 10; i++)
+ {
+ if(!FileStream_Read(pStream, NULL, szString2, dwLength))
+ {
+ printf("Failed to read from the stream\n");
+ return -1;
+ }
+
+ szString2[dwLength] = 0;
+ if(strcmp(szString1, szString2))
+ {
+ printf("Data read from file are different from data written\n");
+ return -1;
+ }
+ }
+ FileStream_Close(pStream);
+ }
+
+ return 0;
+}
+*/
+
diff --git a/src/FileStream.h b/src/FileStream.h
new file mode 100644
index 0000000..d00c82e
--- /dev/null
+++ b/src/FileStream.h
@@ -0,0 +1,189 @@
+/*****************************************************************************/
+/* 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 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_GETPOS)(
+ struct TFileStream * pStream, // Pointer to an open stream
+ ULONGLONG * pByteOffset // Pointer to store current file position
+ );
+
+typedef bool (*STREAM_GETSIZE)(
+ struct TFileStream * pStream, // Pointer to an open stream
+ ULONGLONG * pFileSize // Receives the file size, in bytes
+ );
+
+typedef bool (*STREAM_SETSIZE)(
+ struct TFileStream * pStream, // Pointer to an open stream
+ ULONGLONG FileSize // New size for the file, in bytes
+ );
+
+typedef bool (*STREAM_GETTIME)(
+ struct TFileStream * pStream,
+ ULONGLONG * pFT
+ );
+
+typedef bool (*STREAM_SWITCH)(
+ struct TFileStream * pStream,
+ struct TFileStream * pNewStream
+ );
+
+typedef bool (*STREAM_GETBMP)(
+ TFileStream * pStream,
+ TFileBitmap * pBitmap,
+ DWORD Length,
+ LPDWORD LengthNeeded
+ );
+
+typedef void (*STREAM_CLOSE)(
+ struct TFileStream * pStream
+ );
+
+//-----------------------------------------------------------------------------
+// Local structures - part file structure
+
+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;
+
+//-----------------------------------------------------------------------------
+// Local structures
+
+union TBaseData
+{
+ struct
+ {
+ ULONGLONG FileSize; // Size of the file
+ ULONGLONG FilePos; // Current file position
+ ULONGLONG FileTime; // Date/time of last modification of the file
+ HANDLE hFile; // File handle
+ } File;
+
+ struct
+ {
+ ULONGLONG FileSize; // Mapped file size
+ ULONGLONG FilePos; // Current stream position
+ ULONGLONG FileTime; // Date/time of last modification of the file
+ LPBYTE pbFile; // Pointer to mapped view
+ } Map;
+
+ struct
+ {
+ ULONGLONG FileSize; // Size of the internet file
+ ULONGLONG FilePos; // Current position in the file
+ ULONGLONG FileTime; // Date/time of last modification of the file
+ HANDLE hInternet; // Internet handle
+ HANDLE hConnect; // Connection to the internet server
+ } Http;
+};
+
+//-----------------------------------------------------------------------------
+// Structure for linear stream
+
+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_GETPOS StreamGetPos; // Pointer to function that returns current file position
+ STREAM_GETSIZE StreamGetSize; // Pointer to function returning file size
+ STREAM_SETSIZE StreamSetSize; // Pointer to function changing file size
+ STREAM_GETTIME StreamGetTime; // Pointer to function retrieving the file time
+ STREAM_GETBMP StreamGetBmp; // Pointer to function that retrieves the file bitmap
+ STREAM_SWITCH StreamSwitch; // Pointer to function changing the stream to another file
+ STREAM_CLOSE StreamClose; // Pointer to function closing the stream
+
+ // Stream provider data members
+ TCHAR szFileName[MAX_PATH]; // File name
+ DWORD dwFlags; // Stream flags
+
+ // Base provider functions
+ STREAM_READ BaseRead;
+ STREAM_WRITE BaseWrite;
+ STREAM_GETPOS BaseGetPos; // Pointer to function that returns current file position
+ STREAM_GETSIZE BaseGetSize; // Pointer to function returning file size
+ STREAM_SETSIZE BaseSetSize; // Pointer to function changing file size
+ STREAM_GETTIME BaseGetTime; // Pointer to function retrieving the file time
+ STREAM_CLOSE BaseClose; // Pointer to function closing the stream
+
+ // Base provider data members
+ TBaseData Base; // Base provider data
+
+ // Followed by stream provider data, with variable length
+};
+
+//-----------------------------------------------------------------------------
+// Structure for linear stream
+
+struct TLinearStream : public TFileStream
+{
+ TFileBitmap * pBitmap; // Pointer to the stream bitmap
+};
+
+//-----------------------------------------------------------------------------
+// Structure for partial stream
+
+struct TPartialStream : public TFileStream
+{
+ ULONGLONG VirtualSize; // Virtual size of the file
+ ULONGLONG VirtualPos; // Virtual position in the file
+ DWORD BlockCount; // Number of file blocks. Used by partial file stream
+ DWORD BlockSize; // Size of one block. Used by partial file stream
+
+ PPART_FILE_MAP_ENTRY PartMap; // File map, variable length
+};
+
+//-----------------------------------------------------------------------------
+// Structure for encrypted stream
+
+#define MPQE_CHUNK_SIZE 0x40 // Size of one chunk to be decrypted
+
+struct TEncryptedStream : public TFileStream
+{
+ BYTE Key[MPQE_CHUNK_SIZE]; // File key
+};
+
+#endif // __FILESTREAM_H__
diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp
new file mode 100644
index 0000000..b73a213
--- /dev/null
+++ b/src/SBaseCommon.cpp
@@ -0,0 +1,1736 @@
+/*****************************************************************************/
+/* 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-2012";
+
+//-----------------------------------------------------------------------------
+// Local variables
+
+LCID lcFileLocale = LANG_NEUTRAL; // File locale
+USHORT wPlatform = 0; // File platform
+
+//-----------------------------------------------------------------------------
+// Conversion to uppercase/lowercase
+
+// This table converts ASCII characters to lowercase and slash to backslash
+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
+};
+
+// This table converts ASCII characters to uppercase and slash to backslash
+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
+};
+
+//-----------------------------------------------------------------------------
+// Storm hashing functions
+
+#define STORM_BUFFER_SIZE 0x500
+
+static DWORD StormBuffer[STORM_BUFFER_SIZE]; // Buffer for the decryption engine
+static bool bMpqCryptographyInitialized = false;
+
+DWORD HashString(const char * szFileName, DWORD dwHashType)
+{
+ LPBYTE pbKey = (BYTE *)szFileName;
+ DWORD dwSeed1 = 0x7FED7FED;
+ DWORD dwSeed2 = 0xEEEEEEEE;
+ DWORD ch;
+
+ while(*pbKey != 0)
+ {
+ ch = AsciiToUpperTable[*pbKey++];
+
+ dwSeed1 = StormBuffer[dwHashType + ch] ^ (dwSeed1 + dwSeed2);
+ dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3;
+ }
+
+ return dwSeed1;
+}
+
+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;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Calculates the hash table size for a given amount of files
+
+DWORD GetHashTableSizeForFileCount(DWORD dwFileCount)
+{
+ DWORD dwPowerOfTwo;
+
+ // Round the hash table size up to the nearest power of two
+ for(dwPowerOfTwo = HASH_TABLE_SIZE_MIN; dwPowerOfTwo < HASH_TABLE_SIZE_MAX; dwPowerOfTwo <<= 1)
+ {
+ if(dwPowerOfTwo >= dwFileCount)
+ {
+ return dwPowerOfTwo;
+ }
+ }
+
+ // Don't allow the hash table size go over allowed maximum
+ return HASH_TABLE_SIZE_MAX;
+}
+
+//-----------------------------------------------------------------------------
+// Calculates a Jenkin's Encrypting and decrypting MPQ file data
+
+ULONGLONG HashStringJenkins(const char * szFileName)
+{
+ LPBYTE pbFileName = (LPBYTE)szFileName;
+ char * szTemp;
+ char szLocFileName[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)
+ {
+ szTemp = szLocFileName;
+ while(*pbFileName != 0)
+ *szTemp++ = (char)AsciiToLowerTable[*pbFileName++];
+ *szTemp = 0;
+
+ nLength = szTemp - szLocFileName;
+ }
+
+ // Thanks Quantam for finding out what the algorithm is.
+ // I am really getting old for reversing large chunks of assembly
+ // that does hashing :-)
+ hashlittle2(szLocFileName, nLength, &secondary_hash, &primary_hash);
+
+ // Combine those 2 together
+ return (ULONGLONG)primary_hash * (ULONGLONG)0x100000000ULL + (ULONGLONG)secondary_hash;
+}
+
+//-----------------------------------------------------------------------------
+// This function converts the MPQ header so it always looks like version 4
+
+int ConvertMpqHeaderToFormat4(
+ TMPQArchive * ha,
+ ULONGLONG FileSize,
+ DWORD dwFlags)
+{
+ ULONGLONG ByteOffset;
+ TMPQHeader * pHeader = ha->pHeader;
+ DWORD dwExpectedArchiveSize;
+ USHORT wFormatVersion = pHeader->wFormatVersion;
+ int nError = ERROR_SUCCESS;
+
+ // If version 1.0 is forced, then the format version is forced to be 1.0
+ // Reason: Storm.dll in Warcraft III ignores format version value
+ if(dwFlags & MPQ_OPEN_FORCE_MPQ_V1)
+ wFormatVersion = MPQ_FORMAT_VERSION_1;
+
+ // Format-specific fixes
+ switch(wFormatVersion)
+ {
+ case MPQ_FORMAT_VERSION_1:
+
+ // Check for malformed MPQ header version 1.0
+ if(pHeader->dwHeaderSize != MPQ_HEADER_SIZE_V1)
+ {
+ pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V1;
+ ha->dwFlags |= MPQ_FLAG_PROTECTED;
+ }
+
+ //
+ // The value of "dwArchiveSize" member in the MPQ header
+ // is ignored by Storm.dll and can contain garbage value
+ // ("w3xmaster" protector).
+ //
+
+ dwExpectedArchiveSize = (DWORD)(FileSize - ha->MpqPos);
+ if(pHeader->dwArchiveSize != dwExpectedArchiveSize)
+ {
+ // Note: dwExpectedArchiveSize might be incorrect at this point.
+ // MPQs version 1.0 can have strong digital signature appended at the end,
+ // or they might just have arbitrary data there.
+ // In either case, we recalculate the archive size later when
+ // block table is loaded and positions of all files is known.
+ pHeader->dwArchiveSize = dwExpectedArchiveSize;
+ ha->dwFlags |= MPQ_FLAG_NEED_FIX_SIZE;
+ }
+
+ // Zero the fields in 2.0 part of the MPQ header
+ pHeader->HiBlockTablePos64 = 0;
+ pHeader->wHashTablePosHi = 0;
+ pHeader->wBlockTablePosHi = 0;
+ // No break here !!!
+
+ case MPQ_FORMAT_VERSION_2:
+ 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
+ if(pHeader->dwHeaderSize < MPQ_HEADER_SIZE_V3)
+ {
+ ULONGLONG ArchiveSize64 = pHeader->dwArchiveSize;
+
+ // In format 2.0, the archive size is obsolete and is calculated
+ // as the highest offset of hash table, block table or hi-block table.
+ // However, we can still rely on it, if the size of the archive is under 4 GB
+ if((FileSize - ha->MpqPos) >> 32)
+ {
+ ByteOffset = MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos) + (pHeader->dwHashTableSize * sizeof(TMPQHash));
+ if(ByteOffset > ArchiveSize64)
+ ArchiveSize64 = ByteOffset;
+
+ ByteOffset = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos) + (pHeader->dwBlockTableSize * sizeof(TMPQBlock));
+ if(ByteOffset > ArchiveSize64)
+ ArchiveSize64 = ByteOffset;
+
+ // Only if we actually have a hi-block table
+ if(pHeader->HiBlockTablePos64)
+ {
+ ByteOffset = pHeader->HiBlockTablePos64 + (pHeader->dwBlockTableSize * sizeof(USHORT));
+ if(ByteOffset > ArchiveSize64)
+ ArchiveSize64 = ByteOffset;
+ }
+
+ // We need to recalculate archive size later,
+ // when block table is loaded and the position of files is known
+ ha->dwFlags |= MPQ_FLAG_NEED_FIX_SIZE;
+ }
+
+ // Initialize the rest of the 3.0 header
+ pHeader->ArchiveSize64 = ArchiveSize64;
+ pHeader->HetTablePos64 = 0;
+ pHeader->BetTablePos64 = 0;
+ }
+
+ //
+ // Calculate 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
+ //
+
+ // Set all sizes to zero
+ pHeader->HetTableSize64 = 0;
+ pHeader->BetTableSize64 = 0;
+
+ // Either both HET and BET table exist or none of them does.
+ if(pHeader->HetTablePos64)
+ {
+ // Compressed size of the HET and BET tables
+ pHeader->HetTableSize64 = pHeader->BetTablePos64 - pHeader->HetTablePos64;
+ pHeader->BetTableSize64 = MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos) - pHeader->HetTablePos64;
+ }
+
+ // Compressed size of hash and block table
+ if(wFormatVersion >= MPQ_FORMAT_VERSION_2)
+ {
+ // Compressed size of the hash table
+ pHeader->HashTableSize64 = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos) - MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos);
+
+ // Block and hi-block table
+ if(pHeader->HiBlockTablePos64)
+ {
+ pHeader->BlockTableSize64 = pHeader->HiBlockTablePos64 - MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
+ pHeader->HiBlockTableSize64 = pHeader->ArchiveSize64 - pHeader->HiBlockTablePos64;
+ }
+ else
+ {
+ pHeader->BlockTableSize64 = pHeader->ArchiveSize64 - MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
+ pHeader->HiBlockTableSize64 = 0;
+ }
+ }
+ else
+ {
+ // No known MPQ in format 1.0 has any of the tables compressed
+ pHeader->HashTableSize64 = pHeader->dwHashTableSize * sizeof(TMPQHash);
+ pHeader->BlockTableSize64 = pHeader->dwBlockTableSize * sizeof(TMPQBlock);
+ pHeader->HiBlockTableSize64 = 0;
+ }
+
+ // Set the data chunk size for MD5 to zero
+ pHeader->dwRawChunkSize = 0;
+
+ // Fill the MD5's
+ memset(pHeader->MD5_BlockTable, 0, MD5_DIGEST_SIZE);
+ memset(pHeader->MD5_HashTable, 0, MD5_DIGEST_SIZE);
+ memset(pHeader->MD5_HiBlockTable, 0, MD5_DIGEST_SIZE);
+ memset(pHeader->MD5_BetTable, 0, MD5_DIGEST_SIZE);
+ memset(pHeader->MD5_HetTable, 0, MD5_DIGEST_SIZE);
+ memset(pHeader->MD5_MpqHeader, 0, MD5_DIGEST_SIZE);
+ // No break here !!!!
+
+ 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
+ if(!VerifyDataBlockHash(ha->pHeader, MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE, ha->pHeader->MD5_MpqHeader))
+ nError = ERROR_FILE_CORRUPT;
+ break;
+ }
+
+ return nError;
+}
+
+//-----------------------------------------------------------------------------
+// Default flags for (attributes) and (listfile)
+
+DWORD GetDefaultSpecialFileFlags(TMPQArchive * ha, DWORD dwFileSize)
+{
+ // Fixed for format 1.0
+ if(ha->pHeader->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 and decrypting MPQ file data
+
+void EncryptMpqBlock(void * pvFileBlock, DWORD dwLength, DWORD dwSeed1)
+{
+ LPDWORD block = (LPDWORD)pvFileBlock;
+ DWORD dwSeed2 = 0xEEEEEEEE;
+ DWORD ch;
+
+ // Round to DWORDs
+ dwLength >>= 2;
+
+ while(dwLength-- > 0)
+ {
+ dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)];
+ ch = *block;
+ *block++ = ch ^ (dwSeed1 + dwSeed2);
+
+ dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B);
+ dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3;
+ }
+}
+
+void DecryptMpqBlock(void * pvFileBlock, DWORD dwLength, DWORD dwSeed1)
+{
+ LPDWORD block = (LPDWORD)pvFileBlock;
+ DWORD dwSeed2 = 0xEEEEEEEE;
+ DWORD ch;
+
+ // Round to DWORDs
+ dwLength >>= 2;
+
+ while(dwLength-- > 0)
+ {
+ dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)];
+ ch = *block ^ (dwSeed1 + dwSeed2);
+
+ dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B);
+ dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3;
+ *block++ = ch;
+ }
+}
+
+/*
+void EncryptMpqTable(void * pvMpqTable, DWORD dwLength, const char * szKey)
+{
+ EncryptMpqBlock(pvMpqTable, dwLength, HashString(szKey, MPQ_HASH_FILE_KEY));
+}
+
+void DecryptMpqTable(void * pvMpqTable, DWORD dwLength, const char * szKey)
+{
+ DecryptMpqBlock(pvMpqTable, dwLength, HashString(szKey, MPQ_HASH_FILE_KEY));
+}
+*/
+
+/**
+ * Functions tries to get file decryption key. The trick comes from sector
+ * positions which are stored at the begin of each compressed file. We know the
+ * file size, that means we know number of sectors that means we know the first
+ * DWORD value in sector position. And if we know encrypted and decrypted value,
+ * we can find the decryption key !!!
+ *
+ * hf - MPQ file handle
+ * SectorOffsets - DWORD array of sector positions
+ * ch - Decrypted value of the first sector pos
+ */
+
+DWORD DetectFileKeyBySectorSize(LPDWORD SectorOffsets, DWORD decrypted)
+{
+ DWORD saveKey1;
+ DWORD temp = *SectorOffsets ^ decrypted; // temp = seed1 + seed2
+ temp -= 0xEEEEEEEE; // temp = seed1 + StormBuffer[0x400 + (seed1 & 0xFF)]
+
+ for(int i = 0; i < 0x100; i++) // Try all 255 possibilities
+ {
+ DWORD seed1;
+ DWORD seed2 = 0xEEEEEEEE;
+ DWORD ch;
+
+ // Try the first DWORD (We exactly know the value)
+ seed1 = temp - StormBuffer[0x400 + i];
+ seed2 += StormBuffer[0x400 + (seed1 & 0xFF)];
+ ch = SectorOffsets[0] ^ (seed1 + seed2);
+
+ if(ch != decrypted)
+ continue;
+
+ // Add 1 because we are decrypting sector positions
+ saveKey1 = seed1 + 1;
+
+ // If OK, continue and test the second value. We don't know exactly the value,
+ // but we know that the second one has lower 16 bits set to zero
+ // (no compressed sector is larger than 0xFFFF bytes)
+ seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B);
+ seed2 = ch + seed2 + (seed2 << 5) + 3;
+
+ seed2 += StormBuffer[0x400 + (seed1 & 0xFF)];
+ ch = SectorOffsets[1] ^ (seed1 + seed2);
+
+ if((ch & 0xFFFF0000) == 0)
+ return saveKey1;
+ }
+ return 0;
+}
+
+// Function tries to detect file encryption key. It expectes at least two uncompressed bytes
+DWORD DetectFileKeyByKnownContent(void * pvFileContent, DWORD nDwords, ...)
+{
+ LPDWORD pdwContent = (LPDWORD)pvFileContent;
+ va_list argList;
+ DWORD dwDecrypted[0x10];
+ DWORD saveKey1;
+ DWORD dwTemp;
+ DWORD i, j;
+
+ // We need at least two DWORDS to detect the file key
+ if(nDwords < 0x02 || nDwords > 0x10)
+ return 0;
+
+ va_start(argList, nDwords);
+ for(i = 0; i < nDwords; i++)
+ dwDecrypted[i] = va_arg(argList, DWORD);
+ va_end(argList);
+
+ dwTemp = (*pdwContent ^ dwDecrypted[0]) - 0xEEEEEEEE;
+ for(i = 0; i < 0x100; i++) // Try all 256 possibilities
+ {
+ DWORD seed1;
+ DWORD seed2 = 0xEEEEEEEE;
+ DWORD ch;
+
+ // Try the first DWORD
+ seed1 = dwTemp - StormBuffer[0x400 + i];
+ seed2 += StormBuffer[0x400 + (seed1 & 0xFF)];
+ ch = pdwContent[0] ^ (seed1 + seed2);
+
+ if(ch != dwDecrypted[0])
+ continue;
+
+ saveKey1 = seed1;
+
+ // If OK, continue and test all bytes.
+ for(j = 1; j < nDwords; j++)
+ {
+ seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B);
+ seed2 = ch + seed2 + (seed2 << 5) + 3;
+
+ seed2 += StormBuffer[0x400 + (seed1 & 0xFF)];
+ ch = pdwContent[j] ^ (seed1 + seed2);
+
+ if(ch == dwDecrypted[j] && j == nDwords - 1)
+ return saveKey1;
+ }
+ }
+ return 0;
+}
+
+DWORD DetectFileKeyByContent(void * pvFileContent, DWORD dwFileSize)
+{
+ DWORD dwFileKey;
+
+ // Try to break the file encryption key as if it was a WAVE file
+ if(dwFileSize >= 0x0C)
+ {
+ dwFileKey = DetectFileKeyByKnownContent(pvFileContent, 3, 0x46464952, dwFileSize - 8, 0x45564157);
+ if(dwFileKey != 0)
+ return dwFileKey;
+ }
+
+ // Try to break the encryption key as if it was an EXE file
+ if(dwFileSize > 0x40)
+ {
+ dwFileKey = DetectFileKeyByKnownContent(pvFileContent, 2, 0x00905A4D, 0x00000003);
+ if(dwFileKey != 0)
+ return dwFileKey;
+ }
+
+ // Try to break the encryption key as if it was a XML file
+ if(dwFileSize > 0x04)
+ {
+ dwFileKey = DetectFileKeyByKnownContent(pvFileContent, 2, 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 = GetPlainFileNameA(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
+
+bool IsValidMpqHandle(TMPQArchive * ha)
+{
+ if(ha == NULL)
+ return false;
+ if(ha->pHeader == NULL || ha->pHeader->dwID != ID_MPQ)
+ return false;
+
+ return (bool)(ha->pHeader->dwID == ID_MPQ);
+}
+
+bool IsValidFileHandle(TMPQFile * hf)
+{
+ if(hf == NULL)
+ return false;
+
+ if(hf->dwMagic != ID_MPQ_FILE)
+ return false;
+
+ if(hf->pStream != NULL)
+ return true;
+
+ return IsValidMpqHandle(hf->ha);
+}
+
+//-----------------------------------------------------------------------------
+// Hash table and block table manipulation
+
+// 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)
+{
+ TMPQHash * pStartHash; // File hash entry (start)
+ TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
+ TMPQHash * pHash; // File hash entry (current)
+ DWORD dwHashTableSizeMask;
+ DWORD dwIndex = HashString(szFileName, MPQ_HASH_TABLE_INDEX);
+ DWORD dwName1 = HashString(szFileName, MPQ_HASH_NAME_A);
+ DWORD dwName2 = HashString(szFileName, MPQ_HASH_NAME_B);
+
+ // Get the first possible has entry that might be the one
+ dwHashTableSizeMask = ha->pHeader->dwHashTableSize ? (ha->pHeader->dwHashTableSize - 1) : 0;
+ pStartHash = pHash = ha->pHashTable + (dwIndex & dwHashTableSizeMask);
+
+ // There might be deleted entries in the hash table prior to our desired entry.
+ while(pHash->dwBlockIndex != HASH_ENTRY_FREE)
+ {
+ // If the entry agrees, we found it.
+ if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && pHash->dwBlockIndex < ha->dwFileTableSize)
+ return pHash;
+
+ // Move to the next hash entry. Stop searching
+ // if we got reached the original hash entry
+ if(++pHash >= pHashEnd)
+ pHash = ha->pHashTable;
+ if(pHash == pStartHash)
+ break;
+ }
+
+ // The apropriate hash entry was not found
+ return NULL;
+}
+
+TMPQHash * GetNextHashEntry(TMPQArchive * ha, TMPQHash * pFirstHash, TMPQHash * pPrevHash)
+{
+ TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
+ TMPQHash * pHash = pPrevHash;
+ DWORD dwName1 = pPrevHash->dwName1;
+ DWORD dwName2 = pPrevHash->dwName2;
+
+ // Now go for any next entry that follows the pPrevHash,
+ // 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
+ if(++pHash >= pHashEnd)
+ pHash = ha->pHashTable;
+ if(pHash == pFirstHash)
+ break;
+
+ // If the entry is a free entry, stop search
+ if(pHash->dwBlockIndex == HASH_ENTRY_FREE)
+ break;
+
+ // If the entry is not free and the name agrees, we found it
+ if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && pHash->dwBlockIndex < ha->pHeader->dwBlockTableSize)
+ return pHash;
+ }
+
+ // No next entry
+ return NULL;
+}
+
+// Allocates an entry in the hash table
+DWORD AllocateHashEntry(
+ TMPQArchive * ha,
+ TFileEntry * pFileEntry)
+{
+ TMPQHash * pStartHash; // File hash entry (start)
+ TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
+ TMPQHash * pHash; // File hash entry (current)
+ DWORD dwHashTableSizeMask;
+ DWORD dwIndex = HashString(pFileEntry->szFileName, MPQ_HASH_TABLE_INDEX);
+ DWORD dwName1 = HashString(pFileEntry->szFileName, MPQ_HASH_NAME_A);
+ DWORD dwName2 = HashString(pFileEntry->szFileName, MPQ_HASH_NAME_B);
+
+ // Get the first possible has entry that might be the one
+ dwHashTableSizeMask = ha->pHeader->dwHashTableSize ? (ha->pHeader->dwHashTableSize - 1) : 0;
+ pStartHash = pHash = ha->pHashTable + (dwIndex & dwHashTableSizeMask);
+
+ // There might be deleted entries in the hash table prior to our desired entry.
+ while(pHash->dwBlockIndex < HASH_ENTRY_DELETED)
+ {
+ // If there already is an existing entry, reuse it.
+ if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && pHash->lcLocale == pFileEntry->lcLocale)
+ break;
+
+ // Move to the next hash entry.
+ // If we reached the starting entry, it's failure.
+ if(++pHash >= pHashEnd)
+ pHash = ha->pHashTable;
+ if(pHash == pStartHash)
+ return HASH_ENTRY_FREE;
+ }
+
+ // Fill the free hash entry
+ pHash->dwName1 = dwName1;
+ pHash->dwName2 = dwName2;
+ pHash->lcLocale = pFileEntry->lcLocale;
+ pHash->wPlatform = pFileEntry->wPlatform;
+ pHash->dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable);
+
+ // Fill the hash index in the file entry
+ pFileEntry->dwHashIndex = (DWORD)(pHash - ha->pHashTable);
+ return pFileEntry->dwHashIndex;
+}
+
+// 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.
+void FindFreeMpqSpace(TMPQArchive * ha, ULONGLONG * pFreeSpacePos)
+{
+ TMPQHeader * pHeader = ha->pHeader;
+ TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
+ TFileEntry * pFileEntry = ha->pFileTable;
+ ULONGLONG FreeSpacePos = ha->pHeader->dwHeaderSize;
+ DWORD dwChunkCount;
+
+ // Parse the entire block table
+ for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
+ {
+ // Only take existing files
+ if(pFileEntry->dwFlags & MPQ_FILE_EXISTS)
+ {
+ // 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;
+ }
+ }
+ }
+ }
+
+ // Give the free space position to the caller
+ if(pFreeSpacePos != NULL)
+ *pFreeSpacePos = FreeSpacePos;
+}
+
+//-----------------------------------------------------------------------------
+// Common functions - MPQ File
+
+TMPQFile * CreateMpqFile(TMPQArchive * ha)
+{
+ TMPQFile * hf;
+
+ // Allocate space for TMPQFile
+ hf = STORM_ALLOC(TMPQFile, 1);
+ if(hf != NULL)
+ {
+ // Fill the file structure
+ memset(hf, 0, sizeof(TMPQFile));
+ hf->ha = ha;
+ hf->pStream = NULL;
+ hf->dwMagic = ID_MPQ_FILE;
+ }
+
+ return hf;
+}
+
+// Loads a table from MPQ.
+// Can be used for hash table, block table, sector offset table or sector checksum table
+int LoadMpqTable(
+ TMPQArchive * ha,
+ ULONGLONG ByteOffset,
+ void * pvTable,
+ DWORD dwCompressedSize,
+ DWORD dwRealSize,
+ DWORD dwKey)
+{
+ LPBYTE pbCompressed = NULL;
+ LPBYTE pbToRead = (LPBYTE)pvTable;
+ int nError = ERROR_SUCCESS;
+
+ // "interface.MPQ.part" in trial version of World of Warcraft
+ // has block table and hash table compressed.
+ if(dwCompressedSize < dwRealSize)
+ {
+ // Allocate temporary buffer for holding compressed data
+ pbCompressed = STORM_ALLOC(BYTE, dwCompressedSize);
+ if(pbCompressed == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ // Assign the temporary buffer as target for read operation
+ pbToRead = pbCompressed;
+ }
+
+ // Read the table
+ if(FileStream_Read(ha->pStream, &ByteOffset, pbToRead, dwCompressedSize))
+ {
+ // 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 < dwRealSize)
+ {
+ int cbOutBuffer = (int)dwRealSize;
+ int cbInBuffer = (int)dwCompressedSize;
+
+ if(!SCompDecompress2(pvTable, &cbOutBuffer, pbCompressed, cbInBuffer))
+ nError = GetLastError();
+
+ // Free the temporary buffer
+ STORM_FREE(pbCompressed);
+ }
+ }
+ else
+ {
+ nError = GetLastError();
+ }
+
+ BSWAP_ARRAY32_UNSIGNED(pvTable, dwRealSize);
+ return nError;
+}
+
+void CalculateRawSectorOffset(
+ ULONGLONG & RawFilePos,
+ TMPQFile * hf,
+ DWORD dwSectorOffset)
+{
+ //
+ // 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.
+ //
+ // The position of sector table must be always within the MPQ, however.
+ // When a negative sector offset is found, we make sure that we make the addition
+ // just in 32-bits, and then add the MPQ offset.
+ //
+
+ if(dwSectorOffset & 0x80000000)
+ {
+ RawFilePos = hf->ha->MpqPos + ((DWORD)hf->pFileEntry->ByteOffset + dwSectorOffset);
+ }
+ else
+ {
+ RawFilePos = hf->RawFilePos + dwSectorOffset;
+ }
+
+ // We also have to add patch header size, if patch header is present
+ if(hf->pPatchInfo != NULL)
+ RawFilePos += hf->pPatchInfo->dwLength;
+}
+
+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
+int 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) ? (int)ERROR_SUCCESS : (int)ERROR_NOT_ENOUGH_MEMORY;
+}
+
+// Allocates sector offset table
+int 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 = (TPatchInfo *)STORM_ALLOC(BYTE, dwLength);
+ 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
+int 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_COMPRESSED)
+ {
+ __LoadSectorOffsets:
+
+ // Allocate the sector offset table
+ hf->SectorOffsets = (DWORD *)STORM_ALLOC(BYTE, dwSectorOffsLen);
+ 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;
+
+ if(hf->pPatchInfo != NULL)
+ 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, 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
+ if((dwSectorOffset1 - dwSectorOffset0) > pFileEntry->dwCmpSize)
+ {
+ 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)
+ {
+ dwSectorOffsLen = hf->SectorOffsets[0];
+ STORM_FREE(hf->SectorOffsets);
+ hf->SectorOffsets = NULL;
+ goto __LoadSectorOffsets;
+ }
+ }
+ else
+ {
+ memset(hf->SectorOffsets, 0, dwSectorOffsLen);
+ hf->SectorOffsets[0] = dwSectorOffsLen;
+ }
+ }
+
+ return ERROR_SUCCESS;
+}
+
+int 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] == dwExpectedSize)
+ {
+ // 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;
+
+ // Allocate the array for the sector checksums
+ hf->SectorChksums = STORM_ALLOC(DWORD, hf->dwSectorCount);
+ if(hf->SectorChksums == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ // If we are not supposed to load it from the file, allocate empty buffer
+ if(bLoadFromFile == false)
+ {
+ memset(hf->SectorChksums, 0, hf->dwSectorCount * sizeof(DWORD));
+ return ERROR_SUCCESS;
+ }
+
+ // Calculate offset of the CRC table
+ dwCrcSize = hf->dwSectorCount * sizeof(DWORD);
+ dwCrcOffset = hf->SectorOffsets[hf->dwSectorCount];
+ CalculateRawSectorOffset(RawFilePos, hf, dwCrcOffset);
+
+ // Now read the table from the MPQ
+ return LoadMpqTable(ha, RawFilePos, hf->SectorChksums, dwCompressedSize, dwCrcSize, 0);
+ }
+
+ // If the size doesn't match, we ignore sector checksums
+// assert(false);
+ return ERROR_SUCCESS;
+}
+
+int 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;
+}
+
+int 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_COMPRESSED);
+ 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;
+}
+
+
+int WriteSectorChecksums(TMPQFile * hf)
+{
+ TMPQArchive * ha = hf->ha;
+ ULONGLONG RawFilePos;
+ TFileEntry * pFileEntry = hf->pFileEntry;
+ LPBYTE pbCompressed;
+ DWORD dwCompressedSize = 0;
+ DWORD dwCrcSize;
+ int nOutSize;
+ int nError = ERROR_SUCCESS;
+
+ // 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))
+ nError = 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 nError;
+}
+
+int 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;
+ int nError = 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))
+ nError = 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 nError;
+}
+
+
+// Writes the MD5 for each chunk of the raw file data
+int WriteMpqDataMD5(
+ TFileStream * pStream,
+ ULONGLONG RawDataOffs,
+ DWORD dwRawDataSize,
+ DWORD dwChunkSize)
+{
+ unsigned char * md5_array;
+ unsigned char * md5;
+ LPBYTE pbFileChunk;
+ DWORD dwMd5ArraySize = 0;
+ DWORD dwToRead = dwRawDataSize;
+ int nError = 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))
+ {
+ nError = 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(nError == ERROR_SUCCESS)
+ {
+ if(!FileStream_Write(pStream, NULL, md5_array, dwMd5ArraySize))
+ nError = GetLastError();
+ }
+
+ // Free buffers and exit
+ STORM_FREE(pbFileChunk);
+ STORM_FREE(md5_array);
+ return nError;
+}
+
+// Frees the structure for MPQ file
+void FreeMPQFile(TMPQFile *& hf)
+{
+ if(hf != NULL)
+ {
+ // If we have patch file attached to this one, free it first
+ if(hf->hfPatchFile != NULL)
+ FreeMPQFile(hf->hfPatchFile);
+
+ // Then free all buffers allocated in the file structure
+ if(hf->pPatchHeader != NULL)
+ STORM_FREE(hf->pPatchHeader);
+ 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);
+ FileStream_Close(hf->pStream);
+ STORM_FREE(hf);
+ hf = NULL;
+ }
+}
+
+// Frees the MPQ archive
+void FreeMPQArchive(TMPQArchive *& ha)
+{
+ if(ha != NULL)
+ {
+ // First of all, free the patch archive, if any
+ if(ha->haPatch != NULL)
+ FreeMPQArchive(ha->haPatch);
+
+ // 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->pBitmap != NULL)
+ STORM_FREE(ha->pBitmap);
+ if(ha->pHashTable != NULL)
+ STORM_FREE(ha->pHashTable);
+ if(ha->pHetTable != NULL)
+ FreeHetTable(ha->pHetTable);
+ STORM_FREE(ha);
+ ha = NULL;
+ }
+}
+
+const char * GetPlainFileNameA(const char * szFileName)
+{
+ const char * szPlainName = szFileName;
+
+ while(*szFileName != 0)
+ {
+ if(*szFileName == '\\' || *szFileName == '/')
+ szPlainName = szFileName + 1;
+ szFileName++;
+ }
+
+ return szPlainName;
+}
+
+const TCHAR * GetPlainFileNameT(const TCHAR * szFileName)
+{
+ const TCHAR * szPlainName = szFileName;
+
+ while(*szFileName != 0)
+ {
+ if(*szFileName == '\\' || *szFileName == '/')
+ szPlainName = szFileName + 1;
+ szFileName++;
+ }
+
+ return szPlainName;
+}
+
+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)
+{
+ BYTE BitSummary = 0;
+
+ // The MD5 is considered invalid of it is zeroed
+ BitSummary |= pbMd5[0x00] | pbMd5[0x01] | pbMd5[0x02] | pbMd5[0x03] | pbMd5[0x04] | pbMd5[0x05] | pbMd5[0x06] | pbMd5[0x07];
+ BitSummary |= pbMd5[0x08] | pbMd5[0x09] | pbMd5[0x0A] | pbMd5[0x0B] | pbMd5[0x0C] | pbMd5[0x0D] | pbMd5[0x0E] | pbMd5[0x0F];
+ return (BitSummary != 0);
+}
+
+bool VerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5)
+{
+ hash_state md5_state;
+ BYTE md5_digest[MD5_DIGEST_SIZE];
+
+ // Don't verify the block if the MD5 is not valid.
+ if(!IsValidMD5(expected_md5))
+ return true;
+
+ // 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?
+ return (memcmp(md5_digest, expected_md5, MD5_DIGEST_SIZE) == 0);
+}
+
+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 PLATFORM_LITTLE_ENDIAN
+
+//
+// Note that those functions are implemented for Mac operating system,
+// as this is the only supported platform that uses big endian.
+//
+
+// Swaps a signed 16-bit integer
+int16_t SwapInt16(uint16_t data)
+{
+ return (int16_t)CFSwapInt16(data);
+}
+
+// Swaps an unsigned 16-bit integer
+uint16_t SwapUInt16(uint16_t data)
+{
+ return CFSwapInt16(data);
+}
+
+// Swaps signed 32-bit integer
+int32_t SwapInt32(uint32_t data)
+{
+ return (int32_t)CFSwapInt32(data);
+}
+
+// Swaps an unsigned 32-bit integer
+uint32_t SwapUInt32(uint32_t data)
+{
+ return CFSwapInt32(data);
+}
+
+// Swaps signed 64-bit integer
+int64_t SwapInt64(int64_t data)
+{
+ return (int64_t)CFSwapInt64(data);
+}
+
+// Swaps an unsigned 64-bit integer
+uint64_t SwapUInt64(uint64_t data)
+{
+ return CFSwapInt64(data);
+}
+
+// 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 TMPQUserData structure
+void ConvertTMPQUserData(void *userData)
+{
+ TMPQUserData * theData = (TMPQUserData *)userData;
+
+ theData->dwID = SwapUInt32(theData->dwID);
+ theData->cbUserDataSize = SwapUInt32(theData->cbUserDataSize);
+ theData->dwHeaderOffs = SwapUInt32(theData->dwHeaderOffs);
+ theData->cbUserDataHeader = SwapUInt32(theData->cbUserDataHeader);
+}
+
+// Swaps the TMPQHeader structure
+void ConvertTMPQHeader(void *header)
+{
+ TMPQHeader * theHeader = (TMPQHeader *)header;
+
+ 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(theHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2)
+ {
+ // Swap the hi-block table position
+ theHeader->HiBlockTablePos64 = SwapUInt64(theHeader->HiBlockTablePos64);
+
+ theHeader->wHashTablePosHi = SwapUInt16(theHeader->wHashTablePosHi);
+ theHeader->wBlockTablePosHi = SwapUInt16(theHeader->wBlockTablePosHi);
+
+ if(theHeader->wFormatVersion >= MPQ_FORMAT_VERSION_3)
+ {
+ theHeader->ArchiveSize64 = SwapUInt64(theHeader->ArchiveSize64);
+ theHeader->BetTablePos64 = SwapUInt64(theHeader->BetTablePos64);
+ theHeader->HetTablePos64 = SwapUInt64(theHeader->HetTablePos64);
+
+ if(theHeader->wFormatVersion >= 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 // PLATFORM_LITTLE_ENDIAN
diff --git a/src/SBaseDumpData.cpp b/src/SBaseDumpData.cpp
new file mode 100644
index 0000000..7056d8b
--- /dev/null
+++ b/src/SBaseDumpData.cpp
@@ -0,0 +1,144 @@
+/*****************************************************************************/
+/* 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 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 dwIndexSizeTotal = %08X\n", pHetTable->dwIndexSizeTotal);
+ printf("DWORD dwIndexSizeExtra = %08X\n", pHetTable->dwIndexSizeExtra);
+ printf("DWORD dwIndexSize = %08X\n", pHetTable->dwIndexSize);
+ printf("DWORD dwMaxFileCount = %08X\n", pHetTable->dwMaxFileCount);
+ printf("DWORD dwHashTableSize = %08X\n", pHetTable->dwHashTableSize);
+ printf("DWORD dwHashBitSize = %08X\n", pHetTable->dwHashBitSize);
+ 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 dwBetHashSizeTotal = %08X\n", pBetTable->dwBetHashSizeTotal);
+ printf("DWORD dwBetHashSizeExtra = %08X\n", pBetTable->dwBetHashSizeExtra);
+ printf("DWORD dwBetHashSize = %08X\n", pBetTable->dwBetHashSize);
+ printf("DWORD dwMaxFileCount = %08X\n", pBetTable->dwMaxFileCount);
+ 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->dwHashTableSize; i++)
+ {
+ ULONGLONG ByteOffset = 0;
+ ULONGLONG BetHash = 0;
+ DWORD dwFileSize = 0;
+ DWORD dwCmpSize = 0;
+ DWORD dwFlagIndex = 0;
+ DWORD dwFlags = 0;
+ DWORD dwBetIndex = 0;
+
+ GetBits(pHetTable->pBetIndexes, i * pHetTable->dwIndexSizeTotal,
+ pHetTable->dwIndexSize,
+ &dwBetIndex,
+ 4);
+
+ if(dwBetIndex < pHetTable->dwMaxFileCount)
+ {
+ DWORD dwEntryIndex = pBetTable->dwTableEntrySize * dwBetIndex;
+
+ GetBits(pBetTable->pBetHashes, dwBetIndex * pBetTable->dwBetHashSizeTotal,
+ pBetTable->dwBetHashSize,
+ &BetHash,
+ 8);
+
+ GetBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FilePos,
+ pBetTable->dwBitCount_FilePos,
+ &ByteOffset,
+ 8);
+
+ GetBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FileSize,
+ pBetTable->dwBitCount_FileSize,
+ &dwFileSize,
+ 4);
+
+ GetBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_CmpSize,
+ pBetTable->dwBitCount_CmpSize,
+ &dwCmpSize,
+ 4);
+
+ GetBits(pBetTable->pFileTable, dwEntryIndex + pBetTable->dwBitIndex_FlagIndex,
+ pBetTable->dwBitCount_FlagIndex,
+ &dwFlagIndex,
+ 4);
+
+ dwFlags = pBetTable->pFileFlags[dwFlagIndex];
+ }
+
+ printf(" %04X %02lX %04X %016llX %016llX %08X %08X %04X %08X\n", i,
+ pHetTable->pHetHashes[i],
+ dwBetIndex,
+ BetHash,
+ ByteOffset,
+ dwFileSize,
+ dwCmpSize,
+ dwFlagIndex,
+ dwFlags);
+ }
+ printf("-----------------------------------------------------------------------------------------\n");
+}
+
+#endif // __STORMLIB_DUMP_DATA__
diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp
new file mode 100644
index 0000000..c77e71d
--- /dev/null
+++ b/src/SBaseFileTable.cpp
@@ -0,0 +1,2552 @@
+/*****************************************************************************/
+/* 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
+
+//-----------------------------------------------------------------------------
+// Local structures
+
+// Structure for HET table header
+typedef struct _HET_TABLE_HEADER
+{
+ DWORD dwTableSize; // Size of the entire HET table, including HET_TABLE_HEADER (in bytes)
+ DWORD dwMaxFileCount; // Maximum number of files in the MPQ
+ DWORD dwHashTableSize; // Size of the hash table (in bytes)
+ DWORD dwHashEntrySize; // Effective size of the hash entry (in bits)
+ DWORD dwIndexSizeTotal; // Total size of file index (in bits)
+ DWORD dwIndexSizeExtra; // Extra bits in the file index
+ DWORD dwIndexSize; // Effective size of the file index (in bits)
+ DWORD dwIndexTableSize; // Size of the block index subtable (in bytes)
+
+} HET_TABLE_HEADER, *PHET_TABLE_HEADER;
+
+// Structure for BET table header
+typedef struct _BET_TABLE_HEADER
+{
+ DWORD dwTableSize; // Size of the entire BET table, including the header (in bytes)
+ DWORD dwFileCount; // Number of files in the BET table
+ DWORD dwUnknown08;
+ DWORD dwTableEntrySize; // Size of one table entry (in bits)
+ DWORD dwBitIndex_FilePos; // Bit index of the file position (within the entry record)
+ DWORD dwBitIndex_FileSize; // Bit index of the file size (within the entry record)
+ DWORD dwBitIndex_CmpSize; // Bit index of the compressed size (within the entry record)
+ DWORD dwBitIndex_FlagIndex; // Bit index of the flag index (within the entry record)
+ DWORD dwBitIndex_Unknown; // Bit index of the ??? (within the entry record)
+ DWORD dwBitCount_FilePos; // Bit size of file position (in the entry record)
+ DWORD dwBitCount_FileSize; // Bit size of file size (in the entry record)
+ DWORD dwBitCount_CmpSize; // Bit size of compressed file size (in the entry record)
+ DWORD dwBitCount_FlagIndex; // Bit size of flags index (in the entry record)
+ DWORD dwBitCount_Unknown; // Bit size of ??? (in the entry record)
+ DWORD dwBetHashSizeTotal; // Total size of the BET hash
+ DWORD dwBetHashSizeExtra; // Extra bits in the BET hash
+ DWORD dwBetHashSize; // Effective size of BET hash (in bits)
+ DWORD dwBetHashArraySize; // Size of BET hashes array, in bytes
+ DWORD dwFlagCount; // Number of flags in the following array
+
+} BET_TABLE_HEADER, *PBET_TABLE_HEADER;
+
+//-----------------------------------------------------------------------------
+// Support for calculating bit sizes
+
+static void InitFileFlagArray(LPDWORD FlagArray)
+{
+ for(DWORD dwFlagIndex = 0; dwFlagIndex < MAX_FLAG_INDEX; dwFlagIndex++)
+ FlagArray[dwFlagIndex] = INVALID_FLAG_VALUE;
+}
+
+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;
+}
+
+//-----------------------------------------------------------------------------
+// Support functions for BIT_ARRAY
+
+static USHORT SetBitsMask[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
+
+static TBitArray * CreateBitArray(
+ DWORD NumberOfBits,
+ BYTE FillValue)
+{
+ TBitArray * pBitArray;
+ size_t nSize = sizeof(TBitArray) + (NumberOfBits + 7) / 8;
+
+ // Allocate the bit array
+ pBitArray = (TBitArray *)STORM_ALLOC(BYTE, nSize);
+ if(pBitArray != NULL)
+ {
+ memset(pBitArray, FillValue, nSize);
+ pBitArray->NumberOfBits = NumberOfBits;
+ }
+
+ return pBitArray;
+}
+
+void GetBits(
+ TBitArray * pArray,
+ 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 PLATFORM_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)((pArray->Elements[nBytePosition0] >> nBitOffset) | (pArray->Elements[nBytePosition1] << (0x08 - nBitOffset)));
+ }
+ else
+ {
+ BitBuffer = pArray->Elements[nBytePosition0];
+ }
+
+#ifdef PLATFORM_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)(pArray->Elements[nBytePosition0] >> nBitOffset);
+
+ if(nBitLength > (8 - nBitOffset))
+ *pbBuffer = (unsigned char)((pArray->Elements[nBytePosition1] << (8 - nBitOffset)) | (pArray->Elements[nBytePosition0] >> nBitOffset));
+
+ *pbBuffer &= (0x01 << nBitLength) - 1;
+ }
+}
+
+void SetBits(
+ TBitArray * pArray,
+ 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 PLATFORM_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 PLATFORM_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
+ pArray->Elements[nBytePosition] = (BYTE)((pArray->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
+ pArray->Elements[nBytePosition] = (BYTE)((pArray->Elements[nBytePosition] & ~AndMask) | BitBuffer);
+
+ // Update the next byte, if needed
+ if(AndMask & 0xFF00)
+ {
+ nBytePosition++;
+ BitBuffer >>= 0x08;
+ AndMask >>= 0x08;
+
+ pArray->Elements[nBytePosition] = (BYTE)((pArray->Elements[nBytePosition] & ~AndMask) | BitBuffer);
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Support for hash table
+
+// Returns a hash table entry in the following order:
+// 1) A hash table entry with the neutral locale
+// 2) A hash table entry with any other locale
+// 3) NULL
+static TMPQHash * GetHashEntryAny(TMPQArchive * ha, const char * szFileName)
+{
+ TMPQHash * pHashNeutral = NULL;
+ TMPQHash * pFirstHash = GetFirstHashEntry(ha, szFileName);
+ TMPQHash * pHashAny = NULL;
+ TMPQHash * pHash = pFirstHash;
+
+ // Parse the found hashes
+ while(pHash != NULL)
+ {
+ // If we found neutral hash, remember it
+ if(pHash->lcLocale == 0)
+ pHashNeutral = pHash;
+ if(pHashAny == NULL)
+ pHashAny = 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 (pHashNeutral != NULL) ? pHashNeutral : pHashAny;
+}
+
+// Returns a hash table entry in the following order:
+// 1) A hash table entry with the preferred locale
+// 2) A hash table entry with the neutral locale
+// 3) NULL
+static TMPQHash * GetHashEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale)
+{
+ TMPQHash * pHashNeutral = NULL;
+ 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;
+
+ // If we found neutral hash, remember it
+ if(pHash->lcLocale == 0)
+ pHashNeutral = 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 pHashNeutral;
+}
+
+// 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;
+}
+
+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;
+}
+
+static TMPQBlock * TranslateBlockTable(
+ TMPQArchive * ha,
+ ULONGLONG * pcbTableSize,
+ bool * pbNeedHiBlockTable)
+{
+ TFileEntry * pFileEntry = ha->pFileTable;
+ TMPQBlock * pBlockTable;
+ TMPQBlock * pBlock;
+ size_t BlockTableSize;
+ bool bNeedHiBlockTable = false;
+
+ // Allocate copy of the hash table
+ pBlockTable = pBlock = STORM_ALLOC(TMPQBlock, ha->dwFileTableSize);
+ if(pBlockTable != NULL)
+ {
+ // Copy the block table
+ BlockTableSize = sizeof(TMPQBlock) * ha->dwFileTableSize;
+ for(DWORD i = 0; i < ha->dwFileTableSize; i++)
+ {
+ bNeedHiBlockTable = (pFileEntry->ByteOffset >> 32) ? true : false;
+ 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)BlockTableSize;
+
+ if(pbNeedHiBlockTable != NULL)
+ *pbNeedHiBlockTable = bNeedHiBlockTable;
+ }
+
+ return pBlockTable;
+}
+
+static USHORT * TranslateHiBlockTable(
+ TMPQArchive * ha,
+ ULONGLONG * pcbTableSize)
+{
+ TFileEntry * pFileEntry = ha->pFileTable;
+ USHORT * pHiBlockTable;
+ USHORT * pHiBlock;
+ size_t HiBlockTableSize;
+
+ // Allocate copy of the hash table
+ pHiBlockTable = pHiBlock = STORM_ALLOC(USHORT, ha->dwFileTableSize);
+ if(pHiBlockTable != NULL)
+ {
+ // Copy the block table
+ HiBlockTableSize = sizeof(USHORT) * ha->dwFileTableSize;
+ for(DWORD i = 0; i < ha->dwFileTableSize; i++)
+ pHiBlock[i] = (USHORT)(pFileEntry[i].ByteOffset >> 0x20);
+
+ // Give the size to the caller
+ if(pcbTableSize != NULL)
+ *pcbTableSize = (ULONGLONG)HiBlockTableSize;
+ }
+
+ return pHiBlockTable;
+}
+
+//-----------------------------------------------------------------------------
+// General EXT table functions
+
+TMPQExtTable * LoadExtTable(
+ TMPQArchive * ha,
+ ULONGLONG ByteOffset,
+ size_t Size,
+ DWORD dwSignature,
+ DWORD dwKey)
+{
+ TMPQExtTable * pCompressed = NULL; // Compressed table
+ TMPQExtTable * pExtTable = NULL; // Uncompressed table
+
+ // Do nothing if the size is zero
+ if(ByteOffset != 0 && Size != 0)
+ {
+ // Allocate size for the compressed table
+ pExtTable = (TMPQExtTable *)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(TMPQExtTable));
+ 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(TMPQExtTable)), dwKey);
+ BSWAP_ARRAY32_UNSIGNED(pExtTable + 1, pExtTable->dwDataSize);
+
+ // If the table is compressed, decompress it
+ if((pExtTable->dwDataSize + sizeof(TMPQExtTable)) > Size)
+ {
+ pCompressed = pExtTable;
+ pExtTable = (TMPQExtTable *)STORM_ALLOC(BYTE, sizeof(TMPQExtTable) + 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;
+}
+
+// Used in MPQ Editor
+void FreeMpqBuffer(void * pvBuffer)
+{
+ STORM_FREE(pvBuffer);
+}
+
+static int SaveMpqTable(
+ TMPQArchive * ha,
+ void * pMpqTable,
+ ULONGLONG ByteOffset,
+ size_t Size,
+ unsigned char * md5,
+ DWORD dwKey,
+ bool bCompress)
+{
+ ULONGLONG FileOffset;
+ void * pCompressed = NULL;
+ int nError = 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))
+ nError = GetLastError();
+
+ // Free the compressed table, if any
+ if(pCompressed != NULL)
+ STORM_FREE(pCompressed);
+ return nError;
+}
+
+static int SaveExtTable(
+ TMPQArchive * ha,
+ TMPQExtTable * pExtTable,
+ ULONGLONG ByteOffset,
+ DWORD dwTableSize,
+ unsigned char * md5,
+ DWORD dwKey,
+ bool bCompress,
+ LPDWORD pcbTotalSize)
+{
+ ULONGLONG FileOffset;
+ TMPQExtTable * pCompressed = NULL;
+ DWORD cbTotalSize = 0;
+ int nError = 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 = (TMPQExtTable *)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(TMPQExtTable)), 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
+ nError = GetLastError();
+
+ // We have to write raw data MD5
+ if(nError == ERROR_SUCCESS && ha->pHeader->dwRawChunkSize != 0)
+ {
+ nError = 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 nError;
+}
+
+//-----------------------------------------------------------------------------
+// Support for HET table
+
+static void CreateHetHeader(
+ TMPQHetTable * pHetTable,
+ PHET_TABLE_HEADER pHetHeader)
+{
+ // Fill the BET header
+ pHetHeader->dwMaxFileCount = pHetTable->dwMaxFileCount;
+ pHetHeader->dwHashTableSize = pHetTable->dwHashTableSize;
+ pHetHeader->dwHashEntrySize = pHetTable->dwHashBitSize;
+ pHetHeader->dwIndexSizeTotal = GetNecessaryBitCount(pHetTable->dwMaxFileCount);
+ pHetHeader->dwIndexSizeExtra = 0;
+ pHetHeader->dwIndexSize = pHetHeader->dwIndexSizeTotal;
+ pHetHeader->dwIndexTableSize = ((pHetHeader->dwIndexSizeTotal * pHetTable->dwHashTableSize) + 7) / 8;
+
+ // Calculate the total size needed for holding HET table
+ pHetHeader->dwTableSize = sizeof(HET_TABLE_HEADER) +
+ pHetHeader->dwHashTableSize +
+ pHetHeader->dwIndexTableSize;
+}
+
+TMPQHetTable * CreateHetTable(DWORD dwMaxFileCount, DWORD dwHashBitSize, bool bCreateEmpty)
+{
+ TMPQHetTable * pHetTable;
+
+ pHetTable = STORM_ALLOC(TMPQHetTable, 1);
+ if(pHetTable != NULL)
+ {
+ pHetTable->dwIndexSizeTotal = 0;
+ pHetTable->dwIndexSizeExtra = 0;
+ pHetTable->dwIndexSize = pHetTable->dwIndexSizeTotal;
+ pHetTable->dwMaxFileCount = dwMaxFileCount;
+ pHetTable->dwHashTableSize = (dwMaxFileCount * 4 / 3);
+ pHetTable->dwHashBitSize = dwHashBitSize;
+
+ // Size of one index is calculated from max file count
+ pHetTable->dwIndexSizeTotal = GetNecessaryBitCount(dwMaxFileCount);
+ pHetTable->dwIndexSizeExtra = 0;
+ pHetTable->dwIndexSize = pHetTable->dwIndexSizeTotal;
+
+ // Allocate hash table
+ pHetTable->pHetHashes = STORM_ALLOC(BYTE, pHetTable->dwHashTableSize);
+ memset(pHetTable->pHetHashes, 0, pHetTable->dwHashTableSize);
+
+ // If we shall create empty HET table, we have to allocate empty block index table as well
+ if(bCreateEmpty)
+ pHetTable->pBetIndexes = CreateBitArray(pHetTable->dwHashTableSize * pHetTable->dwIndexSizeTotal, 0xFF);
+
+ // Calculate masks
+ pHetTable->AndMask64 = 0;
+ if(dwHashBitSize != 0x40)
+ pHetTable->AndMask64 = (ULONGLONG)1 << dwHashBitSize;
+ pHetTable->AndMask64--;
+
+ pHetTable->OrMask64 = (ULONGLONG)1 << (dwHashBitSize - 1);
+ }
+
+ return pHetTable;
+}
+
+static TMPQHetTable * TranslateHetTable(TMPQExtTable * pExtTable)
+{
+ HET_TABLE_HEADER HetHeader;
+ TMPQHetTable * pHetTable = NULL;
+ LPBYTE pbSrcData = (LPBYTE)(pExtTable + 1);
+
+ // Sanity check
+ assert(pExtTable->dwSignature == HET_TABLE_SIGNATURE);
+ assert(pExtTable->dwVersion == 1);
+
+ // Verify size of the HET table
+ if(pExtTable != NULL && pExtTable->dwDataSize >= sizeof(HET_TABLE_HEADER))
+ {
+ // Copy the table header in order to have it aligned and swapped
+ memcpy(&HetHeader, pbSrcData, sizeof(HET_TABLE_HEADER));
+ BSWAP_ARRAY32_UNSIGNED(&HetHeader, sizeof(HET_TABLE_HEADER));
+ pbSrcData += sizeof(HET_TABLE_HEADER);
+
+ // Verify the size of the table in the header
+ if(HetHeader.dwTableSize == pExtTable->dwDataSize)
+ {
+ // Create translated table
+ pHetTable = CreateHetTable(HetHeader.dwMaxFileCount, HetHeader.dwHashEntrySize, false);
+ if(pHetTable != NULL)
+ {
+ // Copy the hash table size, index size and extra bits from the HET header
+ pHetTable->dwHashTableSize = HetHeader.dwHashTableSize;
+ pHetTable->dwIndexSizeTotal = HetHeader.dwIndexSizeTotal;
+ pHetTable->dwIndexSizeExtra = HetHeader.dwIndexSizeExtra;
+
+ // Fill the hash table
+ if(pHetTable->pHetHashes != NULL)
+ memcpy(pHetTable->pHetHashes, pbSrcData, pHetTable->dwHashTableSize);
+ pbSrcData += pHetTable->dwHashTableSize;
+
+ // Copy the block index table
+ pHetTable->pBetIndexes = CreateBitArray(HetHeader.dwIndexTableSize * 8, 0xFF);
+ if(pHetTable->pBetIndexes != NULL)
+ memcpy(pHetTable->pBetIndexes->Elements, pbSrcData, HetHeader.dwIndexTableSize);
+ pbSrcData += HetHeader.dwIndexTableSize;
+ }
+ }
+ }
+
+ return pHetTable;
+}
+
+static TMPQExtTable * TranslateHetTable(TMPQHetTable * pHetTable, ULONGLONG * pcbHetTable)
+{
+ TMPQExtTable * pExtTable = NULL;
+ HET_TABLE_HEADER HetHeader;
+ LPBYTE pbLinearTable = NULL;
+ LPBYTE pbTrgData;
+ size_t HetTableSize;
+
+ // Prepare header of the HET table
+ CreateHetHeader(pHetTable, &HetHeader);
+
+ // Calculate the total size needed for holding the encrypted HET table
+ HetTableSize = HetHeader.dwTableSize;
+
+ // Allocate space for the linear table
+ pbLinearTable = STORM_ALLOC(BYTE, sizeof(TMPQExtTable) + HetTableSize);
+ if(pbLinearTable != NULL)
+ {
+ // Create the common ext table header
+ pExtTable = (TMPQExtTable *)pbLinearTable;
+ pExtTable->dwSignature = HET_TABLE_SIGNATURE;
+ pExtTable->dwVersion = 1;
+ pExtTable->dwDataSize = (DWORD)HetTableSize;
+ pbTrgData = (LPBYTE)(pExtTable + 1);
+
+ // Copy the HET table header
+ memcpy(pbTrgData, &HetHeader, sizeof(HET_TABLE_HEADER));
+ BSWAP_ARRAY32_UNSIGNED(pbTrgData, sizeof(HET_TABLE_HEADER));
+ pbTrgData += sizeof(HET_TABLE_HEADER);
+
+ // Copy the array of HET hashes
+ memcpy(pbTrgData, pHetTable->pHetHashes, pHetTable->dwHashTableSize);
+ pbTrgData += pHetTable->dwHashTableSize;
+
+ // Copy the bit array of BET indexes
+ memcpy(pbTrgData, pHetTable->pBetIndexes->Elements, HetHeader.dwIndexTableSize);
+
+ // Calculate the total size of the table, including the TMPQExtTable
+ if(pcbHetTable != NULL)
+ {
+ *pcbHetTable = (ULONGLONG)(sizeof(TMPQExtTable) + HetTableSize);
+ }
+ }
+
+ return pExtTable;
+}
+
+DWORD GetFileIndex_Het(TMPQArchive * ha, const char * szFileName)
+{
+ TMPQHetTable * pHetTable = ha->pHetTable;
+ ULONGLONG FileNameHash;
+ ULONGLONG AndMask64;
+ ULONGLONG OrMask64;
+ ULONGLONG BetHash;
+ DWORD StartIndex;
+ DWORD Index;
+ BYTE HetHash; // Upper 8 bits of the masked file name hash
+
+ // Do nothing if the MPQ has no HET table
+ assert(ha->pHetTable != NULL);
+
+ // Calculate 64-bit hash of the file name
+ AndMask64 = pHetTable->AndMask64;
+ OrMask64 = pHetTable->OrMask64;
+ FileNameHash = (HashStringJenkins(szFileName) & AndMask64) | OrMask64;
+
+ // Split the file name hash into two parts:
+ // Part 1: The highest 8 bits of the name hash
+ // Part 2: The rest of the name hash (without the highest 8 bits)
+ HetHash = (BYTE)(FileNameHash >> (pHetTable->dwHashBitSize - 8));
+ BetHash = FileNameHash & (AndMask64 >> 0x08);
+
+ // Calculate the starting index to the hash table
+ StartIndex = Index = (DWORD)(FileNameHash % pHetTable->dwHashTableSize);
+
+ // Go through HET table until we find a terminator
+ while(pHetTable->pHetHashes[Index] != HET_ENTRY_FREE)
+ {
+ // Did we find match ?
+ if(pHetTable->pHetHashes[Index] == HetHash)
+ {
+ DWORD dwFileIndex = 0;
+
+ // Get the index of the BetHash
+ GetBits(pHetTable->pBetIndexes, pHetTable->dwIndexSizeTotal * Index,
+ pHetTable->dwIndexSize,
+ &dwFileIndex,
+ 4);
+
+ //
+ // TODO: This condition only happens when we are opening a MPQ
+ // where some files were deleted by StormLib. Perhaps
+ // we should not allow shrinking of the file table in MPQs v 4.0?
+ // assert(dwFileIndex <= ha->dwFileTableSize);
+ //
+
+ // Verify the BetHash against the entry in the table of BET hashes
+ if(dwFileIndex <= ha->dwFileTableSize && ha->pFileTable[dwFileIndex].BetHash == BetHash)
+ return dwFileIndex;
+ }
+
+ // Move to the next entry in the primary search table
+ // If we came to the start index again, we are done
+ Index = (Index + 1) % pHetTable->dwHashTableSize;
+ if(Index == StartIndex)
+ break;
+ }
+
+ // File not found
+ return HASH_ENTRY_FREE;
+}
+
+DWORD AllocateHetEntry(
+ TMPQArchive * ha,
+ TFileEntry * pFileEntry)
+{
+ TMPQHetTable * pHetTable = ha->pHetTable;
+ ULONGLONG FileNameHash;
+ ULONGLONG AndMask64;
+ ULONGLONG OrMask64;
+ ULONGLONG BetHash;
+ DWORD FreeHetIndex = HASH_ENTRY_FREE;
+ DWORD dwFileIndex;
+ DWORD StartIndex;
+ DWORD Index;
+ BYTE HetHash; // Upper 8 bits of the masked file name hash
+
+ // Do nothing if the MPQ has no HET table
+ assert(ha->pHetTable != NULL);
+
+ // Calculate 64-bit hash of the file name
+ AndMask64 = pHetTable->AndMask64;
+ OrMask64 = pHetTable->OrMask64;
+ FileNameHash = (HashStringJenkins(pFileEntry->szFileName) & AndMask64) | OrMask64;
+
+ // Calculate the starting index to the hash table
+ StartIndex = Index = (DWORD)(FileNameHash % pHetTable->dwHashTableSize);
+
+ // Split the file name hash into two parts:
+ // Part 1: The highest 8 bits of the name hash
+ // Part 2: The rest of the name hash (without the highest 8 bits)
+ HetHash = (BYTE)(FileNameHash >> (pHetTable->dwHashBitSize - 8));
+ BetHash = FileNameHash & (AndMask64 >> 0x08);
+
+ // Go through HET table until we find a terminator
+ for(;;)
+ {
+ // Check for entries that might have been deleted
+ if(pHetTable->pHetHashes[Index] == HET_ENTRY_DELETED)
+ {
+ DWORD dwInvalidBetIndex = (1 << pHetTable->dwIndexSizeTotal) - 1;
+ DWORD dwBetIndex = 0;
+
+ // Verify the BET index. If it's really free, we can use it
+ dwFileIndex = (DWORD)(pFileEntry - ha->pFileTable);
+ GetBits(pHetTable->pBetIndexes, pHetTable->dwIndexSizeTotal * Index,
+ pHetTable->dwIndexSize,
+ &dwBetIndex,
+ 4);
+
+ if(dwBetIndex == dwInvalidBetIndex)
+ {
+ FreeHetIndex = Index;
+ break;
+ }
+ }
+
+ // Is that entry free ?
+ if(pHetTable->pHetHashes[Index] == HET_ENTRY_FREE)
+ {
+ FreeHetIndex = Index;
+ break;
+ }
+
+ // Move to the next entry in the primary search table
+ // If we came to the start index again, we are done
+ Index = (Index + 1) % pHetTable->dwHashTableSize;
+ if(Index == StartIndex)
+ return HASH_ENTRY_FREE;
+ }
+
+ // Fill the HET table entry
+ dwFileIndex = (DWORD)(pFileEntry - ha->pFileTable);
+ pHetTable->pHetHashes[FreeHetIndex] = HetHash;
+ SetBits(pHetTable->pBetIndexes, pHetTable->dwIndexSizeTotal * FreeHetIndex,
+ pHetTable->dwIndexSize,
+ &dwFileIndex,
+ 4);
+ // Fill the file entry
+ pFileEntry->BetHash = BetHash;
+ pFileEntry->dwHetIndex = FreeHetIndex;
+ return FreeHetIndex;
+}
+
+void FreeHetTable(TMPQHetTable * pHetTable)
+{
+ if(pHetTable != NULL)
+ {
+ if(pHetTable->pHetHashes != NULL)
+ STORM_FREE(pHetTable->pHetHashes);
+ if(pHetTable->pBetIndexes != NULL)
+ STORM_FREE(pHetTable->pBetIndexes);
+
+ STORM_FREE(pHetTable);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Support for BET table
+
+static void CreateBetHeader(
+ TMPQArchive * ha,
+ PBET_TABLE_HEADER 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);
+
+ // Get the maximum values for the BET table
+ for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
+ {
+ // 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->dwFileCount = ha->dwFileTableSize;
+ pBetHeader->dwFlagCount = dwMaxFlagIndex + 1;
+ pBetHeader->dwUnknown08 = 0x10;
+
+ // Save the total size of the BET hash
+ pBetHeader->dwBetHashSizeTotal = ha->pHetTable->dwHashBitSize - 0x08;
+ pBetHeader->dwBetHashSizeExtra = 0;
+ pBetHeader->dwBetHashSize = pBetHeader->dwBetHashSizeTotal;
+ pBetHeader->dwBetHashArraySize = ((pBetHeader->dwBetHashSizeTotal * pBetHeader->dwFileCount) + 7) / 8;
+
+ // Save the total table size
+ pBetHeader->dwTableSize = sizeof(BET_TABLE_HEADER) +
+ pBetHeader->dwFlagCount * sizeof(DWORD) +
+ ((pBetHeader->dwTableEntrySize * pBetHeader->dwFileCount) + 7) / 8 +
+ pBetHeader->dwBetHashArraySize;
+}
+
+TMPQBetTable * CreateBetTable(DWORD dwFileCount)
+{
+ TMPQBetTable * pBetTable;
+
+ // Allocate BET table
+ pBetTable = STORM_ALLOC(TMPQBetTable, 1);
+ if(pBetTable != NULL)
+ {
+ memset(pBetTable, 0, sizeof(TMPQBetTable));
+ pBetTable->dwFileCount = dwFileCount;
+ }
+
+ return pBetTable;
+}
+
+static TMPQBetTable * TranslateBetTable(
+ TMPQArchive * ha,
+ TMPQExtTable * pExtTable)
+{
+ BET_TABLE_HEADER BetHeader;
+ TMPQBetTable * pBetTable = NULL;
+ LPBYTE pbSrcData = (LPBYTE)(pExtTable + 1);
+ DWORD LengthInBytes;
+
+ // Sanity check
+ assert(pExtTable->dwSignature == BET_TABLE_SIGNATURE);
+ assert(pExtTable->dwVersion == 1);
+ assert(ha->pHetTable != NULL);
+ ha = ha;
+
+ // Verify size of the HET table
+ if(pExtTable != NULL && pExtTable->dwDataSize >= sizeof(BET_TABLE_HEADER))
+ {
+ // Copy the table header in order to have it aligned and swapped
+ memcpy(&BetHeader, pbSrcData, sizeof(BET_TABLE_HEADER));
+ BSWAP_ARRAY32_UNSIGNED(&BetHeader, sizeof(BET_TABLE_HEADER));
+ pbSrcData += sizeof(BET_TABLE_HEADER);
+
+ // Some MPQs affected by a bug in StormLib have pBetTable->dwFileCount
+ // greater than ha->dwMaxFileCount
+ if(BetHeader.dwFileCount > ha->dwMaxFileCount)
+ return NULL;
+
+ // Verify the size of the table in the header
+ if(BetHeader.dwTableSize == pExtTable->dwDataSize)
+ {
+ // Create translated table
+ pBetTable = CreateBetTable(BetHeader.dwFileCount);
+ if(pBetTable != NULL)
+ {
+ // Copy the variables from the header to the BetTable
+ pBetTable->dwTableEntrySize = BetHeader.dwTableEntrySize;
+ pBetTable->dwBitIndex_FilePos = BetHeader.dwBitIndex_FilePos;
+ pBetTable->dwBitIndex_FileSize = BetHeader.dwBitIndex_FileSize;
+ pBetTable->dwBitIndex_CmpSize = BetHeader.dwBitIndex_CmpSize;
+ pBetTable->dwBitIndex_FlagIndex = BetHeader.dwBitIndex_FlagIndex;
+ pBetTable->dwBitIndex_Unknown = BetHeader.dwBitIndex_Unknown;
+ pBetTable->dwBitCount_FilePos = BetHeader.dwBitCount_FilePos;
+ pBetTable->dwBitCount_FileSize = BetHeader.dwBitCount_FileSize;
+ pBetTable->dwBitCount_CmpSize = BetHeader.dwBitCount_CmpSize;
+ pBetTable->dwBitCount_FlagIndex = BetHeader.dwBitCount_FlagIndex;
+ pBetTable->dwBitCount_Unknown = BetHeader.dwBitCount_Unknown;
+
+ // Since we don't know what the "unknown" is, we'll assert when it's nonzero
+ assert(pBetTable->dwBitCount_Unknown == 0);
+
+ // Allocate array for flags
+ if(BetHeader.dwFlagCount != 0)
+ {
+ // Allocate array for file flags and load it
+ pBetTable->pFileFlags = STORM_ALLOC(DWORD, BetHeader.dwFlagCount);
+ if(pBetTable->pFileFlags != NULL)
+ {
+ LengthInBytes = BetHeader.dwFlagCount * sizeof(DWORD);
+ memcpy(pBetTable->pFileFlags, pbSrcData, LengthInBytes);
+ BSWAP_ARRAY32_UNSIGNED(pBetTable->pFileFlags, LengthInBytes);
+ pbSrcData += LengthInBytes;
+ }
+
+ // Save the number of flags
+ pBetTable->dwFlagCount = BetHeader.dwFlagCount;
+ }
+
+ // Load the bit-based file table
+ pBetTable->pFileTable = CreateBitArray(pBetTable->dwTableEntrySize * BetHeader.dwFileCount, 0);
+ LengthInBytes = (pBetTable->pFileTable->NumberOfBits + 7) / 8;
+ if(pBetTable->pFileTable != NULL)
+ memcpy(pBetTable->pFileTable->Elements, pbSrcData, LengthInBytes);
+ pbSrcData += LengthInBytes;
+
+ // Fill the sizes of BET hash
+ pBetTable->dwBetHashSizeTotal = BetHeader.dwBetHashSizeTotal;
+ pBetTable->dwBetHashSizeExtra = BetHeader.dwBetHashSizeExtra;
+ pBetTable->dwBetHashSize = BetHeader.dwBetHashSize;
+
+ // Create and load the array of BET hashes
+ pBetTable->pBetHashes = CreateBitArray(pBetTable->dwBetHashSizeTotal * BetHeader.dwFileCount, 0);
+ LengthInBytes = (pBetTable->pBetHashes->NumberOfBits + 7) / 8;
+ if(pBetTable->pBetHashes != NULL)
+ memcpy(pBetTable->pBetHashes->Elements, pbSrcData, LengthInBytes);
+ pbSrcData += BetHeader.dwBetHashArraySize;
+
+ // Dump both tables
+// DumpHetAndBetTable(ha->pHetTable, pBetTable);
+ }
+ }
+ }
+
+ return pBetTable;
+}
+
+TMPQExtTable * TranslateBetTable(
+ TMPQArchive * ha,
+ ULONGLONG * pcbBetTable)
+{
+ TMPQExtTable * pExtTable = NULL;
+ BET_TABLE_HEADER BetHeader;
+ TBitArray * pBitArray = NULL;
+ LPBYTE pbLinearTable = NULL;
+ LPBYTE pbTrgData;
+ size_t BetTableSize;
+ DWORD LengthInBytes;
+ DWORD FlagArray[MAX_FLAG_INDEX];
+ DWORD i;
+
+ // Calculate the bit sizes of various entries
+ InitFileFlagArray(FlagArray);
+ CreateBetHeader(ha, &BetHeader);
+
+ // Calculate the size of the BET table
+ BetTableSize = sizeof(BET_TABLE_HEADER) +
+ BetHeader.dwFlagCount * sizeof(DWORD) +
+ ((BetHeader.dwTableEntrySize * BetHeader.dwFileCount) + 7) / 8 +
+ BetHeader.dwBetHashArraySize;
+
+ // Allocate space
+ pbLinearTable = STORM_ALLOC(BYTE, sizeof(TMPQExtTable) + BetTableSize);
+ if(pbLinearTable != NULL)
+ {
+ // Create the common ext table header
+ pExtTable = (TMPQExtTable *)pbLinearTable;
+ pExtTable->dwSignature = BET_TABLE_SIGNATURE;
+ pExtTable->dwVersion = 1;
+ pExtTable->dwDataSize = (DWORD)BetTableSize;
+ pbTrgData = (LPBYTE)(pExtTable + 1);
+
+ // Copy the BET table header
+ memcpy(pbTrgData, &BetHeader, sizeof(BET_TABLE_HEADER));
+ BSWAP_ARRAY32_UNSIGNED(pbTrgData, sizeof(BET_TABLE_HEADER));
+ pbTrgData += sizeof(BET_TABLE_HEADER);
+
+ // Save the bit-based block table
+ pBitArray = CreateBitArray(BetHeader.dwFileCount * BetHeader.dwTableEntrySize, 0);
+ if(pBitArray != NULL)
+ {
+ TFileEntry * pFileEntry = ha->pFileTable;
+ DWORD dwFlagIndex = 0;
+ DWORD nBitOffset = 0;
+
+ // Construct the array of flag values and bit-based file table
+ for(i = 0; i < BetHeader.dwFileCount; i++, pFileEntry++)
+ {
+ //
+ // Note: Blizzard MPQs contain valid values even for non-existant files
+ // (FilePos, FileSize, CmpSize and FlagIndex)
+ // Note: If flags is zero, it must be in the flag table too !!!
+ //
+
+ // Save the byte offset
+ SetBits(pBitArray, nBitOffset + BetHeader.dwBitIndex_FilePos,
+ BetHeader.dwBitCount_FilePos,
+ &pFileEntry->ByteOffset,
+ 8);
+ SetBits(pBitArray, nBitOffset + BetHeader.dwBitIndex_FileSize,
+ BetHeader.dwBitCount_FileSize,
+ &pFileEntry->dwFileSize,
+ 4);
+ SetBits(pBitArray, nBitOffset + BetHeader.dwBitIndex_CmpSize,
+ BetHeader.dwBitCount_CmpSize,
+ &pFileEntry->dwCmpSize,
+ 4);
+
+ // Save the flag index
+ dwFlagIndex = GetFileFlagIndex(FlagArray, pFileEntry->dwFlags);
+ SetBits(pBitArray, nBitOffset + BetHeader.dwBitIndex_FlagIndex,
+ 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 BET hashes
+ pBitArray = CreateBitArray(BetHeader.dwBetHashSizeTotal * BetHeader.dwFileCount, 0);
+ if(pBitArray != NULL)
+ {
+ TFileEntry * pFileEntry = ha->pFileTable;
+ ULONGLONG AndMask64 = ha->pHetTable->AndMask64;
+ ULONGLONG OrMask64 = ha->pHetTable->OrMask64;
+
+ for(i = 0; i < BetHeader.dwFileCount; i++)
+ {
+ ULONGLONG FileNameHash = 0;
+
+ // Calculate 64-bit hash of the file name
+ if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) && pFileEntry->szFileName != NULL)
+ {
+ FileNameHash = (HashStringJenkins(pFileEntry->szFileName) & AndMask64) | OrMask64;
+ FileNameHash = FileNameHash & (AndMask64 >> 0x08);
+ }
+
+ // Insert the name hash to the bit array
+ SetBits(pBitArray, BetHeader.dwBetHashSizeTotal * i,
+ BetHeader.dwBetHashSize,
+ &FileNameHash,
+ 8);
+
+ // Move to the next file entry
+ pFileEntry++;
+ }
+
+ // 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(TMPQExtTable) + BetTableSize);
+ }
+ }
+
+ return pExtTable;
+}
+
+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->pBetHashes != NULL)
+ STORM_FREE(pBetTable->pBetHashes);
+
+ STORM_FREE(pBetTable);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Support for file table
+
+TFileEntry * GetFileEntryAny(TMPQArchive * ha, const char * szFileName)
+{
+ TMPQHash * pHash;
+ DWORD dwFileIndex;
+
+ // 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;
+ }
+
+ // Otherwise, perform the file search in the classic hash table
+ if(ha->pHashTable != NULL)
+ {
+ pHash = GetHashEntryAny(ha, szFileName);
+ if(pHash != NULL && pHash->dwBlockIndex < ha->dwFileTableSize)
+ return ha->pFileTable + pHash->dwBlockIndex;
+ }
+
+ // Not found
+ return NULL;
+}
+
+TFileEntry * GetFileEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale)
+{
+ TMPQHash * pHash;
+ DWORD dwFileIndex;
+
+ // 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;
+ }
+
+ // Otherwise, perform the file search in the classic hash table
+ if(ha->pHashTable != NULL)
+ {
+ pHash = GetHashEntryLocale(ha, szFileName, lcLocale);
+ if(pHash != NULL && pHash->dwBlockIndex < ha->dwFileTableSize)
+ return ha->pFileTable + pHash->dwBlockIndex;
+ }
+
+ // Not found
+ return NULL;
+}
+
+TFileEntry * GetFileEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcLocale)
+{
+ TMPQHash * pHash;
+ DWORD dwFileIndex;
+
+ // 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;
+ }
+
+ // Otherwise, perform the file search in the classic hash table
+ if(ha->pHashTable != NULL)
+ {
+ pHash = GetHashEntryExact(ha, szFileName, lcLocale);
+ if(pHash != NULL && pHash->dwBlockIndex < ha->dwFileTableSize)
+ return ha->pFileTable + pHash->dwBlockIndex;
+ }
+
+ // Not found
+ return NULL;
+}
+
+TFileEntry * GetFileEntryByIndex(TMPQArchive * ha, DWORD dwIndex)
+{
+ // For MPQs with classic hash table
+ if(dwIndex < ha->dwFileTableSize)
+ return ha->pFileTable + dwIndex;
+ return NULL;
+}
+
+void AllocateFileName(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);
+ }
+}
+
+
+// Finds a free file entry. Does NOT increment table size.
+TFileEntry * FindFreeFileEntry(TMPQArchive * ha)
+{
+ TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
+ TFileEntry * pFreeEntry = NULL;
+ TFileEntry * pFileEntry;
+
+ // Try to find a free entry
+ for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
+ {
+ // If that entry is free, we reuse it
+ if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0)
+ {
+ pFreeEntry = pFileEntry;
+ break;
+ }
+
+ //
+ // Note: Files with "delete marker" are not deleted.
+ // Don't consider them free entries
+ //
+ }
+
+ // Do we have a deleted entry?
+ if(pFreeEntry != NULL)
+ {
+ ClearFileEntry(ha, pFreeEntry);
+ return pFreeEntry;
+ }
+
+ // If no file entry within the existing file table is free,
+ // we try the reserve space after current file table
+ if(ha->dwFileTableSize < ha->dwMaxFileCount)
+ return ha->pFileTable + ha->dwFileTableSize;
+
+ // If we reached maximum file count, we cannot add more files to the MPQ
+ assert(ha->dwFileTableSize == ha->dwMaxFileCount);
+ return NULL;
+}
+
+
+TFileEntry * AllocateFileEntry(TMPQArchive * ha, const char * szFileName, LCID lcLocale)
+{
+ TFileEntry * pFileEntry = NULL;
+ TMPQHash * pHash;
+ DWORD dwHashIndex;
+ DWORD dwFileIndex;
+ bool bHashEntryExists = false;
+ bool bHetEntryExists = false;
+
+ // If the archive has classic hash table, we try to
+ // find the file in the hash table
+ if(ha->pHashTable != NULL)
+ {
+ // If the hash entry is already there, we reuse the file entry
+ pHash = GetHashEntryExact(ha, szFileName, lcLocale);
+ if(pHash != NULL)
+ {
+ pFileEntry = ha->pFileTable + pHash->dwBlockIndex;
+ bHashEntryExists = true;
+ }
+ }
+
+ // If the archive has HET table, try to use it for
+ // finding the file
+ if(ha->pHetTable != NULL)
+ {
+ dwFileIndex = GetFileIndex_Het(ha, szFileName);
+ if(dwFileIndex != HASH_ENTRY_FREE)
+ {
+ pFileEntry = ha->pFileTable + dwFileIndex;
+ bHetEntryExists = true;
+ }
+ }
+
+ // If still haven't found the file entry, we allocate new one
+ if(pFileEntry == NULL)
+ {
+ pFileEntry = FindFreeFileEntry(ha);
+ if(pFileEntry == NULL)
+ return NULL;
+ }
+
+ // Fill the rest of the file entry
+ pFileEntry->ByteOffset = 0;
+ pFileEntry->FileTime = 0;
+ pFileEntry->dwFileSize = 0;
+ pFileEntry->dwCmpSize = 0;
+ pFileEntry->dwFlags = 0;
+ pFileEntry->lcLocale = (USHORT)lcLocale;
+ pFileEntry->wPlatform = 0;
+ pFileEntry->dwCrc32 = 0;
+ memset(pFileEntry->md5, 0, MD5_DIGEST_SIZE);
+
+ // Allocate space for file name, if it's not there yet
+ AllocateFileName(pFileEntry, szFileName);
+
+ // If the free file entry is at the end of the file table,
+ // we have to increment file table size
+ if(pFileEntry == ha->pFileTable + ha->dwFileTableSize)
+ {
+ assert(ha->dwFileTableSize < ha->dwMaxFileCount);
+ ha->pHeader->dwBlockTableSize++;
+ ha->dwFileTableSize++;
+ }
+
+ // If the MPQ has hash table, we have to insert the new entry into the hash table
+ if(ha->pHashTable != NULL && bHashEntryExists == false)
+ {
+ dwHashIndex = AllocateHashEntry(ha, pFileEntry);
+ assert(dwHashIndex != HASH_ENTRY_FREE);
+ }
+
+ // If the MPQ has HET table, we have to insert it to the HET table as well
+ if(ha->pHetTable != NULL && bHetEntryExists == false)
+ {
+ // TODO: Does HET table even support locales?
+ // Most probably, Blizzard gave up that silly idea long ago.
+ dwHashIndex = AllocateHetEntry(ha, pFileEntry);
+ assert(dwHashIndex != HASH_ENTRY_FREE);
+ }
+
+ // Return the file entry
+ return pFileEntry;
+}
+
+int RenameFileEntry(
+ TMPQArchive * ha,
+ TFileEntry * pFileEntry,
+ const char * szNewFileName)
+{
+ TMPQHash * pHash;
+ DWORD dwFileIndex;
+ int nError = ERROR_SUCCESS;
+
+ // If the MPQ has classic hash table, clear the entry there
+ if(ha->pHashTable != NULL)
+ {
+ assert(pFileEntry->dwHashIndex < ha->pHeader->dwHashTableSize);
+
+ pHash = ha->pHashTable + pFileEntry->dwHashIndex;
+ memset(pHash, 0xFF, sizeof(TMPQHash));
+ pHash->dwBlockIndex = HASH_ENTRY_DELETED;
+ }
+
+ // If the MPQ has HET table, clear the entry there as well
+ if(ha->pHetTable != NULL)
+ {
+ TMPQHetTable * pHetTable = ha->pHetTable;
+ DWORD dwInvalidFileIndex = (1 << pHetTable->dwIndexSizeTotal) - 1;
+
+ assert(pFileEntry->dwHetIndex < pHetTable->dwHashTableSize);
+
+ // Clear the entry in the HET hash array
+ pHetTable->pHetHashes[pFileEntry->dwHetIndex] = HET_ENTRY_DELETED;
+
+ // Set the BET index to invalid index
+ SetBits(pHetTable->pBetIndexes, pHetTable->dwIndexSizeTotal * pFileEntry->dwHetIndex,
+ pHetTable->dwIndexSize,
+ &dwInvalidFileIndex,
+ 4);
+ }
+
+ // Free the old file name
+ if(pFileEntry->szFileName != NULL)
+ STORM_FREE(pFileEntry->szFileName);
+ pFileEntry->szFileName = NULL;
+
+ // Allocate new file name
+ AllocateFileName(pFileEntry, szNewFileName);
+
+ // Now find a hash entry for the new file name
+ if(ha->pHashTable != NULL)
+ {
+ // Try to find the hash table entry for the new file name
+ // Note: If this fails, we leave the MPQ in a corrupt state
+ dwFileIndex = AllocateHashEntry(ha, pFileEntry);
+ if(dwFileIndex == HASH_ENTRY_FREE)
+ nError = ERROR_FILE_CORRUPT;
+ }
+
+ // If the archive has HET table, we have to allocate HET table for the file as well
+ // finding the file
+ if(ha->pHetTable != NULL)
+ {
+ dwFileIndex = AllocateHetEntry(ha, pFileEntry);
+ if(dwFileIndex == HASH_ENTRY_FREE)
+ nError = ERROR_FILE_CORRUPT;
+ }
+
+ // Invalidate the entries for (listfile) and (attributes)
+ // After we are done with MPQ changes, we need to re-create them
+ InvalidateInternalFiles(ha);
+ return nError;
+}
+
+void ClearFileEntry(
+ TMPQArchive * ha,
+ TFileEntry * pFileEntry)
+{
+ TMPQHash * pHash = NULL;
+
+ // If the MPQ has classic hash table, clear the entry there
+ if(ha->pHashTable != NULL)
+ {
+ assert(pFileEntry->dwHashIndex < ha->pHeader->dwHashTableSize);
+
+ pHash = ha->pHashTable + pFileEntry->dwHashIndex;
+ memset(pHash, 0xFF, sizeof(TMPQHash));
+ pHash->dwBlockIndex = HASH_ENTRY_DELETED;
+ }
+
+ // If the MPQ has HET table, clear the entry there as well
+ if(ha->pHetTable != NULL)
+ {
+ TMPQHetTable * pHetTable = ha->pHetTable;
+ DWORD dwInvalidFileIndex = (1 << pHetTable->dwIndexSizeTotal) - 1;
+
+ assert(pFileEntry->dwHetIndex < pHetTable->dwHashTableSize);
+
+ // Clear the entry in the HET hash array
+ pHetTable->pHetHashes[pFileEntry->dwHetIndex] = HET_ENTRY_DELETED;
+
+ // Set the BET index to invalid index
+ SetBits(pHetTable->pBetIndexes, pHetTable->dwIndexSizeTotal * pFileEntry->dwHetIndex,
+ pHetTable->dwIndexSize,
+ &dwInvalidFileIndex,
+ 4);
+ }
+
+ // Free the file name, and set the file entry as deleted
+ if(pFileEntry->szFileName != NULL)
+ STORM_FREE(pFileEntry->szFileName);
+
+ // Invalidate the file entry
+ memset(pFileEntry, 0, sizeof(TFileEntry));
+}
+
+int FreeFileEntry(
+ TMPQArchive * ha,
+ TFileEntry * pFileEntry)
+{
+ TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
+ TFileEntry * pTempEntry;
+ int nError = ERROR_SUCCESS;
+
+ //
+ // If we have HET table, we cannot just get rid of the file
+ // Doing so would lead to empty gaps in the HET table
+ // We have to keep BET hash, hash index, HET index, locale, platform and file name
+ //
+
+ if(ha->pHetTable == NULL)
+ {
+ TFileEntry * pLastFileEntry = ha->pFileTable + ha->dwFileTableSize - 1;
+ TFileEntry * pLastUsedEntry = pLastFileEntry;
+
+ // Zero the file entry
+ ClearFileEntry(ha, pFileEntry);
+
+ // Now there is a chance that we created a chunk of free
+ // file entries at the end of the file table. We check this
+ // and eventually free all deleted file entries at the end
+ for(pTempEntry = ha->pFileTable; pTempEntry < pFileTableEnd; pTempEntry++)
+ {
+ // Is that an occupied file entry?
+ if(pTempEntry->dwFlags & MPQ_FILE_EXISTS)
+ pLastUsedEntry = pTempEntry;
+ }
+
+ // Can we free some entries at the end?
+ if(pLastUsedEntry < pLastFileEntry)
+ {
+ // Fix the size of the file table entry
+ ha->dwFileTableSize = (DWORD)(pLastUsedEntry - ha->pFileTable) + 1;
+ ha->pHeader->dwBlockTableSize = ha->dwFileTableSize;
+ }
+ }
+ else
+ {
+ // Note: Deleted entries in Blizzard MPQs version 4.0
+ // normally contain valid byte offset and length
+ pFileEntry->dwFlags &= ~MPQ_FILE_EXISTS;
+ nError = ERROR_SUCCESS;
+ }
+
+ return nError;
+}
+
+void InvalidateInternalFiles(TMPQArchive * ha)
+{
+ TFileEntry * pFileEntry;
+
+ // Invalidate the (listfile), if not done yet
+ if(!(ha->dwFlags & MPQ_FLAG_INV_LISTFILE))
+ {
+ pFileEntry = GetFileEntryExact(ha, LISTFILE_NAME, LANG_NEUTRAL);
+ if(pFileEntry != NULL)
+ FreeFileEntry(ha, pFileEntry);
+ ha->dwFlags |= MPQ_FLAG_INV_LISTFILE;
+ }
+
+ // Invalidate the (attributes), if not done yet
+ if(!(ha->dwFlags & MPQ_FLAG_INV_ATTRIBUTES))
+ {
+ pFileEntry = GetFileEntryExact(ha, ATTRIBUTES_NAME, LANG_NEUTRAL);
+ if(pFileEntry != NULL)
+ FreeFileEntry(ha, pFileEntry);
+ ha->dwFlags |= MPQ_FLAG_INV_ATTRIBUTES;
+ }
+
+ // Remember that the MPQ has been changed and it will be necessary
+ // to update the tables
+ ha->dwFlags |= MPQ_FLAG_CHANGED;
+}
+
+//-----------------------------------------------------------------------------
+// Functions that loads and verify MPQ data bitmap
+
+int LoadMpqDataBitmap(TMPQArchive * ha, ULONGLONG FileSize, bool * pbFileIsComplete)
+{
+ TMPQBitmap * pBitmap = NULL;
+ TMPQBitmap DataBitmap;
+ ULONGLONG BitmapOffset;
+ ULONGLONG EndOfMpq;
+ DWORD DataBlockCount = 0;
+ DWORD BitmapByteSize;
+ DWORD WholeByteCount;
+ DWORD ExtraBitsCount;
+
+ // Is there enough space for a MPQ bitmap?
+ EndOfMpq = ha->MpqPos + ha->pHeader->ArchiveSize64;
+ FileSize = FileSize - sizeof(TMPQBitmap);
+ if(FileSize > EndOfMpq)
+ {
+ // Try to load the data bitmap from the end of the file
+ if(FileStream_Read(ha->pStream, &FileSize, &DataBitmap, sizeof(TMPQBitmap)))
+ {
+ // Is it a valid data bitmap?
+ BSWAP_ARRAY32_UNSIGNED((LPDWORD)(&DataBitmap), sizeof(TMPQBitmap));
+ if(DataBitmap.dwSignature == MPQ_DATA_BITMAP_SIGNATURE)
+ {
+ // We assume that MPQs with data bitmap begin at position 0
+ assert(ha->MpqPos == 0);
+
+ // Calculate the number of extra bytes for data bitmap
+ DataBlockCount = (DWORD)(((ha->pHeader->ArchiveSize64 - 1) / DataBitmap.dwBlockSize) + 1);
+ BitmapByteSize = ((DataBlockCount - 1) / 8) + 1;
+
+ // Verify the data block size
+ BitmapOffset = ((ULONGLONG)DataBitmap.dwMapOffsetHi << 32) | DataBitmap.dwMapOffsetLo;
+ assert((DWORD)(FileSize - BitmapOffset) == BitmapByteSize);
+
+ // Allocate space for the data bitmap
+ pBitmap = (TMPQBitmap *)STORM_ALLOC(BYTE, sizeof(TMPQBitmap) + BitmapByteSize);
+ if(pBitmap != NULL)
+ {
+ // Copy the bitmap header
+ memcpy(pBitmap, &DataBitmap, sizeof(TMPQBitmap));
+
+ // Read the remaining part
+ if(!FileStream_Read(ha->pStream, &BitmapOffset, (pBitmap + 1), BitmapByteSize))
+ {
+ STORM_FREE(pBitmap);
+ pBitmap = NULL;
+ }
+ }
+ }
+ }
+ }
+
+ // If the caller asks for file completeness, check it
+ if(pBitmap != NULL && pbFileIsComplete != NULL)
+ {
+ LPBYTE pbBitmap = (LPBYTE)(pBitmap + 1);
+ DWORD i;
+ bool bFileIsComplete = true;
+
+ // Calculate the number of whole bytes and extra bits of the bitmap
+ WholeByteCount = (DataBlockCount / 8);
+ ExtraBitsCount = (DataBlockCount & 7);
+
+ // Verify the whole bytes - their value must be 0xFF
+ for(i = 0; i < WholeByteCount; i++)
+ {
+ if(pbBitmap[i] != 0xFF)
+ bFileIsComplete = false;
+ }
+
+ // If there are extra bits, calculate the mask
+ if(ExtraBitsCount != 0)
+ {
+ BYTE ExpectedValue = (BYTE)((1 << ExtraBitsCount) - 1);
+
+ if(pbBitmap[i] != ExpectedValue)
+ bFileIsComplete = false;
+ }
+
+ // Give the result to the caller
+ *pbFileIsComplete = bFileIsComplete;
+ }
+
+ ha->pBitmap = pBitmap;
+ return ERROR_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Support for file tables - hash table, block table, hi-block table
+
+int CreateHashTable(TMPQArchive * ha, DWORD dwHashTableSize)
+{
+ TMPQHash * pHashTable;
+
+ // Sanity checks
+ assert((dwHashTableSize & (dwHashTableSize - 1)) == 0);
+ assert(ha->pHashTable == NULL);
+
+ // 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->pHashTable = pHashTable;
+
+ // Set the max file count, if needed
+ if(ha->pHetTable == NULL)
+ ha->dwMaxFileCount = dwHashTableSize;
+ return ERROR_SUCCESS;
+}
+
+TMPQHash * LoadHashTable(TMPQArchive * ha)
+{
+ TMPQHeader * pHeader = ha->pHeader;
+ ULONGLONG ByteOffset;
+ TMPQHash * pHashTable;
+ DWORD dwTableSize;
+ DWORD dwCmpSize;
+ int nError;
+
+ // If the MPQ has no hash table, do nothing
+ if(pHeader->dwHashTablePos == 0 && pHeader->wHashTablePosHi == 0)
+ return NULL;
+
+ // If the hash table size is zero, do nothing
+ if(pHeader->dwHashTableSize == 0)
+ return NULL;
+
+ // Allocate buffer for the hash table
+ dwTableSize = pHeader->dwHashTableSize * sizeof(TMPQHash);
+ pHashTable = STORM_ALLOC(TMPQHash, pHeader->dwHashTableSize);
+ if(pHashTable == NULL)
+ return NULL;
+
+ // Compressed size of the hash table
+ dwCmpSize = (DWORD)pHeader->HashTableSize64;
+
+ //
+ // Load the table from the MPQ, with decompression
+ //
+ // Note: We will NOT check if the hash table is properly decrypted.
+ // Some MPQ protectors corrupt the hash table by rewriting part of it.
+ // Hash table, the way how it works, allows arbitrary values for unused entries.
+ //
+
+ ByteOffset = ha->MpqPos + MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos);
+ nError = LoadMpqTable(ha, ByteOffset, pHashTable, dwCmpSize, dwTableSize, MPQ_KEY_HASH_TABLE);
+ if(nError != ERROR_SUCCESS)
+ {
+ STORM_FREE(pHashTable);
+ pHashTable = NULL;
+ }
+
+ // Return the hash table
+ return pHashTable;
+}
+
+static void FixBlockTableSize(
+ TMPQArchive * ha,
+ TMPQBlock * pBlockTable,
+ DWORD dwClaimedSize)
+{
+ TMPQHeader * pHeader = ha->pHeader;
+ ULONGLONG BlockTableStart;
+ ULONGLONG BlockTableEnd;
+ ULONGLONG FileDataStart;
+
+ // Only perform this check on MPQs version 1.0
+ if(pHeader->dwHeaderSize == MPQ_HEADER_SIZE_V1)
+ {
+ // Calculate claimed block table begin and end
+ BlockTableStart = ha->MpqPos + MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
+ BlockTableEnd = BlockTableStart + (pHeader->dwBlockTableSize * sizeof(TMPQBlock));
+
+ for(DWORD i = 0; i < dwClaimedSize; i++)
+ {
+ // If the block table end goes into that file, fix the block table end
+ FileDataStart = ha->MpqPos + pBlockTable[i].dwFilePos;
+ if(BlockTableStart < FileDataStart && BlockTableEnd > FileDataStart)
+ {
+ dwClaimedSize = (DWORD)((FileDataStart - BlockTableStart) / sizeof(TMPQBlock));
+ BlockTableEnd = FileDataStart;
+ }
+ }
+ }
+
+ // Fix the block table size
+ pHeader->BlockTableSize64 = dwClaimedSize * sizeof(TMPQBlock);
+ pHeader->dwBlockTableSize = dwClaimedSize;
+}
+
+TMPQBlock * LoadBlockTable(TMPQArchive * ha, ULONGLONG FileSize)
+{
+ TMPQHeader * pHeader = ha->pHeader;
+ TMPQBlock * pBlockTable;
+ ULONGLONG ByteOffset;
+ DWORD dwTableSize;
+ DWORD dwCmpSize;
+ int nError;
+
+ // Do nothing if the block table position is zero
+ if(pHeader->dwBlockTablePos == 0 && pHeader->wBlockTablePosHi == 0)
+ return NULL;
+
+ // Do nothing if the block table size is zero
+ if(pHeader->dwBlockTableSize == 0)
+ return NULL;
+
+ // Sanity check, enforced by LoadAnyHashTable
+ assert(ha->dwMaxFileCount >= pHeader->dwBlockTableSize);
+
+ // Calculate sizes of both tables
+ ByteOffset = ha->MpqPos + MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
+ dwTableSize = pHeader->dwBlockTableSize * sizeof(TMPQBlock);
+ dwCmpSize = (DWORD)pHeader->BlockTableSize64;
+
+ // Allocate space for the block table
+ // Note: pHeader->dwBlockTableSize can be zero !!!
+ pBlockTable = STORM_ALLOC(TMPQBlock, ha->dwMaxFileCount);
+ if(pBlockTable == NULL)
+ return NULL;
+
+ // Fill the block table with zeros
+ memset(pBlockTable, 0, dwTableSize);
+
+ // I found a MPQ which claimed 0x200 entries in the block table,
+ // but the file was cut and there was only 0x1A0 entries.
+ // We will handle this case properly.
+ if(dwTableSize == dwCmpSize && (ByteOffset + dwTableSize) > FileSize)
+ {
+ pHeader->dwBlockTableSize = (DWORD)((FileSize - ByteOffset) / sizeof(TMPQBlock));
+ pHeader->BlockTableSize64 = pHeader->dwBlockTableSize * sizeof(TMPQBlock);
+ dwTableSize = dwCmpSize = pHeader->dwBlockTableSize * sizeof(TMPQBlock);
+ }
+
+ //
+ // One of the first cracked versions of Diablo I had block table unencrypted
+ // StormLib does NOT support such MPQs anymore, as they are incompatible
+ // with compressed block table feature
+ //
+
+ // Load the block table
+ nError = LoadMpqTable(ha, ByteOffset, pBlockTable, dwCmpSize, dwTableSize, MPQ_KEY_BLOCK_TABLE);
+ if(nError != ERROR_SUCCESS)
+ {
+ // Failed, sorry
+ STORM_FREE(pBlockTable);
+ return NULL;
+ }
+
+ // Defense against MPQs that claim block table to be bigger than it really is
+ FixBlockTableSize(ha, pBlockTable, pHeader->dwBlockTableSize);
+ return pBlockTable;
+}
+
+int LoadHetTable(TMPQArchive * ha)
+{
+ TMPQExtTable * pExtTable;
+ TMPQHeader * pHeader = ha->pHeader;
+ int nError = ERROR_SUCCESS;
+
+ // If the HET table position is not NULL, we expect
+ // both HET and BET tables to be present.
+ if(pHeader->HetTablePos64 != 0)
+ {
+ // 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 succeeded, we have to limit the maximum file count
+ // to the values saved in the HET table
+ // If loading HET table fails, we ignore the result.
+ ha->pHetTable = TranslateHetTable(pExtTable);
+ if(ha->pHetTable != NULL)
+ ha->dwMaxFileCount = ha->pHetTable->dwMaxFileCount;
+
+ STORM_FREE(pExtTable);
+ }
+
+ // If the HET hable failed to load, it's corrupt.
+ if(ha->pHetTable == NULL)
+ nError = ERROR_FILE_CORRUPT;
+ }
+
+ return nError;
+}
+
+TMPQBetTable * LoadBetTable(TMPQArchive * ha)
+{
+ TMPQExtTable * pExtTable;
+ TMPQBetTable * pBetTable = NULL;
+ TMPQHeader * pHeader = ha->pHeader;
+
+ // If the HET table position is not NULL, we expect
+ // both HET and BET tables to be present.
+ if(pHeader->BetTablePos64 != 0)
+ {
+ // 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, pExtTable);
+ STORM_FREE(pExtTable);
+ }
+ }
+
+ return pBetTable;
+}
+
+int 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 and/or classic hash table
+ LoadHetTable(ha);
+
+ // Load the HASH table
+ ha->pHashTable = LoadHashTable(ha);
+
+ // Set the maximum file count to the size of the hash table
+ // In case there is HET table, we have to keep the file limit
+ if(ha->pHetTable == NULL)
+ ha->dwMaxFileCount = pHeader->dwHashTableSize;
+
+ // Did at least one succeed?
+ if(ha->pHetTable == NULL && ha->pHashTable == NULL)
+ return ERROR_FILE_CORRUPT;
+
+ // In theory, a MPQ could have bigger block table than hash table
+ if(ha->pHeader->dwBlockTableSize > ha->dwMaxFileCount)
+ {
+ ha->dwMaxFileCount = ha->pHeader->dwBlockTableSize;
+ ha->dwFlags |= MPQ_FLAG_READ_ONLY;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+int BuildFileTable_Classic(
+ TMPQArchive * ha,
+ TFileEntry * pFileTable,
+ ULONGLONG FileSize)
+{
+ TFileEntry * pFileEntry;
+ TMPQHeader * pHeader = ha->pHeader;
+ TMPQBlock * pBlockTable;
+ TMPQBlock * pBlock;
+ int nError = ERROR_SUCCESS;
+
+ // Sanity checks
+ assert(ha->pHashTable != NULL);
+
+ // Load the block table
+ pBlockTable = LoadBlockTable(ha, FileSize);
+ if(pBlockTable != NULL)
+ {
+ TMPQHash * pHashEnd = ha->pHashTable + pHeader->dwHashTableSize;
+ TMPQHash * pHash;
+
+ // If we don't have HET table, we build the file entries from the hash&block tables
+ if(ha->pHetTable == NULL)
+ {
+ for(pHash = ha->pHashTable; pHash < pHashEnd; pHash++)
+ {
+ if(pHash->dwBlockIndex < pHeader->dwBlockTableSize)
+ {
+ pFileEntry = pFileTable + pHash->dwBlockIndex;
+ pBlock = pBlockTable + pHash->dwBlockIndex;
+
+ //
+ // Yet another silly map protector: For each valid file,
+ // there are 4 items in the hash table, that appears to be valid:
+ //
+ // a6d79af0 e61a0932 001e0000 0000770b <== Fake valid
+ // a6d79af0 e61a0932 0000d761 0000dacb <== Fake valid
+ // a6d79af0 e61a0932 00000000 0000002f <== Real file entry
+ // a6d79af0 e61a0932 00005a4f 000093bc <== Fake valid
+ //
+
+ if(!(pBlock->dwFlags & ~MPQ_FILE_VALID_FLAGS) && (pBlock->dwFlags & MPQ_FILE_EXISTS))
+ {
+ // Fill the entry
+ pFileEntry->ByteOffset = pBlock->dwFilePos;
+ pFileEntry->dwHashIndex = (DWORD)(pHash - ha->pHashTable);
+ pFileEntry->dwFileSize = pBlock->dwFSize;
+ pFileEntry->dwCmpSize = pBlock->dwCSize;
+ pFileEntry->dwFlags = pBlock->dwFlags;
+ pFileEntry->lcLocale = pHash->lcLocale;
+ pFileEntry->wPlatform = pHash->wPlatform;
+ }
+ else
+ {
+ // If the hash table entry doesn't point to the valid file item,
+ // we invalidate the entire hash table entry
+ pHash->dwName1 = 0xFFFFFFFF;
+ pHash->dwName2 = 0xFFFFFFFF;
+ pHash->lcLocale = 0xFFFF;
+ pHash->wPlatform = 0xFFFF;
+ pHash->dwBlockIndex = HASH_ENTRY_DELETED;
+ }
+ }
+ }
+ }
+ else
+ {
+ for(pHash = ha->pHashTable; pHash < pHashEnd; pHash++)
+ {
+ if(pHash->dwBlockIndex < ha->dwFileTableSize)
+ {
+ pFileEntry = pFileTable + pHash->dwBlockIndex;
+ if(pFileEntry->dwFlags & MPQ_FILE_EXISTS)
+ {
+ pFileEntry->dwHashIndex = (DWORD)(pHash - ha->pHashTable);
+ pFileEntry->lcLocale = pHash->lcLocale;
+ pFileEntry->wPlatform = pHash->wPlatform;
+ }
+ }
+ }
+ }
+
+ // Free the block table
+ STORM_FREE(pBlockTable);
+ }
+ else
+ {
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Load the hi-block table
+ if(nError == 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))
+ nError = GetLastError();
+
+ // Now merge the hi-block table to the file table
+ if(nError == ERROR_SUCCESS)
+ {
+ pFileEntry = pFileTable;
+
+ // Add the high file offset to the base file offset.
+ // We also need to swap it during the process.
+ for(DWORD i = 0; i < pHeader->dwBlockTableSize; i++)
+ {
+ pFileEntry->ByteOffset |= ((ULONGLONG)BSWAP_INT16_UNSIGNED(pHiBlockTable[i]) << 32);
+ pFileEntry++;
+ }
+ }
+
+ // Free the hi-block table
+ STORM_FREE(pHiBlockTable);
+ }
+ else
+ {
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+ }
+
+ // Set the current size of the file table
+ ha->dwFileTableSize = pHeader->dwBlockTableSize;
+ return nError;
+}
+
+int BuildFileTable_HetBet(
+ TMPQArchive * ha,
+ TFileEntry * pFileTable)
+{
+ TMPQHetTable * pHetTable = ha->pHetTable;
+ TMPQBetTable * pBetTable;
+ TFileEntry * pFileEntry = pFileTable;
+ TBitArray * pBitArray;
+ DWORD dwBitPosition = 0;
+ DWORD i;
+ int nError = ERROR_FILE_CORRUPT;
+
+ // Load the BET table from the MPQ
+ pBetTable = LoadBetTable(ha);
+ if(pBetTable != NULL)
+ {
+ // Step one: Fill the indexes to the HET table
+ for(i = 0; i < pHetTable->dwHashTableSize; i++)
+ {
+ DWORD dwFileIndex = 0;
+
+ // Is the entry in the HET table occupied?
+ if(pHetTable->pHetHashes[i] != 0)
+ {
+ // Load the index to the BET table
+ GetBits(pHetTable->pBetIndexes, pHetTable->dwIndexSizeTotal * i,
+ pHetTable->dwIndexSize,
+ &dwFileIndex,
+ 4);
+ // Overflow test
+ if(dwFileIndex < pBetTable->dwFileCount)
+ {
+ // Get the file entry and save HET index
+ pFileEntry = pFileTable + dwFileIndex;
+ pFileEntry->dwHetIndex = i;
+
+ // Load the BET hash
+ GetBits(pBetTable->pBetHashes, pBetTable->dwBetHashSizeTotal * dwFileIndex,
+ pBetTable->dwBetHashSize,
+ &pFileEntry->BetHash,
+ 8);
+ }
+ }
+ }
+
+ // Go through the entire BET table and convert it to the file table.
+ pFileEntry = pFileTable;
+ pBitArray = pBetTable->pFileTable;
+ for(i = 0; i < pBetTable->dwFileCount; i++)
+ {
+ DWORD dwFlagIndex = 0;
+
+ // Read the file position
+ GetBits(pBitArray, dwBitPosition + pBetTable->dwBitIndex_FilePos,
+ pBetTable->dwBitCount_FilePos,
+ &pFileEntry->ByteOffset,
+ 8);
+
+ // Read the file size
+ GetBits(pBitArray, dwBitPosition + pBetTable->dwBitIndex_FileSize,
+ pBetTable->dwBitCount_FileSize,
+ &pFileEntry->dwFileSize,
+ 4);
+
+ // Read the compressed size
+ GetBits(pBitArray, dwBitPosition + pBetTable->dwBitIndex_CmpSize,
+ pBetTable->dwBitCount_CmpSize,
+ &pFileEntry->dwCmpSize,
+ 4);
+
+
+ // Read the flag index
+ if(pBetTable->dwFlagCount != 0)
+ {
+ GetBits(pBitArray, 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
+ ha->dwFileTableSize = pBetTable->dwFileCount;
+ FreeBetTable(pBetTable);
+ nError = ERROR_SUCCESS;
+ }
+ else
+ {
+ nError = ERROR_FILE_CORRUPT;
+ }
+
+ return nError;
+}
+
+int BuildFileTable(TMPQArchive * ha, ULONGLONG FileSize)
+{
+ TFileEntry * pFileTable;
+ bool bFileTableCreated = false;
+
+ // Sanity checks
+ assert(ha->dwFileTableSize == 0);
+ assert(ha->dwMaxFileCount != 0);
+
+ // Allocate the file table with size determined before
+ pFileTable = STORM_ALLOC(TFileEntry, ha->dwMaxFileCount);
+ if(pFileTable == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ // Fill the table with zeros
+ memset(pFileTable, 0, ha->dwMaxFileCount * sizeof(TFileEntry));
+
+ // 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, pFileTable) != 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, pFileTable, FileSize) != ERROR_SUCCESS)
+ ha->dwFlags |= MPQ_FLAG_READ_ONLY;
+ else
+ bFileTableCreated = true;
+ }
+
+ // If something failed, we free the file table entry
+ if(bFileTableCreated == false)
+ {
+ STORM_FREE(pFileTable);
+ return ERROR_FILE_CORRUPT;
+ }
+
+ // Assign it to the archive structure
+ ha->pFileTable = pFileTable;
+ return ERROR_SUCCESS;
+}
+
+// Saves MPQ header, hash table, block table and hi-block table.
+int SaveMPQTables(TMPQArchive * ha)
+{
+ TMPQExtTable * pHetTable = NULL;
+ TMPQExtTable * 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;
+ int nError = 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
+ FindFreeMpqSpace(ha, &TablePos);
+
+ // If the MPQ has HET table, we prepare a ready-to-save version
+ if(nError == ERROR_SUCCESS && ha->pHetTable != NULL)
+ {
+ pHetTable = TranslateHetTable(ha->pHetTable, &HetTableSize64);
+ if(pHetTable == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // If the MPQ has HET table, we also must create BET table to be saved
+ if(nError == ERROR_SUCCESS && ha->pHetTable != NULL)
+ {
+ pBetTable = TranslateBetTable(ha, &BetTableSize64);
+ if(pBetTable == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Now create hash table
+ if(nError == ERROR_SUCCESS && ha->pHashTable != NULL)
+ {
+ pHashTable = TranslateHashTable(ha, &HashTableSize64);
+ if(pHashTable == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Create block table
+ if(nError == ERROR_SUCCESS && ha->pHashTable != NULL)
+ {
+ pBlockTable = TranslateBlockTable(ha, &BlockTableSize64, &bNeedHiBlockTable);
+ if(pBlockTable == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Create hi-block table, if needed
+ if(nError == ERROR_SUCCESS && bNeedHiBlockTable)
+ {
+ pHiBlockTable = TranslateHiBlockTable(ha, &HiBlockTableSize64);
+ if(pHiBlockTable == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Write the HET table, if any
+ if(nError == ERROR_SUCCESS && pHetTable != NULL)
+ {
+ pHeader->HetTableSize64 = HetTableSize64;
+ pHeader->HetTablePos64 = TablePos;
+ nError = SaveExtTable(ha, pHetTable, TablePos, (DWORD)HetTableSize64, pHeader->MD5_HetTable, MPQ_KEY_HASH_TABLE, false, &cbTotalSize);
+ TablePos += cbTotalSize;
+ }
+
+ // Write the BET table, if any
+ if(nError == ERROR_SUCCESS && pBetTable != NULL)
+ {
+ pHeader->BetTableSize64 = BetTableSize64;
+ pHeader->BetTablePos64 = TablePos;
+ nError = 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(nError == ERROR_SUCCESS && pHashTable != NULL)
+ {
+ pHeader->HashTableSize64 = HashTableSize64;
+ pHeader->wHashTablePosHi = (USHORT)(TablePos >> 32);
+ pHeader->dwHashTableSize = (DWORD)(HashTableSize64 / sizeof(TMPQHash));
+ pHeader->dwHashTablePos = (DWORD)TablePos;
+ nError = 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(nError == ERROR_SUCCESS && pBlockTable != NULL)
+ {
+ pHeader->BlockTableSize64 = BlockTableSize64;
+ pHeader->wBlockTablePosHi = (USHORT)(TablePos >> 32);
+ pHeader->dwBlockTableSize = (DWORD)(BlockTableSize64 / sizeof(TMPQBlock));
+ pHeader->dwBlockTablePos = (DWORD)TablePos;
+ nError = 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(nError == 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))
+ nError = GetLastError();
+ TablePos += HiBlockTableSize64;
+ }
+
+ // Cut the MPQ
+ if(nError == ERROR_SUCCESS)
+ {
+ ULONGLONG FileSize = ha->MpqPos + TablePos;
+
+ if(!FileStream_SetSize(ha->pStream, FileSize))
+ nError = GetLastError();
+ }
+
+ // Write the MPQ header
+ if(nError == ERROR_SUCCESS)
+ {
+ // 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
+ BSWAP_TMPQHEADER(pHeader);
+ if(!FileStream_Write(ha->pStream, &ha->MpqPos, pHeader, pHeader->dwHeaderSize))
+ nError = GetLastError();
+ BSWAP_TMPQHEADER(pHeader);
+ }
+
+ // Clear the changed flag
+ if(nError == 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 nError;
+}
diff --git a/src/SCompression.cpp b/src/SCompression.cpp
new file mode 100644
index 0000000..e3b99e0
--- /dev/null
+++ b/src/SCompression.cpp
@@ -0,0 +1,1065 @@
+/*****************************************************************************/
+/* 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)) == 0)
+ {
+ // Call zlib to decompress the data
+ nResult = inflate(&z, Z_FINISH);
+ *pcbOutBuffer = z.total_out;
+ inflateEnd(&z);
+ }
+ return nResult;
+}
+
+/******************************************************************************/
+/* */
+/* 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);
+
+ // 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 ues fixed dictionary size of CMP_IMPLODE_DICT_SIZE3
+ // Starcraft 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 = STORM_ALLOC(char, EXP_BUFFER_SIZE);// Pklib's work buffer
+
+ // 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
+ explode(ReadInputData, WriteOutputData, work_buf, &Info);
+
+ // If PKLIB is unable to decompress the data, return 0;
+ if(Info.pbOutBuff == pvOutBuffer)
+ return 0;
+
+ // Give away the number of decompressed bytes
+ *pcbOutBuffer = (int)(Info.pbOutBuff - (unsigned char *)pvOutBuffer);
+ STORM_FREE(work_buf);
+ return 1;
+}
+
+/******************************************************************************/
+/* */
+/* 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;
+
+ // 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 = BZ_OK;
+
+ // Initialize the BZIP2 decompression
+ strm.bzalloc = NULL;
+ strm.bzfree = NULL;
+ if(BZ2_bzDecompressInit(&strm, 0, 0) == BZ_OK)
+ {
+ strm.next_in = (char *)pvInBuffer;
+ strm.avail_in = cbInBuffer;
+ strm.next_out = (char *)pvOutBuffer;
+ strm.avail_out = *pcbOutBuffer;
+
+ // Perform the decompression
+ while(nResult != BZ_STREAM_END)
+ {
+ nResult = BZ2_bzDecompress(&strm);
+
+ // If any error there, break the loop
+ if(nResult < BZ_OK)
+ break;
+ }
+
+ // Put the stream into idle state
+ BZ2_bzDecompressEnd(&strm);
+
+ // If all succeeded, set the number of output bytes
+ if(nResult >= BZ_OK)
+ {
+ *pcbOutBuffer = strm.total_out_lo32;
+ return 1;
+ }
+ }
+
+ // Something failed, so set number of output bytes to zero
+ *pcbOutBuffer = 0;
+ return 1;
+}
+
+/******************************************************************************/
+/* */
+/* 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;
+}
+
+/******************************************************************************/
+/* */
+/* 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 = *pcbOutBuffer;
+
+ // Check for valid parameters
+ if(!pcbOutBuffer || *pcbOutBuffer < cbInBuffer || !pvOutBuffer || !pvInBuffer)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ // Perform the compression
+ 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 = *pcbOutBuffer;
+
+ // 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.
+ 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 false;
+ }
+
+ *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.
+ //
+
+ 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, pvInBuffer, 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;
+}
diff --git a/src/SFileAddFile.cpp b/src/SFileAddFile.cpp
new file mode 100644
index 0000000..3441b26
--- /dev/null
+++ b/src/SFileAddFile.cpp
@@ -0,0 +1,1277 @@
+/*****************************************************************************/
+/* SFileAddFile.cpp Copyright (c) Ladislav Zezula 2010 */
+/*---------------------------------------------------------------------------*/
+/* MPQ Editing functions */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 27.03.10 1.00 Lad Splitted from SFileCreateArchiveEx.cpp */
+/*****************************************************************************/
+
+#define __STORMLIB_SELF__
+#include "StormLib.h"
+#include "StormCommon.h"
+
+//-----------------------------------------------------------------------------
+// Local structures
+
+#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;
+
+//-----------------------------------------------------------------------------
+// Local variables
+
+// Data compression for SFileAddFile
+// Kept here for compatibility with code that was created with StormLib version < 6.50
+static DWORD DefaultDataCompression = MPQ_COMPRESSION_PKWARE;
+
+static SFILE_ADDFILE_CALLBACK AddFileCB = NULL;
+static void * pvUserData = NULL;
+
+//-----------------------------------------------------------------------------
+// MPQ write data functions
+
+#define LOSSY_COMPRESSION_MASK (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN)
+
+static int IsWaveFile(
+ LPBYTE pbFileData,
+ DWORD cbFileData,
+ LPDWORD pdwChannels)
+{
+ PWAVE_FILE_HEADER pWaveHdr = (PWAVE_FILE_HEADER)pbFileData;
+
+ if(cbFileData > sizeof(WAVE_FILE_HEADER))
+ {
+ if(pWaveHdr->dwChunkId == FILE_SIGNATURE_RIFF && pWaveHdr->dwFormat == FILE_SIGNATURE_WAVE)
+ {
+ if(pWaveHdr->dwSubChunk1Id == FILE_SIGNATURE_FMT && pWaveHdr->wAudioFormat == AUDIO_FORMAT_PCM)
+ {
+ *pdwChannels = pWaveHdr->wChannels;
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+
+static int 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 = NULL; // Data to write to the file
+ int nCompressionLevel = -1; // ADPCM compression level (only used for wave files)
+ int nError = ERROR_SUCCESS;
+
+ // If the caller wants ADPCM compression, we will set wave compression level to 4,
+ // which corresponds to medium quality
+ if(dwCompression & LOSSY_COMPRESSION_MASK)
+ nCompressionLevel = 4;
+
+ // 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;
+ pbToWrite = hf->pbFileSector;
+
+ // Now write all data to the file sector buffer
+ if(nError == 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_COMPRESSED)
+ {
+ 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)
+ {
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ break;
+ }
+ }
+
+ //
+ // Note that both SCompImplode and SCompCompress give original buffer,
+ // if they are unable to comperss the data.
+ //
+
+ if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE)
+ {
+ SCompImplode(pbCompressed, &nOutBuffer, hf->pbFileSector, nInBuffer);
+ }
+
+ if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS)
+ {
+ 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))
+ {
+ nError = GetLastError();
+ break;
+ }
+
+ // Call the compact callback, if any
+ if(AddFileCB != NULL)
+ AddFileCB(pvUserData, hf->dwFilePos, hf->dwDataSize, false);
+
+ // Update the compressed file size
+ pFileEntry->dwCmpSize += dwBytesInSector;
+ dwBytesInSector = 0;
+ dwSectorIndex++;
+ }
+ }
+ }
+
+ // Cleanup
+ if(pbCompressed != NULL)
+ STORM_FREE(pbCompressed);
+ return nError;
+}
+
+//-----------------------------------------------------------------------------
+// Recrypts file data for file renaming
+
+static int 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;
+ int nError = ERROR_SUCCESS;
+
+ // The file must be encrypted
+ assert(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED);
+
+ // File decryption key is calculated from the plain name
+ szNewFileName = GetPlainFileNameA(szNewFileName);
+ szFileName = GetPlainFileNameA(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
+ nError = AllocateSectorBuffer(hf);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ // Also allocate buffer for sector offsets
+ // Note: Don't load sector checksums, we don't need to recrypt them
+ nError = AllocateSectorOffsets(hf, true);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ // If we have sector offsets, recrypt these as well
+ if(hf->SectorOffsets != NULL)
+ {
+ // Allocate secondary buffer for sectors copy
+ DWORD * SectorOffsetsCopy = (DWORD *)STORM_ALLOC(BYTE, hf->SectorOffsets[0]);
+ 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))
+ nError = 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(nError == 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
+ CalculateRawSectorOffset(RawFilePos, hf, dwRawByteOffset);
+
+ // Read the file sector
+ if(!FileStream_Read(ha->pStream, &RawFilePos, hf->pbFileSector, dwRawDataInSector))
+ {
+ nError = 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))
+ {
+ nError = GetLastError();
+ break;
+ }
+
+ // Decrement number of bytes remaining
+ dwBytesToRecrypt -= hf->dwSectorSize;
+ }
+ }
+
+ return nError;
+}
+
+//-----------------------------------------------------------------------------
+// Support functions for adding files to the MPQ
+
+int SFileAddFile_Init(
+ TMPQArchive * ha,
+ const char * szFileName,
+ ULONGLONG FileTime,
+ DWORD dwFileSize,
+ LCID lcLocale,
+ DWORD dwFlags,
+ TMPQFile ** phf)
+{
+ TFileEntry * pFileEntry = NULL;
+ ULONGLONG TempPos; // For various file offset calculations
+ TMPQFile * hf = NULL; // File structure for newly added file
+ int nError = 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_COMPRESSED))
+ 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 = CreateMpqFile(ha);
+ if(hf == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+
+ // Find a free space in the MPQ, as well as free block table entry
+ if(nError == ERROR_SUCCESS)
+ {
+ // Find the position where the file will be stored
+ FindFreeMpqSpace(ha, &hf->MpqFilePos);
+ hf->RawFilePos = ha->MpqPos + hf->MpqFilePos;
+ hf->bIsWriteHandle = true;
+
+ // Sanity check: The MPQ must be marked as changed at this point
+ assert((ha->dwFlags & MPQ_FLAG_CHANGED) != 0);
+
+ // When format V1, the size of the archive cannot exceed 4 GB
+ if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
+ {
+ TempPos = hf->MpqFilePos + dwFileSize;
+ TempPos += ha->pHeader->dwHashTableSize * sizeof(TMPQHash);
+ TempPos += ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock);
+ TempPos += ha->pHeader->dwBlockTableSize * sizeof(USHORT);
+ if((TempPos >> 32) != 0)
+ nError = ERROR_DISK_FULL;
+ }
+ }
+
+ // Allocate file entry in the MPQ
+ if(nError == ERROR_SUCCESS)
+ {
+ // Check if the file already exists in the archive
+ pFileEntry = GetFileEntryExact(ha, szFileName, lcLocale);
+ if(pFileEntry == NULL)
+ {
+ pFileEntry = AllocateFileEntry(ha, szFileName, lcLocale);
+ if(pFileEntry == NULL)
+ nError = ERROR_DISK_FULL;
+ }
+ else
+ {
+ // If the file exists and "replace existing" is not set, fail it
+ if((dwFlags & MPQ_FILE_REPLACEEXISTING) == 0)
+ nError = ERROR_ALREADY_EXISTS;
+
+ // If the file entry already contains a file
+ // and it is a pseudo-name, replace it
+ if(nError == ERROR_SUCCESS)
+ {
+ AllocateFileName(pFileEntry, szFileName);
+ }
+ }
+ }
+
+ //
+ // At this point, the file name in file entry must be non-NULL
+ //
+
+ // Create key for file encryption
+ if(nError == ERROR_SUCCESS && (dwFlags & MPQ_FILE_ENCRYPTED))
+ {
+ hf->dwFileKey = DecryptFileKey(szFileName, hf->MpqFilePos, dwFileSize, dwFlags);
+ }
+
+ if(nError == ERROR_SUCCESS)
+ {
+ // Initialize the hash entry for the file
+ hf->pFileEntry = pFileEntry;
+ 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;
+ pFileEntry->lcLocale = (USHORT)lcLocale;
+
+ // 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;
+
+ // Call the callback, if needed
+ if(AddFileCB != NULL)
+ AddFileCB(pvUserData, 0, hf->dwDataSize, false);
+ }
+
+ // If an error occured, remember it
+ if(nError != ERROR_SUCCESS)
+ hf->bErrorOccured = true;
+ *phf = hf;
+ return nError;
+}
+
+int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD dwCompression)
+{
+ TMPQArchive * ha;
+ TFileEntry * pFileEntry;
+ int nError = 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
+ nError = AllocateSectorBuffer(hf);
+ if(nError != ERROR_SUCCESS)
+ {
+ hf->bErrorOccured = true;
+ return nError;
+ }
+
+ // Allocate patch info, if the data is patch
+ if(hf->pPatchInfo == NULL && IsIncrementalPatchFile(pvData, dwSize, &hf->dwPatchedFileSize))
+ {
+ // Set the MPQ_FILE_PATCH_FILE flag
+ hf->pFileEntry->dwFlags |= MPQ_FILE_PATCH_FILE;
+
+ // Allocate the patch info
+ nError = AllocatePatchInfo(hf, false);
+ if(nError != ERROR_SUCCESS)
+ {
+ hf->bErrorOccured = true;
+ return nError;
+ }
+ }
+
+ // Allocate sector offsets
+ if(hf->SectorOffsets == NULL)
+ {
+ nError = AllocateSectorOffsets(hf, false);
+ if(nError != ERROR_SUCCESS)
+ {
+ hf->bErrorOccured = true;
+ return nError;
+ }
+ }
+
+ // Create array of sector checksums
+ if(hf->SectorChksums == NULL && (pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC))
+ {
+ nError = AllocateSectorChecksums(hf, false);
+ if(nError != ERROR_SUCCESS)
+ {
+ hf->bErrorOccured = true;
+ return nError;
+ }
+ }
+
+ // Pre-save the patch info, if any
+ if(hf->pPatchInfo != NULL)
+ {
+ if(!FileStream_Write(ha->pStream, &RawFilePos, hf->pPatchInfo, hf->pPatchInfo->dwLength))
+ nError = 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]))
+ nError = GetLastError();
+
+ pFileEntry->dwCmpSize += hf->SectorOffsets[0];
+ RawFilePos += hf->SectorOffsets[0];
+ }
+ }
+
+ // Write the MPQ data to the file
+ if(nError == ERROR_SUCCESS)
+ nError = 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(nError == ERROR_SUCCESS)
+ {
+ if(hf->dwFilePos >= pFileEntry->dwFileSize)
+ {
+ // Finish calculating CRC32
+ hf->pFileEntry->dwCrc32 = hf->dwCrc32;
+
+ // Finish calculating MD5
+ md5_done((hash_state *)hf->hctx, hf->pFileEntry->md5);
+
+ // If we also have sector checksums, write them to the file
+ if(hf->SectorChksums != NULL)
+ {
+ nError = WriteSectorChecksums(hf);
+ if(nError != ERROR_SUCCESS)
+ hf->bErrorOccured = true;
+ }
+
+ // Now write patch info
+ if(hf->pPatchInfo != NULL)
+ {
+ memcpy(hf->pPatchInfo->md5, hf->pFileEntry->md5, MD5_DIGEST_SIZE);
+ hf->pPatchInfo->dwDataSize = hf->pFileEntry->dwFileSize;
+ hf->pFileEntry->dwFileSize = hf->dwPatchedFileSize;
+ nError = WritePatchInfo(hf);
+ if(nError != ERROR_SUCCESS)
+ hf->bErrorOccured = true;
+ }
+
+ // Now write sector offsets to the file
+ if(hf->SectorOffsets != NULL)
+ {
+ nError = WriteSectorOffsets(hf);
+ if(nError != ERROR_SUCCESS)
+ hf->bErrorOccured = true;
+ }
+
+ // Write the MD5 hashes of each file chunk, if required
+ if(ha->pHeader->dwRawChunkSize != 0)
+ {
+ nError = WriteMpqDataMD5(ha->pStream,
+ ha->MpqPos + hf->pFileEntry->ByteOffset,
+ hf->pFileEntry->dwCmpSize,
+ ha->pHeader->dwRawChunkSize);
+ if(nError != ERROR_SUCCESS)
+ hf->bErrorOccured = true;
+ }
+ }
+ }
+ else
+ {
+ hf->bErrorOccured = true;
+ }
+
+ return nError;
+}
+
+int SFileAddFile_Finish(TMPQFile * hf)
+{
+ TMPQArchive * ha = hf->ha;
+ TFileEntry * pFileEntry = hf->pFileEntry;
+ int nError = ERROR_SUCCESS;
+
+ // If all previous operations succeeded, we can update the MPQ
+ if(!hf->bErrorOccured)
+ {
+ // Verify if the caller wrote the file properly
+ if(hf->pPatchInfo == NULL)
+ {
+ assert(pFileEntry != NULL);
+ if(hf->dwFilePos != pFileEntry->dwFileSize)
+ {
+ nError = ERROR_CAN_NOT_COMPLETE;
+ hf->bErrorOccured = true;
+ }
+ }
+ else
+ {
+ if(hf->dwFilePos != hf->pPatchInfo->dwDataSize)
+ {
+ nError = ERROR_CAN_NOT_COMPLETE;
+ hf->bErrorOccured = true;
+ }
+ }
+ }
+
+ if(!hf->bErrorOccured)
+ {
+ // Call the user callback, if any
+ if(AddFileCB != NULL)
+ AddFileCB(pvUserData, hf->dwDataSize, hf->dwDataSize, true);
+
+ // Update the size of the block table
+ ha->pHeader->dwBlockTableSize = ha->dwFileTableSize;
+ }
+ else
+ {
+ // Free the file entry in MPQ tables
+ if(pFileEntry != NULL)
+ FreeFileEntry(ha, pFileEntry);
+ }
+
+ // Clear the add file callback
+ FreeMPQFile(hf);
+ pvUserData = NULL;
+ AddFileCB = NULL;
+ return nError;
+}
+
+//-----------------------------------------------------------------------------
+// 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;
+ int nError = ERROR_SUCCESS;
+
+ // Check valid parameters
+ if(!IsValidMpqHandle(ha))
+ nError = ERROR_INVALID_HANDLE;
+ if(szArchivedName == NULL || *szArchivedName == 0)
+ nError = ERROR_INVALID_PARAMETER;
+ if(phFile == NULL)
+ nError = ERROR_INVALID_PARAMETER;
+
+ // Don't allow to add file if the MPQ is open for read only
+ if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
+ nError = ERROR_ACCESS_DENIED;
+
+ // Don't allow to add a file under pseudo-file name
+ if(IsPseudoFileName(szArchivedName, NULL))
+ nError = ERROR_INVALID_PARAMETER;
+
+ // Don't allow to add any of the internal files
+ if(IsInternalMpqFileName(szArchivedName))
+ nError = ERROR_INTERNAL_FILE;
+
+ // Perform validity check of the MPQ flags
+ if(nError == ERROR_SUCCESS)
+ {
+ // Mask all unsupported flags out
+ dwFlags &= MPQ_FILE_VALID_FLAGS;
+
+ // Check for valid flag combinations
+ if((dwFlags & (MPQ_FILE_IMPLODE | MPQ_FILE_COMPRESS)) == (MPQ_FILE_IMPLODE | MPQ_FILE_COMPRESS))
+ nError = ERROR_INVALID_PARAMETER;
+ }
+
+ // Create the file in MPQ
+ if(nError == ERROR_SUCCESS)
+ {
+ // Invalidate the entries for (listfile) and (attributes)
+ // After we are done with MPQ changes, we need to re-create them anyway
+ InvalidateInternalFiles(ha);
+
+ // Initiate the add file operation
+ nError = SFileAddFile_Init(ha, szArchivedName, FileTime, dwFileSize, lcLocale, dwFlags, (TMPQFile **)phFile);
+ }
+
+ // Deal with the errors
+ if(nError != ERROR_SUCCESS)
+ SetLastError(nError);
+ return (nError == ERROR_SUCCESS);
+}
+
+bool WINAPI SFileWriteFile(
+ HANDLE hFile,
+ const void * pvData,
+ DWORD dwSize,
+ DWORD dwCompression)
+{
+ TMPQFile * hf = (TMPQFile *)hFile;
+ int nError = ERROR_SUCCESS;
+
+ // Check the proper parameters
+ if(!IsValidFileHandle(hf))
+ nError = ERROR_INVALID_HANDLE;
+ if(hf->bIsWriteHandle == false)
+ nError = ERROR_INVALID_HANDLE;
+
+ // Special checks for single unit files
+ if(nError == 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)
+// nError = ERROR_INVALID_PARAMETER;
+//
+// if(dwFlags & MPQ_FILE_ENCRYPTED)
+// nError = ERROR_INVALID_PARAMETER;
+
+ // Lossy compression is not allowed on single unit files
+ if(dwCompression & LOSSY_COMPRESSION_MASK)
+ nError = ERROR_INVALID_PARAMETER;
+ }
+
+
+ // Write the data to the file
+ if(nError == ERROR_SUCCESS)
+ nError = SFileAddFile_Write(hf, pvData, dwSize, dwCompression);
+
+ // Deal with errors
+ if(nError != ERROR_SUCCESS)
+ SetLastError(nError);
+ return (nError == ERROR_SUCCESS);
+}
+
+bool WINAPI SFileFinishFile(HANDLE hFile)
+{
+ TMPQFile * hf = (TMPQFile *)hFile;
+ int nError = ERROR_SUCCESS;
+
+ // Check the proper parameters
+ if(!IsValidFileHandle(hf))
+ nError = ERROR_INVALID_HANDLE;
+ if(hf->bIsWriteHandle == false)
+ nError = ERROR_INVALID_HANDLE;
+
+ // Finish the file
+ if(nError == ERROR_SUCCESS)
+ nError = SFileAddFile_Finish(hf);
+
+ // Deal with errors
+ if(nError != ERROR_SUCCESS)
+ SetLastError(nError);
+ return (nError == 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;
+ int nError = ERROR_SUCCESS;
+
+ // Check parameters
+ if(szFileName == NULL || *szFileName == 0)
+ nError = ERROR_INVALID_PARAMETER;
+
+ // Open added file
+ if(nError == ERROR_SUCCESS)
+ {
+ pStream = FileStream_OpenFile(szFileName, STREAM_FLAG_READ_ONLY | STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
+ if(pStream == NULL)
+ nError = GetLastError();
+ }
+
+ // Get the file size and file time
+ if(nError == ERROR_SUCCESS)
+ {
+ FileStream_GetTime(pStream, &FileTime);
+ FileStream_GetSize(pStream, &FileSize);
+
+ // Files bigger than 4GB cannot be added to MPQ
+ if(FileSize >> 32)
+ nError = ERROR_DISK_FULL;
+ }
+
+ // Allocate data buffer for reading from the source file
+ if(nError == ERROR_SUCCESS)
+ {
+ dwBytesRemaining = (DWORD)FileSize;
+ pbFileData = STORM_ALLOC(BYTE, dwSectorSize);
+ if(pbFileData == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Deal with various combination of compressions
+ if(nError == 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 first compression must not be WAVE
+ if(dwCompression & (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO))
+ dwCompression = MPQ_COMPRESSION_PKWARE;
+
+ dwCompressionNext &= ~(MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO);
+ bIsAdpcmCompression = true;
+ }
+
+ // Initiate adding file to the MPQ
+ if(!SFileCreateFile(hMpq, szArchivedName, FileTime, (DWORD)FileSize, lcFileLocale, dwFlags, &hMpqFile))
+ nError = GetLastError();
+ }
+
+ // Write the file data to the MPQ
+ while(nError == 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))
+ {
+ nError = 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, otherwise it's data corruption
+ if(!IsWaveFile(pbFileData, dwBytesToRead, &dwChannels))
+ {
+ nError = ERROR_BAD_FORMAT;
+ break;
+ }
+
+ // Setup the compression according to number of channels
+ dwCompressionNext |= (dwChannels == 1) ? MPQ_COMPRESSION_ADPCM_MONO : MPQ_COMPRESSION_ADPCM_STEREO;
+ bIsFirstSector = false;
+ }
+
+ // Add the file sectors to the MPQ
+ if(!SFileWriteFile(hMpqFile, pbFileData, dwBytesToRead, dwCompression))
+ {
+ nError = GetLastError();
+ break;
+ }
+
+ // Set the next data compression
+ dwBytesRemaining -= dwBytesToRead;
+ dwCompression = dwCompressionNext;
+ }
+
+ // Finish the file writing
+ if(hMpqFile != NULL)
+ {
+ if(!SFileFinishFile(hMpqFile))
+ nError = GetLastError();
+ }
+
+ // Cleanup and exit
+ if(pbFileData != NULL)
+ STORM_FREE(pbFileData);
+ if(pStream != NULL)
+ FileStream_Close(pStream);
+ if(nError != ERROR_SUCCESS)
+ SetLastError(nError);
+ return (nError == ERROR_SUCCESS);
+}
+
+// Adds a data file into the archive
+bool WINAPI SFileAddFile(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags)
+{
+ 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. The file content
+// remains there, only the entries in the hash table and in the block
+// table are updated.
+
+bool WINAPI SFileRemoveFile(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope)
+{
+ TMPQArchive * ha = (TMPQArchive *)hMpq;
+ TFileEntry * pFileEntry = NULL; // File entry of the file to be deleted
+ DWORD dwFileIndex = 0;
+ int nError = ERROR_SUCCESS;
+
+ // Keep compiler happy
+ dwSearchScope = dwSearchScope;
+
+ // Check the parameters
+ if(nError == ERROR_SUCCESS)
+ {
+ if(!IsValidMpqHandle(ha))
+ nError = ERROR_INVALID_HANDLE;
+ if(szFileName == NULL || *szFileName == 0)
+ nError = ERROR_INVALID_PARAMETER;
+ if(IsInternalMpqFileName(szFileName))
+ nError = ERROR_INTERNAL_FILE;
+ }
+
+ if(nError == ERROR_SUCCESS)
+ {
+ // Do not allow to remove files from MPQ open for read only
+ if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
+ nError = ERROR_ACCESS_DENIED;
+ }
+
+ // Get hash entry belonging to this file
+ if(nError == ERROR_SUCCESS)
+ {
+ if(!IsPseudoFileName(szFileName, &dwFileIndex))
+ {
+ if((pFileEntry = GetFileEntryExact(ha, (char *)szFileName, lcFileLocale)) == NULL)
+ nError = ERROR_FILE_NOT_FOUND;
+ }
+ else
+ {
+ if((pFileEntry = GetFileEntryByIndex(ha, dwFileIndex)) == NULL)
+ nError = ERROR_FILE_NOT_FOUND;
+ }
+ }
+
+ // Test if the file is not already deleted
+ if(nError == ERROR_SUCCESS)
+ {
+ if(!(pFileEntry->dwFlags & MPQ_FILE_EXISTS))
+ nError = ERROR_FILE_NOT_FOUND;
+ }
+
+ if(nError == ERROR_SUCCESS)
+ {
+ // Invalidate the entries for (listfile) and (attributes)
+ // After we are done with MPQ changes, we need to re-create them anyway
+ InvalidateInternalFiles(ha);
+
+ // Mark the file entry as free
+ nError = FreeFileEntry(ha, pFileEntry);
+ }
+
+ // Resolve error and exit
+ if(nError != ERROR_SUCCESS)
+ SetLastError(nError);
+ return (nError == ERROR_SUCCESS);
+}
+
+// Renames the file within the archive.
+bool WINAPI SFileRenameFile(HANDLE hMpq, const char * szFileName, const char * szNewFileName)
+{
+ TMPQArchive * ha = (TMPQArchive *)hMpq;
+ TFileEntry * pFileEntry = NULL;
+ ULONGLONG RawDataOffs;
+ TMPQFile * hf;
+ int nError = ERROR_SUCCESS;
+
+ // Test the valid parameters
+ if(nError == ERROR_SUCCESS)
+ {
+ if(!IsValidMpqHandle(ha))
+ nError = ERROR_INVALID_HANDLE;
+ if(szFileName == NULL || *szFileName == 0 || szNewFileName == NULL || *szNewFileName == 0)
+ nError = ERROR_INVALID_PARAMETER;
+ }
+
+ if(nError == ERROR_SUCCESS)
+ {
+ // Do not allow to rename files in MPQ open for read only
+ if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
+ nError = ERROR_ACCESS_DENIED;
+
+ // Do not allow renaming anything to a pseudo-file name
+ if(IsPseudoFileName(szFileName, NULL) || IsPseudoFileName(szNewFileName, NULL))
+ nError = ERROR_INVALID_PARAMETER;
+
+ // Do not allow to rename any of the internal files
+ // Also do not allow to rename any of files to an internal file
+ if(IsInternalMpqFileName(szFileName) || IsInternalMpqFileName(szNewFileName))
+ nError = ERROR_INTERNAL_FILE;
+ }
+
+ // Find the current file entry.
+ if(nError == ERROR_SUCCESS)
+ {
+ // Get the file entry
+ pFileEntry = GetFileEntryLocale(ha, szFileName, lcFileLocale);
+ if(pFileEntry == NULL)
+ nError = ERROR_FILE_NOT_FOUND;
+ }
+
+ // Also try to find file entry for the new file.
+ // This verifies if we are not overwriting an existing file
+ // (whose name we perhaps don't know)
+ if(nError == ERROR_SUCCESS)
+ {
+ if(GetFileEntryLocale(ha, szNewFileName, pFileEntry->lcLocale) != NULL)
+ nError = ERROR_ALREADY_EXISTS;
+ }
+
+ // Now we rename the existing file entry.
+ if(nError == ERROR_SUCCESS)
+ {
+ // Rename the file entry
+ nError = RenameFileEntry(ha, pFileEntry, szNewFileName);
+ }
+
+ // Now we copy the existing file entry to the new one
+ if(nError == ERROR_SUCCESS)
+ {
+ // If the file is encrypted, we have to re-crypt the file content
+ // with the new decryption key
+ if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
+ {
+ hf = CreateMpqFile(ha);
+ if(hf != NULL)
+ {
+ // Recrypt the file data in the MPQ
+ hf->pFileEntry = pFileEntry;
+ hf->dwDataSize = pFileEntry->dwFileSize;
+ nError = RecryptFileData(ha, hf, szFileName, szNewFileName);
+
+ // Update the MD5
+ if(ha->pHeader->dwRawChunkSize != 0)
+ {
+ RawDataOffs = ha->MpqPos + pFileEntry->ByteOffset;
+ WriteMpqDataMD5(ha->pStream,
+ RawDataOffs,
+ pFileEntry->dwCmpSize,
+ ha->pHeader->dwRawChunkSize);
+ }
+
+ FreeMPQFile(hf);
+ }
+ else
+ {
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+ }
+ }
+
+ //
+ // Note: MPQ_FLAG_CHANGED is set by RenameFileEntry
+ //
+
+ // Resolve error and return
+ if(nError != ERROR_SUCCESS)
+ SetLastError(nError);
+ return (nError == 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 = (TMPQFile *)hFile;
+
+ // Invalid handle => do nothing
+ if(!IsValidFileHandle(hf))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ 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 in MPQs version 3 or higher
+ ha = hf->ha;
+ if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_3)
+ {
+ SetLastError(ERROR_NOT_SUPPORTED);
+ return false;
+ }
+
+ // Do not allow to rename files in MPQ open for read only
+ if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
+ {
+ SetLastError(ERROR_ACCESS_DENIED);
+ return false;
+ }
+
+ // If the file already has that locale, return OK
+ if(hf->pFileEntry->lcLocale == lcNewLocale)
+ return true;
+
+ // We have to check if the file+locale is not already there
+ pFileEntry = GetFileEntryExact(ha, hf->pFileEntry->szFileName, lcNewLocale);
+ if(pFileEntry != NULL)
+ {
+ SetLastError(ERROR_ALREADY_EXISTS);
+ return false;
+ }
+
+ // Set the locale and return success
+ pFileEntry = hf->pFileEntry;
+ pFileEntry->lcLocale = (USHORT)lcNewLocale;
+
+ // Save the new locale to the hash table, if any
+ if(ha->pHashTable != NULL)
+ ha->pHashTable[pFileEntry->dwHashIndex].lcLocale = (USHORT)lcNewLocale;
+
+ // Remember that the MPQ tables have been changed
+ ha->dwFlags |= MPQ_FLAG_CHANGED;
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Sets add file callback
+
+bool WINAPI SFileSetAddFileCallback(HANDLE /* hMpq */, SFILE_ADDFILE_CALLBACK aAddFileCB, void * pvData)
+{
+ pvUserData = pvData;
+ AddFileCB = aAddFileCB;
+ return true;
+}
diff --git a/src/SFileAttributes.cpp b/src/SFileAttributes.cpp
new file mode 100644
index 0000000..865debc
--- /dev/null
+++ b/src/SFileAttributes.cpp
@@ -0,0 +1,472 @@
+/*****************************************************************************/
+/* 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
+} MPQ_ATTRIBUTES_HEADER, *PMPQ_ATTRIBUTES_HEADER;
+
+//-----------------------------------------------------------------------------
+// Public functions (internal use by StormLib)
+
+int SAttrLoadAttributes(TMPQArchive * ha)
+{
+ MPQ_ATTRIBUTES_HEADER AttrHeader;
+ HANDLE hFile = NULL;
+ DWORD dwBlockTableSize = ha->pHeader->dwBlockTableSize;
+ DWORD dwArraySize;
+ DWORD dwBytesRead;
+ DWORD i;
+ int nError = ERROR_SUCCESS;
+
+ // File table must be initialized
+ assert(ha->pFileTable != NULL);
+
+ // Attempt to open the "(attributes)" file.
+ // If it's not there, then the archive doesn't support attributes
+ if(SFileOpenFileEx((HANDLE)ha, ATTRIBUTES_NAME, SFILE_OPEN_ANY_LOCALE, &hFile))
+ {
+ // Load the content of the attributes file
+ SFileReadFile(hFile, &AttrHeader, sizeof(MPQ_ATTRIBUTES_HEADER), &dwBytesRead, NULL);
+ if(dwBytesRead != sizeof(MPQ_ATTRIBUTES_HEADER))
+ nError = ERROR_FILE_CORRUPT;
+
+ // Verify the header of the (attributes) file
+ if(nError == ERROR_SUCCESS)
+ {
+ AttrHeader.dwVersion = BSWAP_INT32_UNSIGNED(AttrHeader.dwVersion);
+ AttrHeader.dwFlags = BSWAP_INT32_UNSIGNED(AttrHeader.dwFlags);
+ ha->dwAttrFlags = AttrHeader.dwFlags;
+ if(dwBytesRead != sizeof(MPQ_ATTRIBUTES_HEADER))
+ nError = ERROR_FILE_CORRUPT;
+ }
+
+ // Verify format of the attributes
+ if(nError == ERROR_SUCCESS)
+ {
+ if(AttrHeader.dwVersion > MPQ_ATTRIBUTES_V1)
+ nError = ERROR_BAD_FORMAT;
+ }
+
+ // Load the CRC32 (if any)
+ if(nError == ERROR_SUCCESS && (AttrHeader.dwFlags & MPQ_ATTRIBUTE_CRC32))
+ {
+ LPDWORD pArrayCRC32 = STORM_ALLOC(DWORD, dwBlockTableSize);
+
+ if(pArrayCRC32 != NULL)
+ {
+ dwArraySize = dwBlockTableSize * sizeof(DWORD);
+ SFileReadFile(hFile, pArrayCRC32, dwArraySize, &dwBytesRead, NULL);
+ if(dwBytesRead == dwArraySize)
+ {
+ for(i = 0; i < dwBlockTableSize; i++)
+ ha->pFileTable[i].dwCrc32 = BSWAP_INT32_UNSIGNED(pArrayCRC32[i]);
+ }
+ else
+ nError = ERROR_FILE_CORRUPT;
+
+ STORM_FREE(pArrayCRC32);
+ }
+ else
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Read the array of file times
+ if(nError == ERROR_SUCCESS && (AttrHeader.dwFlags & MPQ_ATTRIBUTE_FILETIME))
+ {
+ ULONGLONG * pArrayFileTime = STORM_ALLOC(ULONGLONG, dwBlockTableSize);
+
+ if(pArrayFileTime != NULL)
+ {
+ dwArraySize = dwBlockTableSize * sizeof(ULONGLONG);
+ SFileReadFile(hFile, pArrayFileTime, dwArraySize, &dwBytesRead, NULL);
+ if(dwBytesRead == dwArraySize)
+ {
+ for(i = 0; i < dwBlockTableSize; i++)
+ ha->pFileTable[i].FileTime = BSWAP_INT64_UNSIGNED(pArrayFileTime[i]);
+ }
+ else
+ nError = ERROR_FILE_CORRUPT;
+
+ STORM_FREE(pArrayFileTime);
+ }
+ else
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Read the MD5 (if any)
+ // Note: MD5 array can be incomplete, if it's the last array in the (attributes)
+ if(nError == ERROR_SUCCESS && (AttrHeader.dwFlags & MPQ_ATTRIBUTE_MD5))
+ {
+ unsigned char * pArrayMD5 = STORM_ALLOC(unsigned char, (dwBlockTableSize * MD5_DIGEST_SIZE));
+ unsigned char * md5;
+
+ if(pArrayMD5 != NULL)
+ {
+ dwArraySize = dwBlockTableSize * MD5_DIGEST_SIZE;
+ SFileReadFile(hFile, pArrayMD5, dwArraySize, &dwBytesRead, NULL);
+ if(dwBytesRead == dwArraySize)
+ {
+ md5 = pArrayMD5;
+ for(i = 0; i < dwBlockTableSize; i++)
+ {
+ memcpy(ha->pFileTable[i].md5, md5, MD5_DIGEST_SIZE);
+ md5 += MD5_DIGEST_SIZE;
+ }
+ }
+ else
+ nError = ERROR_FILE_CORRUPT;
+
+ STORM_FREE(pArrayMD5);
+ }
+ else
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Read the patch bit for each file
+ if(nError == ERROR_SUCCESS && (AttrHeader.dwFlags & MPQ_ATTRIBUTE_PATCH_BIT))
+ {
+ LPBYTE pbBitArray;
+ DWORD dwByteSize = ((dwBlockTableSize - 1) / 8) + 1;
+
+ pbBitArray = STORM_ALLOC(BYTE, dwByteSize);
+ if(pbBitArray != NULL)
+ {
+ SFileReadFile(hFile, pbBitArray, dwByteSize, &dwBytesRead, NULL);
+ if(dwBytesRead == dwByteSize)
+ {
+ for(i = 0; i < dwBlockTableSize; i++)
+ {
+ DWORD dwByteIndex = i / 8;
+ DWORD dwBitMask = 0x80 >> (i & 7);
+
+ // Is the appropriate bit set?
+ if(pbBitArray[dwByteIndex] & dwBitMask)
+ {
+ // At the moment, we assume that the patch bit is present
+ // in both file table and (attributes)
+ assert((ha->pFileTable[i].dwFlags & MPQ_FILE_PATCH_FILE) != 0);
+ ha->pFileTable[i].dwFlags |= MPQ_FILE_PATCH_FILE;
+ }
+ }
+ }
+ else
+ nError = ERROR_FILE_CORRUPT;
+
+ STORM_FREE(pbBitArray);
+ }
+ }
+
+ //
+ // Note: Version 7.00 of StormLib saved the (attributes) incorrectly.
+ // Sometimes, number of entries in the (attributes) was 1 item less
+ // than block table size.
+ // If we encounter such table, we will zero all three arrays
+ //
+
+ if(nError != ERROR_SUCCESS)
+ ha->dwAttrFlags = 0;
+
+ // Cleanup & exit
+ SFileCloseFile(hFile);
+ }
+ return nError;
+}
+
+int SAttrFileSaveToMpq(TMPQArchive * ha)
+{
+ MPQ_ATTRIBUTES_HEADER AttrHeader;
+ TFileEntry * pFileEntry;
+ TMPQFile * hf = NULL;
+ DWORD dwFinalBlockTableSize = ha->dwFileTableSize;
+ DWORD dwFileSize = 0;
+ DWORD dwToWrite;
+ DWORD i;
+ int nError = ERROR_SUCCESS;
+
+ // Now we have to check if we need patch bits in the (attributes)
+ if(nError == ERROR_SUCCESS)
+ {
+ for(i = 0; i < ha->dwFileTableSize; i++)
+ {
+ if(ha->pFileTable[i].dwFlags & MPQ_FILE_PATCH_FILE)
+ {
+ ha->dwAttrFlags |= MPQ_ATTRIBUTE_PATCH_BIT;
+ break;
+ }
+ }
+ }
+
+ // If the (attributes) is not in the file table yet,
+ // we have to increase the final block table size
+ pFileEntry = GetFileEntryExact(ha, ATTRIBUTES_NAME, LANG_NEUTRAL);
+ if(pFileEntry != NULL)
+ {
+ // If "(attributes)" file exists, and it's set to 0, then remove it
+ if(ha->dwAttrFlags == 0)
+ {
+ FreeFileEntry(ha, pFileEntry);
+ return ERROR_SUCCESS;
+ }
+ }
+ else
+ {
+ // If we don't want to create file atributes, do nothing
+ if(ha->dwAttrFlags == 0)
+ return ERROR_SUCCESS;
+
+ // Check where the file entry is going to be allocated.
+ // If at the end of the file table, we have to increment
+ // the expected size of the (attributes) file.
+ pFileEntry = FindFreeFileEntry(ha);
+ if(pFileEntry == ha->pFileTable + ha->dwFileTableSize)
+ dwFinalBlockTableSize++;
+ }
+
+ // Calculate the size of the attributes file
+ if(nError == ERROR_SUCCESS)
+ {
+ dwFileSize = sizeof(MPQ_ATTRIBUTES_HEADER); // Header
+ if(ha->dwAttrFlags & MPQ_ATTRIBUTE_CRC32)
+ dwFileSize += dwFinalBlockTableSize * sizeof(DWORD);
+ if(ha->dwAttrFlags & MPQ_ATTRIBUTE_FILETIME)
+ dwFileSize += dwFinalBlockTableSize * sizeof(ULONGLONG);
+ if(ha->dwAttrFlags & MPQ_ATTRIBUTE_MD5)
+ dwFileSize += dwFinalBlockTableSize * MD5_DIGEST_SIZE;
+ if(ha->dwAttrFlags & MPQ_ATTRIBUTE_PATCH_BIT)
+ dwFileSize += ((dwFinalBlockTableSize - 1)) / 8 + 1;
+ }
+
+ // Determine the flags for (attributes)
+ if(ha->dwFileFlags2 == 0)
+ ha->dwFileFlags2 = GetDefaultSpecialFileFlags(ha, dwFileSize);
+
+ // Create the attributes file in the MPQ
+ nError = SFileAddFile_Init(ha, ATTRIBUTES_NAME,
+ 0,
+ dwFileSize,
+ LANG_NEUTRAL,
+ ha->dwFileFlags2 | MPQ_FILE_REPLACEEXISTING,
+ &hf);
+
+ // Write all parts of the (attributes) file
+ if(nError == ERROR_SUCCESS)
+ {
+ assert(ha->dwFileTableSize == dwFinalBlockTableSize);
+
+ // Note that we don't know what the new bit (0x08) means.
+ AttrHeader.dwVersion = BSWAP_INT32_UNSIGNED(100);
+ AttrHeader.dwFlags = BSWAP_INT32_UNSIGNED((ha->dwAttrFlags & MPQ_ATTRIBUTE_ALL));
+ dwToWrite = sizeof(MPQ_ATTRIBUTES_HEADER);
+ nError = SFileAddFile_Write(hf, &AttrHeader, dwToWrite, MPQ_COMPRESSION_ZLIB);
+ }
+
+ // Write the array of CRC32
+ if(nError == ERROR_SUCCESS && (ha->dwAttrFlags & MPQ_ATTRIBUTE_CRC32))
+ {
+ LPDWORD pArrayCRC32 = STORM_ALLOC(DWORD, dwFinalBlockTableSize);
+
+ if(pArrayCRC32 != NULL)
+ {
+ // Copy from file table
+ for(i = 0; i < ha->dwFileTableSize; i++)
+ pArrayCRC32[i] = BSWAP_INT32_UNSIGNED(ha->pFileTable[i].dwCrc32);
+
+ dwToWrite = ha->dwFileTableSize * sizeof(DWORD);
+ nError = SFileAddFile_Write(hf, pArrayCRC32, dwToWrite, MPQ_COMPRESSION_ZLIB);
+ STORM_FREE(pArrayCRC32);
+ }
+ }
+
+ // Write the array of file time
+ if(nError == ERROR_SUCCESS && (ha->dwAttrFlags & MPQ_ATTRIBUTE_FILETIME))
+ {
+ ULONGLONG * pArrayFileTime = STORM_ALLOC(ULONGLONG, ha->dwFileTableSize);
+
+ if(pArrayFileTime != NULL)
+ {
+ // Copy from file table
+ for(i = 0; i < ha->dwFileTableSize; i++)
+ pArrayFileTime[i] = BSWAP_INT64_UNSIGNED(ha->pFileTable[i].FileTime);
+
+ dwToWrite = ha->dwFileTableSize * sizeof(ULONGLONG);
+ nError = SFileAddFile_Write(hf, pArrayFileTime, dwToWrite, MPQ_COMPRESSION_ZLIB);
+ STORM_FREE(pArrayFileTime);
+ }
+ }
+
+ // Write the array of MD5s
+ if(nError == ERROR_SUCCESS && (ha->dwAttrFlags & MPQ_ATTRIBUTE_MD5))
+ {
+ char * pArrayMD5 = STORM_ALLOC(char, ha->dwFileTableSize * MD5_DIGEST_SIZE);
+
+ if(pArrayMD5 != NULL)
+ {
+ // Copy from file table
+ for(i = 0; i < ha->dwFileTableSize; i++)
+ memcpy(&pArrayMD5[i * MD5_DIGEST_SIZE], ha->pFileTable[i].md5, MD5_DIGEST_SIZE);
+
+ dwToWrite = ha->dwFileTableSize * MD5_DIGEST_SIZE;
+ nError = SFileAddFile_Write(hf, pArrayMD5, dwToWrite, MPQ_COMPRESSION_ZLIB);
+ STORM_FREE(pArrayMD5);
+ }
+ }
+
+ // Write the array of patch bits
+ if(nError == ERROR_SUCCESS && (ha->dwAttrFlags & MPQ_ATTRIBUTE_PATCH_BIT))
+ {
+ LPBYTE pbBitArray;
+ DWORD dwByteSize = ((ha->dwFileTableSize - 1) / 8) + 1;
+
+ pbBitArray = STORM_ALLOC(BYTE, dwByteSize);
+ if(pbBitArray != NULL)
+ {
+ memset(pbBitArray, 0, dwByteSize);
+ for(i = 0; i < ha->dwFileTableSize; i++)
+ {
+ DWORD dwByteIndex = i / 8;
+ DWORD dwBitMask = 0x80 >> (i & 7);
+
+ if(ha->pFileTable[i].dwFlags & MPQ_FILE_PATCH_FILE)
+ pbBitArray[dwByteIndex] |= dwBitMask;
+ }
+
+ nError = SFileAddFile_Write(hf, pbBitArray, dwByteSize, MPQ_COMPRESSION_ZLIB);
+ STORM_FREE(pbBitArray);
+ }
+ }
+
+ // Finalize the file in the archive
+ if(hf != NULL)
+ {
+ SFileAddFile_Finish(hf);
+ }
+
+ if(nError == ERROR_SUCCESS)
+ ha->dwFlags &= ~MPQ_FLAG_INV_ATTRIBUTES;
+ return nError;
+}
+
+//-----------------------------------------------------------------------------
+// Public functions
+
+DWORD WINAPI SFileGetAttributes(HANDLE hMpq)
+{
+ TMPQArchive * ha = (TMPQArchive *)hMpq;
+
+ // Verify the parameters
+ if(!IsValidMpqHandle(ha))
+ {
+ 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(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;
+ }
+
+ // 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;
+ SFileGetFileInfo(hFile, SFILE_INFO_FILE_SIZE, &dwTotalBytes, sizeof(DWORD), NULL);
+
+ // 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/src/SFileCompactArchive.cpp b/src/SFileCompactArchive.cpp
new file mode 100644
index 0000000..004ca7d
--- /dev/null
+++ b/src/SFileCompactArchive.cpp
@@ -0,0 +1,765 @@
+/*****************************************************************************/
+/* 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 */
+/*****************************************************************************/
+
+#define __STORMLIB_SELF__
+#include "StormLib.h"
+#include "StormCommon.h"
+
+/*****************************************************************************/
+/* Local variables */
+/*****************************************************************************/
+
+static SFILE_COMPACT_CALLBACK CompactCB = NULL;
+static ULONGLONG CompactBytesProcessed = 0;
+static ULONGLONG CompactTotalBytes = 0;
+static void * pvUserData = NULL;
+
+/*****************************************************************************/
+/* Local functions */
+/*****************************************************************************/
+
+static int CheckIfAllFilesKnown(TMPQArchive * ha, const char * szListFile, LPDWORD pFileKeys)
+{
+ TFileEntry * pFileTableEnd;
+ TFileEntry * pFileEntry;
+ DWORD dwBlockIndex = 0;
+ int nError = ERROR_SUCCESS;
+
+ // Add the listfile to the MPQ
+ if(nError == ERROR_SUCCESS && szListFile != NULL)
+ {
+ // Notify the user
+ if(CompactCB != NULL)
+ CompactCB(pvUserData, CCB_CHECKING_FILES, CompactBytesProcessed, CompactTotalBytes);
+
+ nError = SFileAddListFile((HANDLE)ha, szListFile);
+ }
+
+ // Verify the file table
+ if(nError == ERROR_SUCCESS)
+ {
+ pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
+ for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++, dwBlockIndex++)
+ {
+ if(pFileEntry->dwFlags & MPQ_FILE_EXISTS)
+ {
+ if(pFileEntry->szFileName != NULL && !IsPseudoFileName(pFileEntry->szFileName, NULL))
+ {
+ DWORD dwFileKey = 0;
+
+ // Resolve the file key. Use plain file name for it
+ if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
+ {
+ dwFileKey = DecryptFileKey(pFileEntry->szFileName,
+ pFileEntry->ByteOffset,
+ pFileEntry->dwFileSize,
+ pFileEntry->dwFlags);
+ }
+
+ // Give the key to the caller
+ if(pFileKeys != NULL)
+ pFileKeys[dwBlockIndex] = dwFileKey;
+ }
+ else
+ {
+ nError = ERROR_CAN_NOT_COMPLETE;
+ break;
+ }
+ }
+ }
+ }
+
+ return nError;
+}
+
+static int CopyNonMpqData(
+ TFileStream * pSrcStream,
+ TFileStream * pTrgStream,
+ ULONGLONG & ByteOffset,
+ ULONGLONG & ByteCount)
+{
+ ULONGLONG DataSize = ByteCount;
+ DWORD dwToRead;
+ char DataBuffer[0x1000];
+ int nError = 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))
+ {
+ nError = GetLastError();
+ break;
+ }
+
+ // Write to the target stream
+ if(!FileStream_Write(pTrgStream, NULL, DataBuffer, dwToRead))
+ {
+ nError = GetLastError();
+ break;
+ }
+
+ // Update the progress
+ if(CompactCB != NULL)
+ {
+ CompactBytesProcessed += dwToRead;
+ CompactCB(pvUserData, CCB_COPYING_NON_MPQ_DATA, CompactBytesProcessed, CompactTotalBytes);
+ }
+
+ // Decrement the number of data to be copied
+ ByteOffset += dwToRead;
+ DataSize -= dwToRead;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+// Copies all file sectors into another archive.
+static int CopyMpqFileSectors(
+ TMPQArchive * ha,
+ TMPQFile * hf,
+ TFileStream * pNewStream)
+{
+ TFileEntry * pFileEntry = hf->pFileEntry;
+ ULONGLONG RawFilePos; // Used for calculating sector offset in the old MPQ archive
+ ULONGLONG MpqFilePos; // MPQ file position in the new 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
+ int nError = ERROR_SUCCESS;
+
+ // Remember the position in the destination file
+ FileStream_GetPos(pNewStream, &MpqFilePos);
+ MpqFilePos -= ha->MpqPos;
+
+ // Resolve decryption keys. Note that the file key given
+ // in the TMPQFile structure also includes the key adjustment
+ if(nError == ERROR_SUCCESS && (pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED))
+ {
+ 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(nError == ERROR_SUCCESS && hf->pPatchInfo != NULL)
+ {
+ BSWAP_ARRAY32_UNSIGNED(hf->pPatchInfo, sizeof(DWORD) * 3);
+ if(!FileStream_Write(pNewStream, NULL, hf->pPatchInfo, hf->pPatchInfo->dwLength))
+ nError = GetLastError();
+
+ // Save the size of the patch info
+ dwPatchSize = hf->pPatchInfo->dwLength;
+ }
+
+ // If we have to save sector offset table, do it.
+ if(nError == ERROR_SUCCESS && hf->SectorOffsets != NULL)
+ {
+ DWORD * SectorOffsetsCopy = (DWORD *)STORM_ALLOC(BYTE, hf->SectorOffsets[0]);
+ DWORD dwSectorOffsLen = hf->SectorOffsets[0];
+
+ assert((pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) == 0);
+ assert(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED);
+
+ if(SectorOffsetsCopy == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+
+ // Encrypt the secondary sector offset table and write it to the target file
+ if(nError == 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))
+ nError = GetLastError();
+
+ dwBytesToCopy -= dwSectorOffsLen;
+ dwCmpSize += dwSectorOffsLen;
+ }
+
+ // Update compact progress
+ if(CompactCB != NULL)
+ {
+ CompactBytesProcessed += dwSectorOffsLen;
+ CompactCB(pvUserData, CCB_COMPACTING_FILES, CompactBytesProcessed, 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(nError == 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
+ CalculateRawSectorOffset(RawFilePos, hf, dwRawByteOffset);
+
+ // Read the file sector
+ if(!FileStream_Read(ha->pStream, &RawFilePos, hf->pbFileSector, dwRawDataInSector))
+ {
+ nError = 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))
+ {
+ nError = GetLastError();
+ break;
+ }
+
+ // Update compact progress
+ if(CompactCB != NULL)
+ {
+ CompactBytesProcessed += dwRawDataInSector;
+ CompactCB(pvUserData, CCB_COMPACTING_FILES, CompactBytesProcessed, CompactTotalBytes);
+ }
+
+ // Adjust byte counts
+ dwBytesToCopy -= dwRawDataInSector;
+ dwCmpSize += dwRawDataInSector;
+ }
+ }
+
+ // Copy the sector CRCs, if any
+ // Sector CRCs are always compressed (not imploded) and unencrypted
+ if(nError == 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))
+ nError = GetLastError();
+
+ if(!FileStream_Write(pNewStream, NULL, hf->SectorChksums, dwCrcLength))
+ nError = GetLastError();
+
+ // Update compact progress
+ if(CompactCB != NULL)
+ {
+ CompactBytesProcessed += dwCrcLength;
+ CompactCB(pvUserData, CCB_COMPACTING_FILES, CompactBytesProcessed, 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(nError == 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))
+ nError = GetLastError();
+
+ if(!FileStream_Write(pNewStream, NULL, pbExtraData, dwBytesToCopy))
+ nError = GetLastError();
+
+ // Include these extra data in the compressed size
+ dwCmpSize += dwBytesToCopy;
+ dwBytesToCopy = 0;
+ STORM_FREE(pbExtraData);
+ }
+ else
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Write the MD5's of the raw file data, if needed
+ if(nError == ERROR_SUCCESS && ha->pHeader->dwRawChunkSize != 0)
+ {
+ nError = WriteMpqDataMD5(pNewStream,
+ ha->MpqPos + MpqFilePos,
+ pFileEntry->dwCmpSize,
+ ha->pHeader->dwRawChunkSize);
+ }
+
+ // Update file position in the block table
+ if(nError == 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 protection, ...)
+ //
+ // 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
+ // Seems like some sort of protection to me.
+ //
+ // Note: Some patch files in WOW patches don't count the patch header
+ // into compressed size
+ //
+
+ if(dwCmpSize <= pFileEntry->dwCmpSize && pFileEntry->dwCmpSize <= dwCmpSize + dwPatchSize)
+ {
+ // Note: DO NOT update the compressed size in the file entry, no matter how bad it is.
+ pFileEntry->ByteOffset = MpqFilePos;
+ }
+ else
+ {
+ nError = ERROR_FILE_CORRUPT;
+ assert(false);
+ }
+ }
+
+ return nError;
+}
+
+static int CopyMpqFiles(TMPQArchive * ha, LPDWORD pFileKeys, TFileStream * pNewStream)
+{
+ TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
+ TFileEntry * pFileEntry;
+ TMPQFile * hf = NULL;
+ int nError = 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) && pFileEntry->dwFileSize != 0)
+ {
+ // Allocate structure for the MPQ file
+ hf = CreateMpqFile(ha);
+ if(hf == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ // Store file entry
+ hf->pFileEntry = pFileEntry;
+
+ // Set the raw file position
+ hf->MpqFilePos = pFileEntry->ByteOffset;
+ hf->RawFilePos = ha->MpqPos + hf->MpqFilePos;
+
+ // Set the file decryption key
+ hf->dwFileKey = pFileKeys[pFileEntry - ha->pFileTable];
+ hf->dwDataSize = pFileEntry->dwFileSize;
+
+ // If the file is a patch file, load the patch header
+ if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE)
+ {
+ nError = AllocatePatchInfo(hf, true);
+ if(nError != ERROR_SUCCESS)
+ break;
+ }
+
+ // Allocate buffers for file sector and sector offset table
+ nError = AllocateSectorBuffer(hf);
+ if(nError != ERROR_SUCCESS)
+ break;
+
+ // Also allocate sector offset table and sector checksum table
+ nError = AllocateSectorOffsets(hf, true);
+ if(nError != ERROR_SUCCESS)
+ break;
+
+ // Also load sector checksums, if any
+ if(pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC)
+ {
+ nError = AllocateSectorChecksums(hf, false);
+ if(nError != ERROR_SUCCESS)
+ break;
+ }
+
+ // Copy all file sectors
+ nError = CopyMpqFileSectors(ha, hf, pNewStream);
+ if(nError != ERROR_SUCCESS)
+ break;
+
+ // Free buffers. This also sets "hf" to NULL.
+ FreeMPQFile(hf);
+ }
+ }
+
+ // Cleanup and exit
+ if(hf != NULL)
+ FreeMPQFile(hf);
+ return nError;
+}
+
+
+/*****************************************************************************/
+/* Public functions */
+/*****************************************************************************/
+
+bool WINAPI SFileSetCompactCallback(HANDLE /* hMpq */, SFILE_COMPACT_CALLBACK aCompactCB, void * pvData)
+{
+ CompactCB = aCompactCB;
+ pvUserData = pvData;
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Archive compacting
+
+bool WINAPI SFileCompactArchive(HANDLE hMpq, const char * szListFile, bool /* bReserved */)
+{
+ TFileStream * pTempStream = NULL;
+ TMPQArchive * ha = (TMPQArchive *)hMpq;
+ ULONGLONG ByteOffset;
+ ULONGLONG ByteCount;
+ LPDWORD pFileKeys = NULL;
+ TCHAR szTempFile[MAX_PATH] = _T("");
+ TCHAR * szTemp = NULL;
+ int nError = ERROR_SUCCESS;
+
+ // Test the valid parameters
+ if(!IsValidMpqHandle(ha))
+ nError = ERROR_INVALID_HANDLE;
+ if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
+ nError = ERROR_ACCESS_DENIED;
+
+ // If the MPQ is changed at this moment, we have to flush the archive
+ if(nError == ERROR_SUCCESS && (ha->dwFlags & MPQ_FLAG_CHANGED))
+ {
+ SFileFlushArchive(hMpq);
+ }
+
+ // Create the table with file keys
+ if(nError == ERROR_SUCCESS)
+ {
+ if((pFileKeys = STORM_ALLOC(DWORD, ha->dwFileTableSize)) != NULL)
+ memset(pFileKeys, 0, sizeof(DWORD) * ha->dwFileTableSize);
+ else
+ nError = 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(nError == ERROR_SUCCESS)
+ {
+ // Initialize the progress variables for compact callback
+ FileStream_GetSize(ha->pStream, &CompactTotalBytes);
+ CompactBytesProcessed = 0;
+ nError = CheckIfAllFilesKnown(ha, szListFile, pFileKeys);
+ }
+
+ // Get the temporary file name and create it
+ if(nError == ERROR_SUCCESS)
+ {
+ _tcscpy(szTempFile, FileStream_GetFileName(ha->pStream));
+ if((szTemp = _tcsrchr(szTempFile, '.')) != NULL)
+ _tcscpy(szTemp + 1, _T("mp_"));
+ else
+ _tcscat(szTempFile, _T("_"));
+
+ pTempStream = FileStream_CreateFile(szTempFile, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
+ if(pTempStream == NULL)
+ nError = GetLastError();
+ }
+
+ // Write the data before MPQ user data (if any)
+ if(nError == ERROR_SUCCESS && ha->UserDataPos != 0)
+ {
+ // Inform the application about the progress
+ if(CompactCB != NULL)
+ CompactCB(pvUserData, CCB_COPYING_NON_MPQ_DATA, CompactBytesProcessed, CompactTotalBytes);
+
+ ByteOffset = 0;
+ ByteCount = ha->UserDataPos;
+ nError = CopyNonMpqData(ha->pStream, pTempStream, ByteOffset, ByteCount);
+ }
+
+ // Write the MPQ user data (if any)
+ if(nError == 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);
+ nError = CopyNonMpqData(ha->pStream, pTempStream, ByteOffset, ByteCount);
+ }
+
+ // Write the MPQ header
+ if(nError == ERROR_SUCCESS)
+ {
+ // Remember the header size before swapping
+ DWORD dwBytesToWrite = ha->pHeader->dwHeaderSize;
+
+ BSWAP_TMPQHEADER(ha->pHeader);
+ if(!FileStream_Write(pTempStream, NULL, ha->pHeader, dwBytesToWrite))
+ nError = GetLastError();
+ BSWAP_TMPQHEADER(ha->pHeader);
+
+ // Update the progress
+ CompactBytesProcessed += ha->pHeader->dwHeaderSize;
+ }
+
+ // Now copy all files
+ if(nError == ERROR_SUCCESS)
+ {
+ nError = CopyMpqFiles(ha, pFileKeys, pTempStream);
+ ha->dwFlags |= MPQ_FLAG_CHANGED;
+ }
+
+ // If succeeded, switch the streams
+ if(nError == ERROR_SUCCESS)
+ {
+ if(FileStream_Switch(ha->pStream, pTempStream))
+ pTempStream = NULL;
+ else
+ nError = ERROR_CAN_NOT_COMPLETE;
+ }
+
+ // If all succeeded, save the MPQ tables
+ if(nError == ERROR_SUCCESS)
+ {
+ //
+ // Note: We don't recalculate position of the MPQ tables at this point.
+ // SaveMPQTables does it automatically.
+ //
+
+ nError = SaveMPQTables(ha);
+ if(nError == ERROR_SUCCESS && CompactCB != NULL)
+ {
+ CompactBytesProcessed += (ha->pHeader->dwHashTableSize * sizeof(TMPQHash));
+ CompactBytesProcessed += (ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock));
+ CompactCB(pvUserData, CCB_CLOSING_ARCHIVE, CompactBytesProcessed, CompactTotalBytes);
+ }
+ }
+
+ // Invalidate the compact callback
+ pvUserData = NULL;
+ CompactCB = NULL;
+
+ // Cleanup and return
+ if(pTempStream != NULL)
+ FileStream_Close(pTempStream);
+ if(pFileKeys != NULL)
+ STORM_FREE(pFileKeys);
+ if(nError != ERROR_SUCCESS)
+ SetLastError(nError);
+ return (nError == ERROR_SUCCESS);
+}
+
+//-----------------------------------------------------------------------------
+// Changing hash table size
+
+DWORD WINAPI SFileGetMaxFileCount(HANDLE hMpq)
+{
+ TMPQArchive * ha = (TMPQArchive *)hMpq;
+
+ return ha->dwMaxFileCount;
+}
+
+bool WINAPI SFileSetMaxFileCount(HANDLE hMpq, DWORD dwMaxFileCount)
+{
+ TMPQHetTable * pOldHetTable = NULL;
+ TMPQArchive * ha = (TMPQArchive *)hMpq;
+ TFileEntry * pOldFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
+ TFileEntry * pOldFileTable = NULL;
+ TFileEntry * pOldFileEntry;
+ TFileEntry * pFileEntry;
+ TMPQHash * pOldHashTable = NULL;
+ DWORD dwOldHashTableSize = 0;
+ DWORD dwOldFileTableSize = 0;
+ int nError = ERROR_SUCCESS;
+
+ // Test the valid parameters
+ if(!IsValidMpqHandle(ha))
+ nError = ERROR_INVALID_HANDLE;
+ if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
+ nError = ERROR_ACCESS_DENIED;
+
+ // The new limit must not be lower than the index of the last file entry in the table
+ if(nError == ERROR_SUCCESS && ha->dwFileTableSize > dwMaxFileCount)
+ nError = ERROR_DISK_FULL;
+
+ // ALL file names must be known in order to be able
+ // to rebuild hash table size
+ if(nError == ERROR_SUCCESS)
+ {
+ nError = CheckIfAllFilesKnown(ha, NULL, NULL);
+ }
+
+ // If the MPQ has a hash table, then we relocate the hash table
+ if(nError == ERROR_SUCCESS && ha->pHashTable != NULL)
+ {
+ // Save parameters for the current hash table
+ dwOldHashTableSize = ha->pHeader->dwHashTableSize;
+ pOldHashTable = ha->pHashTable;
+
+ // Allocate new hash table
+ ha->pHeader->dwHashTableSize = GetHashTableSizeForFileCount(dwMaxFileCount);
+ ha->pHashTable = STORM_ALLOC(TMPQHash, ha->pHeader->dwHashTableSize);
+ if(ha->pHashTable != NULL)
+ memset(ha->pHashTable, 0xFF, ha->pHeader->dwHashTableSize * sizeof(TMPQHash));
+ else
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // If the MPQ has HET table, allocate new one as well
+ if(nError == ERROR_SUCCESS && ha->pHetTable != NULL)
+ {
+ // Save the original HET table
+ pOldHetTable = ha->pHetTable;
+
+ // Create new one
+ ha->pHetTable = CreateHetTable(dwMaxFileCount, 0x40, true);
+ if(ha->pHetTable == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Now reallocate the file table
+ if(nError == ERROR_SUCCESS)
+ {
+ // Save the current file table
+ dwOldFileTableSize = ha->dwFileTableSize;
+ pOldFileTable = ha->pFileTable;
+
+ // Create new one
+ ha->pFileTable = STORM_ALLOC(TFileEntry, dwMaxFileCount);
+ if(ha->pFileTable != NULL)
+ memset(ha->pFileTable, 0, dwMaxFileCount * sizeof(TFileEntry));
+ else
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Now we have to build both classic hash table and HET table.
+ if(nError == ERROR_SUCCESS)
+ {
+ DWORD dwFileIndex = 0;
+ DWORD dwHashIndex = 0;
+
+ // Create new hash and HET entry for each file
+ pFileEntry = ha->pFileTable;
+ for(pOldFileEntry = pOldFileTable; pOldFileEntry < pOldFileTableEnd; pOldFileEntry++)
+ {
+ if(pOldFileEntry->dwFlags & MPQ_FILE_EXISTS)
+ {
+ // Copy the old file entry to the new one
+ memcpy(pFileEntry, pOldFileEntry, sizeof(TFileEntry));
+ assert(pFileEntry->szFileName != NULL);
+
+ // Create new entry in the hash table
+ if(ha->pHashTable != NULL)
+ {
+ dwHashIndex = AllocateHashEntry(ha, pFileEntry);
+ if(dwHashIndex == HASH_ENTRY_FREE)
+ {
+ nError = ERROR_CAN_NOT_COMPLETE;
+ break;
+ }
+ }
+
+ // Create new entry in the HET table, if needed
+ if(ha->pHetTable != NULL)
+ {
+ dwHashIndex = AllocateHetEntry(ha, pFileEntry);
+ if(dwHashIndex == HASH_ENTRY_FREE)
+ {
+ nError = ERROR_CAN_NOT_COMPLETE;
+ break;
+ }
+ }
+
+ // Move to the next file entry in the new table
+ pFileEntry++;
+ dwFileIndex++;
+ }
+ }
+ }
+
+ // Mark the archive as changed
+ // Note: We always have to rebuild the (attributes) file due to file table change
+ if(nError == ERROR_SUCCESS)
+ {
+ ha->dwMaxFileCount = dwMaxFileCount;
+ InvalidateInternalFiles(ha);
+ }
+ else
+ {
+ // Revert the hash table
+ if(ha->pHashTable != NULL && pOldHashTable != NULL)
+ {
+ STORM_FREE(ha->pHashTable);
+ ha->pHeader->dwHashTableSize = dwOldHashTableSize;
+ ha->pHashTable = pOldHashTable;
+ }
+
+ // Revert the HET table
+ if(ha->pHetTable != NULL && pOldHetTable != NULL)
+ {
+ FreeHetTable(ha->pHetTable);
+ ha->pHetTable = pOldHetTable;
+ }
+
+ // Revert the file table
+ if(pOldFileTable != NULL)
+ {
+ STORM_FREE(ha->pFileTable);
+ ha->pFileTable = pOldFileTable;
+ }
+
+ SetLastError(nError);
+ }
+
+ // Return the result
+ return (nError == ERROR_SUCCESS);
+}
diff --git a/src/SFileCreateArchive.cpp b/src/SFileCreateArchive.cpp
new file mode 100644
index 0000000..84109d3
--- /dev/null
+++ b/src/SFileCreateArchive.cpp
@@ -0,0 +1,255 @@
+/*****************************************************************************/
+/* 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 int WriteNakedMPQHeader(TMPQArchive * ha)
+{
+ TMPQHeader * pHeader = ha->pHeader;
+ TMPQHeader Header;
+ DWORD dwBytesToWrite = pHeader->dwHeaderSize;
+ int nError = 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);
+ if(!FileStream_Write(ha->pStream, &ha->MpqPos, &Header, dwBytesToWrite))
+ nError = GetLastError();
+
+ return nError;
+}
+
+//-----------------------------------------------------------------------------
+// Creates a new MPQ archive.
+
+bool WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwFlags, 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 = (dwFlags & MPQ_CREATE_ARCHIVE_VMASK) >> FLAGS_TO_FORMAT_SHIFT;
+ CreateInfo.dwStreamFlags = STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE;
+ CreateInfo.dwAttrFlags = (dwFlags & MPQ_CREATE_ATTRIBUTES) ? MPQ_ATTRIBUTE_ALL : 0;
+ CreateInfo.dwSectorSize = (CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_3) ? 0x4000 : 0x1000;
+ CreateInfo.dwRawChunkSize = (CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_4) ? 0x4000 : 0;
+ CreateInfo.dwMaxFileCount = dwMaxFileCount;
+ 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
+ ULONGLONG MpqPos = 0; // Position of MPQ header in the file
+ HANDLE hMpq = NULL;
+ DWORD dwBlockTableSize = 0; // Initial block table size
+ DWORD dwHashTableSize = 0;
+ DWORD dwMaxFileCount;
+ int nError = 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)) ||
+ (pCreateInfo->dwMaxFileCount < 4))
+ {
+ 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_LINEAR | 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 and attributes file
+ dwMaxFileCount = pCreateInfo->dwMaxFileCount;
+ if(pCreateInfo->dwAttrFlags != 0)
+ dwMaxFileCount++;
+ dwMaxFileCount++;
+
+ // If file count is not zero, initialize the hash table size
+ dwHashTableSize = GetHashTableSizeForFileCount(dwMaxFileCount);
+
+ // 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))
+ nError = GetLastError();
+
+#ifdef _DEBUG
+ // Debug code, used for testing StormLib
+// dwBlockTableSize = dwHashTableSize * 2;
+#endif
+
+ // Create the archive handle
+ if(nError == ERROR_SUCCESS)
+ {
+ if((ha = STORM_ALLOC(TMPQArchive, 1)) == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Fill the MPQ archive handle structure
+ if(nError == ERROR_SUCCESS)
+ {
+ memset(ha, 0, sizeof(TMPQArchive));
+ ha->pStream = pStream;
+ ha->dwSectorSize = pCreateInfo->dwSectorSize;
+ ha->UserDataPos = MpqPos;
+ ha->MpqPos = MpqPos;
+ ha->pHeader = (TMPQHeader *)ha->HeaderData;
+ ha->dwMaxFileCount = dwMaxFileCount;
+ ha->dwFileTableSize = 0;
+ ha->dwFileFlags1 = pCreateInfo->dwFileFlags1;
+ ha->dwFileFlags2 = pCreateInfo->dwFileFlags2;
+ ha->dwFlags = 0;
+
+ // Setup the attributes
+ ha->dwAttrFlags = pCreateInfo->dwAttrFlags;
+ pStream = NULL;
+ }
+
+ // Fill the MPQ header
+ if(nError == ERROR_SUCCESS)
+ {
+ TMPQHeader * pHeader = ha->pHeader;
+
+ // Fill the MPQ header
+ memset(pHeader, 0, sizeof(ha->HeaderData));
+ pHeader->dwID = ID_MPQ;
+ 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
+ nError = WriteNakedMPQHeader(ha);
+
+ // Remember that the (listfile) and (attributes) need to be saved
+ ha->dwFlags |= MPQ_FLAG_CHANGED | MPQ_FLAG_INV_LISTFILE | MPQ_FLAG_INV_ATTRIBUTES;
+ }
+
+ // Create initial HET table, if the caller required an MPQ format 3.0 or newer
+ if(nError == ERROR_SUCCESS && pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_3)
+ {
+ ha->pHetTable = CreateHetTable(ha->dwMaxFileCount, 0x40, true);
+ if(ha->pHetTable == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Create initial hash table
+ if(nError == ERROR_SUCCESS)
+ {
+ nError = CreateHashTable(ha, dwHashTableSize);
+ }
+
+ // Create initial file table
+ if(nError == ERROR_SUCCESS)
+ {
+ ha->pFileTable = STORM_ALLOC(TFileEntry, ha->dwMaxFileCount);
+ if(ha->pFileTable != NULL)
+ memset(ha->pFileTable, 0x00, sizeof(TFileEntry) * ha->dwMaxFileCount);
+ else
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Cleanup : If an error, delete all buffers and return
+ if(nError != ERROR_SUCCESS)
+ {
+ FileStream_Close(pStream);
+ FreeMPQArchive(ha);
+ SetLastError(nError);
+ ha = NULL;
+ }
+
+ // Return the values
+ *phMpq = (HANDLE)ha;
+ return (nError == ERROR_SUCCESS);
+}
diff --git a/src/SFileExtractFile.cpp b/src/SFileExtractFile.cpp
new file mode 100644
index 0000000..c8053ed
--- /dev/null
+++ b/src/SFileExtractFile.cpp
@@ -0,0 +1,67 @@
+/*****************************************************************************/
+/* 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;
+ int nError = ERROR_SUCCESS;
+
+ // Open the MPQ file
+ if(nError == ERROR_SUCCESS)
+ {
+ if(!SFileOpenFileEx(hMpq, szToExtract, dwSearchScope, &hMpqFile))
+ nError = GetLastError();
+ }
+
+ // Create the local file
+ if(nError == ERROR_SUCCESS)
+ {
+ pLocalFile = FileStream_CreateFile(szExtracted, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
+ if(pLocalFile == NULL)
+ nError = GetLastError();
+ }
+
+ // Copy the file's content
+ if(nError == ERROR_SUCCESS)
+ {
+ char szBuffer[0x1000];
+ DWORD dwTransferred;
+
+ for(;;)
+ {
+ // dwTransferred is only set to nonzero if something has been read.
+ // nError can be ERROR_SUCCESS or ERROR_HANDLE_EOF
+ if(!SFileReadFile(hMpqFile, szBuffer, sizeof(szBuffer), &dwTransferred, NULL))
+ nError = GetLastError();
+ if(nError == ERROR_HANDLE_EOF)
+ nError = ERROR_SUCCESS;
+ if(dwTransferred == 0)
+ break;
+
+ // If something has been actually read, write it
+ if(!FileStream_Write(pLocalFile, NULL, szBuffer, dwTransferred))
+ nError = GetLastError();
+ }
+ }
+
+ // Close the files
+ if(hMpqFile != NULL)
+ SFileCloseFile(hMpqFile);
+ if(pLocalFile != NULL)
+ FileStream_Close(pLocalFile);
+ if(nError != ERROR_SUCCESS)
+ SetLastError(nError);
+ return (nError == ERROR_SUCCESS);
+}
diff --git a/src/SFileFindFile.cpp b/src/SFileFindFile.cpp
new file mode 100644
index 0000000..80aa6e1
--- /dev/null
+++ b/src/SFileFindFile.cpp
@@ -0,0 +1,446 @@
+/*****************************************************************************/
+/* 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"
+
+//-----------------------------------------------------------------------------
+// Defines
+
+#define LISTFILE_CACHE_SIZE 0x1000
+
+//-----------------------------------------------------------------------------
+// Private structure used for file search (search handle)
+
+struct TMPQSearch;
+typedef int (*MPQSEARCH)(TMPQSearch *, SFILE_FIND_DATA *);
+
+// 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 bool IsValidSearchHandle(TMPQSearch * hs)
+{
+ if(hs == NULL)
+ return false;
+
+ return IsValidMpqHandle(hs->ha);
+}
+
+bool CheckWildCard(const char * szString, const char * szWildCard)
+{
+ const char * szSubString;
+ int nSubStringLength;
+ int nMatchCount = 0;
+
+ // When the mask is empty, it never matches
+ if(szWildCard == NULL || *szWildCard == 0)
+ return false;
+
+ // If the wildcard contains just "*", then it always matches
+ if(szWildCard[0] == '*' && szWildCard[1] == 0)
+ return true;
+
+ // Do normal test
+ for(;;)
+ {
+ // If there is '?' in the wildcard, we skip one char
+ while(*szWildCard == '?')
+ {
+ szWildCard++;
+ szString++;
+ }
+
+ // If there is '*', means zero or more chars. We have to
+ // find the sequence after '*'
+ if(*szWildCard == '*')
+ {
+ // More stars is equal to one star
+ while(*szWildCard == '*' || *szWildCard == '?')
+ szWildCard++;
+
+ // If we found end of the wildcard, it's a match
+ if(*szWildCard == 0)
+ return true;
+
+ // Determine the length of the substring in szWildCard
+ szSubString = szWildCard;
+ while(*szSubString != 0 && *szSubString != '?' && *szSubString != '*')
+ szSubString++;
+ nSubStringLength = (int)(szSubString - szWildCard);
+ nMatchCount = 0;
+
+ // Now we have to find a substring in szString,
+ // that matches the substring in szWildCard
+ while(*szString != 0)
+ {
+ // Calculate match count
+ while(nMatchCount < nSubStringLength)
+ {
+ if(AsciiToUpperTable[(BYTE)szString[nMatchCount]] != AsciiToUpperTable[(BYTE)szWildCard[nMatchCount]])
+ break;
+ if(szString[nMatchCount] == 0)
+ break;
+ nMatchCount++;
+ }
+
+ // If the match count has reached substring length, we found a match
+ if(nMatchCount == nSubStringLength)
+ {
+ szWildCard += nMatchCount;
+ szString += nMatchCount;
+ break;
+ }
+
+ // No match, move to the next char in szString
+ nMatchCount = 0;
+ szString++;
+ }
+ }
+ else
+ {
+ // If we came to the end of the string, compare it to the wildcard
+ if(AsciiToUpperTable[(BYTE)*szString] != AsciiToUpperTable[(BYTE)*szWildCard])
+ return false;
+
+ // If we arrived to the end of the string, it's a match
+ if(*szString == 0)
+ return true;
+
+ // Otherwise, continue in comparing
+ szWildCard++;
+ szString++;
+ }
+ }
+}
+
+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->dwMaxFileCount
+ : 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->cchPatchPrefix != 0)
+ {
+ // If the patch prefix doesn't fit, we pretend that the file
+ // was there before and it will be skipped
+ if(_strnicmp(szRealFileName, ha->szPatchPrefix, ha->cchPatchPrefix))
+ return true;
+
+ szRealFileName += ha->cchPatchPrefix;
+ }
+
+ // Calculate the hash to the table
+ dwNameHash = HashString(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 = NULL;
+ TFileEntry * pTempEntry;
+ char szFileName[MAX_PATH];
+ LCID lcLocale = pFileEntry->lcLocale;
+
+ // Go while there are patches
+ while(ha->haPatch != NULL)
+ {
+ // Move to the patch archive
+ ha = ha->haPatch;
+
+ // Prepare the prefix for the file name
+ strcpy(szFileName, ha->szPatchPrefix);
+ strcat(szFileName, pFileEntry->szFileName);
+
+ // Try to find the file there
+ pTempEntry = GetFileEntryExact(ha, szFileName, lcLocale);
+ if(pTempEntry != NULL)
+ pPatchEntry = pTempEntry;
+ }
+
+ // Return the found patch entry
+ return pPatchEntry;
+}
+
+// Performs one MPQ search
+static int DoMPQSearch(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData)
+{
+ TMPQArchive * ha = hs->ha;
+ TFileEntry * pFileTableEnd;
+ TFileEntry * pPatchEntry;
+ TFileEntry * pFileEntry;
+ const char * szFileName;
+ HANDLE hFile;
+ char szPseudoName[20];
+ DWORD dwBlockIndex;
+ size_t nPrefixLength;
+
+ // Start searching with base MPQ
+ while(ha != NULL)
+ {
+ // Now parse the file entry table in order to get all files.
+ pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
+ pFileEntry = ha->pFileTable + hs->dwNextIndex;
+
+ // Get the length of the patch prefix (0 if none)
+ nPrefixLength = strlen(ha->szPatchPrefix);
+
+ // Parse the file table
+ while(pFileEntry < pFileTableEnd)
+ {
+ // Increment the next index for subsequent search
+ hs->dwNextIndex++;
+
+ // Is it a file and not a patch file?
+ if((pFileEntry->dwFlags & hs->dwFlagMask) == MPQ_FILE_EXISTS)
+ {
+ // Now we have to check if this file was not enumerated before
+ if(!FileWasFoundBefore(ha, hs, pFileEntry))
+ {
+ // Find a patch to this file
+ pPatchEntry = FindPatchEntry(ha, pFileEntry);
+ if(pPatchEntry == NULL)
+ pPatchEntry = pFileEntry;
+
+ // Prepare the block index
+ dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable);
+
+ // 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.
+ // This also generates the file name with a proper extension
+ sprintf(szPseudoName, "File%08u.xxx", dwBlockIndex);
+ if(SFileOpenFileEx((HANDLE)hs->ha, szPseudoName, SFILE_OPEN_BASE_FILE, &hFile))
+ {
+ szFileName = (pFileEntry->szFileName != NULL) ? pFileEntry->szFileName : szPseudoName;
+ SFileCloseFile(hFile);
+ }
+ }
+
+ // Check the file name against the wildcard
+ if(CheckWildCard(szFileName + nPrefixLength, hs->szSearchMask))
+ {
+ // Fill the found entry
+ lpFindFileData->dwHashIndex = pPatchEntry->dwHashIndex;
+ lpFindFileData->dwBlockIndex = dwBlockIndex;
+ lpFindFileData->dwFileSize = pPatchEntry->dwFileSize;
+ lpFindFileData->dwFileFlags = pPatchEntry->dwFlags;
+ lpFindFileData->dwCompSize = pPatchEntry->dwCmpSize;
+ lpFindFileData->lcLocale = pPatchEntry->lcLocale;
+
+ // Fill the filetime
+ lpFindFileData->dwFileTimeHi = (DWORD)(pPatchEntry->FileTime >> 32);
+ lpFindFileData->dwFileTimeLo = (DWORD)(pPatchEntry->FileTime);
+
+ // Fill the file name and plain file name
+ strcpy(lpFindFileData->cFileName, szFileName + nPrefixLength);
+ lpFindFileData->szPlainName = (char *)GetPlainFileNameA(lpFindFileData->cFileName);
+ return ERROR_SUCCESS;
+ }
+
+ }
+ }
+
+ pFileEntry++;
+ }
+
+ // 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 char * szListFile)
+{
+ TMPQArchive * ha = (TMPQArchive *)hMpq;
+ TMPQSearch * hs = NULL;
+ size_t nSize = 0;
+ int nError = ERROR_SUCCESS;
+
+ // Check for the valid parameters
+ if(!IsValidMpqHandle(ha))
+ nError = ERROR_INVALID_HANDLE;
+ if(szMask == NULL || lpFindFileData == NULL)
+ nError = 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(nError == ERROR_SUCCESS && szListFile != NULL && *szListFile != 0)
+ nError = SFileAddListFile((HANDLE)ha, szListFile);
+
+ // Allocate the structure for MPQ search
+ if(nError == ERROR_SUCCESS)
+ {
+ nSize = sizeof(TMPQSearch) + strlen(szMask) + 1;
+ if((hs = (TMPQSearch *)STORM_ALLOC(char, nSize)) == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Perform the first search
+ if(nError == 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
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+ }
+
+ // Perform first item searching
+ if(nError == ERROR_SUCCESS)
+ {
+ nError = DoMPQSearch(hs, lpFindFileData);
+ }
+
+ // Cleanup
+ if(nError != ERROR_SUCCESS)
+ {
+ FreeMPQSearch(hs);
+ SetLastError(nError);
+ }
+
+ // Return the result value
+ return (HANDLE)hs;
+}
+
+bool WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData)
+{
+ TMPQSearch * hs = (TMPQSearch *)hFind;
+ int nError = ERROR_SUCCESS;
+
+ // Check the parameters
+ if(!IsValidSearchHandle(hs))
+ nError = ERROR_INVALID_HANDLE;
+ if(lpFindFileData == NULL)
+ nError = ERROR_INVALID_PARAMETER;
+
+ if(nError == ERROR_SUCCESS)
+ nError = DoMPQSearch(hs, lpFindFileData);
+
+ if(nError != ERROR_SUCCESS)
+ SetLastError(nError);
+ return (nError == ERROR_SUCCESS);
+}
+
+bool WINAPI SFileFindClose(HANDLE hFind)
+{
+ TMPQSearch * hs = (TMPQSearch *)hFind;
+
+ // Check the parameters
+ if(!IsValidSearchHandle(hs))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return false;
+ }
+
+ FreeMPQSearch(hs);
+ return true;
+}
diff --git a/src/SFileListFile.cpp b/src/SFileListFile.cpp
new file mode 100644
index 0000000..2293403
--- /dev/null
+++ b/src/SFileListFile.cpp
@@ -0,0 +1,636 @@
+/*****************************************************************************/
+/* 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 <assert.h>
+
+//-----------------------------------------------------------------------------
+// Listfile entry structure
+
+#define CACHE_BUFFER_SIZE 0x1000 // Size of the cache buffer
+
+struct TListFileCache
+{
+ HANDLE hFile; // Stormlib file handle
+ char * szMask; // File mask
+ DWORD dwFileSize; // Total size of the cached file
+ DWORD dwFilePos; // Position of the cache in the file
+ BYTE * pBegin; // The begin of the listfile cache
+ BYTE * pPos;
+ BYTE * pEnd; // The last character in the file cache
+
+ BYTE Buffer[CACHE_BUFFER_SIZE]; // Listfile cache itself
+};
+
+//-----------------------------------------------------------------------------
+// Local functions (cache)
+
+static bool FreeListFileCache(TListFileCache * pCache)
+{
+ // Valid parameter check
+ if(pCache == NULL)
+ return false;
+
+ // Free all allocated buffers
+ if(pCache->hFile != NULL)
+ SFileCloseFile(pCache->hFile);
+ if(pCache->szMask != NULL)
+ STORM_FREE(pCache->szMask);
+ STORM_FREE(pCache);
+ return true;
+}
+
+static TListFileCache * CreateListFileCache(HANDLE hListFile, const char * szMask)
+{
+ TListFileCache * pCache = NULL;
+ DWORD dwBytesRead = 0;
+ int nError = ERROR_SUCCESS;
+
+ // Allocate cache for one file block
+ pCache = (TListFileCache *)STORM_ALLOC(TListFileCache, 1);
+ if(pCache == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+
+ // Clear the entire structure
+ if(nError == ERROR_SUCCESS)
+ {
+ memset(pCache, 0, sizeof(TListFileCache));
+ pCache->hFile = hListFile;
+
+ // Shall we allocate a mask?
+ if(szMask != NULL)
+ {
+ pCache->szMask = STORM_ALLOC(char, strlen(szMask) + 1);
+ if(pCache->szMask != NULL)
+ strcpy(pCache->szMask, szMask);
+ else
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+ }
+
+ // Initialize the file cache
+ if(nError == ERROR_SUCCESS)
+ {
+ pCache->dwFileSize = SFileGetFileSize(pCache->hFile, NULL);
+
+ // Fill the cache
+ SFileReadFile(pCache->hFile, pCache->Buffer, CACHE_BUFFER_SIZE, &dwBytesRead, NULL);
+ if(dwBytesRead == 0)
+ nError = GetLastError();
+ }
+
+ // Allocate pointers
+ if(nError == ERROR_SUCCESS)
+ {
+ pCache->pBegin =
+ pCache->pPos = &pCache->Buffer[0];
+ pCache->pEnd = pCache->pBegin + dwBytesRead;
+ }
+ else
+ {
+ FreeListFileCache(pCache);
+ SetLastError(nError);
+ pCache = NULL;
+ }
+
+ // Return the cache
+ return pCache;
+}
+
+// Reloads the cache. Returns number of characters
+// that has been loaded into the cache.
+static DWORD ReloadListFileCache(TListFileCache * pCache)
+{
+ DWORD dwBytesToRead;
+ DWORD dwBytesRead = 0;
+
+ // Only do something if the cache is empty
+ if(pCache->pPos >= pCache->pEnd)
+ {
+// __TryReadBlock:
+
+ // Move the file position forward
+ pCache->dwFilePos += CACHE_BUFFER_SIZE;
+ if(pCache->dwFilePos >= pCache->dwFileSize)
+ return 0;
+
+ // Get the number of bytes remaining
+ dwBytesToRead = pCache->dwFileSize - pCache->dwFilePos;
+ if(dwBytesToRead > CACHE_BUFFER_SIZE)
+ dwBytesToRead = CACHE_BUFFER_SIZE;
+
+ // Load the next data chunk to the cache
+ SFileSetFilePointer(pCache->hFile, pCache->dwFilePos, NULL, FILE_BEGIN);
+ SFileReadFile(pCache->hFile, pCache->Buffer, CACHE_BUFFER_SIZE, &dwBytesRead, NULL);
+
+ // If we didn't read anything, it might mean that the block
+ // of the file is not available (in case of partial MPQs).
+ // We stop reading the file at this point, because the rest
+ // of the listfile is unreliable
+ if(dwBytesRead == 0)
+ return 0;
+
+ // Set the buffer pointers
+ pCache->pBegin =
+ pCache->pPos = &pCache->Buffer[0];
+ pCache->pEnd = pCache->pBegin + dwBytesRead;
+ }
+
+ return dwBytesRead;
+}
+
+static size_t ReadListFileLine(TListFileCache * pCache, char * szLine, int nMaxChars)
+{
+ char * szLineBegin = szLine;
+ char * szLineEnd = szLine + nMaxChars - 1;
+ char * szExtraString = NULL;
+
+ // Skip newlines, spaces, tabs and another non-printable stuff
+ for(;;)
+ {
+ // If we need to reload the cache, do it
+ if(pCache->pPos == pCache->pEnd)
+ {
+ if(ReloadListFileCache(pCache) == 0)
+ break;
+ }
+
+ // If we found a non-whitespace character, stop
+ if(*pCache->pPos > 0x20)
+ break;
+
+ // Skip the character
+ pCache->pPos++;
+ }
+
+ // Copy the remaining characters
+ while(szLine < szLineEnd)
+ {
+ // If we need to reload the cache, do it now and resume copying
+ if(pCache->pPos == pCache->pEnd)
+ {
+ if(ReloadListFileCache(pCache) == 0)
+ break;
+ }
+
+ // If we have found a newline, stop loading
+ if(*pCache->pPos == 0x0D || *pCache->pPos == 0x0A)
+ break;
+
+ // Blizzard listfiles can also contain information about patch:
+ // Pass1\Files\MacOS\unconditional\user\Background Downloader.app\Contents\Info.plist~Patch(Data#frFR#base-frFR,1326)
+ if(*pCache->pPos == '~')
+ szExtraString = szLine;
+
+ // Copy the character
+ *szLine++ = *pCache->pPos++;
+ }
+
+ // Terminate line with zero
+ *szLine = 0;
+
+ // If there was extra string after the file name, clear it
+ if(szExtraString != NULL)
+ {
+ if(szExtraString[0] == '~' && szExtraString[1] == 'P')
+ {
+ szLine = szExtraString;
+ *szExtraString = 0;
+ }
+ }
+
+ // Return the length of the line
+ return (szLine - szLineBegin);
+}
+
+static int CompareFileNodes(const void * p1, const void * p2)
+{
+ char * szFileName1 = *(char **)p1;
+ char * szFileName2 = *(char **)p2;
+
+ return _stricmp(szFileName1, szFileName2);
+}
+
+static int WriteListFileLine(
+ TMPQFile * hf,
+ const char * szLine)
+{
+ char szNewLine[2] = {0x0D, 0x0A};
+ size_t nLength = strlen(szLine);
+ int nError;
+
+ nError = SFileAddFile_Write(hf, szLine, (DWORD)nLength, MPQ_COMPRESSION_ZLIB);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ return SFileAddFile_Write(hf, szNewLine, sizeof(szNewLine), MPQ_COMPRESSION_ZLIB);
+}
+
+//-----------------------------------------------------------------------------
+// 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 int SListFileCreateNodeForAllLocales(TMPQArchive * ha, const char * szFileName)
+{
+ TMPQHeader * pHeader = ha->pHeader;
+ TFileEntry * pFileEntry;
+ TMPQHash * pFirstHash;
+ TMPQHash * pHash;
+ bool bNameEntryCreated = false;
+
+ // If we have HET table, use that one
+ if(ha->pHetTable != NULL)
+ {
+ pFileEntry = GetFileEntryAny(ha, szFileName);
+ if(pFileEntry != NULL)
+ {
+ // Allocate file name for the file entry
+ AllocateFileName(pFileEntry, szFileName);
+ bNameEntryCreated = true;
+ }
+
+ return ERROR_SUCCESS;
+ }
+
+ // If we have hash table, we use it
+ if(bNameEntryCreated == false && ha->pHashTable != NULL)
+ {
+ // Look for the first hash table entry for the file
+ pFirstHash = pHash = GetFirstHashEntry(ha, szFileName);
+
+ // Go while we found something
+ while(pHash != NULL)
+ {
+ // Is it a valid file table index ?
+ if(pHash->dwBlockIndex < pHeader->dwBlockTableSize)
+ {
+ // Allocate file name for the file entry
+ AllocateFileName(ha->pFileTable + pHash->dwBlockIndex, szFileName);
+ bNameEntryCreated = true;
+ }
+
+ // Now find the next language version of the file
+ pHash = GetNextHashEntry(ha, pFirstHash, pHash);
+ }
+ }
+
+ return ERROR_CAN_NOT_COMPLETE;
+}
+
+// Saves the whole listfile into the MPQ.
+int SListFileSaveToMpq(TMPQArchive * ha)
+{
+ TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
+ TFileEntry * pFileEntry;
+ TMPQFile * hf = NULL;
+ char * szPrevItem;
+ char ** SortTable = NULL;
+ DWORD dwFileSize = 0;
+ size_t nFileNodes = 0;
+ size_t i;
+ int nError = ERROR_SUCCESS;
+
+ // Allocate the table for sorting listfile
+ SortTable = STORM_ALLOC(char*, ha->dwFileTableSize);
+ if(SortTable == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ // Construct the sort table
+ // Note: in MPQs with multiple locale versions of the same file,
+ // this code causes adding multiple listfile entries.
+ // Since those MPQs were last time used in Starcraft,
+ // we leave it as it is.
+ for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
+ {
+ // Only take existing items
+ if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) && pFileEntry->szFileName != NULL)
+ {
+ // Ignore pseudo-names
+ if(!IsPseudoFileName(pFileEntry->szFileName, NULL) && !IsInternalMpqFileName(pFileEntry->szFileName))
+ {
+ SortTable[nFileNodes++] = pFileEntry->szFileName;
+ }
+ }
+ }
+
+ // Sort the table
+ qsort(SortTable, nFileNodes, sizeof(char *), CompareFileNodes);
+
+ // Now parse the table of file names again - remove duplicates
+ // and count file size.
+ if(nFileNodes != 0)
+ {
+ // Count the 0-th item
+ dwFileSize += (DWORD)strlen(SortTable[0]) + 2;
+ szPrevItem = SortTable[0];
+
+ // Count all next items
+ for(i = 1; i < nFileNodes; i++)
+ {
+ // If the item is the same like the last one, skip it
+ if(_stricmp(SortTable[i], szPrevItem))
+ {
+ dwFileSize += (DWORD)strlen(SortTable[i]) + 2;
+ szPrevItem = SortTable[i];
+ }
+ }
+
+ // Determine the flags for (listfile)
+ if(ha->dwFileFlags1 == 0)
+ ha->dwFileFlags1 = GetDefaultSpecialFileFlags(ha, dwFileSize);
+
+ // Create the listfile in the MPQ
+ nError = SFileAddFile_Init(ha, LISTFILE_NAME,
+ 0,
+ dwFileSize,
+ LANG_NEUTRAL,
+ ha->dwFileFlags1 | MPQ_FILE_REPLACEEXISTING,
+ &hf);
+ // Add all file names
+ if(nError == ERROR_SUCCESS)
+ {
+ // Each name is followed by newline ("\x0D\x0A")
+ szPrevItem = SortTable[0];
+ nError = WriteListFileLine(hf, SortTable[0]);
+
+ // Count all next items
+ for(i = 1; i < nFileNodes; i++)
+ {
+ // If the item is the same like the last one, skip it
+ if(_stricmp(SortTable[i], szPrevItem))
+ {
+ WriteListFileLine(hf, SortTable[i]);
+ szPrevItem = SortTable[i];
+ }
+ }
+ }
+ }
+ else
+ {
+ // Create the listfile in the MPQ
+ dwFileSize = (DWORD)strlen(LISTFILE_NAME) + 2;
+ nError = SFileAddFile_Init(ha, LISTFILE_NAME,
+ 0,
+ dwFileSize,
+ LANG_NEUTRAL,
+ MPQ_FILE_ENCRYPTED | MPQ_FILE_COMPRESS | MPQ_FILE_REPLACEEXISTING,
+ &hf);
+
+ // Just add "(listfile)" there
+ if(nError == ERROR_SUCCESS)
+ {
+ WriteListFileLine(hf, LISTFILE_NAME);
+ }
+ }
+
+ // Finalize the file in the MPQ
+ if(hf != NULL)
+ {
+ SFileAddFile_Finish(hf);
+ }
+
+ // Free buffers
+ if(nError == ERROR_SUCCESS)
+ ha->dwFlags &= ~MPQ_FLAG_INV_LISTFILE;
+ if(SortTable != NULL)
+ STORM_FREE(SortTable);
+ return nError;
+}
+
+static int SFileAddArbitraryListFile(
+ TMPQArchive * ha,
+ HANDLE hListFile)
+{
+ TListFileCache * pCache = NULL;
+ size_t nLength;
+ char szFileName[MAX_PATH];
+ int nError = ERROR_SUCCESS;
+
+ // Create the listfile cache for that file
+ pCache = CreateListFileCache(hListFile, NULL);
+ if(pCache == NULL)
+ nError = GetLastError();
+
+ // Load the node list. Add the node for every locale in the archive
+ if(nError == ERROR_SUCCESS)
+ {
+ while((nLength = ReadListFileLine(pCache, szFileName, sizeof(szFileName))) > 0)
+ SListFileCreateNodeForAllLocales(ha, szFileName);
+ pCache->hFile = NULL;
+ }
+
+ // Delete the cache
+ if(pCache != NULL)
+ FreeListFileCache(pCache);
+ return nError;
+}
+
+static int SFileAddExternalListFile(
+ TMPQArchive * ha,
+ HANDLE hMpq,
+ const char * szListFile)
+{
+ HANDLE hListFile;
+ int nError = ERROR_SUCCESS;
+
+ // Open the external list file
+ if(SFileOpenFileEx(hMpq, szListFile, SFILE_OPEN_LOCAL_FILE, &hListFile))
+ {
+ // Add the data from the listfile to MPQ
+ nError = SFileAddArbitraryListFile(ha, hListFile);
+ SFileCloseFile(hListFile);
+ }
+ return nError;
+}
+
+static int SFileAddInternalListFile(
+ TMPQArchive * ha,
+ HANDLE hMpq)
+{
+ TMPQArchive * haMpq = (TMPQArchive *)hMpq;
+ TMPQHash * pFirstHash;
+ TMPQHash * pHash;
+ HANDLE hListFile;
+ LCID lcSaveLocale = lcFileLocale;
+ int nError = ERROR_SUCCESS;
+
+ // If there is hash table, we need to support multiple listfiles
+ // with different locales (BrooDat.mpq)
+ if(haMpq->pHashTable != NULL)
+ {
+ pFirstHash = pHash = GetFirstHashEntry(haMpq, LISTFILE_NAME);
+ while(nError == ERROR_SUCCESS && pHash != NULL)
+ {
+ // Set the prefered locale to that from list file
+ SFileSetLocale(pHash->lcLocale);
+ if(SFileOpenFileEx(hMpq, LISTFILE_NAME, 0, &hListFile))
+ {
+ // Add the data from the listfile to MPQ
+ nError = SFileAddArbitraryListFile(ha, hListFile);
+ SFileCloseFile(hListFile);
+ }
+
+ // Restore the original locale
+ SFileSetLocale(lcSaveLocale);
+
+ // Move to the next hash
+ pHash = GetNextHashEntry(haMpq, pFirstHash, pHash);
+ }
+ }
+ else
+ {
+ // Open the external list file
+ if(SFileOpenFileEx(hMpq, LISTFILE_NAME, 0, &hListFile))
+ {
+ // Add the data from the listfile to MPQ
+ // The function also closes the listfile handle
+ nError = SFileAddArbitraryListFile(ha, hListFile);
+ SFileCloseFile(hListFile);
+ }
+ }
+
+ // Return the result of the operation
+ return nError;
+}
+
+//-----------------------------------------------------------------------------
+// File functions
+
+// Adds a listfile into the MPQ archive.
+int WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile)
+{
+ TMPQArchive * ha = (TMPQArchive *)hMpq;
+ int nError = ERROR_SUCCESS;
+
+ // Add the listfile for each MPQ in the patch chain
+ while(ha != NULL)
+ {
+ if(szListFile != NULL)
+ SFileAddExternalListFile(ha, hMpq, szListFile);
+ else
+ 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 nError;
+}
+
+//-----------------------------------------------------------------------------
+// Enumerating files in listfile
+
+HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData)
+{
+ TListFileCache * pCache = NULL;
+ HANDLE hListFile;
+ size_t nLength = 0;
+ DWORD dwSearchScope = SFILE_OPEN_LOCAL_FILE;
+ int nError = ERROR_SUCCESS;
+
+ // Initialize the structure with zeros
+ memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA));
+
+ // If the szListFile is NULL, it means we have to open internal listfile
+ if(szListFile == NULL)
+ {
+ // Use SFILE_OPEN_ANY_LOCALE for listfile. This will allow us to load
+ // the listfile even if there is only non-neutral version of the listfile in the MPQ
+ dwSearchScope = SFILE_OPEN_ANY_LOCALE;
+ szListFile = LISTFILE_NAME;
+ }
+
+ // Open the local/internal listfile
+ if(!SFileOpenFileEx(hMpq, szListFile, dwSearchScope, &hListFile))
+ nError = GetLastError();
+
+ // Load the listfile to cache
+ if(nError == ERROR_SUCCESS)
+ {
+ pCache = CreateListFileCache(hListFile, szMask);
+ if(pCache == NULL)
+ nError = GetLastError();
+ }
+
+ // Perform file search
+ if(nError == ERROR_SUCCESS)
+ {
+ for(;;)
+ {
+ // Read the (next) line
+ nLength = ReadListFileLine(pCache, lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName));
+ if(nLength == 0)
+ {
+ nError = ERROR_NO_MORE_FILES;
+ break;
+ }
+
+ // If some mask entered, check it
+ if(CheckWildCard(lpFindFileData->cFileName, pCache->szMask))
+ break;
+ }
+ }
+
+ // Cleanup & exit
+ if(nError != ERROR_SUCCESS)
+ {
+ memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA));
+ FreeListFileCache(pCache);
+ SetLastError(nError);
+ pCache = NULL;
+ }
+ return (HANDLE)pCache;
+}
+
+bool WINAPI SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData)
+{
+ TListFileCache * pCache = (TListFileCache *)hFind;
+ size_t nLength;
+ bool bResult = false;
+ int nError = ERROR_SUCCESS;
+
+ for(;;)
+ {
+ // Read the (next) line
+ nLength = ReadListFileLine(pCache, lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName));
+ if(nLength == 0)
+ {
+ nError = ERROR_NO_MORE_FILES;
+ break;
+ }
+
+ // If some mask entered, check it
+ if(CheckWildCard(lpFindFileData->cFileName, pCache->szMask))
+ {
+ bResult = true;
+ break;
+ }
+ }
+
+ if(nError != ERROR_SUCCESS)
+ SetLastError(nError);
+ return bResult;
+}
+
+bool WINAPI SListFileFindClose(HANDLE hFind)
+{
+ return FreeListFileCache((TListFileCache *)hFind);
+}
+
diff --git a/src/SFileOpenArchive.cpp b/src/SFileOpenArchive.cpp
new file mode 100644
index 0000000..c385019
--- /dev/null
+++ b/src/SFileOpenArchive.cpp
@@ -0,0 +1,480 @@
+/*****************************************************************************/
+/* SFileOpenArchive.cpp Copyright Ladislav Zezula 1999 */
+/* */
+/* Author : Ladislav Zezula */
+/* E-mail : ladik@zezula.net */
+/* WWW : www.zezula.net */
+/*---------------------------------------------------------------------------*/
+/* Archive functions of Storm.dll */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* xx.xx.xx 1.00 Lad The first version of SFileOpenArchive.cpp */
+/* 19.11.03 1.01 Dan Big endian handling */
+/*****************************************************************************/
+
+#define __STORMLIB_SELF__
+#include "StormLib.h"
+#include "StormCommon.h"
+
+/*****************************************************************************/
+/* Local functions */
+/*****************************************************************************/
+
+static bool IsAviFile(void * pvFileBegin)
+{
+ LPDWORD AviHeader = (DWORD *)pvFileBegin;
+ DWORD DwordValue0 = BSWAP_INT32_UNSIGNED(AviHeader[0]);
+ DWORD DwordValue2 = BSWAP_INT32_UNSIGNED(AviHeader[2]);
+ DWORD DwordValue3 = BSWAP_INT32_UNSIGNED(AviHeader[3]);
+
+ // Test for 'RIFF', 'AVI ' or 'LIST'
+ return (DwordValue0 == 0x46464952 && DwordValue2 == 0x20495641 && DwordValue3 == 0x5453494C);
+}
+
+static TFileBitmap * CreateFileBitmap(TMPQArchive * ha, TMPQBitmap * pMpqBitmap, bool bFileIsComplete)
+{
+ TFileBitmap * pBitmap;
+ size_t nLength;
+
+ // Calculate the length of the bitmap in blocks and in bytes
+ nLength = (size_t)(((ha->pHeader->ArchiveSize64 - 1) / pMpqBitmap->dwBlockSize) + 1);
+ nLength = (size_t)(((nLength - 1) / 8) + 1);
+
+ // Allocate the file bitmap
+ pBitmap = (TFileBitmap *)STORM_ALLOC(BYTE, sizeof(TFileBitmap) + nLength);
+ if(pBitmap != NULL)
+ {
+ // Fill the structure
+ pBitmap->StartOffset = ha->MpqPos;
+ pBitmap->EndOffset = ha->MpqPos + ha->pHeader->ArchiveSize64;
+ pBitmap->IsComplete = bFileIsComplete ? 1 : 0;
+ pBitmap->BitmapSize = (DWORD)nLength;
+ pBitmap->BlockSize = pMpqBitmap->dwBlockSize;
+ pBitmap->Reserved = 0;
+
+ // Copy the file bitmap
+ memcpy((pBitmap + 1), (pMpqBitmap + 1), nLength);
+ }
+
+ return pBitmap;
+}
+
+// This function gets the right positions of the hash table and the block table.
+static int VerifyMpqTablePositions(TMPQArchive * ha, ULONGLONG FileSize)
+{
+ TMPQHeader * pHeader = ha->pHeader;
+ ULONGLONG ByteOffset;
+
+ // 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 = ha->MpqPos + 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 = ha->MpqPos + 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;
+}
+
+
+/*****************************************************************************/
+/* Public functions */
+/*****************************************************************************/
+
+//-----------------------------------------------------------------------------
+// SFileGetLocale and SFileSetLocale
+// Set the locale for all newly opened files
+
+LCID WINAPI SFileGetLocale()
+{
+ return lcFileLocale;
+}
+
+LCID WINAPI SFileSetLocale(LCID lcNewLocale)
+{
+ lcFileLocale = lcNewLocale;
+ return 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)
+{
+ TFileStream * pStream = NULL; // Open file stream
+ TMPQArchive * ha = NULL; // Archive handle
+ TFileEntry * pFileEntry;
+ ULONGLONG FileSize = 0; // Size of the file
+ int nError = ERROR_SUCCESS;
+
+ // Verify the parameters
+ if(szMpqName == NULL || *szMpqName == 0 || phMpq == NULL)
+ nError = ERROR_INVALID_PARAMETER;
+
+ // One time initialization of MPQ cryptography
+ InitializeMpqCryptography();
+ dwPriority = dwPriority;
+
+ // Open the MPQ archive file
+ if(nError == ERROR_SUCCESS)
+ {
+ // Initialize the stream
+ pStream = FileStream_OpenFile(szMpqName, (dwFlags & STREAM_OPTIONS_MASK));
+ if(pStream == NULL)
+ nError = GetLastError();
+ }
+
+ // Allocate the MPQhandle
+ if(nError == ERROR_SUCCESS)
+ {
+ FileStream_GetSize(pStream, &FileSize);
+ if((ha = STORM_ALLOC(TMPQArchive, 1)) == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Initialize handle structure and allocate structure for MPQ header
+ if(nError == ERROR_SUCCESS)
+ {
+ memset(ha, 0, sizeof(TMPQArchive));
+ ha->pStream = pStream;
+ pStream = NULL;
+
+ // Remember if the archive is open for write
+ if(FileStream_IsReadOnly(ha->pStream))
+ ha->dwFlags |= MPQ_FLAG_READ_ONLY;
+
+ // Also remember if we shall check sector CRCs when reading file
+ if(dwFlags & MPQ_OPEN_CHECK_SECTOR_CRC)
+ ha->dwFlags |= MPQ_FLAG_CHECK_SECTOR_CRC;
+ }
+
+ // Find the offset of MPQ header within the file
+ if(nError == ERROR_SUCCESS)
+ {
+ ULONGLONG SearchPos = 0;
+ DWORD dwHeaderID;
+
+ while(SearchPos < FileSize)
+ {
+ DWORD dwBytesAvailable = MPQ_HEADER_SIZE_V4;
+
+ // Cut the bytes available, if needed
+ if((FileSize - SearchPos) < MPQ_HEADER_SIZE_V4)
+ dwBytesAvailable = (DWORD)(FileSize - SearchPos);
+
+ // Read the eventual MPQ header
+ if(!FileStream_Read(ha->pStream, &SearchPos, ha->HeaderData, dwBytesAvailable))
+ {
+ nError = GetLastError();
+ break;
+ }
+
+ // There are AVI files from Warcraft III with 'MPQ' extension.
+ if(SearchPos == 0 && IsAviFile(ha->HeaderData))
+ {
+ nError = ERROR_AVI_FILE;
+ break;
+ }
+
+ // If there is the MPQ user data signature, process it
+ dwHeaderID = BSWAP_INT32_UNSIGNED(*(LPDWORD)ha->HeaderData);
+ if(dwHeaderID == ID_MPQ_USERDATA && ha->pUserData == NULL)
+ {
+ // Ignore the MPQ user data completely if the caller wants to open the MPQ as V1.0
+ if((dwFlags & MPQ_OPEN_FORCE_MPQ_V1) == 0)
+ {
+ // Fill the user data header
+ ha->pUserData = &ha->UserData;
+ memcpy(ha->pUserData, ha->HeaderData, sizeof(TMPQUserData));
+ BSWAP_TMPQUSERDATA(ha->pUserData);
+
+ // Remember the position of the user data and continue search
+ ha->UserDataPos = SearchPos;
+ SearchPos += ha->pUserData->dwHeaderOffs;
+ continue;
+ }
+ }
+
+ // There must be MPQ header signature
+ if(dwHeaderID == ID_MPQ)
+ {
+ // Save the position where the MPQ header has been found
+ if(ha->pUserData == NULL)
+ ha->UserDataPos = SearchPos;
+ ha->pHeader = (TMPQHeader *)ha->HeaderData;
+ ha->MpqPos = SearchPos;
+
+ // Now convert the header to version 4
+ BSWAP_TMPQHEADER(ha->pHeader);
+ nError = ConvertMpqHeaderToFormat4(ha, FileSize, dwFlags);
+ break;
+ }
+
+ // Move to the next possible offset
+ SearchPos += 0x200;
+ }
+
+ // If we haven't found MPQ header in the file, it's an error
+ if(ha->pHeader == NULL)
+ nError = ERROR_BAD_FORMAT;
+ }
+
+ // Fix table positions according to format
+ if(nError == 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 probably 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;
+ }
+
+ // 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;
+
+ // 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
+ nError = VerifyMpqTablePositions(ha, FileSize);
+ }
+
+ // Check if the MPQ has data bitmap. If yes, we can verify if the MPQ is complete
+ if(nError == ERROR_SUCCESS && ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_4)
+ {
+ TFileBitmap * pBitmap;
+ bool bFileIsComplete = true;
+
+ LoadMpqDataBitmap(ha, FileSize, &bFileIsComplete);
+ if(ha->pBitmap != NULL && bFileIsComplete == false)
+ {
+ // Convert the MPQ bitmap to the file bitmap
+ pBitmap = CreateFileBitmap(ha, ha->pBitmap, bFileIsComplete);
+
+ // Set the data bitmap into the file stream for additional checks
+ FileStream_SetBitmap(ha->pStream, pBitmap);
+ ha->dwFlags |= MPQ_FLAG_READ_ONLY;
+ }
+ }
+
+ // 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(nError == ERROR_SUCCESS)
+ {
+ nError = 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(nError == ERROR_SUCCESS)
+ {
+ nError = BuildFileTable(ha, FileSize);
+ }
+
+ // Verify the file table, if no kind of protection was detected
+ if(nError == ERROR_SUCCESS && (ha->dwFlags & MPQ_FLAG_PROTECTED) == 0)
+ {
+ TFileEntry * pFileTableEnd = ha->pFileTable + ha->pHeader->dwBlockTableSize;
+// ULONGLONG ArchiveSize = 0;
+ ULONGLONG RawFilePos;
+
+ // Parse all file entries
+ for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++)
+ {
+ // If that file entry is valid, check the file position
+ if(pFileEntry->dwFlags & MPQ_FILE_EXISTS)
+ {
+ // Get the 64-bit file position,
+ // relative to the begin of the file
+ RawFilePos = ha->MpqPos + pFileEntry->ByteOffset;
+
+ // Begin of the file must be within range
+ if(RawFilePos > FileSize)
+ {
+ nError = ERROR_FILE_CORRUPT;
+ break;
+ }
+
+ // End of the file must be within range
+ RawFilePos += pFileEntry->dwCmpSize;
+ if(RawFilePos > FileSize)
+ {
+ nError = ERROR_FILE_CORRUPT;
+ break;
+ }
+
+ // Also, we remember end of the file
+// if(RawFilePos > ArchiveSize)
+// ArchiveSize = RawFilePos;
+ }
+ }
+ }
+
+ // Load the internal listfile and include it to the file table
+ if(nError == ERROR_SUCCESS && (dwFlags & MPQ_OPEN_NO_LISTFILE) == 0)
+ {
+ // Save the flags for (listfile)
+ pFileEntry = GetFileEntryLocale(ha, LISTFILE_NAME, LANG_NEUTRAL);
+ if(pFileEntry != NULL)
+ ha->dwFileFlags1 = pFileEntry->dwFlags;
+
+ // Ignore result of the operation. (listfile) is optional.
+ SFileAddListFile((HANDLE)ha, NULL);
+ }
+
+ // Load the "(attributes)" file and merge it to the file table
+ if(nError == ERROR_SUCCESS && (dwFlags & MPQ_OPEN_NO_ATTRIBUTES) == 0)
+ {
+ // Save the flags for (attributes)
+ pFileEntry = GetFileEntryLocale(ha, ATTRIBUTES_NAME, LANG_NEUTRAL);
+ if(pFileEntry != NULL)
+ ha->dwFileFlags2 = pFileEntry->dwFlags;
+
+ // Ignore result of the operation. (attributes) is optional.
+ SAttrLoadAttributes(ha);
+ }
+
+ // Cleanup and exit
+ if(nError != ERROR_SUCCESS)
+ {
+ FileStream_Close(pStream);
+ FreeMPQArchive(ha);
+ SetLastError(nError);
+ ha = NULL;
+ }
+
+ *phMpq = ha;
+ return (nError == ERROR_SUCCESS);
+}
+
+//-----------------------------------------------------------------------------
+// SFileGetArchiveBitmap
+
+bool WINAPI SFileGetArchiveBitmap(HANDLE hMpq, TFileBitmap * pBitmap, DWORD Length, LPDWORD LengthNeeded)
+{
+ TMPQArchive * ha = (TMPQArchive *)hMpq;
+
+ return FileStream_GetBitmap(ha->pStream, pBitmap, Length, LengthNeeded);
+}
+
+//-----------------------------------------------------------------------------
+// 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 = (TMPQArchive *)hMpq;
+ int nResultError = ERROR_SUCCESS;
+ int nError;
+
+ // Do nothing if 'hMpq' is bad parameter
+ if(!IsValidMpqHandle(ha))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return false;
+ }
+
+ // If the (listfile) has been invalidated, save it
+ if(ha->dwFlags & MPQ_FLAG_INV_LISTFILE)
+ {
+ nError = SListFileSaveToMpq(ha);
+ if(nError != ERROR_SUCCESS)
+ nResultError = nError;
+ }
+
+ // If the (attributes) has been invalidated, save it
+ if(ha->dwFlags & MPQ_FLAG_INV_ATTRIBUTES)
+ {
+ nError = SAttrFileSaveToMpq(ha);
+ if(nError != ERROR_SUCCESS)
+ nResultError = nError;
+ }
+
+ // Save HET table, BET table, hash table, block table, hi-block table
+ if(ha->dwFlags & MPQ_FLAG_CHANGED)
+ {
+ nError = SaveMPQTables(ha);
+ if(nError != ERROR_SUCCESS)
+ nResultError = nError;
+ }
+
+ // Return the error
+ if(nResultError != ERROR_SUCCESS)
+ SetLastError(nResultError);
+ return (nResultError == ERROR_SUCCESS);
+}
+
+//-----------------------------------------------------------------------------
+// bool SFileCloseArchive(HANDLE hMpq);
+//
+
+bool WINAPI SFileCloseArchive(HANDLE hMpq)
+{
+ TMPQArchive * ha = (TMPQArchive *)hMpq;
+ bool bResult;
+
+ // Flush all unsaved data to the storage
+ bResult = SFileFlushArchive(hMpq);
+
+ // Free all memory used by MPQ archive
+ FreeMPQArchive(ha);
+ return bResult;
+}
+
diff --git a/src/SFileOpenFileEx.cpp b/src/SFileOpenFileEx.cpp
new file mode 100644
index 0000000..9fe77a7
--- /dev/null
+++ b/src/SFileOpenFileEx.cpp
@@ -0,0 +1,473 @@
+/*****************************************************************************/
+/* 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 bool OpenLocalFile(const char * szFileName, HANDLE * phFile)
+{
+ TFileStream * pStream;
+ TMPQFile * hf = NULL;
+
+ // We have to convert the local file name to UNICODE, if needed
+#ifdef _UNICODE
+ TCHAR szFileNameT[MAX_PATH];
+ int i;
+
+ for(i = 0; szFileName[i] != 0; i++)
+ szFileNameT[i] = szFileName[i];
+ szFileNameT[i] = 0;
+ pStream = FileStream_OpenFile(szFileNameT, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
+
+#else
+ pStream = FileStream_OpenFile(szFileName, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
+#endif
+
+ if(pStream != NULL)
+ {
+ // Allocate and initialize file handle
+ hf = CreateMpqFile(NULL);
+ if(hf != NULL)
+ {
+ hf->pStream = pStream;
+ *phFile = hf;
+ return true;
+ }
+ else
+ {
+ FileStream_Close(pStream);
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ }
+ }
+ *phFile = NULL;
+ return false;
+}
+
+bool OpenPatchedFile(HANDLE hMpq, const char * szFileName, DWORD dwReserved, HANDLE * phFile)
+{
+ TMPQArchive * ha = (TMPQArchive *)hMpq;
+ TMPQFile * hfPatch; // Pointer to patch file
+ TMPQFile * hfBase = NULL; // Pointer to base open file
+ TMPQFile * hfLast = NULL; // The highest file in the chain that is not patch file
+ TMPQFile * hf = NULL;
+ HANDLE hPatchFile;
+ char szPatchFileName[MAX_PATH];
+
+ // Keep this flag here for future updates
+ dwReserved = dwReserved;
+
+ // First of all, try to open the original version of the file in any of the patch chain
+ while(ha != NULL)
+ {
+ // Construct the name of the patch file
+ strcpy(szPatchFileName, ha->szPatchPrefix);
+ strcpy(&szPatchFileName[ha->cchPatchPrefix], szFileName);
+ if(SFileOpenFileEx((HANDLE)ha, szPatchFileName, SFILE_OPEN_BASE_FILE, (HANDLE *)&hfBase))
+ {
+ // The file must be a base file, i.e. without MPQ_FILE_PATCH_FILE
+ if((hfBase->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0)
+ {
+ hf = hfLast = hfBase;
+ break;
+ }
+
+ SFileCloseFile((HANDLE)hfBase);
+ }
+
+ // Move to the next file in the patch chain
+ ha = ha->haPatch;
+ }
+
+ // If we couldn't find the file in any of the patches, it doesn't exist
+ if(hf == NULL)
+ {
+ SetLastError(ERROR_FILE_NOT_FOUND);
+ return false;
+ }
+
+ // Now keep going in the patch chain and open every patch file that is there
+ for(ha = ha->haPatch; ha != NULL; ha = ha->haPatch)
+ {
+ // Construct patch file name
+ strcpy(szPatchFileName, ha->szPatchPrefix);
+ strcpy(&szPatchFileName[ha->cchPatchPrefix], szFileName);
+ if(SFileOpenFileEx((HANDLE)ha, szPatchFileName, SFILE_OPEN_BASE_FILE, &hPatchFile))
+ {
+ // Remember the new version
+ hfPatch = (TMPQFile *)hPatchFile;
+
+ // If we encountered a full replacement of the file,
+ // we have to remember the highest full file
+ if((hfPatch->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0)
+ hfLast = hfPatch;
+
+ // Set current patch to base file and move on
+ hf->hfPatchFile = hfPatch;
+ hf = hfPatch;
+ }
+ }
+
+ // Now we need to free all files that are below the highest unpatched version
+ while(hfBase != hfLast)
+ {
+ TMPQFile * hfNext = hfBase->hfPatchFile;
+
+ // Free the file below
+ hfBase->hfPatchFile = NULL;
+ FreeMPQFile(hfBase);
+
+ // Move the base to the next file
+ hfBase = hfNext;
+ }
+
+ // Give the updated base MPQ
+ if(phFile != NULL)
+ *phFile = (HANDLE)hfBase;
+ return true;
+}
+
+/*****************************************************************************/
+/* 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.
+
+int WINAPI SFileEnumLocales(
+ HANDLE hMpq,
+ const char * szFileName,
+ LCID * plcLocales,
+ LPDWORD pdwMaxLocales,
+ DWORD dwSearchScope)
+{
+ TMPQArchive * ha = (TMPQArchive *)hMpq;
+ TFileEntry * pFileEntry;
+ TMPQHash * pFirstHash;
+ TMPQHash * pHash;
+ DWORD dwFileIndex = 0;
+ DWORD dwLocales = 0;
+
+ // Test the parameters
+ if(!IsValidMpqHandle(ha))
+ return ERROR_INVALID_HANDLE;
+ if(szFileName == NULL || *szFileName == 0)
+ return ERROR_INVALID_PARAMETER;
+ if(pdwMaxLocales == NULL)
+ return ERROR_INVALID_PARAMETER;
+
+ // Keep compiler happy
+ dwSearchScope = dwSearchScope;
+
+ // Parse hash table entries for all locales
+ if(!IsPseudoFileName(szFileName, &dwFileIndex))
+ {
+ // Calculate the number of locales
+ pFirstHash = pHash = GetFirstHashEntry(ha, szFileName);
+ while(pHash != NULL)
+ {
+ dwLocales++;
+ pHash = GetNextHashEntry(ha, pFirstHash, pHash);
+ }
+
+ // Test if there is enough space to copy the locales
+ if(*pdwMaxLocales < dwLocales)
+ {
+ *pdwMaxLocales = dwLocales;
+ return ERROR_INSUFFICIENT_BUFFER;
+ }
+
+ // Enum the locales
+ pFirstHash = pHash = GetFirstHashEntry(ha, szFileName);
+ while(pHash != NULL)
+ {
+ *plcLocales++ = pHash->lcLocale;
+ pHash = GetNextHashEntry(ha, pFirstHash, pHash);
+ }
+ }
+ else
+ {
+ // There must be space for 1 locale
+ if(*pdwMaxLocales < 1)
+ {
+ *pdwMaxLocales = 1;
+ return ERROR_INSUFFICIENT_BUFFER;
+ }
+
+ // For nameless access, always return 1 locale
+ pFileEntry = GetFileEntryByIndex(ha, dwFileIndex);
+ pHash = ha->pHashTable + pFileEntry->dwHashIndex;
+ *plcLocales = pHash->lcLocale;
+ dwLocales = 1;
+ }
+
+ // Give the caller the total number of found locales
+ *pdwMaxLocales = dwLocales;
+ return ERROR_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// SFileHasFile
+//
+// hMpq - Handle of opened MPQ archive
+// szFileName - Name of file to look for
+
+bool WINAPI SFileHasFile(HANDLE hMpq, const char * szFileName)
+{
+ TMPQArchive * ha = (TMPQArchive *)hMpq;
+ TFileEntry * pFileEntry;
+ DWORD dwFlagsToCheck = MPQ_FILE_EXISTS;
+ DWORD dwFileIndex = 0;
+ char szPatchFileName[MAX_PATH];
+ bool bIsPseudoName;
+ int nError = ERROR_SUCCESS;
+
+ if(!IsValidMpqHandle(ha))
+ nError = ERROR_INVALID_HANDLE;
+ if(szFileName == NULL || *szFileName == 0)
+ nError = ERROR_INVALID_PARAMETER;
+
+ // Prepare the file opening
+ if(nError == ERROR_SUCCESS)
+ {
+ // Different processing for pseudo-names
+ bIsPseudoName = IsPseudoFileName(szFileName, &dwFileIndex);
+
+ // Walk through the MPQ and all patches
+ while(ha != NULL)
+ {
+ // Verify presence of the file
+ pFileEntry = (bIsPseudoName == false) ? GetFileEntryLocale(ha, szFileName, lcFileLocale)
+ : GetFileEntryByIndex(ha, dwFileIndex);
+ // Verify the file flags
+ if(pFileEntry != NULL && (pFileEntry->dwFlags & dwFlagsToCheck) == MPQ_FILE_EXISTS)
+ return true;
+
+ // If this is patched archive, go to the patch
+ dwFlagsToCheck = MPQ_FILE_EXISTS | MPQ_FILE_PATCH_FILE;
+ ha = ha->haPatch;
+
+ // Prepare the patched file name
+ if(ha != NULL)
+ {
+ strcpy(szPatchFileName, ha->szPatchPrefix);
+ strcat(szPatchFileName, szFileName);
+ szFileName = szPatchFileName;
+ }
+ }
+
+ // Not found, sorry
+ nError = ERROR_FILE_NOT_FOUND;
+ }
+
+ // Cleanup
+ SetLastError(nError);
+ return false;
+}
+
+
+//-----------------------------------------------------------------------------
+// SFileOpenFileEx
+//
+// hMpq - Handle of opened MPQ archive
+// szFileName - Name of file to open
+// dwSearchScope - Where to search
+// phFile - Pointer to store opened file handle
+
+bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope, HANDLE * phFile)
+{
+ TMPQArchive * ha = (TMPQArchive *)hMpq;
+ TFileEntry * pFileEntry = NULL;
+ TMPQFile * hf = NULL;
+ DWORD dwFileIndex = 0;
+ bool bOpenByIndex = false;
+ int nError = ERROR_SUCCESS;
+
+ // Don't accept NULL pointer to file handle
+ if(phFile == NULL)
+ nError = ERROR_INVALID_PARAMETER;
+
+ // Prepare the file opening
+ if(nError == ERROR_SUCCESS)
+ {
+ switch(dwSearchScope)
+ {
+ case SFILE_OPEN_FROM_MPQ:
+ case SFILE_OPEN_BASE_FILE:
+
+ if(!IsValidMpqHandle(ha))
+ {
+ nError = ERROR_INVALID_HANDLE;
+ break;
+ }
+
+ if(szFileName == NULL || *szFileName == 0)
+ {
+ nError = ERROR_INVALID_PARAMETER;
+ break;
+ }
+
+ // Check the pseudo-file name
+ if(IsPseudoFileName(szFileName, &dwFileIndex))
+ {
+ pFileEntry = GetFileEntryByIndex(ha, dwFileIndex);
+ bOpenByIndex = true;
+ if(pFileEntry == NULL)
+ nError = ERROR_FILE_NOT_FOUND;
+ }
+ else
+ {
+ // If this MPQ is a patched archive, open the file as patched
+ if(ha->haPatch == NULL || dwSearchScope == SFILE_OPEN_BASE_FILE)
+ {
+ // Otherwise, open the file from *this* MPQ
+ pFileEntry = GetFileEntryLocale(ha, szFileName, lcFileLocale);
+ if(pFileEntry == NULL)
+ nError = ERROR_FILE_NOT_FOUND;
+ }
+ else
+ {
+ return OpenPatchedFile(hMpq, szFileName, 0, phFile);
+ }
+ }
+ 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 = GetFileEntryAny(ha, szFileName);
+ if(pFileEntry == NULL)
+ nError = ERROR_FILE_NOT_FOUND;
+ break;
+
+ case SFILE_OPEN_LOCAL_FILE:
+
+ if(szFileName == NULL || *szFileName == 0)
+ {
+ nError = ERROR_INVALID_PARAMETER;
+ break;
+ }
+
+ return OpenLocalFile(szFileName, phFile);
+
+ default:
+
+ // Don't accept any other value
+ nError = ERROR_INVALID_PARAMETER;
+ break;
+ }
+
+ // Quick return if something failed
+ if(nError != ERROR_SUCCESS)
+ {
+ SetLastError(nError);
+ return false;
+ }
+ }
+
+ // Test if the file was not already deleted.
+ if(nError == ERROR_SUCCESS)
+ {
+ if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0)
+ nError = ERROR_FILE_NOT_FOUND;
+ if(pFileEntry->dwFlags & ~MPQ_FILE_VALID_FLAGS)
+ nError = ERROR_NOT_SUPPORTED;
+ }
+
+ // Allocate file handle
+ if(nError == ERROR_SUCCESS)
+ {
+ if((hf = STORM_ALLOC(TMPQFile, 1)) == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Initialize file handle
+ if(nError == ERROR_SUCCESS)
+ {
+ memset(hf, 0, sizeof(TMPQFile));
+ hf->pFileEntry = pFileEntry;
+ hf->dwMagic = ID_MPQ_FILE;
+ hf->ha = ha;
+
+ hf->MpqFilePos = pFileEntry->ByteOffset;
+ hf->RawFilePos = ha->MpqPos + hf->MpqFilePos;
+ hf->dwDataSize = pFileEntry->dwFileSize;
+
+ // 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(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
+ {
+ // Try to auto-detect the file name
+ if(!SFileGetFileName(hf, NULL))
+ nError = GetLastError();
+ }
+ }
+
+ // If the file is actually a patch file, we have to load the patch file header
+ if(nError == ERROR_SUCCESS && pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE)
+ {
+ assert(hf->pPatchInfo == NULL);
+ nError = AllocatePatchInfo(hf, true);
+ }
+
+ // Cleanup
+ if(nError != ERROR_SUCCESS)
+ {
+ SetLastError(nError);
+ FreeMPQFile(hf);
+ }
+
+ *phFile = hf;
+ return (nError == ERROR_SUCCESS);
+}
+
+//-----------------------------------------------------------------------------
+// bool WINAPI SFileCloseFile(HANDLE hFile);
+
+bool WINAPI SFileCloseFile(HANDLE hFile)
+{
+ TMPQFile * hf = (TMPQFile *)hFile;
+
+ if(!IsValidFileHandle(hf))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return false;
+ }
+
+ // Free the structure
+ FreeMPQFile(hf);
+ return true;
+}
diff --git a/src/SFilePatchArchives.cpp b/src/SFilePatchArchives.cpp
new file mode 100644
index 0000000..8f259f4
--- /dev/null
+++ b/src/SFilePatchArchives.cpp
@@ -0,0 +1,587 @@
+/*****************************************************************************/
+/* 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
+
+typedef struct _BLIZZARD_BSDIFF40_FILE
+{
+ ULONGLONG Signature;
+ ULONGLONG CtrlBlockSize;
+ ULONGLONG DataBlockSize;
+ ULONGLONG NewFileSize;
+} BLIZZARD_BSDIFF40_FILE, *PBLIZZARD_BSDIFF40_FILE;
+
+//-----------------------------------------------------------------------------
+// Local functions
+
+static bool GetDefaultPatchPrefix(
+ const TCHAR * szBaseMpqName,
+ char * szBuffer)
+{
+ const TCHAR * szExtension;
+ const TCHAR * szDash;
+
+ // Ensure that both names are plain names
+ szBaseMpqName = GetPlainFileNameT(szBaseMpqName);
+
+ // Patch prefix is for the Cataclysm MPQs, whose names
+ // are like "locale-enGB.MPQ" or "speech-enGB.MPQ"
+ szExtension = _tcsrchr(szBaseMpqName, _T('.'));
+ szDash = _tcsrchr(szBaseMpqName, _T('-'));
+ strcpy(szBuffer, "Base");
+
+ // If the length of the prefix doesn't match, use default one
+ if(szExtension != NULL && szDash != NULL && (szExtension - szDash) == 5)
+ {
+ // Copy the prefix
+ szBuffer[0] = (char)szDash[1];
+ szBuffer[1] = (char)szDash[2];
+ szBuffer[2] = (char)szDash[3];
+ szBuffer[3] = (char)szDash[4];
+ szBuffer[4] = 0;
+ }
+
+ return true;
+}
+
+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);
+ cbCompressed -= 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 int LoadMpqPatch_COPY(TMPQFile * hf, TPatchHeader * pPatchHeader)
+{
+ int nError = ERROR_SUCCESS;
+
+ // Allocate space for patch header and compressed data
+ hf->pPatchHeader = (TPatchHeader *)STORM_ALLOC(BYTE, pPatchHeader->dwSizeOfPatchData);
+ if(hf->pPatchHeader == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+
+ // Load the patch data and decide if they are compressed or not
+ if(nError == ERROR_SUCCESS)
+ {
+ LPBYTE pbPatchFile = (LPBYTE)hf->pPatchHeader;
+
+ // Copy the patch header itself
+ memcpy(pbPatchFile, pPatchHeader, sizeof(TPatchHeader));
+ pbPatchFile += sizeof(TPatchHeader);
+
+ // Load the rest of the patch
+ if(!SFileReadFile((HANDLE)hf, pbPatchFile, pPatchHeader->dwSizeOfPatchData - sizeof(TPatchHeader), NULL, NULL))
+ nError = GetLastError();
+ }
+
+ return nError;
+}
+
+static int LoadMpqPatch_BSD0(TMPQFile * hf, TPatchHeader * pPatchHeader)
+{
+ LPBYTE pbDecompressed = NULL;
+ LPBYTE pbCompressed = NULL;
+ DWORD cbDecompressed = 0;
+ DWORD cbCompressed = 0;
+ DWORD dwBytesRead = 0;
+ int nError = ERROR_SUCCESS;
+
+ // Allocate space for compressed data
+ cbCompressed = pPatchHeader->dwXfrmBlockSize - SIZE_OF_XFRM_HEADER;
+ pbCompressed = STORM_ALLOC(BYTE, cbCompressed);
+ if(pbCompressed == NULL)
+ nError = ERROR_SUCCESS;
+
+ // Read the compressed patch data
+ if(nError == ERROR_SUCCESS)
+ {
+ // Load the rest of the header
+ SFileReadFile((HANDLE)hf, pbCompressed, cbCompressed, &dwBytesRead, NULL);
+ if(dwBytesRead != cbCompressed)
+ nError = ERROR_FILE_CORRUPT;
+ }
+
+ // Get the uncompressed size of the patch
+ if(nError == ERROR_SUCCESS)
+ {
+ cbDecompressed = pPatchHeader->dwSizeOfPatchData - sizeof(TPatchHeader);
+ hf->pPatchHeader = (TPatchHeader *)STORM_ALLOC(BYTE, pPatchHeader->dwSizeOfPatchData);
+ if(hf->pPatchHeader == NULL)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ // Now decompress the patch data
+ if(nError == ERROR_SUCCESS)
+ {
+ // Copy the patch header
+ memcpy(hf->pPatchHeader, pPatchHeader, sizeof(TPatchHeader));
+ pbDecompressed = (LPBYTE)hf->pPatchHeader + sizeof(TPatchHeader);
+
+ // Uncompress or copy the patch data
+ if(cbCompressed < cbDecompressed)
+ {
+ Decompress_RLE(pbDecompressed, cbDecompressed, pbCompressed, cbCompressed);
+ }
+ else
+ {
+ assert(cbCompressed == cbDecompressed);
+ memcpy(pbDecompressed, pbCompressed, cbCompressed);
+ }
+ }
+
+ // Free buffers and exit
+ if(pbCompressed != NULL)
+ STORM_FREE(pbCompressed);
+ return nError;
+}
+
+static int ApplyMpqPatch_COPY(
+ TMPQFile * hf,
+ TPatchHeader * pPatchHeader)
+{
+ LPBYTE pbNewFileData;
+ DWORD cbNewFileData;
+
+ // Allocate space for new file data
+ cbNewFileData = pPatchHeader->dwXfrmBlockSize - SIZE_OF_XFRM_HEADER;
+ pbNewFileData = STORM_ALLOC(BYTE, cbNewFileData);
+ if(pbNewFileData == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ // Copy the patch data as-is
+ memcpy(pbNewFileData, (LPBYTE)pPatchHeader + sizeof(TPatchHeader), cbNewFileData);
+
+ // Free the old file data
+ STORM_FREE(hf->pbFileData);
+
+ // Put the new file data there
+ hf->pbFileData = pbNewFileData;
+ hf->cbFileData = cbNewFileData;
+ return ERROR_SUCCESS;
+}
+
+static int ApplyMpqPatch_BSD0(
+ TMPQFile * hf,
+ TPatchHeader * pPatchHeader)
+{
+ PBLIZZARD_BSDIFF40_FILE pBsdiff;
+ LPDWORD pCtrlBlock;
+ LPBYTE pbPatchData = (LPBYTE)pPatchHeader + sizeof(TPatchHeader);
+ LPBYTE pDataBlock;
+ LPBYTE pExtraBlock;
+ LPBYTE pbNewData = NULL;
+ LPBYTE pbOldData = (LPBYTE)hf->pbFileData;
+ DWORD dwNewOffset = 0; // Current position to patch
+ DWORD dwOldOffset = 0; // Current source position
+ DWORD dwNewSize; // Patched file size
+ DWORD dwOldSize = hf->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 = (LPDWORD)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);
+
+ // Allocate new buffer
+ pbNewData = STORM_ALLOC(BYTE, dwNewSize);
+ if(pbNewData == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ // Now patch the file
+ while(dwNewOffset < dwNewSize)
+ {
+ DWORD dwAddDataLength = BSWAP_INT32_UNSIGNED(pCtrlBlock[0]);
+ DWORD dwMovDataLength = BSWAP_INT32_UNSIGNED(pCtrlBlock[1]);
+ DWORD dwOldMoveLength = BSWAP_INT32_UNSIGNED(pCtrlBlock[2]);
+ DWORD i;
+
+ // Sanity check
+ if((dwNewOffset + dwAddDataLength) > dwNewSize)
+ {
+ STORM_FREE(pbNewData);
+ return ERROR_FILE_CORRUPT;
+ }
+
+ // Read the diff string to the target buffer
+ memcpy(pbNewData + dwNewOffset, pDataBlock, dwAddDataLength);
+ pDataBlock += dwAddDataLength;
+
+ // Now combine the patch data with the original file
+ for(i = 0; i < dwAddDataLength; i++)
+ {
+ if(dwOldOffset < dwOldSize)
+ pbNewData[dwNewOffset] = pbNewData[dwNewOffset] + pbOldData[dwOldOffset];
+
+ dwNewOffset++;
+ dwOldOffset++;
+ }
+
+ // Sanity check
+ if((dwNewOffset + dwMovDataLength) > dwNewSize)
+ {
+ STORM_FREE(pbNewData);
+ 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 += 3;
+ }
+
+ // Free the old file data
+ STORM_FREE(hf->pbFileData);
+
+ // Put the new data to the fil structure
+ hf->pbFileData = pbNewData;
+ hf->cbFileData = dwNewSize;
+ return ERROR_SUCCESS;
+}
+
+
+static int LoadMpqPatch(TMPQFile * hf)
+{
+ TPatchHeader PatchHeader;
+ DWORD dwBytesRead;
+ int nError = ERROR_SUCCESS;
+
+ // Read the patch header
+ SFileReadFile((HANDLE)hf, &PatchHeader, sizeof(TPatchHeader), &dwBytesRead, NULL);
+ if(dwBytesRead != sizeof(TPatchHeader))
+ nError = ERROR_FILE_CORRUPT;
+
+ // Verify the signatures in the patch header
+ if(nError == ERROR_SUCCESS)
+ {
+ // BSWAP the entire header, if needed
+ BSWAP_ARRAY32_UNSIGNED(&PatchHeader, sizeof(DWORD) * 6);
+ PatchHeader.dwXFRM = BSWAP_INT32_UNSIGNED(PatchHeader.dwXFRM);
+ PatchHeader.dwXfrmBlockSize = BSWAP_INT32_UNSIGNED(PatchHeader.dwXfrmBlockSize);
+ PatchHeader.dwPatchType = BSWAP_INT32_UNSIGNED(PatchHeader.dwPatchType);
+
+ if(PatchHeader.dwSignature != 0x48435450 || PatchHeader.dwMD5 != 0x5f35444d || PatchHeader.dwXFRM != 0x4d524658)
+ nError = ERROR_FILE_CORRUPT;
+ }
+
+ // Read the patch, depending on patch type
+ if(nError == ERROR_SUCCESS)
+ {
+ switch(PatchHeader.dwPatchType)
+ {
+ case 0x59504f43: // 'COPY'
+ nError = LoadMpqPatch_COPY(hf, &PatchHeader);
+ break;
+
+ case 0x30445342: // 'BSD0'
+ nError = LoadMpqPatch_BSD0(hf, &PatchHeader);
+ break;
+
+ default:
+ nError = ERROR_FILE_CORRUPT;
+ break;
+ }
+ }
+
+ return nError;
+}
+
+static int ApplyMpqPatch(
+ TMPQFile * hf,
+ TPatchHeader * pPatchHeader)
+{
+ int nError = ERROR_SUCCESS;
+
+ // Verify the original file before patching
+ if(pPatchHeader->dwSizeBeforePatch != 0)
+ {
+ if(!VerifyDataBlockHash(hf->pbFileData, hf->cbFileData, pPatchHeader->md5_before_patch))
+ nError = ERROR_FILE_CORRUPT;
+ }
+
+ // Apply the patch
+ if(nError == ERROR_SUCCESS)
+ {
+ switch(pPatchHeader->dwPatchType)
+ {
+ case 0x59504f43: // 'COPY'
+ nError = ApplyMpqPatch_COPY(hf, pPatchHeader);
+ break;
+
+ case 0x30445342: // 'BSD0'
+ nError = ApplyMpqPatch_BSD0(hf, pPatchHeader);
+ break;
+
+ default:
+ nError = ERROR_FILE_CORRUPT;
+ break;
+ }
+ }
+
+ // Verify MD5 after patch
+ if(nError == ERROR_SUCCESS && pPatchHeader->dwSizeAfterPatch != 0)
+ {
+ // Verify the patched file
+ if(!VerifyDataBlockHash(hf->pbFileData, hf->cbFileData, pPatchHeader->md5_after_patch))
+ nError = ERROR_FILE_CORRUPT;
+ }
+
+ return nError;
+}
+
+//-----------------------------------------------------------------------------
+// Public functions (StormLib internals)
+
+bool IsIncrementalPatchFile(const void * pvData, DWORD cbData, LPDWORD pdwPatchedFileSize)
+{
+ TPatchHeader * pPatchHeader = (TPatchHeader *)pvData;
+ BLIZZARD_BSDIFF40_FILE DiffFile;
+ DWORD dwPatchType;
+
+ if(cbData >= sizeof(TPatchHeader) + 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;
+}
+
+int PatchFileData(TMPQFile * hf)
+{
+ TMPQFile * hfBase = hf;
+ int nError = ERROR_SUCCESS;
+
+ // Move to the first patch
+ hf = hf->hfPatchFile;
+
+ // Now go through all patches and patch the original data
+ while(hf != NULL)
+ {
+ // This must be true
+ assert(hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE);
+
+ // Make sure that the patch data is loaded
+ nError = LoadMpqPatch(hf);
+ if(nError != ERROR_SUCCESS)
+ break;
+
+ // Apply the patch
+ nError = ApplyMpqPatch(hfBase, hf->pPatchHeader);
+ if(nError != ERROR_SUCCESS)
+ break;
+
+ // Move to the next patch
+ hf = hf->hfPatchFile;
+ }
+
+ return nError;
+}
+
+//-----------------------------------------------------------------------------
+// Public functions
+
+//
+// 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
+//
+
+bool WINAPI SFileOpenPatchArchive(
+ HANDLE hMpq,
+ const TCHAR * szPatchMpqName,
+ const char * szPatchPathPrefix,
+ DWORD dwFlags)
+{
+ TMPQArchive * haPatch;
+ TMPQArchive * ha = (TMPQArchive *)hMpq;
+ HANDLE hPatchMpq = NULL;
+ char szPatchPrefixBuff[MPQ_PATCH_PREFIX_LEN];
+ int nError = ERROR_SUCCESS;
+
+ // Keep compiler happy
+ dwFlags = dwFlags;
+
+ // Verify input parameters
+ if(!IsValidMpqHandle(ha))
+ nError = ERROR_INVALID_HANDLE;
+ if(szPatchMpqName == NULL || *szPatchMpqName == 0)
+ nError = ERROR_INVALID_PARAMETER;
+
+ // If the user didn't give the patch prefix, get default one
+ if(szPatchPathPrefix != NULL)
+ {
+ // Save length of the patch prefix
+ if(strlen(szPatchPathPrefix) > MPQ_PATCH_PREFIX_LEN - 2)
+ nError = 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(nError == ERROR_SUCCESS)
+ {
+ if(!FileStream_IsReadOnly(ha->pStream))
+ nError = ERROR_ACCESS_DENIED;
+ }
+
+ // Open the archive like it is normal archive
+ if(nError == ERROR_SUCCESS)
+ {
+ if(!SFileOpenArchive(szPatchMpqName, 0, MPQ_OPEN_READ_ONLY, &hPatchMpq))
+ return false;
+ haPatch = (TMPQArchive *)hPatchMpq;
+
+ // Older WoW patches (build 13914) used to have
+ // several language versions in one patch file
+ // Those patches needed to have a path prefix
+ // We can distinguish such patches by not having the (patch_metadata) file
+ if(szPatchPathPrefix == NULL)
+ {
+ if(!SFileHasFile(hPatchMpq, PATCH_METADATA_NAME))
+ {
+ GetDefaultPatchPrefix(FileStream_GetFileName(ha->pStream), szPatchPrefixBuff);
+ szPatchPathPrefix = szPatchPrefixBuff;
+ }
+ }
+
+ // Save the prefix for patch file names.
+ // Make sure that there is backslash after it
+ if(szPatchPathPrefix != NULL && *szPatchPathPrefix != 0)
+ {
+ strcpy(haPatch->szPatchPrefix, szPatchPathPrefix);
+ strcat(haPatch->szPatchPrefix, "\\");
+ haPatch->cchPatchPrefix = strlen(haPatch->szPatchPrefix);
+ }
+
+ // 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;
+ }
+
+ // Should never happen
+ nError = ERROR_CAN_NOT_COMPLETE;
+ }
+
+ SetLastError(nError);
+ return false;
+}
+
+bool WINAPI SFileIsPatchedArchive(HANDLE hMpq)
+{
+ TMPQArchive * ha = (TMPQArchive *)hMpq;
+
+ // Verify input parameters
+ if(!IsValidMpqHandle(ha))
+ return false;
+
+ return (ha->haPatch != NULL);
+}
diff --git a/src/SFileReadFile.cpp b/src/SFileReadFile.cpp
new file mode 100644
index 0000000..164b646
--- /dev/null
+++ b/src/SFileReadFile.cpp
@@ -0,0 +1,1186 @@
+/*****************************************************************************/
+/* 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 structures
+
+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
+};
+
+//-----------------------------------------------------------------------------
+// Local functions
+
+static void CopyFileName(char * szTarget, const TCHAR * szSource)
+{
+ while(*szSource != 0)
+ *szTarget++ = (char)*szSource++;
+ *szTarget = 0;
+}
+
+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 GetFilePatchChain(TMPQFile * hf, void * pvFileInfo, DWORD cbFileInfo, LPDWORD pcbLengthNeeded)
+{
+ TMPQFile * hfTemp;
+ TCHAR * szPatchChain = (TCHAR *)pvFileInfo;
+ TCHAR * szFileName;
+ size_t cchCharsNeeded = 1;
+ size_t nLength;
+ DWORD cbLengthNeeded;
+
+ // Check if the "hf" is a MPQ file
+ if(hf->pStream != NULL)
+ {
+ // Calculate the length needed
+ szFileName = FileStream_GetFileName(hf->pStream);
+ cchCharsNeeded += _tcslen(szFileName) + 1;
+ cbLengthNeeded = (DWORD)(cchCharsNeeded * sizeof(TCHAR));
+
+ // If we have enough space, copy the file name
+ if(cbFileInfo >= cbLengthNeeded)
+ {
+ nLength = _tcslen(szFileName) + 1;
+ memcpy(szPatchChain, szFileName, nLength * sizeof(TCHAR));
+ szPatchChain += nLength;
+
+ // Terminate the multi-string
+ *szPatchChain = 0;
+ }
+ }
+ else
+ {
+ // Calculate number of characters needed
+ for(hfTemp = hf; hfTemp != NULL; hfTemp = hfTemp->hfPatchFile)
+ cchCharsNeeded += _tcslen(FileStream_GetFileName(hfTemp->ha->pStream)) + 1;
+ cbLengthNeeded = (DWORD)(cchCharsNeeded * sizeof(TCHAR));
+
+ // If we have enough space, the copy the patch chain
+ if(cbFileInfo >= cbLengthNeeded)
+ {
+ for(hfTemp = hf; hfTemp != NULL; hfTemp = hfTemp->hfPatchFile)
+ {
+ szFileName = FileStream_GetFileName(hfTemp->ha->pStream);
+ nLength = _tcslen(szFileName) + 1;
+ memcpy(szPatchChain, szFileName, nLength * sizeof(TCHAR));
+ szPatchChain += nLength;
+ }
+
+ // Terminate the multi-string
+ *szPatchChain = 0;
+ }
+ }
+
+ // Give result length, terminate multi-string and return
+ *pcbLengthNeeded = cbLengthNeeded;
+ return true;
+}
+
+// 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 int 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;
+ int nError = 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_COMPRESSED)
+ {
+ // If the sector positions are not loaded yet, do it
+ if(hf->SectorOffsets == NULL)
+ {
+ nError = AllocateSectorOffsets(hf, true);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+ }
+
+ // 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)
+// {
+// nError = AllocateRawMD5s(hf, true);
+// if(nError != ERROR_SUCCESS)
+// return nError;
+// }
+
+ // If the file is compressed, also allocate secondary buffer
+ pbInSector = pbRawSector = STORM_ALLOC(BYTE, dwBytesToRead);
+ if(pbRawSector == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ // Assign the temporary buffer as target for read operation
+ dwRawSectorOffset = hf->SectorOffsets[dwSectorIndex];
+ dwRawBytesToRead = hf->SectorOffsets[dwSectorIndex + dwSectorsToRead] - dwRawSectorOffset;
+ }
+
+ // Calculate raw file offset where the sector(s) are stored.
+ CalculateRawSectorOffset(RawFilePos, hf, dwRawSectorOffset);
+
+ // Set file pointer and read all required sectors
+ if(!FileStream_Read(ha->pStream, &RawFilePos, pbInSector, dwRawBytesToRead))
+ return GetLastError();
+ dwBytesRead = 0;
+
+ // 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_COMPRESSED)
+ 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);
+ if(hf->dwFileKey == 0)
+ {
+ nError = 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)
+ {
+ nError = 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)
+ {
+ 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)
+ {
+ nError = 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++;
+ }
+
+ // Free all used buffers
+ if(pbRawSector != NULL)
+ STORM_FREE(pbRawSector);
+
+ // Give the caller thenumber of bytes read
+ *pdwBytesRead = dwBytesRead;
+ return nError;
+}
+
+static int 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 = NULL;
+ int nError = ERROR_SUCCESS;
+
+ // If the file buffer is not allocated yet, do it.
+ if(hf->pbFileSector == NULL)
+ {
+ nError = AllocateSectorBuffer(hf);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+ pbRawData = hf->pbFileSector;
+ }
+
+ // If the file is a patch file, adjust raw data offset
+ if(hf->pPatchInfo != NULL)
+ RawFilePos += hf->pPatchInfo->dwLength;
+
+ // If the file sector is not loaded yet, do it
+ if(hf->dwSectorOffs != 0)
+ {
+ // Is the file compressed?
+ if(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED)
+ {
+ // 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_COMPRESSED)
+ {
+ 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)
+ {
+ 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);
+
+ nError = (nResult != 0) ? ERROR_SUCCESS : 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(nError == 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 int ReadMpqFile(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)
+ int nError;
+
+ // 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)
+ {
+ nError = AllocateSectorBuffer(hf);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+ }
+
+ // 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
+ nError = ReadMpqSectors(hf, hf->pbFileSector, dwFileSectorPos, ha->dwSectorSize, &dwBytesInSector);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ // 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
+ nError = ReadMpqSectors(hf, pbBuffer, dwFileSectorPos, dwBlockBytes, &dwBytesRead);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ // 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
+ nError = ReadMpqSectors(hf, hf->pbFileSector, dwFileSectorPos, ha->dwSectorSize, &dwBytesRead);
+ if(nError != ERROR_SUCCESS)
+ return nError;
+
+ // 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 int ReadMpqFilePatchFile(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead)
+{
+ DWORD dwBytesToRead = dwToRead;
+ DWORD dwBytesRead = 0;
+ int nError = ERROR_SUCCESS;
+
+ // Make sure that the patch file is loaded completely
+ if(hf->pbFileData == NULL)
+ {
+ // Load the original file and store its content to "pbOldData"
+ hf->pbFileData = STORM_ALLOC(BYTE, hf->pFileEntry->dwFileSize);
+ hf->cbFileData = hf->pFileEntry->dwFileSize;
+ if(hf->pbFileData == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ // Read the file data
+ if(hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT)
+ nError = ReadMpqFileSingleUnit(hf, hf->pbFileData, 0, hf->cbFileData, &dwBytesRead);
+ else
+ nError = ReadMpqFile(hf, hf->pbFileData, 0, hf->cbFileData, &dwBytesRead);
+
+ // Fix error code
+ if(nError == ERROR_SUCCESS && dwBytesRead != hf->cbFileData)
+ nError = ERROR_FILE_CORRUPT;
+
+ // Patch the file data
+ if(nError == ERROR_SUCCESS)
+ nError = PatchFileData(hf);
+
+ // Reset number of bytes read to zero
+ dwBytesRead = 0;
+ }
+
+ // If there is something to read, do it
+ if(nError == 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
+ nError = (dwBytesRead == dwBytesToRead) ? ERROR_SUCCESS : ERROR_HANDLE_EOF;
+ }
+
+ // Give the result to the caller
+ if(pdwBytesRead != NULL)
+ *pdwBytesRead = dwBytesRead;
+ return nError;
+}
+
+//-----------------------------------------------------------------------------
+// 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
+ int nError = ERROR_SUCCESS;
+
+ // Keep compilers happy
+ lpOverlapped = lpOverlapped;
+
+ // Check valid parameters
+ if(!IsValidFileHandle(hf))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return false;
+ }
+
+ if(pvBuffer == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+
+ // If the file is local file, read the data directly from the stream
+ if(hf->pStream != NULL)
+ {
+ ULONGLONG FilePosition1;
+ ULONGLONG FilePosition2;
+
+ // 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
+
+ FileStream_GetPos(hf->pStream, &FilePosition1);
+ if(!FileStream_Read(hf->pStream, NULL, pvBuffer, dwToRead))
+ {
+ // If not all bytes have been read, then return the number
+ // of bytes read
+ if((nError = GetLastError()) == ERROR_HANDLE_EOF)
+ {
+ FileStream_GetPos(hf->pStream, &FilePosition2);
+ dwBytesRead = (DWORD)(FilePosition2 - FilePosition1);
+ }
+ else
+ {
+ nError = GetLastError();
+ }
+ }
+ else
+ {
+ dwBytesRead = dwToRead;
+ }
+ }
+ else
+ {
+ // If the file is a patch file, we have to read it special way
+ if(hf->hfPatchFile != NULL && (hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0)
+ {
+ nError = ReadMpqFilePatchFile(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)
+ {
+ nError = ReadMpqFileSingleUnit(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead);
+ }
+
+ // Otherwise read it as sector based MPQ file
+ else
+ {
+ nError = ReadMpqFile(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(nError == ERROR_SUCCESS && (dwBytesRead < dwToRead))
+ nError = ERROR_HANDLE_EOF;
+
+ // If something failed, set the last error value
+ if(nError != ERROR_SUCCESS)
+ SetLastError(nError);
+ return (nError == 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(hf))
+ {
+ // 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->hfPatchFile != 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->hfPatchFile;
+ }
+ }
+ 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 FilePosition;
+ ULONGLONG MoveOffset;
+ DWORD dwFilePosHi;
+
+ // If the hFile is not a valid file handle, return an error.
+ if(!IsValidFileHandle(hf))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return SFILE_INVALID_POS;
+ }
+
+ // Get the relative point where to move from
+ switch(dwMoveMethod)
+ {
+ case FILE_BEGIN:
+ FilePosition = 0;
+ break;
+
+ case FILE_CURRENT:
+ if(hf->pStream != NULL)
+ {
+ FileStream_GetPos(hf->pStream, &FilePosition);
+ }
+ else
+ {
+ FilePosition = hf->dwFilePos;
+ }
+ break;
+
+ case FILE_END:
+ if(hf->pStream != NULL)
+ {
+ FileStream_GetSize(hf->pStream, &FilePosition);
+ }
+ else
+ {
+ FilePosition = SFileGetFileSize(hFile, NULL);
+ }
+ break;
+
+ default:
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return SFILE_INVALID_POS;
+ }
+
+ // Now get the move offset. Note that both values form
+ // a signed 64-bit value (a file pointer can be moved backwards)
+ if(plFilePosHigh != NULL)
+ dwFilePosHi = *plFilePosHigh;
+ else
+ dwFilePosHi = (lFilePos & 0x80000000) ? 0xFFFFFFFF : 0;
+ MoveOffset = MAKE_OFFSET64(dwFilePosHi, lFilePos);
+
+ // Now calculate the new file pointer
+ // Do not allow the file pointer to go before the begin of the file
+ FilePosition += MoveOffset;
+ if(FilePosition < 0)
+ FilePosition = 0;
+
+ // Now apply the file pointer to the file
+ if(hf->pStream != NULL)
+ {
+ // Apply the new file position
+ if(!FileStream_Read(hf->pStream, &FilePosition, NULL, 0))
+ return SFILE_INVALID_POS;
+
+ // Return the new file position
+ if(plFilePosHigh != NULL)
+ *plFilePosHigh = (LONG)(FilePosition >> 32);
+ return (DWORD)FilePosition;
+ }
+ else
+ {
+ // Files in MPQ can't be bigger than 4 GB.
+ // We don't allow to go past 4 GB
+ if(FilePosition >> 32)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return SFILE_INVALID_POS;
+ }
+
+ // Change the file position
+ hf->dwFilePos = (DWORD)FilePosition;
+
+ // Return the new file position
+ if(plFilePosHigh != NULL)
+ *plFilePosHigh = 0;
+ return (DWORD)FilePosition;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Tries to retrieve the file name
+
+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 '<htm'
+ {0x4D54483C, 0xFFFFFFFF, 0x00000000, 0x00000000, "html"}, // HTML '<HTM
+ {0x216F6F57, 0xFFFFFFFF, 0x00000000, 0x00000000, "tbl"}, // Table files
+ {0x31504C42, 0xFFFFFFFF, 0x00000000, 0x00000000, "blp"}, // BLP textures
+ {0x32504C42, 0xFFFFFFFF, 0x00000000, 0x00000000, "blp"}, // BLP textures (v2)
+ {0x584C444D, 0xFFFFFFFF, 0x00000000, 0x00000000, "mdx"}, // MDX files
+ {0x45505954, 0xFFFFFFFF, 0x00000000, 0x00000000, "pud"}, // Warcraft II maps
+ {0x38464947, 0xFFFFFFFF, 0x00000000, 0x00000000, "gif"}, // GIF images 'GIF8'
+ {0x3032444D, 0xFFFFFFFF, 0x00000000, 0x00000000, "m2"}, // WoW ??? .m2
+ {0x43424457, 0xFFFFFFFF, 0x00000000, 0x00000000, "dbc"}, // ??? .dbc
+ {0x47585053, 0xFFFFFFFF, 0x00000000, 0x00000000, "bls"}, // WoW pixel shaders
+ {0xE0FFD8FF, 0xFFFFFFFF, 0x00000000, 0x00000000, "jpg"}, // JPEG image
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000, "xxx"}, // Default extension
+ {0, 0, 0, 0, NULL} // Terminator
+};
+
+bool WINAPI SFileGetFileName(HANDLE hFile, char * szFileName)
+{
+ TFileEntry * pFileEntry;
+ TMPQFile * hf = (TMPQFile *)hFile; // MPQ File handle
+ char szPseudoName[20];
+ DWORD FirstBytes[2]; // The first 4 bytes of the file
+ DWORD dwFilePos; // Saved file position
+ int nError = ERROR_SUCCESS;
+ int i;
+
+ // Pre-zero the output buffer
+ if(szFileName != NULL)
+ *szFileName = 0;
+
+ // Check valid parameters
+ if(!IsValidFileHandle(hf))
+ nError = ERROR_INVALID_HANDLE;
+ pFileEntry = hf->pFileEntry;
+
+ // Only do something if the file name is not filled
+ if(nError == ERROR_SUCCESS && pFileEntry != NULL && pFileEntry->szFileName == NULL)
+ {
+ // Read the first 2 DWORDs bytes from the file
+ FirstBytes[0] = FirstBytes[1] = 0;
+ dwFilePos = SFileSetFilePointer(hf, 0, NULL, FILE_CURRENT);
+ SFileReadFile(hFile, FirstBytes, sizeof(FirstBytes), NULL, NULL);
+ BSWAP_ARRAY32_UNSIGNED(FirstBytes, sizeof(FirstBytes));
+ SFileSetFilePointer(hf, dwFilePos, NULL, FILE_BEGIN);
+
+ // Try to guess file extension from those 2 DWORDs
+ for(i = 0; data2ext[i].szExt != NULL; i++)
+ {
+ if((FirstBytes[0] & data2ext[i].dwOffset00Mask) == data2ext[i].dwOffset00Data &&
+ (FirstBytes[1] & data2ext[i].dwOffset04Mask) == data2ext[i].dwOffset04Data)
+ {
+ sprintf(szPseudoName, "File%08u.%s", (unsigned int)(pFileEntry - hf->ha->pFileTable), data2ext[i].szExt);
+ break;
+ }
+ }
+
+ // Put the file name to the file table
+ AllocateFileName(pFileEntry, szPseudoName);
+ }
+
+ // Now put the file name to the file structure
+ if(nError == ERROR_SUCCESS && szFileName != NULL)
+ {
+ if(pFileEntry != NULL && pFileEntry->szFileName != NULL)
+ strcpy(szFileName, pFileEntry->szFileName);
+ else if(hf->pStream != NULL)
+ CopyFileName(szFileName, FileStream_GetFileName(hf->pStream));
+ }
+ return (nError == ERROR_SUCCESS);
+}
+
+//-----------------------------------------------------------------------------
+// Retrieves an information about an archive or about a file within the archive
+//
+// hMpqOrFile - Handle to an MPQ archive or to a file
+// dwInfoType - Information to obtain
+
+#define VERIFY_MPQ_HANDLE(h) \
+ if(!IsValidMpqHandle(h)) \
+ { \
+ nError = ERROR_INVALID_HANDLE; \
+ break; \
+ }
+
+#define VERIFY_FILE_HANDLE(h) \
+ if(!IsValidFileHandle(h)) \
+ { \
+ nError = ERROR_INVALID_HANDLE; \
+ break; \
+ }
+
+bool WINAPI SFileGetFileInfo(
+ HANDLE hMpqOrFile,
+ DWORD dwInfoType,
+ void * pvFileInfo,
+ DWORD cbFileInfo,
+ LPDWORD pcbLengthNeeded)
+{
+ TMPQArchive * ha = (TMPQArchive *)hMpqOrFile;
+ TMPQBlock * pBlock;
+ TMPQFile * hf = (TMPQFile *)hMpqOrFile;
+ void * pvSrcFileInfo = NULL;
+ DWORD cbLengthNeeded = 0;
+ DWORD dwIsReadOnly;
+ DWORD dwFileCount = 0;
+ DWORD dwFileIndex;
+ DWORD dwFileKey;
+ DWORD i;
+ int nError = ERROR_SUCCESS;
+
+ switch(dwInfoType)
+ {
+ case SFILE_INFO_ARCHIVE_NAME:
+ VERIFY_MPQ_HANDLE(ha);
+
+ // pvFileInfo receives the name of the archive, terminated by 0
+ pvSrcFileInfo = FileStream_GetFileName(ha->pStream);
+ cbLengthNeeded = (DWORD)(_tcslen((TCHAR *)pvSrcFileInfo) + 1) * sizeof(TCHAR);
+ break;
+
+ case SFILE_INFO_ARCHIVE_SIZE: // Size of the archive
+ VERIFY_MPQ_HANDLE(ha);
+ cbLengthNeeded = sizeof(DWORD);
+ pvSrcFileInfo = &ha->pHeader->dwArchiveSize;
+ break;
+
+ case SFILE_INFO_MAX_FILE_COUNT: // Max. number of files in the MPQ
+ VERIFY_MPQ_HANDLE(ha);
+ cbLengthNeeded = sizeof(DWORD);
+ pvSrcFileInfo = &ha->dwMaxFileCount;
+ break;
+
+ case SFILE_INFO_HASH_TABLE_SIZE: // Size of the hash table
+ VERIFY_MPQ_HANDLE(ha);
+ cbLengthNeeded = sizeof(DWORD);
+ pvSrcFileInfo = &ha->pHeader->dwHashTableSize;
+ break;
+
+ case SFILE_INFO_BLOCK_TABLE_SIZE: // Size of the block table
+ VERIFY_MPQ_HANDLE(ha);
+ cbLengthNeeded = sizeof(DWORD);
+ pvSrcFileInfo = &ha->pHeader->dwBlockTableSize;
+ break;
+
+ case SFILE_INFO_SECTOR_SIZE:
+ VERIFY_MPQ_HANDLE(ha);
+ cbLengthNeeded = sizeof(DWORD);
+ pvSrcFileInfo = &ha->dwSectorSize;
+ break;
+
+ case SFILE_INFO_HASH_TABLE:
+ VERIFY_MPQ_HANDLE(ha);
+ cbLengthNeeded = ha->pHeader->dwHashTableSize * sizeof(TMPQHash);
+ pvSrcFileInfo = ha->pHashTable;
+ break;
+
+ case SFILE_INFO_BLOCK_TABLE:
+ VERIFY_MPQ_HANDLE(ha);
+ cbLengthNeeded = ha->dwFileTableSize * sizeof(TMPQBlock);
+ if(cbFileInfo < cbLengthNeeded)
+ {
+ nError = ERROR_INSUFFICIENT_BUFFER;
+ break;
+ }
+
+ // Construct block table from file table size
+ pBlock = (TMPQBlock *)pvFileInfo;
+ for(i = 0; i < ha->dwFileTableSize; i++)
+ {
+ pBlock->dwFilePos = (DWORD)ha->pFileTable[i].ByteOffset;
+ pBlock->dwFSize = ha->pFileTable[i].dwFileSize;
+ pBlock->dwCSize = ha->pFileTable[i].dwCmpSize;
+ pBlock->dwFlags = ha->pFileTable[i].dwFlags;
+ pBlock++;
+ }
+ break;
+
+ case SFILE_INFO_NUM_FILES:
+ VERIFY_MPQ_HANDLE(ha);
+ dwFileCount = GetMpqFileCount(ha);
+ cbLengthNeeded = sizeof(DWORD);
+ pvSrcFileInfo = &dwFileCount;
+ break;
+
+ case SFILE_INFO_STREAM_FLAGS:
+ VERIFY_MPQ_HANDLE(ha);
+ FileStream_GetFlags(ha->pStream, &dwFileKey);
+ cbLengthNeeded = sizeof(DWORD);
+ pvSrcFileInfo = &dwFileKey;
+ break;
+
+ case SFILE_INFO_IS_READ_ONLY:
+ VERIFY_MPQ_HANDLE(ha);
+ dwIsReadOnly = (FileStream_IsReadOnly(ha->pStream) || (ha->dwFlags & MPQ_FLAG_READ_ONLY));
+ cbLengthNeeded = sizeof(DWORD);
+ pvSrcFileInfo = &dwIsReadOnly;
+ break;
+
+ case SFILE_INFO_HASH_INDEX:
+ VERIFY_FILE_HANDLE(hf);
+ cbLengthNeeded = sizeof(DWORD);
+ pvSrcFileInfo = &hf->pFileEntry->dwHashIndex;
+ break;
+
+ case SFILE_INFO_CODENAME1:
+ VERIFY_FILE_HANDLE(hf);
+ cbLengthNeeded = sizeof(DWORD);
+ pvSrcFileInfo = &hf->pFileEntry->dwHashIndex;
+ if(ha->pHashTable != NULL)
+ pvSrcFileInfo = &ha->pHashTable[hf->pFileEntry->dwHashIndex].dwName1;
+ break;
+
+ case SFILE_INFO_CODENAME2:
+ VERIFY_FILE_HANDLE(hf);
+ cbLengthNeeded = sizeof(DWORD);
+ if(ha->pHashTable != NULL)
+ pvSrcFileInfo = &ha->pHashTable[hf->pFileEntry->dwHashIndex].dwName2;
+ break;
+
+ case SFILE_INFO_LOCALEID:
+ VERIFY_FILE_HANDLE(hf);
+ cbLengthNeeded = sizeof(DWORD);
+ pvSrcFileInfo = &hf->pFileEntry->lcLocale;
+ break;
+
+ case SFILE_INFO_BLOCKINDEX:
+ VERIFY_FILE_HANDLE(hf);
+ dwFileIndex = (DWORD)(hf->pFileEntry - hf->ha->pFileTable);
+ cbLengthNeeded = sizeof(DWORD);
+ pvSrcFileInfo = &dwFileIndex;
+ break;
+
+ case SFILE_INFO_FILE_SIZE:
+ VERIFY_FILE_HANDLE(hf);
+ cbLengthNeeded = sizeof(DWORD);
+ pvSrcFileInfo = &hf->pFileEntry->dwFileSize;
+ break;
+
+ case SFILE_INFO_COMPRESSED_SIZE:
+ VERIFY_FILE_HANDLE(hf);
+ cbLengthNeeded = sizeof(DWORD);
+ pvSrcFileInfo = &hf->pFileEntry->dwCmpSize;
+ break;
+
+ case SFILE_INFO_FLAGS:
+ VERIFY_FILE_HANDLE(hf);
+ cbLengthNeeded = sizeof(DWORD);
+ pvSrcFileInfo = &hf->pFileEntry->dwFlags;
+ break;
+
+ case SFILE_INFO_POSITION:
+ VERIFY_FILE_HANDLE(hf);
+ cbLengthNeeded = sizeof(ULONGLONG);
+ pvSrcFileInfo = &hf->pFileEntry->ByteOffset;
+ break;
+
+ case SFILE_INFO_KEY:
+ VERIFY_FILE_HANDLE(hf);
+ cbLengthNeeded = sizeof(DWORD);
+ pvSrcFileInfo = &hf->dwFileKey;
+ break;
+
+ case SFILE_INFO_KEY_UNFIXED:
+ VERIFY_FILE_HANDLE(hf);
+ dwFileKey = hf->dwFileKey;
+ if(hf->pFileEntry->dwFlags & MPQ_FILE_FIX_KEY)
+ dwFileKey = (dwFileKey ^ hf->pFileEntry->dwFileSize) - (DWORD)hf->MpqFilePos;
+ cbLengthNeeded = sizeof(DWORD);
+ pvSrcFileInfo = &dwFileKey;
+ break;
+
+ case SFILE_INFO_FILETIME:
+ VERIFY_FILE_HANDLE(hf);
+ cbLengthNeeded = sizeof(ULONGLONG);
+ pvSrcFileInfo = &hf->pFileEntry->FileTime;
+ break;
+
+ case SFILE_INFO_PATCH_CHAIN:
+ VERIFY_FILE_HANDLE(hf);
+ GetFilePatchChain(hf, pvFileInfo, cbFileInfo, &cbLengthNeeded);
+ break;
+
+ default:
+ nError = ERROR_INVALID_PARAMETER;
+ break;
+ }
+
+ // If everything is OK so far, copy the information
+ if(nError == ERROR_SUCCESS)
+ {
+ // Is the output buffer large enough?
+ if(cbFileInfo >= cbLengthNeeded)
+ {
+ // Copy the data
+ if(pvSrcFileInfo != NULL)
+ memcpy(pvFileInfo, pvSrcFileInfo, cbLengthNeeded);
+ }
+ else
+ {
+ nError = ERROR_INSUFFICIENT_BUFFER;
+ }
+
+ // Give the size to the caller
+ if(pcbLengthNeeded != NULL)
+ *pcbLengthNeeded = cbLengthNeeded;
+ }
+
+ // Set the last error value, if needed
+ if(nError != ERROR_SUCCESS)
+ SetLastError(nError);
+ return (nError == ERROR_SUCCESS);
+}
diff --git a/src/SFileVerify.cpp b/src/SFileVerify.cpp
new file mode 100644
index 0000000..1354bfc
--- /dev/null
+++ b/src/SFileVerify.cpp
@@ -0,0 +1,922 @@
+/*****************************************************************************/
+/* SFileVerify.cpp Copyright (c) Ladislav Zezula 2010 */
+/*---------------------------------------------------------------------------*/
+/* MPQ files and MPQ archives verification. */
+/* */
+/* The MPQ signature verification has been written by Jean-Francois Roy */
+/* <bahamut@macstorm.org> 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 SIGNATURE_TYPE_NONE 0
+#define SIGNATURE_TYPE_WEAK 1
+#define SIGNATURE_TYPE_STRONG 2
+
+#define MPQ_DIGEST_UNIT_SIZE 0x10000
+
+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
+ int nSignatureType; // See SIGNATURE_TYPE_XXX
+
+} MPQ_SIGNATURE_INFO, *PMPQ_SIGNATURE_INFO;
+
+//-----------------------------------------------------------------------------
+// Known Blizzard public keys
+// Created by Jean-Francois Roy using OpenSSL
+
+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 is_valid_md5(void * pvMd5)
+{
+ LPDWORD Md5 = (LPDWORD)pvMd5;
+
+ return (Md5[0] | Md5[1] | Md5[2] | Md5[3]) ? true : false;
+}
+
+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 = GetPlainFileNameT(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 our MPQ header,
+ // and it's been already prepared by SFileOpenArchive,
+ pSI->EndMpqData = ha->MpqPos + ha->pHeader->ArchiveSize64;
+
+ // Get the size of the entire file
+ FileStream_GetSize(ha->pStream, &pSI->EndOfFile);
+}
+
+static bool QueryMpqSignatureInfo(
+ TMPQArchive * ha,
+ PMPQ_SIGNATURE_INFO pSI)
+{
+ ULONGLONG ExtraBytes;
+ TMPQFile * hf;
+ HANDLE hFile;
+ DWORD dwFileSize;
+
+ // Calculate the range of the MPQ
+ CalculateArchiveRange(ha, pSI);
+
+ // If there is "(signature)" file in the MPQ, it has a weak signature
+ if(SFileOpenFileEx((HANDLE)ha, SIGNATURE_NAME, SFILE_OPEN_BASE_FILE, &hFile))
+ {
+ // Get the content of the signature
+ SFileReadFile(hFile, pSI->Signature, sizeof(pSI->Signature), &pSI->cbSignatureSize, NULL);
+
+ // Verify the size of the signature
+ hf = (TMPQFile *)hFile;
+
+ // We have to exclude the signature file from the digest
+ pSI->BeginExclude = ha->MpqPos + hf->pFileEntry->ByteOffset;
+ pSI->EndExclude = pSI->BeginExclude + hf->pFileEntry->dwCmpSize;
+ dwFileSize = hf->dwDataSize;
+
+ // Close the file
+ SFileCloseFile(hFile);
+ pSI->nSignatureType = SIGNATURE_TYPE_WEAK;
+ return (dwFileSize == (MPQ_WEAK_SIGNATURE_SIZE + 8)) ? true : false;
+ }
+
+ // 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 false;
+
+ pSI->nSignatureType = SIGNATURE_TYPE_STRONG;
+ return true;
+ }
+
+ // Succeeded, but no known signature found
+ return true;
+}
+
+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 int 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;
+ int nError = 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)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+
+ // Calculate MD5 of each data chunk
+ if(nError == 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))
+ {
+ nError = 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(nError == ERROR_SUCCESS)
+ {
+ // Read the array of MD5
+ if(!FileStream_Read(ha->pStream, &DataOffset, pbMD5Array2, dwMD5Size))
+ nError = GetLastError();
+ }
+
+ // Compare the array of MD5
+ if(nError == ERROR_SUCCESS)
+ {
+ // Compare the MD5
+ if(memcmp(pbMD5Array1, pbMD5Array2, dwMD5Size))
+ nError = 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 nError;
+}
+
+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;
+
+ // 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 dwBytesRead;
+ DWORD dwCrc32 = 0;
+
+ //
+ // Note: When the MPQ is patched, it will
+ // automatically check the patched version of the file
+ //
+
+ // 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, 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(;;)
+ {
+ // 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->hfPatchFile == 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(is_valid_md5(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;
+}
+
+//-----------------------------------------------------------------------------
+// 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
+int WINAPI SFileVerifyRawData(HANDLE hMpq, DWORD dwWhatToVerify, const char * szFileName)
+{
+ TMPQArchive * ha = (TMPQArchive *)hMpq;
+ TFileEntry * pFileEntry;
+ TMPQHeader * pHeader;
+
+ // Verify input parameters
+ if(!IsValidMpqHandle(ha))
+ 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, 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(ha))
+ return ERROR_VERIFY_FAILED;
+
+ // Get the MPQ signature and signature type
+ memset(&si, 0, sizeof(MPQ_SIGNATURE_INFO));
+ if(!QueryMpqSignatureInfo(ha, &si))
+ return ERROR_VERIFY_FAILED;
+
+ // Verify the signature
+ switch(si.nSignatureType)
+ {
+ case SIGNATURE_TYPE_NONE:
+ return ERROR_NO_SIGNATURE;
+
+ case SIGNATURE_TYPE_WEAK:
+ return VerifyWeakSignature(ha, &si);
+
+ case SIGNATURE_TYPE_STRONG:
+ return VerifyStrongSignature(ha, &si);
+ }
+
+ return ERROR_VERIFY_FAILED;
+}
diff --git a/src/StormCommon.h b/src/StormCommon.h
new file mode 100644
index 0000000..2d5c2ab
--- /dev/null
+++ b/src/StormCommon.h
@@ -0,0 +1,281 @@
+/*****************************************************************************/
+/* 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 <zlib.h>
+#endif
+
+// Include functions from bzlib
+#ifndef __SYS_BZLIB
+ #include "bzip2/bzlib.h"
+#else
+ #include <bzlib.h>
+#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')
+
+#define MPQ_WEAK_SIGNATURE_SIZE 64
+#define MPQ_STRONG_SIGNATURE_SIZE 256
+
+// 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))
+
+// Macro for building 64-bit file offset from two 32-bit
+#define MAKE_OFFSET64(hi, lo) (((ULONGLONG)hi << 32) | lo)
+
+//-----------------------------------------------------------------------------
+// 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)
+// - It is not necessary 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)
+__inline void * DebugMalloc(char * /* szFile */, int /* nLine */, size_t nSize)
+{
+// return new BYTE[nSize];
+ return HeapAlloc(GetProcessHeap(), 0, nSize);
+}
+
+__inline void DebugFree(void * ptr)
+{
+// delete [] ptr;
+ HeapFree(GetProcessHeap(), 0, ptr);
+}
+
+#define STORM_ALLOC(type, nitems) (type *)DebugMalloc(__FILE__, __LINE__, (nitems) * sizeof(type))
+#define STORM_FREE(ptr) DebugFree(ptr)
+#else
+
+#define STORM_ALLOC(type, nitems) (type *)malloc((nitems) * sizeof(type))
+#define STORM_FREE(ptr) free(ptr)
+
+#endif
+
+//-----------------------------------------------------------------------------
+// StormLib internal global variables
+
+extern LCID lcFileLocale; // Preferred file locale
+
+//-----------------------------------------------------------------------------
+// Conversion to uppercase/lowercase (and "/" to "\")
+
+extern unsigned char AsciiToLowerTable[256];
+extern unsigned char AsciiToUpperTable[256];
+
+//-----------------------------------------------------------------------------
+// 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
+
+DWORD HashString(const char * szFileName, DWORD dwHashType);
+
+void InitializeMpqCryptography();
+
+DWORD GetHashTableSizeForFileCount(DWORD dwFileCount);
+
+bool IsPseudoFileName(const char * szFileName, LPDWORD pdwFileIndex);
+ULONGLONG HashStringJenkins(const char * szFileName);
+
+int ConvertMpqHeaderToFormat4(TMPQArchive * ha, ULONGLONG FileSize, DWORD dwFlags);
+
+DWORD GetDefaultSpecialFileFlags(TMPQArchive * ha, DWORD dwFileSize);
+
+void EncryptMpqBlock(void * pvFileBlock, DWORD dwLength, DWORD dwKey);
+void DecryptMpqBlock(void * pvFileBlock, DWORD dwLength, DWORD dwKey);
+
+DWORD DetectFileKeyBySectorSize(LPDWORD SectorOffsets, DWORD decrypted);
+DWORD DetectFileKeyByContent(void * pvFileContent, DWORD dwFileSize);
+DWORD DecryptFileKey(const char * szFileName, ULONGLONG MpqPos, DWORD dwFileSize, DWORD dwFlags);
+
+bool IsValidMD5(LPBYTE pbMd5);
+bool VerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5);
+void CalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_hash);
+
+//-----------------------------------------------------------------------------
+// Handle validation functions
+
+bool IsValidMpqHandle(TMPQArchive * ha);
+bool IsValidFileHandle(TMPQFile * hf);
+
+//-----------------------------------------------------------------------------
+// Hash table and block table manipulation
+
+TMPQHash * GetFirstHashEntry(TMPQArchive * ha, const char * szFileName);
+TMPQHash * GetNextHashEntry(TMPQArchive * ha, TMPQHash * pFirstHash, TMPQHash * pPrevHash);
+DWORD AllocateHashEntry(TMPQArchive * ha, TFileEntry * pFileEntry);
+DWORD AllocateHetEntry(TMPQArchive * ha, TFileEntry * pFileEntry);
+
+void FindFreeMpqSpace(TMPQArchive * ha, ULONGLONG * pFreeSpacePos);
+
+// Functions that loads and verifies MPQ data bitmap
+int LoadMpqDataBitmap(TMPQArchive * ha, ULONGLONG FileSize, bool * pbFileIsComplete);
+
+// Functions that load the HET and BET tables
+int CreateHashTable(TMPQArchive * ha, DWORD dwHashTableSize);
+int LoadAnyHashTable(TMPQArchive * ha);
+int BuildFileTable(TMPQArchive * ha, ULONGLONG FileSize);
+int SaveMPQTables(TMPQArchive * ha);
+
+TMPQHetTable * CreateHetTable(DWORD dwMaxFileCount, DWORD dwHashBitSize, bool bCreateEmpty);
+void FreeHetTable(TMPQHetTable * pHetTable);
+
+TMPQBetTable * CreateBetTable(DWORD dwMaxFileCount);
+void FreeBetTable(TMPQBetTable * pBetTable);
+
+// Functions for finding files in the file table
+TFileEntry * GetFileEntryAny(TMPQArchive * ha, const char * szFileName);
+TFileEntry * GetFileEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale);
+TFileEntry * GetFileEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcLocale);
+TFileEntry * GetFileEntryByIndex(TMPQArchive * ha, DWORD dwIndex);
+
+// Allocates file name in the file entry
+void AllocateFileName(TFileEntry * pFileEntry, const char * szFileName);
+
+// Allocates new file entry in the MPQ tables. Reuses existing, if possible
+TFileEntry * FindFreeFileEntry(TMPQArchive * ha);
+TFileEntry * AllocateFileEntry(TMPQArchive * ha, const char * szFileName, LCID lcLocale);
+int RenameFileEntry(TMPQArchive * ha, TFileEntry * pFileEntry, const char * szNewFileName);
+void ClearFileEntry(TMPQArchive * ha, TFileEntry * pFileEntry);
+int FreeFileEntry(TMPQArchive * ha, TFileEntry * pFileEntry);
+
+// Invalidates entries for (listfile) and (attributes)
+void InvalidateInternalFiles(TMPQArchive * ha);
+
+//-----------------------------------------------------------------------------
+// Common functions - MPQ File
+
+TMPQFile * CreateMpqFile(TMPQArchive * ha);
+int LoadMpqTable(TMPQArchive * ha, ULONGLONG ByteOffset, void * pvTable, DWORD dwCompressedSize, DWORD dwRealSize, DWORD dwKey);
+int AllocateSectorBuffer(TMPQFile * hf);
+int AllocatePatchInfo(TMPQFile * hf, bool bLoadFromFile);
+int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile);
+int AllocateSectorChecksums(TMPQFile * hf, bool bLoadFromFile);
+void CalculateRawSectorOffset(ULONGLONG & RawFilePos, TMPQFile * hf, DWORD dwSectorOffset);
+int WritePatchInfo(TMPQFile * hf);
+int WriteSectorOffsets(TMPQFile * hf);
+int WriteSectorChecksums(TMPQFile * hf);
+int WriteMemDataMD5(TFileStream * pStream, ULONGLONG RawDataOffs, void * pvRawData, DWORD dwRawDataSize, DWORD dwChunkSize, LPDWORD pcbTotalSize);
+int WriteMpqDataMD5(TFileStream * pStream, ULONGLONG RawDataOffs, DWORD dwRawDataSize, DWORD dwChunkSize);
+void FreeMPQFile(TMPQFile *& hf);
+
+bool IsIncrementalPatchFile(const void * pvData, DWORD cbData, LPDWORD pdwPatchedFileSize);
+int PatchFileData(TMPQFile * hf);
+
+void FreeMPQArchive(TMPQArchive *& ha);
+
+//-----------------------------------------------------------------------------
+// Utility functions
+
+bool CheckWildCard(const char * szString, const char * szWildCard);
+const char * GetPlainFileNameA(const char * szFileName);
+const TCHAR * GetPlainFileNameT(const TCHAR * szFileName);
+bool IsInternalMpqFileName(const char * szFileName);
+
+//-----------------------------------------------------------------------------
+// Support for adding files to the MPQ
+
+int SFileAddFile_Init(
+ TMPQArchive * ha,
+ const char * szArchivedName,
+ ULONGLONG ft,
+ DWORD dwFileSize,
+ LCID lcLocale,
+ DWORD dwFlags,
+ TMPQFile ** phf
+ );
+
+int SFileAddFile_Write(
+ TMPQFile * hf,
+ const void * pvData,
+ DWORD dwSize,
+ DWORD dwCompression
+ );
+
+int SFileAddFile_Finish(
+ TMPQFile * hf
+ );
+
+//-----------------------------------------------------------------------------
+// Attributes support
+
+int SAttrLoadAttributes(TMPQArchive * ha);
+int SAttrFileSaveToMpq(TMPQArchive * ha);
+
+//-----------------------------------------------------------------------------
+// Listfile functions
+
+int SListFileSaveToMpq(TMPQArchive * ha);
+
+//-----------------------------------------------------------------------------
+// Dump data support
+
+#ifdef __STORMLIB_DUMP_DATA__
+void DumpMpqHeader(TMPQHeader * pHeader);
+void DumpHetAndBetTable(TMPQHetTable * pHetTable, TMPQBetTable * pBetTable);
+
+#else
+#define DumpMpqHeader(h) /* */
+#define DumpHetAndBetTable(h, b) /* */
+#endif
+
+#endif // __STORMCOMMON_H__
+
diff --git a/src/StormLib.h b/src/StormLib.h
new file mode 100644
index 0000000..db813d3
--- /dev/null
+++ b/src/StormLib.h
@@ -0,0 +1,988 @@
+/*****************************************************************************/
+/* StormLib.h Copyright (c) Ladislav Zezula 1999-2010 */
+/*---------------------------------------------------------------------------*/
+/* StormLib library v 7.02 */
+/* */
+/* Author : Ladislav Zezula */
+/* E-mail : ladik@zezula.net */
+/* WWW : http://www.zezula.net */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* xx.xx.99 1.00 Lad Created */
+/* 24.03.03 2.50 Lad Version 2.50 */
+/* 02.04.03 3.00 Lad Version 3.00 with compression */
+/* 11.04.03 3.01 Lad Renamed to StormLib.h for compatibility with */
+/* original headers for Storm.dll */
+/* 10.05.03 3.02 Lad Added Pkware DCL compression */
+/* 26.05.03 4.00 Lad Completed all compressions */
+/* 18.06.03 4.01 Lad Added SFileSetFileLocale */
+/* Added SFileExtractFile */
+/* 26.07.03 4.02 Lad Implemented nameless rename and delete */
+/* 26.07.03 4.03 Lad Added support for protected MPQs */
+/* 28.08.03 4.10 Lad Fixed bugs that caused StormLib incorrectly work */
+/* with Diablo I savegames and with files having full */
+/* hash table */
+/* 08.12.03 4.11 DCH Fixed bug in reading file sector larger than 0x1000 */
+/* on certain files. */
+/* Fixed bug in AddFile with MPQ_FILE_REPLACE_EXISTING */
+/* (Thanx Daniel Chiamarello, dchiamarello@madvawes.com)*/
+/* 21.12.03 4.50 Lad Completed port for Mac */
+/* Fixed bug in compacting (if fsize is mul of 0x1000) */
+/* Fixed bug in SCompCompress */
+/* 27.05.04 4.51 Lad Changed memory management from new/delete to our */
+/* own macros */
+/* 22.06.04 4.60 Lad Optimized search. Support for multiple listfiles. */
+/* 30.09.04 4.61 Lad Fixed some bugs (Aaargh !!!) */
+/* Correctly works if HashTableSize > BlockTableSize */
+/* 29.12.04 4.70 Lad Fixed compatibility problem with MPQs from WoW */
+/* 14.07.05 5.00 Lad Added the BZLIB compression support */
+/* Added suport of files stored as single unit */
+/* 17.04.06 5.01 Lad Converted to MS Visual Studio 8.0 */
+/* Fixed issue with protected Warcraft 3 protected maps */
+/* 15.05.06 5.02 Lad Fixed issue with WoW 1.10+ */
+/* 07.09.06 5.10 Lad Fixed processing files longer than 2GB */
+/* 22.11.06 6.00 Lad Support for MPQ archives V2 */
+/* 12.06.07 6.10 Lad Support for (attributes) file */
+/* 10.09.07 6.12 Lad Support for MPQs protected by corrupting hash table */
+/* 03.12.07 6.13 Lad Support for MPQs with hash tbl size > block tbl size */
+/* 07.04.08 6.20 Lad Added SFileFlushArchive */
+/* 09.04.08 Lad Removed FilePointer variable from MPQ handle */
+/* structure, as it caused more problems than benefits */
+/* 12.05.08 6.22 Lad Support for w3xMaster map protector */
+/* 05.10.08 6.23 Lad Support for protectors who set negative values in */
+/* the table of file blocks */
+/* 26.05.09 6.24 Lad Fixed search for multiple lang files with deleted */
+/* entries */
+/* 03.09.09 6.25 Lad Fixed decompression bug in huffmann decompression */
+/* 22.03.10 6.50 Lad New compressions in Starcraft II (LZMA, sparse) */
+/* Fixed compacting MPQs that contain single unit files */
+/* 26.04.10 7.00 Lad Major rewrite */
+/* 08.06.10 7.10 Lad Support for partial MPQs */
+/* 08.07.10 7.11 Lad Support for MPQs v 3.0 */
+/* 20.08.10 7.20 Lad Support for opening multiple MPQs in patch mode */
+/* 20.09.10 8.00 Lad MPQs v 4, HET and BET tables */
+/* 07.01.11 8.01 Lad Write support for MPQs v 3 and 4 */
+/* 15.09.11 8.04 Lad Bug fixes, testing for Diablo III MPQs */
+/* 26.04.12 8.10 Lad Support for data map, added SFileGetArchiveBitmap */
+/* 29.05.12 8.20 Lad C-only interface */
+/*****************************************************************************/
+
+#ifndef __STORMLIB_H__
+#define __STORMLIB_H__
+
+#ifdef _MSC_VER
+#pragma warning(disable:4668) // 'XXX' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
+#pragma warning(disable:4820) // 'XXX' : '2' bytes padding added after data member 'XXX::yyy'
+#endif
+
+#include "StormPort.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//-----------------------------------------------------------------------------
+// Use the apropriate library
+//
+// The library type is encoded in the library name as the following
+// StormLibXYZ.lib
+//
+// X - D for Debug version, R for Release version
+// Y - A for ANSI version, U for Unicode version
+// Z - S for static-linked CRT library, D for multithreaded DLL CRT library
+//
+
+#if defined(_MSC_VER) && !defined(__STORMLIB_SELF__)
+
+ #ifdef _DEBUG // DEBUG VERSIONS
+ #ifndef _UNICODE
+ #ifdef _DLL
+ #pragma comment(lib, "StormLibDAD.lib") // Debug Ansi CRT-DLL version
+ #else
+ #pragma comment(lib, "StormLibDAS.lib") // Debug Ansi CRT-LIB version
+ #endif
+ #else
+ #ifdef _DLL
+ #pragma comment(lib, "StormLibDUD.lib") // Debug Unicode CRT-DLL version
+ #else
+ #pragma comment(lib, "StormLibDUS.lib") // Debug Unicode CRT-LIB version
+ #endif
+ #endif
+ #else // RELEASE VERSIONS
+ #ifndef _UNICODE
+ #ifdef _DLL
+ #pragma comment(lib, "StormLibRAD.lib") // Release Ansi CRT-DLL version
+ #else
+ #pragma comment(lib, "StormLibRAS.lib") // Release Ansi CRT-LIB version
+ #endif
+ #else
+ #ifdef _DLL
+ #pragma comment(lib, "StormLibRUD.lib") // Release Unicode CRT-DLL version
+ #else
+ #pragma comment(lib, "StormLibRUS.lib") // Release Unicode CRT-LIB version
+ #endif
+ #endif
+ #endif
+
+#endif
+
+//-----------------------------------------------------------------------------
+// Defines
+
+#define ID_MPQ 0x1A51504D // MPQ archive header ID ('MPQ\x1A')
+#define ID_MPQ_USERDATA 0x1B51504D // MPQ userdata entry ('MPQ\x1B')
+
+#define ERROR_AVI_FILE 10000 // No MPQ file, but AVI file.
+#define ERROR_UNKNOWN_FILE_KEY 10001 // Returned by SFileReadFile when can't find file key
+#define ERROR_CHECKSUM_ERROR 10002 // Returned by SFileReadFile when sector CRC doesn't match
+#define ERROR_INTERNAL_FILE 10003 // The given operation is not allowed on internal file
+#define ERROR_BASE_FILE_MISSING 10004 // The file is present as incremental patch file, but base file is missing
+#define ERROR_MARKED_FOR_DELETE 10005 // The file was marked as "deleted" in the MPQ
+
+// Values for SFileCreateArchive
+#define HASH_TABLE_SIZE_MIN 0x00000004 // Minimum acceptable hash table size
+#define HASH_TABLE_SIZE_DEFAULT 0x00001000 // Default hash table size for empty MPQs
+#define HASH_TABLE_SIZE_MAX 0x00080000 // Maximum acceptable hash table size
+
+#define HASH_ENTRY_DELETED 0xFFFFFFFE // Block index for deleted entry in the hash table
+#define HASH_ENTRY_FREE 0xFFFFFFFF // Block index for free entry in the hash table
+
+#define HET_ENTRY_DELETED 0x80 // HET hash value for a deleted entry
+#define HET_ENTRY_FREE 0x00 // HET hash value for free entry
+
+#define HASH_STATE_SIZE 0x60 // Size of LibTomCrypt's hash_state structure
+
+#define MPQ_PATCH_PREFIX_LEN 0x20 // Maximum length of the patch prefix
+
+// Values for SFileOpenArchive
+#define SFILE_OPEN_HARD_DISK_FILE 2 // Open the archive on HDD
+#define SFILE_OPEN_CDROM_FILE 3 // Open the archive only if it is on CDROM
+
+// Values for SFileOpenFile
+#define SFILE_OPEN_FROM_MPQ 0x00000000 // Open the file from the MPQ archive
+#define SFILE_OPEN_BASE_FILE 0xFFFFFFFD // Reserved for StormLib internal use
+#define SFILE_OPEN_ANY_LOCALE 0xFFFFFFFE // Reserved for StormLib internal use
+#define SFILE_OPEN_LOCAL_FILE 0xFFFFFFFF // Open a local file
+
+// Flags for TMPQArchive::dwFlags
+#define MPQ_FLAG_READ_ONLY 0x00000001 // If set, the MPQ has been open for read-only access
+#define MPQ_FLAG_CHANGED 0x00000002 // If set, the MPQ tables have been changed
+#define MPQ_FLAG_PROTECTED 0x00000004 // Set on protected MPQs (like W3M maps)
+#define MPQ_FLAG_CHECK_SECTOR_CRC 0x00000008 // Checking sector CRC when reading files
+#define MPQ_FLAG_NEED_FIX_SIZE 0x00000010 // Used during opening the archive
+#define MPQ_FLAG_INV_LISTFILE 0x00000020 // If set, it means that the (listfile) has been invalidated
+#define MPQ_FLAG_INV_ATTRIBUTES 0x00000040 // If set, it means that the (attributes) has been invalidated
+
+// Return value for SFileGetFileSize and SFileSetFilePointer
+#define SFILE_INVALID_SIZE 0xFFFFFFFF
+#define SFILE_INVALID_POS 0xFFFFFFFF
+#define SFILE_INVALID_ATTRIBUTES 0xFFFFFFFF
+
+// Flags for SFileAddFile
+#define MPQ_FILE_IMPLODE 0x00000100 // Implode method (By PKWARE Data Compression Library)
+#define MPQ_FILE_COMPRESS 0x00000200 // Compress methods (By multiple methods)
+#define MPQ_FILE_COMPRESSED 0x0000FF00 // File is compressed
+#define MPQ_FILE_ENCRYPTED 0x00010000 // Indicates whether file is encrypted
+#define MPQ_FILE_FIX_KEY 0x00020000 // File decryption key has to be fixed
+#define MPQ_FILE_PATCH_FILE 0x00100000 // The file is a patch file. Raw file data begin with TPatchInfo structure
+#define MPQ_FILE_SINGLE_UNIT 0x01000000 // File is stored as a single unit, rather than split into sectors (Thx, Quantam)
+#define MPQ_FILE_DELETE_MARKER 0x02000000 // File is a deletion marker. Used in MPQ patches, indicating that the file no longer exists.
+#define MPQ_FILE_SECTOR_CRC 0x04000000 // File has checksums for each sector.
+ // Ignored if file is not compressed or imploded.
+#define MPQ_FILE_EXISTS 0x80000000 // Set if file exists, reset when the file was deleted
+#define MPQ_FILE_REPLACEEXISTING 0x80000000 // Replace when the file exist (SFileAddFile)
+
+#define MPQ_FILE_VALID_FLAGS (MPQ_FILE_IMPLODE | \
+ MPQ_FILE_COMPRESS | \
+ MPQ_FILE_ENCRYPTED | \
+ MPQ_FILE_FIX_KEY | \
+ MPQ_FILE_PATCH_FILE | \
+ MPQ_FILE_SINGLE_UNIT | \
+ MPQ_FILE_DELETE_MARKER | \
+ MPQ_FILE_SECTOR_CRC | \
+ MPQ_FILE_EXISTS)
+
+// Compression types for multiple compressions
+#define MPQ_COMPRESSION_HUFFMANN 0x01 // Huffmann compression (used on WAVE files only)
+#define MPQ_COMPRESSION_ZLIB 0x02 // ZLIB compression
+#define MPQ_COMPRESSION_PKWARE 0x08 // PKWARE DCL compression
+#define MPQ_COMPRESSION_BZIP2 0x10 // BZIP2 compression (added in Warcraft III)
+#define MPQ_COMPRESSION_SPARSE 0x20 // Sparse compression (added in Starcraft 2)
+#define MPQ_COMPRESSION_ADPCM_MONO 0x40 // IMA ADPCM compression (mono)
+#define MPQ_COMPRESSION_ADPCM_STEREO 0x80 // IMA ADPCM compression (stereo)
+#define MPQ_COMPRESSION_LZMA 0x12 // LZMA compression. Added in Starcraft 2. This value is NOT a combination of flags.
+#define MPQ_COMPRESSION_NEXT_SAME 0xFFFFFFFF // Same compression
+
+// Constants for SFileAddWave
+#define MPQ_WAVE_QUALITY_HIGH 0 // Best quality, the worst compression
+#define MPQ_WAVE_QUALITY_MEDIUM 1 // Medium quality, medium compression
+#define MPQ_WAVE_QUALITY_LOW 2 // Low quality, the best compression
+
+// Signatures for HET and BET table
+#define HET_TABLE_SIGNATURE 0x1A544548 // 'HET\x1a'
+#define BET_TABLE_SIGNATURE 0x1A544542 // 'BET\x1a'
+
+// Decryption keys for MPQ tables
+#define MPQ_KEY_HASH_TABLE 0xC3AF3770 // Obtained by HashString("(hash table)", MPQ_HASH_FILE_KEY)
+#define MPQ_KEY_BLOCK_TABLE 0xEC83B3A3 // Obtained by HashString("(block table)", MPQ_HASH_FILE_KEY)
+
+// Block map defines
+#define MPQ_DATA_BITMAP_SIGNATURE 0x33767470 // Signature of the MPQ data bitmap ('ptv3')
+
+// Constants for SFileGetFileInfo
+#define SFILE_INFO_ARCHIVE_NAME 1 // MPQ size (value from header)
+#define SFILE_INFO_ARCHIVE_SIZE 2 // MPQ size (value from header)
+#define SFILE_INFO_MAX_FILE_COUNT 3 // Max number of files in the MPQ
+#define SFILE_INFO_HASH_TABLE_SIZE 4 // Size of hash table, in entries
+#define SFILE_INFO_BLOCK_TABLE_SIZE 5 // Number of entries in the block table
+#define SFILE_INFO_SECTOR_SIZE 6 // Size of file sector (in bytes)
+#define SFILE_INFO_HASH_TABLE 7 // Pointer to Hash table (TMPQHash *)
+#define SFILE_INFO_BLOCK_TABLE 8 // Pointer to Block Table (TMPQBlock *)
+#define SFILE_INFO_NUM_FILES 9 // Real number of files within archive
+#define SFILE_INFO_STREAM_FLAGS 10 // Stream flags for the MPQ. See STREAM_FLAG_XXX
+#define SFILE_INFO_IS_READ_ONLY 11 // TRUE of the MPQ was open as read only
+//------
+#define SFILE_INFO_HASH_INDEX 100 // Hash index of file in MPQ
+#define SFILE_INFO_CODENAME1 101 // The first codename of the file
+#define SFILE_INFO_CODENAME2 102 // The second codename of the file
+#define SFILE_INFO_LOCALEID 103 // Locale ID of file in MPQ
+#define SFILE_INFO_BLOCKINDEX 104 // Index to Block Table
+#define SFILE_INFO_FILE_SIZE 105 // Original file size (from the block table)
+#define SFILE_INFO_COMPRESSED_SIZE 106 // Compressed file size (from the block table)
+#define SFILE_INFO_FLAGS 107 // File flags
+#define SFILE_INFO_POSITION 108 // File position within archive
+ // Note: for current pointer in open MPQ file,
+ // use SFileSetFilePointer(hFile, 0, NULL, FILE_CURRENT);
+#define SFILE_INFO_KEY 109 // File decryption key
+#define SFILE_INFO_KEY_UNFIXED 110 // Decryption key not fixed to file pos and size
+#define SFILE_INFO_FILETIME 111 // TMPQFileTime
+#define SFILE_INFO_PATCH_CHAIN 112 // Chain of patches
+
+#define LISTFILE_NAME "(listfile)" // Name of internal listfile
+#define SIGNATURE_NAME "(signature)" // Name of internal signature
+#define ATTRIBUTES_NAME "(attributes)" // Name of internal attributes file
+#define PATCH_METADATA_NAME "(patch_metadata)"
+
+#define STORMLIB_VERSION 0x0814 // Current version of StormLib (8.10)
+#define STORMLIB_VERSION_STRING "8.20"
+
+#define MPQ_FORMAT_VERSION_1 0 // Up to The Burning Crusade
+#define MPQ_FORMAT_VERSION_2 1 // The Burning Crusade and newer
+#define MPQ_FORMAT_VERSION_3 2 // WoW Cataclysm Beta
+#define MPQ_FORMAT_VERSION_4 3 // WoW Cataclysm and newer
+
+// Flags for MPQ attributes
+#define MPQ_ATTRIBUTE_CRC32 0x00000001 // The "(attributes)" contains CRC32 for each file
+#define MPQ_ATTRIBUTE_FILETIME 0x00000002 // The "(attributes)" contains file time for each file
+#define MPQ_ATTRIBUTE_MD5 0x00000004 // The "(attributes)" contains MD5 for each file
+#define MPQ_ATTRIBUTE_PATCH_BIT 0x00000008 // The "(attributes)" contains a patch bit for each file
+#define MPQ_ATTRIBUTE_ALL 0x0000000F // Summary mask
+
+#define MPQ_ATTRIBUTES_V1 100 // (attributes) format version 1.00
+
+// Flags for SFileOpenArchive
+#define BASE_PROVIDER_FILE 0x00000000 // Base data source is a file
+#define BASE_PROVIDER_MAP 0x00000001 // Base data source is memory-mapped file
+#define BASE_PROVIDER_HTTP 0x00000002 // Base data source is a file on web server
+#define BASE_PROVIDER_MASK 0x0000000F // Mask for base provider value
+
+#define STREAM_PROVIDER_LINEAR 0x00000000 // Stream is linear with no offset mapping
+#define STREAM_PROVIDER_PARTIAL 0x00000010 // Stream is partial file (.part)
+#define STREAM_PROVIDER_ENCRYPTED 0x00000020 // Stream is an encrypted MPQ
+#define STREAM_PROVIDER_MASK 0x000000F0 // Mask for stream provider value
+
+#define STREAM_FLAG_READ_ONLY 0x00000100 // Stream is read only
+#define STREAM_FLAG_WRITE_SHARE 0x00000200 // Allow write sharing when open for write
+#define STREAM_FLAG_MASK 0x0000FF00 // Mask for stream flags
+#define STREAM_OPTIONS_MASK 0x0000FFFF // Mask for all stream options
+
+#define MPQ_OPEN_NO_LISTFILE 0x00010000 // Don't load the internal listfile
+#define MPQ_OPEN_NO_ATTRIBUTES 0x00020000 // Don't open the attributes
+#define MPQ_OPEN_FORCE_MPQ_V1 0x00040000 // Always open the archive as MPQ v 1.00, ignore the "wFormatVersion" variable in the header
+#define MPQ_OPEN_CHECK_SECTOR_CRC 0x00080000 // On files with MPQ_FILE_SECTOR_CRC, the CRC will be checked when reading file
+
+// Deprecated
+#define MPQ_OPEN_READ_ONLY STREAM_FLAG_READ_ONLY
+#define MPQ_OPEN_ENCRYPTED STREAM_PROVIDER_ENCRYPTED
+
+// Flags for SFileCreateArchive
+#define MPQ_CREATE_ATTRIBUTES 0x00100000 // Also add the (attributes) file
+#define MPQ_CREATE_ARCHIVE_V1 0x00000000 // Creates archive of version 1 (size up to 4GB)
+#define MPQ_CREATE_ARCHIVE_V2 0x01000000 // Creates archive of version 2 (larger than 4 GB)
+#define MPQ_CREATE_ARCHIVE_V3 0x02000000 // Creates archive of version 3
+#define MPQ_CREATE_ARCHIVE_V4 0x03000000 // Creates archive of version 4
+#define MPQ_CREATE_ARCHIVE_VMASK 0x0F000000 // Mask for archive version
+
+#define FLAGS_TO_FORMAT_SHIFT 24 // (MPQ_CREATE_ARCHIVE_V4 >> FLAGS_TO_FORMAT_SHIFT) => MPQ_FORMAT_VERSION_4
+
+// Flags for SFileVerifyFile
+#define SFILE_VERIFY_SECTOR_CRC 0x00000001 // Verify sector checksum for the file, if available
+#define SFILE_VERIFY_FILE_CRC 0x00000002 // Verify file CRC, if available
+#define SFILE_VERIFY_FILE_MD5 0x00000004 // Verify file MD5, if available
+#define SFILE_VERIFY_RAW_MD5 0x00000008 // Verify raw file MD5, if available
+#define SFILE_VERIFY_ALL 0x0000000F // Verify every checksum possible
+
+// Return values for SFileVerifyFile
+#define VERIFY_OPEN_ERROR 0x0001 // Failed to open the file
+#define VERIFY_READ_ERROR 0x0002 // Failed to read all data from the file
+#define VERIFY_FILE_HAS_SECTOR_CRC 0x0004 // File has sector CRC
+#define VERIFY_FILE_SECTOR_CRC_ERROR 0x0008 // Sector CRC check failed
+#define VERIFY_FILE_HAS_CHECKSUM 0x0010 // File has CRC32
+#define VERIFY_FILE_CHECKSUM_ERROR 0x0020 // CRC32 check failed
+#define VERIFY_FILE_HAS_MD5 0x0040 // File has data MD5
+#define VERIFY_FILE_MD5_ERROR 0x0080 // MD5 check failed
+#define VERIFY_FILE_HAS_RAW_MD5 0x0100 // File has raw data MD5
+#define VERIFY_FILE_RAW_MD5_ERROR 0x0200 // Raw MD5 check failed
+#define VERIFY_FILE_ERROR_MASK (VERIFY_OPEN_ERROR | VERIFY_READ_ERROR | VERIFY_FILE_SECTOR_CRC_ERROR | VERIFY_FILE_CHECKSUM_ERROR | VERIFY_FILE_MD5_ERROR | VERIFY_FILE_RAW_MD5_ERROR)
+
+// Flags for SFileVerifyRawData (for MPQs version 4.0 or higher)
+#define SFILE_VERIFY_MPQ_HEADER 0x0001 // Verify raw MPQ header
+#define SFILE_VERIFY_HET_TABLE 0x0002 // Verify raw data of the HET table
+#define SFILE_VERIFY_BET_TABLE 0x0003 // Verify raw data of the BET table
+#define SFILE_VERIFY_HASH_TABLE 0x0004 // Verify raw data of the hash table
+#define SFILE_VERIFY_BLOCK_TABLE 0x0005 // Verify raw data of the block table
+#define SFILE_VERIFY_HIBLOCK_TABLE 0x0006 // Verify raw data of the hi-block table
+#define SFILE_VERIFY_FILE 0x0007 // Verify raw data of a file
+
+// Return values for SFileVerifyArchive
+#define ERROR_NO_SIGNATURE 0 // There is no signature in the MPQ
+#define ERROR_VERIFY_FAILED 1 // There was an error during verifying signature (like no memory)
+#define ERROR_WEAK_SIGNATURE_OK 2 // There is a weak signature and sign check passed
+#define ERROR_WEAK_SIGNATURE_ERROR 3 // There is a weak signature but sign check failed
+#define ERROR_STRONG_SIGNATURE_OK 4 // There is a strong signature and sign check passed
+#define ERROR_STRONG_SIGNATURE_ERROR 5 // There is a strong signature but sign check failed
+
+#ifndef MD5_DIGEST_SIZE
+#define MD5_DIGEST_SIZE 0x10
+#endif
+
+#ifndef SHA1_DIGEST_SIZE
+#define SHA1_DIGEST_SIZE 0x14 // 160 bits
+#endif
+
+#ifndef LANG_NEUTRAL
+#define LANG_NEUTRAL 0x00 // Neutral locale
+#endif
+
+//-----------------------------------------------------------------------------
+// Callback functions
+
+// Values for compact callback
+#define CCB_CHECKING_FILES 1 // Checking archive (dwParam1 = current, dwParam2 = total)
+#define CCB_CHECKING_HASH_TABLE 2 // Checking hash table (dwParam1 = current, dwParam2 = total)
+#define CCB_COPYING_NON_MPQ_DATA 3 // Copying non-MPQ data: No params used
+#define CCB_COMPACTING_FILES 4 // Compacting archive (dwParam1 = current, dwParam2 = total)
+#define CCB_CLOSING_ARCHIVE 5 // Closing archive: No params used
+
+typedef void (WINAPI * SFILE_ADDFILE_CALLBACK)(void * pvUserData, DWORD dwBytesWritten, DWORD dwTotalBytes, bool bFinalCall);
+typedef void (WINAPI * SFILE_COMPACT_CALLBACK)(void * pvUserData, DWORD dwWorkType, ULONGLONG BytesProcessed, ULONGLONG TotalBytes);
+
+typedef struct TFileStream TFileStream;
+
+//-----------------------------------------------------------------------------
+// Structure for bit arrays used for HET and BET tables
+
+typedef struct _TBitArray
+{
+ DWORD NumberOfBits; // Total number of bits that are available
+ BYTE Elements[1]; // Array of elements (variable length)
+} TBitArray;
+
+void GetBits(TBitArray * array, unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultSize);
+void SetBits(TBitArray * array, unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultSize);
+
+// Structure for file bitmap. Used by SFileGetArchiveBitmap
+typedef struct _TFileBitmap
+{
+ ULONGLONG StartOffset; // Starting offset of the file, covered by bitmap
+ ULONGLONG EndOffset; // Ending offset of the file, covered by bitmap
+ DWORD IsComplete; // If nonzero, no blocks are missing
+ DWORD BitmapSize; // Size of the file bitmap (in bytes)
+ DWORD BlockSize; // Size of one block, in bytes
+ DWORD Reserved; // Alignment
+
+ // Followed by file bitmap (variable length), array of BYTEs)
+} TFileBitmap;
+
+//-----------------------------------------------------------------------------
+// Structures related to MPQ format
+//
+// Note: All structures in this header file are supposed to remain private
+// to StormLib. The structures may (and will) change over time, as the MPQ
+// file format evolves. Programmers directly using these structures need to
+// be aware of this. And the last, but not least, NEVER do any modifications
+// to those structures directly, always use SFile* functions.
+//
+
+#define MPQ_HEADER_SIZE_V1 0x20
+#define MPQ_HEADER_SIZE_V2 0x2C
+#define MPQ_HEADER_SIZE_V3 0x44
+#define MPQ_HEADER_SIZE_V4 0xD0
+
+typedef struct _TMPQUserData
+{
+ // The ID_MPQ_USERDATA ('MPQ\x1B') signature
+ DWORD dwID;
+
+ // Maximum size of the user data
+ DWORD cbUserDataSize;
+
+ // Offset of the MPQ header, relative to the begin of this header
+ DWORD dwHeaderOffs;
+
+ // Appears to be size of user data header (Starcraft II maps)
+ DWORD cbUserDataHeader;
+} TMPQUserData;
+
+// MPQ file header
+//
+// We have to make sure that the header is packed OK.
+// Reason: A 64-bit integer at the beginning of 3.0 part,
+// which is offset 0x2C
+#pragma pack(push, 1)
+typedef struct _TMPQHeader
+{
+ // The ID_MPQ ('MPQ\x1A') signature
+ DWORD dwID;
+
+ // Size of the archive header
+ DWORD dwHeaderSize;
+
+ // 32-bit size of MPQ archive
+ // 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 hi-block table (whichever is largest).
+ DWORD dwArchiveSize;
+
+ // 0 = Format 1 (up to The Burning Crusade)
+ // 1 = Format 2 (The Burning Crusade and newer)
+ // 2 = Format 3 (WoW - Cataclysm beta or newer)
+ // 3 = Format 4 (WoW - Cataclysm beta or newer)
+ 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;
+
+ // 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;
+
+ //-- MPQ HEADER v 2 -------------------------------------------
+
+ // Offset to the beginning of array of 16-bit high parts of file offsets.
+ ULONGLONG HiBlockTablePos64;
+
+ // High 16 bits of the hash table offset for large archives.
+ USHORT wHashTablePosHi;
+
+ // High 16 bits of the block table offset for large archives.
+ USHORT wBlockTablePosHi;
+
+ //-- MPQ HEADER v 3 -------------------------------------------
+
+ // 64-bit version of the archive size
+ ULONGLONG ArchiveSize64;
+
+ // 64-bit position of the BET table
+ ULONGLONG BetTablePos64;
+
+ // 64-bit position of the HET table
+ ULONGLONG HetTablePos64;
+
+ //-- MPQ HEADER v 4 -------------------------------------------
+
+ // Compressed size of the hash table
+ ULONGLONG HashTableSize64;
+
+ // Compressed size of the block table
+ ULONGLONG BlockTableSize64;
+
+ // Compressed size of the hi-block table
+ ULONGLONG HiBlockTableSize64;
+
+ // Compressed size of the HET block
+ ULONGLONG HetTableSize64;
+
+ // Compressed size of the BET block
+ ULONGLONG BetTableSize64;
+
+ // Size of raw data chunk to calculate MD5.
+ // MD5 of each data chunk follows the raw file data.
+ DWORD dwRawChunkSize;
+
+ // MD5 of MPQ tables
+ unsigned char MD5_BlockTable[MD5_DIGEST_SIZE]; // MD5 of the block table before decryption
+ unsigned char MD5_HashTable[MD5_DIGEST_SIZE]; // MD5 of the hash table before decryption
+ unsigned char MD5_HiBlockTable[MD5_DIGEST_SIZE]; // MD5 of the hi-block table
+ unsigned char MD5_BetTable[MD5_DIGEST_SIZE]; // MD5 of the BET table before decryption
+ unsigned char MD5_HetTable[MD5_DIGEST_SIZE]; // MD5 of the HET table before decryption
+ unsigned char MD5_MpqHeader[MD5_DIGEST_SIZE]; // MD5 of the MPQ header from signature to (including) MD5_HetTable
+} TMPQHeader;
+#pragma pack(pop)
+
+
+// Hash entry. All files in the archive are searched by their hashes.
+typedef struct _TMPQHash
+{
+ // The hash of the file path, using method A.
+ DWORD dwName1;
+
+ // The hash of the file path, using method B.
+ DWORD dwName2;
+
+#ifdef PLATFORM_LITTLE_ENDIAN
+
+ // 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.
+ USHORT lcLocale;
+
+ // The platform the file is used for. 0 indicates the default platform.
+ // No other values have been observed.
+ // Note: wPlatform is actually just BYTE, but since it has never been used, we don't care.
+ USHORT wPlatform;
+
+#else
+
+ USHORT wPlatform;
+ USHORT lcLocale;
+
+#endif
+
+ // 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;
+} TMPQHash;
+
+
+// File description block contains informations about the file
+typedef struct _TMPQBlock
+{
+ // Offset of the beginning of the file, relative to the beginning of the archive.
+ DWORD dwFilePos;
+
+ // Compressed file size
+ DWORD dwCSize;
+
+ // Only valid if the block is a file; otherwise meaningless, and should be 0.
+ // If the file is compressed, this is the size of the uncompressed file data.
+ DWORD dwFSize;
+
+ // Flags for the file. See MPQ_FILE_XXXX constants
+ DWORD dwFlags;
+} TMPQBlock;
+
+// Patch file information, preceding the sector offset table
+typedef struct _TPatchInfo
+{
+ DWORD dwLength; // Length of patch info header, in bytes
+ DWORD dwFlags; // Flags. 0x80000000 = MD5 (?)
+ DWORD dwDataSize; // Uncompressed size of the patch file
+ BYTE md5[0x10]; // MD5 of the entire patch file after decompression
+
+ // Followed by the sector table (variable length)
+} TPatchInfo;
+
+// Header for PTCH files
+typedef struct _TPatchHeader
+{
+ //-- 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
+} TPatchHeader;
+
+#define SIZE_OF_XFRM_HEADER 0x0C
+
+// This is the combined file entry for maintaining file list in the MPQ.
+// This structure is combined from block table, hi-block table,
+// (attributes) file and from (listfile).
+typedef struct _TFileEntry
+{
+ ULONGLONG ByteOffset; // Position of the file content in the MPQ, relative to the MPQ header
+ ULONGLONG FileTime; // FileTime from the (attributes) file. 0 if not present.
+ ULONGLONG BetHash; // Lower part of the file name hash. Only used when the MPQ has BET table.
+ DWORD dwHashIndex; // Index to the hash table. Only used when the MPQ has classic hash table
+ DWORD dwHetIndex; // Index to the HET table. Only used when the MPQ has HET table
+ DWORD dwFileSize; // Decompressed size of the file
+ DWORD dwCmpSize; // Compressed size of the file (i.e., size of the file data in the MPQ)
+ DWORD dwFlags; // File flags (from block table)
+ USHORT lcLocale; // Locale ID for the file
+ USHORT wPlatform; // Platform ID for the file
+ DWORD dwCrc32; // CRC32 from (attributes) file. 0 if not present.
+ unsigned char md5[MD5_DIGEST_SIZE]; // File MD5 from the (attributes) file. 0 if not present.
+ char * szFileName; // File name. NULL if not known.
+} TFileEntry;
+
+// Common header for HET and BET tables
+typedef struct _TMPQExtTable
+{
+ DWORD dwSignature; // 'HET\x1A' or 'BET\x1A'
+ DWORD dwVersion; // Version. Seems to be always 1
+ DWORD dwDataSize; // Size of the contained table
+
+ // Followed by the table header
+ // Followed by the table data
+
+} TMPQExtTable;
+
+//
+// MPQ data bitmap, can be found at (FileSize - sizeof(TMPQBlockMap))
+//
+// There is bit map of the entire MPQ before TMPQBitmap. Each 0x4000-byte
+// block is represented by one bit (including the last, eventually incomplete block).
+//
+typedef struct _TMPQBitmap
+{
+ DWORD dwSignature; // 'ptv3' (MPQ_BLOCK_MAP_SIGNATURE)
+ DWORD dwAlways3; // Unknown, seems to always have value of 3
+ DWORD dwBuildNumber; // Game build number for that MPQ
+ DWORD dwMapOffsetLo; // Low 32-bits of the offset of the bit map
+ DWORD dwMapOffsetHi; // High 32-bits of the offset of the bit map
+ DWORD dwBlockSize; // Size of one block (usually 0x4000 bytes)
+} TMPQBitmap;
+
+// Structure for parsed HET table
+typedef struct _TMPQHetTable
+{
+ TBitArray * pBetIndexes; // Bit array of indexes to BET tables
+ LPBYTE pHetHashes; // Array of HET hashes. Each entry has size of 1 byte
+ ULONGLONG AndMask64; // AND mask used for calculating file name hash
+ ULONGLONG OrMask64; // OR mask used for setting the highest bit of the file name hash
+
+ DWORD dwIndexSizeTotal; // Total size of one entry in pBetIndexes (in bits)
+ DWORD dwIndexSizeExtra; // Extra bits in the entry in pBetIndexes
+ DWORD dwIndexSize; // Effective size of one entry in pBetIndexes (in bits)
+ DWORD dwMaxFileCount; // Maximum number of files in the MPQ
+ DWORD dwHashTableSize; // Number of entries in pBetHashes
+ DWORD dwHashBitSize; // Effective number of bits in the hash
+} TMPQHetTable;
+
+// Structure for parsed BET table
+typedef struct _TMPQBetTable
+{
+ TBitArray * pBetHashes; // Array of BET hashes
+ TBitArray * pFileTable; // Bit-based file table
+ LPDWORD pFileFlags; // Array of file flags
+
+ DWORD dwTableEntrySize; // Size of one table entry, in bits
+ DWORD dwBitIndex_FilePos; // Bit index of the file position in the table entry
+ DWORD dwBitIndex_FileSize; // Bit index of the file size in the table entry
+ DWORD dwBitIndex_CmpSize; // Bit index of the compressed size in the table entry
+ DWORD dwBitIndex_FlagIndex; // Bit index of the flag index in the table entry
+ DWORD dwBitIndex_Unknown; // Bit index of ??? in the table entry
+ DWORD dwBitCount_FilePos; // Size of file offset (in bits) within table entry
+ DWORD dwBitCount_FileSize; // Size of file size (in bits) within table entry
+ DWORD dwBitCount_CmpSize; // Size of compressed file size (in bits) within table entry
+ DWORD dwBitCount_FlagIndex; // Size of flag index (in bits) within table entry
+ DWORD dwBitCount_Unknown; // Size of ??? (in bits) within table entry
+ DWORD dwBetHashSizeTotal; // Total size of bet hash
+ DWORD dwBetHashSizeExtra; // Extra bits in the bet hash
+ DWORD dwBetHashSize; // Effective size of the bet hash
+ DWORD dwFileCount; // Number of files (usually equal to maximum number of files)
+ DWORD dwFlagCount; // Number of entries in pFileFlags
+} TMPQBetTable;
+
+// Archive handle structure
+typedef struct _TMPQArchive
+{
+ TFileStream * pStream; // Open stream for the MPQ
+
+ ULONGLONG UserDataPos; // Position of user data (relative to the begin of the file)
+ ULONGLONG MpqPos; // MPQ header offset (relative to the begin of the file)
+
+ struct _TMPQArchive * haPatch; // Pointer to patch archive, if any
+ struct _TMPQArchive * haBase; // Pointer to base ("previous version") archive, if any
+ char szPatchPrefix[MPQ_PATCH_PREFIX_LEN]; // Prefix for file names in patch MPQs
+ size_t cchPatchPrefix; // Length of the patch prefix, in characters
+
+ TMPQUserData * pUserData; // MPQ user data (NULL if not present in the file)
+ TMPQHeader * pHeader; // MPQ file header
+ TMPQBitmap * pBitmap; // MPQ bitmap
+ TMPQHash * pHashTable; // Hash table
+ TMPQHetTable * pHetTable; // Het table
+ TFileEntry * pFileTable; // File table
+
+ TMPQUserData UserData; // MPQ user data. Valid only when ID_MPQ_USERDATA has been found
+ BYTE HeaderData[MPQ_HEADER_SIZE_V4]; // Storage for MPQ header
+
+ DWORD dwHETBlockSize;
+ DWORD dwBETBlockSize;
+ DWORD dwFileTableSize; // Current size of the file table, e.g. index of the entry past the last occupied one
+ DWORD dwMaxFileCount; // Maximum number of files in the MPQ
+ DWORD dwSectorSize; // Default size of one file sector
+ DWORD dwFileFlags1; // Flags for (listfile)
+ DWORD dwFileFlags2; // Flags for (attributes)
+ DWORD dwAttrFlags; // Flags for the (attributes) file, see MPQ_ATTRIBUTE_XXX
+ DWORD dwFlags; // See MPQ_FLAG_XXXXX
+} TMPQArchive;
+
+// File handle structure
+typedef struct _TMPQFile
+{
+ TFileStream * pStream; // File stream. Only used on local files
+ TMPQArchive * ha; // Archive handle
+ TFileEntry * pFileEntry; // File entry for the file
+ DWORD dwFileKey; // Decryption key
+ DWORD dwFilePos; // Current file position
+ ULONGLONG RawFilePos; // Offset in MPQ archive (relative to file begin)
+ ULONGLONG MpqFilePos; // Offset in MPQ archive (relative to MPQ header)
+ DWORD dwMagic; // 'FILE'
+
+ struct _TMPQFile * hfPatchFile; // Pointer to opened patch file
+ TPatchHeader * pPatchHeader; // Patch header. Only used if the file is a patch file
+ LPBYTE pbFileData; // Loaded and patched file data. Only used if the file is a patch file
+ DWORD cbFileData; // Size of loaded patched data
+
+ TPatchInfo * pPatchInfo; // Patch info block, preceding the sector table
+ DWORD * SectorOffsets; // Position of each file sector, relative to the begin of the file. Only for compressed files.
+ DWORD * SectorChksums; // Array of sector checksums (either ADLER32 or MD5) values for each file sector
+ DWORD dwSectorCount; // Number of sectors in the file
+ DWORD dwPatchedFileSize; // Size of patched file. Used when saving patch file to the MPQ
+ DWORD dwDataSize; // Size of data in the file (on patch files, this differs from file size in block table entry)
+
+ LPBYTE pbFileSector; // Last loaded file sector. For single unit files, entire file content
+ DWORD dwSectorOffs; // File position of currently loaded file sector
+ DWORD dwSectorSize; // Size of the file sector. For single unit files, this is equal to the file size
+
+ unsigned char hctx[HASH_STATE_SIZE];// Hash state for MD5. Used when saving file to MPQ
+ DWORD dwCrc32; // CRC32 value, used when saving file to MPQ
+
+ bool bLoadedSectorCRCs; // If true, we already tried to load sector CRCs
+ bool bCheckSectorCRCs; // If true, then SFileReadFile will check sector CRCs when reading the file
+ bool bIsWriteHandle; // If true, this handle has been created by SFileCreateFile
+ bool bErrorOccured; // If true, then at least one error occured during saving the file to the archive
+} TMPQFile;
+
+// Structure for SFileFindFirstFile and SFileFindNextFile
+typedef struct _SFILE_FIND_DATA
+{
+ char cFileName[MAX_PATH]; // Full name of the found file
+ char * szPlainName; // Plain name of the found file
+ DWORD dwHashIndex; // Hash table index for the file
+ DWORD dwBlockIndex; // Block table index for the file
+ DWORD dwFileSize; // File size in bytes
+ DWORD dwFileFlags; // MPQ file flags
+ DWORD dwCompSize; // Compressed file size
+ DWORD dwFileTimeLo; // Low 32-bits of the file time (0 if not present)
+ DWORD dwFileTimeHi; // High 32-bits of the file time (0 if not present)
+ LCID lcLocale; // Locale version
+
+} SFILE_FIND_DATA, *PSFILE_FIND_DATA;
+
+typedef struct _SFILE_CREATE_MPQ
+{
+ DWORD cbSize; // Size of this structure, in bytes
+ DWORD dwMpqVersion; // Version of the MPQ to be created
+ void *pvUserData; // Reserved, must be NULL
+ DWORD cbUserData; // Reserved, must be 0
+ DWORD dwStreamFlags; // Stream flags for creating the MPQ
+ DWORD dwFileFlags1; // File flags for (listfile). 0 = default
+ DWORD dwFileFlags2; // File flags for (attributes). 0 = default
+ DWORD dwAttrFlags; // Flags for the (attributes) file. If 0, no attributes will be created
+ DWORD dwSectorSize; // Sector size for compressed files
+ DWORD dwRawChunkSize; // Size of raw data chunk
+ DWORD dwMaxFileCount; // File limit for the MPQ
+
+} SFILE_CREATE_MPQ, *PSFILE_CREATE_MPQ;
+
+//-----------------------------------------------------------------------------
+// Stream support - functions
+
+TFileStream * FileStream_CreateFile(const TCHAR * szFileName, DWORD dwStreamFlags);
+TFileStream * FileStream_OpenFile(const TCHAR * szFileName, DWORD dwStreamFlags);
+TCHAR * FileStream_GetFileName(TFileStream * pStream);
+bool FileStream_IsReadOnly(TFileStream * pStream);
+bool FileStream_Read(TFileStream * pStream, ULONGLONG * pByteOffset, void * pvBuffer, DWORD dwBytesToRead);
+bool FileStream_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite);
+bool FileStream_GetPos(TFileStream * pStream, ULONGLONG * pByteOffset);
+bool FileStream_SetPos(TFileStream * pStream, ULONGLONG ByteOffset);
+bool FileStream_GetSize(TFileStream * pStream, ULONGLONG * pFileSize);
+bool FileStream_SetSize(TFileStream * pStream, ULONGLONG NewFileSize);
+bool FileStream_GetTime(TFileStream * pStream, ULONGLONG * pFT);
+bool FileStream_GetFlags(TFileStream * pStream, LPDWORD pdwStreamFlags);
+bool FileStream_Switch(TFileStream * pStream, TFileStream * pTempStream);
+bool FileStream_SetBitmap(TFileStream * pStream, TFileBitmap * pBitmap);
+bool FileStream_GetBitmap(TFileStream * pStream, TFileBitmap * pBitmap, DWORD Length, LPDWORD LengthNeeded);
+void FileStream_Close(TFileStream * pStream);
+
+//-----------------------------------------------------------------------------
+// Functions prototypes for Storm.dll
+
+// Typedefs for functions exported by Storm.dll
+typedef LCID (WINAPI * SFILESETLOCALE)(LCID);
+typedef bool (WINAPI * SFILEOPENARCHIVE)(const char *, DWORD, DWORD, HANDLE *);
+typedef bool (WINAPI * SFILECLOSEARCHIVE)(HANDLE);
+typedef bool (WINAPI * SFILEOPENFILEEX)(HANDLE, const char *, DWORD, HANDLE *);
+typedef bool (WINAPI * SFILECLOSEFILE)(HANDLE);
+typedef DWORD (WINAPI * SFILEGETFILESIZE)(HANDLE, LPDWORD);
+typedef DWORD (WINAPI * SFILESETFILEPOINTER)(HANDLE, LONG, LONG *, DWORD);
+typedef bool (WINAPI * SFILEREADFILE)(HANDLE, void *, DWORD, LPDWORD, LPOVERLAPPED);
+
+//-----------------------------------------------------------------------------
+// Functions for manipulation with StormLib global flags
+
+LCID WINAPI SFileGetLocale();
+LCID WINAPI SFileSetLocale(LCID lcNewLocale);
+
+//-----------------------------------------------------------------------------
+// Functions for archive manipulation
+
+bool WINAPI SFileOpenArchive(const TCHAR * szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE * phMpq);
+bool WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwFlags, DWORD dwMaxFileCount, HANDLE * phMpq);
+bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCreateInfo, HANDLE * phMpq);
+
+bool WINAPI SFileGetArchiveBitmap(HANDLE hMpq, TFileBitmap * pBitmap, DWORD Length, LPDWORD LengthNeeded);
+bool WINAPI SFileFlushArchive(HANDLE hMpq);
+bool WINAPI SFileCloseArchive(HANDLE hMpq);
+
+// Adds another listfile into MPQ. The currently added listfile(s) remain,
+// so you can use this API to combining more listfiles.
+// Note that this function is internally called by SFileFindFirstFile
+int WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile);
+
+// Archive compacting
+bool WINAPI SFileSetCompactCallback(HANDLE hMpq, SFILE_COMPACT_CALLBACK CompactCB, void * pvData);
+bool WINAPI SFileCompactArchive(HANDLE hMpq, const char * szListFile, bool bReserved);
+
+// Changing the maximum file count
+DWORD WINAPI SFileGetMaxFileCount(HANDLE hMpq);
+bool WINAPI SFileSetMaxFileCount(HANDLE hMpq, DWORD dwMaxFileCount);
+
+// Changing (attributes) file
+DWORD WINAPI SFileGetAttributes(HANDLE hMpq);
+bool WINAPI SFileSetAttributes(HANDLE hMpq, DWORD dwFlags);
+bool WINAPI SFileUpdateFileAttributes(HANDLE hMpq, const char * szFileName);
+
+//-----------------------------------------------------------------------------
+// Functions for manipulation with patch archives
+
+bool WINAPI SFileOpenPatchArchive(HANDLE hMpq, const TCHAR * szPatchMpqName, const char * szPatchPathPrefix, DWORD dwFlags);
+bool WINAPI SFileIsPatchedArchive(HANDLE hMpq);
+
+//-----------------------------------------------------------------------------
+// Functions for file manipulation
+
+// Reading from MPQ file
+bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope, HANDLE * phFile);
+DWORD WINAPI SFileGetFileSize(HANDLE hFile, LPDWORD pdwFileSizeHigh);
+DWORD WINAPI SFileSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * plFilePosHigh, DWORD dwMoveMethod);
+bool WINAPI SFileReadFile(HANDLE hFile, void * lpBuffer, DWORD dwToRead, LPDWORD pdwRead, LPOVERLAPPED lpOverlapped);
+bool WINAPI SFileCloseFile(HANDLE hFile);
+
+// Retrieving info about the file
+bool WINAPI SFileHasFile(HANDLE hMpq, const char * szFileName);
+bool WINAPI SFileGetFileName(HANDLE hFile, char * szFileName);
+bool WINAPI SFileGetFileInfo(HANDLE hMpqOrFile, DWORD dwInfoType, void * pvFileInfo, DWORD cbFileInfo, LPDWORD pcbLengthNeeded);
+
+// High-level extract function
+bool WINAPI SFileExtractFile(HANDLE hMpq, const char * szToExtract, const TCHAR * szExtracted, DWORD dwSearchScope);
+
+//-----------------------------------------------------------------------------
+// Functions for file and archive verification
+
+// Generates file CRC32
+bool WINAPI SFileGetFileChecksums(HANDLE hMpq, const char * szFileName, LPDWORD pdwCrc32, char * pMD5);
+
+// Verifies file against its checksums stored in (attributes) attributes (depending on dwFlags).
+// For dwFlags, use one or more of MPQ_ATTRIBUTE_MD5
+DWORD WINAPI SFileVerifyFile(HANDLE hMpq, const char * szFileName, DWORD dwFlags);
+
+// Verifies raw data of the archive. Only works for MPQs version 4 or newer
+int WINAPI SFileVerifyRawData(HANDLE hMpq, DWORD dwWhatToVerify, const char * szFileName);
+
+// Verifies the signature, if present
+DWORD WINAPI SFileVerifyArchive(HANDLE hMpq);
+
+//-----------------------------------------------------------------------------
+// Functions for file searching
+
+HANDLE WINAPI SFileFindFirstFile(HANDLE hMpq, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const char * szListFile);
+bool WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData);
+bool WINAPI SFileFindClose(HANDLE hFind);
+
+HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData);
+bool WINAPI SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData);
+bool WINAPI SListFileFindClose(HANDLE hFind);
+
+// Locale support
+int WINAPI SFileEnumLocales(HANDLE hMpq, const char * szFileName, LCID * plcLocales, LPDWORD pdwMaxLocales, DWORD dwSearchScope);
+
+//-----------------------------------------------------------------------------
+// Support for adding files to the MPQ
+
+bool WINAPI SFileCreateFile(HANDLE hMpq, const char * szArchivedName, ULONGLONG FileTime, DWORD dwFileSize, LCID lcLocale, DWORD dwFlags, HANDLE * phFile);
+bool WINAPI SFileWriteFile(HANDLE hFile, const void * pvData, DWORD dwSize, DWORD dwCompression);
+bool WINAPI SFileFinishFile(HANDLE hFile);
+
+bool WINAPI SFileAddFileEx(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwCompression, DWORD dwCompressionNext);
+bool WINAPI SFileAddFile(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags);
+bool WINAPI SFileAddWave(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwQuality);
+bool WINAPI SFileRemoveFile(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope);
+bool WINAPI SFileRenameFile(HANDLE hMpq, const char * szOldFileName, const char * szNewFileName);
+bool WINAPI SFileSetFileLocale(HANDLE hFile, LCID lcNewLocale);
+bool WINAPI SFileSetDataCompression(DWORD DataCompression);
+
+bool WINAPI SFileSetAddFileCallback(HANDLE hMpq, SFILE_ADDFILE_CALLBACK AddFileCB, void * pvData);
+
+//-----------------------------------------------------------------------------
+// Compression and decompression
+
+int WINAPI SCompImplode (void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer);
+int WINAPI SCompExplode (void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer);
+int WINAPI SCompCompress (void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, unsigned uCompressionMask, int nCmpType, int nCmpLevel);
+int WINAPI SCompDecompress (void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer);
+int WINAPI SCompDecompress2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer);
+
+//-----------------------------------------------------------------------------
+// Non-Windows support for SetLastError/GetLastError
+
+#ifndef PLATFORM_WINDOWS
+
+void SetLastError(int err);
+int GetLastError();
+
+#endif
+
+//-----------------------------------------------------------------------------
+// Functions from Storm.dll. They use slightly different names for keeping
+// possibility to use them together with StormLib (StormXXX instead of SFileXXX)
+
+#ifdef __LINK_STORM_DLL__
+ #define STORM_ALTERNATE_NAMES // Force storm_dll.h to use alternate fnc names
+ #include "..\storm_dll\storm_dll.h"
+#endif // __LINK_STORM_DLL__
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // __STORMLIB_H__
diff --git a/src/StormPort.h b/src/StormPort.h
new file mode 100644
index 0000000..069033a
--- /dev/null
+++ b/src/StormPort.h
@@ -0,0 +1,243 @@
+/*****************************************************************************/
+/* StormPort.h Copyright (c) Marko Friedemann 2001 */
+/*---------------------------------------------------------------------------*/
+/* Portability module for the StormLib library. Contains a wrapper symbols */
+/* to make the compilation under Linux work */
+/* */
+/* Author: Marko Friedemann <marko.friedemann@bmx-chemnitz.de> */
+/* Created at: Mon Jan 29 18:26:01 CEST 2001 */
+/* Computer: whiplash.flachland-chemnitz.de */
+/* System: Linux 2.4.0 on i686 */
+/* */
+/* Author: Sam Wilkins <swilkins1337@gmail.com> */
+/* System: Mac OS X and port to big endian processor */
+/* */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 29.01.01 1.00 Mar Created */
+/* 24.03.03 1.01 Lad Some cosmetic changes */
+/* 12.11.03 1.02 Dan Macintosh compatibility */
+/* 24.07.04 1.03 Sam Mac OS X compatibility */
+/* 22.11.06 1.04 Sam Mac OS X compatibility (for StormLib 6.0) */
+/* 31.12.06 1.05 XPinguin Full GNU/Linux compatibility */
+/* 17.10.12 1.05 Lad Moved error codes so they don't overlap with errno.h */
+/*****************************************************************************/
+
+#ifndef __STORMPORT_H__
+#define __STORMPORT_H__
+
+#ifndef __cplusplus
+ #define bool char
+ #define true 1
+ #define false 0
+#endif
+
+// Defines for Windows
+#if !defined(PLATFORM_DEFINED) && (defined(WIN32) || defined(WIN64))
+
+ // In MSVC 8.0, there are some functions declared as deprecated.
+ #if _MSC_VER >= 1400
+ #define _CRT_SECURE_NO_DEPRECATE
+ #define _CRT_NON_CONFORMING_SWPRINTFS
+ #endif
+
+ #include <tchar.h>
+ #include <assert.h>
+ #include <ctype.h>
+ #include <stdio.h>
+ #include <windows.h>
+ #include <wininet.h>
+ #define PLATFORM_LITTLE_ENDIAN
+
+ #ifdef WIN64
+ #define PLATFORM_64BIT
+ #else
+ #define PLATFORM_32BIT
+ #endif
+
+ #define PLATFORM_WINDOWS
+ #define PLATFORM_DEFINED // The platform is known now
+
+#endif
+
+// Defines for Mac
+#if !defined(PLATFORM_DEFINED) && defined(__APPLE__) // Mac BSD API
+
+ // Macintosh
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/mman.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <stdlib.h>
+ #include <errno.h>
+
+ #define PKEXPORT
+ #define __SYS_ZLIB
+ #define __SYS_BZLIB
+
+ #ifndef __BIG_ENDIAN__
+ #define PLATFORM_LITTLE_ENDIAN
+ #endif
+
+ #define PLATFORM_MAC
+ #define PLATFORM_DEFINED // The platform is known now
+
+#endif
+
+// Assumption: we are not on Windows nor Macintosh, so this must be linux *grin*
+#if !defined(PLATFORM_DEFINED)
+
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/mman.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <stdint.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <stdarg.h>
+ #include <string.h>
+ #include <ctype.h>
+ #include <assert.h>
+ #include <errno.h>
+
+ #define PLATFORM_LITTLE_ENDIAN
+ #define PLATFORM_LINUX
+ #define PLATFORM_DEFINED
+
+#endif
+
+// Definition of Windows-specific structures for non-Windows platforms
+#ifndef PLATFORM_WINDOWS
+ #if __LP64__
+ #define PLATFORM_64BIT
+ #else
+ #define PLATFORM_32BIT
+ #endif
+
+ // Typedefs for ANSI C
+ typedef unsigned char BYTE;
+ typedef unsigned short USHORT;
+ typedef int LONG;
+ typedef unsigned int DWORD;
+ typedef unsigned long DWORD_PTR;
+ typedef long LONG_PTR;
+ typedef long INT_PTR;
+ typedef long long LONGLONG;
+ typedef unsigned long long ULONGLONG;
+ typedef void * HANDLE;
+ typedef void * LPOVERLAPPED; // Unsupported on Linux and Mac
+ typedef char TCHAR;
+ typedef unsigned int LCID;
+ typedef LONG * PLONG;
+ typedef DWORD * LPDWORD;
+ typedef BYTE * LPBYTE;
+
+ #ifdef PLATFORM_32BIT
+ #define _LZMA_UINT32_IS_ULONG
+ #endif
+
+ // Some Windows-specific defines
+ #ifndef MAX_PATH
+ #define MAX_PATH 1024
+ #endif
+
+ #define WINAPI
+
+ #define FILE_BEGIN SEEK_SET
+ #define FILE_CURRENT SEEK_CUR
+ #define FILE_END SEEK_END
+
+ #define _T(x) x
+ #define _tcslen strlen
+ #define _tcscpy strcpy
+ #define _tcscat strcat
+ #define _tcsrchr strrchr
+ #define _tprintf printf
+ #define _stprintf sprintf
+ #define _tremove remove
+
+ #define _stricmp strcasecmp
+ #define _strnicmp strncasecmp
+ #define _tcsnicmp strncasecmp
+
+#endif // !WIN32
+
+// 64-bit calls are supplied by "normal" calls on Mac
+#if defined(PLATFORM_MAC)
+ #define stat64 stat
+ #define fstat64 fstat
+ #define lseek64 lseek
+ #define off64_t off_t
+ #define O_LARGEFILE 0
+#endif
+
+// Platform-specific error codes for UNIX-based platforms
+#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX)
+ #define ERROR_SUCCESS 0
+ #define ERROR_FILE_NOT_FOUND ENOENT
+ #define ERROR_ACCESS_DENIED EPERM
+ #define ERROR_INVALID_HANDLE EBADF
+ #define ERROR_NOT_ENOUGH_MEMORY ENOMEM
+ #define ERROR_NOT_SUPPORTED ENOTSUP
+ #define ERROR_INVALID_PARAMETER EINVAL
+ #define ERROR_DISK_FULL ENOSPC
+ #define ERROR_ALREADY_EXISTS EEXIST
+ #define ERROR_INSUFFICIENT_BUFFER ENOBUFS
+ #define ERROR_BAD_FORMAT 1000 // No such error code under Linux
+ #define ERROR_NO_MORE_FILES 1001 // No such error code under Linux
+ #define ERROR_HANDLE_EOF 1002 // No such error code under Linux
+ #define ERROR_CAN_NOT_COMPLETE 1003 // No such error code under Linux
+ #define ERROR_FILE_CORRUPT 1004 // No such error code under Linux
+#endif
+
+#ifdef PLATFORM_LITTLE_ENDIAN
+ #define BSWAP_INT16_UNSIGNED(a) (a)
+ #define BSWAP_INT16_SIGNED(a) (a)
+ #define BSWAP_INT32_UNSIGNED(a) (a)
+ #define BSWAP_INT32_SIGNED(a) (a)
+ #define BSWAP_INT64_SIGNED(a) (a)
+ #define BSWAP_INT64_UNSIGNED(a) (a)
+ #define BSWAP_ARRAY16_UNSIGNED(a,b) {}
+ #define BSWAP_ARRAY32_UNSIGNED(a,b) {}
+ #define BSWAP_ARRAY64_UNSIGNED(a,b) {}
+ #define BSWAP_PART_HEADER(a) {}
+ #define BSWAP_TMPQUSERDATA(a) {}
+ #define BSWAP_TMPQHEADER(a) {}
+#else
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+ int16_t SwapInt16(uint16_t);
+ uint16_t SwapUInt16(uint16_t);
+ int32_t SwapInt32(uint32_t);
+ uint32_t SwapUInt32(uint32_t);
+ int64_t SwapInt64(uint64_t);
+ uint64_t SwapUInt64(uint64_t);
+ void ConvertUInt16Buffer(void * ptr, size_t length);
+ void ConvertUInt32Buffer(void * ptr, size_t length);
+ void ConvertUInt64Buffer(void * ptr, size_t length);
+ void ConvertPartHeader(void * partHeader);
+ void ConvertTMPQUserData(void *userData);
+ void ConvertTMPQHeader(void *header);
+#ifdef __cplusplus
+ }
+#endif
+ #define BSWAP_INT16_SIGNED(a) SwapInt16((a))
+ #define BSWAP_INT16_UNSIGNED(a) SwapUInt16((a))
+ #define BSWAP_INT32_SIGNED(a) SwapInt32((a))
+ #define BSWAP_INT32_UNSIGNED(a) SwapUInt32((a))
+ #define BSWAP_INT64_SIGNED(a) SwapInt64((a))
+ #define BSWAP_INT64_UNSIGNED(a) SwapUInt64((a))
+ #define BSWAP_ARRAY16_UNSIGNED(a,b) ConvertUInt16Buffer((a),(b))
+ #define BSWAP_ARRAY32_UNSIGNED(a,b) ConvertUInt32Buffer((a),(b))
+ #define BSWAP_ARRAY64_UNSIGNED(a,b) ConvertUInt64Buffer((a),(b))
+ #define BSWAP_PART_HEADER(a) ConvertPartHeader(a)
+ #define BSWAP_TMPQUSERDATA(a) ConvertTMPQUserData((a))
+ #define BSWAP_TMPQHEADER(a) ConvertTMPQHeader((a))
+#endif
+
+#endif // __STORMPORT_H__
diff --git a/src/adpcm/adpcm.cpp b/src/adpcm/adpcm.cpp
new file mode 100644
index 0000000..d05fca6
--- /dev/null
+++ b/src/adpcm/adpcm.cpp
@@ -0,0 +1,398 @@
+/*****************************************************************************/
+/* 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 "../StormPort.h"
+#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((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((pbBufferEnd - pbBuffer) < sizeof(short))
+ return false;
+
+ // Write the sample
+ *pbBuffer++ = (unsigned char)(OneSample & 0xFF);
+ *pbBuffer++ = (unsigned char)(OneSample >> 0x08);
+ return true;
+ }
+
+ int LengthProcessed(void * pvBuffer)
+ {
+ return pbBuffer - (unsigned char *)pvBuffer;
+ }
+
+ 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
+ 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
+ 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/src/adpcm/adpcm.h b/src/adpcm/adpcm.h
new file mode 100644
index 0000000..b1bf361
--- /dev/null
+++ b/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/src/adpcm/adpcm_old.cpp b/src/adpcm/adpcm_old.cpp
new file mode 100644
index 0000000..916fa38
--- /dev/null
+++ b/src/adpcm/adpcm_old.cpp
@@ -0,0 +1,358 @@
+/*****************************************************************************/
+/* adpcm.cpp Copyright (c) Ladislav Zezula 2003 */
+/*---------------------------------------------------------------------------*/
+/* This module contains implementation of adpcm decompression method used by */
+/* Storm.dll to decompress WAVE files. Thanks to Tom Amigo for releasing */
+/* his sources. */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 11.03.03 1.00 Lad Splitted from Pkware.cpp */
+/* 20.05.03 2.00 Lad Added compression */
+/* 19.11.03 2.01 Dan Big endian handling */
+/*****************************************************************************/
+
+#include "adpcm.h"
+
+//------------------------------------------------------------------------------
+// Structures
+
+typedef union _BYTE_AND_WORD_PTR
+{
+ short * pw;
+ unsigned char * pb;
+} BYTE_AND_WORD_PTR;
+
+typedef union _WORD_AND_BYTE_ARRAY
+{
+ short w;
+ unsigned char b[2];
+} WORD_AND_BYTE_ARRAY;
+
+//-----------------------------------------------------------------------------
+// Tables necessary dor decompression
+
+static long Table1503F120[] =
+{
+ 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000006,
+ 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007,
+ 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007,
+ 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000006, 0xFFFFFFFF, 0x00000008
+};
+
+static long step_table[] =
+{
+ 0x00000007, 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E,
+ 0x00000010, 0x00000011, 0x00000013, 0x00000015, 0x00000017, 0x00000019, 0x0000001C, 0x0000001F,
+ 0x00000022, 0x00000025, 0x00000029, 0x0000002D, 0x00000032, 0x00000037, 0x0000003C, 0x00000042,
+ 0x00000049, 0x00000050, 0x00000058, 0x00000061, 0x0000006B, 0x00000076, 0x00000082, 0x0000008F,
+ 0x0000009D, 0x000000AD, 0x000000BE, 0x000000D1, 0x000000E6, 0x000000FD, 0x00000117, 0x00000133,
+ 0x00000151, 0x00000173, 0x00000198, 0x000001C1, 0x000001EE, 0x00000220, 0x00000256, 0x00000292,
+ 0x000002D4, 0x0000031C, 0x0000036C, 0x000003C3, 0x00000424, 0x0000048E, 0x00000502, 0x00000583,
+ 0x00000610, 0x000006AB, 0x00000756, 0x00000812, 0x000008E0, 0x000009C3, 0x00000ABD, 0x00000BD0,
+ 0x00000CFF, 0x00000E4C, 0x00000FBA, 0x0000114C, 0x00001307, 0x000014EE, 0x00001706, 0x00001954,
+ 0x00001BDC, 0x00001EA5, 0x000021B6, 0x00002515, 0x000028CA, 0x00002CDF, 0x0000315B, 0x0000364B,
+ 0x00003BB9, 0x000041B2, 0x00004844, 0x00004F7E, 0x00005771, 0x0000602F, 0x000069CE, 0x00007462,
+ 0x00007FFF
+};
+
+//----------------------------------------------------------------------------
+// CompressWave
+
+// 1500EF70
+int CompressADPCM(unsigned char * pbOutBuffer, int dwOutLength, short * pwInBuffer, int dwInLength, int nChannels, int nCmpLevel)
+// ECX EDX
+{
+ WORD_AND_BYTE_ARRAY Wcmp;
+ BYTE_AND_WORD_PTR out; // Pointer to the output buffer
+ long SInt32Array1[2];
+ long SInt32Array2[2];
+ long SInt32Array3[2];
+ long nBytesRemains = dwOutLength; // Number of bytes remaining
+ long nWordsRemains; // Number of words remaining
+// unsigned char * pbSaveOutBuffer; // Copy of output buffer (actually not used)
+ unsigned long dwBitBuff;
+ unsigned long dwStopBit;
+ unsigned long dwBit;
+ unsigned long ebx;
+ unsigned long esi;
+ long nTableValue;
+ long nOneWord;
+ long var_1C;
+ long var_2C;
+ int nLength;
+ int nIndex;
+ int nValue;
+ int i, chnl;
+
+ // If less than 2 bytes remain, don't decompress anything
+// pbSaveOutBuffer = pbOutBuffer;
+ out.pb = pbOutBuffer;
+ if(nBytesRemains < 2)
+ return 2;
+
+ Wcmp.b[1] = (unsigned char)(nCmpLevel - 1);
+ Wcmp.b[0] = (unsigned char)0;
+
+ *out.pw++ = BSWAP_INT16_SIGNED(Wcmp.w);
+ if((out.pb - pbOutBuffer + (nChannels * 2)) > nBytesRemains)
+ return (int)(out.pb - pbOutBuffer + (nChannels * 2));
+
+ SInt32Array1[0] = SInt32Array1[1] = 0x2C;
+
+ for(i = 0; i < nChannels; i++)
+ {
+ nOneWord = BSWAP_INT16_SIGNED(*pwInBuffer++);
+ *out.pw++ = BSWAP_INT16_SIGNED((short)nOneWord);
+ SInt32Array2[i] = nOneWord;
+ }
+
+ // Weird. But it's there
+ nLength = dwInLength;
+ if(nLength < 0) // mov eax, dwInLength; cdq; sub eax, edx;
+ nLength++;
+
+ nLength = (nLength / 2) - (int)(out.pb - pbOutBuffer);
+ nLength = (nLength < 0) ? 0 : nLength;
+
+ nIndex = nChannels - 1; // edi
+ nWordsRemains = dwInLength / 2; // eax
+
+ // ebx - nChannels
+ // ecx - pwOutPos
+ for(chnl = nChannels; chnl < nWordsRemains; chnl++)
+ {
+ // 1500F030
+ if((out.pb - pbOutBuffer + 2) > nBytesRemains)
+ return (int)(out.pb - pbOutBuffer + 2);
+
+ // Switch index
+ if(nChannels == 2)
+ nIndex = (nIndex == 0) ? 1 : 0;
+
+ // Load one word from the input stream
+ nOneWord = BSWAP_INT16_SIGNED(*pwInBuffer++); // ecx - nOneWord
+ SInt32Array3[nIndex] = nOneWord;
+
+ // esi - SInt32Array2[nIndex]
+ // eax - nValue
+ nValue = nOneWord - SInt32Array2[nIndex];
+ nValue = (nValue < 0) ? ((nValue ^ 0xFFFFFFFF) + 1) : nValue;
+
+ ebx = (nOneWord >= SInt32Array2[nIndex]) ? 0 : 0x40;
+
+ // esi - SInt32Array2[nIndex]
+ // edx - step_table[SInt32Array2[nIndex]]
+ // edi - (step_table[SInt32Array1[nIndex]] >> nCmpLevel)
+ nTableValue = step_table[SInt32Array1[nIndex]];
+ dwStopBit = (unsigned long)nCmpLevel;
+
+ // edi - nIndex;
+ if(nValue < (nTableValue >> nCmpLevel))
+ {
+ if(SInt32Array1[nIndex] != 0)
+ SInt32Array1[nIndex]--;
+ *out.pb++ = 0x80;
+ }
+ else
+ {
+ while(nValue > nTableValue * 2)
+ {
+ if(SInt32Array1[nIndex] >= 0x58 || nLength == 0)
+ break;
+
+ SInt32Array1[nIndex] += 8;
+ if(SInt32Array1[nIndex] > 0x58)
+ SInt32Array1[nIndex] = 0x58;
+
+ nTableValue = step_table[SInt32Array1[nIndex]];
+ *out.pb++ = 0x81;
+ nLength--;
+ }
+
+ var_2C = nTableValue >> Wcmp.b[1];
+ dwBitBuff = 0;
+
+ esi = (1 << (dwStopBit - 2));
+ dwStopBit = (esi <= 0x20) ? esi : 0x20;
+
+ for(var_1C = 0, dwBit = 1; ; dwBit <<= 1)
+ {
+// esi = var_1C + nTableValue;
+ if((var_1C + nTableValue) <= nValue)
+ {
+ var_1C += nTableValue;
+ dwBitBuff |= dwBit;
+ }
+ if(dwBit == dwStopBit)
+ break;
+
+ nTableValue >>= 1;
+ }
+
+ nValue = SInt32Array2[nIndex];
+ if(ebx != 0)
+ {
+ nValue -= (var_1C + var_2C);
+ if(nValue < -32768)
+ nValue = -32768;
+ }
+ else
+ {
+ nValue += (var_1C + var_2C);
+ if(nValue > 32767)
+ nValue = 32767;
+ }
+
+ SInt32Array2[nIndex] = nValue;
+ *out.pb++ = (unsigned char)(dwBitBuff | ebx);
+ nTableValue = Table1503F120[dwBitBuff & 0x1F];
+ SInt32Array1[nIndex] = SInt32Array1[nIndex] + nTableValue;
+ if(SInt32Array1[nIndex] < 0)
+ SInt32Array1[nIndex] = 0;
+ else if(SInt32Array1[nIndex] > 0x58)
+ SInt32Array1[nIndex] = 0x58;
+ }
+ }
+
+ return (int)(out.pb - pbOutBuffer);
+}
+
+//----------------------------------------------------------------------------
+// DecompressADPCM
+
+// 1500F230
+int DecompressADPCM(unsigned char * pbOutBuffer, int dwOutLength, unsigned char * pbInBuffer, int dwInLength, int nChannels)
+{
+ BYTE_AND_WORD_PTR out; // Output buffer
+ BYTE_AND_WORD_PTR in;
+ unsigned char * pbInBufferEnd = (pbInBuffer + dwInLength);
+ long SInt32Array1[2];
+ long SInt32Array2[2];
+ long nOneWord;
+ int nIndex;
+ int i;
+
+ SInt32Array1[0] = SInt32Array1[1] = 0x2C;
+ out.pb = pbOutBuffer;
+ in.pb = pbInBuffer;
+ in.pw++;
+
+ // Fill the Uint32Array2 array by channel values.
+ for(i = 0; i < nChannels; i++)
+ {
+ nOneWord = BSWAP_INT16_SIGNED(*in.pw++);
+ SInt32Array2[i] = nOneWord;
+ if(dwOutLength < 2)
+ return (int)(out.pb - pbOutBuffer);
+
+ *out.pw++ = BSWAP_INT16_SIGNED((short)nOneWord);
+ dwOutLength -= sizeof(short);
+ }
+
+ // Get the initial index
+ nIndex = nChannels - 1;
+
+ // Perform the decompression
+ while(in.pb < pbInBufferEnd)
+ {
+ unsigned char nOneByte = *in.pb++;
+
+ // Switch index
+ if(nChannels == 2)
+ nIndex = (nIndex == 0) ? 1 : 0;
+
+ // 1500F2A2: Get one byte from input buffer
+ if(nOneByte & 0x80)
+ {
+ switch(nOneByte & 0x7F)
+ {
+ case 0: // 1500F315
+ if(SInt32Array1[nIndex] != 0)
+ SInt32Array1[nIndex]--;
+
+ if(dwOutLength < 2)
+ return (int)(out.pb - pbOutBuffer);
+
+ *out.pw++ = BSWAP_INT16_SIGNED((unsigned short)SInt32Array2[nIndex]);
+ dwOutLength -= sizeof(unsigned short);
+ break;
+
+ case 1: // 1500F2E8
+ SInt32Array1[nIndex] += 8;
+ if(SInt32Array1[nIndex] > 0x58)
+ SInt32Array1[nIndex] = 0x58;
+
+ if(nChannels == 2)
+ nIndex = (nIndex == 0) ? 1 : 0;
+ break;
+
+ case 2: // 1500F41E
+ break;
+
+ default: // 1500F2C4
+ SInt32Array1[nIndex] -= 8;
+ if(SInt32Array1[nIndex] < 0)
+ SInt32Array1[nIndex] = 0;
+
+ if(nChannels == 2)
+ nIndex = (nIndex == 0) ? 1 : 0;
+ break;
+ }
+ }
+ else
+ {
+ // 1500F349
+ long temp1 = step_table[SInt32Array1[nIndex]]; // EDI
+ long temp2 = temp1 >> pbInBuffer[1]; // ESI
+ long temp3 = SInt32Array2[nIndex]; // ECX
+
+ if(nOneByte & 0x01) // EBX = nOneByte
+ temp2 += (temp1 >> 0);
+
+ if(nOneByte & 0x02)
+ temp2 += (temp1 >> 1);
+
+ if(nOneByte & 0x04)
+ temp2 += (temp1 >> 2);
+
+ if(nOneByte & 0x08)
+ temp2 += (temp1 >> 3);
+
+ if(nOneByte & 0x10)
+ temp2 += (temp1 >> 4);
+
+ if(nOneByte & 0x20)
+ temp2 += (temp1 >> 5);
+
+ if(nOneByte & 0x40)
+ {
+ temp3 = temp3 - temp2;
+ if(temp3 <= -32768)
+ temp3 = -32768;
+ }
+ else
+ {
+ temp3 = temp3 + temp2;
+ if(temp3 >= 32767)
+ temp3 = 32767;
+ }
+
+ SInt32Array2[nIndex] = temp3;
+ if(dwOutLength < 2)
+ break;
+
+ // Store the output 16-bit value
+ *out.pw++ = BSWAP_INT16_SIGNED((short)SInt32Array2[nIndex]);
+ dwOutLength -= 2;
+
+ SInt32Array1[nIndex] += Table1503F120[nOneByte & 0x1F];
+
+ if(SInt32Array1[nIndex] < 0)
+ SInt32Array1[nIndex] = 0;
+ else if(SInt32Array1[nIndex] > 0x58)
+ SInt32Array1[nIndex] = 0x58;
+ }
+ }
+ return (int)(out.pb - pbOutBuffer);
+}
diff --git a/src/adpcm/adpcm_old.h b/src/adpcm/adpcm_old.h
new file mode 100644
index 0000000..beb9615
--- /dev/null
+++ b/src/adpcm/adpcm_old.h
@@ -0,0 +1,22 @@
+/*****************************************************************************/
+/* adpcm.h Copyright (c) Ladislav Zezula 2003 */
+/*---------------------------------------------------------------------------*/
+/* Header file for adpcm decompress functions */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 31.03.03 1.00 Lad The first version of adpcm.h */
+/*****************************************************************************/
+
+#ifndef __ADPCM_H__
+#define __ADPCM_H__
+
+//-----------------------------------------------------------------------------
+// Functions
+
+#include "../StormPort.h"
+
+int CompressADPCM (unsigned char * pbOutBuffer, int dwOutLength, short * pwInBuffer, int dwInLength, int nCmpType, int nChannels);
+int DecompressADPCM(unsigned char * pbOutBuffer, int dwOutLength, unsigned char * pbInBuffer, int dwInLength, int nChannels);
+
+#endif // __ADPCM_H__
diff --git a/src/bzip2/blocksort.c b/src/bzip2/blocksort.c
new file mode 100644
index 0000000..bd2dec1
--- /dev/null
+++ b/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 <jseward@bzip.org>
+
+ 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/src/bzip2/bzlib.c b/src/bzip2/bzlib.c
new file mode 100644
index 0000000..b98f3e5
--- /dev/null
+++ b/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 <jseward@bzip.org>
+
+ 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 <fcntl.h>
+# include <io.h>
+# 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/src/bzip2/bzlib.h b/src/bzip2/bzlib.h
new file mode 100644
index 0000000..c5b75d6
--- /dev/null
+++ b/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 <jseward@bzip.org>
+
+ 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 <stdio.h>
+#endif
+
+#ifdef _WIN32
+# include <windows.h>
+# 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/src/bzip2/bzlib_private.h b/src/bzip2/bzlib_private.h
new file mode 100644
index 0000000..2342787
--- /dev/null
+++ b/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 <jseward@bzip.org>
+
+ 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 <stdlib.h>
+
+#ifndef BZ_NO_STDIO
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#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/src/bzip2/compress.c b/src/bzip2/compress.c
new file mode 100644
index 0000000..8c80a07
--- /dev/null
+++ b/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 <jseward@bzip.org>
+
+ 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/src/bzip2/crctable.c b/src/bzip2/crctable.c
new file mode 100644
index 0000000..215687b
--- /dev/null
+++ b/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 <jseward@bzip.org>
+
+ 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/src/bzip2/decompress.c b/src/bzip2/decompress.c
new file mode 100644
index 0000000..bba5e0f
--- /dev/null
+++ b/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 <jseward@bzip.org>
+
+ 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/src/bzip2/huffman.c b/src/bzip2/huffman.c
new file mode 100644
index 0000000..87e79e3
--- /dev/null
+++ b/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 <jseward@bzip.org>
+
+ 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/src/bzip2/randtable.c b/src/bzip2/randtable.c
new file mode 100644
index 0000000..068b763
--- /dev/null
+++ b/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 <jseward@bzip.org>
+
+ 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/src/huffman/HuffTree.xls b/src/huffman/HuffTree.xls
new file mode 100644
index 0000000..68e0664
--- /dev/null
+++ b/src/huffman/HuffTree.xls
Binary files differ
diff --git a/src/huffman/huff.cpp b/src/huffman/huff.cpp
new file mode 100644
index 0000000..cf5ae05
--- /dev/null
+++ b/src/huffman/huff.cpp
@@ -0,0 +1,869 @@
+/*****************************************************************************/
+/* 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 <assert.h>
+#include <string.h>
+
+#include "../StormPort.h"
+#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)
+{
+ // TODO: Obsolete, delete this!!
+// InitializeHTListHead(&ItemLinks);
+ pFirst = pLast = LIST_HEAD();
+
+ MinValidValue = 1;
+ ItemsUsed = 0;
+
+ // 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;
+
+ // 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
+void 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
+ assert((CompressionType & 0x0F) <= 0x08);
+ 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);
+
+ // 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;
+}
+
+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++;
+ }
+ }
+}
+
+void 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);
+ pChildHi->pParent = pLastItem;
+ ItemsByByte[Value1] = pChildHi;
+
+ // Create lower-weight child
+ pChildLo = CreateNewItem(Value2, 0, InsertBefore);
+ pChildLo->pParent = pLastItem;
+ pLastItem->pChildLo = pChildLo;
+ ItemsByByte[Value2] = pChildLo;
+
+ IncWeightsAndRebalance(pChildLo);
+}
+
+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
+ ItemLinkIndex &= (0xFFFFFFFF >> (32 - BitCount));
+ 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;
+
+ BuildTree(CompressionType);
+ 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);
+
+ InsertNewBranchAndRebalance(pLast->DecompressedValue, InputByte);
+
+ 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
+ BuildTree(CompressionType);
+
+ // 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();
+
+ InsertNewBranchAndRebalance(pLast->DecompressedValue, DecompressedValue);
+
+ 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/src/huffman/huff.h b/src/huffman/huff.h
new file mode 100644
index 0000000..b0a54ee
--- /dev/null
+++ b/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;}
+// ~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);
+ void BuildTree(unsigned int CompressionType);
+
+ void IncWeightsAndRebalance(THTreeItem * pItem);
+ void 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/src/huffman/huff_old.cpp b/src/huffman/huff_old.cpp
new file mode 100644
index 0000000..66a46b3
--- /dev/null
+++ b/src/huffman/huff_old.cpp
@@ -0,0 +1,1303 @@
+/*****************************************************************************/
+/* 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 <assert.h>
+#include <string.h>
+
+#include "huff.h"
+
+// Special for Mac - we have to know if normal pointer greater or less
+// than 0x80000000. This variable is used in the PTR_VALID and PTR_INVALID
+// macros
+static long mul = 1;
+
+#define PTR_VALID(ptr) (((LONG_PTR)(ptr) * mul) > 0)
+#define PTR_INVALID(ptr) (((LONG_PTR)(ptr) * mul) < 0)
+#define PTR_INVALID_OR_NULL(ptr) (((LONG_PTR)(ptr) * mul) <= 0)
+
+
+//-----------------------------------------------------------------------------
+// Methods of the THTreeItem struct
+
+// 1501DB70
+THTreeItem * THTreeItem::Call1501DB70(THTreeItem * pLast)
+{
+ if(pLast == NULL)
+ pLast = this + 1;
+ return pLast;
+}
+
+// Gets previous Huffman tree item (?)
+THTreeItem * THTreeItem::GetPrevItem(LONG_PTR value)
+{
+ if(PTR_INVALID(prev))
+ return PTR_NOT(prev);
+
+ if(value == -1 || PTR_INVALID(value))
+ value = (LONG_PTR)(this - next->prev);
+ return prev + value;
+
+// OLD VERSION
+// if(PTR_INT(value) < 0)
+// value = PTR_INT((item - item->next->prev));
+// return (THTreeItem *)((char *)prev + value);
+}
+
+// 1500F5E0
+void THTreeItem::ClearItemLinks()
+{
+ next = prev = NULL;
+}
+
+// 1500BC90
+void THTreeItem::RemoveItem()
+{
+ THTreeItem * pTemp; // EDX
+
+ if(next != NULL)
+ {
+ pTemp = prev;
+
+ if(PTR_INVALID_OR_NULL(pTemp))
+ pTemp = PTR_NOT(pTemp);
+ else
+ pTemp += (this - next->prev);
+
+ pTemp->next = next;
+ next->prev = prev;
+ next = prev = NULL;
+ }
+}
+
+/*
+// OLD VERSION : Removes item from the tree (?)
+static void RemoveItem(THTreeItem * item)
+{
+ THTreeItem * next = item->next; // ESI
+ THTreeItem * prev = item->prev; // EDX
+
+ if(next == NULL)
+ return;
+
+ if(PTR_INT(prev) < 0)
+ prev = PTR_NOT(prev);
+ else
+ // ??? usually item == next->prev, so what is it ?
+ prev = (THTreeItem *)((unsigned char *)prev + (unsigned long)((unsigned char *)item - (unsigned char *)(next->prev)));
+
+ // Remove HTree item from the chain
+ prev->next = next; // Sets the 'first' pointer
+ next->prev = item->prev;
+
+ // Invalidate pointers
+ item->next = NULL;
+ item->prev = NULL;
+}
+*/
+
+//-----------------------------------------------------------------------------
+// TOutputStream functions
+
+void TOutputStream::PutBits(unsigned long dwBuff, unsigned int nPutBits)
+{
+ dwBitBuff |= (dwBuff << nBits);
+ nBits += nPutBits;
+
+ // Flush completed bytes
+ while(nBits >= 8)
+ {
+ if(cbOutSize != 0)
+ {
+ *pbOutPos++ = (unsigned char)dwBitBuff;
+ cbOutSize--;
+ }
+
+ dwBitBuff >>= 8;
+ nBits -= 8;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// TInputStream functions
+
+// Gets one bit from input stream
+unsigned long TInputStream::GetBit()
+{
+ unsigned long dwOneBit = 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
+ dwOneBit = (BitBuffer & 0x01);
+ BitBuffer >>= 1;
+ BitCount--;
+
+ return dwOneBit;
+}
+
+// Gets 7 bits from the stream. DOES NOT remove the bits from input stream
+unsigned long TInputStream::Get7Bits()
+{
+ unsigned long 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 the whole byte from the input stream.
+unsigned long TInputStream::Get8Bits()
+{
+ unsigned long dwReloadByte = 0;
+ unsigned long 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 long 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;
+}
+
+//-----------------------------------------------------------------------------
+// Functions for huffmann tree items
+
+// Inserts item into the tree (?)
+static void InsertItem(THTreeItem ** itemPtr, THTreeItem * item, unsigned long nWhere, THTreeItem * item2)
+{
+ THTreeItem * next = item->next; // EDI - next to the first item
+ THTreeItem * prev = item->prev; // ESI - prev to the first item
+ THTreeItem * prev2; // Pointer to previous item
+ LONG_PTR next2; // Pointer to the next item
+
+ // The same code like in RemoveItem(item);
+ if(next != 0) // If the first item already has next one
+ {
+ if(PTR_INVALID(prev))
+ prev = PTR_NOT(prev);
+ else
+ prev += (item - next->prev);
+
+ // 150083C1
+ // Remove the item from the tree
+ prev->next = next;
+ next->prev = prev;
+
+ // Invalidate 'prev' and 'next' pointer
+ item->next = 0;
+ item->prev = 0;
+ }
+
+ if(item2 == NULL) // EDX - If the second item is not entered,
+ item2 = PTR_PTR(&itemPtr[1]); // take the first tree item
+
+ switch(nWhere)
+ {
+ case SWITCH_ITEMS : // Switch the two items
+ item->next = item2->next; // item2->next (Pointer to pointer to first)
+ item->prev = item2->next->prev;
+ item2->next->prev = item;
+ item2->next = item; // Set the first item
+ return;
+
+ case INSERT_ITEM: // Insert as the last item
+ item->next = item2; // Set next item (or pointer to pointer to first item)
+ item->prev = item2->prev; // Set prev item (or last item in the tree)
+
+ next2 = PTR_INT(itemPtr[0]);// Usually NULL
+ prev2 = item2->prev; // Prev item to the second (or last tree item)
+
+ if(PTR_INVALID(prev2))
+ {
+ if(prev != NULL)
+ {
+ prev2 = PTR_NOT(prev);
+ if(prev2 != NULL)
+ {
+ prev2->next = item;
+ item2->prev = item; // Next after last item
+ }
+ }
+ return;
+ }
+
+ if(PTR_INVALID(next2))
+ next2 = (LONG_PTR)(item2 - item2->next->prev);
+// next2 = (THTreeItem *)(unsigned long)((unsigned char *)item2 - (unsigned char *)(item2->next->prev));
+
+// prev2 = (THTreeItem *)((char *)prev2 + (unsigned long)next2);// ???
+ prev2 += next2;
+ prev2->next = item;
+ item2->prev = item; // Set the next/last item
+ return;
+
+ default:
+ return;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// THuffmannTree class functions
+
+THuffmannTree::THuffmannTree()
+{
+ // We have to check if the "this" pointer is less than zero
+ if((LONG_PTR)this < 0)
+ mul = -1;
+}
+
+void THuffmannTree::InitTree(bool bCompression)
+{
+ THTreeItem * pItem;
+ unsigned int nCount;
+
+ // Clear links for all the items in the tree
+ for(pItem = items0008, nCount = 0x203; nCount != 0; pItem++, nCount--)
+ pItem->ClearItemLinks();
+
+ pItem3050 = NULL;
+ pItem3054 = PTR_PTR(&pItem3054);
+ pItem3058 = PTR_NOT(pItem3054);
+
+ pItem305C = NULL;
+ pFirst = PTR_PTR(&pFirst);
+ pLast = PTR_NOT(pFirst);
+
+ offs0004 = 1;
+ nItems = 0;
+
+ // Clear all TQDecompress items. Do this only if preparing for decompression
+ if(bCompression == false)
+ {
+ for(nCount = 0; nCount < sizeof(qd3474) / sizeof(TQDecompress); nCount++)
+ qd3474[nCount].offs00 = 0;
+ }
+}
+
+// Builds Huffman tree. Called with the first 8 bits loaded from input stream
+void THuffmannTree::BuildTree(unsigned int nCmpType)
+{
+ unsigned long maxByte; // [ESP+10] - The greatest character found in table
+ THTreeItem ** itemPtr; // [ESP+14] - Pointer to Huffman tree item pointer array
+ unsigned char * byteArray; // [ESP+1C] - Pointer to unsigned char in Table1502A630
+ THTreeItem * child1;
+ unsigned long i; // egcs in linux doesn't like multiple for loops without an explicit i
+
+ // Loop while pointer has a valid value
+ while(PTR_VALID(pLast)) // ESI - Last entry
+ {
+ THTreeItem * temp; // EAX
+
+ if(pLast->next != NULL) // ESI->next
+ pLast->RemoveItem();
+ // EDI = &offs3054
+ pItem3058 = PTR_PTR(&pItem3054); // [EDI+4]
+ pLast->prev = pItem3058; // EAX
+
+ temp = PTR_PTR(&pItem3054)->GetPrevItem(PTR_INT(&pItem3050));
+
+ temp->next = pLast;
+ pItem3054 = pLast;
+ }
+
+ // Clear all pointers in HTree item array
+ memset(items306C, 0, sizeof(items306C));
+
+ maxByte = 0; // Greatest character found init to zero.
+ itemPtr = (THTreeItem **)&items306C; // Pointer to current entry in HTree item pointer array
+
+ // Ensure we have low 8 bits only
+ nCmpType &= 0xFF;
+ byteArray = Table1502A630 + nCmpType * 258; // EDI also
+
+ for(i = 0; i < 0x100; i++, itemPtr++)
+ {
+ THTreeItem * item = pItem3058; // Item to be created
+ THTreeItem * pItem3 = pItem3058;
+ unsigned char oneByte = byteArray[i];
+
+ // Skip all the bytes which are zero.
+ if(byteArray[i] == 0)
+ continue;
+
+ // If not valid pointer, take the first available item in the array
+ if(PTR_INVALID_OR_NULL(item))
+ item = &items0008[nItems++];
+
+ // Insert this item as the top of the tree
+ InsertItem(&pItem305C, item, SWITCH_ITEMS, NULL);
+
+ item->parent = NULL; // Invalidate child and parent
+ item->child = NULL;
+ *itemPtr = item; // Store pointer into pointer array
+
+ item->dcmpByte = i; // Store counter
+ item->byteValue = oneByte; // Store byte value
+ if(oneByte >= maxByte)
+ {
+ maxByte = oneByte;
+ continue;
+ }
+
+ // Find the first item which has byte value greater than current one byte
+ if(PTR_VALID(pItem3 = pLast)) // EDI - Pointer to the last item
+ {
+ // 15006AF7
+ if(pItem3 != NULL)
+ {
+ do // 15006AFB
+ {
+ if(pItem3->byteValue >= oneByte)
+ goto _15006B09;
+ pItem3 = pItem3->prev;
+ }
+ while(PTR_VALID(pItem3));
+ }
+ }
+ pItem3 = NULL;
+
+ // 15006B09
+ _15006B09:
+ if(item->next != NULL)
+ item->RemoveItem();
+
+ // 15006B15
+ if(pItem3 == NULL)
+ pItem3 = PTR_PTR(&pFirst);
+
+ // 15006B1F
+ item->next = pItem3->next;
+ item->prev = pItem3->next->prev;
+ pItem3->next->prev = item;
+ pItem3->next = item;
+ }
+
+ // 15006B4A
+ for(; i < 0x102; i++)
+ {
+ THTreeItem ** itemPtr = &items306C[i]; // EDI
+
+ // 15006B59
+ THTreeItem * item = pItem3058; // ESI
+ if(PTR_INVALID_OR_NULL(item))
+ item = &items0008[nItems++];
+
+ InsertItem(&pItem305C, item, INSERT_ITEM, NULL);
+
+ // 15006B89
+ item->dcmpByte = i;
+ item->byteValue = 1;
+ item->parent = NULL;
+ item->child = NULL;
+ *itemPtr++ = item;
+ }
+
+ // 15006BAA
+ if(PTR_VALID(child1 = pLast)) // EDI - last item (first child to item
+ {
+ THTreeItem * child2; // EBP
+ THTreeItem * item; // ESI
+
+ // 15006BB8
+ while(PTR_VALID(child2 = child1->prev))
+ {
+ if(PTR_INVALID_OR_NULL(item = pItem3058))
+ item = &items0008[nItems++];
+
+ // 15006BE3
+ InsertItem(&pItem305C, item, SWITCH_ITEMS, NULL);
+
+ // 15006BF3
+ item->parent = NULL;
+ item->child = NULL;
+
+ //EDX = child2->byteValue + child1->byteValue;
+ //EAX = child1->byteValue;
+ //ECX = maxByte; // The greatest character (0xFF usually)
+
+ item->byteValue = child1->byteValue + child2->byteValue; // 0x02
+ item->child = child1; // Prev item in the
+ child1->parent = item;
+ child2->parent = item;
+
+ // EAX = item->byteValue;
+ if(item->byteValue >= maxByte)
+ maxByte = item->byteValue;
+ else
+ {
+ THTreeItem * pItem2 = child2->prev; // EDI
+
+ // 15006C2D
+ while(PTR_VALID(pItem2))
+ {
+ if(pItem2->byteValue >= item->byteValue)
+ goto _15006C3B;
+ pItem2 = pItem2->prev;
+ }
+ pItem2 = NULL;
+
+ _15006C3B:
+ if(item->next != 0)
+ {
+ THTreeItem * temp4 = item->GetPrevItem(-1);
+
+ temp4->next = item->next; // The first item changed
+ item->next->prev = item->prev; // First->prev changed to negative value
+ item->next = NULL;
+ item->prev = NULL;
+ }
+
+ // 15006C62
+ if(pItem2 == NULL)
+ pItem2 = PTR_PTR(&pFirst);
+
+ item->next = pItem2->next; // Set item with 0x100 byte value
+ item->prev = pItem2->next->prev; // Set item with 0x17 byte value
+ pItem2->next->prev = item; // Changed prev of item with
+ pItem2->next = item;
+ }
+
+ // 15006C7B
+ if(PTR_INVALID_OR_NULL(child1 = child2->prev))
+ break;
+ }
+ }
+ // 15006C88
+ offs0004 = 1;
+}
+/*
+// Modifies Huffman tree. Adds new item and changes
+void THuffmannTree::ModifyTree(unsigned long dwIndex)
+{
+ THTreeItem * pItem1 = pItem3058; // ESI
+ THTreeItem * pSaveLast = (PTR_INT(pLast) <= 0) ? NULL : pLast; // EBX
+ THTreeItem * temp; // EAX
+
+ // Prepare the first item to insert to the tree
+ if(PTR_INT(pItem1) <= 0)
+ pItem1 = &items0008[nItems++];
+
+ // If item has any next item, remove it from the chain
+ if(pItem1->next != NULL)
+ {
+ THTreeItem * temp = pItem1->GetPrevItem(-1); // EAX
+
+ temp->next = pItem1->next;
+ pItem1->next->prev = pItem1->prev;
+ pItem1->next = NULL;
+ pItem1->prev = NULL;
+ }
+
+ pItem1->next = PTR_PTR(&pFirst);
+ pItem1->prev = pLast;
+ temp = pItem1->next->GetPrevItem(PTR_INT(pItem305C));
+
+ // 150068E9
+ temp->next = pItem1;
+ pLast = pItem1;
+
+ pItem1->parent = NULL;
+ pItem1->child = NULL;
+
+ // 150068F6
+ pItem1->dcmpByte = pSaveLast->dcmpByte; // Copy item index
+ pItem1->byteValue = pSaveLast->byteValue; // Copy item byte value
+ pItem1->parent = pSaveLast; // Set parent to last item
+ items306C[pSaveLast->dcmpByte] = pItem1; // Insert item into item pointer array
+
+ // Prepare the second item to insert into the tree
+ if(PTR_INT((pItem1 = pItem3058)) <= 0)
+ pItem1 = &items0008[nItems++];
+
+ // 1500692E
+ if(pItem1->next != NULL)
+ {
+ temp = pItem1->GetPrevItem(-1); // EAX
+
+ temp->next = pItem1->next;
+ pItem1->next->prev = pItem1->prev;
+ pItem1->next = NULL;
+ pItem1->prev = NULL;
+ }
+ // 1500694C
+ pItem1->next = PTR_PTR(&pFirst);
+ pItem1->prev = pLast;
+ temp = pItem1->next->GetPrevItem(PTR_INT(pItem305C));
+
+ // 15006968
+ temp->next = pItem1;
+ pLast = pItem1;
+
+ // 1500696E
+ pItem1->child = NULL;
+ pItem1->dcmpByte = dwIndex;
+ pItem1->byteValue = 0;
+ pItem1->parent = pSaveLast;
+ pSaveLast->child = pItem1;
+ items306C[dwIndex] = pItem1;
+
+ do
+ {
+ THTreeItem * pItem2 = pItem1;
+ THTreeItem * pItem3;
+ unsigned long byteValue;
+
+ // 15006993
+ byteValue = ++pItem1->byteValue;
+
+ // Pass through all previous which have its value greater than byteValue
+ while(PTR_INT((pItem3 = pItem2->prev)) > 0) // EBX
+ {
+ if(pItem3->byteValue >= byteValue)
+ goto _150069AE;
+
+ pItem2 = pItem2->prev;
+ }
+ // 150069AC
+ pItem3 = NULL;
+
+ _150069AE:
+ if(pItem2 == pItem1)
+ continue;
+
+ // 150069B2
+ // Switch pItem2 with item
+ InsertItem(&pItem305C, pItem2, SWITCH_ITEMS, pItem1);
+ InsertItem(&pItem305C, pItem1, SWITCH_ITEMS, pItem3);
+
+ // 150069D0
+ // Switch parents of pItem1 and pItem2
+ temp = pItem2->parent->child;
+ if(pItem1 == pItem1->parent->child)
+ pItem1->parent->child = pItem2;
+
+ if(pItem2 == temp)
+ pItem2->parent->child = pItem1;
+
+ // 150069ED
+ // Switch parents of pItem1 and pItem3
+ temp = pItem1->parent;
+ pItem1 ->parent = pItem2->parent;
+ pItem2->parent = temp;
+ offs0004++;
+ }
+ while(PTR_INT((pItem1 = pItem1->parent)) > 0);
+}
+
+void THuffmannTree::UninitTree()
+{
+ while(PTR_INT(pLast) > 0)
+ {
+ pItem = pItem305C->Call1501DB70(pLast);
+ pItem->RemoveItem();
+ }
+
+ for(pItem = pFirst; PTR_INT(pItem3058) > 0; pItem = pItem3058)
+ pItem->RemoveItem();
+ PTR_PTR(&pItem3054)->RemoveItem();
+
+ for(pItem = items0008 + 0x203, nCount = 0x203; nCount != 0; nCount--)
+ {
+ pItem--;
+ pItem->RemoveItem();
+ pItem->RemoveItem();
+ }
+}
+*/
+
+THTreeItem * THuffmannTree::Call1500E740(unsigned int nValue)
+{
+ THTreeItem * pItem1 = pItem3058; // EDX
+ THTreeItem * pItem2; // EAX
+ THTreeItem * pNext;
+ THTreeItem * pPrev;
+ THTreeItem ** ppItem;
+
+ if(PTR_INVALID_OR_NULL(pItem1) || (pItem2 = pItem1) == NULL)
+ {
+ if((pItem2 = &items0008[nItems++]) != NULL)
+ pItem1 = pItem2;
+ else
+ pItem1 = pFirst;
+ }
+ else
+ pItem1 = pItem2;
+
+ pNext = pItem1->next;
+ if(pNext != NULL)
+ {
+ pPrev = pItem1->prev;
+ if(PTR_INVALID_OR_NULL(pPrev))
+ pPrev = PTR_NOT(pPrev);
+ else
+ pPrev += (pItem1 - pItem1->next->prev);
+
+ pPrev->next = pNext;
+ pNext->prev = pPrev;
+ pItem1->next = NULL;
+ pItem1->prev = NULL;
+ }
+
+ ppItem = &pFirst; // esi
+ if(nValue > 1)
+ {
+ // ecx = pFirst->next;
+ pItem1->next = *ppItem;
+ pItem1->prev = (*ppItem)->prev;
+
+ (*ppItem)->prev = pItem2;
+ *ppItem = pItem1;
+
+ pItem2->parent = NULL;
+ pItem2->child = NULL;
+ }
+ else
+ {
+ pItem1->next = (THTreeItem *)ppItem;
+ pItem1->prev = ppItem[1];
+ // edi = pItem305C;
+ pPrev = ppItem[1]; // ecx
+ if(PTR_INVALID_OR_NULL(pPrev))
+ {
+ pPrev = PTR_NOT(pPrev);
+ pPrev->next = pItem1;
+ pPrev->prev = pItem2;
+
+ pItem2->parent = NULL;
+ pItem2->child = NULL;
+ }
+ else
+ {
+ if(PTR_INVALID(pItem305C))
+ pPrev += (THTreeItem *)ppItem - (*ppItem)->prev;
+ else
+ pPrev += PTR_INT(pItem305C);
+
+ pPrev->next = pItem1;
+ ppItem[1] = pItem2;
+ pItem2->parent = NULL;
+ pItem2->child = NULL;
+ }
+ }
+ return pItem2;
+}
+
+void THuffmannTree::Call1500E820(THTreeItem * pItem)
+{
+ THTreeItem * pItem1; // edi
+ THTreeItem * pItem2 = NULL; // eax
+ THTreeItem * pItem3; // edx
+ THTreeItem * pPrev; // ebx
+
+ for(; pItem != NULL; pItem = pItem->parent)
+ {
+ pItem->byteValue++;
+
+ for(pItem1 = pItem; ; pItem1 = pPrev)
+ {
+ pPrev = pItem1->prev;
+ if(PTR_INVALID_OR_NULL(pPrev))
+ {
+ pPrev = NULL;
+ break;
+ }
+
+ if(pPrev->byteValue >= pItem->byteValue)
+ break;
+ }
+
+ if(pItem1 == pItem)
+ continue;
+
+ if(pItem1->next != NULL)
+ {
+ pItem2 = pItem1->GetPrevItem(-1);
+ pItem2->next = pItem1->next;
+ pItem1->next->prev = pItem1->prev;
+ pItem1->next = NULL;
+ pItem1->prev = NULL;
+ }
+
+ pItem2 = pItem->next;
+ pItem1->next = pItem2;
+ pItem1->prev = pItem2->prev;
+ pItem2->prev = pItem1;
+ pItem->next = pItem1;
+ if((pItem2 = pItem1) != NULL)
+ {
+ pItem2 = pItem->GetPrevItem(-1);
+ pItem2->next = pItem->next;
+ pItem->next->prev = pItem->prev;
+ pItem->next = NULL;
+ pItem->prev = NULL;
+ }
+
+ if(pPrev == NULL)
+ pPrev = PTR_PTR(&pFirst);
+
+ pItem2 = pPrev->next;
+ pItem->next = pItem2;
+ pItem->prev = pItem2->prev;
+ pItem2->prev = pItem;
+ pPrev->next = pItem;
+
+ pItem3 = pItem1->parent->child;
+ pItem2 = pItem->parent;
+ if(pItem2->child == pItem)
+ pItem2->child = pItem1;
+ if(pItem3 == pItem1)
+ pItem1->parent->child = pItem;
+
+ pItem2 = pItem->parent;
+ pItem->parent = pItem1->parent;
+ pItem1->parent = pItem2;
+ offs0004++;
+ }
+}
+
+// 1500E920
+unsigned int THuffmannTree::DoCompression(TOutputStream * os, unsigned char * pbInBuffer, int nInLength, int nCmpType)
+{
+ THTreeItem * pItem1;
+ THTreeItem * pItem2;
+ THTreeItem * pItem3;
+ THTreeItem * pTemp;
+ unsigned long dwBitBuff;
+ unsigned int nBits;
+ unsigned int nBit;
+
+ BuildTree(nCmpType);
+ bIsCmp0 = (nCmpType == 0);
+
+ // Store the compression type into output buffer
+ os->dwBitBuff |= (nCmpType << os->nBits);
+ os->nBits += 8;
+
+ // Flush completed bytes
+ while(os->nBits >= 8)
+ {
+ if(os->cbOutSize != 0)
+ {
+ *os->pbOutPos++ = (unsigned char)os->dwBitBuff;
+ os->cbOutSize--;
+ }
+
+ os->dwBitBuff >>= 8;
+ os->nBits -= 8;
+ }
+
+ for(; nInLength != 0; nInLength--)
+ {
+ unsigned char bOneByte = *pbInBuffer++;
+
+ if((pItem1 = items306C[bOneByte]) == NULL)
+ {
+ pItem2 = items306C[0x101]; // ecx
+ pItem3 = pItem2->parent; // eax
+ dwBitBuff = 0;
+ nBits = 0;
+
+ for(; pItem3 != NULL; pItem3 = pItem3->parent)
+ {
+ nBit = (pItem3->child != pItem2) ? 1 : 0;
+ dwBitBuff = (dwBitBuff << 1) | nBit;
+ nBits++;
+ pItem2 = pItem3;
+ }
+ os->PutBits(dwBitBuff, nBits);
+
+ // Store the loaded byte into output stream
+ os->dwBitBuff |= (bOneByte << os->nBits);
+ os->nBits += 8;
+
+ // Flush the whole byte(s)
+ while(os->nBits >= 8)
+ {
+ if(os->cbOutSize != 0)
+ {
+ *os->pbOutPos++ = (unsigned char)os->dwBitBuff;
+ os->cbOutSize--;
+ }
+ os->dwBitBuff >>= 8;
+ os->nBits -= 8;
+ }
+
+ pItem1 = (PTR_INVALID_OR_NULL(pLast)) ? NULL : pLast;
+ pItem2 = Call1500E740(1);
+ pItem2->dcmpByte = pItem1->dcmpByte;
+ pItem2->byteValue = pItem1->byteValue;
+ pItem2->parent = pItem1;
+ items306C[pItem2->dcmpByte] = pItem2;
+
+ pItem2 = Call1500E740(1);
+ pItem2->dcmpByte = bOneByte;
+ pItem2->byteValue = 0;
+ pItem2->parent = pItem1;
+ items306C[pItem2->dcmpByte] = pItem2;
+ pItem1->child = pItem2;
+
+ Call1500E820(pItem2);
+
+ if(bIsCmp0 != 0)
+ {
+ Call1500E820(items306C[bOneByte]);
+ continue;
+ }
+
+ for(pItem1 = items306C[bOneByte]; pItem1 != NULL; pItem1 = pItem1->parent)
+ {
+ pItem1->byteValue++;
+ pItem2 = pItem1;
+
+ for(;;)
+ {
+ pItem3 = pItem2->prev;
+ if(PTR_INVALID_OR_NULL(pItem3))
+ {
+ pItem3 = NULL;
+ break;
+ }
+ if(pItem3->byteValue >= pItem1->byteValue)
+ break;
+ pItem2 = pItem3;
+ }
+
+ if(pItem2 != pItem1)
+ {
+ InsertItem(&pItem305C, pItem2, SWITCH_ITEMS, pItem1);
+ InsertItem(&pItem305C, pItem1, SWITCH_ITEMS, pItem3);
+
+ pItem3 = pItem2->parent->child;
+ if(pItem1->parent->child == pItem1)
+ pItem1->parent->child = pItem2;
+
+ if(pItem3 == pItem2)
+ pItem2->parent->child = pItem1;
+
+ pTemp = pItem1->parent;
+ pItem1->parent = pItem2->parent;
+ pItem2->parent = pTemp;
+ offs0004++;
+ }
+ }
+ }
+// 1500EB62
+ else
+ {
+ dwBitBuff = 0;
+ nBits = 0;
+ for(pItem2 = pItem1->parent; pItem2 != NULL; pItem2 = pItem2->parent)
+ {
+ nBit = (pItem2->child != pItem1) ? 1 : 0;
+ dwBitBuff = (dwBitBuff << 1) | nBit;
+ nBits++;
+ pItem1 = pItem2;
+ }
+ os->PutBits(dwBitBuff, nBits);
+ }
+
+// 1500EB98
+ if(bIsCmp0 != 0)
+ Call1500E820(items306C[bOneByte]); // 1500EB9D
+// 1500EBAF
+ } // for(; nInLength != 0; nInLength--)
+
+// 1500EBB8
+ pItem1 = items306C[0x100];
+ dwBitBuff = 0;
+ nBits = 0;
+ for(pItem2 = pItem1->parent; pItem2 != NULL; pItem2 = pItem2->parent)
+ {
+ nBit = (pItem2->child != pItem1) ? 1 : 0;
+ dwBitBuff = (dwBitBuff << 1) | nBit;
+ nBits++;
+ pItem1 = pItem2;
+ }
+
+// 1500EBE6
+ os->PutBits(dwBitBuff, nBits);
+
+// 1500EBEF
+ // Flush the remaining bits
+ while(os->nBits != 0)
+ {
+ if(os->cbOutSize != 0)
+ {
+ *os->pbOutPos++ = (unsigned char)os->dwBitBuff;
+ os->cbOutSize--;
+ }
+ os->dwBitBuff >>= 8;
+ os->nBits -= ((os->nBits > 8) ? 8 : os->nBits);
+ }
+
+ return (unsigned int)(os->pbOutPos - os->pbOutBuffer);
+}
+
+// Decompression using Huffman tree (1500E450)
+unsigned int THuffmannTree::DoDecompression(unsigned char * pbOutBuffer, unsigned int dwOutLength, TInputStream * is)
+{
+ TQDecompress * qd;
+ THTreeItem * pItem1;
+ THTreeItem * pItem2;
+ unsigned char * pbOutPos = pbOutBuffer;
+ unsigned long nBitCount;
+ unsigned int nDcmpByte = 0;
+ unsigned int n8Bits; // 8 bits loaded from input stream
+ unsigned int n7Bits; // 7 bits loaded from input stream
+ bool bHasQdEntry;
+
+ // Test the output length. Must not be NULL.
+ if(dwOutLength == 0)
+ return 0;
+
+ // Get the compression type from the input stream
+ n8Bits = is->Get8Bits();
+
+ // Build the Huffman tree
+ BuildTree(n8Bits);
+ bIsCmp0 = (n8Bits == 0) ? 1 : 0;
+
+ for(;;)
+ {
+ // Security check: If we are at the end of the input buffer,
+ // it means that the data is corrupt
+ if(is->BitCount == 0 && is->pbInBuffer >= is->pbInBufferEnd)
+ return 0;
+
+ // Get 7 bits from input stream
+ n7Bits = is->Get7Bits();
+
+ // Try to use quick decompression. Check TQDecompress array for corresponding item.
+ // If found, ise the result byte instead.
+ qd = &qd3474[n7Bits];
+
+ // If there is a quick-pass possible (ebx)
+ bHasQdEntry = (qd->offs00 >= offs0004) ? true : false;
+
+ // If we can use quick decompress, use it.
+ if(bHasQdEntry)
+ {
+ if(qd->nBits > 7)
+ {
+ is->SkipBits(7);
+ pItem1 = qd->pItem;
+ goto _1500E549;
+ }
+ is->SkipBits(qd->nBits);
+ nDcmpByte = qd->dcmpByte;
+ }
+ else
+ {
+ pItem1 = pFirst->next->prev;
+ if(PTR_INVALID_OR_NULL(pItem1))
+ pItem1 = NULL;
+_1500E549:
+ nBitCount = 0;
+ pItem2 = NULL;
+
+ do
+ {
+ if(pItem1 == NULL)
+ return 0;
+
+ pItem1 = pItem1->child; // Move down by one level
+ if(is->GetBit()) // If current bit is set, move to previous
+ pItem1 = pItem1->prev;
+
+ if(++nBitCount == 7) // If we are at 7th bit, save current HTree item.
+ pItem2 = pItem1;
+ }
+ while(pItem1->child != NULL); // Walk until tree has no deeper level
+
+ if(bHasQdEntry == false)
+ {
+ if(nBitCount > 7)
+ {
+ qd->offs00 = offs0004;
+ qd->nBits = nBitCount;
+ qd->pItem = pItem2;
+ }
+ else
+ {
+ unsigned long nIndex = n7Bits & (0xFFFFFFFF >> (32 - nBitCount));
+ unsigned long nAdd = (1 << nBitCount);
+
+ for(qd = &qd3474[nIndex]; nIndex <= 0x7F; nIndex += nAdd, qd += nAdd)
+ {
+ qd->offs00 = offs0004;
+ qd->nBits = nBitCount;
+ qd->dcmpByte = pItem1->dcmpByte;
+ }
+ }
+ }
+ nDcmpByte = pItem1->dcmpByte;
+ }
+
+ if(nDcmpByte == 0x101) // Huffman tree needs to be modified
+ {
+ n8Bits = is->Get8Bits();
+ pItem1 = (PTR_INVALID_OR_NULL(pLast)) ? NULL : pLast;
+
+ pItem2 = Call1500E740(1);
+ pItem2->parent = pItem1;
+ pItem2->dcmpByte = pItem1->dcmpByte;
+ pItem2->byteValue = pItem1->byteValue;
+ items306C[pItem2->dcmpByte] = pItem2;
+
+ pItem2 = Call1500E740(1);
+ pItem2->parent = pItem1;
+ pItem2->dcmpByte = n8Bits;
+ pItem2->byteValue = 0;
+ items306C[pItem2->dcmpByte] = pItem2;
+
+ pItem1->child = pItem2;
+ Call1500E820(pItem2);
+ if(bIsCmp0 == 0)
+ Call1500E820(items306C[n8Bits]);
+
+ nDcmpByte = n8Bits;
+ }
+
+ if(nDcmpByte == 0x100)
+ break;
+
+ *pbOutPos++ = (unsigned char)nDcmpByte;
+ if(--dwOutLength == 0)
+ break;
+
+ if(bIsCmp0)
+ Call1500E820(items306C[nDcmpByte]);
+ }
+
+ return (unsigned int)(pbOutPos - pbOutBuffer);
+}
+
+
+// Table for (de)compression. Every compression type has 258 entries
+unsigned char THuffmannTree::Table1502A630[] =
+{
+ // Data for compression type 0x00
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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
+};
diff --git a/src/huffman/huff_old.h b/src/huffman/huff_old.h
new file mode 100644
index 0000000..83e9b2c
--- /dev/null
+++ b/src/huffman/huff_old.h
@@ -0,0 +1,142 @@
+/*****************************************************************************/
+/* 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__
+
+#include "../StormPort.h"
+
+//-----------------------------------------------------------------------------
+// Defines
+
+#define INSERT_ITEM 1
+#define SWITCH_ITEMS 2 // Switch the item1 and item2
+
+#define PTR_NOT(ptr) (THTreeItem *)(~(DWORD_PTR)(ptr))
+#define PTR_PTR(ptr) ((THTreeItem *)(ptr))
+#define PTR_INT(ptr) (INT_PTR)(ptr)
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+//-----------------------------------------------------------------------------
+// Structures and classes
+
+// Input stream for Huffmann decompression
+class TInputStream
+{
+ public:
+
+ unsigned long GetBit();
+ unsigned long Get7Bits();
+ unsigned long Get8Bits();
+ void SkipBits(unsigned int BitCount);
+
+ unsigned char * pbInBuffer; // Input data
+ unsigned char * pbInBufferEnd; // End of the input buffer
+ unsigned long BitBuffer; // Input bit buffer
+ unsigned int BitCount; // Number of bits remaining in 'dwBitBuff'
+};
+
+// Output stream for Huffmann compression
+class TOutputStream
+{
+ public:
+
+ void PutBits(unsigned long dwBuff, unsigned int nPutBits);
+
+ unsigned char * pbOutBuffer; // 00 : Output buffer
+ unsigned long cbOutSize; // 04 : Size of output buffer
+ unsigned char * pbOutPos; // 08 : Current output position
+ unsigned long dwBitBuff; // 0C : Bit buffer
+ unsigned long nBits; // 10 : Number of bits in the bit buffer
+};
+
+// Huffmann tree item (?)
+struct THTreeItem
+{
+ THTreeItem * Call1501DB70(THTreeItem * pLast);
+ THTreeItem * GetPrevItem(LONG_PTR value);
+ void ClearItemLinks();
+ void RemoveItem();
+
+ THTreeItem * next; // 00 - Pointer to next THTreeItem
+ THTreeItem * prev; // 04 - Pointer to prev THTreeItem (< 0 if none)
+ unsigned long dcmpByte; // 08 - Index of this item in item pointer array, decompressed byte value
+ unsigned long byteValue; // 0C - Some byte value
+ THTreeItem * parent; // 10 - Pointer to parent THTreeItem (NULL if none)
+ THTreeItem * child; // 14 - Pointer to child THTreeItem
+ int addressMultiplier; // -1 if object on negative address (>0x80000000), +1 if positive
+};
+
+// Structure used for quick decompress. The 'bitCount' contains number of bits
+// and byte value contains result decompressed byte value.
+// After each walk through Huffman tree are filled all entries which are
+// multiplies of number of bits loaded from input stream. These entries
+// contain number of bits and result value. At the next 7 bits is tested this
+// structure first. If corresponding entry found, decompression routine will
+// not walk through Huffman tree and directly stores output byte to output stream.
+struct TQDecompress
+{
+ unsigned long offs00; // 00 - 1 if resolved
+ unsigned long nBits; // 04 - Bit count
+ union
+ {
+ unsigned long dcmpByte; // 08 - Byte value for decompress (if bitCount <= 7)
+ THTreeItem * pItem; // 08 - THTreeItem (if number of bits is greater than 7
+ };
+};
+
+// 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();
+ void InitTree(bool bCompression);
+ void BuildTree(unsigned int nCmpType);
+// void ModifyTree(unsigned long dwIndex);
+// void UninitTree();
+
+// void Call15007010(Bit32 dwInLength, THTreeItem * item);
+ THTreeItem * Call1500E740(unsigned int nValue);
+ void Call1500E820(THTreeItem * pItem);
+ unsigned int DoCompression(TOutputStream * os, unsigned char * pbInBuffer, int nInLength, int nCmpType);
+ unsigned int DoDecompression(unsigned char * pbOutBuffer, unsigned int dwOutLength, TInputStream * is);
+
+ unsigned long bIsCmp0; // 0000 - 1 if compression type 0
+ unsigned long offs0004; // 0004 - Some flag
+ THTreeItem items0008[0x203]; // 0008 - HTree items
+
+ //- Sometimes used as HTree item -----------
+ THTreeItem * pItem3050; // 3050 - Always NULL (?)
+ THTreeItem * pItem3054; // 3054 - Pointer to Huffman tree item
+ THTreeItem * pItem3058; // 3058 - Pointer to Huffman tree item (< 0 if invalid)
+
+ //- Sometimes used as HTree item -----------
+ THTreeItem * pItem305C; // 305C - Usually NULL
+ THTreeItem * pFirst; // 3060 - Pointer to top (first) Huffman tree item
+ THTreeItem * pLast; // 3064 - Pointer to bottom (last) Huffman tree item (< 0 if invalid)
+ unsigned long nItems; // 3068 - Number of used HTree items
+
+ //-------------------------------------------
+ THTreeItem * items306C[0x102]; // 306C - THTreeItem pointer array
+ TQDecompress qd3474[0x80]; // 3474 - Array for quick decompression
+ int addressMultiplier; // -1 if object on negative address (>0x80000000), +1 if positive
+
+ static unsigned char Table1502A630[];// Some table
+};
+
+#endif // __HUFFMAN_H__
diff --git a/src/jenkins/lookup.h b/src/jenkins/lookup.h
new file mode 100644
index 0000000..54ccc97
--- /dev/null
+++ b/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 <stdint.h> /* 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/src/jenkins/lookup3.c b/src/jenkins/lookup3.c
new file mode 100644
index 0000000..6af56b4
--- /dev/null
+++ b/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 <stdio.h> /* defines printf for tests */
+#include <time.h> /* defines time_t for timings in the test */
+
+#ifdef linux
+#include <sys/param.h> /* attempt to define endianness */
+#include <endian.h> /* 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<n; ++i) h = hashlittle( k[i], len[i], h);
+
+By Bob Jenkins, 2006. bob_jenkins@burtleburtle.net. You may use this
+code any way you wish, private, educational, or commercial. It's free.
+
+Use for hash table lookup, or anything where one collision in 2^^32 is
+acceptable. Do NOT use for cryptographic purposes.
+-------------------------------------------------------------------------------
+*/
+
+uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
+{
+ 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) + initval;
+
+ 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 : 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<hlen; ++i) /*----------------------- for each input byte, */
+ {
+ for (j=0; j<8; ++j) /*------------------------ for each input bit, */
+ {
+ for (m=1; m<8; ++m) /*------------ for serveral possible initvals, */
+ {
+ for (l=0; l<HASHSTATE; ++l)
+ e[l]=f[l]=g[l]=h[l]=x[l]=y[l]=~((uint32_t)0);
+
+ /*---- check that every output bit is affected by that input bit */
+ for (k=0; k<MAXPAIR; k+=2)
+ {
+ uint32_t finished=1;
+ /* keys have one bit different */
+ for (l=0; l<hlen+1; ++l) {a[l] = b[l] = (uint8_t)0;}
+ /* have a and b be two keys differing in only one bit */
+ a[i] ^= (k<<j);
+ a[i] ^= (k>>(8-j));
+ c[0] = hashlittle(a, hlen, m);
+ b[i] ^= ((k+1)<<j);
+ 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; l<HASHSTATE; ++l)
+ {
+ e[l] &= (c[l]^d[l]);
+ f[l] &= ~(c[l]^d[l]);
+ g[l] &= c[l];
+ h[l] &= ~c[l];
+ x[l] &= d[l];
+ y[l] &= ~d[l];
+ if (e[l]|f[l]|g[l]|h[l]|x[l]|y[l]) finished=0;
+ }
+ if (finished) break;
+ }
+ if (k>z) 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; i<MAXLEN; ++i)
+ {
+ len = i;
+ for (j=0; j<i; ++j) *(b+j)=0;
+
+ /* these should all be equal */
+ ref = hashlittle(b, len, (uint32_t)1);
+ *(b+i)=(uint8_t)~0;
+ *(b-1)=(uint8_t)~0;
+ x = hashlittle(b, len, (uint32_t)1);
+ y = hashlittle(b, len, (uint32_t)1);
+ if ((ref != x) || (ref != y))
+ {
+ printf("alignment error: %.8x %.8x %.8x %d %d\n",ref,x,y,
+ h, i);
+ }
+ }
+ }
+}
+
+/* check for problems with nulls */
+ void driver4()
+{
+ uint8_t buf[1];
+ uint32_t h,i,state[HASHSTATE];
+
+
+ buf[0] = ~0;
+ for (i=0; i<HASHSTATE; ++i) state[i] = 1;
+ printf("These should all be different\n");
+ for (i=0, h=0; i<8; ++i)
+ {
+ h = hashlittle(buf, 0, h);
+ printf("%2ld 0-byte strings, hash is %.8x\n", i, h);
+ }
+}
+
+void driver5()
+{
+ uint32_t b,c;
+ b=0, c=0, hashlittle2("", 0, &c, &b);
+ printf("hash is %.8lx %.8lx\n", c, b); /* deadbeef deadbeef */
+ b=0xdeadbeef, c=0, hashlittle2("", 0, &c, &b);
+ printf("hash is %.8lx %.8lx\n", c, b); /* bd5b7dde deadbeef */
+ b=0xdeadbeef, c=0xdeadbeef, hashlittle2("", 0, &c, &b);
+ printf("hash is %.8lx %.8lx\n", c, b); /* 9c093ccd bd5b7dde */
+ b=0, c=0, hashlittle2("Four score and seven years ago", 30, &c, &b);
+ printf("hash is %.8lx %.8lx\n", c, b); /* 17770551 ce7226e6 */
+ b=1, c=0, hashlittle2("Four score and seven years ago", 30, &c, &b);
+ printf("hash is %.8lx %.8lx\n", c, b); /* e3607cae bd371de4 */
+ b=0, c=1, hashlittle2("Four score and seven years ago", 30, &c, &b);
+ printf("hash is %.8lx %.8lx\n", c, b); /* cd628161 6cbea4b3 */
+ c = hashlittle("Four score and seven years ago", 30, 0);
+ printf("hash is %.8lx\n", c); /* 17770551 */
+ c = hashlittle("Four score and seven years ago", 30, 1);
+ printf("hash is %.8lx\n", c); /* cd628161 */
+}
+
+
+int main()
+{
+ driver1(); /* test that the key is hashed: used for timings */
+ driver2(); /* test that whole key is hashed thoroughly */
+ driver3(); /* test that nothing but the key is hashed */
+ driver4(); /* test hashing multiple buffers (all buffers are null) */
+ driver5(); /* test the hash against known vectors */
+ return 1;
+}
+
+#endif /* SELF_TEST */
diff --git a/src/libtomcrypt/src/hashes/hash_memory.c b/src/libtomcrypt/src/hashes/hash_memory.c
new file mode 100644
index 0000000..1daf0bf
--- /dev/null
+++ b/src/libtomcrypt/src/hashes/hash_memory.c
@@ -0,0 +1,69 @@
+/* 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 hash_memory.c
+ Hash memory helper, Tom St Denis
+*/
+
+/**
+ Hash a block of memory and store the digest.
+ @param hash The index of the hash you wish to use
+ @param in The data you wish to hash
+ @param inlen The length of the data to hash (octets)
+ @param out [out] Where to store the digest
+ @param outlen [in/out] Max size and resulting size of the digest
+ @return CRYPT_OK if successful
+*/
+int hash_memory(int hash, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen)
+{
+ hash_state *md;
+ int err;
+
+ LTC_ARGCHK(in != NULL);
+ LTC_ARGCHK(out != NULL);
+ LTC_ARGCHK(outlen != NULL);
+
+ if ((err = hash_is_valid(hash)) != CRYPT_OK) {
+ return err;
+ }
+
+ if (*outlen < hash_descriptor[hash].hashsize) {
+ *outlen = hash_descriptor[hash].hashsize;
+ return CRYPT_BUFFER_OVERFLOW;
+ }
+
+ md = XMALLOC(sizeof(hash_state));
+ if (md == NULL) {
+ return CRYPT_MEM;
+ }
+
+ if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) {
+ goto LBL_ERR;
+ }
+ if ((err = hash_descriptor[hash].process(md, in, inlen)) != CRYPT_OK) {
+ goto LBL_ERR;
+ }
+ err = hash_descriptor[hash].done(md, out);
+ *outlen = hash_descriptor[hash].hashsize;
+LBL_ERR:
+#ifdef LTC_CLEAN_STACK
+ zeromem(md, sizeof(hash_state));
+#endif
+ XFREE(md);
+
+ return err;
+}
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/helper/hash_memory.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2006/12/28 01:27:23 $ */
diff --git a/src/libtomcrypt/src/hashes/md5.c b/src/libtomcrypt/src/hashes/md5.c
new file mode 100644
index 0000000..4cbd000
--- /dev/null
+++ b/src/libtomcrypt/src/hashes/md5.c
@@ -0,0 +1,368 @@
+/* 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 md5.c
+ LTC_MD5 hash function by Tom St Denis
+*/
+
+#ifdef LTC_MD5
+
+const struct ltc_hash_descriptor md5_desc =
+{
+ "md5",
+ 3,
+ 16,
+ 64,
+
+ /* OID */
+ { 1, 2, 840, 113549, 2, 5, },
+ 6,
+
+ &md5_init,
+ &md5_process,
+ &md5_done,
+ &md5_test,
+ NULL
+};
+
+#define F(x,y,z) (z ^ (x & (y ^ z)))
+#define G(x,y,z) (y ^ (z & (y ^ x)))
+#define H(x,y,z) (x^y^z)
+#define I(x,y,z) (y^(x|(~z)))
+
+#ifdef LTC_SMALL_CODE
+
+#define FF(a,b,c,d,M,s,t) \
+ a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b;
+
+#define GG(a,b,c,d,M,s,t) \
+ a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b;
+
+#define HH(a,b,c,d,M,s,t) \
+ a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b;
+
+#define II(a,b,c,d,M,s,t) \
+ a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b;
+
+static const unsigned char Worder[64] = {
+ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
+ 1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
+ 5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
+ 0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
+};
+
+static const unsigned char Rorder[64] = {
+ 7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
+ 5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
+ 4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
+ 6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
+};
+
+static const ulong32 Korder[64] = {
+0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
+0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
+0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
+0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
+0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
+0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
+0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
+0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL
+};
+
+#else
+
+#define FF(a,b,c,d,M,s,t) \
+ a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b;
+
+#define GG(a,b,c,d,M,s,t) \
+ a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b;
+
+#define HH(a,b,c,d,M,s,t) \
+ a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b;
+
+#define II(a,b,c,d,M,s,t) \
+ a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b;
+
+
+#endif
+
+#ifdef LTC_CLEAN_STACK
+static int _md5_compress(hash_state *md, unsigned char *buf)
+#else
+static int md5_compress(hash_state *md, unsigned char *buf)
+#endif
+{
+ ulong32 i, W[16], a, b, c, d;
+#ifdef LTC_SMALL_CODE
+ ulong32 t;
+#endif
+
+ /* copy the state into 512-bits into W[0..15] */
+ for (i = 0; i < 16; i++) {
+ LOAD32L(W[i], buf + (4*i));
+ }
+
+ /* copy state */
+ a = md->md5.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/src/libtomcrypt/src/hashes/sha1.c b/src/libtomcrypt/src/hashes/sha1.c
new file mode 100644
index 0000000..409d095
--- /dev/null
+++ b/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/src/libtomcrypt/src/headers/tomcrypt.h b/src/libtomcrypt/src/headers/tomcrypt.h
new file mode 100644
index 0000000..74cdff4
--- /dev/null
+++ b/src/libtomcrypt/src/headers/tomcrypt.h
@@ -0,0 +1,87 @@
+#ifndef TOMCRYPT_H_
+#define TOMCRYPT_H_
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <ctype.h>
+#include <limits.h>
+
+/* 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
+
+/* 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/src/libtomcrypt/src/headers/tomcrypt_argchk.h b/src/libtomcrypt/src/headers/tomcrypt_argchk.h
new file mode 100644
index 0000000..cfc93ad
--- /dev/null
+++ b/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 <signal.h>
+
+/* 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/src/libtomcrypt/src/headers/tomcrypt_cfg.h b/src/libtomcrypt/src/headers/tomcrypt_cfg.h
new file mode 100644
index 0000000..7feae6e
--- /dev/null
+++ b/src/libtomcrypt/src/headers/tomcrypt_cfg.h
@@ -0,0 +1,136 @@
+/* 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(*compar)(const void *, const void *));
+
+
+/* change the clock function too */
+LTC_EXPORT clock_t LTC_CALL XCLOCK(void);
+
+/* various other functions */
+LTC_EXPORT void * LTC_CALL XMEMCPY(void *dest, const void *src, size_t n);
+LTC_EXPORT int LTC_CALL XMEMCMP(const void *s1, const void *s2, size_t n);
+LTC_EXPORT void * LTC_CALL XMEMSET(void *s, int c, size_t n);
+
+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/src/libtomcrypt/src/headers/tomcrypt_cipher.h b/src/libtomcrypt/src/headers/tomcrypt_cipher.h
new file mode 100644
index 0000000..bd740bf
--- /dev/null
+++ b/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/src/libtomcrypt/src/headers/tomcrypt_custom.h b/src/libtomcrypt/src/headers/tomcrypt_custom.h
new file mode 100644
index 0000000..88ec8f9
--- /dev/null
+++ b/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
+ #endif
+#define XMEMSET memset
+#endif
+#ifndef XMEMCPY
+ #ifdef memcpy
+ #define LTC_NO_PROTOTYPES
+ #endif
+#define XMEMCPY memcpy
+#endif
+#ifndef XMEMCMP
+ #ifdef memcmp
+ #define LTC_NO_PROTOTYPES
+ #endif
+#define XMEMCMP memcmp
+#endif
+#ifndef XSTRCMP
+ #ifdef strcmp
+ #define LTC_NO_PROTOTYPES
+ #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 <pthread.h>
+
+#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/src/libtomcrypt/src/headers/tomcrypt_hash.h b/src/libtomcrypt/src/headers/tomcrypt_hash.h
new file mode 100644
index 0000000..18553eb
--- /dev/null
+++ b/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/src/libtomcrypt/src/headers/tomcrypt_mac.h b/src/libtomcrypt/src/headers/tomcrypt_mac.h
new file mode 100644
index 0000000..7ad9516
--- /dev/null
+++ b/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/src/libtomcrypt/src/headers/tomcrypt_macros.h b/src/libtomcrypt/src/headers/tomcrypt_macros.h
new file mode 100644
index 0000000..53bda9b
--- /dev/null
+++ b/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 <stdlib.h>
+#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/src/libtomcrypt/src/headers/tomcrypt_math.h b/src/libtomcrypt/src/headers/tomcrypt_math.h
new file mode 100644
index 0000000..a05d7ff
--- /dev/null
+++ b/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/src/libtomcrypt/src/headers/tomcrypt_misc.h b/src/libtomcrypt/src/headers/tomcrypt_misc.h
new file mode 100644
index 0000000..f5384ca
--- /dev/null
+++ b/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/src/libtomcrypt/src/headers/tomcrypt_pk.h b/src/libtomcrypt/src/headers/tomcrypt_pk.h
new file mode 100644
index 0000000..b5f277a
--- /dev/null
+++ b/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 <type, size, data> */
+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 <wchar.h>
+#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/src/libtomcrypt/src/headers/tomcrypt_pkcs.h b/src/libtomcrypt/src/headers/tomcrypt_pkcs.h
new file mode 100644
index 0000000..84fb82a
--- /dev/null
+++ b/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/src/libtomcrypt/src/headers/tomcrypt_prng.h b/src/libtomcrypt/src/headers/tomcrypt_prng.h
new file mode 100644
index 0000000..f3e3e55
--- /dev/null
+++ b/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/src/libtomcrypt/src/math/ltm_desc.c b/src/libtomcrypt/src/math/ltm_desc.c
new file mode 100644
index 0000000..25dc0b3
--- /dev/null
+++ b/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,
+ &copy,
+
+ &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,
+ &divide,
+ &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
+ &ltc_ecc_fp_mulmod,
+#else
+ &ltc_ecc_mulmod,
+#endif
+ &ltc_ecc_projective_add_point,
+ &ltc_ecc_projective_dbl_point,
+ &ltc_ecc_map,
+#ifdef LTC_ECC_SHAMIR
+#ifdef LTC_MECC_FP
+ &ltc_ecc_fp_mul2add,
+#else
+ &ltc_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/src/libtomcrypt/src/math/multi.c b/src/libtomcrypt/src/math/multi.c
new file mode 100644
index 0000000..7d40040
--- /dev/null
+++ b/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 <stdarg.h>
+
+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/src/libtomcrypt/src/math/rand_prime.c b/src/libtomcrypt/src/math/rand_prime.c
new file mode 100644
index 0000000..913fa95
--- /dev/null
+++ b/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/src/libtomcrypt/src/misc/base64_decode.c b/src/libtomcrypt/src/misc/base64_decode.c
new file mode 100644
index 0000000..3d13393
--- /dev/null
+++ b/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/src/libtomcrypt/src/misc/crypt_argchk.c b/src/libtomcrypt/src/misc/crypt_argchk.c
new file mode 100644
index 0000000..537516d
--- /dev/null
+++ b/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 <signal.h>
+
+/**
+ @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/src/libtomcrypt/src/misc/crypt_find_hash.c b/src/libtomcrypt/src/misc/crypt_find_hash.c
new file mode 100644
index 0000000..fef2d8c
--- /dev/null
+++ b/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(&ltc_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(&ltc_hash_mutex);
+ return x;
+ }
+ }
+ LTC_MUTEX_UNLOCK(&ltc_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/src/libtomcrypt/src/misc/crypt_find_prng.c b/src/libtomcrypt/src/misc/crypt_find_prng.c
new file mode 100644
index 0000000..fafbb0e
--- /dev/null
+++ b/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(&ltc_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(&ltc_prng_mutex);
+ return x;
+ }
+ }
+ LTC_MUTEX_UNLOCK(&ltc_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/src/libtomcrypt/src/misc/crypt_hash_descriptor.c b/src/libtomcrypt/src/misc/crypt_hash_descriptor.c
new file mode 100644
index 0000000..5925fd2
--- /dev/null
+++ b/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/src/libtomcrypt/src/misc/crypt_hash_is_valid.c b/src/libtomcrypt/src/misc/crypt_hash_is_valid.c
new file mode 100644
index 0000000..8ed5105
--- /dev/null
+++ b/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(&ltc_hash_mutex);
+ if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) {
+ LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
+ return CRYPT_INVALID_HASH;
+ }
+ LTC_MUTEX_UNLOCK(&ltc_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/src/libtomcrypt/src/misc/crypt_libc.c b/src/libtomcrypt/src/misc/crypt_libc.c
new file mode 100644
index 0000000..bcc89f4
--- /dev/null
+++ b/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 <stdlib.h>
+#include "../headers/tomcrypt.h"
+
+void * LibTomMalloc(size_t n)
+{
+ return malloc(n);
+}
+
+void * LibTomCalloc(size_t n, size_t s)
+{
+ return calloc(n, s);
+}
+
+void * LibTomRealloc(void *p, size_t n)
+{
+ return realloc(p, n);
+}
+
+void LibTomFree(void * p)
+{
+ free(p);
+}
+
+clock_t LibTomClock(void)
+{
+ return clock();
+}
+
+void LibTomQsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *))
+{
+ qsort(base, nmemb, size, compar);
+}
diff --git a/src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c b/src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c
new file mode 100644
index 0000000..91ba9d1
--- /dev/null
+++ b/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;
diff --git a/src/libtomcrypt/src/misc/crypt_prng_descriptor.c b/src/libtomcrypt/src/misc/crypt_prng_descriptor.c
new file mode 100644
index 0000000..c5b39e0
--- /dev/null
+++ b/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/src/libtomcrypt/src/misc/crypt_prng_is_valid.c b/src/libtomcrypt/src/misc/crypt_prng_is_valid.c
new file mode 100644
index 0000000..d38fd3a
--- /dev/null
+++ b/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(&ltc_prng_mutex);
+ if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) {
+ LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
+ return CRYPT_INVALID_PRNG;
+ }
+ LTC_MUTEX_UNLOCK(&ltc_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/src/libtomcrypt/src/misc/crypt_register_hash.c b/src/libtomcrypt/src/misc/crypt_register_hash.c
new file mode 100644
index 0000000..1730091
--- /dev/null
+++ b/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(&ltc_hash_mutex);
+ for (x = 0; x < TAB_SIZE; x++) {
+ if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) {
+ LTC_MUTEX_UNLOCK(&ltc_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(&ltc_hash_mutex);
+ return x;
+ }
+ }
+
+ /* no spot */
+ LTC_MUTEX_UNLOCK(&ltc_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/src/libtomcrypt/src/misc/crypt_register_prng.c b/src/libtomcrypt/src/misc/crypt_register_prng.c
new file mode 100644
index 0000000..29fc9bd
--- /dev/null
+++ b/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(&ltc_prng_mutex);
+ for (x = 0; x < TAB_SIZE; x++) {
+ if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) == 0) {
+ LTC_MUTEX_UNLOCK(&ltc_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(&ltc_prng_mutex);
+ return x;
+ }
+ }
+
+ /* no spot */
+ LTC_MUTEX_UNLOCK(&ltc_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/src/libtomcrypt/src/misc/zeromem.c b/src/libtomcrypt/src/misc/zeromem.c
new file mode 100644
index 0000000..faa0efa
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c b/src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c
new file mode 100644
index 0000000..e536867
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_decode_boolean.c b/src/libtomcrypt/src/pk/asn1/der_decode_boolean.c
new file mode 100644
index 0000000..617d4e8
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_decode_choice.c b/src/libtomcrypt/src/pk/asn1/der_decode_choice.c
new file mode 100644
index 0000000..44a0891
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c b/src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c
new file mode 100644
index 0000000..f2e073b
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_decode_integer.c b/src/libtomcrypt/src/pk/asn1/der_decode_integer.c
new file mode 100644
index 0000000..cca2745
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c b/src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c
new file mode 100644
index 0000000..e7baae8
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c b/src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c
new file mode 100644
index 0000000..523d0ba
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c b/src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c
new file mode 100644
index 0000000..f832593
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c b/src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c
new file mode 100644
index 0000000..9b00f61
--- /dev/null
+++ b/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 <stdarg.h>
+
+
+/**
+ @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/src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c b/src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c
new file mode 100644
index 0000000..9c648bc
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c b/src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c
new file mode 100644
index 0000000..ff633df
--- /dev/null
+++ b/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 <stdarg.h>
+
+
+/**
+ @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 <type, size, data> (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/src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c b/src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c
new file mode 100644
index 0000000..907e4e1
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_decode_utctime.c b/src/libtomcrypt/src/pk/asn1/der_decode_utctime.c
new file mode 100644
index 0000000..7f3f0d7
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c b/src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c
new file mode 100644
index 0000000..898d6cd
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_length_bit_string.c b/src/libtomcrypt/src/pk/asn1/der_length_bit_string.c
new file mode 100644
index 0000000..2bffa3b
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_length_boolean.c b/src/libtomcrypt/src/pk/asn1/der_length_boolean.c
new file mode 100644
index 0000000..e34ce5c
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c b/src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c
new file mode 100644
index 0000000..473bc79
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_length_integer.c b/src/libtomcrypt/src/pk/asn1/der_length_integer.c
new file mode 100644
index 0000000..540d205
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c b/src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c
new file mode 100644
index 0000000..94c326f
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_length_octet_string.c b/src/libtomcrypt/src/pk/asn1/der_length_octet_string.c
new file mode 100644
index 0000000..acd4053
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_length_printable_string.c b/src/libtomcrypt/src/pk/asn1/der_length_printable_string.c
new file mode 100644
index 0000000..ef1ed0e
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_length_sequence.c b/src/libtomcrypt/src/pk/asn1/der_length_sequence.c
new file mode 100644
index 0000000..e75ed7e
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_length_short_integer.c b/src/libtomcrypt/src/pk/asn1/der_length_short_integer.c
new file mode 100644
index 0000000..afa6dd0
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_length_utctime.c b/src/libtomcrypt/src/pk/asn1/der_length_utctime.c
new file mode 100644
index 0000000..1296bab
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c b/src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c
new file mode 100644
index 0000000..514db84
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/asn1/der_sequence_free.c b/src/libtomcrypt/src/pk/asn1/der_sequence_free.c
new file mode 100644
index 0000000..4887215
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c b/src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c
new file mode 100644
index 0000000..5a1324c
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c b/src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c
new file mode 100644
index 0000000..2c468ea
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c b/src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c
new file mode 100644
index 0000000..f9d0cad
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c b/src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c
new file mode 100644
index 0000000..f5a4acb
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c b/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c
new file mode 100644
index 0000000..b4416fc
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c b/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c
new file mode 100644
index 0000000..b990e0a
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c b/src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c
new file mode 100644
index 0000000..e8f6418
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c b/src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c
new file mode 100644
index 0000000..709ab8a
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c b/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c
new file mode 100644
index 0000000..c3a7211
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c b/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c
new file mode 100644
index 0000000..7c3711c
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/rsa/rsa_exptmod.c b/src/libtomcrypt/src/pk/rsa/rsa_exptmod.c
new file mode 100644
index 0000000..ba44106
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/rsa/rsa_free.c b/src/libtomcrypt/src/pk/rsa/rsa_free.c
new file mode 100644
index 0000000..a10ed59
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/rsa/rsa_import.c b/src/libtomcrypt/src/pk/rsa/rsa_import.c
new file mode 100644
index 0000000..6254fd7
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/rsa/rsa_make_key.c b/src/libtomcrypt/src/pk/rsa/rsa_make_key.c
new file mode 100644
index 0000000..bd37b4a
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c b/src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c
new file mode 100644
index 0000000..103ae2f
--- /dev/null
+++ b/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/src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c b/src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c
new file mode 100644
index 0000000..6d8888c
--- /dev/null
+++ b/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/src/libtommath/bn_fast_mp_invmod.c b/src/libtommath/bn_fast_mp_invmod.c
new file mode 100644
index 0000000..597d7a9
--- /dev/null
+++ b/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/src/libtommath/bn_fast_mp_montgomery_reduce.c b/src/libtommath/bn_fast_mp_montgomery_reduce.c
new file mode 100644
index 0000000..65eed7d
--- /dev/null
+++ b/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/src/libtommath/bn_fast_s_mp_mul_digs.c b/src/libtommath/bn_fast_s_mp_mul_digs.c
new file mode 100644
index 0000000..df83f89
--- /dev/null
+++ b/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/src/libtommath/bn_fast_s_mp_mul_high_digs.c b/src/libtommath/bn_fast_s_mp_mul_high_digs.c
new file mode 100644
index 0000000..6866aab
--- /dev/null
+++ b/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/src/libtommath/bn_fast_s_mp_sqr.c b/src/libtommath/bn_fast_s_mp_sqr.c
new file mode 100644
index 0000000..5f9d58c
--- /dev/null
+++ b/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/src/libtommath/bn_mp_2expt.c b/src/libtommath/bn_mp_2expt.c
new file mode 100644
index 0000000..f899eae
--- /dev/null
+++ b/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/src/libtommath/bn_mp_abs.c b/src/libtommath/bn_mp_abs.c
new file mode 100644
index 0000000..14f3a7e
--- /dev/null
+++ b/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/src/libtommath/bn_mp_add.c b/src/libtommath/bn_mp_add.c
new file mode 100644
index 0000000..b368b21
--- /dev/null
+++ b/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/src/libtommath/bn_mp_add_d.c b/src/libtommath/bn_mp_add_d.c
new file mode 100644
index 0000000..c147554
--- /dev/null
+++ b/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/src/libtommath/bn_mp_addmod.c b/src/libtommath/bn_mp_addmod.c
new file mode 100644
index 0000000..0a21f62
--- /dev/null
+++ b/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/src/libtommath/bn_mp_and.c b/src/libtommath/bn_mp_and.c
new file mode 100644
index 0000000..6b7afc1
--- /dev/null
+++ b/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/src/libtommath/bn_mp_clamp.c b/src/libtommath/bn_mp_clamp.c
new file mode 100644
index 0000000..d3cc21c
--- /dev/null
+++ b/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/src/libtommath/bn_mp_clear.c b/src/libtommath/bn_mp_clear.c
new file mode 100644
index 0000000..7644c38
--- /dev/null
+++ b/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/src/libtommath/bn_mp_clear_multi.c b/src/libtommath/bn_mp_clear_multi.c
new file mode 100644
index 0000000..a107624
--- /dev/null
+++ b/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 <stdarg.h>
+
+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/src/libtommath/bn_mp_cmp.c b/src/libtommath/bn_mp_cmp.c
new file mode 100644
index 0000000..761d2b0
--- /dev/null
+++ b/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/src/libtommath/bn_mp_cmp_d.c b/src/libtommath/bn_mp_cmp_d.c
new file mode 100644
index 0000000..420dfd3
--- /dev/null
+++ b/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/src/libtommath/bn_mp_cmp_mag.c b/src/libtommath/bn_mp_cmp_mag.c
new file mode 100644
index 0000000..92565a3
--- /dev/null
+++ b/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/src/libtommath/bn_mp_cnt_lsb.c b/src/libtommath/bn_mp_cnt_lsb.c
new file mode 100644
index 0000000..6040661
--- /dev/null
+++ b/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/src/libtommath/bn_mp_copy.c b/src/libtommath/bn_mp_copy.c
new file mode 100644
index 0000000..7828592
--- /dev/null
+++ b/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/src/libtommath/bn_mp_count_bits.c b/src/libtommath/bn_mp_count_bits.c
new file mode 100644
index 0000000..9d8640f
--- /dev/null
+++ b/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/src/libtommath/bn_mp_div.c b/src/libtommath/bn_mp_div.c
new file mode 100644
index 0000000..3004a3e
--- /dev/null
+++ b/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/src/libtommath/bn_mp_div_2.c b/src/libtommath/bn_mp_div_2.c
new file mode 100644
index 0000000..f3b9d16
--- /dev/null
+++ b/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/src/libtommath/bn_mp_div_2d.c b/src/libtommath/bn_mp_div_2d.c
new file mode 100644
index 0000000..861ea23
--- /dev/null
+++ b/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/src/libtommath/bn_mp_div_3.c b/src/libtommath/bn_mp_div_3.c
new file mode 100644
index 0000000..4fc08fc
--- /dev/null
+++ b/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/src/libtommath/bn_mp_div_d.c b/src/libtommath/bn_mp_div_d.c
new file mode 100644
index 0000000..c0318a4
--- /dev/null
+++ b/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)<<x)) {
+ *p = x;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* single digit division (based on routine from MPI) */
+int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
+{
+ mp_int q;
+ mp_word w;
+ mp_digit t;
+ int res, ix;
+
+ /* cannot divide by zero */
+ if (b == 0) {
+ return MP_VAL;
+ }
+
+ /* quick outs */
+ if (b == 1 || mp_iszero(a) == 1) {
+ if (d != NULL) {
+ *d = 0;
+ }
+ if (c != NULL) {
+ return mp_copy(a, c);
+ }
+ return MP_OKAY;
+ }
+
+ /* power of two ? */
+ if (s_is_power_of_two(b, &ix) == 1) {
+ if (d != NULL) {
+ *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1);
+ }
+ if (c != NULL) {
+ return mp_div_2d(a, ix, c, NULL);
+ }
+ return MP_OKAY;
+ }
+
+#ifdef BN_MP_DIV_3_C
+ /* three? */
+ if (b == 3) {
+ return mp_div_3(a, c, d);
+ }
+#endif
+
+ /* no easy answer [c'est la vie]. Just division */
+ 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 >= 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/src/libtommath/bn_mp_dr_is_modulus.c b/src/libtommath/bn_mp_dr_is_modulus.c
new file mode 100644
index 0000000..22ba5df
--- /dev/null
+++ b/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/src/libtommath/bn_mp_dr_reduce.c b/src/libtommath/bn_mp_dr_reduce.c
new file mode 100644
index 0000000..0afac94
--- /dev/null
+++ b/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/src/libtommath/bn_mp_dr_setup.c b/src/libtommath/bn_mp_dr_setup.c
new file mode 100644
index 0000000..a5152f7
--- /dev/null
+++ b/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/src/libtommath/bn_mp_exch.c b/src/libtommath/bn_mp_exch.c
new file mode 100644
index 0000000..e5ec7f5
--- /dev/null
+++ b/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/src/libtommath/bn_mp_expt_d.c b/src/libtommath/bn_mp_expt_d.c
new file mode 100644
index 0000000..7bf371c
--- /dev/null
+++ b/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/src/libtommath/bn_mp_exptmod.c b/src/libtommath/bn_mp_exptmod.c
new file mode 100644
index 0000000..27c46ea
--- /dev/null
+++ b/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/src/libtommath/bn_mp_exptmod_fast.c b/src/libtommath/bn_mp_exptmod_fast.c
new file mode 100644
index 0000000..31205d4
--- /dev/null
+++ b/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/src/libtommath/bn_mp_exteuclid.c b/src/libtommath/bn_mp_exteuclid.c
new file mode 100644
index 0000000..9881d6e
--- /dev/null
+++ b/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/src/libtommath/bn_mp_fread.c b/src/libtommath/bn_mp_fread.c
new file mode 100644
index 0000000..2976b30
--- /dev/null
+++ b/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/src/libtommath/bn_mp_fwrite.c b/src/libtommath/bn_mp_fwrite.c
new file mode 100644
index 0000000..6782b2e
--- /dev/null
+++ b/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/src/libtommath/bn_mp_gcd.c b/src/libtommath/bn_mp_gcd.c
new file mode 100644
index 0000000..ce980eb
--- /dev/null
+++ b/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/src/libtommath/bn_mp_get_int.c b/src/libtommath/bn_mp_get_int.c
new file mode 100644
index 0000000..d9c76d0
--- /dev/null
+++ b/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/src/libtommath/bn_mp_grow.c b/src/libtommath/bn_mp_grow.c
new file mode 100644
index 0000000..a05dad7
--- /dev/null
+++ b/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/src/libtommath/bn_mp_init.c b/src/libtommath/bn_mp_init.c
new file mode 100644
index 0000000..107d98b
--- /dev/null
+++ b/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/src/libtommath/bn_mp_init_copy.c b/src/libtommath/bn_mp_init_copy.c
new file mode 100644
index 0000000..3ca1186
--- /dev/null
+++ b/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/src/libtommath/bn_mp_init_multi.c b/src/libtommath/bn_mp_init_multi.c
new file mode 100644
index 0000000..4f6f367
--- /dev/null
+++ b/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 <stdarg.h>
+
+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/src/libtommath/bn_mp_init_set.c b/src/libtommath/bn_mp_init_set.c
new file mode 100644
index 0000000..853323f
--- /dev/null
+++ b/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/src/libtommath/bn_mp_init_set_int.c b/src/libtommath/bn_mp_init_set_int.c
new file mode 100644
index 0000000..b2f8727
--- /dev/null
+++ b/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/src/libtommath/bn_mp_init_size.c b/src/libtommath/bn_mp_init_size.c
new file mode 100644
index 0000000..17b8d9f
--- /dev/null
+++ b/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/src/libtommath/bn_mp_invmod.c b/src/libtommath/bn_mp_invmod.c
new file mode 100644
index 0000000..038e584
--- /dev/null
+++ b/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/src/libtommath/bn_mp_invmod_slow.c b/src/libtommath/bn_mp_invmod_slow.c
new file mode 100644
index 0000000..3792a4c
--- /dev/null
+++ b/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/src/libtommath/bn_mp_is_square.c b/src/libtommath/bn_mp_is_square.c
new file mode 100644
index 0000000..5d2fa07
--- /dev/null
+++ b/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/src/libtommath/bn_mp_jacobi.c b/src/libtommath/bn_mp_jacobi.c
new file mode 100644
index 0000000..c70b946
--- /dev/null
+++ b/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/src/libtommath/bn_mp_karatsuba_mul.c b/src/libtommath/bn_mp_karatsuba_mul.c
new file mode 100644
index 0000000..b15ec24
--- /dev/null
+++ b/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))<<B */
+ if (mp_lshd (&x1y1, B * 2) != MP_OKAY)
+ goto X1Y1; /* x1y1 = x1y1 << 2*B */
+
+ if (mp_add (&x0y0, &t1, &t1) != MP_OKAY)
+ goto X1Y1; /* t1 = x0y0 + t1 */
+ if (mp_add (&t1, &x1y1, c) != MP_OKAY)
+ goto X1Y1; /* t1 = x0y0 + t1 + x1y1 */
+
+ /* Algorithm succeeded set the return code to MP_OKAY */
+ err = MP_OKAY;
+
+X1Y1:mp_clear (&x1y1);
+X0Y0:mp_clear (&x0y0);
+T1:mp_clear (&t1);
+Y1:mp_clear (&y1);
+Y0:mp_clear (&y0);
+X1:mp_clear (&x1);
+X0:mp_clear (&x0);
+ERR:
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_karatsuba_mul.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/src/libtommath/bn_mp_karatsuba_sqr.c b/src/libtommath/bn_mp_karatsuba_sqr.c
new file mode 100644
index 0000000..b3a45ab
--- /dev/null
+++ b/src/libtommath/bn_mp_karatsuba_sqr.c
@@ -0,0 +1,121 @@
+#include "tommath.h"
+#ifdef BN_MP_KARATSUBA_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
+ */
+
+/* Karatsuba squaring, computes b = a*a using three
+ * half size squarings
+ *
+ * See comments of karatsuba_mul for details. It
+ * is essentially the same algorithm but merely
+ * tuned to perform recursive squarings.
+ */
+int mp_karatsuba_sqr (mp_int * a, mp_int * b)
+{
+ mp_int x0, x1, t1, t2, x0x0, x1x1;
+ int B, err;
+
+ err = MP_MEM;
+
+ /* min # of digits */
+ B = a->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))<<B */
+ if (mp_lshd (&x1x1, B * 2) != MP_OKAY)
+ goto X1X1; /* x1x1 = x1x1 << 2*B */
+
+ if (mp_add (&x0x0, &t1, &t1) != MP_OKAY)
+ goto X1X1; /* t1 = x0x0 + t1 */
+ if (mp_add (&t1, &x1x1, b) != MP_OKAY)
+ goto X1X1; /* t1 = x0x0 + t1 + x1x1 */
+
+ err = MP_OKAY;
+
+X1X1:mp_clear (&x1x1);
+X0X0:mp_clear (&x0x0);
+T2:mp_clear (&t2);
+T1:mp_clear (&t1);
+X1:mp_clear (&x1);
+X0:mp_clear (&x0);
+ERR:
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_karatsuba_sqr.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/src/libtommath/bn_mp_lcm.c b/src/libtommath/bn_mp_lcm.c
new file mode 100644
index 0000000..af7ae23
--- /dev/null
+++ b/src/libtommath/bn_mp_lcm.c
@@ -0,0 +1,60 @@
+#include "tommath.h"
+#ifdef BN_MP_LCM_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 least common multiple as |a*b|/(a, b) */
+int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
+{
+ int res;
+ mp_int t1, t2;
+
+
+ if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) {
+ return res;
+ }
+
+ /* t1 = get the GCD of the two inputs */
+ if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) {
+ goto LBL_T;
+ }
+
+ /* divide the smallest by the GCD */
+ if (mp_cmp_mag(a, b) == MP_LT) {
+ /* store quotient in t2 such that t2 * b is the LCM */
+ if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
+ goto LBL_T;
+ }
+ res = mp_mul(b, &t2, c);
+ } else {
+ /* store quotient in t2 such that t2 * a is the LCM */
+ if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
+ goto LBL_T;
+ }
+ res = mp_mul(a, &t2, c);
+ }
+
+ /* fix the sign to positive */
+ c->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/src/libtommath/bn_mp_lshd.c b/src/libtommath/bn_mp_lshd.c
new file mode 100644
index 0000000..ffb0def
--- /dev/null
+++ b/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/src/libtommath/bn_mp_mod.c b/src/libtommath/bn_mp_mod.c
new file mode 100644
index 0000000..b24c71f
--- /dev/null
+++ b/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/src/libtommath/bn_mp_mod_2d.c b/src/libtommath/bn_mp_mod_2d.c
new file mode 100644
index 0000000..a54a024
--- /dev/null
+++ b/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/src/libtommath/bn_mp_mod_d.c b/src/libtommath/bn_mp_mod_d.c
new file mode 100644
index 0000000..59886e7
--- /dev/null
+++ b/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/src/libtommath/bn_mp_montgomery_calc_normalization.c b/src/libtommath/bn_mp_montgomery_calc_normalization.c
new file mode 100644
index 0000000..fdefcbd
--- /dev/null
+++ b/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/src/libtommath/bn_mp_montgomery_reduce.c b/src/libtommath/bn_mp_montgomery_reduce.c
new file mode 100644
index 0000000..173848e
--- /dev/null
+++ b/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/src/libtommath/bn_mp_montgomery_setup.c b/src/libtommath/bn_mp_montgomery_setup.c
new file mode 100644
index 0000000..6f27732
--- /dev/null
+++ b/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/src/libtommath/bn_mp_mul.c b/src/libtommath/bn_mp_mul.c
new file mode 100644
index 0000000..a1315da
--- /dev/null
+++ b/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/src/libtommath/bn_mp_mul_2.c b/src/libtommath/bn_mp_mul_2.c
new file mode 100644
index 0000000..3315744
--- /dev/null
+++ b/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/src/libtommath/bn_mp_mul_2d.c b/src/libtommath/bn_mp_mul_2d.c
new file mode 100644
index 0000000..c636c17
--- /dev/null
+++ b/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/src/libtommath/bn_mp_mul_d.c b/src/libtommath/bn_mp_mul_d.c
new file mode 100644
index 0000000..a36a76b
--- /dev/null
+++ b/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/src/libtommath/bn_mp_mulmod.c b/src/libtommath/bn_mp_mulmod.c
new file mode 100644
index 0000000..8ec98bb
--- /dev/null
+++ b/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/src/libtommath/bn_mp_n_root.c b/src/libtommath/bn_mp_n_root.c
new file mode 100644
index 0000000..f188f52
--- /dev/null
+++ b/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/src/libtommath/bn_mp_neg.c b/src/libtommath/bn_mp_neg.c
new file mode 100644
index 0000000..87a8b50
--- /dev/null
+++ b/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/src/libtommath/bn_mp_or.c b/src/libtommath/bn_mp_or.c
new file mode 100644
index 0000000..12601ea
--- /dev/null
+++ b/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/src/libtommath/bn_mp_prime_fermat.c b/src/libtommath/bn_mp_prime_fermat.c
new file mode 100644
index 0000000..297e13c
--- /dev/null
+++ b/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/src/libtommath/bn_mp_prime_is_divisible.c b/src/libtommath/bn_mp_prime_is_divisible.c
new file mode 100644
index 0000000..0ae6498
--- /dev/null
+++ b/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/src/libtommath/bn_mp_prime_is_prime.c b/src/libtommath/bn_mp_prime_is_prime.c
new file mode 100644
index 0000000..0e1e94b
--- /dev/null
+++ b/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/src/libtommath/bn_mp_prime_miller_rabin.c b/src/libtommath/bn_mp_prime_miller_rabin.c
new file mode 100644
index 0000000..47385bc
--- /dev/null
+++ b/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/src/libtommath/bn_mp_prime_next_prime.c b/src/libtommath/bn_mp_prime_next_prime.c
new file mode 100644
index 0000000..833992b
--- /dev/null
+++ b/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)<<DIGIT_BIT) - kstep));
+
+ /* add the step */
+ if ((err = mp_add_d(a, step, a)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ /* if didn't pass sieve and step == MAX then skip test */
+ if (y == 1 && step >= ((((mp_digit)1)<<DIGIT_BIT) - kstep)) {
+ continue;
+ }
+
+ /* is this prime? */
+ for (x = 0; x < t; x++) {
+ mp_set(&b, ltm_prime_tab[t]);
+ if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if (res == MP_NO) {
+ break;
+ }
+ }
+
+ if (res == MP_YES) {
+ break;
+ }
+ }
+
+ err = MP_OKAY;
+LBL_ERR:
+ mp_clear(&b);
+ return err;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_prime_next_prime.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/src/libtommath/bn_mp_prime_rabin_miller_trials.c b/src/libtommath/bn_mp_prime_rabin_miller_trials.c
new file mode 100644
index 0000000..3f7608a
--- /dev/null
+++ b/src/libtommath/bn_mp_prime_rabin_miller_trials.c
@@ -0,0 +1,52 @@
+#include "tommath.h"
+#ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_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 struct {
+ int k, t;
+} sizes[] = {
+{ 128, 28 },
+{ 256, 16 },
+{ 384, 10 },
+{ 512, 7 },
+{ 640, 6 },
+{ 768, 5 },
+{ 896, 4 },
+{ 1024, 4 }
+};
+
+/* returns # of RM trials required for a given bit size */
+int mp_prime_rabin_miller_trials(int size)
+{
+ int x;
+
+ for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) {
+ if (sizes[x].k == size) {
+ return sizes[x].t;
+ } else if (sizes[x].k > 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/src/libtommath/bn_mp_prime_random_ex.c b/src/libtommath/bn_mp_prime_random_ex.c
new file mode 100644
index 0000000..4eec3f6
--- /dev/null
+++ b/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/src/libtommath/bn_mp_radix_size.c b/src/libtommath/bn_mp_radix_size.c
new file mode 100644
index 0000000..2378f1f
--- /dev/null
+++ b/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/src/libtommath/bn_mp_radix_smap.c b/src/libtommath/bn_mp_radix_smap.c
new file mode 100644
index 0000000..5cbe952
--- /dev/null
+++ b/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/src/libtommath/bn_mp_rand.c b/src/libtommath/bn_mp_rand.c
new file mode 100644
index 0000000..e124178
--- /dev/null
+++ b/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/src/libtommath/bn_mp_read_radix.c b/src/libtommath/bn_mp_read_radix.c
new file mode 100644
index 0000000..6869668
--- /dev/null
+++ b/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/src/libtommath/bn_mp_read_signed_bin.c b/src/libtommath/bn_mp_read_signed_bin.c
new file mode 100644
index 0000000..e9a780c
--- /dev/null
+++ b/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/src/libtommath/bn_mp_read_unsigned_bin.c b/src/libtommath/bn_mp_read_unsigned_bin.c
new file mode 100644
index 0000000..7d35370
--- /dev/null
+++ b/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/src/libtommath/bn_mp_reduce.c b/src/libtommath/bn_mp_reduce.c
new file mode 100644
index 0000000..3a6bb5a
--- /dev/null
+++ b/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/src/libtommath/bn_mp_reduce_2k.c b/src/libtommath/bn_mp_reduce_2k.c
new file mode 100644
index 0000000..3191d82
--- /dev/null
+++ b/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/src/libtommath/bn_mp_reduce_2k_l.c b/src/libtommath/bn_mp_reduce_2k_l.c
new file mode 100644
index 0000000..49b7e34
--- /dev/null
+++ b/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/src/libtommath/bn_mp_reduce_2k_setup.c b/src/libtommath/bn_mp_reduce_2k_setup.c
new file mode 100644
index 0000000..aa3b3ba
--- /dev/null
+++ b/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/src/libtommath/bn_mp_reduce_2k_setup_l.c b/src/libtommath/bn_mp_reduce_2k_setup_l.c
new file mode 100644
index 0000000..4eca870
--- /dev/null
+++ b/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/src/libtommath/bn_mp_reduce_is_2k.c b/src/libtommath/bn_mp_reduce_is_2k.c
new file mode 100644
index 0000000..b9ede97
--- /dev/null
+++ b/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/src/libtommath/bn_mp_reduce_is_2k_l.c b/src/libtommath/bn_mp_reduce_is_2k_l.c
new file mode 100644
index 0000000..787875f
--- /dev/null
+++ b/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/src/libtommath/bn_mp_reduce_setup.c b/src/libtommath/bn_mp_reduce_setup.c
new file mode 100644
index 0000000..00e0a62
--- /dev/null
+++ b/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/src/libtommath/bn_mp_rshd.c b/src/libtommath/bn_mp_rshd.c
new file mode 100644
index 0000000..eac6721
--- /dev/null
+++ b/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/src/libtommath/bn_mp_set.c b/src/libtommath/bn_mp_set.c
new file mode 100644
index 0000000..d76d5bb
--- /dev/null
+++ b/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/src/libtommath/bn_mp_set_int.c b/src/libtommath/bn_mp_set_int.c
new file mode 100644
index 0000000..68cf0e3
--- /dev/null
+++ b/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/src/libtommath/bn_mp_shrink.c b/src/libtommath/bn_mp_shrink.c
new file mode 100644
index 0000000..54920d1
--- /dev/null
+++ b/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/src/libtommath/bn_mp_signed_bin_size.c b/src/libtommath/bn_mp_signed_bin_size.c
new file mode 100644
index 0000000..b9492a5
--- /dev/null
+++ b/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/src/libtommath/bn_mp_sqr.c b/src/libtommath/bn_mp_sqr.c
new file mode 100644
index 0000000..c10fa6f
--- /dev/null
+++ b/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/src/libtommath/bn_mp_sqrmod.c b/src/libtommath/bn_mp_sqrmod.c
new file mode 100644
index 0000000..5f4b2f3
--- /dev/null
+++ b/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/src/libtommath/bn_mp_sqrt.c b/src/libtommath/bn_mp_sqrt.c
new file mode 100644
index 0000000..e15ba98
--- /dev/null
+++ b/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/src/libtommath/bn_mp_sub.c b/src/libtommath/bn_mp_sub.c
new file mode 100644
index 0000000..6e72138
--- /dev/null
+++ b/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/src/libtommath/bn_mp_sub_d.c b/src/libtommath/bn_mp_sub_d.c
new file mode 100644
index 0000000..aa08e31
--- /dev/null
+++ b/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/src/libtommath/bn_mp_submod.c b/src/libtommath/bn_mp_submod.c
new file mode 100644
index 0000000..6617ff4
--- /dev/null
+++ b/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/src/libtommath/bn_mp_to_signed_bin.c b/src/libtommath/bn_mp_to_signed_bin.c
new file mode 100644
index 0000000..154f64b
--- /dev/null
+++ b/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/src/libtommath/bn_mp_to_signed_bin_n.c b/src/libtommath/bn_mp_to_signed_bin_n.c
new file mode 100644
index 0000000..e119c38
--- /dev/null
+++ b/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/src/libtommath/bn_mp_to_unsigned_bin.c b/src/libtommath/bn_mp_to_unsigned_bin.c
new file mode 100644
index 0000000..ce69e5b
--- /dev/null
+++ b/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/src/libtommath/bn_mp_to_unsigned_bin_n.c b/src/libtommath/bn_mp_to_unsigned_bin_n.c
new file mode 100644
index 0000000..dfa27c4
--- /dev/null
+++ b/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/src/libtommath/bn_mp_toom_mul.c b/src/libtommath/bn_mp_toom_mul.c
new file mode 100644
index 0000000..e48c6b3
--- /dev/null
+++ b/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/src/libtommath/bn_mp_toom_sqr.c b/src/libtommath/bn_mp_toom_sqr.c
new file mode 100644
index 0000000..fd8bc67
--- /dev/null
+++ b/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/src/libtommath/bn_mp_toradix.c b/src/libtommath/bn_mp_toradix.c
new file mode 100644
index 0000000..539abe9
--- /dev/null
+++ b/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/src/libtommath/bn_mp_toradix_n.c b/src/libtommath/bn_mp_toradix_n.c
new file mode 100644
index 0000000..0322f8d
--- /dev/null
+++ b/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/src/libtommath/bn_mp_unsigned_bin_size.c b/src/libtommath/bn_mp_unsigned_bin_size.c
new file mode 100644
index 0000000..88f3e92
--- /dev/null
+++ b/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/src/libtommath/bn_mp_xor.c b/src/libtommath/bn_mp_xor.c
new file mode 100644
index 0000000..bf0446e
--- /dev/null
+++ b/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/src/libtommath/bn_mp_zero.c b/src/libtommath/bn_mp_zero.c
new file mode 100644
index 0000000..f21db5e
--- /dev/null
+++ b/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/src/libtommath/bn_prime_tab.c b/src/libtommath/bn_prime_tab.c
new file mode 100644
index 0000000..7d306dd
--- /dev/null
+++ b/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/src/libtommath/bn_reverse.c b/src/libtommath/bn_reverse.c
new file mode 100644
index 0000000..d4a919a
--- /dev/null
+++ b/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/src/libtommath/bn_s_mp_add.c b/src/libtommath/bn_s_mp_add.c
new file mode 100644
index 0000000..5ea9c6d
--- /dev/null
+++ b/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/src/libtommath/bn_s_mp_exptmod.c b/src/libtommath/bn_s_mp_exptmod.c
new file mode 100644
index 0000000..9fb2da8
--- /dev/null
+++ b/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/src/libtommath/bn_s_mp_mul_digs.c b/src/libtommath/bn_s_mp_mul_digs.c
new file mode 100644
index 0000000..f04dacf
--- /dev/null
+++ b/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/src/libtommath/bn_s_mp_mul_high_digs.c b/src/libtommath/bn_s_mp_mul_high_digs.c
new file mode 100644
index 0000000..b1d0199
--- /dev/null
+++ b/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/src/libtommath/bn_s_mp_sqr.c b/src/libtommath/bn_s_mp_sqr.c
new file mode 100644
index 0000000..c1e994e
--- /dev/null
+++ b/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/src/libtommath/bn_s_mp_sub.c b/src/libtommath/bn_s_mp_sub.c
new file mode 100644
index 0000000..0ae91cc
--- /dev/null
+++ b/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/src/libtommath/bncore.c b/src/libtommath/bncore.c
new file mode 100644
index 0000000..ad7347f
--- /dev/null
+++ b/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/src/libtommath/tommath.h b/src/libtommath/tommath.h
new file mode 100644
index 0000000..1ead3d0
--- /dev/null
+++ b/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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <limits.h>
+
+#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/src/libtommath/tommath_class.h b/src/libtommath/tommath_class.h
new file mode 100644
index 0000000..18d1553
--- /dev/null
+++ b/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/src/libtommath/tommath_superclass.h b/src/libtommath/tommath_superclass.h
new file mode 100644
index 0000000..2fdebe6
--- /dev/null
+++ b/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/src/lzma/C/LzFind.c b/src/lzma/C/LzFind.c
new file mode 100644
index 0000000..e3ecb05
--- /dev/null
+++ b/src/lzma/C/LzFind.c
@@ -0,0 +1,761 @@
+/* LzFind.c -- Match finder for LZ algorithms
+2009-04-22 : Igor Pavlov : Public domain */
+
+#include <string.h>
+
+#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/src/lzma/C/LzFind.h b/src/lzma/C/LzFind.h
new file mode 100644
index 0000000..010c4b9
--- /dev/null
+++ b/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/src/lzma/C/LzFindMt.c b/src/lzma/C/LzFindMt.c
new file mode 100644
index 0000000..aa41ed9
--- /dev/null
+++ b/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/src/lzma/C/LzFindMt.h b/src/lzma/C/LzFindMt.h
new file mode 100644
index 0000000..b985af5
--- /dev/null
+++ b/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/src/lzma/C/LzHash.h b/src/lzma/C/LzHash.h
new file mode 100644
index 0000000..f3e8996
--- /dev/null
+++ b/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/src/lzma/C/LzmaDec.c b/src/lzma/C/LzmaDec.c
new file mode 100644
index 0000000..2036761
--- /dev/null
+++ b/src/lzma/C/LzmaDec.c
@@ -0,0 +1,999 @@
+/* LzmaDec.c -- LZMA Decoder
+2009-09-20 : Igor Pavlov : Public domain */
+
+#include "LzmaDec.h"
+
+#include <string.h>
+
+#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/src/lzma/C/LzmaDec.h b/src/lzma/C/LzmaDec.h
new file mode 100644
index 0000000..bf7f084
--- /dev/null
+++ b/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/src/lzma/C/LzmaEnc.c b/src/lzma/C/LzmaEnc.c
new file mode 100644
index 0000000..169d4f4
--- /dev/null
+++ b/src/lzma/C/LzmaEnc.c
@@ -0,0 +1,2268 @@
+/* LzmaEnc.c -- LZMA Encoder
+2009-11-24 : Igor Pavlov : Public domain */
+
+#include <string.h>
+
+/* #define SHOW_STAT */
+/* #define SHOW_STAT2 */
+
+#if defined(SHOW_STAT) || defined(SHOW_STAT2)
+#include <stdio.h>
+#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/src/lzma/C/LzmaEnc.h b/src/lzma/C/LzmaEnc.h
new file mode 100644
index 0000000..200d60e
--- /dev/null
+++ b/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/src/lzma/C/Threads.c b/src/lzma/C/Threads.c
new file mode 100644
index 0000000..7af1da2
--- /dev/null
+++ b/src/lzma/C/Threads.c
@@ -0,0 +1,84 @@
+/* Threads.c -- multithreading library
+2009-09-20 : Igor Pavlov : Public domain */
+
+#ifndef _WIN32_WCE
+#include <process.h>
+#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/src/lzma/C/Threads.h b/src/lzma/C/Threads.h
new file mode 100644
index 0000000..d0ddd80
--- /dev/null
+++ b/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/src/lzma/C/Types.h b/src/lzma/C/Types.h
new file mode 100644
index 0000000..0526cb4
--- /dev/null
+++ b/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 <stddef.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#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/src/lzma/info.txt b/src/lzma/info.txt
new file mode 100644
index 0000000..4cee86e
--- /dev/null
+++ b/src/lzma/info.txt
@@ -0,0 +1 @@
+Taken from LZMA SDK v 9.11 \ No newline at end of file
diff --git a/src/pklib/crc32.c b/src/pklib/crc32.c
new file mode 100644
index 0000000..cd47b1d
--- /dev/null
+++ b/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/src/pklib/explode.c b/src/pklib/explode.c
new file mode 100644
index 0000000..73c5004
--- /dev/null
+++ b/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 <assert.h>
+#include <string.h>
+
+#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
+
+static unsigned char DistBits[] =
+{
+ 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
+};
+
+static unsigned char DistCode[] =
+{
+ 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A,
+ 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C,
+ 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
+ 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00
+};
+
+static unsigned char ExLenBits[] =
+{
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
+};
+
+static unsigned short LenBase[] =
+{
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+ 0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106
+};
+
+static unsigned char LenBits[] =
+{
+ 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07
+};
+
+static unsigned char LenCode[] =
+{
+ 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00
+};
+
+static unsigned char ChBitsAsc[] =
+{
+ 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08,
+ 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B,
+ 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06,
+ 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08,
+ 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05,
+ 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D,
+ 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D
+};
+
+static unsigned short ChCodeAsc[] =
+{
+ 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0,
+ 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0,
+ 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360,
+ 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60,
+ 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8,
+ 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098,
+ 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C,
+ 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710,
+ 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8,
+ 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E,
+ 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8,
+ 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088,
+ 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A,
+ 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D,
+ 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078,
+ 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0,
+ 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040,
+ 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380,
+ 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180,
+ 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280,
+ 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080,
+ 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300,
+ 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0,
+ 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320,
+ 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220,
+ 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0,
+ 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0,
+ 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340,
+ 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900,
+ 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600,
+ 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200,
+ 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000
+};
+
+//-----------------------------------------------------------------------------
+// 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], &copyBytes, 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.
+ memcpy(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], &copyBytes, pWork->param);
+ return result;
+}
+
+
+//-----------------------------------------------------------------------------
+// Main exploding function.
+
+unsigned int 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/src/pklib/implode.c b/src/pklib/implode.c
new file mode 100644
index 0000000..1771b18
--- /dev/null
+++ b/src/pklib/implode.c
@@ -0,0 +1,769 @@
+/*****************************************************************************/
+/* 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 <assert.h>
+#include <string.h>
+
+#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
+
+//-----------------------------------------------------------------------------
+// Tables
+
+static unsigned char DistBits[] =
+{
+ 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
+};
+
+static unsigned char DistCode[] =
+{
+ 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A,
+ 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C,
+ 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
+ 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00
+};
+
+static unsigned char ExLenBits[] =
+{
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
+};
+
+static unsigned char LenBits[] =
+{
+ 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07
+};
+
+static unsigned char LenCode[] =
+{
+ 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00
+};
+
+static unsigned char ChBitsAsc[] =
+{
+ 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08,
+ 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B,
+ 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06,
+ 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08,
+ 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05,
+ 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D,
+ 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D
+};
+
+static unsigned short ChCodeAsc[] =
+{
+ 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0,
+ 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0,
+ 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360,
+ 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60,
+ 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8,
+ 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098,
+ 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C,
+ 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710,
+ 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8,
+ 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E,
+ 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8,
+ 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088,
+ 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A,
+ 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D,
+ 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078,
+ 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0,
+ 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040,
+ 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380,
+ 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180,
+ 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280,
+ 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080,
+ 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300,
+ 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0,
+ 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320,
+ 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220,
+ 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0,
+ 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0,
+ 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340,
+ 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900,
+ 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600,
+ 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200,
+ 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000
+};
+
+//-----------------------------------------------------------------------------
+// Macros
+
+// 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;
+ memcpy(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++)
+ {
+ if(1 << ExLenBits[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/src/pklib/pklib.h b/src/pklib/pklib.h
new file mode 100644
index 0000000..f43da15
--- /dev/null
+++ b/src/pklib/pklib.h
@@ -0,0 +1,148 @@
+/*****************************************************************************/
+/* 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__
+
+#include "../StormPort.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]; // 2EB4: 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
+
+//-----------------------------------------------------------------------------
+// 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/src/sparse/sparse.cpp b/src/sparse/sparse.cpp
new file mode 100644
index 0000000..dd65c82
--- /dev/null
+++ b/src/sparse/sparse.cpp
@@ -0,0 +1,296 @@
+/*****************************************************************************/
+/* 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 <assert.h>
+#include <string.h>
+
+#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;
+ }
+ else
+ {
+ // 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 pointers
+ pbOutBuffer++;
+ pbInBuffer++;
+ }
+ }
+
+ // 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 > *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/src/sparse/sparse.h b/src/sparse/sparse.h
new file mode 100644
index 0000000..b1cd872
--- /dev/null
+++ b/src/sparse/sparse.h
@@ -0,0 +1,19 @@
+/*****************************************************************************/
+/* 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__
+
+#include "../StormPort.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/src/zlib/adler32.c b/src/zlib/adler32.c
new file mode 100644
index 0000000..007ba26
--- /dev/null
+++ b/src/zlib/adler32.c
@@ -0,0 +1,149 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#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);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off_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);
+}
diff --git a/src/zlib/compress2.c b/src/zlib/compress2.c
new file mode 100644
index 0000000..df04f01
--- /dev/null
+++ b/src/zlib/compress2.c
@@ -0,0 +1,79 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2003 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) + 11;
+}
diff --git a/src/zlib/crc32.c b/src/zlib/crc32.c
new file mode 100644
index 0000000..f658a9e
--- /dev/null
+++ b/src/zlib/crc32.c
@@ -0,0 +1,423 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64@csc.com.au> 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 <stdio.h>
+# 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 <limits.h>
+# 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)+(((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));
+
+#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;
+ unsigned 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]);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off_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 */
+ if (len2 == 0)
+ return crc1;
+
+ /* put operator for one zero bit in odd */
+ odd[0] = 0xedb88320L; /* 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;
+}
diff --git a/src/zlib/crc32.h b/src/zlib/crc32.h
new file mode 100644
index 0000000..8053b61
--- /dev/null
+++ b/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/src/zlib/deflate.c b/src/zlib/deflate.c
new file mode 100644
index 0000000..29ce1f6
--- /dev/null
+++ b/src/zlib/deflate.c
@@ -0,0 +1,1736 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * 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.3 Copyright 1995-2005 Jean-loup Gailly ";
+/*
+ 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 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));
+#ifndef FASTEST
+#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
+#endif
+local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
+
+#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 */
+
+#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.
+ */
+
+/* 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)<<s->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->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 > MAX_DIST(s)) {
+ length = MAX_DIST(s);
+ 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 (func != configuration_table[level].func && strm->total_in != 0) {
+ /* Flush the last buffer: */
+ err = deflate(strm, Z_PARTIAL_FLUSH);
+ }
+ 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, as well as wrap.
+ * 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 destLen;
+
+ /* conservative upper bound */
+ destLen = sourceLen +
+ ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
+
+ /* if can't get parameters, return conservative bound */
+ if (strm == Z_NULL || strm->state == Z_NULL)
+ return destLen;
+
+ /* if not default parameters, return conservative bound */
+ s = strm->state;
+ if (s->w_bits != 15 || s->hash_bits != 8 + 7)
+ return destLen;
+
+ /* default settings: return tight bound for that case */
+ return compressBound(sourceLen);
+}
+
+/* =========================================================================
+ * 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_FINISH || 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 == 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 != 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 != 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 != 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 != 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 = (*(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 { /* 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 */
+ }
+ }
+ 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 */
+#endif /* FASTEST */
+
+/* ---------------------------------------------------------------------------
+ * Optimized version for level == 1 or strategy == Z_RLE only
+ */
+local uInt longest_match_fast(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;
+}
+
+#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.)
+ */
+ /* %%% avoid this when Z_RLE */
+ 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);
+}
+
+/* ===========================================================================
+ * 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, eof) { \
+ _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), \
+ (eof)); \
+ s->block_start = s->strstart; \
+ flush_pending(s->strm); \
+ Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, eof) { \
+ FLUSH_BLOCK_ONLY(s, eof); \
+ if (s->strm->avail_out == 0) return (eof) ? 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 = NIL; /* 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:
+ */
+ 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).
+ */
+#ifdef FASTEST
+ if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
+ (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+#else
+ if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
+ s->match_length = longest_match (s, hash_head);
+ } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+#endif
+ /* longest_match() or longest_match_fast() 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 = NIL; /* 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:
+ */
+ 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).
+ */
+ if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
+ s->match_length = longest_match (s, hash_head);
+ } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+ /* longest_match() or longest_match_fast() 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 */
+
+#if 0
+/* ===========================================================================
+ * 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 run; /* length of run */
+ uInt max; /* maximum length of run */
+ uInt prev; /* byte at distance one to match */
+ Bytef *scan; /* scan for end 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 */
+ run = 0;
+ if (s->strstart > 0) { /* if there is a previous byte, that is */
+ max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
+ scan = s->window + s->strstart - 1;
+ prev = *scan++;
+ do {
+ if (*scan++ != prev)
+ break;
+ } while (++run < max);
+ }
+
+ /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+ if (run >= MIN_MATCH) {
+ check_match(s, s->strstart, s->strstart - 1, run);
+ _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
+ s->lookahead -= run;
+ s->strstart += run;
+ } 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;
+}
+#endif
diff --git a/src/zlib/deflate.h b/src/zlib/deflate.h
new file mode 100644
index 0000000..05a5ab3
--- /dev/null
+++ b/src/zlib/deflate.h
@@ -0,0 +1,331 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2004 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.
+ */
+
+} 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.
+ */
+
+ /* in trees.c */
+void _tr_init OF((deflate_state *s));
+int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+void _tr_align OF((deflate_state *s));
+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+
+#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 _length_code[];
+ extern uch _dist_code[];
+#else
+ extern const uch _length_code[];
+ extern const uch _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/src/zlib/inffast.c b/src/zlib/inffast.c
new file mode 100644
index 0000000..bbee92e
--- /dev/null
+++ b/src/zlib/inffast.c
@@ -0,0 +1,318 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2004 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 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 write; /* 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 this; /* 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;
+ write = state->write;
+ 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;
+ }
+ this = lcode[hold & lmask];
+ dolen:
+ op = (unsigned)(this.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(this.op);
+ if (op == 0) { /* literal */
+ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", this.val));
+ PUP(out) = (unsigned char)(this.val);
+ }
+ else if (op & 16) { /* length base */
+ len = (unsigned)(this.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;
+ }
+ this = dcode[hold & dmask];
+ dodist:
+ op = (unsigned)(this.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(this.op);
+ if (op & 16) { /* distance base */
+ dist = (unsigned)(this.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) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ from = window - OFF;
+ if (write == 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 (write < op) { /* wrap around window */
+ from += wsize + write - op;
+ op -= write;
+ if (op < len) { /* some from end of window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = window - OFF;
+ if (write < len) { /* some from start of window */
+ op = write;
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ }
+ else { /* contiguous in window */
+ from += write - 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 */
+ this = dcode[this.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 */
+ this = lcode[this.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 write == 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/src/zlib/inffast.h b/src/zlib/inffast.h
new file mode 100644
index 0000000..1e88d2d
--- /dev/null
+++ b/src/zlib/inffast.h
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003 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 inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/src/zlib/inffixed.h b/src/zlib/inffixed.h
new file mode 100644
index 0000000..75ed4b5
--- /dev/null
+++ b/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/src/zlib/inflate.c b/src/zlib/inflate.c
new file mode 100644
index 0000000..792fdee
--- /dev/null
+++ b/src/zlib/inflate.c
@@ -0,0 +1,1368 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2005 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 write == 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->write = 0;
+ state->hold = 0;
+ state->bits = 0;
+ state->lencode = state->distcode = state->next = state->codes;
+ Tracev((stderr, "inflate: reset\n"));
+ return Z_OK;
+}
+
+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 > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
+ value &= (1L << bits) - 1;
+ state->hold += value << state->bits;
+ state->bits += bits;
+ return Z_OK;
+}
+
+int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
+z_streamp strm;
+int windowBits;
+const char *version;
+int stream_size;
+{
+ 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;
+ if (windowBits < 0) {
+ state->wrap = 0;
+ windowBits = -windowBits;
+ }
+ else {
+ state->wrap = (windowBits >> 4) + 1;
+#ifdef GUNZIP
+ if (windowBits < 48) windowBits &= 15;
+#endif
+ }
+ if (windowBits < 8 || windowBits > 15) {
+ ZFREE(strm, state);
+ strm->state = Z_NULL;
+ return Z_STREAM_ERROR;
+ }
+ state->wbits = (unsigned)windowBits;
+ state->window = Z_NULL;
+ return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit_(strm, version, stream_size)
+z_streamp strm;
+const char *version;
+int stream_size;
+{
+ return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+/*
+ 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 <stdio.h>
+
+/*
+ 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->write = 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->write = 0;
+ state->whave = state->wsize;
+ }
+ else {
+ dist = state->wsize - state->write;
+ if (dist > copy) dist = copy;
+ zmemcpy(state->window + state->write, strm->next_out - copy, dist);
+ copy -= dist;
+ if (copy) {
+ zmemcpy(state->window, strm->next_out - copy, copy);
+ state->write = copy;
+ state->whave = state->wsize;
+ }
+ else {
+ state->write += dist;
+ if (state->write == state->wsize) state->write = 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 this; /* 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 (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) 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 */
+ 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;
+ 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 (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.val < 16) {
+ NEEDBITS(this.bits);
+ DROPBITS(this.bits);
+ state->lens[state->have++] = this.val;
+ }
+ else {
+ if (this.val == 16) {
+ NEEDBITS(this.bits + 2);
+ DROPBITS(this.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 (this.val == 17) {
+ NEEDBITS(this.bits + 3);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(this.bits + 7);
+ DROPBITS(this.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;
+
+ /* build code tables */
+ 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;
+ case LEN:
+ if (have >= 6 && left >= 258) {
+ RESTORE();
+ inflate_fast(strm, out);
+ LOAD();
+ break;
+ }
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.op && (this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ state->length = (unsigned)this.val;
+ if ((int)(this.op) == 0) {
+ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", this.val));
+ state->mode = LIT;
+ break;
+ }
+ if (this.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ state->extra = (unsigned)(this.op) & 15;
+ state->mode = LENEXT;
+ case LENEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->length += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ Tracevv((stderr, "inflate: length %u\n", state->length));
+ state->mode = DIST;
+ case DIST:
+ for (;;) {
+ this = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ state->offset = (unsigned)this.val;
+ state->extra = (unsigned)(this.op) & 15;
+ state->mode = DISTEXT;
+ case DISTEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->offset += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+#ifdef INFLATE_STRICT
+ if (state->offset > state->dmax) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ if (state->offset > state->whave + out - left) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ 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->write) {
+ copy -= state->write;
+ from = state->window + (state->wsize - copy);
+ }
+ else
+ from = state->window + (state->write - 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);
+ 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;
+}
diff --git a/src/zlib/inflate.h b/src/zlib/inflate.h
new file mode 100644
index 0000000..07bd3e7
--- /dev/null
+++ b/src/zlib/inflate.h
@@ -0,0 +1,115 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2004 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.
+ */
+
+/* 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, /* 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: 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: waiting for length/lit 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 the BAD or MEM mode -- not shown for clarity)
+
+ Process header:
+ HEAD -> (gzip) or (zlib)
+ (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
+ NAME -> COMMENT -> HCRC -> TYPE
+ (zlib) -> DICTID or TYPE
+ DICTID -> DICT -> TYPE
+ Read deflate blocks:
+ TYPE -> STORED or TABLE or LEN or CHECK
+ STORED -> COPY -> TYPE
+ TABLE -> LENLENS -> CODELENS -> LEN
+ Read deflate codes:
+ 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. */
+struct inflate_state {
+ inflate_mode mode; /* current inflate mode */
+ int last; /* true if processing last block */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ int 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 write; /* 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 */
+};
diff --git a/src/zlib/inftrees.c b/src/zlib/inftrees.c
new file mode 100644
index 0000000..8a9c13f
--- /dev/null
+++ b/src/zlib/inftrees.c
@@ -0,0 +1,329 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2005 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.3 Copyright 1995-2005 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 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 this; /* 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, 201, 196};
+ 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 */
+ this.op = (unsigned char)64; /* invalid code marker */
+ this.bits = (unsigned char)1;
+ this.val = (unsigned short)0;
+ *(*table)++ = this; /* make a table to force an error */
+ *(*table)++ = this;
+ *bits = 1;
+ return 0; /* no symbols, but wait for decoding to report error */
+ }
+ for (min = 1; min <= MAXBITS; 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 when a LENS table is being made
+ against the space in *table, ENOUGH, minus the maximum space needed by
+ the worst case distance code, MAXD. This should never happen, but the
+ sufficiency of ENOUGH has not been proven exhaustively, hence the check.
+ This assumes that when type == LENS, bits == 9.
+
+ 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 - MAXD)
+ return 1;
+
+ /* process all codes and make table entries */
+ for (;;) {
+ /* create table entry */
+ this.bits = (unsigned char)(len - drop);
+ if ((int)(work[sym]) < end) {
+ this.op = (unsigned char)0;
+ this.val = work[sym];
+ }
+ else if ((int)(work[sym]) > end) {
+ this.op = (unsigned char)(extra[work[sym]]);
+ this.val = base[work[sym]];
+ }
+ else {
+ this.op = (unsigned char)(32 + 64); /* end of block */
+ this.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] = this;
+ } 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 - MAXD)
+ 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.
+ */
+ this.op = (unsigned char)64; /* invalid code marker */
+ this.bits = (unsigned char)(len - drop);
+ this.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;
+ this.bits = (unsigned char)len;
+ }
+
+ /* put invalid code marker in table */
+ next[huff >> drop] = this;
+
+ /* 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/src/zlib/inftrees.h b/src/zlib/inftrees.h
new file mode 100644
index 0000000..b1104c8
--- /dev/null
+++ b/src/zlib/inftrees.h
@@ -0,0 +1,55 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2005 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.
+ */
+
+/* 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 dynamic tree. The maximum found in a long but non-
+ exhaustive search was 1444 code structures (852 for length/literals
+ and 592 for distances, the latter actually the result of an
+ exhaustive search). The true maximum is not known, but the value
+ below is more than safe. */
+#define ENOUGH 2048
+#define MAXD 592
+
+/* Type of code to build for inftable() */
+typedef enum {
+ CODES,
+ LENS,
+ DISTS
+} codetype;
+
+extern int inflate_table OF((codetype type, unsigned short FAR *lens,
+ unsigned codes, code FAR * FAR *table,
+ unsigned FAR *bits, unsigned short FAR *work));
diff --git a/src/zlib/trees.c b/src/zlib/trees.c
new file mode 100644
index 0000000..395e4e1
--- /dev/null
+++ b/src/zlib/trees.c
@@ -0,0 +1,1219 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2005 Jean-loup Gailly
+ * 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 <ctype.h>
+#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 void set_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 |= (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 |= 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 |= (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 |= (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: */
+ 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;
+
+ /* 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<<extra_lbits[code]); n++) {
+ _length_code[length++] = (uch)code;
+ }
+ }
+ Assert (length == 256, "tr_static_init: length != 256");
+ /* Note that the length 255 (match length 258) can be represented
+ * in two different ways: code 284 + 5 bits or code 285, so we
+ * overwrite length_code[255] to use the best encoding:
+ */
+ _length_code[length-1] = (uch)code;
+
+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+ dist = 0;
+ for (code = 0 ; code < 16; code++) {
+ base_dist[code] = dist;
+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
+ _dist_code[dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: dist != 256");
+ dist >>= 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 <stdio.h>
+# 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 _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 _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 _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<<MAX_BITS)-1,
+ "inconsistent bit counts");
+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+ for (n = 0; n <= max_code; n++) {
+ int len = tree[n].Len;
+ if (len == 0) continue;
+ /* Now reverse the bits */
+ tree[n].Code = bi_reverse(next_code[len]++, len);
+
+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+ }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ * and corresponding code. The length opt_len is updated; static_len is
+ * also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->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 _tr_stored_block(s, buf, stored_len, eof)
+ deflate_state *s;
+ charf *buf; /* input block */
+ ulg stored_len; /* length of input block */
+ int eof; /* true if this is the last block for a file */
+{
+ send_bits(s, (STORED_BLOCK<<1)+eof, 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 _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 _tr_flush_block(s, buf, stored_len, eof)
+ deflate_state *s;
+ charf *buf; /* input block, or NULL if too old */
+ ulg stored_len; /* length of input block */
+ int eof; /* true 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 (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
+ set_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, eof);
+
+#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)+eof, 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)+eof, 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 (eof) {
+ 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*eof));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int _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;
+}
+
+/* ===========================================================================
+ * Set the data type to BINARY or TEXT, using a crude approximation:
+ * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
+ * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
+ * IN assertion: the fields Freq of dyn_ltree are set.
+ */
+local void set_data_type(s)
+ deflate_state *s;
+{
+ int n;
+
+ for (n = 0; n < 9; n++)
+ if (s->dyn_ltree[n].Freq != 0)
+ break;
+ if (n == 9)
+ for (n = 14; n < 32; n++)
+ if (s->dyn_ltree[n].Freq != 0)
+ break;
+ s->strm->data_type = (n == 32) ? Z_TEXT : 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/src/zlib/trees.h b/src/zlib/trees.h
new file mode 100644
index 0000000..72facf9
--- /dev/null
+++ b/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 _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 _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/src/zlib/zconf.h b/src/zlib/zconf.h
new file mode 100644
index 0000000..03a9431
--- /dev/null
+++ b/src/zlib/zconf.h
@@ -0,0 +1,332 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2005 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.
+ */
+#ifdef Z_PREFIX
+# define deflateInit_ z_deflateInit_
+# define deflate z_deflate
+# define deflateEnd z_deflateEnd
+# define inflateInit_ z_inflateInit_
+# define inflate z_inflate
+# define inflateEnd z_inflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateCopy z_deflateCopy
+# define deflateReset z_deflateReset
+# define deflateParams z_deflateParams
+# define deflateBound z_deflateBound
+# define deflatePrime z_deflatePrime
+# define inflateInit2_ z_inflateInit2_
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateCopy z_inflateCopy
+# define inflateReset z_inflateReset
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# define uncompress z_uncompress
+# define adler32 z_adler32
+# define crc32 z_crc32
+# define get_crc_table z_get_crc_table
+# define zError z_zError
+
+# define alloc_func z_alloc_func
+# define free_func z_free_func
+# define in_func z_in_func
+# define out_func z_out_func
+# define Byte z_Byte
+# define uInt z_uInt
+# define uLong z_uLong
+# define Bytef z_Bytef
+# define charf z_charf
+# define intf z_intf
+# define uIntf z_uIntf
+# define uLongf z_uLongf
+# define voidpf z_voidpf
+# define voidp z_voidp
+#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 <windows.h>
+ /* 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
+
+#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
+# include <sys/types.h> /* for off_t */
+# include <unistd.h> /* for SEEK_* and off_t */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# define z_off_t off_t
+#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(__OS400__)
+# define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+# define NO_vsnprintf
+# ifdef FAR
+# undef FAR
+# endif
+#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/src/zlib/zlib.h b/src/zlib/zlib.h
new file mode 100644
index 0000000..0228179
--- /dev/null
+++ b/src/zlib/zlib.h
@@ -0,0 +1,1357 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.2.3, July 18th, 2005
+
+ Copyright (C) 1995-2005 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.3"
+#define ZLIB_VERNUM 0x1230
+
+/*
+ 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 (for example if an input file is mmap'ed), 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 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+#define Z_BLOCK 5
+/* 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,
+ 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 accumualte 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.
+
+ 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 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. msg is set to null if there is no error
+ message. inflateInit does not perform any decompression apart from reading
+ the zlib header if present: this will be done by inflate(). (So next_in and
+ avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+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, or Z_BLOCK. 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.
+
+ 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 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() will decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically. 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
+ if next_in or next_out was 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 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 a parameter is invalid (such as an invalid
+ method). 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 in
+ deflate or deflate2. 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 (such as NULL dictionary) 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 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 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(). 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 -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_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
+ is set to null if there is no error message. inflateInit2 does not perform
+ any decompression apart from reading the zlib header if present: this will
+ be done by inflate(). (So next_in and avail_in may be modified, but next_out
+ and avail_out are unchanged.)
+*/
+
+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 (such as NULL dictionary) 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 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 NULL).
+*/
+
+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.
+
+ inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the 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 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 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 easily 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.
+ This function can be used to compress a whole file at once if the
+ input file is mmap'ed.
+ 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 compressed buffer.
+ This function can be used to decompress a whole file at once if the
+ input file is mmap'ed.
+
+ 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.
+*/
+
+
+typedef voidp gzFile;
+
+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", or 'R' for run-length encoding
+ as in "wb1R". (See the description of deflateInit2 for more information
+ about the strategy parameter.)
+
+ 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 or if there was
+ insufficient memory to allocate the (de)compression state; errno
+ can be checked to distinguish the two cases (if errno is zero, the
+ zlib error is Z_MEM_ERROR). */
+
+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 (in 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 gzdopen(dup(fd), mode).
+ gzdopen returns NULL if there was insufficient memory to allocate
+ the (de)compression state.
+*/
+
+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.
+ gzread returns the number of uncompressed bytes actually read (0 for
+ end of file, -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 actually written
+ (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the args to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written (0 in case of error). The number of
+ uncompressed bytes written is limited to 4095. The caller should assure that
+ this limit is not exceeded. If it is exceeded, then gzprintf() will return
+ 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.
+*/
+
+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. The string is then terminated with a null
+ character.
+ gzgets returns buf, or Z_NULL in case of error.
+*/
+
+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 again later.
+ Only one character of push-back is allowed. gzungetc() returns the
+ character pushed, or -1 on failure. gzungetc() will fail if a
+ character has been pushed but not read yet, or if c is -1. 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 returns Z_OK if
+ the flush parameter is Z_FINISH and all output could be flushed.
+ gzflush should be called only when strictly necessary because it can
+ degrade compression.
+*/
+
+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.
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns 1 when EOF has previously been detected reading the given
+ input stream, otherwise zero.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+ Returns 1 if file is being read directly without decompression, otherwise
+ zero.
+*/
+
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file
+ and deallocates all the (de)compression state. The return value is the zlib
+ error number (see function gzerror below).
+*/
+
+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.
+*/
+
+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 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 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))
+
+
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+ZEXTERN const char * ZEXPORT zError OF((int));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/src/zlib/zutil.c b/src/zlib/zutil.c
new file mode 100644
index 0000000..d55f594
--- /dev/null
+++ b/src/zlib/zutil.c
@@ -0,0 +1,318 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2005 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 (sizeof(uInt)) {
+ case 2: break;
+ case 4: flags += 1; break;
+ case 8: flags += 2; break;
+ default: flags += 3;
+ }
+ switch (sizeof(uLong)) {
+ case 2: break;
+ case 4: flags += 1 << 2; break;
+ case 8: flags += 2 << 2; break;
+ default: flags += 3 << 2;
+ }
+ switch (sizeof(voidpf)) {
+ case 2: break;
+ case 4: flags += 1 << 4; break;
+ case 8: flags += 2 << 4; break;
+ default: flags += 3 << 4;
+ }
+ switch (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 z_verbose = verbose;
+
+void 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 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 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 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 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 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 zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ return _halloc((long)items, size);
+}
+
+void 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 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 zcfree (opaque, ptr)
+ voidpf opaque;
+ voidpf ptr;
+{
+ free(ptr);
+ if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
diff --git a/src/zlib/zutil.h b/src/zlib/zutil.h
new file mode 100644
index 0000000..b7d5eff
--- /dev/null
+++ b/src/zlib/zutil.h
@@ -0,0 +1,269 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2005 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
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#ifdef STDC
+# ifndef _WIN32_WCE
+# include <stddef.h>
+# endif
+# include <string.h>
+# include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+# ifdef _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. We rename it to
+ * avoid conflict with other libraries that use the same workaround.
+ */
+# define errno z_errno
+# endif
+ extern int errno;
+#else
+# ifndef _WIN32_WCE
+# include <errno.h>
+# endif
+#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 <alloc.h>
+# endif
+# else /* MSC or DJGPP */
+# include <malloc.h>
+# 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 <malloc.h>
+# 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 <unix.h> /* 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))
+# 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
+
+ /* 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)
+# define vsnprintf _vsnprintf
+# 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
+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+ extern void zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+# include <stdio.h>
+ extern int z_verbose;
+ extern void 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 zcalloc OF((voidpf opaque, unsigned items, unsigned size));
+void 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/storm.dll b/storm.dll
new file mode 100644
index 0000000..d4daca0
--- /dev/null
+++ b/storm.dll
Binary files differ
diff --git a/storm_dll/storm_dll.cpp b/storm_dll/storm_dll.cpp
new file mode 100644
index 0000000..2941f2a
--- /dev/null
+++ b/storm_dll/storm_dll.cpp
@@ -0,0 +1,117 @@
+/*****************************************************************************/
+/* Storm.cpp Copyright (c) Ladislav Zezula 2003 */
+/*---------------------------------------------------------------------------*/
+/* This is just a dummy module for building import library for Storm.dll */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 11.04.03 1.00 Lad The first version of Storm.cpp */
+/*****************************************************************************/
+
+#include <windows.h>
+
+#define BUILDING_STORM_CPP
+#define STORM_ALTERNATE_NAMES
+#include "storm_dll.h"
+
+BOOL WINAPI SFILE(OpenArchive)(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, HANDLE *hMPQ)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+BOOL WINAPI SFILE(CloseArchive)(HANDLE hMPQ)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+BOOL WINAPI SFILE(GetArchiveName)(HANDLE hMPQ, LPCSTR lpBuffer, DWORD dwBufferLength)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+BOOL WINAPI SFILE(OpenFile)(LPCSTR lpFileName, HANDLE *hFile)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+BOOL WINAPI SFILE(OpenFileEx)(HANDLE hMPQ, LPCSTR lpFileName, DWORD dwSearchScope, HANDLE *hFile)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+BOOL WINAPI SFILE(CloseFile)(HANDLE hFile)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+DWORD WINAPI SFILE(GetFileSize)(HANDLE hFile, LPDWORD lpFileSizeHigh)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+BOOL WINAPI SFILE(GetFileArchive)(HANDLE hFile, HANDLE *hMPQ)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+BOOL WINAPI SFILE(GetFileName)(HANDLE hFile, LPCSTR lpBuffer, DWORD dwBufferLength)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+DWORD WINAPI SFILE(SetFilePointer)(HANDLE hFile, long lDistanceToMove, PLONG lplDistanceToMoveHigh, DWORD dwMoveMethod)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+BOOL WINAPI SFILE(ReadFile)(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+LCID WINAPI SFILE(SetLocale)(LCID nNewLocale)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+BOOL WINAPI SFILE(GetBasePath)(LPCSTR lpBuffer, DWORD dwBufferLength)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+BOOL WINAPI SFILE(SetBasePath)(LPCSTR lpNewBasePath)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+BOOL WINAPI SFILE(Destroy)()
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+BOOL WINAPI SCOMP(Compress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength, int uCmp, int uCmpType, int nCmpLevel)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+BOOL WINAPI SCOMP(Decompress)(char * pbOutBuffer, int * pdwOutLength, char * pbInBuffer, int dwInLength)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
diff --git a/storm_dll/storm_dll.def b/storm_dll/storm_dll.def
new file mode 100644
index 0000000..8de88f5
--- /dev/null
+++ b/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/storm_dll/storm_dll.h b/storm_dll/storm_dll.h
new file mode 100644
index 0000000..6d67820
--- /dev/null
+++ b/storm_dll/storm_dll.h
@@ -0,0 +1,67 @@
+/*****************************************************************************/
+/* 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 */
+/*****************************************************************************/
+
+// We need the Windows data types for the Storm prototypes
+#include <windows.h>
+
+#ifndef __STORM_H__
+#define __STORM_H__
+
+// Somethimes 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
+
+
+// Just in case anyone is still using C out there
+#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);
+
+
+#if defined(_MSC_VER) && !defined(BUILDING_STORM_CPP)
+#pragma comment(lib, "Storm.lib") // Force linking Storm.lib and thus Storm.dll
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __STORM_H__
diff --git a/stormlib_dll/DllMain.c b/stormlib_dll/DllMain.c
new file mode 100644
index 0000000..cbfa84a
--- /dev/null
+++ b/stormlib_dll/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 <windows.h>
+
+//-----------------------------------------------------------------------------
+// DllMain
+
+DWORD WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved)
+{
+ UNREFERENCED_PARAMETER(hInst);
+ UNREFERENCED_PARAMETER(dwReason);
+ UNREFERENCED_PARAMETER(lpReserved);
+
+ return TRUE;
+}
diff --git a/stormlib_dll/StormLib.def b/stormlib_dll/StormLib.def
new file mode 100644
index 0000000..0ba9188
--- /dev/null
+++ b/stormlib_dll/StormLib.def
@@ -0,0 +1,76 @@
+;
+; Export file for Windows
+; Copyright (c) 2007-2010 Ladislav Zezula
+; ladik@zezula.net
+;
+
+LIBRARY StormLib.dll
+
+EXPORTS
+
+ SFileSetLocale
+ SFileGetLocale
+
+ SFileOpenArchive
+ SFileCreateArchive
+ SFileGetArchiveBitmap
+ 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
diff --git a/stormlib_dll/StormLib.exp b/stormlib_dll/StormLib.exp
new file mode 100644
index 0000000..aa18edb
--- /dev/null
+++ b/stormlib_dll/StormLib.exp
@@ -0,0 +1,75 @@
+#
+# Export file for Mac OS X
+# Copyright (c) 2009 Sam Wilkins
+# swilkins1337@gmail.com
+#
+
+_SFileSetLocale
+_SFileGetLocale
+
+_SFileOpenArchive
+_SFileCreateArchive
+_SFileGetArchiveBitmap
+_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/test/Test.cpp b/test/Test.cpp
new file mode 100644
index 0000000..3edde98
--- /dev/null
+++ b/test/Test.cpp
@@ -0,0 +1,2263 @@
+/*****************************************************************************/
+/* StormLibTest.cpp Copyright (c) Ladislav Zezula 2003 */
+/*---------------------------------------------------------------------------*/
+/* Test module for StormLib */
+/*---------------------------------------------------------------------------*/
+/* Date Ver Who Comment */
+/* -------- ---- --- ------- */
+/* 25.03.03 1.00 Lad The first version of StormLibTest.cpp */
+/*****************************************************************************/
+
+#define _CRT_SECURE_NO_DEPRECATE
+#define __INCLUDE_CRYPTOGRAPHY__
+#define __STORMLIB_SELF__ // Don't use StormLib.lib
+#include <stdio.h>
+
+#ifdef _MSC_VER
+#include <crtdbg.h>
+#endif
+
+#include "../src/StormLib.h"
+#include "../src/StormCommon.h"
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4505) // 'XXX' : unreferenced local function has been removed
+#pragma comment(lib, "winmm.lib")
+#endif
+
+#ifndef ERROR_BAD_LENGTH
+#define ERROR_INVALID_DATA 13L
+#define ERROR_BAD_LENGTH 24L
+#endif
+
+//------------------------------------------------------------------------------
+// Defines
+
+#ifdef PLATFORM_WINDOWS
+#define WORK_PATH_ROOT "E:\\Multimedia\\MPQs\\"
+#endif
+
+#ifdef PLATFORM_LINUX
+#define WORK_PATH_ROOT "/home/ladik/MPQs/"
+#endif
+
+#ifdef PLATFORM_MAC
+#define WORK_PATH_ROOT "/Users/sam/StormLib/test"
+#endif
+
+#ifndef LANG_CZECH
+#define LANG_CZECH 0x0405
+#endif
+
+#define MPQ_SECTOR_SIZE 0x1000
+
+#define MAKE_PATH(path) _T(WORK_PATH_ROOT) _T(path)
+#define MAKE_PATHA(path) (WORK_PATH_ROOT path)
+
+//-----------------------------------------------------------------------------
+// Unicode MPQ names
+
+/* Czech */ static const wchar_t szUnicodeName1[] = {0x010C, 0x0065, 0x0073, 0x006B, 0x00FD, _T('.'), _T('m'), _T('p'), _T('q'), 0};
+/* Russian */ static const wchar_t szUnicodeName2[] = {0x0420, 0x0443, 0x0441, 0x0441, 0x043A, 0x0438, 0x0439, _T('.'), _T('m'), _T('p'), _T('q'), 0};
+/* Greece */ static const wchar_t szUnicodeName3[] = {0x03B5, 0x03BB, 0x03BB, 0x03B7, 0x03BD, 0x03B9, 0x03BA, 0x03AC, _T('.'), _T('m'), _T('p'), _T('q'), 0};
+/* Chinese */ static const wchar_t szUnicodeName4[] = {0x65E5, 0x672C, 0x8A9E, _T('.'), _T('m'), _T('p'), _T('q'), 0};
+/* Japanese */ static const wchar_t szUnicodeName5[] = {0x7B80, 0x4F53, 0x4E2D, 0x6587, _T('.'), _T('m'), _T('p'), _T('q'), 0};
+/* Arabic */ static const wchar_t szUnicodeName6[] = {0x0627, 0x0644, 0x0639, 0x0639, 0x0631, 0x0628, 0x064A, 0x0629, _T('.'), _T('m'), _T('p'), _T('q'), 0};
+
+//-----------------------------------------------------------------------------
+// Constants
+
+static const TCHAR * szWorkDir = MAKE_PATH("Work");
+
+static unsigned int 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
+};
+
+//-----------------------------------------------------------------------------
+// Local testing functions
+
+static void clreol()
+{
+#ifdef PLATFORM_WINDOWS
+ CONSOLE_SCREEN_BUFFER_INFO ScreenInfo;
+ HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
+ LPTSTR szConsoleLine;
+ int nConsoleChars;
+ int i = 0;
+
+ GetConsoleScreenBufferInfo(hConsole, &ScreenInfo);
+ nConsoleChars = (ScreenInfo.srWindow.Right - ScreenInfo.srWindow.Left);
+ if(nConsoleChars > 0)
+ {
+ szConsoleLine = new TCHAR[nConsoleChars + 3];
+ if(szConsoleLine != NULL)
+ {
+ szConsoleLine[i++] = '\r';
+ for(; i < nConsoleChars; i++)
+ szConsoleLine[i] = ' ';
+ szConsoleLine[i++] = '\r';
+ szConsoleLine[i] = 0;
+
+ _tprintf(szConsoleLine);
+ delete [] szConsoleLine;
+ }
+ }
+#endif // PLATFORM_WINDOWS
+}
+
+static void PrintfTA(const TCHAR * szFormat, const TCHAR * szStrT, const char * szStrA, int lcLocale = 0)
+{
+ TCHAR * szTemp;
+ TCHAR szBuffer[MAX_PATH];
+
+ // Convert ANSI string to TCHAR
+ for(szTemp = szBuffer; *szStrA != 0; szTemp++, szStrA++)
+ szTemp[0] = szStrA[0];
+ szTemp[0] = 0;
+
+ _tprintf(szFormat, szStrT, szBuffer, lcLocale);
+}
+
+static void MergeLocalPath(TCHAR * szBuffer, const TCHAR * szPart1, const char * szPart2)
+{
+ // Copy directory name
+ while(*szPart1 != 0)
+ *szBuffer++ = *szPart1++;
+
+ // Add separator
+ *szBuffer++ = _T('/');
+
+ // Copy file name
+ while(*szPart2 != 0)
+ *szBuffer++ = *szPart2++;
+
+ // Terminate the string
+ *szBuffer = 0;
+}
+
+int GetFirstDiffer(void * ptr1, void * ptr2, int nSize)
+{
+ char * buff1 = (char *)ptr1;
+ char * buff2 = (char *)ptr2;
+ int nDiffer;
+
+ for(nDiffer = 0; nDiffer < nSize; nDiffer++)
+ {
+ if(*buff1++ != *buff2++)
+ return nDiffer;
+ }
+ return -1;
+}
+
+static void WINAPI CompactCB(void * /* lpParam */, DWORD dwWork, ULONGLONG BytesDone, ULONGLONG TotalBytes)
+{
+ clreol();
+
+ _tprintf(_T("%u of %u "), (DWORD)BytesDone, (DWORD)TotalBytes);
+ switch(dwWork)
+ {
+ case CCB_CHECKING_FILES:
+ _tprintf(_T("Checking files in archive ...\r"));
+ break;
+
+ case CCB_CHECKING_HASH_TABLE:
+ _tprintf(_T("Checking hash table ...\r"));
+ break;
+
+ case CCB_COPYING_NON_MPQ_DATA:
+ _tprintf(_T("Copying non-MPQ data ...\r"));
+ break;
+
+ case CCB_COMPACTING_FILES:
+ _tprintf(_T("Compacting archive ...\r"));
+ break;
+
+ case CCB_CLOSING_ARCHIVE:
+ _tprintf(_T("Closing archive ...\r"));
+ break;
+ }
+}
+
+static void GenerateRandomDataBlock(LPBYTE pbBuffer, DWORD cbBuffer)
+{
+ LPBYTE pbBufferEnd = pbBuffer + cbBuffer;
+ LPBYTE pbPtr = pbBuffer;
+ DWORD cbBytesToPut = 0;
+ BYTE ByteToPut = 0;
+ bool bRandomData = false;
+
+ while(pbPtr < pbBufferEnd)
+ {
+ // If there are no bytes to put, we will generate new byte and length
+ if(cbBytesToPut == 0)
+ {
+ bRandomData = false;
+ switch(rand() % 10)
+ {
+ case 0: // A short sequence of zeros
+ cbBytesToPut = rand() % 0x08;
+ ByteToPut = 0;
+ break;
+
+ case 1: // A long sequence of zeros
+ cbBytesToPut = rand() % 0x80;
+ ByteToPut = 0;
+ break;
+
+ case 2: // A short sequence of non-zeros
+ cbBytesToPut = rand() % 0x08;
+ ByteToPut = (BYTE)(rand() % 0x100);
+ break;
+
+ case 3: // A long sequence of non-zeros
+ cbBytesToPut = rand() % 0x80;
+ ByteToPut = (BYTE)(rand() % 0x100);
+ break;
+
+ case 4: // A short random data
+ cbBytesToPut = rand() % 0x08;
+ bRandomData = true;
+ break;
+
+ case 5: // A long random data
+ cbBytesToPut = rand() % 0x80;
+ bRandomData = true;
+ break;
+
+ default: // A single random byte
+ cbBytesToPut = 1;
+ ByteToPut = (BYTE)(rand() % 0x100);
+ break;
+ }
+ }
+
+ // Generate random byte, if needed
+ if(bRandomData)
+ ByteToPut = (BYTE)(rand() % 0x100);
+
+ // Put next byte to the output buffer
+ *pbPtr++ = ByteToPut;
+ cbBytesToPut--;
+ }
+}
+
+static bool CompareArchivedFiles(const char * szFileName, HANDLE hFile1, HANDLE hFile2, DWORD dwBlockSize)
+{
+ LPBYTE pbBuffer1 = NULL;
+ LPBYTE pbBuffer2 = NULL;
+ DWORD dwRead1; // Number of bytes read (Storm.dll)
+ DWORD dwRead2; // Number of bytes read (StormLib)
+ bool bResult1 = false; // Result from Storm.dll
+ bool bResult2 = false; // Result from StormLib
+ bool bResult = true;
+ int nDiff;
+
+ szFileName = szFileName;
+
+ // Allocate buffers
+ pbBuffer1 = new BYTE[dwBlockSize];
+ pbBuffer2 = new BYTE[dwBlockSize];
+
+ for(;;)
+ {
+ // Read the file's content by both methods and compare the result
+ memset(pbBuffer1, 0, dwBlockSize);
+ memset(pbBuffer2, 0, dwBlockSize);
+ bResult1 = SFileReadFile(hFile1, pbBuffer1, dwBlockSize, &dwRead1, NULL);
+ bResult2 = SFileReadFile(hFile2, pbBuffer2, dwBlockSize, &dwRead2, NULL);
+ if(bResult1 != bResult2)
+ {
+ _tprintf(_T("Different results from SFileReadFile, Mpq1 %u, Mpq2 %u\n"), bResult1, bResult2);
+ bResult = false;
+ break;
+ }
+
+ // Test the number of bytes read
+ if(dwRead1 != dwRead2)
+ {
+ _tprintf(_T("Different bytes read from SFileReadFile, Mpq1 %u, Mpq2 %u\n"), dwRead1, dwRead2);
+ bResult = false;
+ break;
+ }
+
+ // No more bytes ==> OK
+ if(dwRead1 == 0)
+ break;
+
+ // Test the content
+ if((nDiff = GetFirstDiffer(pbBuffer1, pbBuffer2, dwRead1)) != -1)
+ {
+ bResult = false;
+ break;
+ }
+ }
+
+ delete [] pbBuffer2;
+ delete [] pbBuffer1;
+ return bResult;
+}
+
+// Random read version
+static bool CompareArchivedFilesRR(const char * /* szFileName */, HANDLE hFile1, HANDLE hFile2, DWORD dwBlockSize)
+{
+ const char * szPositions[3] = {"FILE_BEGIN ", "FILE_CURRENT", "FILE_END "};
+ LPBYTE pbBuffer1 = NULL;
+ LPBYTE pbBuffer2 = NULL;
+ DWORD dwFileSize1; // File size (Storm.dll)
+ DWORD dwFileSize2; // File size (StormLib)
+ DWORD dwRead1; // Number of bytes read (Storm.dll)
+ DWORD dwRead2; // Number of bytes read (StormLib)
+ bool bResult1 = false; // Result from Storm.dll
+ bool bResult2 = false; // Result from StormLib
+ int nError = ERROR_SUCCESS;
+
+ // Test the file size
+ dwFileSize1 = SFileGetFileSize(hFile1, NULL);
+ dwFileSize2 = SFileGetFileSize(hFile2, NULL);
+ if(dwFileSize1 != dwFileSize2)
+ {
+ _tprintf(_T("Different size from SFileGetFileSize (file1: %u, file2: %u)\n"), dwFileSize1, dwFileSize2);
+ return false;
+ }
+
+ if(dwFileSize1 != 0)
+ {
+ for(int i = 0; i < 10000; i++)
+ {
+ DWORD dwRandom = rand() * rand();
+ DWORD dwMoveMethod = dwRandom % 3;
+ DWORD dwPosition = dwRandom % dwFileSize1;
+ DWORD dwToRead = dwRandom % dwBlockSize;
+
+ // Also test negative seek
+ if(rand() & 1)
+ {
+ int nPosition = (int)dwPosition;
+ dwPosition = (DWORD)(-nPosition);
+ }
+
+ // Allocate buffers
+ pbBuffer1 = new BYTE[dwToRead];
+ pbBuffer2 = new BYTE[dwToRead];
+
+ // Set the file pointer
+ _tprintf(_T("RndRead (%u): pos %8i from %s, size %u ...\r"), i, dwPosition, szPositions[dwMoveMethod], dwToRead);
+ dwRead1 = SFileSetFilePointer(hFile1, dwPosition, NULL, dwMoveMethod);
+ dwRead2 = SFileSetFilePointer(hFile2, dwPosition, NULL, dwMoveMethod);
+ if(dwRead1 != dwRead2)
+ {
+ _tprintf(_T("Difference returned by SFileSetFilePointer (file1: %u, file2: %u)\n"), dwRead1, dwRead2);
+ nError = ERROR_CAN_NOT_COMPLETE;
+ break;
+ }
+
+ // Read the file's content by both methods and compare the result
+ bResult1 = SFileReadFile(hFile1, pbBuffer1, dwToRead, &dwRead1, NULL);
+ bResult2 = SFileReadFile(hFile2, pbBuffer2, dwToRead, &dwRead2, NULL);
+ if(bResult1 != bResult2)
+ {
+ _tprintf(_T("Different results from SFileReadFile (file1: %u, file2: %u)\n\n"), bResult1, bResult2);
+ nError = ERROR_CAN_NOT_COMPLETE;
+ break;
+ }
+
+ // Test the number of bytes read
+ if(dwRead1 != dwRead2)
+ {
+ _tprintf(_T("Different bytes read from SFileReadFile (file1: %u, file2: %u)\n\n"), dwRead1, dwRead2);
+ nError = ERROR_CAN_NOT_COMPLETE;
+ break;
+ }
+
+ // Test the content
+ if(dwRead1 != 0 && memcmp(pbBuffer1, pbBuffer2, dwRead1))
+ {
+ _tprintf(_T("Different data content from SFileReadFile\n"));
+ nError = ERROR_CAN_NOT_COMPLETE;
+ break;
+ }
+
+ delete [] pbBuffer2;
+ delete [] pbBuffer1;
+ }
+ }
+ clreol();
+ return (nError == ERROR_SUCCESS) ? true : false;
+}
+
+//-----------------------------------------------------------------------------
+// Opening local file
+
+static int TestOpenLocalFile(const char * szFileName)
+{
+ HANDLE hFile;
+ char szRetrievedName[MAX_PATH];
+
+ if(SFileOpenFileEx(NULL, szFileName, SFILE_OPEN_LOCAL_FILE, &hFile))
+ {
+ SFileGetFileName(hFile, szRetrievedName);
+ SFileCloseFile(hFile);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Partial file reading
+
+static int TestPartFileRead(const TCHAR * szFileName)
+{
+ ULONGLONG ByteOffset;
+ ULONGLONG FileSize = 0;
+ TFileStream * pStream;
+ BYTE BigBuffer[0x7000];
+ BYTE Buffer[0x100];
+ int nError = ERROR_SUCCESS;
+
+ // Open the partial file
+ pStream = FileStream_OpenFile(szFileName, false);
+ if(pStream == NULL)
+ nError = GetLastError();
+
+ // Get the size of the stream
+ if(nError == ERROR_SUCCESS)
+ {
+ if(!FileStream_GetSize(pStream, &FileSize))
+ nError = GetLastError();
+ }
+
+ // Read the last 0x7000 bytes
+ if(nError == ERROR_SUCCESS)
+ {
+ ByteOffset = FileSize - sizeof(BigBuffer);
+ if(!FileStream_Read(pStream, &ByteOffset, BigBuffer, sizeof(BigBuffer)))
+ nError = GetLastError();
+ }
+
+ // Read the last 0x100 bytes
+ if(nError == ERROR_SUCCESS)
+ {
+ ByteOffset = FileSize - sizeof(Buffer);
+ if(!FileStream_Read(pStream, &ByteOffset, Buffer, sizeof(Buffer)))
+ nError = GetLastError();
+ }
+
+ // Read 0x100 bytes from position (FileSize - 0xFF)
+ if(nError == ERROR_SUCCESS)
+ {
+ ByteOffset = FileSize - sizeof(Buffer) + 1;
+ if(!FileStream_Read(pStream, &ByteOffset, Buffer, sizeof(Buffer)))
+ nError = GetLastError();
+ }
+
+ FileStream_Close(pStream);
+ return nError;
+}
+
+//-----------------------------------------------------------------------------
+// Compare Huffmann decompression
+
+struct TFileData
+{
+ DWORD dwFileSize;
+ BYTE FileData[1];
+};
+
+static TFileData * ReadFileContent(const TCHAR * szMpqName, const char * szFileName)
+{
+ TFileData * pFileData = NULL;
+ HANDLE hMpq = NULL;
+ HANDLE hFile = NULL;
+ DWORD dwSearchScope = (szMpqName == NULL) ? SFILE_OPEN_LOCAL_FILE : SFILE_OPEN_FROM_MPQ;
+ DWORD dwBytesRead = 0;
+ DWORD dwFileSize = 0;
+
+ // Open the MPQ, if any
+ if(szMpqName != NULL)
+ {
+ if(!SFileOpenArchive(szMpqName, 0, 0, &hMpq))
+ return NULL;
+ }
+
+ // Open the file
+ if(SFileOpenFileEx(hMpq, szFileName, dwSearchScope, &hFile))
+ {
+ dwFileSize = SFileGetFileSize(hFile, NULL);
+ pFileData = (TFileData *)(new BYTE[sizeof(TFileData) + dwFileSize]);
+ if(pFileData != NULL)
+ {
+ SFileReadFile(hFile, pFileData->FileData, dwFileSize, &dwBytesRead, NULL);
+ pFileData->dwFileSize = dwFileSize;
+ }
+ SFileCloseFile(hFile);
+ }
+
+ if(hMpq != NULL)
+ SFileCloseArchive(hMpq);
+ return pFileData;
+}
+
+static TFileData * CompressFileContent(TFileData * pDecompressed, BYTE Compression1, BYTE Compression2)
+{
+ TFileData * pRecompressed;
+ LPBYTE pbOutBuffer;
+ LPBYTE pbInBuffer;
+ DWORD dwBytesRemaining;
+ int cbOutBuffer;
+ int cbInBuffer;
+
+ // Allocate buffer for compressed data
+ pRecompressed = (TFileData *)(new BYTE[sizeof(TFileData) + pDecompressed->dwFileSize]);
+ if(pRecompressed != NULL)
+ {
+ // Set the source and target
+ dwBytesRemaining = pDecompressed->dwFileSize;
+ pbInBuffer = pDecompressed->FileData;
+ pbOutBuffer = pRecompressed->FileData;
+
+ while(dwBytesRemaining != 0)
+ {
+ // Perform the compression
+ cbOutBuffer = cbInBuffer = (int)STORMLIB_MIN(dwBytesRemaining, 0x1000);
+ SCompCompress((char *)pbOutBuffer, &cbOutBuffer, (char *)pbInBuffer, cbInBuffer, Compression1, 0x00, 0);
+ assert(cbOutBuffer < cbInBuffer);
+
+ // Move buffers
+ dwBytesRemaining -= cbInBuffer;
+ pbOutBuffer += cbOutBuffer;
+ pbInBuffer += cbInBuffer;
+ Compression1 = Compression2;
+ }
+
+ // Put the size of the decompressed part
+ pRecompressed->dwFileSize = (DWORD)(pbOutBuffer - pRecompressed->FileData);
+ }
+
+ return pRecompressed;
+}
+
+static int WriteFileContent(const TCHAR * szFileName, TFileData * pFileData)
+{
+ TFileStream * pLocalFile = NULL;
+ int nError = ERROR_SUCCESS;
+
+ // Create the local file
+ if(nError == ERROR_SUCCESS)
+ {
+ pLocalFile = FileStream_CreateFile(szFileName, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
+ if(pLocalFile == NULL)
+ nError = GetLastError();
+ }
+
+ // Write the file data
+ if(nError == ERROR_SUCCESS)
+ {
+ if(!FileStream_Write(pLocalFile, NULL, pFileData->FileData, pFileData->dwFileSize))
+ nError = GetLastError();
+ }
+
+ // Close handles and return
+ if(pLocalFile != NULL)
+ FileStream_Close(pLocalFile);
+ return nError;
+}
+
+static int CompareHuffmanCompressions7()
+{
+ TFileData * pDecompressed1 = NULL;
+ TFileData * pDecompressed2 = NULL;
+ TFileData * pRecompressed1 = NULL;
+ TFileData * pRecompressed2 = NULL;
+ int nDifference;
+ int nError = ERROR_SUCCESS;
+
+ // Load the decompressed data
+ if(nError == ERROR_SUCCESS)
+ {
+ pDecompressed1 = ReadFileContent(MAKE_PATH("BroodWar.mpq"), "music\\prdyroom.wav");
+ pDecompressed2 = ReadFileContent(NULL, MAKE_PATHA("mpq_decompressed.wav"));
+ if(pDecompressed1 != NULL && pDecompressed2 != NULL)
+ {
+ // Compare decompressed size
+ if(pDecompressed1->dwFileSize == pDecompressed2->dwFileSize)
+ {
+ // Compare the data
+ nDifference = GetFirstDiffer(pDecompressed1->FileData, pDecompressed2->FileData, pDecompressed1->dwFileSize);
+ if(nDifference != -1)
+ {
+ _tprintf(_T("Different decompressed data at offset %08X\n\n"), nDifference);
+ nError = ERROR_BAD_FORMAT;
+ }
+ else
+ {
+ _tprintf(_T("Huffmann decompression OK\n"));
+ }
+ }
+ else
+ {
+ _tprintf(_T("Different decompressed size: %u <-> %u\n"), pDecompressed1->dwFileSize, pDecompressed2->dwFileSize);
+ nError = ERROR_BAD_LENGTH;
+ }
+ }
+ else
+ {
+ _tprintf(_T("Failed to real one of the compressed files.\n"));
+ nError = ERROR_CAN_NOT_COMPLETE;
+ }
+ }
+
+ // Get the recompressed data
+ if(nError == ERROR_SUCCESS)
+ {
+ pRecompressed1 = CompressFileContent(pDecompressed1, MPQ_COMPRESSION_PKWARE, MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_HUFFMANN);
+ pRecompressed2 = ReadFileContent(NULL, MAKE_PATHA("mpq_recompressed.bin"));
+ if(pRecompressed1 != NULL && pRecompressed2 != NULL)
+ {
+ // Comprare decompressed size
+ if(pRecompressed1->dwFileSize == pRecompressed2->dwFileSize)
+ {
+ // Compare the data
+ nDifference = GetFirstDiffer(pRecompressed1->FileData, pRecompressed2->FileData, pRecompressed1->dwFileSize);
+ if(nDifference != -1)
+ {
+ _tprintf(_T("Different recompressed data at offset %08X\n"), nDifference);
+ nError = ERROR_BAD_FORMAT;
+ }
+ else
+ {
+ _tprintf(_T("Huffmann recompression OK\n"));
+ }
+ }
+ else
+ {
+ _tprintf(_T("Different recompressed size: %u <-> %u\n"), pRecompressed1->dwFileSize, pRecompressed2->dwFileSize);
+ nError = ERROR_BAD_LENGTH;
+ }
+ }
+ else
+ {
+ _tprintf(_T("Failed to compress the file or read the compressed muster.\n"));
+ nError = ERROR_CAN_NOT_COMPLETE;
+ }
+ }
+
+ assert(nError == ERROR_SUCCESS);
+
+ if(pRecompressed1 != NULL)
+ delete [] pRecompressed1;
+ if(pRecompressed2 != NULL)
+ delete [] pRecompressed2;
+ if(pDecompressed1 != NULL)
+ delete [] pDecompressed1;
+ if(pDecompressed2 != NULL)
+ delete [] pDecompressed2;
+ return ERROR_SUCCESS;
+}
+
+// Just some binary data
+static unsigned char Decompressed[2048] =
+{
+ 0x2E, 0x56, 0xF8, 0x44, 0xB0, 0xE2, 0x58, 0x20, 0x44, 0xBC, 0xE2, 0x46, 0x00, 0x44, 0x4A, 0x1D,
+ 0x59, 0x44, 0xC4, 0xE3, 0x00, 0x00, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x34, 0xE2, 0x01, 0x01,
+ 0x01, 0x6C, 0x44, 0xB4, 0xE2, 0x58, 0x01, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x00, 0xB4, 0xE2, 0x58,
+ 0x44, 0xB4, 0x02, 0x02, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x00, 0x44, 0xB4, 0xE2, 0x40, 0x58,
+ 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0x02, 0x02, 0xE2, 0x58, 0x44, 0x04, 0xB4, 0xE0, 0x58, 0x40,
+ 0x44, 0xC0, 0xC3, 0x58, 0x58, 0x08, 0x8B, 0x8A, 0x4B, 0xDE, 0xF6, 0x80, 0x92, 0x5B, 0xDC, 0x2F,
+ 0xA1, 0x78, 0x10, 0x10, 0x65, 0x1C, 0x32, 0x8A, 0xA2, 0xF4, 0x02, 0xBC, 0x02, 0x02, 0x9A, 0x7A,
+ 0x06, 0x9A, 0x9E, 0x01, 0xF4, 0x38, 0x20, 0xB2, 0xA2, 0x5C, 0xA2, 0x01, 0x9C, 0x8E, 0xF4, 0x06,
+ 0xB2, 0x98, 0x80, 0x80, 0xF4, 0x08, 0x84, 0x8C, 0x7E, 0x40, 0x06, 0x18, 0xEA, 0x66, 0x10, 0x3E,
+ 0x3E, 0x08, 0x20, 0xAE, 0xF6, 0x10, 0x2A, 0xB4, 0x10, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44,
+ 0x00, 0x00, 0xB4, 0xE2, 0x58, 0x44, 0x04, 0xB4, 0xE2, 0x58, 0x80, 0x44, 0xB4, 0xE2, 0x58, 0x44,
+ 0x80, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0x10, 0x10, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x40, 0x58, 0x44,
+ 0x08, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x80, 0x80, 0x58, 0x44, 0xB4,
+ 0xE2, 0x58, 0x44, 0xB4, 0x02, 0x02, 0xE2, 0x58, 0x00, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2,
+ 0x00, 0x00, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0x00, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58,
+ 0x44, 0xB4, 0x01, 0x01, 0x01, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x01, 0x58, 0x44, 0xB4, 0xE2, 0x58,
+ 0x44, 0xB4, 0xE2, 0x58, 0x02, 0x02, 0x44, 0xB4, 0xE2, 0x20, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44,
+ 0x01, 0x01, 0xB4, 0xE2, 0x58, 0x44, 0x40, 0xB4, 0xE2, 0x58, 0x44, 0x40, 0xB4, 0xE2, 0x58, 0x08,
+ 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x08, 0x08, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4,
+ 0x40, 0x40, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x00, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2,
+ 0x01, 0x01, 0x58, 0x44, 0x14, 0x68, 0x58, 0x44, 0x2C, 0xE0, 0x5C, 0x01, 0x01, 0x01, 0x44, 0x20,
+ 0x85, 0x3B, 0xD3, 0xB4, 0xE2, 0x02, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x20, 0x20, 0x44, 0x75, 0xE3,
+ 0x44, 0x08, 0x47, 0xA2, 0xE0, 0x5C, 0x76, 0xB4, 0x00, 0xBA, 0x7E, 0x44, 0x40, 0xB4, 0xB2, 0x4B,
+ 0x44, 0xB4, 0x08, 0x08, 0xE2, 0x58, 0x44, 0xB4, 0xC2, 0x58, 0x01, 0x44, 0xB4, 0xC2, 0x80, 0x58,
+ 0x44, 0xB4, 0x62, 0x10, 0x7E, 0x44, 0xB4, 0xE2, 0xD8, 0x10, 0x44, 0xB4, 0x20, 0xC2, 0x58, 0x44,
+ 0xB4, 0xE6, 0x58, 0x80, 0x80, 0x44, 0xBE, 0xE2, 0x58, 0x44, 0x04, 0xB4, 0xE2, 0x58, 0x44, 0xBE,
+ 0xE2, 0x58, 0x44, 0x10, 0x10, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0x04, 0x82, 0x63, 0x44, 0xB4, 0xEA,
+ 0x58, 0x80, 0x80, 0x44, 0xAE, 0x6E, 0x42, 0x10, 0x44, 0xB0, 0xE2, 0x58, 0x44, 0x01, 0x01, 0xB4,
+ 0xE2, 0x78, 0x44, 0xB4, 0x62, 0x58, 0x04, 0x44, 0xB4, 0xE2, 0x78, 0x44, 0xB4, 0x01, 0x01, 0xC2,
+ 0x58, 0x44, 0xB4, 0xE2, 0x04, 0x58, 0x44, 0x94, 0x02, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44,
+ 0xB4, 0x80, 0x80, 0xE2, 0x58, 0x44, 0x2C, 0xDC, 0x63, 0x44, 0x02, 0x02, 0xDC, 0xE4, 0x58, 0x44,
+ 0xB4, 0x02, 0x02, 0xE2, 0x63, 0x44, 0x64, 0xD8, 0x58, 0x44, 0xB4, 0xE2, 0x04, 0x04, 0x58, 0x44,
+ 0xB4, 0xE2, 0x58, 0x00, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0x00, 0x00, 0xE2, 0x58, 0x44, 0x02,
+ 0xB4, 0xE2, 0x58, 0x00, 0x44, 0xB4, 0xE2, 0x58, 0x10, 0x44, 0xB4, 0xE2, 0x58, 0x20, 0x44, 0xB4,
+ 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x00, 0x00, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x80,
+ 0x80, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x2C, 0x01, 0x01, 0xBC, 0x63, 0x44, 0x0C, 0xE2, 0x58,
+ 0x44, 0x20, 0x20, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x08, 0x08, 0x44, 0xB4, 0xE2, 0x58,
+ 0x44, 0xB4, 0x20, 0xE2, 0x58, 0x44, 0x01, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0x01, 0xE2, 0x58, 0x44,
+ 0xB4, 0x00, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x00, 0x00, 0x58, 0x44, 0xB4, 0xE2, 0x01, 0x58, 0x44,
+ 0xB4, 0xE2, 0x80, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0x08, 0x08, 0xE2, 0x58, 0x44, 0xE8,
+ 0x0A, 0x92, 0xB4, 0x04, 0x04, 0x5C, 0xE2, 0x58, 0x44, 0xB4, 0x02, 0x62, 0x44, 0xB4, 0xC2, 0x01,
+ 0x01, 0x58, 0x44, 0xB4, 0xBE, 0x08, 0x41, 0x44, 0xB4, 0xEA, 0x80, 0x80, 0x58, 0x44, 0x14, 0x68,
+ 0xDE, 0x20, 0x1C, 0x7C, 0x20, 0x20, 0x58, 0x44, 0xB4, 0xE2, 0x40, 0x58, 0x44, 0xF5, 0xE2, 0x01,
+ 0x58, 0x84, 0xE8, 0x06, 0xBE, 0xA0, 0x72, 0xE2, 0x02, 0x02, 0x58, 0x44, 0xB4, 0x82, 0x58, 0x44,
+ 0xB4, 0xE2, 0x63, 0x20, 0x20, 0x44, 0xB4, 0x82, 0x58, 0x44, 0xB4, 0x86, 0x02, 0x02, 0x41, 0x44,
+ 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x01, 0x01, 0x58, 0x40, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xF5,
+ 0xE2, 0x58, 0x08, 0x08, 0x84, 0xB4, 0xE2, 0x58, 0x08, 0x44, 0xB4, 0xE2, 0x04, 0x58, 0x44, 0xB4,
+ 0xE2, 0x58, 0x10, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x20, 0x20, 0x44, 0x80, 0xB4,
+ 0xE2, 0x58, 0x44, 0xB4, 0x40, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0x80, 0x80, 0xE2,
+ 0x58, 0x44, 0xB4, 0x20, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x20, 0x20, 0xB4, 0xE2, 0x58,
+ 0x08, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x20, 0xB4, 0xE2, 0x20, 0x58, 0x44, 0xB4, 0x04, 0xE2, 0x58,
+ 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x80, 0xB4, 0xE2, 0x10, 0x58, 0x44, 0xB4, 0x00, 0xE2, 0x58, 0x44,
+ 0xB4, 0xE2, 0x58, 0x08, 0x44, 0xB4, 0x40, 0xE2, 0x58, 0x44, 0xB4, 0x08, 0xE2, 0x58, 0x80, 0x44,
+ 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x80, 0x80, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2,
+ 0x04, 0x04, 0x58, 0x44, 0xB4, 0xE2, 0x08, 0x58, 0x44, 0xB4, 0x04, 0xE2, 0x58, 0x44, 0xB4, 0xE2,
+ 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x02, 0x02, 0x02, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0x04, 0xE2,
+ 0x58, 0x44, 0xB4, 0xE2, 0x10, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x10, 0x10, 0xB4, 0xE2, 0x58,
+ 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x00, 0x00, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x80, 0x80,
+ 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x40, 0x40, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4,
+ 0x80, 0x80, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x20, 0x44, 0xB4, 0xE2, 0x01, 0x58, 0x44, 0x40,
+ 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x08, 0x08, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x40, 0xB4,
+ 0xE2, 0x58, 0x44, 0x01, 0xB4, 0xE2, 0x58, 0x44, 0x80, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58,
+ 0x04, 0x04, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x04, 0x04, 0x58, 0x44, 0xB4, 0x02, 0xE2,
+ 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x04, 0x04, 0xB4, 0xE2, 0x58, 0x44, 0x20, 0xB4, 0xE2, 0x58,
+ 0x44, 0x20, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x20, 0x20, 0xB4, 0xE2, 0x58, 0x44,
+ 0x20, 0xB4, 0xE2, 0x58, 0x44, 0x40, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x08, 0x08,
+ 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0x02, 0x02, 0x02, 0xE2, 0x58, 0x44, 0xB4,
+ 0xE2, 0x58, 0x44, 0x01, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x01, 0x01, 0x01, 0xB4,
+ 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0x10, 0x10, 0xE2, 0x58, 0x44, 0xB4, 0x01, 0xE2,
+ 0x58, 0x44, 0x10, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0x08, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44,
+ 0xB4, 0x01, 0x01, 0xE2, 0x04, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x01, 0x44, 0xB4, 0xE2, 0x58, 0x44,
+ 0xB4, 0xE2, 0x58, 0x08, 0x08, 0x44, 0x02, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4,
+ 0xE2, 0x20, 0x20, 0x58, 0x44, 0xB4, 0x08, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x40, 0x58, 0x44, 0x20,
+ 0xB4, 0xE2, 0x58, 0x20, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x08, 0x08, 0x58, 0x44, 0xB4,
+ 0xE2, 0x58, 0x01, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0x00, 0x00, 0xE2, 0x58, 0x44, 0xB4, 0xE2,
+ 0x58, 0x40, 0x44, 0xB4, 0x20, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0x10, 0x10, 0xE2,
+ 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x10, 0x10, 0xB4, 0xE2, 0x58, 0x44, 0x01, 0xB4, 0xE2, 0x58,
+ 0x10, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x02, 0x02, 0x02, 0x58,
+ 0x44, 0xB4, 0xE2, 0x58, 0x02, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x00, 0xB4, 0xE2, 0x58, 0x44, 0xB4,
+ 0xE2, 0x08, 0x08, 0x58, 0x44, 0x80, 0xB4, 0xE2, 0x58, 0x44, 0xB4, 0xE2, 0x40, 0x58, 0x44, 0xB4,
+ 0xE2, 0x58, 0x44, 0xB4, 0x20, 0x20, 0xE2, 0x58, 0x04, 0x44, 0xB4, 0xE2, 0x58, 0x44, 0x20, 0xB4,
+ 0xE2, 0x58, 0x44, 0xC4, 0xEB, 0x05, 0x10, 0x10, 0xFF, 0xB5, 0x42, 0x90, 0xBA, 0xDE, 0x20, 0xE2,
+ 0x58, 0x44, 0x40, 0xB4, 0x2A, 0x40, 0x4A, 0x0F, 0xB4, 0x80, 0xE2, 0x58, 0x44, 0xD2, 0x40, 0x62,
+ 0x4B, 0x55, 0x14, 0x68, 0x02, 0xDE, 0x9A, 0x00, 0x6E, 0x02, 0x9A, 0x82, 0x5C, 0x86, 0x00, 0x58,
+ 0x62, 0x0B, 0xBA, 0x7F, 0xA9, 0x00, 0x00, 0x00, 0xFF, 0xCC, 0x38, 0x71, 0xD8, 0x90, 0x4C, 0x01,
+ 0x01, 0x27, 0xB2, 0x6B, 0x10, 0x30, 0x43, 0xC4, 0x9B, 0xB1, 0x1E, 0x45, 0x02, 0x02, 0x34, 0xDF,
+ 0x72, 0x36, 0x00, 0xF5, 0xDC, 0xCE, 0x7A, 0x01, 0x93, 0xEF, 0x4F, 0xB0, 0xDA, 0x22, 0xA4, 0xBB,
+ 0x01, 0x01, 0xC5, 0x47, 0x27, 0x50, 0x80, 0x23, 0x7B, 0xC1, 0x5F, 0x00, 0x13, 0x47, 0xC1, 0x52,
+ 0x46, 0xD9, 0xAB, 0xB6, 0x20, 0x20, 0x8F, 0x04, 0xEF, 0xD5, 0x9E, 0x2B, 0x73, 0x5F, 0x91, 0xF4,
+ 0x40, 0x40, 0x9C, 0xB2, 0x9B, 0x76, 0xDE, 0xDF, 0x90, 0x01, 0x01, 0xFC, 0x27, 0x9C, 0x66, 0x17,
+ 0x6B, 0xB1, 0x5E, 0x00, 0x00, 0xEC, 0x8E, 0x0A, 0xEF, 0x1B, 0xFA, 0xE3, 0xF8, 0xDF, 0x08, 0x08,
+ 0x8E, 0x38, 0x77, 0x24, 0x40, 0xCA, 0x10, 0x2B, 0x10, 0x9D, 0xF7, 0x8E, 0x67, 0xD1, 0x20, 0xEF,
+ 0xF2, 0x94, 0x8F, 0xFC, 0x70, 0xF8, 0x3F, 0x01, 0x01, 0x01, 0xF7, 0xBF, 0x6B, 0xD1, 0x50, 0xA5,
+ 0x10, 0x66, 0x6A, 0x6F, 0xB0, 0x69, 0x68, 0x21, 0xAA, 0x01, 0x01, 0x17, 0x00, 0x48, 0x85, 0x6A,
+ 0xBB, 0xAA, 0x51, 0x0F, 0x01, 0xCE, 0xBB, 0x08, 0x08, 0x1C, 0x2D, 0x84, 0x04, 0x4A, 0xBD, 0x01,
+ 0x7E, 0x88, 0x04, 0x04, 0xE4, 0x29, 0x3E, 0x6C, 0xD0, 0x10, 0x49, 0xA7, 0x93, 0x09, 0xA7, 0x52,
+ 0x48, 0x01, 0x01, 0x4A, 0x24, 0xA5, 0x5E, 0xBE, 0x04, 0x0C, 0x77, 0x01, 0x23, 0xE0, 0x5D, 0xFB,
+ 0x02, 0xD0, 0x1F, 0xD2, 0x3A, 0xFC, 0x5F, 0x08, 0x9A, 0xF2, 0x20, 0x77, 0x54, 0x95, 0x22, 0xD2,
+ 0x32, 0x17, 0x9D, 0x02, 0x02, 0x6B, 0xC0, 0xD6, 0x5B, 0xF4, 0xE5, 0x50, 0x00, 0x00, 0x9A, 0xF7,
+ 0xC6, 0xD6, 0x02, 0x5F, 0x8D, 0x71, 0x80, 0xD8, 0xD2, 0x87, 0x40, 0x7C, 0xF3, 0xB2, 0xBC, 0x84,
+ 0x4B, 0x83, 0xCE, 0x80, 0x80, 0xE3, 0x71, 0x89, 0xAF, 0xE2, 0x01, 0xF8, 0x1B, 0x86, 0x66, 0x4F,
+ 0x40, 0x0F, 0x73, 0x4C, 0x4E, 0xF3, 0x0B, 0x01, 0x01, 0x18, 0x7F, 0x04, 0xBD, 0x7D, 0x51, 0x3C,
+ 0xEB, 0x5B, 0x04, 0xC6, 0xFE, 0x7B, 0x9B, 0x2F, 0x86, 0x62, 0x02, 0x02, 0x56, 0x35, 0x20, 0x05,
+ 0xE6, 0x1C, 0x4C, 0x68, 0x01, 0x29, 0xEA, 0xB0, 0xD3, 0xB0, 0xB5, 0xFE, 0x40, 0x40, 0x9D, 0xE0,
+ 0xC4, 0x6B, 0xF8, 0x6C, 0x00, 0x00, 0xE4, 0x74, 0x6A, 0x95, 0x04, 0x7A, 0xDC, 0x8C, 0x1B, 0x02,
+ 0xBB, 0x8C, 0x29, 0x1F, 0x01, 0xC6, 0xA7, 0x9C, 0x9C, 0xC7, 0x02, 0xB8, 0xD1, 0x10, 0x73, 0xA5,
+ 0x95, 0x92, 0xCC, 0xE8, 0x10, 0x67, 0x14, 0x39, 0xB3, 0x22, 0xB2, 0xAB, 0x00, 0x00, 0xF1, 0x5E,
+ 0x56, 0x90, 0x5F, 0x9D, 0xC5, 0x00, 0x00, 0xA4, 0xA3, 0x36, 0x20, 0xAF, 0x4E, 0x5A, 0xB3, 0x96,
+ 0x41, 0xDE, 0x04, 0x04, 0x77, 0x92, 0x16, 0x8D, 0x02, 0x2D, 0xB9, 0xCA, 0xC2, 0x40, 0xEF, 0x88,
+ 0x5D, 0x5F, 0x81, 0x93, 0xF7, 0x5A, 0x08, 0x08, 0xE3, 0xA3, 0x37, 0xE4, 0x10, 0xE1, 0xEA, 0x8B,
+ 0xDE, 0x02, 0xAC, 0x2D, 0xFE, 0x9C, 0x09, 0x05, 0xBF, 0xA4, 0x40, 0x40, 0xF0, 0x02, 0x92, 0xBB,
+ 0x5D, 0x42, 0x9D, 0x83, 0xF5, 0x2C, 0x40, 0x40, 0x3A, 0xE4, 0x52, 0x62, 0x36, 0x53, 0x8E, 0x40,
+ 0x40, 0x71, 0x91, 0xB7, 0x3E, 0xC0, 0x55, 0x88, 0x1C, 0x40, 0x40, 0xEF, 0x3F, 0xB4, 0x70, 0xF8,
+ 0xE9, 0x2A, 0x7A, 0x4D, 0x02, 0x02, 0xC0, 0x9B, 0x1C, 0x05, 0x08, 0xE2, 0x6C, 0x5E, 0x80, 0xDC,
+ 0x2A, 0xC0, 0x91, 0x05, 0x10, 0x10, 0x1B, 0x85, 0x09, 0x47, 0xBC, 0x27, 0x38, 0x02, 0x04, 0x04,
+ 0xCC, 0x7F, 0x55, 0x1A, 0xF0, 0x06, 0x02, 0xDF, 0xC6, 0xF8, 0xB5, 0x18, 0xB5, 0xF1, 0x97, 0x08,
+ 0x08, 0x08, 0x20, 0xF5, 0x1F, 0xCD, 0x02, 0x20, 0x07, 0xC5, 0x98, 0x44, 0x57, 0x21, 0x00, 0x24,
+ 0xBC, 0x78, 0x10, 0xD6, 0xA9, 0xCC, 0xD1, 0xC4, 0x20, 0x20, 0x30, 0x61, 0x51, 0xEC, 0x5F, 0x80,
+ 0x06, 0xAE, 0x5F, 0x6E, 0x32, 0x2E, 0x8B, 0x01, 0x01, 0x8F, 0xC5, 0x9D, 0x4F, 0x5E, 0x00, 0x07,
+ 0x6A, 0x02, 0xF9, 0xF6, 0x9B, 0xA1, 0x20, 0xF6, 0x8B, 0x19, 0xCA, 0x6D, 0x7E, 0x01, 0xBE, 0x7D,
+ 0x40, 0x18, 0x2D, 0xC2, 0xD5, 0xF8, 0x14, 0x83, 0x49, 0x80, 0x80, 0x1A, 0x7E, 0xDC, 0x6F, 0x0F,
+ 0xB1, 0xA4, 0x04, 0x04, 0x13, 0x0A, 0x2E, 0xF0, 0x08, 0x38, 0x74, 0xAB, 0x40, 0x13, 0xBE, 0xC5,
+ 0x20, 0xFD, 0xFB, 0xC5, 0xDD, 0x37, 0xF3, 0x47, 0xB6, 0x10, 0x10, 0xE0, 0x01, 0x7C, 0xB3, 0xE8,
+ 0x80, 0x95, 0x91, 0xF7, 0x00, 0x63, 0x01, 0x01, 0xFE, 0xBA, 0x86, 0xBE, 0xF0, 0xA8, 0x20, 0xBE,
+ 0xA3, 0x20, 0x90, 0x5A, 0x84, 0xB4, 0x9F, 0x63, 0x20, 0xC2, 0x8E, 0x3A, 0x38, 0xFD, 0xB7, 0x1D,
+ 0x20, 0x20, 0x26, 0x02, 0xDA, 0xDA, 0xA5, 0xFC, 0xA3, 0x65, 0x08, 0x88, 0xF6, 0xCD, 0xAF, 0x81,
+ 0x98, 0x90, 0x10, 0x10, 0xED, 0x7D, 0x2B, 0x74, 0xF5, 0x0B, 0x08, 0x08, 0xE8, 0xB3, 0x92, 0x04,
+ 0x7D, 0xE5, 0x7E, 0x36, 0x48, 0x02, 0xC2, 0x0D, 0x93, 0x4C, 0x20, 0x02, 0xC8, 0x73, 0x81, 0xC5
+};
+
+static int CompareHuffmanCompressions0()
+{
+ unsigned char * pbDecompressed = Decompressed;
+ unsigned char * pbCompressed;
+ unsigned char * pbUncompressed;
+ int cbOutLength;
+ int cbInLength;
+ int nLength = sizeof(Decompressed);
+ int nError = ERROR_NOT_ENOUGH_MEMORY;
+
+ // Allocate buffers for compressed buffer
+ pbCompressed = new unsigned char[nLength];
+ if(pbCompressed != NULL)
+ {
+ // Perform the compression
+ cbInLength =
+ cbOutLength = nLength;
+ SCompCompress(pbCompressed, &cbOutLength, pbDecompressed, nLength, MPQ_COMPRESSION_HUFFMANN, 0x00, 0);
+ assert(cbOutLength < cbInLength);
+
+ // Allocate space for decompressed buffer
+ pbUncompressed = new unsigned char[nLength];
+ if(pbUncompressed != NULL)
+ {
+ // Perform the decompression
+ cbInLength = cbOutLength;
+ cbOutLength = nLength;
+ SCompDecompress(pbUncompressed, &cbOutLength, pbCompressed, cbInLength);
+
+ // Compare length
+ if(cbOutLength == nLength)
+ {
+ if(!memcmp(pbUncompressed, pbDecompressed, nLength))
+ {
+ _tprintf(_T("Huffmann compression OK\n"));
+ nError = ERROR_SUCCESS;
+ }
+ else
+ {
+ _tprintf(_T("Error: Decompressed data are not the same like the compressed ones\n"));
+ nError = ERROR_INVALID_DATA;
+ }
+ }
+ else
+ {
+ _tprintf(_T("Error: Length of the uncompressed data is different from original length\n"));
+ nError = ERROR_BAD_LENGTH;
+ }
+
+ delete [] pbUncompressed;
+ }
+
+ delete [] pbCompressed;
+ }
+
+ assert(nError == ERROR_SUCCESS);
+ return ERROR_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Compare PKLIB decompression
+
+BYTE pbCompressed1[] = {0x00, 0x04, 0x00, 0x00, 0x04, 0xF0, 0x1F, 0x7B, 0x01, 0xFF};
+BYTE pbCompressed2[] = {0x00, 0x04, 0x00, 0x00, 0x04, 0xF0, 0x1F, 0x00, 0x00, 0x04, 0xFC, 0x03};
+
+static int ComparePklibCompressions()
+{
+ char Decompressed[0x1000];
+ char Compressed[0x1000];
+ int cbDecompressed = 0x208;
+ int cbCompressed = sizeof(Compressed);
+
+ memset(Decompressed, 0, cbDecompressed);
+ SCompImplode(Compressed, &cbCompressed, Decompressed, cbDecompressed);
+
+ cbDecompressed = sizeof(Decompressed);
+ SCompExplode(Decompressed, &cbDecompressed, Compressed, cbCompressed);
+
+
+ return ERROR_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Compare LZMA decompression
+
+#ifdef PLATFORM_WINDOWS
+typedef void * (*ALLOC_MEMORY)(size_t);
+typedef void (*FREE_MEMORY)(void *);
+typedef int (GIVE_DATA)(void *);
+
+extern "C" int starcraft_decompress_lzma(char * pbInBuffer, int cbInBuffer, char * pbOutBuffer, int cbOutBuffer, int * pcbOutBuffer, ALLOC_MEMORY pfnAllocMemory, FREE_MEMORY pfnFreeMemory);
+extern "C" int starcraft_compress_lzma(char * pbInBuffer, int cbInBuffer, int dummy1, char * pbOutBuffer, int cbOutBuffer, int dummy2, int * pcbOutBuffer, ALLOC_MEMORY pfnAllocMemory, FREE_MEMORY pfnFreeMemory, GIVE_DATA pfnGiveData);
+void Compress_LZMA(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer, int *, int);
+int Decompress_LZMA(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer);
+
+extern "C" void * operator_new(size_t sz)
+{
+ return malloc(sz);
+}
+
+void * Memory_Allocate(size_t byte_size)
+{
+ return malloc(byte_size);
+}
+
+void Memory_Free(void * address)
+{
+ if(address != NULL)
+ free(address);
+}
+
+int GiveData(void *)
+{
+ return 0;
+}
+
+static int StarcraftCompress_LZMA(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer)
+{
+ return starcraft_compress_lzma(pbInBuffer,
+ cbInBuffer,
+ 0,
+ pbOutBuffer,
+ *pcbOutBuffer,
+ 0,
+ pcbOutBuffer,
+ Memory_Allocate,
+ Memory_Free,
+ GiveData);
+}
+
+static int StarcraftDecompress_LZMA(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer)
+{
+ return starcraft_decompress_lzma(pbInBuffer,
+ cbInBuffer,
+ pbOutBuffer,
+ *pcbOutBuffer,
+ pcbOutBuffer,
+ Memory_Allocate,
+ Memory_Free);
+}
+
+static int CompareLzmaCompressions(int nSectorSize)
+{
+ LPBYTE pbCompressed1 = NULL; // Compressed by our code
+ LPBYTE pbCompressed2 = NULL; // Compressed by Blizzard's code
+ LPBYTE pbDecompressed1 = NULL; // Decompressed by our code
+ LPBYTE pbDecompressed2 = NULL; // Decompressed by Blizzard's code
+ LPBYTE pbOriginalData = NULL;
+ int nError = ERROR_SUCCESS;
+
+ // Allocate buffers
+ // Must allocate twice blocks due to probable bug in Storm.dll.
+ // Storm.dll corrupts stack when uncompresses data with PKWARE DCL
+ // and no compression occurs.
+ pbDecompressed1 = new BYTE [nSectorSize];
+ pbDecompressed2 = new BYTE [nSectorSize];
+ pbCompressed1 = new BYTE [nSectorSize];
+ pbCompressed2 = new BYTE [nSectorSize];
+ pbOriginalData = new BYTE[nSectorSize];
+ if(!pbDecompressed1 || !pbDecompressed2 || !pbCompressed1 || !pbCompressed2 || !pbOriginalData)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+
+ if(nError == ERROR_SUCCESS)
+ {
+ for(int i = 0; i < 100000; i++)
+ {
+ int nDcmpLength1;
+ int nDcmpLength2;
+ int nCmpLength1;
+ int nCmpLength2;
+ int nDiff;
+
+ clreol();
+ _tprintf(_T("Testing compression of sector %u\r"), i + 1);
+
+ // Generate random data sector
+ GenerateRandomDataBlock(pbOriginalData, nSectorSize);
+
+ // Compress the sector by both methods
+ nCmpLength1 = nCmpLength2 = nSectorSize;
+// Compress_LZMA((char *)pbCompressed1, &nCmpLength1, (char *)pbOriginalData, nSectorSize, 0, 0);
+ StarcraftCompress_LZMA((char *)pbCompressed1, &nCmpLength2, (char *)pbOriginalData, nSectorSize);
+
+__TryToDecompress:
+
+ // Only test decompression when the compression actually succeeded
+ if(nCmpLength1 < nSectorSize)
+ {
+ // Decompress both data
+ nDcmpLength2 = nDcmpLength1 = nSectorSize;
+// Decompress_LZMA((char *)pbDecompressed1, &nDcmpLength1, (char *)pbCompressed1, nCmpLength1);
+ StarcraftDecompress_LZMA((char *)pbDecompressed2, &nDcmpLength2, (char *)pbCompressed1, nCmpLength1);
+
+ // Compare the length of the output data
+ if(nDcmpLength1 != nDcmpLength2)
+ {
+ _tprintf(_T("Difference in compressed blocks lengths (%u vs %u)\n"), nDcmpLength1, nDcmpLength2);
+ goto __TryToDecompress;
+ }
+
+ // Compare the output
+ if((nDiff = GetFirstDiffer(pbDecompressed1, pbDecompressed2, nDcmpLength1)) != -1)
+ {
+ _tprintf(_T("Difference in decompressed blocks (offset 0x%08X)\n"), nDiff);
+ goto __TryToDecompress;
+ }
+
+ // Check for data overflow
+ if(pbDecompressed1[nSectorSize] != 0xFD || pbDecompressed1[nSectorSize] != 0xFD)
+ {
+ _tprintf(_T("Damage after decompressed sector !!!\n"));
+ goto __TryToDecompress;
+ }
+
+ // Compare the decompressed data against original data
+ if((nDiff = GetFirstDiffer(pbDecompressed1, pbOriginalData, nDcmpLength1)) != -1)
+ {
+ _tprintf(_T("Difference between original data and decompressed data (offset 0x%08X)\n"), nDiff);
+ goto __TryToDecompress;
+ }
+ }
+ }
+ }
+
+ // Cleanup
+ if(pbOriginalData != NULL)
+ delete [] pbOriginalData;
+ if(pbCompressed2 != NULL)
+ delete [] pbCompressed2;
+ if(pbCompressed1 != NULL)
+ delete [] pbCompressed1;
+ if(pbDecompressed2 != NULL)
+ delete [] pbDecompressed2;
+ if(pbDecompressed1 != NULL)
+ delete [] pbDecompressed1;
+ clreol();
+ return nError;
+}
+#endif // PLATFORM_WINDOWS
+
+//-----------------------------------------------------------------------------
+// Compression method test
+
+static int TestSectorCompress(int nSectorSize)
+{
+ LPBYTE pbDecompressed = NULL;
+ LPBYTE pbCompressed = NULL;
+ LPBYTE pbOriginal = NULL;
+ int nError = ERROR_SUCCESS;
+
+ // Allocate buffers
+ pbDecompressed = new BYTE[nSectorSize];
+ pbCompressed = new BYTE[nSectorSize];
+ pbOriginal = new BYTE[nSectorSize];
+ if(!pbDecompressed || !pbCompressed || !pbOriginal)
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+
+ if(nError == ERROR_SUCCESS)
+ {
+ for(int i = 0; i < 100000; i++)
+ {
+ int nOriginalLength = nSectorSize % (rand() + 1);
+ int nCompressedLength;
+ int nDecompressedLength;
+ int nCmp = MPQ_COMPRESSION_SPARSE | MPQ_COMPRESSION_ZLIB | MPQ_COMPRESSION_BZIP2 | MPQ_COMPRESSION_PKWARE;
+ int nDiff;
+
+ clreol();
+ _tprintf(_T("Testing compression of sector %u\r"), i + 1);
+
+ // Generate random data sector
+ GenerateRandomDataBlock(pbOriginal, nOriginalLength);
+ if(nOriginalLength == 0x123)
+ nOriginalLength = 0;
+
+__TryAgain:
+
+ // Compress the sector
+ nCompressedLength = nOriginalLength;
+ SCompCompress((char *)pbCompressed, &nCompressedLength, (char *)pbOriginal, nOriginalLength, nCmp, 0, -1);
+// SCompImplode((char *)pbCompressed, &nCompressedLength, (char *)pbOriginal, nOriginalLength);
+
+ // When the method was unable to compress data,
+ // the compressed data must be identical to original data
+ if(nCompressedLength == nOriginalLength)
+ {
+ if((nDiff = GetFirstDiffer(pbCompressed, pbOriginal, nOriginalLength)) != -1)
+ {
+ _tprintf(_T("Compression error: Fail when unable to compress the data (Offset 0x%08X).\n"), nDiff);
+ goto __TryAgain;
+ }
+ }
+
+ // Uncompress the sector
+ nDecompressedLength = nOriginalLength;
+ SCompDecompress((char *)pbDecompressed, &nDecompressedLength, (char *)pbCompressed, nCompressedLength);
+// SCompExplode((char *)pbDecompressed, &nDecompressedLength, (char *)pbCompressed, nCompressedLength);
+
+ // Check the decompressed length against original length
+ if(nDecompressedLength != nOriginalLength)
+ {
+ _tprintf(_T("Length of uncompressed data does not agree with original data length !!!\n"));
+ goto __TryAgain;
+ }
+
+ // Check decompressed block against original block
+ if((nDiff = GetFirstDiffer(pbDecompressed, pbOriginal, nOriginalLength)) != -1)
+ {
+ _tprintf(_T("Decompressed sector does not agree with the original data !!! (Offset 0x%08X)\n"), nDiff);
+ goto __TryAgain;
+ }
+ }
+ }
+
+ // Cleanup
+ delete [] pbOriginal;
+ delete [] pbCompressed;
+ delete [] pbDecompressed;
+ clreol();
+ return nError;
+}
+
+static int TestArchiveOpenAndClose(const TCHAR * szMpqName)
+{
+ const char * szFileName1 = "Sound\\terran\\duran\\TDnPss01.wav";
+// const char * szFileName2 = "items\\map\\mapz_deleted.cel";
+ TMPQArchive * ha = NULL;
+ HANDLE hFile1 = NULL;
+// HANDLE hFile2 = NULL;
+ HANDLE hMpq = NULL;
+ int nError = ERROR_SUCCESS;
+
+ if(nError == ERROR_SUCCESS)
+ {
+ _tprintf(_T("Opening archive %s ...\n"), szMpqName);
+ if(!SFileOpenArchive(szMpqName, 0, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE, &hMpq))
+ nError = GetLastError();
+ ha = (TMPQArchive *)hMpq;
+ }
+
+ if(nError == ERROR_SUCCESS)
+ {
+ SFileAddListFile(hMpq, "c:\\Tools32\\Listfiles\\ListFile.txt");
+ }
+
+ // Verify the raw data in the archive
+ if(nError == ERROR_SUCCESS)
+ {
+ // Verify the archive
+ SFileVerifyRawData(hMpq, SFILE_VERIFY_FILE, szFileName1);
+
+ // Try to open a file
+ if(!SFileOpenFileEx(hMpq, szFileName1, SFILE_OPEN_FROM_MPQ, &hFile1))
+ {
+ nError = GetLastError();
+ printf("%s - file not found in the MPQ\n", szFileName1);
+ }
+ }
+
+ // Dummy read from the file
+ if(nError == ERROR_SUCCESS)
+ {
+ DWORD dwBytesRead = 0;
+ BYTE Buffer[0x1000];
+
+ SFileSetFilePointer(hFile1, 0x1000, NULL, FILE_BEGIN);
+ SFileReadFile(hFile1, Buffer, sizeof(Buffer), &dwBytesRead, NULL);
+ }
+
+ // Verify the MPQ listfile
+#ifdef _MSC_VER
+ if(nError == ERROR_SUCCESS)
+ {
+ SFileExtractFile(hMpq, szFileName1, _T("E:\\extracted.wav"), 0);
+ PlaySound(_T("E:\\extracted.wav"), NULL, SND_FILENAME);
+ }
+#endif
+
+ if(hFile1 != NULL)
+ SFileCloseFile(hFile1);
+ if(hMpq != NULL)
+ SFileCloseArchive(hMpq);
+ return nError;
+}
+
+static int TestFindFiles(const TCHAR * szMpqName)
+{
+ TMPQFile * hf;
+ HANDLE hFile;
+ HANDLE hMpq = NULL;
+ BYTE Buffer[100];
+ int nError = ERROR_SUCCESS;
+ int nFiles = 0;
+ int nFound = 0;
+
+ // Open the archive
+ if(nError == ERROR_SUCCESS)
+ {
+ _tprintf(_T("Opening \"%s\" for finding files ...\n"), szMpqName);
+ if(!SFileOpenArchive(szMpqName, 0, 0, &hMpq))
+ nError = GetLastError();
+ }
+
+ // Compact the archive
+ if(nError == ERROR_SUCCESS)
+ {
+ SFILE_FIND_DATA sf;
+ HANDLE hFind;
+ DWORD dwExtraDataSize;
+ bool bFound = true;
+
+ hFind = SFileFindFirstFile(hMpq, "*", &sf, "c:\\Tools32\\ListFiles\\ListFile.txt");
+ while(hFind != NULL && bFound != false)
+ {
+ if(SFileOpenFileEx(hMpq, sf.cFileName, 0, &hFile))
+ {
+ hf = (TMPQFile *)hFile;
+ SFileReadFile(hFile, Buffer, sizeof(Buffer), NULL, NULL);
+ nFiles++;
+
+ if(sf.dwFileFlags & MPQ_FILE_SECTOR_CRC)
+ {
+ dwExtraDataSize = hf->SectorOffsets[hf->dwSectorCount + 1] - hf->SectorOffsets[hf->dwSectorCount];
+ if(dwExtraDataSize != 0)
+ nFound++;
+ }
+
+ SFileCloseFile(hFile);
+ }
+
+ bFound = SFileFindNextFile(hFind, &sf);
+ }
+ }
+
+ if(hMpq != NULL)
+ SFileCloseArchive(hMpq);
+ if(nError == ERROR_SUCCESS)
+ _tprintf(_T("Search complete\n"));
+ return nError;
+}
+
+static int TestMpqCompacting(const TCHAR * szMpqName)
+{
+ HANDLE hMpq = NULL;
+ int nError = ERROR_SUCCESS;
+
+ // Open the archive
+ if(nError == ERROR_SUCCESS)
+ {
+ _tprintf(_T("Opening \"%s\" for compacting ...\n"), szMpqName);
+ if(!SFileOpenArchive(szMpqName, 0, 0, &hMpq))
+ nError = GetLastError();
+ }
+
+ if(nError == ERROR_SUCCESS)
+ {
+ const char * szFileName = "Shaders\\Effects\\shadowmap.wfx";
+
+ printf("Deleting file %s ...\r", szFileName);
+ if(!SFileRemoveFile(hMpq, szFileName, SFILE_OPEN_FROM_MPQ))
+ nError = GetLastError();
+ }
+/*
+ // Compact the archive
+ if(nError == ERROR_SUCCESS)
+ {
+ _tprintf(_T("Compacting archive ...\r"));
+ SFileSetCompactCallback(hMpq, CompactCB, NULL);
+ if(!SFileCompactArchive(hMpq, "c:\\Tools32\\ListFiles\\ListFile.txt"))
+ nError = GetLastError();
+ }
+*/
+ if(hMpq != NULL)
+ SFileCloseArchive(hMpq);
+ if(nError == ERROR_SUCCESS)
+ _tprintf(_T("Compacting complete (No errors)\n"));
+ return nError;
+}
+
+static int TestCreateArchive(const TCHAR * szMpqName)
+{
+ TFileStream * pStream;
+ const TCHAR * szFileName1 = MAKE_PATH("FileTest.exe");
+ const TCHAR * szFileName2 = MAKE_PATH("ZeroSize.txt");
+ HANDLE hMpq = NULL; // Handle of created archive
+ DWORD dwVerifyResult;
+ DWORD dwFileCount = 0;
+ LCID LocaleIDs[] = {0x000, 0x405, 0x406, 0x407, 0xFFFF};
+ char szMpqFileName[MAX_PATH];
+ int nError = ERROR_SUCCESS;
+ int i;
+
+ // Create the new file
+ _tprintf(_T("Creating %s ...\n"), szMpqName);
+ pStream = FileStream_CreateFile(szMpqName, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
+ if(pStream == NULL)
+ nError = GetLastError();
+
+ // Write some data
+ if(nError == ERROR_SUCCESS)
+ {
+ ULONGLONG FileSize = 0x100000;
+
+ FileStream_SetSize(pStream, FileSize);
+ FileStream_Close(pStream);
+ }
+
+ // Well, now create the MPQ archive
+ if(nError == ERROR_SUCCESS)
+ {
+ if(!SFileCreateArchive(szMpqName,
+ MPQ_CREATE_ARCHIVE_V4 | MPQ_CREATE_ATTRIBUTES,
+ 17,
+ &hMpq))
+ {
+ nError = GetLastError();
+ }
+ }
+
+ // Add the same file multiple times
+ if(nError == ERROR_SUCCESS)
+ {
+ // Add FileTest.exe
+ for(i = 0; AddFlags[i] != 0xFFFFFFFF; i++)
+ {
+ sprintf(szMpqFileName, "FileTest_%02u.exe", i);
+ PrintfTA(_T("Adding %s as %s ...\n"), szFileName1, szMpqFileName);
+ if(SFileAddFileEx(hMpq, szFileName1, szMpqFileName, AddFlags[i], MPQ_COMPRESSION_ZLIB, MPQ_COMPRESSION_NEXT_SAME))
+ {
+ dwVerifyResult = SFileVerifyFile(hMpq, szMpqFileName, 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))
+ printf("CRC error on \"%s\"\n", szMpqFileName);
+ dwFileCount++;
+ }
+ else
+ {
+ printf("Failed to add the file \"%s\".\n", szMpqFileName);
+ }
+ }
+
+
+ // Delete a file in the middle of the file table
+ SFileRemoveFile(hMpq, "FileTest_10.exe", SFILE_OPEN_FROM_MPQ);
+ SFileAddFileEx(hMpq, szFileName1, "FileTest_xx.exe", MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED, MPQ_COMPRESSION_ZLIB, MPQ_COMPRESSION_NEXT_SAME);
+
+ // Try to decrement max file count
+ dwFileCount = SFileGetMaxFileCount(hMpq);
+ SFileSetMaxFileCount(hMpq, dwFileCount - 1);
+
+ // Add ZeroSize.txt (1)
+ sprintf(szMpqFileName, "ZeroSize_1.txt");
+ for(i = 0; LocaleIDs[i] != 0xFFFF; i++)
+ {
+ PrintfTA(_T("Adding %s as %s (locale %04x) ...\n"), szFileName2, szMpqFileName, LocaleIDs[i]);
+ SFileSetLocale(LocaleIDs[i]);
+ if(!SFileAddFileEx(hMpq, szFileName2, szMpqFileName, MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED, MPQ_COMPRESSION_ZLIB, MPQ_COMPRESSION_NEXT_SAME))
+ printf("Cannot add the file\n");
+ }
+
+ // Add ZeroSize.txt (1)
+ sprintf(szMpqFileName, "ZeroSize_2.txt");
+ for(int i = 0; LocaleIDs[i] != 0xFFFF; i++)
+ {
+ PrintfTA(_T("Adding %s as %s (locale %04x) ...\n"), szFileName2, szMpqFileName, LocaleIDs[i]);
+ SFileSetLocale(LocaleIDs[i]);
+ if(!SFileAddFileEx(hMpq, szFileName2, szMpqFileName, MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED, MPQ_COMPRESSION_ZLIB, MPQ_COMPRESSION_NEXT_SAME))
+ printf("Cannot add the file\n");
+ }
+ }
+
+ // Test rename function
+ if(nError == ERROR_SUCCESS)
+ {
+ _tprintf(_T("Testing rename files ...\n"));
+ SFileSetLocale(LANG_NEUTRAL);
+ if(!SFileRenameFile(hMpq, "FileTest_08.exe", "FileTest_08a.exe"))
+ {
+ nError = GetLastError();
+ _tprintf(_T("Failed to rename the file\n"));
+ }
+
+ if(!SFileRenameFile(hMpq, "FileTest_08a.exe", "FileTest_08.exe"))
+ {
+ nError = GetLastError();
+ _tprintf(_T("Failed to rename the file\n"));
+ }
+
+ if(!SFileRenameFile(hMpq, "FileTest_10.exe", "FileTest_10a.exe"))
+ {
+ nError = GetLastError();
+ _tprintf(_T("Failed to rename the file\n"));
+ }
+
+ if(!SFileRenameFile(hMpq, "FileTest_10a.exe", "FileTest_10.exe"))
+ {
+ nError = GetLastError();
+ _tprintf(_T("Failed to rename the file\n"));
+ }
+
+ if(nError == ERROR_SUCCESS)
+ _tprintf(_T("Rename test succeeded.\n\n"));
+ else
+ _tprintf(_T("Rename test failed.\n\n"));
+ }
+
+ // Compact the archive
+// if(nError == ERROR_SUCCESS)
+// SFileCompactArchive(hMpq);
+
+ // Test changing hash table size
+ if(nError == ERROR_SUCCESS)
+ SFileSetMaxFileCount(hMpq, 0x95);
+
+ if(hMpq != NULL)
+ SFileCloseArchive(hMpq);
+
+ // Try to reopen the archive
+ if(SFileOpenArchive(szMpqName, 0, 0, &hMpq))
+ SFileCloseArchive(hMpq);
+
+ _tprintf(_T("\n"));
+ return nError;
+}
+
+static int TestCreateArchive_PaliRoharBug(const TCHAR * szMpqName)
+{
+ const TCHAR * szFileName = MAKE_PATH("FileTest.exe");
+ HANDLE hMpq = NULL; // Handle of created archive
+ DWORD dwMaxFileCount = 0;
+ DWORD dwMpqFlags = MPQ_FILE_ENCRYPTED | MPQ_FILE_COMPRESS;
+ char szMpqFileName[MAX_PATH];
+ int nError = ERROR_SUCCESS;
+ int i;
+
+ _tremove(szMpqName);
+ if(SFileCreateArchive(szMpqName,
+ MPQ_CREATE_ARCHIVE_V4 | MPQ_CREATE_ATTRIBUTES,
+ 1,
+ &hMpq))
+ {
+ // Add the file there
+ SFileAddFileEx(hMpq, szFileName, "FileTest_base.exe", dwMpqFlags, MPQ_COMPRESSION_ZLIB, MPQ_COMPRESSION_NEXT_SAME);
+ SFileFlushArchive(hMpq);
+ SFileCloseArchive(hMpq);
+
+ // Add the same file 10 times
+ for(i = 0; i < 10; i++)
+ {
+ if(SFileOpenArchive(szMpqName, 0, 0, &hMpq))
+ {
+ dwMaxFileCount = SFileGetMaxFileCount(hMpq) + 1;
+ _tprintf(_T("Increasing max file count to %u ...\n"), dwMaxFileCount);
+ SFileSetMaxFileCount(hMpq, dwMaxFileCount);
+
+ sprintf(szMpqFileName, "FileTest_%02u.exe", dwMaxFileCount);
+ PrintfTA(_T("Adding %s as %s\n"), szFileName, szMpqFileName);
+ if(!SFileAddFileEx(hMpq, szFileName, szMpqFileName, dwMpqFlags, MPQ_COMPRESSION_ZLIB, MPQ_COMPRESSION_NEXT_SAME))
+ {
+ printf("Failed to add the file \"%s\".\n", szMpqFileName);
+ break;
+ }
+
+ SFileFlushArchive(hMpq);
+ SFileCompactArchive(hMpq, NULL, false);
+ SFileCloseArchive(hMpq);
+ }
+ }
+ }
+
+ _tprintf(_T("\n"));
+ return nError;
+}
+
+
+static int TestAddFilesToMpq(
+ const TCHAR * szMpqName,
+ ...
+ )
+{
+ const TCHAR * szFileName;
+ const TCHAR * szSrc;
+ char * szTrg;
+ HANDLE hMpq;
+ va_list argList;
+ char szMpqFileName[MAX_PATH];
+ int nError = ERROR_SUCCESS;
+
+ if(!SFileOpenArchive(szMpqName, 0, 0, &hMpq))
+ return GetLastError();
+
+ va_start(argList, szMpqName);
+ while((szFileName = va_arg(argList, const TCHAR *)) != NULL)
+ {
+ // Convert the plain name to ANSI
+ szSrc = GetPlainFileNameT(szFileName);
+ szTrg = szMpqFileName;
+ while(*szSrc != 0)
+ *szTrg++ = (char)*szSrc++;
+ *szTrg = 0;
+
+ // Add the file to MPQ
+ if(!SFileAddFileEx(hMpq, szFileName,
+ szMpqFileName,
+ MPQ_FILE_COMPRESS,
+ MPQ_COMPRESSION_ZLIB,
+ MPQ_COMPRESSION_NEXT_SAME))
+ {
+ nError = GetLastError();
+ printf("Failed to add the file \"%s\"\n", szFileName);
+ }
+ }
+
+ SFileCloseArchive(hMpq);
+ return nError;
+}
+
+static int TestCreateArchiveFromMemory(const TCHAR * szMpqName)
+{
+#define FILE_SIZE 65535
+
+ HANDLE hFile;
+ HANDLE hMPQ;
+ char* data = new char [FILE_SIZE]; // random memory data
+ char szFileName[100];
+ int i;
+
+ // Create an mpq file for testing
+ if(SFileCreateArchive(szMpqName, MPQ_CREATE_ARCHIVE_V2|MPQ_CREATE_ATTRIBUTES, 0x100000, &hMPQ))
+ {
+ for(i = 0; i < 1000; i++)
+ {
+ sprintf(szFileName, "File%03u.bin", i);
+ printf("Adding file %s\r", szFileName);
+
+ if(SFileCreateFile(hMPQ, szFileName, 0, FILE_SIZE, 0, MPQ_FILE_COMPRESS, &hFile))
+ {
+ SFileWriteFile(hFile, data, FILE_SIZE, MPQ_COMPRESSION_ZLIB);
+ SFileFinishFile(hFile);
+ }
+ }
+ }
+ SFileCloseArchive(hMPQ);
+ delete [] data;
+ return ERROR_SUCCESS;
+}
+
+static int TestFileReadAndWrite(
+ const TCHAR * szMpqName,
+ const char * szFileName)
+{
+ LPBYTE pvFile = NULL;
+ HANDLE hFile = NULL;
+ HANDLE hMpq = NULL;
+ DWORD dwBytesRead;
+ DWORD dwFileSize = 0;
+ int nError = ERROR_SUCCESS;
+
+ if(!SFileOpenArchive(szMpqName, 0, 0, &hMpq))
+ {
+ nError = GetLastError();
+ _tprintf(_T("Failed to open the archive %s (%u).\n"), szMpqName, nError);
+ }
+
+ if(nError == ERROR_SUCCESS)
+ {
+ if(!SFileOpenFileEx(hMpq, szFileName, 0, &hFile))
+ {
+ nError = GetLastError();
+ printf("Failed to open the file %s (%u).\n", szFileName, nError);
+ }
+ }
+
+ if(nError == ERROR_SUCCESS)
+ {
+ if(!SFileGetFileInfo(hFile, SFILE_INFO_FILE_SIZE, &dwFileSize, sizeof(DWORD), NULL))
+ {
+ nError = GetLastError();
+ _tprintf(_T("Failed to get the file size (%u).\n"), nError);
+ }
+ }
+
+ if(nError == ERROR_SUCCESS)
+ {
+ pvFile = new BYTE[dwFileSize];
+ if(pvFile == NULL)
+ {
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ printf("Failed to allocate buffer for the file (%u).\n", nError);
+ }
+ }
+
+ if(nError == ERROR_SUCCESS)
+ {
+ if(!SFileReadFile(hFile, pvFile, dwFileSize, &dwBytesRead, NULL))
+ {
+ nError = GetLastError();
+ printf("Failed to read file (%u).\n", nError);
+ }
+ }
+
+ if(hFile != NULL)
+ {
+ SFileCloseFile(hFile);
+ hFile = NULL;
+ }
+
+ if(nError == ERROR_SUCCESS)
+ {
+ if(!SFileCreateFile(hMpq, szFileName, 0, dwFileSize, 0, MPQ_FILE_REPLACEEXISTING, &hFile))
+ {
+ nError = GetLastError();
+ printf("Failed to create %s in the archive (%u).\n", szFileName, nError);
+ }
+ }
+
+ if(nError == ERROR_SUCCESS)
+ {
+ if(!SFileWriteFile(hFile, pvFile, dwFileSize, 0))
+ {
+ nError = GetLastError();
+ printf("Failed to write the data to the MPQ (%u).\n", nError);
+ }
+ }
+
+ if(hFile != NULL)
+ {
+ if(!SFileFinishFile(hFile))
+ {
+ nError = GetLastError();
+ printf("Failed to finalize file creation (%u).\n", nError);
+ }
+ }
+
+ if(pvFile != NULL)
+ delete [] pvFile;
+ if(hMpq != NULL)
+ SFileCloseArchive(hMpq);
+ return nError;
+}
+
+static int TestSignatureVerify(const TCHAR * szMpqName)
+{
+ HANDLE hMpq;
+
+ if(SFileOpenArchive(szMpqName, 0, 0, &hMpq))
+ {
+ _tprintf(_T("Verifying digital signature in %s:\n"), szMpqName);
+ switch(SFileVerifyArchive(hMpq))
+ {
+ case ERROR_NO_SIGNATURE:
+ _tprintf(_T("No digital signature present.\n"));
+ break;
+
+ case ERROR_VERIFY_FAILED:
+ _tprintf(_T("Failed to verify signature.\n"));
+ break;
+
+ case ERROR_WEAK_SIGNATURE_OK:
+ _tprintf(_T("Weak signature is OK.\n"));
+ break;
+
+ case ERROR_WEAK_SIGNATURE_ERROR:
+ _tprintf(_T("Weak signature mismatch.\n"));
+ break;
+
+ case ERROR_STRONG_SIGNATURE_OK:
+ _tprintf(_T("Strong signature is OK.\n"));
+ break;
+
+ case ERROR_STRONG_SIGNATURE_ERROR:
+ _tprintf(_T("Strong signature mismatch.\n"));
+ break;
+ }
+
+ SFileCloseArchive(hMpq);
+ _tprintf(_T("\n"));
+ }
+
+ return 0;
+}
+
+
+static int TestCreateArchiveCopy(const TCHAR * szMpqName, const TCHAR * szMpqCopyName, const char * szListFile)
+{
+ TFileStream * pStream;
+ TCHAR szLocalFile[MAX_PATH];
+ HANDLE hMpq1 = NULL; // Handle of existing archive
+ HANDLE hMpq2 = NULL; // Handle of created archive
+ DWORD dwHashTableSize = 0;
+ int nError = ERROR_SUCCESS;
+
+ // If no listfile or an empty one, use NULL
+ if(szListFile == NULL || *szListFile == 0)
+ szListFile = NULL;
+
+ // Create the new file
+ pStream = FileStream_CreateFile(szMpqCopyName, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
+ if(pStream == NULL)
+ nError = GetLastError();
+
+ // Write some data
+ if(nError == ERROR_SUCCESS)
+ {
+ ULONGLONG FileSize = 0x100000;
+
+ FileStream_SetSize(pStream, FileSize);
+ FileStream_Close(pStream);
+ }
+
+ // Open the existing MPQ archive
+ if(nError == ERROR_SUCCESS)
+ {
+ _tprintf(_T("Opening %s ...\n"), szMpqName);
+ if(!SFileOpenArchive(szMpqName, 0, 0, &hMpq1))
+ nError = GetLastError();
+ }
+
+ // Well, now create the MPQ archive
+ if(nError == ERROR_SUCCESS)
+ {
+ _tprintf(_T("Creating %s ...\n"), szMpqCopyName);
+ SFileGetFileInfo(hMpq1, SFILE_INFO_HASH_TABLE_SIZE, &dwHashTableSize, 4, NULL);
+ if(!SFileCreateArchive(szMpqCopyName, 0, dwHashTableSize, &hMpq2))
+ nError = GetLastError();
+ }
+
+ // Copy all files from one archive to another
+ if(nError == ERROR_SUCCESS)
+ {
+ SFILE_FIND_DATA sf;
+ HANDLE hFind = SFileFindFirstFile(hMpq1, "*", &sf, szListFile);
+ bool bResult = true;
+
+ _tprintf(_T("Copying files ...\n"));
+
+ if(hFind != NULL)
+ {
+ while(bResult)
+ {
+ if(strcmp(sf.cFileName, LISTFILE_NAME) && strcmp(sf.cFileName, ATTRIBUTES_NAME))
+ {
+ SFileSetLocale(sf.lcLocale);
+
+ // Create the local file name
+ MergeLocalPath(szLocalFile, szWorkDir, sf.szPlainName);
+ if(SFileExtractFile(hMpq1, sf.cFileName, szLocalFile, SFILE_OPEN_FROM_MPQ))
+ {
+ printf("Extracting %s ... OK\n", sf.cFileName);
+ if(!SFileAddFile(hMpq2, szLocalFile, sf.cFileName, sf.dwFileFlags))
+ {
+ nError = GetLastError();
+ printf("Adding %s ... Failed\n\n", sf.cFileName);
+ _tremove(szLocalFile);
+ break;
+ }
+ else
+ {
+ printf("Adding %s ... OK\n", sf.cFileName);
+ }
+ }
+ else
+ {
+ printf("Extracting %s ... Failed\n", sf.cFileName);
+ }
+
+ // Delete the added file
+ _tremove(szLocalFile);
+ }
+
+ // Find the next file
+ bResult = SFileFindNextFile(hFind, &sf);
+ }
+
+ // Close the search handle
+ SFileFindClose(hFind);
+ printf("\n");
+ }
+ }
+
+ // Close both archives
+ if(hMpq2 != NULL)
+ SFileCloseArchive(hMpq2);
+ if(hMpq1 != NULL)
+ SFileCloseArchive(hMpq1);
+ return nError;
+}
+
+static int TestOpenPatchedArchive(const TCHAR * szMpqName, ...)
+{
+ TFileStream * pStream;
+ HANDLE hFile = NULL;
+ HANDLE hMpq = NULL;
+ va_list argList;
+ const char * szFileName = "Interface/Cinematics/MOP_BR.mp3";
+ TCHAR szLocFileName[MAX_PATH];
+ LPBYTE pbFullFile = NULL;
+ DWORD dwFileSize;
+ int nError = ERROR_SUCCESS;
+
+ // Open the primary MPQ
+ _tprintf(_T("Opening %s ...\n"), szMpqName);
+ if(!SFileOpenArchive(szMpqName, 0, MPQ_OPEN_READ_ONLY, &hMpq))
+ {
+ nError = GetLastError();
+ _tprintf(_T("Failed to open the archive %s ...\n"), szMpqName);
+ }
+
+ // Add all patches
+ if(nError == ERROR_SUCCESS)
+ {
+ va_start(argList, szMpqName);
+ while((szMpqName = va_arg(argList, const TCHAR *)) != NULL)
+ {
+ _tprintf(_T("Adding patch %s ...\n"), szMpqName);
+ if(!SFileOpenPatchArchive(hMpq, szMpqName, NULL, 0))
+ {
+ nError = GetLastError();
+ printf("Failed to add patch %s ...\n", szMpqName);
+ }
+ }
+ va_end(argList);
+ }
+/*
+ // Now search all files
+ if(nError == ERROR_SUCCESS)
+ {
+ SFILE_FIND_DATA sf;
+ HANDLE hFind;
+ bool bResult = true;
+
+ hFind = SFileFindFirstFile(hMpq, "World\\Minimaps\\Azeroth\\noLiquid_map20_44.*", &sf, NULL);
+ while(hFind && bResult)
+ {
+ printf("%s\n", sf.cFileName);
+ bResult = SFileFindNextFile(hFind, &sf);
+ }
+ }
+
+ // Now try to open patched version of a file
+ if(nError == ERROR_SUCCESS)
+ {
+ SFileExtractFile(hMpq, szFileName, _T("E:\\noLiquid_map20_44.blp"), SFILE_OPEN_FROM_MPQ);
+ }
+*/
+ // Now try to open patched version of "Achievement.dbc"
+ if(nError == ERROR_SUCCESS)
+ {
+ printf("Opening patched file \"%s\" ...\n", szFileName);
+ SFileHasFile(hMpq, szFileName);
+ SFileVerifyFile(hMpq, szFileName, SFILE_VERIFY_RAW_MD5);
+ if(!SFileOpenFileEx(hMpq, szFileName, 0, &hFile))
+ {
+ nError = GetLastError();
+ printf("Failed to open patched file \"%s\"\n", szFileName);
+ }
+ }
+
+ // Verify of the patched version is correct
+ if(nError == ERROR_SUCCESS)
+ {
+ TCHAR * szPatchChain = NULL;
+ DWORD cbPatchChain = 0;
+
+ // Get the patch chain
+ SFileGetFileInfo(hFile, SFILE_INFO_PATCH_CHAIN, szPatchChain, cbPatchChain, &cbPatchChain);
+ szPatchChain = (TCHAR *)(new BYTE[cbPatchChain]);
+ SFileGetFileInfo(hFile, SFILE_INFO_PATCH_CHAIN, szPatchChain, cbPatchChain, &cbPatchChain);
+ delete [] szPatchChain;
+
+ // Get the size of the full patched file
+ dwFileSize = SFileGetFileSize(hFile, NULL);
+ if(dwFileSize != 0)
+ {
+ DWORD dwBytesRead = 0;
+ BYTE TempData[0x100];
+
+ SFileReadFile(hFile, TempData, sizeof(TempData), &dwBytesRead, NULL);
+ SFileSetFilePointer(hFile, 0, NULL, FILE_BEGIN);
+
+ // Allocate space for the full file
+ pbFullFile = new BYTE[dwFileSize];
+ if(pbFullFile != NULL)
+ {
+ if(!SFileReadFile(hFile, pbFullFile, dwFileSize, NULL, NULL))
+ {
+ nError = GetLastError();
+ printf("Failed to read full patched file data \"%s\"\n", szFileName);
+ }
+
+ if(nError == ERROR_SUCCESS)
+ {
+ MergeLocalPath(szLocFileName, MAKE_PATH("Work//"), GetPlainFileNameA(szFileName));
+ pStream = FileStream_CreateFile(szLocFileName, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
+ if(pStream != NULL)
+ {
+ FileStream_Write(pStream, NULL, pbFullFile, dwFileSize);
+ FileStream_Close(pStream);
+ }
+ }
+
+ delete [] pbFullFile;
+ }
+ }
+ }
+
+ // Close handles
+ if(hFile != NULL)
+ SFileCloseFile(hFile);
+ if(hMpq != NULL)
+ SFileCloseArchive(hMpq);
+ return nError;
+}
+
+static int TestCompareTwoArchives(
+ const TCHAR * szMpqName1,
+ const TCHAR * szMpqName2,
+ const char * szListFile,
+ DWORD dwBlockSize)
+{
+ TMPQArchive * ha1 = NULL;
+ TMPQArchive * ha2 = NULL;
+ HANDLE hMpq1 = NULL; // Handle of the first archive
+ HANDLE hMpq2 = NULL; // Handle of the second archive
+ HANDLE hFile1 = NULL;
+ HANDLE hFile2 = NULL;
+ int nError = ERROR_SUCCESS;
+
+ // If no listfile or an empty one, use NULL
+ if(szListFile == NULL || *szListFile == 0)
+ szListFile = NULL;
+
+ _tprintf(_T("=============== Comparing MPQ archives ===============\n"));
+
+ // Open the first MPQ archive
+ if(nError == ERROR_SUCCESS && szMpqName1 != NULL)
+ {
+ _tprintf(_T("Opening %s ...\n"), szMpqName1);
+ if(!SFileOpenArchive(szMpqName1, 0, 0, &hMpq1))
+ nError = GetLastError();
+ ha1 = (TMPQArchive *)hMpq1;
+ }
+
+ // Open the second MPQ archive
+ if(nError == ERROR_SUCCESS && szMpqName2 != NULL)
+ {
+ _tprintf(_T("Opening %s ...\n"), szMpqName2);
+ if(!SFileOpenArchive(szMpqName2, 0, 0, &hMpq2))
+ nError = GetLastError();
+ ha2 = (TMPQArchive *)hMpq2;
+ }
+
+ // Compare the header
+ if(nError == ERROR_SUCCESS && (ha1 != NULL && ha2 != NULL))
+ {
+ if(ha1->pHeader->dwHeaderSize != ha2->pHeader->dwHeaderSize)
+ printf(" - Header size is different\n");
+ if(ha1->pHeader->wFormatVersion != ha2->pHeader->wFormatVersion)
+ printf(" - Format version is different\n");
+ if(ha1->pHeader->wSectorSize != ha2->pHeader->wSectorSize)
+ printf(" - Sector size is different\n");
+ if(ha1->pHeader->HetTableSize64 != ha2->pHeader->HetTableSize64)
+ printf(" - HET table size is different\n");
+ if(ha1->pHeader->BetTableSize64 != ha2->pHeader->BetTableSize64)
+ printf(" - BET table size is different\n");
+ if(ha1->pHeader->dwHashTableSize != ha2->pHeader->dwHashTableSize)
+ printf(" - Hash table size is different\n");
+ if(ha1->pHeader->dwBlockTableSize != ha2->pHeader->dwBlockTableSize)
+ printf(" - Block table size is different\n");
+ }
+
+ // Find all files in the first archive and compare them
+ if(nError == ERROR_SUCCESS)
+ {
+ SFILE_FIND_DATA sf;
+ TMPQFile * hf1;
+ TMPQFile * hf2;
+ HANDLE hFind = SFileFindFirstFile(hMpq1, "*", &sf, szListFile);
+ bool bResult = true;
+
+ while(hFind != NULL && bResult == true)
+ {
+// printf("%s \r", sf.cFileName);
+ SFileSetLocale(sf.lcLocale);
+
+ // Open the first file
+ if(!SFileOpenFileEx(hMpq1, sf.cFileName, 0, &hFile1))
+ printf("Failed to open the file %s in the first archive\n", sf.cFileName);
+
+ if(!SFileOpenFileEx(hMpq2, sf.cFileName, 0, &hFile2))
+ printf("Failed to open the file %s in the second archive\n", sf.cFileName);
+
+ if(hFile1 != NULL && hFile2 != NULL)
+ {
+ // Get the TMPQFile pointers
+ hf1 = (TMPQFile *)hFile1;
+ hf2 = (TMPQFile *)hFile2;
+
+ // Compare the file sizes
+ if(hf1->pFileEntry->dwFileSize != hf2->pFileEntry->dwFileSize)
+ printf("Different file size: %s (%u x %u)\n", sf.cFileName, hf1->pFileEntry->dwFileSize, hf2->pFileEntry->dwFileSize);
+
+ if(hf1->pFileEntry->dwCmpSize != hf2->pFileEntry->dwCmpSize)
+ printf("Different cmpr size: %s (%u x %u)\n", sf.cFileName, hf1->pFileEntry->dwCmpSize, hf2->pFileEntry->dwCmpSize);
+
+ if(hf1->pFileEntry->dwFlags != hf2->pFileEntry->dwFlags)
+ printf("Different mpq flags: %s (%08X x %08X)\n", sf.cFileName, hf1->pFileEntry->dwFlags, hf2->pFileEntry->dwFlags);
+
+ if(!CompareArchivedFiles(sf.cFileName, hFile1, hFile2, dwBlockSize))
+ printf("Different file data: %s\n", sf.cFileName);
+
+// if(!CompareArchivedFilesRR(sf.cFileName, hFile1, hFile2, dwBlockSize))
+// printf("Different file data: %s\n", sf.cFileName);
+ }
+
+ // Close both files
+ if(hFile2 != NULL)
+ SFileCloseFile(hFile2);
+ if(hFile1 != NULL)
+ SFileCloseFile(hFile1);
+ hFile2 = hFile1 = NULL;
+
+ // Find the next file
+ bResult = SFileFindNextFile(hFind, &sf);
+ }
+
+ // Close the find handle
+ if(hFind != NULL)
+ SFileFindClose(hFind);
+ }
+
+ // Close both archives
+ clreol();
+ printf("================ MPQ compare complete ================\n");
+ if(hMpq2 != NULL)
+ SFileCloseArchive(hMpq2);
+ if(hMpq1 != NULL)
+ SFileCloseArchive(hMpq1);
+ return nError;
+}
+
+//-----------------------------------------------------------------------------
+// Searching all known MPQs
+
+#ifdef _WIN32
+static int TestSearchOneArchive(const TCHAR * szMpqName)
+{
+ SFILE_FIND_DATA sf;
+ HANDLE hFind;
+ HANDLE hMpq;
+ const TCHAR * szExtension;
+ bool bFound = true;
+
+ // Get the file extension
+ szExtension = _tcsrchr(szMpqName, _T('.'));
+ if(szExtension == NULL)
+ return ERROR_SUCCESS;
+
+ // Only search defined extensions
+ if(_tcsicmp(szExtension, _T(".mpq")) && _tcsnicmp(szExtension, _T(".SC2"), 4))
+ return ERROR_SUCCESS;
+
+ _tprintf(_T("Searching %s ...\n"), szMpqName);
+
+ // Try to open the MPQ
+ if(SFileOpenArchive(szMpqName, 0, MPQ_OPEN_READ_ONLY, &hMpq))
+ {
+ hFind = SFileFindFirstFile(hMpq, "*", &sf, NULL);
+ if(hFind != NULL)
+ {
+ while(bFound)
+ {
+ if(sf.dwFileFlags & MPQ_FILE_DELETE_MARKER)
+ _tprintf(_T("Delete marker: %s:%hs\n"), szMpqName, sf.cFileName);
+
+ bFound = SFileFindNextFile(hFind, &sf);
+ }
+ }
+
+ SFileCloseArchive(hMpq);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+static int TestSearchAllArchives(const TCHAR * szSearchMask)
+{
+ WIN32_FIND_DATA wf;
+ LPTSTR szFilePart;
+ HANDLE hFind;
+ TCHAR szFullPath[MAX_PATH];
+ BOOL bFound = TRUE;
+
+ // Initiate search
+ _tcscpy(szFullPath, szSearchMask);
+ szFilePart = _tcschr(szFullPath, _T('*'));
+ assert(szFilePart != NULL);
+
+ // Begin search
+ hFind = FindFirstFile(szSearchMask, &wf);
+ if(hFind != INVALID_HANDLE_VALUE)
+ {
+ while(bFound)
+ {
+ // Eliminate "." and ".."
+ if(wf.cFileName[0] != _T('.'))
+ {
+ // Construct the full path
+ _tcscpy(szFilePart, wf.cFileName);
+
+ // If it a directory?
+ if(wf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ _tcscat(szFullPath, _T("\\*"));
+ TestSearchAllArchives(szFullPath);
+ }
+ else
+ {
+ TestSearchOneArchive(szFullPath);
+ }
+ }
+ bFound = FindNextFile(hFind, &wf);
+ }
+ FindClose(hFind);
+ }
+
+ return ERROR_SUCCESS;
+}
+#endif
+
+//-----------------------------------------------------------------------------
+// Main
+//
+
+int main(void)
+{
+ int nError = ERROR_SUCCESS;
+
+#if defined(_MSC_VER) && defined(_DEBUG)
+ _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif // defined(_MSC_VER) && defined(_DEBUG)
+
+ // Mix the random number generator
+// srand(GetTickCount());
+
+// FileStream_OpenEncrypted(_T("e:\\Multimedia\\MPQs\\2010 - Starcraft II\\Installer UI 2 deDE.MPQE"));
+
+ // Test structure sizes
+// if(nError == ERROR_SUCCESS)
+// nError = TestStructureSizes();
+
+// if(nError == ERROR_SUCCESS)
+// nError = TestOpenLocalFile("C:\\autoexec.bat");
+
+ // Test reading partial file
+// if(nError == ERROR_SUCCESS)
+// nError = TestPartFileRead(MAKE_PATH("2009 - PartialMPQs/patch.MPQ.part"));
+
+ if(nError == ERROR_SUCCESS)
+ {
+ CompareHuffmanCompressions7();
+ nError = CompareHuffmanCompressions0();
+ }
+
+// if(nError == ERROR_SUCCESS)
+// nError = ComparePklibCompressions();
+
+ // Test LZMA compression method against the code ripped from Starcraft II
+// if(nError == ERROR_SUCCESS)
+// nError = CompareLzmaCompressions(MPQ_SECTOR_SIZE);
+
+ // Test compression methods
+// if(nError == ERROR_SUCCESS)
+// nError = TestSectorCompress(MPQ_SECTOR_SIZE);
+
+ // Test the archive open and close
+// if(nError == ERROR_SUCCESS)
+// nError = TestArchiveOpenAndClose(MAKE_PATH("BrooDat.mpq"));
+
+// if(nError == ERROR_SUCCESS)
+// nError = TestFindFiles(MAKE_PATH("2002 - Warcraft III/HumanEd.mpq"));
+
+ // Create a big MPQ archive
+// if(nError == ERROR_SUCCESS)
+// nError = TestCreateArchive_PaliRoharBug(MAKE_PATH("Test.mpq"));
+// nError = TestCreateArchive(MAKE_PATH("Test.mpq"));
+// nError = TestCreateArchive((const TCHAR*)szUnicodeName1);
+// nError = TestCreateArchive((const TCHAR*)szUnicodeName2);
+// nError = TestCreateArchive((const TCHAR*)szUnicodeName3);
+// nError = TestCreateArchive((const TCHAR*)szUnicodeName4);
+// nError = TestCreateArchive((const TCHAR*)szUnicodeName5);
+// nError = TestCreateArchive((const TCHAR*)szUnicodeName6);
+
+// if(nError == ERROR_SUCCESS)
+// nError = TestAddFilesToMpq(MAKE_PATH("wow-update-13202.MPQ"),
+// "c:\\Tools32\\Arj32.exe",
+// "c:\\Tools32\\autoruns.chm",
+// "c:\\Tools32\\CPUEater.exe",
+// "c:\\Tools32\\dumpbin.exe",
+// "c:\\Tools32\\editbin.exe",
+// "c:\\Tools32\\fsg.ini",
+// "c:\\Tools32\\hiew8.ini",
+// "c:\\Tools32\\ida.bat",
+// "c:\\Tools32\\mp3.ini",
+// NULL);
+
+// if(nError == ERROR_SUCCESS)
+// nError = TestCreateArchiveFromMemory(MAKE_PATH("Test-leak.mpq"));
+
+// if(nError == ERROR_SUCCESS)
+// nError = TestFileReadAndWrite(MAKE_PATH("2002 - Warcraft III/(10)DustwallowKeys.w3m"), "war3map.j");
+
+ // Verify the archive signature
+// if(nError == ERROR_SUCCESS)
+// nError = TestSignatureVerify(MAKE_PATH("1998 - Starcraft/BW-1152.exe"));
+// nError = TestSignatureVerify(MAKE_PATH("2002 - Warcraft III/(10)DustwallowKeys.w3m"));
+// nError = TestSignatureVerify(MAKE_PATH("2002 - Warcraft III/War3TFT_121b_English.exe"));
+// nError = TestSignatureVerify(MAKE_PATH("2004 - World of Warcraft/WoW-2.3.3.7799-to-2.4.0.8089-enUS-patch.exe"));
+// nError = TestSignatureVerify(MAKE_PATH("2004 - World of Warcraft/standalone.MPQ"));
+
+ // Compact the archive
+// if(nError == ERROR_SUCCESS)
+// nError = TestMpqCompacting(MAKE_PATH("wow-update-base-14333.MPQ"));
+
+ // Create copy of the archive, appending some bytes before the MPQ header
+// if(nError == ERROR_SUCCESS)
+// nError = TestCreateArchiveCopy(MAKE_PATH("PartialMPQs/interface.MPQ.part"), MAKE_PATH("PartialMPQs/interface-copy.MPQ.part"), NULL);
+
+
+// if(nError == ERROR_SUCCESS)
+// {
+// nError = TestOpenPatchedArchive(MAKE_PATH("2012 - WoW\\16057\\enUS\\locale-enUS.MPQ"),
+// MAKE_PATH("2012 - WoW\\16057\\enUS\\wow-update-enUS-16016.MPQ"),
+// NULL);
+// }
+
+// if(nError == ERROR_SUCCESS)
+// {
+// nError = TestCompareTwoArchives(MAKE_PATH("Sound-copy.mpq"),
+// MAKE_PATH("Sound.mpq"),
+// NULL,
+// 0x1001);
+// }
+
+// if(nError == ERROR_SUCCESS)
+// nError = TestSearchAllArchives(MAKE_PATH("*"));
+
+ return nError;
+}