stormlib 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (624) hide show
  1. checksums.yaml +4 -4
  2. data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CMakeCCompiler.cmake +72 -0
  3. data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CMakeCXXCompiler.cmake +83 -0
  4. data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CMakeDetermineCompilerABI_C.bin +0 -0
  5. data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CMakeDetermineCompilerABI_CXX.bin +0 -0
  6. data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CMakeSystem.cmake +15 -0
  7. data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CompilerIdC/CMakeCCompilerId.c +803 -0
  8. data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CompilerIdC/a.out +0 -0
  9. data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CompilerIdCXX/CMakeCXXCompilerId.cpp +791 -0
  10. data/ext/stormlib/StormLib/CMakeFiles/3.22.1/CompilerIdCXX/a.out +0 -0
  11. data/ext/stormlib/StormLib/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
  12. data/ext/stormlib/StormLib/CMakeFiles/CMakeOutput.log +478 -0
  13. data/ext/stormlib/StormLib/CMakeFiles/Export/share/StormLib/StormLibConfig-noconfig.cmake +19 -0
  14. data/ext/stormlib/StormLib/CMakeFiles/Export/share/StormLib/StormLibConfig.cmake +99 -0
  15. data/ext/stormlib/StormLib/CMakeFiles/Makefile.cmake +61 -0
  16. data/ext/stormlib/StormLib/CMakeFiles/Makefile2 +112 -0
  17. data/ext/stormlib/StormLib/CMakeFiles/TargetDirectories.txt +9 -0
  18. data/ext/stormlib/StormLib/CMakeFiles/cmake.check_cache +1 -0
  19. data/ext/stormlib/StormLib/CMakeFiles/progress.marks +1 -0
  20. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/DependInfo.cmake +243 -0
  21. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/build.make +3695 -0
  22. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/cmake_clean.cmake +459 -0
  23. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/cmake_clean_target.cmake +3 -0
  24. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/compiler_depend.make +2 -0
  25. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/compiler_depend.ts +2 -0
  26. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/depend.make +2 -0
  27. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/flags.make +17 -0
  28. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/link.txt +2 -0
  29. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/progress.make +227 -0
  30. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/FileStream.cpp.o.d +160 -0
  31. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SBaseCommon.cpp.o.d +159 -0
  32. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SBaseDumpData.cpp.o.d +159 -0
  33. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SBaseFileTable.cpp.o.d +159 -0
  34. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SBaseSubTypes.cpp.o.d +159 -0
  35. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SCompression.cpp.o.d +159 -0
  36. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileAddFile.cpp.o.d +159 -0
  37. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileAttributes.cpp.o.d +159 -0
  38. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileCompactArchive.cpp.o.d +159 -0
  39. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileCreateArchive.cpp.o.d +159 -0
  40. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileExtractFile.cpp.o.d +159 -0
  41. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileFindFile.cpp.o.d +159 -0
  42. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileGetFileInfo.cpp.o.d +159 -0
  43. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileListFile.cpp.o.d +159 -0
  44. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileOpenArchive.cpp.o.d +159 -0
  45. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileOpenFileEx.cpp.o.d +159 -0
  46. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFilePatchArchives.cpp.o.d +159 -0
  47. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileReadFile.cpp.o.d +159 -0
  48. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/SFileVerify.cpp.o.d +159 -0
  49. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/adpcm/adpcm.cpp.o.d +12 -0
  50. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/huffman/huff.cpp.o.d +16 -0
  51. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/jenkins/lookup3.c.o.d +88 -0
  52. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/hashes/hash_memory.c.o.d +102 -0
  53. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/hashes/md5.c.o.d +102 -0
  54. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/hashes/sha1.c.o.d +102 -0
  55. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/hashes/sha256.c.o.d +102 -0
  56. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/math/ltm_desc.c.o.d +105 -0
  57. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/math/multi.c.o.d +102 -0
  58. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/math/rand_prime.c.o.d +102 -0
  59. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/base64_decode.c.o.d +102 -0
  60. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_argchk.c.o.d +102 -0
  61. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_find_hash.c.o.d +102 -0
  62. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_find_prng.c.o.d +102 -0
  63. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_hash_descriptor.c.o.d +102 -0
  64. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_hash_is_valid.c.o.d +102 -0
  65. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_libc.c.o.d +102 -0
  66. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c.o.d +102 -0
  67. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_prng_descriptor.c.o.d +102 -0
  68. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_prng_is_valid.c.o.d +102 -0
  69. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_register_hash.c.o.d +102 -0
  70. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/crypt_register_prng.c.o.d +102 -0
  71. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/misc/zeromem.c.o.d +102 -0
  72. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c.o.d +102 -0
  73. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_boolean.c.o.d +102 -0
  74. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_choice.c.o.d +102 -0
  75. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c.o.d +102 -0
  76. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_integer.c.o.d +102 -0
  77. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c.o.d +102 -0
  78. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c.o.d +102 -0
  79. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c.o.d +102 -0
  80. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c.o.d +102 -0
  81. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c.o.d +102 -0
  82. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c.o.d +102 -0
  83. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c.o.d +102 -0
  84. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_utctime.c.o.d +102 -0
  85. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c.o.d +102 -0
  86. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_bit_string.c.o.d +102 -0
  87. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_boolean.c.o.d +102 -0
  88. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_ia5_string.c.o.d +102 -0
  89. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_integer.c.o.d +102 -0
  90. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_object_identifier.c.o.d +102 -0
  91. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_octet_string.c.o.d +102 -0
  92. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_printable_string.c.o.d +102 -0
  93. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_sequence_ex.c.o.d +102 -0
  94. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_sequence_multi.c.o.d +102 -0
  95. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_set.c.o.d +102 -0
  96. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_setof.c.o.d +102 -0
  97. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_short_integer.c.o.d +102 -0
  98. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_utctime.c.o.d +102 -0
  99. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_encode_utf8_string.c.o.d +102 -0
  100. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_bit_string.c.o.d +102 -0
  101. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_boolean.c.o.d +102 -0
  102. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c.o.d +102 -0
  103. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_integer.c.o.d +102 -0
  104. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c.o.d +102 -0
  105. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_octet_string.c.o.d +102 -0
  106. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_printable_string.c.o.d +102 -0
  107. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_sequence.c.o.d +102 -0
  108. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_short_integer.c.o.d +102 -0
  109. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_utctime.c.o.d +102 -0
  110. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c.o.d +102 -0
  111. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/asn1/der_sequence_free.c.o.d +102 -0
  112. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c.o.d +102 -0
  113. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c.o.d +102 -0
  114. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c.o.d +102 -0
  115. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c.o.d +102 -0
  116. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c.o.d +102 -0
  117. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c.o.d +102 -0
  118. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c.o.d +102 -0
  119. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c.o.d +102 -0
  120. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c.o.d +102 -0
  121. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_encode.c.o.d +102 -0
  122. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c.o.d +102 -0
  123. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_encode.c.o.d +102 -0
  124. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/rsa/rsa_exptmod.c.o.d +102 -0
  125. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/rsa/rsa_free.c.o.d +102 -0
  126. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/rsa/rsa_import.c.o.d +102 -0
  127. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/rsa/rsa_make_key.c.o.d +102 -0
  128. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/rsa/rsa_sign_hash.c.o.d +102 -0
  129. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c.o.d +102 -0
  130. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c.o.d +102 -0
  131. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_fast_mp_invmod.c.o.d +65 -0
  132. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_fast_mp_montgomery_reduce.c.o.d +65 -0
  133. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_fast_s_mp_mul_digs.c.o.d +65 -0
  134. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_fast_s_mp_mul_high_digs.c.o.d +65 -0
  135. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_fast_s_mp_sqr.c.o.d +65 -0
  136. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_2expt.c.o.d +65 -0
  137. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_abs.c.o.d +65 -0
  138. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_add.c.o.d +65 -0
  139. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_add_d.c.o.d +65 -0
  140. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_addmod.c.o.d +65 -0
  141. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_and.c.o.d +65 -0
  142. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_clamp.c.o.d +65 -0
  143. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_clear.c.o.d +65 -0
  144. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_clear_multi.c.o.d +65 -0
  145. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_cmp.c.o.d +65 -0
  146. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_cmp_d.c.o.d +65 -0
  147. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_cmp_mag.c.o.d +65 -0
  148. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_cnt_lsb.c.o.d +65 -0
  149. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_copy.c.o.d +65 -0
  150. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_count_bits.c.o.d +65 -0
  151. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_div.c.o.d +65 -0
  152. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_div_2.c.o.d +65 -0
  153. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_div_2d.c.o.d +65 -0
  154. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_div_3.c.o.d +65 -0
  155. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_div_d.c.o.d +65 -0
  156. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_dr_is_modulus.c.o.d +65 -0
  157. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_dr_reduce.c.o.d +65 -0
  158. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_dr_setup.c.o.d +65 -0
  159. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_exch.c.o.d +65 -0
  160. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_expt_d.c.o.d +65 -0
  161. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_exptmod.c.o.d +65 -0
  162. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_exptmod_fast.c.o.d +65 -0
  163. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_exteuclid.c.o.d +65 -0
  164. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_fread.c.o.d +65 -0
  165. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_fwrite.c.o.d +65 -0
  166. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_gcd.c.o.d +65 -0
  167. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_get_int.c.o.d +65 -0
  168. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_grow.c.o.d +65 -0
  169. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_init.c.o.d +65 -0
  170. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_init_copy.c.o.d +65 -0
  171. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_init_multi.c.o.d +65 -0
  172. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_init_set.c.o.d +65 -0
  173. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_init_set_int.c.o.d +65 -0
  174. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_init_size.c.o.d +65 -0
  175. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_invmod.c.o.d +65 -0
  176. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_invmod_slow.c.o.d +65 -0
  177. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_is_square.c.o.d +65 -0
  178. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_jacobi.c.o.d +65 -0
  179. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_karatsuba_mul.c.o.d +65 -0
  180. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_karatsuba_sqr.c.o.d +65 -0
  181. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_lcm.c.o.d +65 -0
  182. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_lshd.c.o.d +65 -0
  183. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_mod.c.o.d +65 -0
  184. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_mod_2d.c.o.d +65 -0
  185. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_mod_d.c.o.d +65 -0
  186. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_montgomery_calc_normalization.c.o.d +65 -0
  187. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_montgomery_reduce.c.o.d +65 -0
  188. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_montgomery_setup.c.o.d +65 -0
  189. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_mul.c.o.d +65 -0
  190. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_mul_2.c.o.d +65 -0
  191. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_mul_2d.c.o.d +65 -0
  192. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_mul_d.c.o.d +65 -0
  193. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_mulmod.c.o.d +65 -0
  194. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_n_root.c.o.d +65 -0
  195. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_neg.c.o.d +65 -0
  196. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_or.c.o.d +65 -0
  197. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_prime_fermat.c.o.d +65 -0
  198. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_prime_is_divisible.c.o.d +65 -0
  199. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_prime_is_prime.c.o.d +65 -0
  200. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_prime_miller_rabin.c.o.d +65 -0
  201. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_prime_next_prime.c.o.d +65 -0
  202. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_prime_rabin_miller_trials.c.o.d +65 -0
  203. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_prime_random_ex.c.o.d +65 -0
  204. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_radix_size.c.o.d +65 -0
  205. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_radix_smap.c.o.d +65 -0
  206. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_rand.c.o.d +65 -0
  207. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_read_radix.c.o.d +65 -0
  208. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_read_signed_bin.c.o.d +65 -0
  209. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_read_unsigned_bin.c.o.d +65 -0
  210. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_reduce.c.o.d +65 -0
  211. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_reduce_2k.c.o.d +65 -0
  212. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_reduce_2k_l.c.o.d +65 -0
  213. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_reduce_2k_setup.c.o.d +65 -0
  214. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_reduce_2k_setup_l.c.o.d +65 -0
  215. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_reduce_is_2k.c.o.d +65 -0
  216. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_reduce_is_2k_l.c.o.d +65 -0
  217. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_reduce_setup.c.o.d +65 -0
  218. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_rshd.c.o.d +65 -0
  219. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_set.c.o.d +65 -0
  220. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_set_int.c.o.d +65 -0
  221. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_shrink.c.o.d +65 -0
  222. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_signed_bin_size.c.o.d +65 -0
  223. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_sqr.c.o.d +65 -0
  224. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_sqrmod.c.o.d +65 -0
  225. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_sqrt.c.o.d +65 -0
  226. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_sub.c.o.d +65 -0
  227. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_sub_d.c.o.d +65 -0
  228. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_submod.c.o.d +65 -0
  229. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_to_signed_bin.c.o.d +65 -0
  230. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_to_signed_bin_n.c.o.d +65 -0
  231. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_to_unsigned_bin.c.o.d +65 -0
  232. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_to_unsigned_bin_n.c.o.d +65 -0
  233. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_toom_mul.c.o.d +65 -0
  234. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_toom_sqr.c.o.d +65 -0
  235. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_toradix.c.o.d +65 -0
  236. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_toradix_n.c.o.d +65 -0
  237. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_unsigned_bin_size.c.o.d +65 -0
  238. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_xor.c.o.d +65 -0
  239. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_mp_zero.c.o.d +65 -0
  240. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_prime_tab.c.o.d +65 -0
  241. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_reverse.c.o.d +65 -0
  242. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_s_mp_add.c.o.d +65 -0
  243. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_s_mp_exptmod.c.o.d +65 -0
  244. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_s_mp_mul_digs.c.o.d +65 -0
  245. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_s_mp_mul_high_digs.c.o.d +65 -0
  246. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_s_mp_sqr.c.o.d +65 -0
  247. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bn_s_mp_sub.c.o.d +65 -0
  248. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/libtommath/bncore.c.o.d +65 -0
  249. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/lzma/C/LzFind.c.o.d +18 -0
  250. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/lzma/C/LzmaDec.c.o.d +17 -0
  251. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/lzma/C/LzmaEnc.c.o.d +18 -0
  252. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/pklib/explode.c.o.d +16 -0
  253. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/pklib/implode.c.o.d +23 -0
  254. data/ext/stormlib/StormLib/CMakeFiles/storm.dir/src/sparse/sparse.cpp.o.d +16 -0
  255. data/ext/stormlib/StormLib/CMakeLists.txt +418 -0
  256. data/ext/stormlib/StormLib/Info.plist +22 -0
  257. data/ext/stormlib/StormLib/LICENSE +21 -0
  258. data/ext/stormlib/StormLib/Premake5.lua +132 -0
  259. data/ext/stormlib/StormLib/README.md +39 -0
  260. data/ext/stormlib/StormLib/StormLib.sln +162 -0
  261. data/ext/stormlib/StormLib/StormLib.vcxproj +1024 -0
  262. data/ext/stormlib/StormLib/StormLib.vcxproj.filters +221 -0
  263. data/ext/stormlib/StormLib/StormLib.xcodeproj/project.pbxproj +2104 -0
  264. data/ext/stormlib/StormLib/StormLib_dll.vcxproj +348 -0
  265. data/ext/stormlib/StormLib/StormLib_dll.vcxproj.filters +229 -0
  266. data/ext/stormlib/StormLib/StormLib_test.vcxproj +360 -0
  267. data/ext/stormlib/StormLib/StormLib_test.vcxproj.filters +230 -0
  268. data/ext/stormlib/StormLib/StormLib_vs08.sln +139 -0
  269. data/ext/stormlib/StormLib/StormLib_vs08.vcproj +4205 -0
  270. data/ext/stormlib/StormLib/StormLib_vs08_dll.vcproj +1851 -0
  271. data/ext/stormlib/StormLib/StormLib_vs08_test.vcproj +1289 -0
  272. data/ext/stormlib/StormLib/doc/History.txt +78 -0
  273. data/ext/stormlib/StormLib/doc/The MoPaQ File Format 0.9.txt +318 -0
  274. data/ext/stormlib/StormLib/doc/The MoPaQ File Format 1.0.txt +433 -0
  275. data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-deDE.txt +1 -0
  276. data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-enGB.txt +1 -0
  277. data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-enSG.txt +1 -0
  278. data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-enUS.txt +1 -0
  279. data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-esES.txt +1 -0
  280. data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-esMX.txt +1 -0
  281. data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-frFR.txt +1 -0
  282. data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-itIT.txt +1 -0
  283. data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-koKR.txt +1 -0
  284. data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-plPL.txt +1 -0
  285. data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-ptBR.txt +1 -0
  286. data/ext/stormlib/StormLib/doc/d3-authenticationcode/d3-authenticationcode-zhTW.txt +1 -0
  287. data/ext/stormlib/StormLib/doc/hots-authenticationcode/hots-authenticationcode-bgdl.txt +1 -0
  288. data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-deDE.txt +1 -0
  289. data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-enGB.txt +1 -0
  290. data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-enUS.txt +1 -0
  291. data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-esES.txt +1 -0
  292. data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-esMX.txt +1 -0
  293. data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-frFR.txt +1 -0
  294. data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-itIT.txt +1 -0
  295. data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-koKR.txt +1 -0
  296. data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-plPL.txt +1 -0
  297. data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-ptBR.txt +1 -0
  298. data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-ruRU.txt +1 -0
  299. data/ext/stormlib/StormLib/doc/sc2-authenticationcode/sc2-authenticationcode-zhTW.txt +1 -0
  300. data/ext/stormlib/StormLib/make-msvc.bat +95 -0
  301. data/ext/stormlib/StormLib/make.bat +46 -0
  302. data/ext/stormlib/StormLib/sources +14 -0
  303. data/ext/stormlib/StormLib/src/DllMain.c +24 -0
  304. data/ext/stormlib/StormLib/src/DllMain.def +79 -0
  305. data/ext/stormlib/StormLib/src/DllMain.rc +110 -0
  306. data/ext/stormlib/StormLib/src/FileStream.cpp +2928 -0
  307. data/ext/stormlib/StormLib/src/FileStream.h +217 -0
  308. data/ext/stormlib/StormLib/src/LibTomCrypt.c +85 -0
  309. data/ext/stormlib/StormLib/src/LibTomMath.c +125 -0
  310. data/ext/stormlib/StormLib/src/LibTomMathDesc.c +4 -0
  311. data/ext/stormlib/StormLib/src/SBaseCommon.cpp +1970 -0
  312. data/ext/stormlib/StormLib/src/SBaseDumpData.cpp +183 -0
  313. data/ext/stormlib/StormLib/src/SBaseFileTable.cpp +3194 -0
  314. data/ext/stormlib/StormLib/src/SBaseSubTypes.cpp +688 -0
  315. data/ext/stormlib/StormLib/src/SCompression.cpp +1183 -0
  316. data/ext/stormlib/StormLib/src/SFileAddFile.cpp +1337 -0
  317. data/ext/stormlib/StormLib/src/SFileAttributes.cpp +573 -0
  318. data/ext/stormlib/StormLib/src/SFileCompactArchive.cpp +654 -0
  319. data/ext/stormlib/StormLib/src/SFileCreateArchive.cpp +285 -0
  320. data/ext/stormlib/StormLib/src/SFileExtractFile.cpp +64 -0
  321. data/ext/stormlib/StormLib/src/SFileFindFile.cpp +484 -0
  322. data/ext/stormlib/StormLib/src/SFileGetFileInfo.cpp +627 -0
  323. data/ext/stormlib/StormLib/src/SFileListFile.cpp +750 -0
  324. data/ext/stormlib/StormLib/src/SFileOpenArchive.cpp +723 -0
  325. data/ext/stormlib/StormLib/src/SFileOpenFileEx.cpp +423 -0
  326. data/ext/stormlib/StormLib/src/SFilePatchArchives.cpp +1175 -0
  327. data/ext/stormlib/StormLib/src/SFileReadFile.cpp +922 -0
  328. data/ext/stormlib/StormLib/src/SFileVerify.cpp +1059 -0
  329. data/ext/stormlib/StormLib/src/StormCommon.h +450 -0
  330. data/ext/stormlib/StormLib/src/StormLib.exp +74 -0
  331. data/ext/stormlib/StormLib/src/StormLib.h +1157 -0
  332. data/ext/stormlib/StormLib/src/StormPort.h +474 -0
  333. data/ext/stormlib/StormLib/src/adpcm/adpcm.cpp +539 -0
  334. data/ext/stormlib/StormLib/src/adpcm/adpcm.h +27 -0
  335. data/ext/stormlib/StormLib/src/bzip2/blocksort.c +1094 -0
  336. data/ext/stormlib/StormLib/src/bzip2/bzlib.c +1573 -0
  337. data/ext/stormlib/StormLib/src/bzip2/bzlib.h +282 -0
  338. data/ext/stormlib/StormLib/src/bzip2/bzlib_private.h +509 -0
  339. data/ext/stormlib/StormLib/src/bzip2/compress.c +672 -0
  340. data/ext/stormlib/StormLib/src/bzip2/crctable.c +104 -0
  341. data/ext/stormlib/StormLib/src/bzip2/decompress.c +626 -0
  342. data/ext/stormlib/StormLib/src/bzip2/huffman.c +205 -0
  343. data/ext/stormlib/StormLib/src/bzip2/randtable.c +84 -0
  344. data/ext/stormlib/StormLib/src/huffman/huff.cpp +915 -0
  345. data/ext/stormlib/StormLib/src/huffman/huff.h +143 -0
  346. data/ext/stormlib/StormLib/src/jenkins/lookup.h +24 -0
  347. data/ext/stormlib/StormLib/src/jenkins/lookup3.c +1003 -0
  348. data/ext/stormlib/StormLib/src/libtomcrypt/src/hashes/hash_memory.c +69 -0
  349. data/ext/stormlib/StormLib/src/libtomcrypt/src/hashes/md5.c +368 -0
  350. data/ext/stormlib/StormLib/src/libtomcrypt/src/hashes/sha1.c +288 -0
  351. data/ext/stormlib/StormLib/src/libtomcrypt/src/hashes/sha256.c +340 -0
  352. data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt.h +91 -0
  353. data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_argchk.h +38 -0
  354. data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h +144 -0
  355. data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_cipher.h +891 -0
  356. data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_custom.h +424 -0
  357. data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_hash.h +378 -0
  358. data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_mac.h +384 -0
  359. data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_macros.h +424 -0
  360. data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_math.h +500 -0
  361. data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_misc.h +23 -0
  362. data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_pk.h +558 -0
  363. data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_pkcs.h +89 -0
  364. data/ext/stormlib/StormLib/src/libtomcrypt/src/headers/tomcrypt_prng.h +199 -0
  365. data/ext/stormlib/StormLib/src/libtomcrypt/src/math/ltm_desc.c +483 -0
  366. data/ext/stormlib/StormLib/src/libtomcrypt/src/math/multi.c +61 -0
  367. data/ext/stormlib/StormLib/src/libtomcrypt/src/math/rand_prime.c +87 -0
  368. data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/base64_decode.c +104 -0
  369. data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_argchk.c +30 -0
  370. data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_find_hash.c +40 -0
  371. data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_find_prng.c +41 -0
  372. data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_hash_descriptor.c +27 -0
  373. data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_hash_is_valid.c +36 -0
  374. data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_libc.c +43 -0
  375. data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c +13 -0
  376. data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_prng_descriptor.c +26 -0
  377. data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_prng_is_valid.c +36 -0
  378. data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_register_hash.c +54 -0
  379. data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/crypt_register_prng.c +54 -0
  380. data/ext/stormlib/StormLib/src/libtomcrypt/src/misc/zeromem.c +34 -0
  381. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c +102 -0
  382. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_boolean.c +47 -0
  383. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_choice.c +182 -0
  384. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c +96 -0
  385. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_integer.c +110 -0
  386. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c +99 -0
  387. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c +91 -0
  388. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c +96 -0
  389. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c +287 -0
  390. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c +386 -0
  391. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c +139 -0
  392. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c +68 -0
  393. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utctime.c +127 -0
  394. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c +111 -0
  395. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_bit_string.c +89 -0
  396. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_boolean.c +51 -0
  397. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_ia5_string.c +85 -0
  398. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_integer.c +130 -0
  399. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_object_identifier.c +111 -0
  400. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_octet_string.c +86 -0
  401. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_printable_string.c +85 -0
  402. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_sequence_ex.c +335 -0
  403. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_sequence_multi.c +138 -0
  404. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_set.c +103 -0
  405. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_setof.c +162 -0
  406. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_short_integer.c +97 -0
  407. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_utctime.c +83 -0
  408. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_encode_utf8_string.c +105 -0
  409. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_bit_string.c +54 -0
  410. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_boolean.c +35 -0
  411. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c +194 -0
  412. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_integer.c +82 -0
  413. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c +89 -0
  414. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_octet_string.c +53 -0
  415. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_printable_string.c +166 -0
  416. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_sequence.c +169 -0
  417. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_short_integer.c +70 -0
  418. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utctime.c +46 -0
  419. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c +83 -0
  420. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/asn1/der_sequence_free.c +65 -0
  421. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c +76 -0
  422. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c +207 -0
  423. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c +222 -0
  424. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c +60 -0
  425. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c +196 -0
  426. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c +147 -0
  427. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c +108 -0
  428. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c +189 -0
  429. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c +177 -0
  430. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_encode.c +175 -0
  431. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c +110 -0
  432. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_encode.c +111 -0
  433. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/rsa/rsa_exptmod.c +113 -0
  434. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/rsa/rsa_free.c +34 -0
  435. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/rsa/rsa_import.c +143 -0
  436. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/rsa/rsa_make_key.c +112 -0
  437. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/rsa/rsa_sign_hash.c +134 -0
  438. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c +167 -0
  439. data/ext/stormlib/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c +87 -0
  440. data/ext/stormlib/StormLib/src/libtommath/bn_fast_mp_invmod.c +148 -0
  441. data/ext/stormlib/StormLib/src/libtommath/bn_fast_mp_montgomery_reduce.c +172 -0
  442. data/ext/stormlib/StormLib/src/libtommath/bn_fast_s_mp_mul_digs.c +107 -0
  443. data/ext/stormlib/StormLib/src/libtommath/bn_fast_s_mp_mul_high_digs.c +98 -0
  444. data/ext/stormlib/StormLib/src/libtommath/bn_fast_s_mp_sqr.c +114 -0
  445. data/ext/stormlib/StormLib/src/libtommath/bn_mp_2expt.c +48 -0
  446. data/ext/stormlib/StormLib/src/libtommath/bn_mp_abs.c +43 -0
  447. data/ext/stormlib/StormLib/src/libtommath/bn_mp_add.c +53 -0
  448. data/ext/stormlib/StormLib/src/libtommath/bn_mp_add_d.c +112 -0
  449. data/ext/stormlib/StormLib/src/libtommath/bn_mp_addmod.c +41 -0
  450. data/ext/stormlib/StormLib/src/libtommath/bn_mp_and.c +57 -0
  451. data/ext/stormlib/StormLib/src/libtommath/bn_mp_clamp.c +44 -0
  452. data/ext/stormlib/StormLib/src/libtommath/bn_mp_clear.c +44 -0
  453. data/ext/stormlib/StormLib/src/libtommath/bn_mp_clear_multi.c +34 -0
  454. data/ext/stormlib/StormLib/src/libtommath/bn_mp_cmp.c +43 -0
  455. data/ext/stormlib/StormLib/src/libtommath/bn_mp_cmp_d.c +44 -0
  456. data/ext/stormlib/StormLib/src/libtommath/bn_mp_cmp_mag.c +55 -0
  457. data/ext/stormlib/StormLib/src/libtommath/bn_mp_cnt_lsb.c +53 -0
  458. data/ext/stormlib/StormLib/src/libtommath/bn_mp_copy.c +68 -0
  459. data/ext/stormlib/StormLib/src/libtommath/bn_mp_count_bits.c +45 -0
  460. data/ext/stormlib/StormLib/src/libtommath/bn_mp_div.c +292 -0
  461. data/ext/stormlib/StormLib/src/libtommath/bn_mp_div_2.c +68 -0
  462. data/ext/stormlib/StormLib/src/libtommath/bn_mp_div_2d.c +97 -0
  463. data/ext/stormlib/StormLib/src/libtommath/bn_mp_div_3.c +79 -0
  464. data/ext/stormlib/StormLib/src/libtommath/bn_mp_div_d.c +115 -0
  465. data/ext/stormlib/StormLib/src/libtommath/bn_mp_dr_is_modulus.c +43 -0
  466. data/ext/stormlib/StormLib/src/libtommath/bn_mp_dr_reduce.c +94 -0
  467. data/ext/stormlib/StormLib/src/libtommath/bn_mp_dr_setup.c +32 -0
  468. data/ext/stormlib/StormLib/src/libtommath/bn_mp_exch.c +34 -0
  469. data/ext/stormlib/StormLib/src/libtommath/bn_mp_expt_d.c +57 -0
  470. data/ext/stormlib/StormLib/src/libtommath/bn_mp_exptmod.c +112 -0
  471. data/ext/stormlib/StormLib/src/libtommath/bn_mp_exptmod_fast.c +321 -0
  472. data/ext/stormlib/StormLib/src/libtommath/bn_mp_exteuclid.c +82 -0
  473. data/ext/stormlib/StormLib/src/libtommath/bn_mp_fread.c +67 -0
  474. data/ext/stormlib/StormLib/src/libtommath/bn_mp_fwrite.c +52 -0
  475. data/ext/stormlib/StormLib/src/libtommath/bn_mp_gcd.c +105 -0
  476. data/ext/stormlib/StormLib/src/libtommath/bn_mp_get_int.c +45 -0
  477. data/ext/stormlib/StormLib/src/libtommath/bn_mp_grow.c +57 -0
  478. data/ext/stormlib/StormLib/src/libtommath/bn_mp_init.c +46 -0
  479. data/ext/stormlib/StormLib/src/libtommath/bn_mp_init_copy.c +32 -0
  480. data/ext/stormlib/StormLib/src/libtommath/bn_mp_init_multi.c +59 -0
  481. data/ext/stormlib/StormLib/src/libtommath/bn_mp_init_set.c +32 -0
  482. data/ext/stormlib/StormLib/src/libtommath/bn_mp_init_set_int.c +31 -0
  483. data/ext/stormlib/StormLib/src/libtommath/bn_mp_init_size.c +48 -0
  484. data/ext/stormlib/StormLib/src/libtommath/bn_mp_invmod.c +43 -0
  485. data/ext/stormlib/StormLib/src/libtommath/bn_mp_invmod_slow.c +175 -0
  486. data/ext/stormlib/StormLib/src/libtommath/bn_mp_is_square.c +109 -0
  487. data/ext/stormlib/StormLib/src/libtommath/bn_mp_jacobi.c +105 -0
  488. data/ext/stormlib/StormLib/src/libtommath/bn_mp_karatsuba_mul.c +167 -0
  489. data/ext/stormlib/StormLib/src/libtommath/bn_mp_karatsuba_sqr.c +121 -0
  490. data/ext/stormlib/StormLib/src/libtommath/bn_mp_lcm.c +60 -0
  491. data/ext/stormlib/StormLib/src/libtommath/bn_mp_lshd.c +67 -0
  492. data/ext/stormlib/StormLib/src/libtommath/bn_mp_mod.c +48 -0
  493. data/ext/stormlib/StormLib/src/libtommath/bn_mp_mod_2d.c +55 -0
  494. data/ext/stormlib/StormLib/src/libtommath/bn_mp_mod_d.c +27 -0
  495. data/ext/stormlib/StormLib/src/libtommath/bn_mp_montgomery_calc_normalization.c +59 -0
  496. data/ext/stormlib/StormLib/src/libtommath/bn_mp_montgomery_reduce.c +118 -0
  497. data/ext/stormlib/StormLib/src/libtommath/bn_mp_montgomery_setup.c +59 -0
  498. data/ext/stormlib/StormLib/src/libtommath/bn_mp_mul.c +66 -0
  499. data/ext/stormlib/StormLib/src/libtommath/bn_mp_mul_2.c +82 -0
  500. data/ext/stormlib/StormLib/src/libtommath/bn_mp_mul_2d.c +85 -0
  501. data/ext/stormlib/StormLib/src/libtommath/bn_mp_mul_d.c +79 -0
  502. data/ext/stormlib/StormLib/src/libtommath/bn_mp_mulmod.c +40 -0
  503. data/ext/stormlib/StormLib/src/libtommath/bn_mp_n_root.c +132 -0
  504. data/ext/stormlib/StormLib/src/libtommath/bn_mp_neg.c +40 -0
  505. data/ext/stormlib/StormLib/src/libtommath/bn_mp_or.c +50 -0
  506. data/ext/stormlib/StormLib/src/libtommath/bn_mp_prime_fermat.c +62 -0
  507. data/ext/stormlib/StormLib/src/libtommath/bn_mp_prime_is_divisible.c +50 -0
  508. data/ext/stormlib/StormLib/src/libtommath/bn_mp_prime_is_prime.c +83 -0
  509. data/ext/stormlib/StormLib/src/libtommath/bn_mp_prime_miller_rabin.c +103 -0
  510. data/ext/stormlib/StormLib/src/libtommath/bn_mp_prime_next_prime.c +170 -0
  511. data/ext/stormlib/StormLib/src/libtommath/bn_mp_prime_rabin_miller_trials.c +52 -0
  512. data/ext/stormlib/StormLib/src/libtommath/bn_mp_prime_random_ex.c +125 -0
  513. data/ext/stormlib/StormLib/src/libtommath/bn_mp_radix_size.c +78 -0
  514. data/ext/stormlib/StormLib/src/libtommath/bn_mp_radix_smap.c +24 -0
  515. data/ext/stormlib/StormLib/src/libtommath/bn_mp_rand.c +55 -0
  516. data/ext/stormlib/StormLib/src/libtommath/bn_mp_read_radix.c +85 -0
  517. data/ext/stormlib/StormLib/src/libtommath/bn_mp_read_signed_bin.c +41 -0
  518. data/ext/stormlib/StormLib/src/libtommath/bn_mp_read_unsigned_bin.c +55 -0
  519. data/ext/stormlib/StormLib/src/libtommath/bn_mp_reduce.c +100 -0
  520. data/ext/stormlib/StormLib/src/libtommath/bn_mp_reduce_2k.c +61 -0
  521. data/ext/stormlib/StormLib/src/libtommath/bn_mp_reduce_2k_l.c +62 -0
  522. data/ext/stormlib/StormLib/src/libtommath/bn_mp_reduce_2k_setup.c +47 -0
  523. data/ext/stormlib/StormLib/src/libtommath/bn_mp_reduce_2k_setup_l.c +44 -0
  524. data/ext/stormlib/StormLib/src/libtommath/bn_mp_reduce_is_2k.c +52 -0
  525. data/ext/stormlib/StormLib/src/libtommath/bn_mp_reduce_is_2k_l.c +44 -0
  526. data/ext/stormlib/StormLib/src/libtommath/bn_mp_reduce_setup.c +34 -0
  527. data/ext/stormlib/StormLib/src/libtommath/bn_mp_rshd.c +72 -0
  528. data/ext/stormlib/StormLib/src/libtommath/bn_mp_set.c +29 -0
  529. data/ext/stormlib/StormLib/src/libtommath/bn_mp_set_int.c +48 -0
  530. data/ext/stormlib/StormLib/src/libtommath/bn_mp_shrink.c +35 -0
  531. data/ext/stormlib/StormLib/src/libtommath/bn_mp_signed_bin_size.c +27 -0
  532. data/ext/stormlib/StormLib/src/libtommath/bn_mp_sqr.c +58 -0
  533. data/ext/stormlib/StormLib/src/libtommath/bn_mp_sqrmod.c +41 -0
  534. data/ext/stormlib/StormLib/src/libtommath/bn_mp_sqrt.c +81 -0
  535. data/ext/stormlib/StormLib/src/libtommath/bn_mp_sub.c +59 -0
  536. data/ext/stormlib/StormLib/src/libtommath/bn_mp_sub_d.c +93 -0
  537. data/ext/stormlib/StormLib/src/libtommath/bn_mp_submod.c +42 -0
  538. data/ext/stormlib/StormLib/src/libtommath/bn_mp_to_signed_bin.c +33 -0
  539. data/ext/stormlib/StormLib/src/libtommath/bn_mp_to_signed_bin_n.c +31 -0
  540. data/ext/stormlib/StormLib/src/libtommath/bn_mp_to_unsigned_bin.c +48 -0
  541. data/ext/stormlib/StormLib/src/libtommath/bn_mp_to_unsigned_bin_n.c +31 -0
  542. data/ext/stormlib/StormLib/src/libtommath/bn_mp_toom_mul.c +284 -0
  543. data/ext/stormlib/StormLib/src/libtommath/bn_mp_toom_sqr.c +226 -0
  544. data/ext/stormlib/StormLib/src/libtommath/bn_mp_toradix.c +75 -0
  545. data/ext/stormlib/StormLib/src/libtommath/bn_mp_toradix_n.c +88 -0
  546. data/ext/stormlib/StormLib/src/libtommath/bn_mp_unsigned_bin_size.c +28 -0
  547. data/ext/stormlib/StormLib/src/libtommath/bn_mp_xor.c +51 -0
  548. data/ext/stormlib/StormLib/src/libtommath/bn_mp_zero.c +36 -0
  549. data/ext/stormlib/StormLib/src/libtommath/bn_prime_tab.c +61 -0
  550. data/ext/stormlib/StormLib/src/libtommath/bn_reverse.c +39 -0
  551. data/ext/stormlib/StormLib/src/libtommath/bn_s_mp_add.c +109 -0
  552. data/ext/stormlib/StormLib/src/libtommath/bn_s_mp_exptmod.c +252 -0
  553. data/ext/stormlib/StormLib/src/libtommath/bn_s_mp_mul_digs.c +90 -0
  554. data/ext/stormlib/StormLib/src/libtommath/bn_s_mp_mul_high_digs.c +81 -0
  555. data/ext/stormlib/StormLib/src/libtommath/bn_s_mp_sqr.c +84 -0
  556. data/ext/stormlib/StormLib/src/libtommath/bn_s_mp_sub.c +89 -0
  557. data/ext/stormlib/StormLib/src/libtommath/bncore.c +36 -0
  558. data/ext/stormlib/StormLib/src/libtommath/tommath.h +584 -0
  559. data/ext/stormlib/StormLib/src/libtommath/tommath_class.h +999 -0
  560. data/ext/stormlib/StormLib/src/libtommath/tommath_superclass.h +76 -0
  561. data/ext/stormlib/StormLib/src/lzma/C/LzFind.c +761 -0
  562. data/ext/stormlib/StormLib/src/lzma/C/LzFind.h +115 -0
  563. data/ext/stormlib/StormLib/src/lzma/C/LzFindMt.c +793 -0
  564. data/ext/stormlib/StormLib/src/lzma/C/LzFindMt.h +105 -0
  565. data/ext/stormlib/StormLib/src/lzma/C/LzHash.h +54 -0
  566. data/ext/stormlib/StormLib/src/lzma/C/LzmaDec.c +999 -0
  567. data/ext/stormlib/StormLib/src/lzma/C/LzmaDec.h +231 -0
  568. data/ext/stormlib/StormLib/src/lzma/C/LzmaEnc.c +2268 -0
  569. data/ext/stormlib/StormLib/src/lzma/C/LzmaEnc.h +80 -0
  570. data/ext/stormlib/StormLib/src/lzma/C/Threads.c +84 -0
  571. data/ext/stormlib/StormLib/src/lzma/C/Threads.h +59 -0
  572. data/ext/stormlib/StormLib/src/lzma/C/Types.h +236 -0
  573. data/ext/stormlib/StormLib/src/lzma/info.txt +1 -0
  574. data/ext/stormlib/StormLib/src/pklib/crc32.c +66 -0
  575. data/ext/stormlib/StormLib/src/pklib/explode.c +521 -0
  576. data/ext/stormlib/StormLib/src/pklib/implode.c +674 -0
  577. data/ext/stormlib/StormLib/src/pklib/pklib.h +160 -0
  578. data/ext/stormlib/StormLib/src/resource.h +15 -0
  579. data/ext/stormlib/StormLib/src/sparse/sparse.cpp +287 -0
  580. data/ext/stormlib/StormLib/src/sparse/sparse.h +17 -0
  581. data/ext/stormlib/StormLib/src/wdk/sources-cpp.cpp +26 -0
  582. data/ext/stormlib/StormLib/src/wdk/sources-wdk-bzip2.c +13 -0
  583. data/ext/stormlib/StormLib/src/wdk/sources-wdk-ltc.c +4 -0
  584. data/ext/stormlib/StormLib/src/wdk/sources-wdk-lzma.c +8 -0
  585. data/ext/stormlib/StormLib/src/wdk/sources-wdk-misc.c +6 -0
  586. data/ext/stormlib/StormLib/src/wdk/sources-wdk-tomcrypt.c +82 -0
  587. data/ext/stormlib/StormLib/src/wdk/sources-wdk-tommath.c +123 -0
  588. data/ext/stormlib/StormLib/src/wdk/sources-wdk-zlib.c +21 -0
  589. data/ext/stormlib/StormLib/src/zlib/adler32.c +169 -0
  590. data/ext/stormlib/StormLib/src/zlib/compress.c +80 -0
  591. data/ext/stormlib/StormLib/src/zlib/compress_zlib.c +5 -0
  592. data/ext/stormlib/StormLib/src/zlib/crc32.c +442 -0
  593. data/ext/stormlib/StormLib/src/zlib/crc32.h +441 -0
  594. data/ext/stormlib/StormLib/src/zlib/deflate.c +1834 -0
  595. data/ext/stormlib/StormLib/src/zlib/deflate.h +342 -0
  596. data/ext/stormlib/StormLib/src/zlib/gzguts.h +218 -0
  597. data/ext/stormlib/StormLib/src/zlib/inffast.c +340 -0
  598. data/ext/stormlib/StormLib/src/zlib/inffast.h +11 -0
  599. data/ext/stormlib/StormLib/src/zlib/inffixed.h +94 -0
  600. data/ext/stormlib/StormLib/src/zlib/inflate.c +1480 -0
  601. data/ext/stormlib/StormLib/src/zlib/inflate.h +130 -0
  602. data/ext/stormlib/StormLib/src/zlib/inftrees.c +330 -0
  603. data/ext/stormlib/StormLib/src/zlib/inftrees.h +67 -0
  604. data/ext/stormlib/StormLib/src/zlib/trees.c +1244 -0
  605. data/ext/stormlib/StormLib/src/zlib/trees.h +128 -0
  606. data/ext/stormlib/StormLib/src/zlib/zconf.h +428 -0
  607. data/ext/stormlib/StormLib/src/zlib/zlib.h +1613 -0
  608. data/ext/stormlib/StormLib/src/zlib/zutil.c +318 -0
  609. data/ext/stormlib/StormLib/src/zlib/zutil.h +274 -0
  610. data/ext/stormlib/StormLib/storm_dll/storm.cpp +117 -0
  611. data/ext/stormlib/StormLib/storm_dll/storm.def +25 -0
  612. data/ext/stormlib/StormLib/storm_dll/storm.h +65 -0
  613. data/ext/stormlib/StormLib/storm_dll/storm.vcxproj +209 -0
  614. data/ext/stormlib/StormLib/storm_dll/storm.vcxproj.filters +28 -0
  615. data/ext/stormlib/StormLib/storm_dll/storm_test.cpp +182 -0
  616. data/ext/stormlib/StormLib/storm_dll/storm_test.vcxproj +202 -0
  617. data/ext/stormlib/StormLib/storm_dll/storm_test.vcxproj.filters +22 -0
  618. data/ext/stormlib/StormLib/test/StormTest.cpp +4393 -0
  619. data/ext/stormlib/StormLib/test/TLogHelper.cpp +567 -0
  620. data/ext/stormlib/StormLib/test/stormlib-test-001.txt +164 -0
  621. data/ext/stormlib/extconf.rb +0 -2
  622. data/lib/stormlib/version.rb +1 -1
  623. data/stormlib.gemspec +1 -1
  624. metadata +621 -2
@@ -0,0 +1,2928 @@
1
+ /*****************************************************************************/
2
+ /* FileStream.cpp Copyright (c) Ladislav Zezula 2010 */
3
+ /*---------------------------------------------------------------------------*/
4
+ /* File stream support for StormLib */
5
+ /* */
6
+ /* Windows support: Written by Ladislav Zezula */
7
+ /* Mac support: Written by Sam Wilkins */
8
+ /* Linux support: Written by Sam Wilkins and Ivan Komissarov */
9
+ /* Big-endian: Written & debugged by Sam Wilkins */
10
+ /*---------------------------------------------------------------------------*/
11
+ /* Date Ver Who Comment */
12
+ /* -------- ---- --- ------- */
13
+ /* 11.06.10 1.00 Lad Derived from StormPortMac.cpp and StormPortLinux.cpp */
14
+ /*****************************************************************************/
15
+
16
+ #define __STORMLIB_SELF__
17
+ #include "StormLib.h"
18
+ #include "StormCommon.h"
19
+ #include "FileStream.h"
20
+
21
+ #ifdef _MSC_VER
22
+ #pragma comment(lib, "wininet.lib") // Internet functions for HTTP stream
23
+ #pragma warning(disable: 4800) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
24
+ #endif
25
+
26
+ //-----------------------------------------------------------------------------
27
+ // Local defines
28
+
29
+ #ifndef INVALID_HANDLE_VALUE
30
+ #define INVALID_HANDLE_VALUE ((HANDLE)-1)
31
+ #endif
32
+
33
+ //-----------------------------------------------------------------------------
34
+ // Local functions - platform-specific functions
35
+
36
+ #ifndef STORMLIB_WINDOWS
37
+
38
+ #ifndef STORMLIB_WIIU
39
+ static thread_local DWORD dwLastError = ERROR_SUCCESS;
40
+ #else
41
+ static DWORD dwLastError = ERROR_SUCCESS;
42
+ #endif
43
+
44
+ DWORD GetLastError()
45
+ {
46
+ return dwLastError;
47
+ }
48
+
49
+ void SetLastError(DWORD dwErrCode)
50
+ {
51
+ dwLastError = dwErrCode;
52
+ }
53
+ #endif
54
+
55
+ static DWORD StringToInt(const char * szString)
56
+ {
57
+ DWORD dwValue = 0;
58
+
59
+ while('0' <= szString[0] && szString[0] <= '9')
60
+ {
61
+ dwValue = (dwValue * 10) + (szString[0] - '0');
62
+ szString++;
63
+ }
64
+
65
+ return dwValue;
66
+ }
67
+
68
+ static void CreateNameWithSuffix(LPTSTR szBuffer, size_t cchMaxChars, LPCTSTR szName, unsigned int nValue)
69
+ {
70
+ LPTSTR szBufferEnd = szBuffer + cchMaxChars - 1;
71
+
72
+ // Copy the name
73
+ while(szBuffer < szBufferEnd && szName[0] != 0)
74
+ *szBuffer++ = *szName++;
75
+
76
+ // Append "."
77
+ if(szBuffer < szBufferEnd)
78
+ *szBuffer++ = '.';
79
+
80
+ // Append the number
81
+ IntToString(szBuffer, szBufferEnd - szBuffer + 1, nValue);
82
+ }
83
+
84
+ //-----------------------------------------------------------------------------
85
+ // Dummy init function
86
+
87
+ static void BaseNone_Init(TFileStream *)
88
+ {
89
+ // Nothing here
90
+ }
91
+
92
+ //-----------------------------------------------------------------------------
93
+ // Local functions - base file support
94
+
95
+ static bool BaseFile_Create(TFileStream * pStream)
96
+ {
97
+ #ifdef STORMLIB_WINDOWS
98
+ {
99
+ DWORD dwWriteShare = (pStream->dwFlags & STREAM_FLAG_WRITE_SHARE) ? FILE_SHARE_WRITE : 0;
100
+
101
+ pStream->Base.File.hFile = CreateFile(pStream->szFileName,
102
+ GENERIC_READ | GENERIC_WRITE,
103
+ dwWriteShare | FILE_SHARE_READ,
104
+ NULL,
105
+ CREATE_ALWAYS,
106
+ 0,
107
+ NULL);
108
+ if(pStream->Base.File.hFile == INVALID_HANDLE_VALUE)
109
+ return false;
110
+ }
111
+ #endif
112
+
113
+ #if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX)
114
+ {
115
+ intptr_t handle;
116
+
117
+ handle = open(pStream->szFileName, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
118
+ if(handle == -1)
119
+ {
120
+ pStream->Base.File.hFile = INVALID_HANDLE_VALUE;
121
+ dwLastError = errno;
122
+ return false;
123
+ }
124
+
125
+ pStream->Base.File.hFile = (HANDLE)handle;
126
+ }
127
+ #endif
128
+
129
+ // Reset the file size and position
130
+ pStream->Base.File.FileSize = 0;
131
+ pStream->Base.File.FilePos = 0;
132
+ return true;
133
+ }
134
+
135
+ static bool BaseFile_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD dwStreamFlags)
136
+ {
137
+ #ifdef STORMLIB_WINDOWS
138
+ {
139
+ ULARGE_INTEGER FileSize;
140
+ DWORD dwWriteAccess = (dwStreamFlags & STREAM_FLAG_READ_ONLY) ? 0 : FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES;
141
+ DWORD dwWriteShare = (dwStreamFlags & STREAM_FLAG_WRITE_SHARE) ? FILE_SHARE_WRITE : 0;
142
+
143
+ // Open the file
144
+ pStream->Base.File.hFile = CreateFile(szFileName,
145
+ FILE_READ_DATA | FILE_READ_ATTRIBUTES | dwWriteAccess,
146
+ FILE_SHARE_READ | dwWriteShare,
147
+ NULL,
148
+ OPEN_EXISTING,
149
+ 0,
150
+ NULL);
151
+ if(pStream->Base.File.hFile == INVALID_HANDLE_VALUE)
152
+ return false;
153
+
154
+ // Query the file size
155
+ FileSize.LowPart = GetFileSize(pStream->Base.File.hFile, &FileSize.HighPart);
156
+ pStream->Base.File.FileSize = FileSize.QuadPart;
157
+
158
+ // Query last write time
159
+ GetFileTime(pStream->Base.File.hFile, NULL, NULL, (LPFILETIME)&pStream->Base.File.FileTime);
160
+ }
161
+ #endif
162
+
163
+ #if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX)
164
+ {
165
+ struct stat64 fileinfo;
166
+ int oflag = (dwStreamFlags & STREAM_FLAG_READ_ONLY) ? O_RDONLY : O_RDWR;
167
+ intptr_t handle;
168
+
169
+ // Open the file
170
+ handle = open(szFileName, oflag | O_LARGEFILE);
171
+ if(handle == -1)
172
+ {
173
+ pStream->Base.File.hFile = INVALID_HANDLE_VALUE;
174
+ dwLastError = errno;
175
+ return false;
176
+ }
177
+
178
+ // Get the file size
179
+ if(fstat64(handle, &fileinfo) == -1)
180
+ {
181
+ pStream->Base.File.hFile = INVALID_HANDLE_VALUE;
182
+ dwLastError = errno;
183
+ close(handle);
184
+ return false;
185
+ }
186
+
187
+ // time_t is number of seconds since 1.1.1970, UTC.
188
+ // 1 second = 10000000 (decimal) in FILETIME
189
+ // Set the start to 1.1.1970 00:00:00
190
+ pStream->Base.File.FileTime = 0x019DB1DED53E8000ULL + (10000000 * fileinfo.st_mtime);
191
+ pStream->Base.File.FileSize = (ULONGLONG)fileinfo.st_size;
192
+ pStream->Base.File.hFile = (HANDLE)handle;
193
+ }
194
+ #endif
195
+
196
+ // Reset the file position
197
+ pStream->Base.File.FilePos = 0;
198
+ return true;
199
+ }
200
+
201
+ static bool BaseFile_Read(
202
+ TFileStream * pStream, // Pointer to an open stream
203
+ ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position
204
+ void * pvBuffer, // Pointer to data to be read
205
+ DWORD dwBytesToRead) // Number of bytes to read from the file
206
+ {
207
+ ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos;
208
+ DWORD dwBytesRead = 0; // Must be set by platform-specific code
209
+
210
+ #ifdef STORMLIB_WINDOWS
211
+ {
212
+ // Note: StormLib no longer supports Windows 9x.
213
+ // Thus, we can use the OVERLAPPED structure to specify
214
+ // file offset to read from file. This allows us to skip
215
+ // one system call to SetFilePointer
216
+
217
+ // Update the byte offset
218
+ pStream->Base.File.FilePos = ByteOffset;
219
+
220
+ // Read the data
221
+ if(dwBytesToRead != 0)
222
+ {
223
+ OVERLAPPED Overlapped;
224
+
225
+ Overlapped.OffsetHigh = (DWORD)(ByteOffset >> 32);
226
+ Overlapped.Offset = (DWORD)ByteOffset;
227
+ Overlapped.hEvent = NULL;
228
+ if(!ReadFile(pStream->Base.File.hFile, pvBuffer, dwBytesToRead, &dwBytesRead, &Overlapped))
229
+ return false;
230
+ }
231
+ }
232
+ #endif
233
+
234
+ #if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX)
235
+ {
236
+ ssize_t bytes_read;
237
+
238
+ // If the byte offset is different from the current file position,
239
+ // we have to update the file position xxx
240
+ if(ByteOffset != pStream->Base.File.FilePos)
241
+ {
242
+ lseek64((intptr_t)pStream->Base.File.hFile, (off64_t)(ByteOffset), SEEK_SET);
243
+ pStream->Base.File.FilePos = ByteOffset;
244
+ }
245
+
246
+ // Perform the read operation
247
+ if(dwBytesToRead != 0)
248
+ {
249
+ bytes_read = read((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToRead);
250
+ if(bytes_read == -1)
251
+ {
252
+ dwLastError = errno;
253
+ return false;
254
+ }
255
+
256
+ dwBytesRead = (DWORD)(size_t)bytes_read;
257
+ }
258
+ }
259
+ #endif
260
+
261
+ // Increment the current file position by number of bytes read
262
+ // If the number of bytes read doesn't match to required amount, return false
263
+ pStream->Base.File.FilePos = ByteOffset + dwBytesRead;
264
+ if(dwBytesRead != dwBytesToRead)
265
+ SetLastError(ERROR_HANDLE_EOF);
266
+ return (dwBytesRead == dwBytesToRead);
267
+ }
268
+
269
+ /**
270
+ * \a pStream Pointer to an open stream
271
+ * \a pByteOffset Pointer to file byte offset. If NULL, writes to current position
272
+ * \a pvBuffer Pointer to data to be written
273
+ * \a dwBytesToWrite Number of bytes to write to the file
274
+ */
275
+
276
+ static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite)
277
+ {
278
+ ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos;
279
+ DWORD dwBytesWritten = 0; // Must be set by platform-specific code
280
+
281
+ #ifdef STORMLIB_WINDOWS
282
+ {
283
+ // Note: StormLib no longer supports Windows 9x.
284
+ // Thus, we can use the OVERLAPPED structure to specify
285
+ // file offset to read from file. This allows us to skip
286
+ // one system call to SetFilePointer
287
+
288
+ // Update the byte offset
289
+ pStream->Base.File.FilePos = ByteOffset;
290
+
291
+ // Read the data
292
+ if(dwBytesToWrite != 0)
293
+ {
294
+ OVERLAPPED Overlapped;
295
+
296
+ Overlapped.OffsetHigh = (DWORD)(ByteOffset >> 32);
297
+ Overlapped.Offset = (DWORD)ByteOffset;
298
+ Overlapped.hEvent = NULL;
299
+ if(!WriteFile(pStream->Base.File.hFile, pvBuffer, dwBytesToWrite, &dwBytesWritten, &Overlapped))
300
+ return false;
301
+ }
302
+ }
303
+ #endif
304
+
305
+ #if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX)
306
+ {
307
+ ssize_t bytes_written;
308
+
309
+ // If the byte offset is different from the current file position,
310
+ // we have to update the file position
311
+ if(ByteOffset != pStream->Base.File.FilePos)
312
+ {
313
+ lseek64((intptr_t)pStream->Base.File.hFile, (off64_t)(ByteOffset), SEEK_SET);
314
+ pStream->Base.File.FilePos = ByteOffset;
315
+ }
316
+
317
+ // Perform the read operation
318
+ bytes_written = write((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToWrite);
319
+ if(bytes_written == -1)
320
+ {
321
+ dwLastError = errno;
322
+ return false;
323
+ }
324
+
325
+ dwBytesWritten = (DWORD)(size_t)bytes_written;
326
+ }
327
+ #endif
328
+
329
+ // Increment the current file position by number of bytes read
330
+ pStream->Base.File.FilePos = ByteOffset + dwBytesWritten;
331
+
332
+ // Also modify the file size, if needed
333
+ if(pStream->Base.File.FilePos > pStream->Base.File.FileSize)
334
+ pStream->Base.File.FileSize = pStream->Base.File.FilePos;
335
+
336
+ if(dwBytesWritten != dwBytesToWrite)
337
+ SetLastError(ERROR_DISK_FULL);
338
+ return (dwBytesWritten == dwBytesToWrite);
339
+ }
340
+
341
+ /**
342
+ * \a pStream Pointer to an open stream
343
+ * \a NewFileSize New size of the file
344
+ */
345
+ static bool BaseFile_Resize(TFileStream * pStream, ULONGLONG NewFileSize)
346
+ {
347
+ #ifdef STORMLIB_WINDOWS
348
+ {
349
+ LONG FileSizeHi = (LONG)(NewFileSize >> 32);
350
+ LONG FileSizeLo;
351
+ DWORD dwNewPos;
352
+ bool bResult;
353
+
354
+ // Set the position at the new file size
355
+ dwNewPos = SetFilePointer(pStream->Base.File.hFile, (LONG)NewFileSize, &FileSizeHi, FILE_BEGIN);
356
+ if(dwNewPos == INVALID_SET_FILE_POINTER && GetLastError() != ERROR_SUCCESS)
357
+ return false;
358
+
359
+ // Set the current file pointer as the end of the file
360
+ bResult = (bool)SetEndOfFile(pStream->Base.File.hFile);
361
+ if(bResult)
362
+ pStream->Base.File.FileSize = NewFileSize;
363
+
364
+ // Restore the file position
365
+ FileSizeHi = (LONG)(pStream->Base.File.FilePos >> 32);
366
+ FileSizeLo = (LONG)(pStream->Base.File.FilePos);
367
+ SetFilePointer(pStream->Base.File.hFile, FileSizeLo, &FileSizeHi, FILE_BEGIN);
368
+ return bResult;
369
+ }
370
+ #endif
371
+
372
+ #if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX)
373
+ {
374
+ if(ftruncate64((intptr_t)pStream->Base.File.hFile, (off64_t)NewFileSize) == -1)
375
+ {
376
+ dwLastError = errno;
377
+ return false;
378
+ }
379
+
380
+ pStream->Base.File.FileSize = NewFileSize;
381
+ return true;
382
+ }
383
+ #endif
384
+ }
385
+
386
+ // Gives the current file size
387
+ static bool BaseFile_GetSize(TFileStream * pStream, ULONGLONG * pFileSize)
388
+ {
389
+ // Note: Used by all thre base providers.
390
+ // Requires the TBaseData union to have the same layout for all three base providers
391
+ *pFileSize = pStream->Base.File.FileSize;
392
+ return true;
393
+ }
394
+
395
+ // Gives the current file position
396
+ static bool BaseFile_GetPos(TFileStream * pStream, ULONGLONG * pByteOffset)
397
+ {
398
+ // Note: Used by all thre base providers.
399
+ // Requires the TBaseData union to have the same layout for all three base providers
400
+ *pByteOffset = pStream->Base.File.FilePos;
401
+ return true;
402
+ }
403
+
404
+ // Renames the file pointed by pStream so that it contains data from pNewStream
405
+ static bool BaseFile_Replace(TFileStream * pStream, TFileStream * pNewStream)
406
+ {
407
+ #ifdef STORMLIB_WINDOWS
408
+ // Delete the original stream file. Don't check the result value,
409
+ // because if the file doesn't exist, it would fail
410
+ DeleteFile(pStream->szFileName);
411
+
412
+ // Rename the new file to the old stream's file
413
+ return (bool)MoveFile(pNewStream->szFileName, pStream->szFileName);
414
+ #endif
415
+
416
+ #if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX)
417
+ // "rename" on Linux also works if the target file exists
418
+ if(rename(pNewStream->szFileName, pStream->szFileName) == -1)
419
+ {
420
+ dwLastError = errno;
421
+ return false;
422
+ }
423
+
424
+ return true;
425
+ #endif
426
+ }
427
+
428
+ static void BaseFile_Close(TFileStream * pStream)
429
+ {
430
+ if(pStream->Base.File.hFile != INVALID_HANDLE_VALUE)
431
+ {
432
+ #ifdef STORMLIB_WINDOWS
433
+ CloseHandle(pStream->Base.File.hFile);
434
+ #endif
435
+
436
+ #if defined(STORMLIB_MAC) || defined(STORMLIB_LINUX)
437
+ close((intptr_t)pStream->Base.File.hFile);
438
+ #endif
439
+ }
440
+
441
+ // Also invalidate the handle
442
+ pStream->Base.File.hFile = INVALID_HANDLE_VALUE;
443
+ }
444
+
445
+ // Initializes base functions for the disk file
446
+ static void BaseFile_Init(TFileStream * pStream)
447
+ {
448
+ pStream->BaseCreate = BaseFile_Create;
449
+ pStream->BaseOpen = BaseFile_Open;
450
+ pStream->BaseRead = BaseFile_Read;
451
+ pStream->BaseWrite = BaseFile_Write;
452
+ pStream->BaseResize = BaseFile_Resize;
453
+ pStream->BaseGetSize = BaseFile_GetSize;
454
+ pStream->BaseGetPos = BaseFile_GetPos;
455
+ pStream->BaseClose = BaseFile_Close;
456
+ }
457
+
458
+ //-----------------------------------------------------------------------------
459
+ // Local functions - base memory-mapped file support
460
+
461
+ #ifdef STORMLIB_WINDOWS
462
+
463
+ typedef struct _SECTION_BASIC_INFORMATION
464
+ {
465
+ PVOID BaseAddress;
466
+ ULONG Attributes;
467
+ LARGE_INTEGER Size;
468
+ } SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION;
469
+
470
+ typedef ULONG (WINAPI * NTQUERYSECTION)(
471
+ IN HANDLE SectionHandle,
472
+ IN ULONG SectionInformationClass,
473
+ OUT PVOID SectionInformation,
474
+ IN SIZE_T Length,
475
+ OUT PSIZE_T ResultLength);
476
+
477
+ static bool RetrieveFileMappingSize(HANDLE hSection, ULARGE_INTEGER & RefFileSize)
478
+ {
479
+ SECTION_BASIC_INFORMATION BasicInfo = {0};
480
+ NTQUERYSECTION PfnQuerySection;
481
+ HMODULE hNtdll;
482
+ SIZE_T ReturnLength = 0;
483
+
484
+ if((hNtdll = GetModuleHandle(_T("ntdll.dll"))) != NULL)
485
+ {
486
+ PfnQuerySection = (NTQUERYSECTION)GetProcAddress(hNtdll, "NtQuerySection");
487
+ if(PfnQuerySection != NULL)
488
+ {
489
+ if(PfnQuerySection(hSection, 0, &BasicInfo, sizeof(SECTION_BASIC_INFORMATION), &ReturnLength) == 0)
490
+ {
491
+ RefFileSize.HighPart = BasicInfo.Size.HighPart;
492
+ RefFileSize.LowPart = BasicInfo.Size.LowPart;
493
+ return true;
494
+ }
495
+ }
496
+ }
497
+
498
+ return false;
499
+ }
500
+ #endif
501
+
502
+ static bool BaseMap_Open(TFileStream * pStream, LPCTSTR szFileName, DWORD dwStreamFlags)
503
+ {
504
+ #ifdef STORMLIB_WINDOWS
505
+
506
+ ULARGE_INTEGER FileSize = {0};
507
+ HANDLE hFile = INVALID_HANDLE_VALUE;
508
+ HANDLE hMap = NULL;
509
+ bool bResult = false;
510
+
511
+ // Keep compilers happy
512
+ STORMLIB_UNUSED(dwStreamFlags);
513
+
514
+ // 1) Try to treat "szFileName" as a section name
515
+ hMap = OpenFileMapping(SECTION_QUERY | FILE_MAP_READ, FALSE, szFileName);
516
+ if(hMap != NULL)
517
+ {
518
+ // Try to retrieve the size of the mapping
519
+ if(!RetrieveFileMappingSize(hMap, FileSize))
520
+ {
521
+ CloseHandle(hMap);
522
+ hMap = NULL;
523
+ }
524
+ }
525
+
526
+ // 2) Treat the name as file name
527
+ else
528
+ {
529
+ hFile = CreateFile(szFileName, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
530
+ if(hFile != INVALID_HANDLE_VALUE)
531
+ {
532
+ // Retrieve file size. Don't allow mapping file of a zero size.
533
+ FileSize.LowPart = GetFileSize(hFile, &FileSize.HighPart);
534
+ if(FileSize.QuadPart != 0)
535
+ {
536
+ // Now create file mapping over the file
537
+ hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
538
+ }
539
+ }
540
+ }
541
+
542
+ // Did it succeed?
543
+ if(hMap != NULL)
544
+ {
545
+ // Map the entire view into memory
546
+ // Note that this operation will fail if the file can't fit
547
+ // into usermode address space
548
+ pStream->Base.Map.pbFile = (LPBYTE)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
549
+ if(pStream->Base.Map.pbFile != NULL)
550
+ {
551
+ // Retrieve file time. If it's named section, put 0
552
+ if(hFile != INVALID_HANDLE_VALUE)
553
+ GetFileTime(hFile, NULL, NULL, (LPFILETIME)&pStream->Base.Map.FileTime);
554
+
555
+ // Retrieve file size and position
556
+ pStream->Base.Map.FileSize = FileSize.QuadPart;
557
+ pStream->Base.Map.FilePos = 0;
558
+ bResult = true;
559
+ }
560
+
561
+ // Close the map handle
562
+ CloseHandle(hMap);
563
+ }
564
+
565
+ // Close the file handle
566
+ if(hFile != INVALID_HANDLE_VALUE)
567
+ CloseHandle(hFile);
568
+
569
+ // Return the result of the operation
570
+ return bResult;
571
+
572
+ #elif defined(STORMLIB_HAS_MMAP)
573
+
574
+ struct stat64 fileinfo;
575
+ intptr_t handle;
576
+ bool bResult = false;
577
+
578
+ // Open the file
579
+ handle = open(szFileName, O_RDONLY);
580
+ if(handle != -1)
581
+ {
582
+ // Get the file size
583
+ if(fstat64(handle, &fileinfo) != -1)
584
+ {
585
+ pStream->Base.Map.pbFile = (LPBYTE)mmap(NULL, (size_t)fileinfo.st_size, PROT_READ, MAP_PRIVATE, handle, 0);
586
+ if(pStream->Base.Map.pbFile != NULL)
587
+ {
588
+ // time_t is number of seconds since 1.1.1970, UTC.
589
+ // 1 second = 10000000 (decimal) in FILETIME
590
+ // Set the start to 1.1.1970 00:00:00
591
+ pStream->Base.Map.FileTime = 0x019DB1DED53E8000ULL + (10000000 * fileinfo.st_mtime);
592
+ pStream->Base.Map.FileSize = (ULONGLONG)fileinfo.st_size;
593
+ pStream->Base.Map.FilePos = 0;
594
+ bResult = true;
595
+ }
596
+ }
597
+ close(handle);
598
+ }
599
+
600
+ // Did the mapping fail?
601
+ if(bResult == false)
602
+ dwLastError = errno;
603
+ return bResult;
604
+
605
+ #else
606
+
607
+ // File mapping is not supported
608
+ return false;
609
+
610
+ #endif
611
+ }
612
+
613
+ static bool BaseMap_Read(
614
+ TFileStream * pStream, // Pointer to an open stream
615
+ ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position
616
+ void * pvBuffer, // Pointer to data to be read
617
+ DWORD dwBytesToRead) // Number of bytes to read from the file
618
+ {
619
+ ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.Map.FilePos;
620
+
621
+ // Do we have to read anything at all?
622
+ if(dwBytesToRead != 0)
623
+ {
624
+ // Don't allow reading past file size
625
+ if((ByteOffset + dwBytesToRead) > pStream->Base.Map.FileSize)
626
+ return false;
627
+
628
+ // Copy the required data
629
+ memcpy(pvBuffer, pStream->Base.Map.pbFile + (size_t)ByteOffset, dwBytesToRead);
630
+ }
631
+
632
+ // Move the current file position
633
+ pStream->Base.Map.FilePos += dwBytesToRead;
634
+ return true;
635
+ }
636
+
637
+ static void BaseMap_Close(TFileStream * pStream)
638
+ {
639
+
640
+ #ifdef STORMLIB_WINDOWS
641
+
642
+ if(pStream->Base.Map.pbFile != NULL)
643
+ UnmapViewOfFile(pStream->Base.Map.pbFile);
644
+
645
+ #elif defined(STORMLIB_HAS_MMAP)
646
+
647
+ if(pStream->Base.Map.pbFile != NULL)
648
+ munmap(pStream->Base.Map.pbFile, (size_t )pStream->Base.Map.FileSize);
649
+
650
+ #endif
651
+
652
+ pStream->Base.Map.pbFile = NULL;
653
+ }
654
+
655
+ // Initializes base functions for the mapped file
656
+ static void BaseMap_Init(TFileStream * pStream)
657
+ {
658
+ // Supply the file stream functions
659
+ pStream->BaseOpen = BaseMap_Open;
660
+ pStream->BaseRead = BaseMap_Read;
661
+ pStream->BaseGetSize = BaseFile_GetSize; // Reuse BaseFile function
662
+ pStream->BaseGetPos = BaseFile_GetPos; // Reuse BaseFile function
663
+ pStream->BaseClose = BaseMap_Close;
664
+
665
+ // Mapped files are read-only
666
+ pStream->dwFlags |= STREAM_FLAG_READ_ONLY;
667
+ }
668
+
669
+ //-----------------------------------------------------------------------------
670
+ // Local functions - base HTTP file support
671
+
672
+ static const TCHAR * BaseHttp_ExtractServerName(const TCHAR * szFileName, TCHAR * szServerName)
673
+ {
674
+ // Check for HTTP
675
+ if(!_tcsnicmp(szFileName, _T("http://"), 7))
676
+ szFileName += 7;
677
+
678
+ // Cut off the server name
679
+ if(szServerName != NULL)
680
+ {
681
+ while(szFileName[0] != 0 && szFileName[0] != _T('/'))
682
+ *szServerName++ = *szFileName++;
683
+ *szServerName = 0;
684
+ }
685
+ else
686
+ {
687
+ while(szFileName[0] != 0 && szFileName[0] != _T('/'))
688
+ szFileName++;
689
+ }
690
+
691
+ // Return the remainder
692
+ return szFileName;
693
+ }
694
+
695
+ static bool BaseHttp_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD dwStreamFlags)
696
+ {
697
+ #ifdef STORMLIB_WINDOWS
698
+
699
+ HINTERNET hRequest;
700
+ DWORD dwTemp = 0;
701
+
702
+ // Keep compilers happy
703
+ STORMLIB_UNUSED(dwStreamFlags);
704
+
705
+ // Don't connect to the internet
706
+ if(!InternetGetConnectedState(&dwTemp, 0))
707
+ return false;
708
+
709
+ // Initiate the connection to the internet
710
+ pStream->Base.Http.hInternet = InternetOpen(_T("StormLib HTTP MPQ reader"),
711
+ INTERNET_OPEN_TYPE_PRECONFIG,
712
+ NULL,
713
+ NULL,
714
+ 0);
715
+ if(pStream->Base.Http.hInternet != NULL)
716
+ {
717
+ TCHAR szServerName[MAX_PATH];
718
+ DWORD dwFlags = INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_UI | INTERNET_FLAG_NO_CACHE_WRITE;
719
+
720
+ // Initiate connection with the server
721
+ szFileName = BaseHttp_ExtractServerName(szFileName, szServerName);
722
+ pStream->Base.Http.hConnect = InternetConnect(pStream->Base.Http.hInternet,
723
+ szServerName,
724
+ INTERNET_DEFAULT_HTTP_PORT,
725
+ NULL,
726
+ NULL,
727
+ INTERNET_SERVICE_HTTP,
728
+ dwFlags,
729
+ 0);
730
+ if(pStream->Base.Http.hConnect != NULL)
731
+ {
732
+ // Open HTTP request to the file
733
+ hRequest = HttpOpenRequest(pStream->Base.Http.hConnect, _T("GET"), szFileName, NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
734
+ if(hRequest != NULL)
735
+ {
736
+ if(HttpSendRequest(hRequest, NULL, 0, NULL, 0))
737
+ {
738
+ ULONGLONG FileTime = 0;
739
+ DWORD dwFileSize = 0;
740
+ DWORD dwDataSize;
741
+ DWORD dwIndex = 0;
742
+ TCHAR StatusCode[0x08];
743
+
744
+ // Check if the file succeeded to open
745
+ dwDataSize = sizeof(StatusCode);
746
+ if(HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE, StatusCode, &dwDataSize, &dwIndex))
747
+ {
748
+ if(_tcscmp(StatusCode, _T("200")))
749
+ {
750
+ InternetCloseHandle(hRequest);
751
+ SetLastError(ERROR_FILE_NOT_FOUND);
752
+ return false;
753
+ }
754
+ }
755
+
756
+ // Check if the MPQ has Last Modified field
757
+ dwDataSize = sizeof(ULONGLONG);
758
+ if(HttpQueryInfo(hRequest, HTTP_QUERY_LAST_MODIFIED | HTTP_QUERY_FLAG_SYSTEMTIME, &FileTime, &dwDataSize, &dwIndex))
759
+ pStream->Base.Http.FileTime = FileTime;
760
+
761
+ // Verify if the server supports random access
762
+ dwDataSize = sizeof(DWORD);
763
+ if(HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &dwFileSize, &dwDataSize, &dwIndex))
764
+ {
765
+ if(dwFileSize != 0)
766
+ {
767
+ InternetCloseHandle(hRequest);
768
+ pStream->Base.Http.FileSize = dwFileSize;
769
+ pStream->Base.Http.FilePos = 0;
770
+ return true;
771
+ }
772
+ }
773
+ }
774
+
775
+ // Close the request
776
+ InternetCloseHandle(hRequest);
777
+ }
778
+
779
+ // Close the connection handle
780
+ InternetCloseHandle(pStream->Base.Http.hConnect);
781
+ pStream->Base.Http.hConnect = NULL;
782
+ }
783
+
784
+ // Close the internet handle
785
+ InternetCloseHandle(pStream->Base.Http.hInternet);
786
+ pStream->Base.Http.hInternet = NULL;
787
+ }
788
+
789
+ // If the file is not there or is not available for random access, report error
790
+ pStream->BaseClose(pStream);
791
+ return false;
792
+
793
+ #else
794
+
795
+ // Not supported
796
+ SetLastError(ERROR_NOT_SUPPORTED);
797
+ pStream = pStream;
798
+ return false;
799
+
800
+ #endif
801
+ }
802
+
803
+ static bool BaseHttp_Read(
804
+ TFileStream * pStream, // Pointer to an open stream
805
+ ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position
806
+ void * pvBuffer, // Pointer to data to be read
807
+ DWORD dwBytesToRead) // Number of bytes to read from the file
808
+ {
809
+ #ifdef STORMLIB_WINDOWS
810
+ ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.Http.FilePos;
811
+ DWORD dwTotalBytesRead = 0;
812
+
813
+ // Do we have to read anything at all?
814
+ if(dwBytesToRead != 0)
815
+ {
816
+ HINTERNET hRequest;
817
+ LPCTSTR szFileName;
818
+ LPBYTE pbBuffer = (LPBYTE)pvBuffer;
819
+ TCHAR szRangeRequest[0x80];
820
+ DWORD dwStartOffset = (DWORD)ByteOffset;
821
+ DWORD dwEndOffset = dwStartOffset + dwBytesToRead;
822
+
823
+ // Open HTTP request to the file
824
+ szFileName = BaseHttp_ExtractServerName(pStream->szFileName, NULL);
825
+ hRequest = HttpOpenRequest(pStream->Base.Http.hConnect, _T("GET"), szFileName, NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
826
+ if(hRequest != NULL)
827
+ {
828
+ // Add range request to the HTTP headers
829
+ // http://www.clevercomponents.com/articles/article015/resuming.asp
830
+ wsprintf(szRangeRequest, _T("Range: bytes=%u-%u"), (unsigned int)dwStartOffset, (unsigned int)dwEndOffset);
831
+ HttpAddRequestHeaders(hRequest, szRangeRequest, 0xFFFFFFFF, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
832
+
833
+ // Send the request to the server
834
+ if(HttpSendRequest(hRequest, NULL, 0, NULL, 0))
835
+ {
836
+ while(dwTotalBytesRead < dwBytesToRead)
837
+ {
838
+ DWORD dwBlockBytesToRead = dwBytesToRead - dwTotalBytesRead;
839
+ DWORD dwBlockBytesRead = 0;
840
+
841
+ // Read the block from the file
842
+ if(dwBlockBytesToRead > 0x200)
843
+ dwBlockBytesToRead = 0x200;
844
+ InternetReadFile(hRequest, pbBuffer, dwBlockBytesToRead, &dwBlockBytesRead);
845
+
846
+ // Check for end
847
+ if(dwBlockBytesRead == 0)
848
+ break;
849
+
850
+ // Move buffers
851
+ dwTotalBytesRead += dwBlockBytesRead;
852
+ pbBuffer += dwBlockBytesRead;
853
+ }
854
+ }
855
+ InternetCloseHandle(hRequest);
856
+ }
857
+ }
858
+
859
+ // Increment the current file position by number of bytes read
860
+ pStream->Base.Http.FilePos = ByteOffset + dwTotalBytesRead;
861
+
862
+ // If the number of bytes read doesn't match the required amount, return false
863
+ if(dwTotalBytesRead != dwBytesToRead)
864
+ SetLastError(ERROR_HANDLE_EOF);
865
+ return (dwTotalBytesRead == dwBytesToRead);
866
+
867
+ #else
868
+
869
+ // Not supported
870
+ pStream = pStream;
871
+ pByteOffset = pByteOffset;
872
+ pvBuffer = pvBuffer;
873
+ dwBytesToRead = dwBytesToRead;
874
+ SetLastError(ERROR_NOT_SUPPORTED);
875
+ return false;
876
+
877
+ #endif
878
+ }
879
+
880
+ static void BaseHttp_Close(TFileStream * pStream)
881
+ {
882
+ #ifdef STORMLIB_WINDOWS
883
+ if(pStream->Base.Http.hConnect != NULL)
884
+ InternetCloseHandle(pStream->Base.Http.hConnect);
885
+ pStream->Base.Http.hConnect = NULL;
886
+
887
+ if(pStream->Base.Http.hInternet != NULL)
888
+ InternetCloseHandle(pStream->Base.Http.hInternet);
889
+ pStream->Base.Http.hInternet = NULL;
890
+ #else
891
+ pStream = pStream;
892
+ #endif
893
+ }
894
+
895
+ // Initializes base functions for the mapped file
896
+ static void BaseHttp_Init(TFileStream * pStream)
897
+ {
898
+ // Supply the stream functions
899
+ pStream->BaseOpen = BaseHttp_Open;
900
+ pStream->BaseRead = BaseHttp_Read;
901
+ pStream->BaseGetSize = BaseFile_GetSize; // Reuse BaseFile function
902
+ pStream->BaseGetPos = BaseFile_GetPos; // Reuse BaseFile function
903
+ pStream->BaseClose = BaseHttp_Close;
904
+
905
+ // HTTP files are read-only
906
+ pStream->dwFlags |= STREAM_FLAG_READ_ONLY;
907
+ }
908
+
909
+ //-----------------------------------------------------------------------------
910
+ // Local functions - base block-based support
911
+
912
+ // Generic function that loads blocks from the file
913
+ // The function groups the block with the same availability,
914
+ // so the called BlockRead can finish the request in a single system call
915
+ static bool BlockStream_Read(
916
+ TBlockStream * pStream, // Pointer to an open stream
917
+ ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position
918
+ void * pvBuffer, // Pointer to data to be read
919
+ DWORD dwBytesToRead) // Number of bytes to read from the file
920
+ {
921
+ ULONGLONG BlockOffset0;
922
+ ULONGLONG BlockOffset;
923
+ ULONGLONG ByteOffset;
924
+ ULONGLONG EndOffset;
925
+ LPBYTE TransferBuffer;
926
+ LPBYTE BlockBuffer;
927
+ DWORD BlockBufferOffset; // Offset of the desired data in the block buffer
928
+ DWORD BytesNeeded; // Number of bytes that really need to be read
929
+ DWORD BlockSize = pStream->BlockSize;
930
+ DWORD BlockCount;
931
+ bool bPrevBlockAvailable;
932
+ bool bCallbackCalled = false;
933
+ bool bBlockAvailable;
934
+ bool bResult = true;
935
+
936
+ // The base block read function must be present
937
+ assert(pStream->BlockRead != NULL);
938
+
939
+ // NOP reading of zero bytes
940
+ if(dwBytesToRead == 0)
941
+ return true;
942
+
943
+ // Get the current position in the stream
944
+ ByteOffset = (pByteOffset != NULL) ? pByteOffset[0] : pStream->StreamPos;
945
+ EndOffset = ByteOffset + dwBytesToRead;
946
+ if(EndOffset > pStream->StreamSize)
947
+ {
948
+ SetLastError(ERROR_HANDLE_EOF);
949
+ return false;
950
+ }
951
+
952
+ // Calculate the block parameters
953
+ BlockOffset0 = BlockOffset = ByteOffset & ~((ULONGLONG)BlockSize - 1);
954
+ BlockCount = (DWORD)(((EndOffset - BlockOffset) + (BlockSize - 1)) / BlockSize);
955
+ BytesNeeded = (DWORD)(EndOffset - BlockOffset);
956
+
957
+ // Remember where we have our data
958
+ assert((BlockSize & (BlockSize - 1)) == 0);
959
+ BlockBufferOffset = (DWORD)(ByteOffset & (BlockSize - 1));
960
+
961
+ // Allocate buffer for reading blocks
962
+ TransferBuffer = BlockBuffer = STORM_ALLOC(BYTE, (BlockCount * BlockSize));
963
+ if(TransferBuffer == NULL)
964
+ {
965
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
966
+ return false;
967
+ }
968
+
969
+ // If all blocks are available, just read all blocks at once
970
+ if(pStream->IsComplete == 0)
971
+ {
972
+ // Now parse the blocks and send the block read request
973
+ // to all blocks with the same availability
974
+ assert(pStream->BlockCheck != NULL);
975
+ bPrevBlockAvailable = pStream->BlockCheck(pStream, BlockOffset);
976
+
977
+ // Loop as long as we have something to read
978
+ while(BlockOffset < EndOffset)
979
+ {
980
+ // Determine availability of the next block
981
+ bBlockAvailable = pStream->BlockCheck(pStream, BlockOffset);
982
+
983
+ // If the availability has changed, read all blocks up to this one
984
+ if(bBlockAvailable != bPrevBlockAvailable)
985
+ {
986
+ // Call the file stream callback, if the block is not available
987
+ if(pStream->pMaster && pStream->pfnCallback && bPrevBlockAvailable == false)
988
+ {
989
+ pStream->pfnCallback(pStream->UserData, BlockOffset0, (DWORD)(BlockOffset - BlockOffset0));
990
+ bCallbackCalled = true;
991
+ }
992
+
993
+ // Load the continuous blocks with the same availability
994
+ assert(BlockOffset > BlockOffset0);
995
+ bResult = pStream->BlockRead(pStream, BlockOffset0, BlockOffset, BlockBuffer, BytesNeeded, bPrevBlockAvailable);
996
+ if(!bResult)
997
+ break;
998
+
999
+ // Move the block offset
1000
+ BlockBuffer += (DWORD)(BlockOffset - BlockOffset0);
1001
+ BytesNeeded -= (DWORD)(BlockOffset - BlockOffset0);
1002
+ bPrevBlockAvailable = bBlockAvailable;
1003
+ BlockOffset0 = BlockOffset;
1004
+ }
1005
+
1006
+ // Move to the block offset in the stream
1007
+ BlockOffset += BlockSize;
1008
+ }
1009
+
1010
+ // If there is a block(s) remaining to be read, do it
1011
+ if(BlockOffset > BlockOffset0)
1012
+ {
1013
+ // Call the file stream callback, if the block is not available
1014
+ if(pStream->pMaster && pStream->pfnCallback && bPrevBlockAvailable == false)
1015
+ {
1016
+ pStream->pfnCallback(pStream->UserData, BlockOffset0, (DWORD)(BlockOffset - BlockOffset0));
1017
+ bCallbackCalled = true;
1018
+ }
1019
+
1020
+ // Read the complete blocks from the file
1021
+ if(BlockOffset > pStream->StreamSize)
1022
+ BlockOffset = pStream->StreamSize;
1023
+ bResult = pStream->BlockRead(pStream, BlockOffset0, BlockOffset, BlockBuffer, BytesNeeded, bPrevBlockAvailable);
1024
+ }
1025
+ }
1026
+ else
1027
+ {
1028
+ // Read the complete blocks from the file
1029
+ if(EndOffset > pStream->StreamSize)
1030
+ EndOffset = pStream->StreamSize;
1031
+ bResult = pStream->BlockRead(pStream, BlockOffset, EndOffset, BlockBuffer, BytesNeeded, true);
1032
+ }
1033
+
1034
+ // Now copy the data to the user buffer
1035
+ if(bResult)
1036
+ {
1037
+ memcpy(pvBuffer, TransferBuffer + BlockBufferOffset, dwBytesToRead);
1038
+ pStream->StreamPos = ByteOffset + dwBytesToRead;
1039
+ }
1040
+ else
1041
+ {
1042
+ // If the block read failed, set the last error
1043
+ SetLastError(ERROR_FILE_INCOMPLETE);
1044
+ }
1045
+
1046
+ // Call the callback to indicate we are done
1047
+ if(bCallbackCalled)
1048
+ pStream->pfnCallback(pStream->UserData, 0, 0);
1049
+
1050
+ // Free the block buffer and return
1051
+ STORM_FREE(TransferBuffer);
1052
+ return bResult;
1053
+ }
1054
+
1055
+ static bool BlockStream_GetSize(TFileStream * pStream, ULONGLONG * pFileSize)
1056
+ {
1057
+ *pFileSize = pStream->StreamSize;
1058
+ return true;
1059
+ }
1060
+
1061
+ static bool BlockStream_GetPos(TFileStream * pStream, ULONGLONG * pByteOffset)
1062
+ {
1063
+ *pByteOffset = pStream->StreamPos;
1064
+ return true;
1065
+ }
1066
+
1067
+ static void BlockStream_Close(TBlockStream * pStream)
1068
+ {
1069
+ // Free the data map, if any
1070
+ if(pStream->FileBitmap != NULL)
1071
+ STORM_FREE(pStream->FileBitmap);
1072
+ pStream->FileBitmap = NULL;
1073
+
1074
+ // Call the base class for closing the stream
1075
+ pStream->BaseClose(pStream);
1076
+ }
1077
+
1078
+ //-----------------------------------------------------------------------------
1079
+ // File stream allocation function
1080
+
1081
+ static STREAM_INIT StreamBaseInit[4] =
1082
+ {
1083
+ BaseFile_Init,
1084
+ BaseMap_Init,
1085
+ BaseHttp_Init,
1086
+ BaseNone_Init
1087
+ };
1088
+
1089
+ // This function allocates an empty structure for the file stream
1090
+ // The stream structure is created as flat block, variable length
1091
+ // The file name is placed after the end of the stream structure data
1092
+ static TFileStream * AllocateFileStream(
1093
+ const TCHAR * szFileName,
1094
+ size_t StreamSize,
1095
+ DWORD dwStreamFlags)
1096
+ {
1097
+ TFileStream * pMaster = NULL;
1098
+ TFileStream * pStream;
1099
+ const TCHAR * szNextFile = szFileName;
1100
+ size_t FileNameSize;
1101
+
1102
+ // Sanity check
1103
+ assert(StreamSize != 0);
1104
+
1105
+ // The caller can specify chain of files in the following form:
1106
+ // C:\archive.MPQ*http://www.server.com/MPQs/archive-server.MPQ
1107
+ // In that case, we use the part after "*" as master file name
1108
+ while(szNextFile[0] != 0 && szNextFile[0] != _T('*'))
1109
+ szNextFile++;
1110
+ FileNameSize = (size_t)((szNextFile - szFileName) * sizeof(TCHAR));
1111
+
1112
+ // If we have a next file, we need to open it as master stream
1113
+ // Note that we don't care if the master stream exists or not,
1114
+ // If it doesn't, later attempts to read missing file block will fail
1115
+ if(szNextFile[0] == _T('*'))
1116
+ {
1117
+ // Don't allow another master file in the string
1118
+ if(_tcschr(szNextFile + 1, _T('*')) != NULL)
1119
+ {
1120
+ SetLastError(ERROR_INVALID_PARAMETER);
1121
+ return NULL;
1122
+ }
1123
+
1124
+ // Open the master file
1125
+ pMaster = FileStream_OpenFile(szNextFile + 1, STREAM_FLAG_READ_ONLY);
1126
+ }
1127
+
1128
+ // Allocate the stream structure for the given stream type
1129
+ pStream = (TFileStream *)STORM_ALLOC(BYTE, StreamSize + FileNameSize + sizeof(TCHAR));
1130
+ if(pStream != NULL)
1131
+ {
1132
+ // Zero the entire structure
1133
+ memset(pStream, 0, StreamSize);
1134
+ pStream->pMaster = pMaster;
1135
+ pStream->dwFlags = dwStreamFlags;
1136
+
1137
+ // Initialize the file name
1138
+ pStream->szFileName = (TCHAR *)((BYTE *)pStream + StreamSize);
1139
+ memcpy(pStream->szFileName, szFileName, FileNameSize);
1140
+ pStream->szFileName[FileNameSize / sizeof(TCHAR)] = 0;
1141
+
1142
+ // Initialize the stream functions
1143
+ StreamBaseInit[dwStreamFlags & 0x03](pStream);
1144
+ }
1145
+
1146
+ return pStream;
1147
+ }
1148
+
1149
+ //-----------------------------------------------------------------------------
1150
+ // Local functions - flat stream support
1151
+
1152
+ static DWORD FlatStream_CheckFile(TBlockStream * pStream)
1153
+ {
1154
+ LPBYTE FileBitmap = (LPBYTE)pStream->FileBitmap;
1155
+ DWORD WholeByteCount = (pStream->BlockCount / 8);
1156
+ DWORD ExtraBitsCount = (pStream->BlockCount & 7);
1157
+ BYTE ExpectedValue;
1158
+
1159
+ // Verify the whole bytes - their value must be 0xFF
1160
+ for(DWORD i = 0; i < WholeByteCount; i++)
1161
+ {
1162
+ if(FileBitmap[i] != 0xFF)
1163
+ return 0;
1164
+ }
1165
+
1166
+ // If there are extra bits, calculate the mask
1167
+ if(ExtraBitsCount != 0)
1168
+ {
1169
+ ExpectedValue = (BYTE)((1 << ExtraBitsCount) - 1);
1170
+ if(FileBitmap[WholeByteCount] != ExpectedValue)
1171
+ return 0;
1172
+ }
1173
+
1174
+ // Yes, the file is complete
1175
+ return 1;
1176
+ }
1177
+
1178
+ static bool FlatStream_LoadBitmap(TBlockStream * pStream)
1179
+ {
1180
+ FILE_BITMAP_FOOTER Footer;
1181
+ ULONGLONG ByteOffset;
1182
+ LPBYTE FileBitmap;
1183
+ DWORD BlockCount;
1184
+ DWORD BitmapSize;
1185
+
1186
+ // Do not load the bitmap if we should not have to
1187
+ if(!(pStream->dwFlags & STREAM_FLAG_USE_BITMAP))
1188
+ return false;
1189
+
1190
+ // Only if the size is greater than size of bitmap footer
1191
+ if(pStream->Base.File.FileSize > sizeof(FILE_BITMAP_FOOTER))
1192
+ {
1193
+ // Load the bitmap footer
1194
+ ByteOffset = pStream->Base.File.FileSize - sizeof(FILE_BITMAP_FOOTER);
1195
+ if(pStream->BaseRead(pStream, &ByteOffset, &Footer, sizeof(FILE_BITMAP_FOOTER)))
1196
+ {
1197
+ // Make sure that the array is properly BSWAP-ed
1198
+ BSWAP_ARRAY32_UNSIGNED((LPDWORD)(&Footer), sizeof(FILE_BITMAP_FOOTER));
1199
+
1200
+ // Verify if there is actually a footer
1201
+ if(Footer.Signature == ID_FILE_BITMAP_FOOTER && Footer.Version == 0x03 && Footer.BlockSize != 0)
1202
+ {
1203
+ // Get the offset of the bitmap, number of blocks and size of the bitmap
1204
+ ByteOffset = MAKE_OFFSET64(Footer.MapOffsetHi, Footer.MapOffsetLo);
1205
+ BlockCount = (DWORD)(((ByteOffset - 1) / Footer.BlockSize) + 1);
1206
+ BitmapSize = ((BlockCount + 7) / 8);
1207
+
1208
+ // Check if the sizes match
1209
+ if(ByteOffset + BitmapSize + sizeof(FILE_BITMAP_FOOTER) == pStream->Base.File.FileSize)
1210
+ {
1211
+ // Allocate space for the bitmap
1212
+ FileBitmap = STORM_ALLOC(BYTE, BitmapSize);
1213
+ if(FileBitmap != NULL)
1214
+ {
1215
+ // Load the bitmap bits
1216
+ if(!pStream->BaseRead(pStream, &ByteOffset, FileBitmap, BitmapSize))
1217
+ {
1218
+ STORM_FREE(FileBitmap);
1219
+ return false;
1220
+ }
1221
+
1222
+ // Update the stream size
1223
+ pStream->BuildNumber = Footer.BuildNumber;
1224
+ pStream->StreamSize = ByteOffset;
1225
+
1226
+ // Fill the bitmap information
1227
+ pStream->FileBitmap = FileBitmap;
1228
+ pStream->BitmapSize = BitmapSize;
1229
+ pStream->BlockSize = Footer.BlockSize;
1230
+ pStream->BlockCount = BlockCount;
1231
+ pStream->IsComplete = FlatStream_CheckFile(pStream);
1232
+ return true;
1233
+ }
1234
+ }
1235
+ }
1236
+ }
1237
+ }
1238
+
1239
+ return false;
1240
+ }
1241
+
1242
+ static void FlatStream_UpdateBitmap(
1243
+ TBlockStream * pStream, // Pointer to an open stream
1244
+ ULONGLONG StartOffset,
1245
+ ULONGLONG EndOffset)
1246
+ {
1247
+ LPBYTE FileBitmap = (LPBYTE)pStream->FileBitmap;
1248
+ DWORD BlockIndex;
1249
+ DWORD BlockSize = pStream->BlockSize;
1250
+ DWORD ByteIndex;
1251
+ BYTE BitMask;
1252
+
1253
+ // Sanity checks
1254
+ assert((StartOffset & (BlockSize - 1)) == 0);
1255
+ assert(FileBitmap != NULL);
1256
+
1257
+ // Calculate the index of the block
1258
+ BlockIndex = (DWORD)(StartOffset / BlockSize);
1259
+ ByteIndex = (BlockIndex / 0x08);
1260
+ BitMask = (BYTE)(1 << (BlockIndex & 0x07));
1261
+
1262
+ // Set all bits for the specified range
1263
+ while(StartOffset < EndOffset)
1264
+ {
1265
+ // Set the bit
1266
+ FileBitmap[ByteIndex] |= BitMask;
1267
+
1268
+ // Move all
1269
+ StartOffset += BlockSize;
1270
+ ByteIndex += (BitMask >> 0x07);
1271
+ BitMask = (BitMask >> 0x07) | (BitMask << 0x01);
1272
+ }
1273
+
1274
+ // Increment the bitmap update count
1275
+ pStream->IsModified = 1;
1276
+ }
1277
+
1278
+ static bool FlatStream_BlockCheck(
1279
+ TBlockStream * pStream, // Pointer to an open stream
1280
+ ULONGLONG BlockOffset)
1281
+ {
1282
+ LPBYTE FileBitmap = (LPBYTE)pStream->FileBitmap;
1283
+ DWORD BlockIndex;
1284
+ BYTE BitMask;
1285
+
1286
+ // Sanity checks
1287
+ assert((BlockOffset & (pStream->BlockSize - 1)) == 0);
1288
+ assert(FileBitmap != NULL);
1289
+
1290
+ // Calculate the index of the block
1291
+ BlockIndex = (DWORD)(BlockOffset / pStream->BlockSize);
1292
+ BitMask = (BYTE)(1 << (BlockIndex & 0x07));
1293
+
1294
+ // Check if the bit is present
1295
+ return (FileBitmap[BlockIndex / 0x08] & BitMask) ? true : false;
1296
+ }
1297
+
1298
+ static bool FlatStream_BlockRead(
1299
+ TBlockStream * pStream, // Pointer to an open stream
1300
+ ULONGLONG StartOffset,
1301
+ ULONGLONG EndOffset,
1302
+ LPBYTE BlockBuffer,
1303
+ DWORD BytesNeeded,
1304
+ bool bAvailable)
1305
+ {
1306
+ DWORD BytesToRead = (DWORD)(EndOffset - StartOffset);
1307
+
1308
+ // The starting offset must be aligned to size of the block
1309
+ assert(pStream->FileBitmap != NULL);
1310
+ assert((StartOffset & (pStream->BlockSize - 1)) == 0);
1311
+ assert(StartOffset < EndOffset);
1312
+
1313
+ // If the blocks are not available, we need to load them from the master
1314
+ // and then save to the mirror
1315
+ if(bAvailable == false)
1316
+ {
1317
+ // If we have no master, we cannot satisfy read request
1318
+ if(pStream->pMaster == NULL)
1319
+ return false;
1320
+
1321
+ // Load the blocks from the master stream
1322
+ // Note that we always have to read complete blocks
1323
+ // so they get properly stored to the mirror stream
1324
+ if(!FileStream_Read(pStream->pMaster, &StartOffset, BlockBuffer, BytesToRead))
1325
+ return false;
1326
+
1327
+ // Store the loaded blocks to the mirror file.
1328
+ // Note that this operation is not required to succeed
1329
+ if(pStream->BaseWrite(pStream, &StartOffset, BlockBuffer, BytesToRead))
1330
+ FlatStream_UpdateBitmap(pStream, StartOffset, EndOffset);
1331
+
1332
+ return true;
1333
+ }
1334
+ else
1335
+ {
1336
+ if(BytesToRead > BytesNeeded)
1337
+ BytesToRead = BytesNeeded;
1338
+ return pStream->BaseRead(pStream, &StartOffset, BlockBuffer, BytesToRead);
1339
+ }
1340
+ }
1341
+
1342
+ static void FlatStream_Close(TBlockStream * pStream)
1343
+ {
1344
+ FILE_BITMAP_FOOTER Footer;
1345
+
1346
+ if(pStream->FileBitmap && pStream->IsModified)
1347
+ {
1348
+ // Write the file bitmap
1349
+ pStream->BaseWrite(pStream, &pStream->StreamSize, pStream->FileBitmap, pStream->BitmapSize);
1350
+
1351
+ // Prepare and write the file footer
1352
+ Footer.Signature = ID_FILE_BITMAP_FOOTER;
1353
+ Footer.Version = 3;
1354
+ Footer.BuildNumber = pStream->BuildNumber;
1355
+ Footer.MapOffsetLo = (DWORD)(pStream->StreamSize & 0xFFFFFFFF);
1356
+ Footer.MapOffsetHi = (DWORD)(pStream->StreamSize >> 0x20);
1357
+ Footer.BlockSize = pStream->BlockSize;
1358
+ BSWAP_ARRAY32_UNSIGNED(&Footer, sizeof(FILE_BITMAP_FOOTER));
1359
+ pStream->BaseWrite(pStream, NULL, &Footer, sizeof(FILE_BITMAP_FOOTER));
1360
+ }
1361
+
1362
+ // Close the base class
1363
+ BlockStream_Close(pStream);
1364
+ }
1365
+
1366
+ static bool FlatStream_CreateMirror(TBlockStream * pStream)
1367
+ {
1368
+ ULONGLONG MasterSize = 0;
1369
+ ULONGLONG MirrorSize = 0;
1370
+ LPBYTE FileBitmap = NULL;
1371
+ DWORD dwBitmapSize;
1372
+ DWORD dwBlockCount;
1373
+ bool bNeedCreateMirrorStream = true;
1374
+ bool bNeedResizeMirrorStream = true;
1375
+
1376
+ // Do we have master function and base creation function?
1377
+ if(pStream->pMaster == NULL || pStream->BaseCreate == NULL)
1378
+ return false;
1379
+
1380
+ // Retrieve the master file size, block count and bitmap size
1381
+ FileStream_GetSize(pStream->pMaster, &MasterSize);
1382
+ dwBlockCount = (DWORD)((MasterSize + DEFAULT_BLOCK_SIZE - 1) / DEFAULT_BLOCK_SIZE);
1383
+ dwBitmapSize = (DWORD)((dwBlockCount + 7) / 8);
1384
+
1385
+ // Setup stream size and position
1386
+ pStream->BuildNumber = DEFAULT_BUILD_NUMBER; // BUGBUG: Really???
1387
+ pStream->StreamSize = MasterSize;
1388
+ pStream->StreamPos = 0;
1389
+
1390
+ // Open the base stream for write access
1391
+ if(pStream->BaseOpen(pStream, pStream->szFileName, 0))
1392
+ {
1393
+ // If the file open succeeded, check if the file size matches required size
1394
+ pStream->BaseGetSize(pStream, &MirrorSize);
1395
+ if(MirrorSize == MasterSize + dwBitmapSize + sizeof(FILE_BITMAP_FOOTER))
1396
+ {
1397
+ // Attempt to load an existing file bitmap
1398
+ if(FlatStream_LoadBitmap(pStream))
1399
+ return true;
1400
+
1401
+ // We need to create new file bitmap
1402
+ bNeedResizeMirrorStream = false;
1403
+ }
1404
+
1405
+ // We need to create mirror stream
1406
+ bNeedCreateMirrorStream = false;
1407
+ }
1408
+
1409
+ // Create a new stream, if needed
1410
+ if(bNeedCreateMirrorStream)
1411
+ {
1412
+ if(!pStream->BaseCreate(pStream))
1413
+ return false;
1414
+ }
1415
+
1416
+ // If we need to, then resize the mirror stream
1417
+ if(bNeedResizeMirrorStream)
1418
+ {
1419
+ if(!pStream->BaseResize(pStream, MasterSize + dwBitmapSize + sizeof(FILE_BITMAP_FOOTER)))
1420
+ return false;
1421
+ }
1422
+
1423
+ // Allocate the bitmap array
1424
+ FileBitmap = STORM_ALLOC(BYTE, dwBitmapSize);
1425
+ if(FileBitmap == NULL)
1426
+ return false;
1427
+
1428
+ // Initialize the bitmap
1429
+ memset(FileBitmap, 0, dwBitmapSize);
1430
+ pStream->FileBitmap = FileBitmap;
1431
+ pStream->BitmapSize = dwBitmapSize;
1432
+ pStream->BlockSize = DEFAULT_BLOCK_SIZE;
1433
+ pStream->BlockCount = dwBlockCount;
1434
+ pStream->IsComplete = 0;
1435
+ pStream->IsModified = 1;
1436
+
1437
+ // Note: Don't write the stream bitmap right away.
1438
+ // Doing so would cause sparse file resize on NTFS,
1439
+ // which would take long time on larger files.
1440
+ return true;
1441
+ }
1442
+
1443
+ static TFileStream * FlatStream_Open(const TCHAR * szFileName, DWORD dwStreamFlags)
1444
+ {
1445
+ TBlockStream * pStream;
1446
+ ULONGLONG ByteOffset = 0;
1447
+
1448
+ // Create new empty stream
1449
+ pStream = (TBlockStream *)AllocateFileStream(szFileName, sizeof(TBlockStream), dwStreamFlags);
1450
+ if(pStream == NULL)
1451
+ return NULL;
1452
+
1453
+ // Do we have a master stream?
1454
+ if(pStream->pMaster != NULL)
1455
+ {
1456
+ if(!FlatStream_CreateMirror(pStream))
1457
+ {
1458
+ FileStream_Close(pStream);
1459
+ SetLastError(ERROR_FILE_NOT_FOUND);
1460
+ return NULL;
1461
+ }
1462
+ }
1463
+ else
1464
+ {
1465
+ // Attempt to open the base stream
1466
+ if(!pStream->BaseOpen(pStream, pStream->szFileName, dwStreamFlags))
1467
+ {
1468
+ FileStream_Close(pStream);
1469
+ return NULL;
1470
+ }
1471
+
1472
+ // Load the bitmap, if required to
1473
+ if(dwStreamFlags & STREAM_FLAG_USE_BITMAP)
1474
+ FlatStream_LoadBitmap(pStream);
1475
+ }
1476
+
1477
+ // If we have a stream bitmap, set the reading functions
1478
+ // which check presence of each file block
1479
+ if(pStream->FileBitmap != NULL)
1480
+ {
1481
+ // Set the stream position to zero. Stream size is already set
1482
+ assert(pStream->StreamSize != 0);
1483
+ pStream->StreamPos = 0;
1484
+ pStream->dwFlags |= STREAM_FLAG_READ_ONLY;
1485
+
1486
+ // Supply the stream functions
1487
+ pStream->StreamRead = (STREAM_READ)BlockStream_Read;
1488
+ pStream->StreamGetSize = BlockStream_GetSize;
1489
+ pStream->StreamGetPos = BlockStream_GetPos;
1490
+ pStream->StreamClose = (STREAM_CLOSE)FlatStream_Close;
1491
+
1492
+ // Supply the block functions
1493
+ pStream->BlockCheck = (BLOCK_CHECK)FlatStream_BlockCheck;
1494
+ pStream->BlockRead = (BLOCK_READ)FlatStream_BlockRead;
1495
+ }
1496
+ else
1497
+ {
1498
+ // Reset the base position to zero
1499
+ pStream->BaseRead(pStream, &ByteOffset, NULL, 0);
1500
+
1501
+ // Setup stream size and position
1502
+ pStream->StreamSize = pStream->Base.File.FileSize;
1503
+ pStream->StreamPos = 0;
1504
+
1505
+ // Set the base functions
1506
+ pStream->StreamRead = pStream->BaseRead;
1507
+ pStream->StreamWrite = pStream->BaseWrite;
1508
+ pStream->StreamResize = pStream->BaseResize;
1509
+ pStream->StreamGetSize = pStream->BaseGetSize;
1510
+ pStream->StreamGetPos = pStream->BaseGetPos;
1511
+ pStream->StreamClose = pStream->BaseClose;
1512
+ }
1513
+
1514
+ return pStream;
1515
+ }
1516
+
1517
+ //-----------------------------------------------------------------------------
1518
+ // Local functions - partial stream support
1519
+
1520
+ static bool IsPartHeader(PPART_FILE_HEADER pPartHdr)
1521
+ {
1522
+ // Version number must be 2
1523
+ if(pPartHdr->PartialVersion == 2)
1524
+ {
1525
+ // GameBuildNumber must be an ASCII number
1526
+ if(isdigit(pPartHdr->GameBuildNumber[0]) && isdigit(pPartHdr->GameBuildNumber[1]) && isdigit(pPartHdr->GameBuildNumber[2]))
1527
+ {
1528
+ // Block size must be power of 2
1529
+ if((pPartHdr->BlockSize & (pPartHdr->BlockSize - 1)) == 0)
1530
+ return true;
1531
+ }
1532
+ }
1533
+
1534
+ return false;
1535
+ }
1536
+
1537
+ static DWORD PartStream_CheckFile(TBlockStream * pStream)
1538
+ {
1539
+ PPART_FILE_MAP_ENTRY FileBitmap = (PPART_FILE_MAP_ENTRY)pStream->FileBitmap;
1540
+ DWORD dwBlockCount;
1541
+
1542
+ // Get the number of blocks
1543
+ dwBlockCount = (DWORD)((pStream->StreamSize + pStream->BlockSize - 1) / pStream->BlockSize);
1544
+
1545
+ // Check all blocks
1546
+ for(DWORD i = 0; i < dwBlockCount; i++, FileBitmap++)
1547
+ {
1548
+ // Few sanity checks
1549
+ assert(FileBitmap->LargeValueHi == 0);
1550
+ assert(FileBitmap->LargeValueLo == 0);
1551
+ assert(FileBitmap->Flags == 0 || FileBitmap->Flags == 3);
1552
+
1553
+ // Check if this block is present
1554
+ if(FileBitmap->Flags != 3)
1555
+ return 0;
1556
+ }
1557
+
1558
+ // Yes, the file is complete
1559
+ return 1;
1560
+ }
1561
+
1562
+ static bool PartStream_LoadBitmap(TBlockStream * pStream)
1563
+ {
1564
+ PPART_FILE_MAP_ENTRY FileBitmap;
1565
+ PART_FILE_HEADER PartHdr;
1566
+ ULONGLONG ByteOffset = 0;
1567
+ ULONGLONG StreamSize = 0;
1568
+ DWORD BlockCount;
1569
+ DWORD BitmapSize;
1570
+
1571
+ // Only if the size is greater than size of the bitmap header
1572
+ if(pStream->Base.File.FileSize > sizeof(PART_FILE_HEADER))
1573
+ {
1574
+ // Attempt to read PART file header
1575
+ if(pStream->BaseRead(pStream, &ByteOffset, &PartHdr, sizeof(PART_FILE_HEADER)))
1576
+ {
1577
+ // We need to swap PART file header on big-endian platforms
1578
+ BSWAP_ARRAY32_UNSIGNED(&PartHdr, sizeof(PART_FILE_HEADER));
1579
+
1580
+ // Verify the PART file header
1581
+ if(IsPartHeader(&PartHdr))
1582
+ {
1583
+ // Get the number of blocks and size of one block
1584
+ StreamSize = MAKE_OFFSET64(PartHdr.FileSizeHi, PartHdr.FileSizeLo);
1585
+ ByteOffset = sizeof(PART_FILE_HEADER);
1586
+ BlockCount = (DWORD)((StreamSize + PartHdr.BlockSize - 1) / PartHdr.BlockSize);
1587
+ BitmapSize = BlockCount * sizeof(PART_FILE_MAP_ENTRY);
1588
+
1589
+ // Check if sizes match
1590
+ if((ByteOffset + BitmapSize) < pStream->Base.File.FileSize)
1591
+ {
1592
+ // Allocate space for the array of PART_FILE_MAP_ENTRY
1593
+ FileBitmap = STORM_ALLOC(PART_FILE_MAP_ENTRY, BlockCount);
1594
+ if(FileBitmap != NULL)
1595
+ {
1596
+ // Load the block map
1597
+ if(!pStream->BaseRead(pStream, &ByteOffset, FileBitmap, BitmapSize))
1598
+ {
1599
+ STORM_FREE(FileBitmap);
1600
+ return false;
1601
+ }
1602
+
1603
+ // Make sure that the byte order is correct
1604
+ BSWAP_ARRAY32_UNSIGNED(FileBitmap, BitmapSize);
1605
+
1606
+ // Update the stream size
1607
+ pStream->BuildNumber = StringToInt(PartHdr.GameBuildNumber);
1608
+ pStream->StreamSize = StreamSize;
1609
+
1610
+ // Fill the bitmap information
1611
+ pStream->FileBitmap = FileBitmap;
1612
+ pStream->BitmapSize = BitmapSize;
1613
+ pStream->BlockSize = PartHdr.BlockSize;
1614
+ pStream->BlockCount = BlockCount;
1615
+ pStream->IsComplete = PartStream_CheckFile(pStream);
1616
+ return true;
1617
+ }
1618
+ }
1619
+ }
1620
+ }
1621
+ }
1622
+
1623
+ return false;
1624
+ }
1625
+
1626
+ static void PartStream_UpdateBitmap(
1627
+ TBlockStream * pStream, // Pointer to an open stream
1628
+ ULONGLONG StartOffset,
1629
+ ULONGLONG EndOffset,
1630
+ ULONGLONG RealOffset)
1631
+ {
1632
+ PPART_FILE_MAP_ENTRY FileBitmap;
1633
+ DWORD BlockSize = pStream->BlockSize;
1634
+
1635
+ // Sanity checks
1636
+ assert((StartOffset & (BlockSize - 1)) == 0);
1637
+ assert(pStream->FileBitmap != NULL);
1638
+
1639
+ // Calculate the first entry in the block map
1640
+ FileBitmap = (PPART_FILE_MAP_ENTRY)pStream->FileBitmap + (StartOffset / BlockSize);
1641
+
1642
+ // Set all bits for the specified range
1643
+ while(StartOffset < EndOffset)
1644
+ {
1645
+ // Set the bit
1646
+ FileBitmap->BlockOffsHi = (DWORD)(RealOffset >> 0x20);
1647
+ FileBitmap->BlockOffsLo = (DWORD)(RealOffset & 0xFFFFFFFF);
1648
+ FileBitmap->Flags = 3;
1649
+
1650
+ // Move all
1651
+ StartOffset += BlockSize;
1652
+ RealOffset += BlockSize;
1653
+ FileBitmap++;
1654
+ }
1655
+
1656
+ // Increment the bitmap update count
1657
+ pStream->IsModified = 1;
1658
+ }
1659
+
1660
+ static bool PartStream_BlockCheck(
1661
+ TBlockStream * pStream, // Pointer to an open stream
1662
+ ULONGLONG BlockOffset)
1663
+ {
1664
+ PPART_FILE_MAP_ENTRY FileBitmap;
1665
+
1666
+ // Sanity checks
1667
+ assert((BlockOffset & (pStream->BlockSize - 1)) == 0);
1668
+ assert(pStream->FileBitmap != NULL);
1669
+
1670
+ // Calculate the block map entry
1671
+ FileBitmap = (PPART_FILE_MAP_ENTRY)pStream->FileBitmap + (BlockOffset / pStream->BlockSize);
1672
+
1673
+ // Check if the flags are present
1674
+ return (FileBitmap->Flags & 0x03) ? true : false;
1675
+ }
1676
+
1677
+ static bool PartStream_BlockRead(
1678
+ TBlockStream * pStream,
1679
+ ULONGLONG StartOffset,
1680
+ ULONGLONG EndOffset,
1681
+ LPBYTE BlockBuffer,
1682
+ DWORD BytesNeeded,
1683
+ bool bAvailable)
1684
+ {
1685
+ PPART_FILE_MAP_ENTRY FileBitmap;
1686
+ ULONGLONG ByteOffset;
1687
+ DWORD BytesToRead;
1688
+ DWORD BlockIndex = (DWORD)(StartOffset / pStream->BlockSize);
1689
+
1690
+ // The starting offset must be aligned to size of the block
1691
+ assert(pStream->FileBitmap != NULL);
1692
+ assert((StartOffset & (pStream->BlockSize - 1)) == 0);
1693
+ assert(StartOffset < EndOffset);
1694
+
1695
+ // If the blocks are not available, we need to load them from the master
1696
+ // and then save to the mirror
1697
+ if(bAvailable == false)
1698
+ {
1699
+ // If we have no master, we cannot satisfy read request
1700
+ if(pStream->pMaster == NULL)
1701
+ return false;
1702
+
1703
+ // Load the blocks from the master stream
1704
+ // Note that we always have to read complete blocks
1705
+ // so they get properly stored to the mirror stream
1706
+ BytesToRead = (DWORD)(EndOffset - StartOffset);
1707
+ if(!FileStream_Read(pStream->pMaster, &StartOffset, BlockBuffer, BytesToRead))
1708
+ return false;
1709
+
1710
+ // The loaded blocks are going to be stored to the end of the file
1711
+ // Note that this operation is not required to succeed
1712
+ if(pStream->BaseGetSize(pStream, &ByteOffset))
1713
+ {
1714
+ // Store the loaded blocks to the mirror file.
1715
+ if(pStream->BaseWrite(pStream, &ByteOffset, BlockBuffer, BytesToRead))
1716
+ {
1717
+ PartStream_UpdateBitmap(pStream, StartOffset, EndOffset, ByteOffset);
1718
+ }
1719
+ }
1720
+ }
1721
+ else
1722
+ {
1723
+ // Get the file map entry
1724
+ FileBitmap = (PPART_FILE_MAP_ENTRY)pStream->FileBitmap + BlockIndex;
1725
+
1726
+ // Read all blocks
1727
+ while(StartOffset < EndOffset)
1728
+ {
1729
+ // Get the number of bytes to be read
1730
+ BytesToRead = (DWORD)(EndOffset - StartOffset);
1731
+ if(BytesToRead > pStream->BlockSize)
1732
+ BytesToRead = pStream->BlockSize;
1733
+ if(BytesToRead > BytesNeeded)
1734
+ BytesToRead = BytesNeeded;
1735
+
1736
+ // Read the block
1737
+ ByteOffset = MAKE_OFFSET64(FileBitmap->BlockOffsHi, FileBitmap->BlockOffsLo);
1738
+ if(!pStream->BaseRead(pStream, &ByteOffset, BlockBuffer, BytesToRead))
1739
+ return false;
1740
+
1741
+ // Move the pointers
1742
+ StartOffset += pStream->BlockSize;
1743
+ BlockBuffer += pStream->BlockSize;
1744
+ BytesNeeded -= pStream->BlockSize;
1745
+ FileBitmap++;
1746
+ }
1747
+ }
1748
+
1749
+ return true;
1750
+ }
1751
+
1752
+ static void PartStream_Close(TBlockStream * pStream)
1753
+ {
1754
+ PART_FILE_HEADER PartHeader;
1755
+ ULONGLONG ByteOffset = 0;
1756
+
1757
+ if(pStream->FileBitmap && pStream->IsModified)
1758
+ {
1759
+ // Prepare the part file header
1760
+ memset(&PartHeader, 0, sizeof(PART_FILE_HEADER));
1761
+ PartHeader.PartialVersion = 2;
1762
+ PartHeader.FileSizeHi = (DWORD)(pStream->StreamSize >> 0x20);
1763
+ PartHeader.FileSizeLo = (DWORD)(pStream->StreamSize & 0xFFFFFFFF);
1764
+ PartHeader.BlockSize = pStream->BlockSize;
1765
+
1766
+ // Make sure that the header is properly BSWAPed
1767
+ BSWAP_ARRAY32_UNSIGNED(&PartHeader, sizeof(PART_FILE_HEADER));
1768
+ IntToString(PartHeader.GameBuildNumber, _countof(PartHeader.GameBuildNumber), pStream->BuildNumber);
1769
+
1770
+ // Write the part header
1771
+ pStream->BaseWrite(pStream, &ByteOffset, &PartHeader, sizeof(PART_FILE_HEADER));
1772
+
1773
+ // Write the block bitmap
1774
+ BSWAP_ARRAY32_UNSIGNED(pStream->FileBitmap, pStream->BitmapSize);
1775
+ pStream->BaseWrite(pStream, NULL, pStream->FileBitmap, pStream->BitmapSize);
1776
+ }
1777
+
1778
+ // Close the base class
1779
+ BlockStream_Close(pStream);
1780
+ }
1781
+
1782
+ static bool PartStream_CreateMirror(TBlockStream * pStream)
1783
+ {
1784
+ ULONGLONG RemainingSize;
1785
+ ULONGLONG MasterSize = 0;
1786
+ ULONGLONG MirrorSize = 0;
1787
+ LPBYTE FileBitmap = NULL;
1788
+ DWORD dwBitmapSize;
1789
+ DWORD dwBlockCount;
1790
+ bool bNeedCreateMirrorStream = true;
1791
+ bool bNeedResizeMirrorStream = true;
1792
+
1793
+ // Do we have master function and base creation function?
1794
+ if(pStream->pMaster == NULL || pStream->BaseCreate == NULL)
1795
+ return false;
1796
+
1797
+ // Retrieve the master file size, block count and bitmap size
1798
+ FileStream_GetSize(pStream->pMaster, &MasterSize);
1799
+ dwBlockCount = (DWORD)((MasterSize + DEFAULT_BLOCK_SIZE - 1) / DEFAULT_BLOCK_SIZE);
1800
+ dwBitmapSize = (DWORD)(dwBlockCount * sizeof(PART_FILE_MAP_ENTRY));
1801
+
1802
+ // Setup stream size and position
1803
+ pStream->BuildNumber = DEFAULT_BUILD_NUMBER; // BUGBUG: Really???
1804
+ pStream->StreamSize = MasterSize;
1805
+ pStream->StreamPos = 0;
1806
+
1807
+ // Open the base stream for write access
1808
+ if(pStream->BaseOpen(pStream, pStream->szFileName, 0))
1809
+ {
1810
+ // If the file open succeeded, check if the file size matches required size
1811
+ pStream->BaseGetSize(pStream, &MirrorSize);
1812
+ if(MirrorSize >= sizeof(PART_FILE_HEADER) + dwBitmapSize)
1813
+ {
1814
+ // Check if the remaining size is aligned to block
1815
+ RemainingSize = MirrorSize - sizeof(PART_FILE_HEADER) - dwBitmapSize;
1816
+ if((RemainingSize & (DEFAULT_BLOCK_SIZE - 1)) == 0 || RemainingSize == MasterSize)
1817
+ {
1818
+ // Attempt to load an existing file bitmap
1819
+ if(PartStream_LoadBitmap(pStream))
1820
+ return true;
1821
+ }
1822
+ }
1823
+
1824
+ // We need to create mirror stream
1825
+ bNeedCreateMirrorStream = false;
1826
+ }
1827
+
1828
+ // Create a new stream, if needed
1829
+ if(bNeedCreateMirrorStream)
1830
+ {
1831
+ if(!pStream->BaseCreate(pStream))
1832
+ return false;
1833
+ }
1834
+
1835
+ // If we need to, then resize the mirror stream
1836
+ if(bNeedResizeMirrorStream)
1837
+ {
1838
+ if(!pStream->BaseResize(pStream, sizeof(PART_FILE_HEADER) + dwBitmapSize))
1839
+ return false;
1840
+ }
1841
+
1842
+ // Allocate the bitmap array
1843
+ FileBitmap = STORM_ALLOC(BYTE, dwBitmapSize);
1844
+ if(FileBitmap == NULL)
1845
+ return false;
1846
+
1847
+ // Initialize the bitmap
1848
+ memset(FileBitmap, 0, dwBitmapSize);
1849
+ pStream->FileBitmap = FileBitmap;
1850
+ pStream->BitmapSize = dwBitmapSize;
1851
+ pStream->BlockSize = DEFAULT_BLOCK_SIZE;
1852
+ pStream->BlockCount = dwBlockCount;
1853
+ pStream->IsComplete = 0;
1854
+ pStream->IsModified = 1;
1855
+
1856
+ // Note: Don't write the stream bitmap right away.
1857
+ // Doing so would cause sparse file resize on NTFS,
1858
+ // which would take long time on larger files.
1859
+ return true;
1860
+ }
1861
+
1862
+
1863
+ static TFileStream * PartStream_Open(const TCHAR * szFileName, DWORD dwStreamFlags)
1864
+ {
1865
+ TBlockStream * pStream;
1866
+
1867
+ // Create new empty stream
1868
+ pStream = (TBlockStream *)AllocateFileStream(szFileName, sizeof(TBlockStream), dwStreamFlags);
1869
+ if(pStream == NULL)
1870
+ return NULL;
1871
+
1872
+ // Do we have a master stream?
1873
+ if(pStream->pMaster != NULL)
1874
+ {
1875
+ if(!PartStream_CreateMirror(pStream))
1876
+ {
1877
+ FileStream_Close(pStream);
1878
+ SetLastError(ERROR_FILE_NOT_FOUND);
1879
+ return NULL;
1880
+ }
1881
+ }
1882
+ else
1883
+ {
1884
+ // Attempt to open the base stream
1885
+ if(!pStream->BaseOpen(pStream, pStream->szFileName, dwStreamFlags))
1886
+ {
1887
+ FileStream_Close(pStream);
1888
+ return NULL;
1889
+ }
1890
+
1891
+ // Load the part stream block map
1892
+ if(!PartStream_LoadBitmap(pStream))
1893
+ {
1894
+ FileStream_Close(pStream);
1895
+ SetLastError(ERROR_BAD_FORMAT);
1896
+ return NULL;
1897
+ }
1898
+ }
1899
+
1900
+ // Set the stream position to zero. Stream size is already set
1901
+ assert(pStream->StreamSize != 0);
1902
+ pStream->StreamPos = 0;
1903
+ pStream->dwFlags |= STREAM_FLAG_READ_ONLY;
1904
+
1905
+ // Set new function pointers
1906
+ pStream->StreamRead = (STREAM_READ)BlockStream_Read;
1907
+ pStream->StreamGetPos = BlockStream_GetPos;
1908
+ pStream->StreamGetSize = BlockStream_GetSize;
1909
+ pStream->StreamClose = (STREAM_CLOSE)PartStream_Close;
1910
+
1911
+ // Supply the block functions
1912
+ pStream->BlockCheck = (BLOCK_CHECK)PartStream_BlockCheck;
1913
+ pStream->BlockRead = (BLOCK_READ)PartStream_BlockRead;
1914
+ return pStream;
1915
+ }
1916
+
1917
+ //-----------------------------------------------------------------------------
1918
+ // Local functions - MPQE stream support
1919
+
1920
+ static const char * szKeyTemplate = "expand 32-byte k000000000000000000000000000000000000000000000000";
1921
+
1922
+ static const char * AuthCodeArray[] =
1923
+ {
1924
+ // Starcraft II (Heart of the Swarm)
1925
+ // Authentication code URL: http://dist.blizzard.com/mediakey/hots-authenticationcode-bgdl.txt
1926
+ // -0C- -1C--08- -18--04- -14--00- -10-
1927
+ "S48B6CDTN5XEQAKQDJNDLJBJ73FDFM3U", // SC2 Heart of the Swarm-all : "expand 32-byte kQAKQ0000FM3UN5XE000073FD6CDT0000LJBJS48B0000DJND"
1928
+
1929
+ // Diablo III: Agent.exe (1.0.0.954)
1930
+ // Address of decryption routine: 00502b00
1931
+ // Pointer to decryptor object: ECX
1932
+ // Pointer to key: ECX+0x5C
1933
+ // Authentication code URL: http://dist.blizzard.com/mediakey/d3-authenticationcode-enGB.txt
1934
+ // -0C- -1C--08- -18--04- -14--00- -10-
1935
+ "UCMXF6EJY352EFH4XFRXCFH2XC9MQRZK", // Diablo III Installer (deDE): "expand 32-byte kEFH40000QRZKY3520000XC9MF6EJ0000CFH2UCMX0000XFRX"
1936
+ "MMKVHY48RP7WXP4GHYBQ7SL9J9UNPHBP", // Diablo III Installer (enGB): "expand 32-byte kXP4G0000PHBPRP7W0000J9UNHY4800007SL9MMKV0000HYBQ"
1937
+ "8MXLWHQ7VGGLTZ9MQZQSFDCLJYET3CPP", // Diablo III Installer (enSG): "expand 32-byte kTZ9M00003CPPVGGL0000JYETWHQ70000FDCL8MXL0000QZQS"
1938
+ "EJ2R5TM6XFE2GUNG5QDGHKQ9UAKPWZSZ", // Diablo III Installer (enUS): "expand 32-byte kGUNG0000WZSZXFE20000UAKP5TM60000HKQ9EJ2R00005QDG"
1939
+ "PBGFBE42Z6LNK65UGJQ3WZVMCLP4HQQT", // Diablo III Installer (esES): "expand 32-byte kK65U0000HQQTZ6LN0000CLP4BE420000WZVMPBGF0000GJQ3"
1940
+ "X7SEJJS9TSGCW5P28EBSC47AJPEY8VU2", // Diablo III Installer (esMX): "expand 32-byte kW5P200008VU2TSGC0000JPEYJJS90000C47AX7SE00008EBS"
1941
+ "5KVBQA8VYE6XRY3DLGC5ZDE4XS4P7YA2", // Diablo III Installer (frFR): "expand 32-byte kRY3D00007YA2YE6X0000XS4PQA8V0000ZDE45KVB0000LGC5"
1942
+ "478JD2K56EVNVVY4XX8TDWYT5B8KB254", // Diablo III Installer (itIT): "expand 32-byte kVVY40000B2546EVN00005B8KD2K50000DWYT478J0000XX8T"
1943
+ "8TS4VNFQRZTN6YWHE9CHVDH9NVWD474A", // Diablo III Installer (koKR): "expand 32-byte k6YWH0000474ARZTN0000NVWDVNFQ0000VDH98TS40000E9CH"
1944
+ "LJ52Z32DF4LZ4ZJJXVKK3AZQA6GABLJB", // Diablo III Installer (plPL): "expand 32-byte k4ZJJ0000BLJBF4LZ0000A6GAZ32D00003AZQLJ520000XVKK"
1945
+ "K6BDHY2ECUE2545YKNLBJPVYWHE7XYAG", // Diablo III Installer (ptBR): "expand 32-byte k545Y0000XYAGCUE20000WHE7HY2E0000JPVYK6BD0000KNLB"
1946
+ "NDVW8GWLAYCRPGRNY8RT7ZZUQU63VLPR", // Diablo III Installer (ruRU): "expand 32-byte kXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
1947
+ "6VWCQTN8V3ZZMRUCZXV8A8CGUX2TAA8H", // Diablo III Installer (zhTW): "expand 32-byte kMRUC0000AA8HV3ZZ0000UX2TQTN80000A8CG6VWC0000ZXV8"
1948
+ // "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", // Diablo III Installer (zhCN): "expand 32-byte kXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
1949
+
1950
+ // Starcraft II (Wings of Liberty): Installer.exe (4.1.1.4219)
1951
+ // Address of decryption routine: 0053A3D0
1952
+ // Pointer to decryptor object: ECX
1953
+ // Pointer to key: ECX+0x5C
1954
+ // Authentication code URL: http://dist.blizzard.com/mediakey/sc2-authenticationcode-enUS.txt
1955
+ // -0C- -1C--08- -18--04- -14--00- -10-
1956
+ "Y45MD3CAK4KXSSXHYD9VY64Z8EKJ4XFX", // SC2 Wings of Liberty (deDE): "expand 32-byte kSSXH00004XFXK4KX00008EKJD3CA0000Y64ZY45M0000YD9V"
1957
+ "G8MN8UDG6NA2ANGY6A3DNY82HRGF29ZH", // SC2 Wings of Liberty (enGB): "expand 32-byte kANGY000029ZH6NA20000HRGF8UDG0000NY82G8MN00006A3D"
1958
+ "W9RRHLB2FDU9WW5B3ECEBLRSFWZSF7HW", // SC2 Wings of Liberty (enSG): "expand 32-byte kWW5B0000F7HWFDU90000FWZSHLB20000BLRSW9RR00003ECE"
1959
+ "3DH5RE5NVM5GTFD85LXGWT6FK859ETR5", // SC2 Wings of Liberty (enUS): "expand 32-byte kTFD80000ETR5VM5G0000K859RE5N0000WT6F3DH500005LXG"
1960
+ "8WLKUAXE94PFQU4Y249PAZ24N4R4XKTQ", // SC2 Wings of Liberty (esES): "expand 32-byte kQU4Y0000XKTQ94PF0000N4R4UAXE0000AZ248WLK0000249P"
1961
+ "A34DXX3VHGGXSQBRFE5UFFDXMF9G4G54", // SC2 Wings of Liberty (esMX): "expand 32-byte kSQBR00004G54HGGX0000MF9GXX3V0000FFDXA34D0000FE5U"
1962
+ "ZG7J9K938HJEFWPQUA768MA2PFER6EAJ", // SC2 Wings of Liberty (frFR): "expand 32-byte kFWPQ00006EAJ8HJE0000PFER9K9300008MA2ZG7J0000UA76"
1963
+ "NE7CUNNNTVAPXV7E3G2BSVBWGVMW8BL2", // SC2 Wings of Liberty (itIT): "expand 32-byte kXV7E00008BL2TVAP0000GVMWUNNN0000SVBWNE7C00003G2B"
1964
+ "3V9E2FTMBM9QQWK7U6MAMWAZWQDB838F", // SC2 Wings of Liberty (koKR): "expand 32-byte kQWK70000838FBM9Q0000WQDB2FTM0000MWAZ3V9E0000U6MA"
1965
+ "2NSFB8MELULJ83U6YHA3UP6K4MQD48L6", // SC2 Wings of Liberty (plPL): "expand 32-byte k83U6000048L6LULJ00004MQDB8ME0000UP6K2NSF0000YHA3"
1966
+ "QA2TZ9EWZ4CUU8BMB5WXCTY65F9CSW4E", // SC2 Wings of Liberty (ptBR): "expand 32-byte kU8BM0000SW4EZ4CU00005F9CZ9EW0000CTY6QA2T0000B5WX"
1967
+ "VHB378W64BAT9SH7D68VV9NLQDK9YEGT", // SC2 Wings of Liberty (ruRU): "expand 32-byte k9SH70000YEGT4BAT0000QDK978W60000V9NLVHB30000D68V"
1968
+ "U3NFQJV4M6GC7KBN9XQJ3BRDN3PLD9NE", // SC2 Wings of Liberty (zhTW): "expand 32-byte k7KBN0000D9NEM6GC0000N3PLQJV400003BRDU3NF00009XQJ"
1969
+
1970
+ NULL
1971
+ };
1972
+
1973
+ static DWORD Rol32(DWORD dwValue, DWORD dwRolCount)
1974
+ {
1975
+ DWORD dwShiftRight = 32 - dwRolCount;
1976
+
1977
+ return (dwValue << dwRolCount) | (dwValue >> dwShiftRight);
1978
+ }
1979
+
1980
+ static void CreateKeyFromAuthCode(
1981
+ LPBYTE pbKeyBuffer,
1982
+ const char * szAuthCode)
1983
+ {
1984
+ LPDWORD KeyPosition = (LPDWORD)(pbKeyBuffer + 0x10);
1985
+ LPDWORD AuthCode32 = (LPDWORD)szAuthCode;
1986
+
1987
+ memcpy(pbKeyBuffer, szKeyTemplate, MPQE_CHUNK_SIZE);
1988
+ KeyPosition[0x00] = AuthCode32[0x03];
1989
+ KeyPosition[0x02] = AuthCode32[0x07];
1990
+ KeyPosition[0x03] = AuthCode32[0x02];
1991
+ KeyPosition[0x05] = AuthCode32[0x06];
1992
+ KeyPosition[0x06] = AuthCode32[0x01];
1993
+ KeyPosition[0x08] = AuthCode32[0x05];
1994
+ KeyPosition[0x09] = AuthCode32[0x00];
1995
+ KeyPosition[0x0B] = AuthCode32[0x04];
1996
+ BSWAP_ARRAY32_UNSIGNED(pbKeyBuffer, MPQE_CHUNK_SIZE);
1997
+ }
1998
+
1999
+ static void DecryptFileChunk(
2000
+ DWORD * MpqData,
2001
+ LPBYTE pbKey,
2002
+ ULONGLONG ByteOffset,
2003
+ DWORD dwLength)
2004
+ {
2005
+ ULONGLONG ChunkOffset;
2006
+ DWORD KeyShuffled[0x10];
2007
+ DWORD KeyMirror[0x10];
2008
+ DWORD RoundCount = 0x14;
2009
+
2010
+ // Prepare the key
2011
+ ChunkOffset = ByteOffset / MPQE_CHUNK_SIZE;
2012
+ memcpy(KeyMirror, pbKey, MPQE_CHUNK_SIZE);
2013
+ BSWAP_ARRAY32_UNSIGNED(KeyMirror, MPQE_CHUNK_SIZE);
2014
+ KeyMirror[0x05] = (DWORD)(ChunkOffset >> 32);
2015
+ KeyMirror[0x08] = (DWORD)(ChunkOffset);
2016
+
2017
+ while(dwLength >= MPQE_CHUNK_SIZE)
2018
+ {
2019
+ // Shuffle the key - part 1
2020
+ KeyShuffled[0x0E] = KeyMirror[0x00];
2021
+ KeyShuffled[0x0C] = KeyMirror[0x01];
2022
+ KeyShuffled[0x05] = KeyMirror[0x02];
2023
+ KeyShuffled[0x0F] = KeyMirror[0x03];
2024
+ KeyShuffled[0x0A] = KeyMirror[0x04];
2025
+ KeyShuffled[0x07] = KeyMirror[0x05];
2026
+ KeyShuffled[0x0B] = KeyMirror[0x06];
2027
+ KeyShuffled[0x09] = KeyMirror[0x07];
2028
+ KeyShuffled[0x03] = KeyMirror[0x08];
2029
+ KeyShuffled[0x06] = KeyMirror[0x09];
2030
+ KeyShuffled[0x08] = KeyMirror[0x0A];
2031
+ KeyShuffled[0x0D] = KeyMirror[0x0B];
2032
+ KeyShuffled[0x02] = KeyMirror[0x0C];
2033
+ KeyShuffled[0x04] = KeyMirror[0x0D];
2034
+ KeyShuffled[0x01] = KeyMirror[0x0E];
2035
+ KeyShuffled[0x00] = KeyMirror[0x0F];
2036
+
2037
+ // Shuffle the key - part 2
2038
+ for(DWORD i = 0; i < RoundCount; i += 2)
2039
+ {
2040
+ KeyShuffled[0x0A] = KeyShuffled[0x0A] ^ Rol32((KeyShuffled[0x0E] + KeyShuffled[0x02]), 0x07);
2041
+ KeyShuffled[0x03] = KeyShuffled[0x03] ^ Rol32((KeyShuffled[0x0A] + KeyShuffled[0x0E]), 0x09);
2042
+ KeyShuffled[0x02] = KeyShuffled[0x02] ^ Rol32((KeyShuffled[0x03] + KeyShuffled[0x0A]), 0x0D);
2043
+ KeyShuffled[0x0E] = KeyShuffled[0x0E] ^ Rol32((KeyShuffled[0x02] + KeyShuffled[0x03]), 0x12);
2044
+
2045
+ KeyShuffled[0x07] = KeyShuffled[0x07] ^ Rol32((KeyShuffled[0x0C] + KeyShuffled[0x04]), 0x07);
2046
+ KeyShuffled[0x06] = KeyShuffled[0x06] ^ Rol32((KeyShuffled[0x07] + KeyShuffled[0x0C]), 0x09);
2047
+ KeyShuffled[0x04] = KeyShuffled[0x04] ^ Rol32((KeyShuffled[0x06] + KeyShuffled[0x07]), 0x0D);
2048
+ KeyShuffled[0x0C] = KeyShuffled[0x0C] ^ Rol32((KeyShuffled[0x04] + KeyShuffled[0x06]), 0x12);
2049
+
2050
+ KeyShuffled[0x0B] = KeyShuffled[0x0B] ^ Rol32((KeyShuffled[0x05] + KeyShuffled[0x01]), 0x07);
2051
+ KeyShuffled[0x08] = KeyShuffled[0x08] ^ Rol32((KeyShuffled[0x0B] + KeyShuffled[0x05]), 0x09);
2052
+ KeyShuffled[0x01] = KeyShuffled[0x01] ^ Rol32((KeyShuffled[0x08] + KeyShuffled[0x0B]), 0x0D);
2053
+ KeyShuffled[0x05] = KeyShuffled[0x05] ^ Rol32((KeyShuffled[0x01] + KeyShuffled[0x08]), 0x12);
2054
+
2055
+ KeyShuffled[0x09] = KeyShuffled[0x09] ^ Rol32((KeyShuffled[0x0F] + KeyShuffled[0x00]), 0x07);
2056
+ KeyShuffled[0x0D] = KeyShuffled[0x0D] ^ Rol32((KeyShuffled[0x09] + KeyShuffled[0x0F]), 0x09);
2057
+ KeyShuffled[0x00] = KeyShuffled[0x00] ^ Rol32((KeyShuffled[0x0D] + KeyShuffled[0x09]), 0x0D);
2058
+ KeyShuffled[0x0F] = KeyShuffled[0x0F] ^ Rol32((KeyShuffled[0x00] + KeyShuffled[0x0D]), 0x12);
2059
+
2060
+ KeyShuffled[0x04] = KeyShuffled[0x04] ^ Rol32((KeyShuffled[0x0E] + KeyShuffled[0x09]), 0x07);
2061
+ KeyShuffled[0x08] = KeyShuffled[0x08] ^ Rol32((KeyShuffled[0x04] + KeyShuffled[0x0E]), 0x09);
2062
+ KeyShuffled[0x09] = KeyShuffled[0x09] ^ Rol32((KeyShuffled[0x08] + KeyShuffled[0x04]), 0x0D);
2063
+ KeyShuffled[0x0E] = KeyShuffled[0x0E] ^ Rol32((KeyShuffled[0x09] + KeyShuffled[0x08]), 0x12);
2064
+
2065
+ KeyShuffled[0x01] = KeyShuffled[0x01] ^ Rol32((KeyShuffled[0x0C] + KeyShuffled[0x0A]), 0x07);
2066
+ KeyShuffled[0x0D] = KeyShuffled[0x0D] ^ Rol32((KeyShuffled[0x01] + KeyShuffled[0x0C]), 0x09);
2067
+ KeyShuffled[0x0A] = KeyShuffled[0x0A] ^ Rol32((KeyShuffled[0x0D] + KeyShuffled[0x01]), 0x0D);
2068
+ KeyShuffled[0x0C] = KeyShuffled[0x0C] ^ Rol32((KeyShuffled[0x0A] + KeyShuffled[0x0D]), 0x12);
2069
+
2070
+ KeyShuffled[0x00] = KeyShuffled[0x00] ^ Rol32((KeyShuffled[0x05] + KeyShuffled[0x07]), 0x07);
2071
+ KeyShuffled[0x03] = KeyShuffled[0x03] ^ Rol32((KeyShuffled[0x00] + KeyShuffled[0x05]), 0x09);
2072
+ KeyShuffled[0x07] = KeyShuffled[0x07] ^ Rol32((KeyShuffled[0x03] + KeyShuffled[0x00]), 0x0D);
2073
+ KeyShuffled[0x05] = KeyShuffled[0x05] ^ Rol32((KeyShuffled[0x07] + KeyShuffled[0x03]), 0x12);
2074
+
2075
+ KeyShuffled[0x02] = KeyShuffled[0x02] ^ Rol32((KeyShuffled[0x0F] + KeyShuffled[0x0B]), 0x07);
2076
+ KeyShuffled[0x06] = KeyShuffled[0x06] ^ Rol32((KeyShuffled[0x02] + KeyShuffled[0x0F]), 0x09);
2077
+ KeyShuffled[0x0B] = KeyShuffled[0x0B] ^ Rol32((KeyShuffled[0x06] + KeyShuffled[0x02]), 0x0D);
2078
+ KeyShuffled[0x0F] = KeyShuffled[0x0F] ^ Rol32((KeyShuffled[0x0B] + KeyShuffled[0x06]), 0x12);
2079
+ }
2080
+
2081
+ // Decrypt one data chunk
2082
+ BSWAP_ARRAY32_UNSIGNED(MpqData, MPQE_CHUNK_SIZE);
2083
+ MpqData[0x00] = MpqData[0x00] ^ (KeyShuffled[0x0E] + KeyMirror[0x00]);
2084
+ MpqData[0x01] = MpqData[0x01] ^ (KeyShuffled[0x04] + KeyMirror[0x0D]);
2085
+ MpqData[0x02] = MpqData[0x02] ^ (KeyShuffled[0x08] + KeyMirror[0x0A]);
2086
+ MpqData[0x03] = MpqData[0x03] ^ (KeyShuffled[0x09] + KeyMirror[0x07]);
2087
+ MpqData[0x04] = MpqData[0x04] ^ (KeyShuffled[0x0A] + KeyMirror[0x04]);
2088
+ MpqData[0x05] = MpqData[0x05] ^ (KeyShuffled[0x0C] + KeyMirror[0x01]);
2089
+ MpqData[0x06] = MpqData[0x06] ^ (KeyShuffled[0x01] + KeyMirror[0x0E]);
2090
+ MpqData[0x07] = MpqData[0x07] ^ (KeyShuffled[0x0D] + KeyMirror[0x0B]);
2091
+ MpqData[0x08] = MpqData[0x08] ^ (KeyShuffled[0x03] + KeyMirror[0x08]);
2092
+ MpqData[0x09] = MpqData[0x09] ^ (KeyShuffled[0x07] + KeyMirror[0x05]);
2093
+ MpqData[0x0A] = MpqData[0x0A] ^ (KeyShuffled[0x05] + KeyMirror[0x02]);
2094
+ MpqData[0x0B] = MpqData[0x0B] ^ (KeyShuffled[0x00] + KeyMirror[0x0F]);
2095
+ MpqData[0x0C] = MpqData[0x0C] ^ (KeyShuffled[0x02] + KeyMirror[0x0C]);
2096
+ MpqData[0x0D] = MpqData[0x0D] ^ (KeyShuffled[0x06] + KeyMirror[0x09]);
2097
+ MpqData[0x0E] = MpqData[0x0E] ^ (KeyShuffled[0x0B] + KeyMirror[0x06]);
2098
+ MpqData[0x0F] = MpqData[0x0F] ^ (KeyShuffled[0x0F] + KeyMirror[0x03]);
2099
+ BSWAP_ARRAY32_UNSIGNED(MpqData, MPQE_CHUNK_SIZE);
2100
+
2101
+ // Update byte offset in the key
2102
+ KeyMirror[0x08]++;
2103
+ if(KeyMirror[0x08] == 0)
2104
+ KeyMirror[0x05]++;
2105
+
2106
+ // Move pointers and decrease number of bytes to decrypt
2107
+ MpqData += (MPQE_CHUNK_SIZE / sizeof(DWORD));
2108
+ dwLength -= MPQE_CHUNK_SIZE;
2109
+ }
2110
+ }
2111
+
2112
+ static bool MpqeStream_DetectFileKey(TEncryptedStream * pStream)
2113
+ {
2114
+ ULONGLONG ByteOffset = 0;
2115
+ BYTE EncryptedHeader[MPQE_CHUNK_SIZE];
2116
+ BYTE FileHeader[MPQE_CHUNK_SIZE];
2117
+
2118
+ // Read the first file chunk
2119
+ if(pStream->BaseRead(pStream, &ByteOffset, EncryptedHeader, sizeof(EncryptedHeader)))
2120
+ {
2121
+ // We just try all known keys one by one
2122
+ for(int i = 0; AuthCodeArray[i] != NULL; i++)
2123
+ {
2124
+ // Prepare they decryption key from game serial number
2125
+ CreateKeyFromAuthCode(pStream->Key, AuthCodeArray[i]);
2126
+
2127
+ // Try to decrypt with the given key
2128
+ memcpy(FileHeader, EncryptedHeader, MPQE_CHUNK_SIZE);
2129
+ DecryptFileChunk((LPDWORD)FileHeader, pStream->Key, ByteOffset, MPQE_CHUNK_SIZE);
2130
+
2131
+ // We check the decrypted data
2132
+ // All known encrypted MPQs have header at the begin of the file,
2133
+ // so we check for MPQ signature there.
2134
+ if(FileHeader[0] == 'M' && FileHeader[1] == 'P' && FileHeader[2] == 'Q')
2135
+ {
2136
+ // Update the stream size
2137
+ pStream->StreamSize = pStream->Base.File.FileSize;
2138
+
2139
+ // Fill the block information
2140
+ pStream->BlockSize = MPQE_CHUNK_SIZE;
2141
+ pStream->BlockCount = (DWORD)(pStream->Base.File.FileSize + MPQE_CHUNK_SIZE - 1) / MPQE_CHUNK_SIZE;
2142
+ pStream->IsComplete = 1;
2143
+ return true;
2144
+ }
2145
+ }
2146
+ }
2147
+
2148
+ // Key not found, sorry
2149
+ return false;
2150
+ }
2151
+
2152
+ static bool MpqeStream_BlockRead(
2153
+ TEncryptedStream * pStream,
2154
+ ULONGLONG StartOffset,
2155
+ ULONGLONG EndOffset,
2156
+ LPBYTE BlockBuffer,
2157
+ DWORD BytesNeeded,
2158
+ bool bAvailable)
2159
+ {
2160
+ DWORD dwBytesToRead;
2161
+
2162
+ assert((StartOffset & (pStream->BlockSize - 1)) == 0);
2163
+ assert(StartOffset < EndOffset);
2164
+ assert(bAvailable != false);
2165
+ BytesNeeded = BytesNeeded;
2166
+ bAvailable = bAvailable;
2167
+
2168
+ // Read the file from the stream as-is
2169
+ // Limit the reading to number of blocks really needed
2170
+ dwBytesToRead = (DWORD)(EndOffset - StartOffset);
2171
+ if(!pStream->BaseRead(pStream, &StartOffset, BlockBuffer, dwBytesToRead))
2172
+ return false;
2173
+
2174
+ // Decrypt the data
2175
+ dwBytesToRead = (dwBytesToRead + MPQE_CHUNK_SIZE - 1) & ~(MPQE_CHUNK_SIZE - 1);
2176
+ DecryptFileChunk((LPDWORD)BlockBuffer, pStream->Key, StartOffset, dwBytesToRead);
2177
+ return true;
2178
+ }
2179
+
2180
+ static TFileStream * MpqeStream_Open(const TCHAR * szFileName, DWORD dwStreamFlags)
2181
+ {
2182
+ TEncryptedStream * pStream;
2183
+
2184
+ // Create new empty stream
2185
+ pStream = (TEncryptedStream *)AllocateFileStream(szFileName, sizeof(TEncryptedStream), dwStreamFlags);
2186
+ if(pStream == NULL)
2187
+ return NULL;
2188
+
2189
+ // Attempt to open the base stream
2190
+ assert(pStream->BaseOpen != NULL);
2191
+ if(!pStream->BaseOpen(pStream, pStream->szFileName, dwStreamFlags))
2192
+ return NULL;
2193
+
2194
+ // Determine the encryption key for the MPQ
2195
+ if(MpqeStream_DetectFileKey(pStream))
2196
+ {
2197
+ // Set the stream position and size
2198
+ assert(pStream->StreamSize != 0);
2199
+ pStream->StreamPos = 0;
2200
+ pStream->dwFlags |= STREAM_FLAG_READ_ONLY;
2201
+
2202
+ // Set new function pointers
2203
+ pStream->StreamRead = (STREAM_READ)BlockStream_Read;
2204
+ pStream->StreamGetPos = BlockStream_GetPos;
2205
+ pStream->StreamGetSize = BlockStream_GetSize;
2206
+ pStream->StreamClose = pStream->BaseClose;
2207
+
2208
+ // Supply the block functions
2209
+ pStream->BlockRead = (BLOCK_READ)MpqeStream_BlockRead;
2210
+ return pStream;
2211
+ }
2212
+
2213
+ // Cleanup the stream and return
2214
+ FileStream_Close(pStream);
2215
+ SetLastError(ERROR_UNKNOWN_FILE_KEY);
2216
+ return NULL;
2217
+ }
2218
+
2219
+ //-----------------------------------------------------------------------------
2220
+ // Local functions - Block4 stream support
2221
+
2222
+ #define BLOCK4_BLOCK_SIZE 0x4000 // Size of one block
2223
+ #define BLOCK4_HASH_SIZE 0x20 // Size of MD5 hash that is after each block
2224
+ #define BLOCK4_MAX_BLOCKS 0x00002000 // Maximum amount of blocks per file
2225
+ #define BLOCK4_MAX_FSIZE 0x08040000 // Max size of one file
2226
+
2227
+ static bool Block4Stream_BlockRead(
2228
+ TBlockStream * pStream, // Pointer to an open stream
2229
+ ULONGLONG StartOffset,
2230
+ ULONGLONG EndOffset,
2231
+ LPBYTE BlockBuffer,
2232
+ DWORD BytesNeeded,
2233
+ bool bAvailable)
2234
+ {
2235
+ TBaseProviderData * BaseArray = (TBaseProviderData *)pStream->FileBitmap;
2236
+ ULONGLONG ByteOffset;
2237
+ DWORD BytesToRead;
2238
+ DWORD StreamIndex;
2239
+ DWORD BlockIndex;
2240
+ bool bResult;
2241
+
2242
+ // The starting offset must be aligned to size of the block
2243
+ assert(pStream->FileBitmap != NULL);
2244
+ assert((StartOffset & (pStream->BlockSize - 1)) == 0);
2245
+ assert(StartOffset < EndOffset);
2246
+ assert(bAvailable == true);
2247
+
2248
+ // Keep compilers happy
2249
+ STORMLIB_UNUSED(bAvailable);
2250
+ STORMLIB_UNUSED(EndOffset);
2251
+
2252
+ while(BytesNeeded != 0)
2253
+ {
2254
+ // Calculate the block index and the file index
2255
+ StreamIndex = (DWORD)((StartOffset / pStream->BlockSize) / BLOCK4_MAX_BLOCKS);
2256
+ BlockIndex = (DWORD)((StartOffset / pStream->BlockSize) % BLOCK4_MAX_BLOCKS);
2257
+ if(StreamIndex > pStream->BitmapSize)
2258
+ return false;
2259
+
2260
+ // Calculate the block offset
2261
+ ByteOffset = ((ULONGLONG)BlockIndex * (BLOCK4_BLOCK_SIZE + BLOCK4_HASH_SIZE));
2262
+ BytesToRead = STORMLIB_MIN(BytesNeeded, BLOCK4_BLOCK_SIZE);
2263
+
2264
+ // Read from the base stream
2265
+ pStream->Base = BaseArray[StreamIndex];
2266
+ bResult = pStream->BaseRead(pStream, &ByteOffset, BlockBuffer, BytesToRead);
2267
+ BaseArray[StreamIndex] = pStream->Base;
2268
+
2269
+ // Did the result succeed?
2270
+ if(bResult == false)
2271
+ return false;
2272
+
2273
+ // Move pointers
2274
+ StartOffset += BytesToRead;
2275
+ BlockBuffer += BytesToRead;
2276
+ BytesNeeded -= BytesToRead;
2277
+ }
2278
+
2279
+ return true;
2280
+ }
2281
+
2282
+
2283
+ static void Block4Stream_Close(TBlockStream * pStream)
2284
+ {
2285
+ TBaseProviderData * BaseArray = (TBaseProviderData *)pStream->FileBitmap;
2286
+
2287
+ // If we have a non-zero count of base streams,
2288
+ // we have to close them all
2289
+ if(BaseArray != NULL)
2290
+ {
2291
+ // Close all base streams
2292
+ for(DWORD i = 0; i < pStream->BitmapSize; i++)
2293
+ {
2294
+ memcpy(&pStream->Base, BaseArray + i, sizeof(TBaseProviderData));
2295
+ pStream->BaseClose(pStream);
2296
+ }
2297
+ }
2298
+
2299
+ // Free the data map, if any
2300
+ if(pStream->FileBitmap != NULL)
2301
+ STORM_FREE(pStream->FileBitmap);
2302
+ pStream->FileBitmap = NULL;
2303
+
2304
+ // Do not call the BaseClose function,
2305
+ // we closed all handles already
2306
+ return;
2307
+ }
2308
+
2309
+ static TFileStream * Block4Stream_Open(const TCHAR * szFileName, DWORD dwStreamFlags)
2310
+ {
2311
+ TBaseProviderData * NewBaseArray = NULL;
2312
+ ULONGLONG RemainderBlock;
2313
+ ULONGLONG BlockCount;
2314
+ ULONGLONG FileSize;
2315
+ TBlockStream * pStream;
2316
+ TCHAR * szNameBuff;
2317
+ size_t nNameLength;
2318
+ DWORD dwBaseFiles = 0;
2319
+ DWORD dwBaseFlags;
2320
+
2321
+ // Create new empty stream
2322
+ pStream = (TBlockStream *)AllocateFileStream(szFileName, sizeof(TBlockStream), dwStreamFlags);
2323
+ if(pStream == NULL)
2324
+ return NULL;
2325
+
2326
+ // Sanity check
2327
+ assert(pStream->BaseOpen != NULL);
2328
+
2329
+ // Get the length of the file name without numeric suffix
2330
+ nNameLength = _tcslen(pStream->szFileName);
2331
+ if(pStream->szFileName[nNameLength - 2] == '.' && pStream->szFileName[nNameLength - 1] == '0')
2332
+ nNameLength -= 2;
2333
+ pStream->szFileName[nNameLength] = 0;
2334
+
2335
+ // Supply the stream functions
2336
+ pStream->StreamRead = (STREAM_READ)BlockStream_Read;
2337
+ pStream->StreamGetSize = BlockStream_GetSize;
2338
+ pStream->StreamGetPos = BlockStream_GetPos;
2339
+ pStream->StreamClose = (STREAM_CLOSE)Block4Stream_Close;
2340
+ pStream->BlockRead = (BLOCK_READ)Block4Stream_BlockRead;
2341
+
2342
+ // Allocate work space for numeric names
2343
+ szNameBuff = STORM_ALLOC(TCHAR, nNameLength + 4);
2344
+ if(szNameBuff != NULL)
2345
+ {
2346
+ // Set the base flags
2347
+ dwBaseFlags = (dwStreamFlags & STREAM_PROVIDERS_MASK) | STREAM_FLAG_READ_ONLY;
2348
+
2349
+ // Go all suffixes from 0 to 30
2350
+ for(int nSuffix = 0; nSuffix < 30; nSuffix++)
2351
+ {
2352
+ // Open the n-th file
2353
+ CreateNameWithSuffix(szNameBuff, nNameLength + 4, pStream->szFileName, nSuffix);
2354
+ if(!pStream->BaseOpen(pStream, szNameBuff, dwBaseFlags))
2355
+ break;
2356
+
2357
+ // If the open succeeded, we re-allocate the base provider array
2358
+ NewBaseArray = STORM_ALLOC(TBaseProviderData, dwBaseFiles + 1);
2359
+ if(NewBaseArray == NULL)
2360
+ {
2361
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2362
+ return NULL;
2363
+ }
2364
+
2365
+ // Copy the old base data array to the new base data array
2366
+ if(pStream->FileBitmap != NULL)
2367
+ {
2368
+ memcpy(NewBaseArray, pStream->FileBitmap, sizeof(TBaseProviderData) * dwBaseFiles);
2369
+ STORM_FREE(pStream->FileBitmap);
2370
+ }
2371
+
2372
+ // Also copy the opened base array
2373
+ memcpy(NewBaseArray + dwBaseFiles, &pStream->Base, sizeof(TBaseProviderData));
2374
+ pStream->FileBitmap = NewBaseArray;
2375
+ dwBaseFiles++;
2376
+
2377
+ // Get the size of the base stream
2378
+ pStream->BaseGetSize(pStream, &FileSize);
2379
+ assert(FileSize <= BLOCK4_MAX_FSIZE);
2380
+ RemainderBlock = FileSize % (BLOCK4_BLOCK_SIZE + BLOCK4_HASH_SIZE);
2381
+ BlockCount = FileSize / (BLOCK4_BLOCK_SIZE + BLOCK4_HASH_SIZE);
2382
+
2383
+ // Increment the stream size and number of blocks
2384
+ pStream->StreamSize += (BlockCount * BLOCK4_BLOCK_SIZE);
2385
+ pStream->BlockCount += (DWORD)BlockCount;
2386
+
2387
+ // Is this the last file?
2388
+ if(FileSize < BLOCK4_MAX_FSIZE)
2389
+ {
2390
+ if(RemainderBlock)
2391
+ {
2392
+ pStream->StreamSize += (RemainderBlock - BLOCK4_HASH_SIZE);
2393
+ pStream->BlockCount++;
2394
+ }
2395
+ break;
2396
+ }
2397
+ }
2398
+
2399
+ // Fill the remainining block stream variables
2400
+ pStream->BitmapSize = dwBaseFiles;
2401
+ pStream->BlockSize = BLOCK4_BLOCK_SIZE;
2402
+ pStream->IsComplete = 1;
2403
+ pStream->IsModified = 0;
2404
+
2405
+ // Fill the remaining stream variables
2406
+ pStream->StreamPos = 0;
2407
+ pStream->dwFlags |= STREAM_FLAG_READ_ONLY;
2408
+
2409
+ STORM_FREE(szNameBuff);
2410
+ }
2411
+
2412
+ // If we opened something, return success
2413
+ if(dwBaseFiles == 0)
2414
+ {
2415
+ FileStream_Close(pStream);
2416
+ SetLastError(ERROR_FILE_NOT_FOUND);
2417
+ pStream = NULL;
2418
+ }
2419
+
2420
+ return pStream;
2421
+ }
2422
+
2423
+ //-----------------------------------------------------------------------------
2424
+ // Public functions
2425
+
2426
+ /**
2427
+ * This function creates a new file for read-write access
2428
+ *
2429
+ * - If the current platform supports file sharing,
2430
+ * the file must be created for read sharing (i.e. another application
2431
+ * can open the file for read, but not for write)
2432
+ * - If the file does not exist, the function must create new one
2433
+ * - If the file exists, the function must rewrite it and set to zero size
2434
+ * - The parameters of the function must be validate by the caller
2435
+ * - The function must initialize all stream function pointers in TFileStream
2436
+ * - If the function fails from any reason, it must close all handles
2437
+ * and free all memory that has been allocated in the process of stream creation,
2438
+ * including the TFileStream structure itself
2439
+ *
2440
+ * \a szFileName Name of the file to create
2441
+ */
2442
+
2443
+ TFileStream * FileStream_CreateFile(
2444
+ const TCHAR * szFileName,
2445
+ DWORD dwStreamFlags)
2446
+ {
2447
+ TFileStream * pStream;
2448
+
2449
+ // We only support creation of flat, local file
2450
+ if((dwStreamFlags & (STREAM_PROVIDERS_MASK)) != (STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE))
2451
+ {
2452
+ SetLastError(ERROR_NOT_SUPPORTED);
2453
+ return NULL;
2454
+ }
2455
+
2456
+ // Allocate file stream structure for flat stream
2457
+ pStream = AllocateFileStream(szFileName, sizeof(TBlockStream), dwStreamFlags);
2458
+ if(pStream != NULL)
2459
+ {
2460
+ // Attempt to create the disk file
2461
+ if(BaseFile_Create(pStream))
2462
+ {
2463
+ // Fill the stream provider functions
2464
+ pStream->StreamRead = pStream->BaseRead;
2465
+ pStream->StreamWrite = pStream->BaseWrite;
2466
+ pStream->StreamResize = pStream->BaseResize;
2467
+ pStream->StreamGetSize = pStream->BaseGetSize;
2468
+ pStream->StreamGetPos = pStream->BaseGetPos;
2469
+ pStream->StreamClose = pStream->BaseClose;
2470
+ return pStream;
2471
+ }
2472
+
2473
+ // File create failed, delete the stream
2474
+ STORM_FREE(pStream);
2475
+ pStream = NULL;
2476
+ }
2477
+
2478
+ // Return the stream
2479
+ return pStream;
2480
+ }
2481
+
2482
+ /**
2483
+ * This function opens an existing file for read or read-write access
2484
+ * - If the current platform supports file sharing,
2485
+ * the file must be open for read sharing (i.e. another application
2486
+ * can open the file for read, but not for write)
2487
+ * - If the file does not exist, the function must return NULL
2488
+ * - If the file exists but cannot be open, then function must return NULL
2489
+ * - The parameters of the function must be validate by the caller
2490
+ * - The function must initialize all stream function pointers in TFileStream
2491
+ * - If the function fails from any reason, it must close all handles
2492
+ * and free all memory that has been allocated in the process of stream creation,
2493
+ * including the TFileStream structure itself
2494
+ *
2495
+ * \a szFileName Name of the file to open
2496
+ * \a dwStreamFlags specifies the provider and base storage type
2497
+ */
2498
+
2499
+ TFileStream * FileStream_OpenFile(
2500
+ const TCHAR * szFileName,
2501
+ DWORD dwStreamFlags)
2502
+ {
2503
+ DWORD dwProvider = dwStreamFlags & STREAM_PROVIDERS_MASK;
2504
+ size_t nPrefixLength = FileStream_Prefix(szFileName, &dwProvider);
2505
+
2506
+ // Re-assemble the stream flags
2507
+ dwStreamFlags = (dwStreamFlags & STREAM_OPTIONS_MASK) | dwProvider;
2508
+ szFileName += nPrefixLength;
2509
+
2510
+ // Perform provider-specific open
2511
+ switch(dwStreamFlags & STREAM_PROVIDER_MASK)
2512
+ {
2513
+ case STREAM_PROVIDER_FLAT:
2514
+ return FlatStream_Open(szFileName, dwStreamFlags);
2515
+
2516
+ case STREAM_PROVIDER_PARTIAL:
2517
+ return PartStream_Open(szFileName, dwStreamFlags);
2518
+
2519
+ case STREAM_PROVIDER_MPQE:
2520
+ return MpqeStream_Open(szFileName, dwStreamFlags);
2521
+
2522
+ case STREAM_PROVIDER_BLOCK4:
2523
+ return Block4Stream_Open(szFileName, dwStreamFlags);
2524
+
2525
+ default:
2526
+ SetLastError(ERROR_INVALID_PARAMETER);
2527
+ return NULL;
2528
+ }
2529
+ }
2530
+
2531
+ /**
2532
+ * Returns the file name of the stream
2533
+ *
2534
+ * \a pStream Pointer to an open stream
2535
+ */
2536
+ const TCHAR * FileStream_GetFileName(TFileStream * pStream)
2537
+ {
2538
+ assert(pStream != NULL);
2539
+ return pStream->szFileName;
2540
+ }
2541
+
2542
+ /**
2543
+ * Returns the length of the provider prefix. Returns zero if no prefix
2544
+ *
2545
+ * \a szFileName Pointer to a stream name (file, mapped file, URL)
2546
+ * \a pdwStreamProvider Pointer to a DWORD variable that receives stream provider (STREAM_PROVIDER_XXX)
2547
+ */
2548
+
2549
+ size_t FileStream_Prefix(const TCHAR * szFileName, DWORD * pdwProvider)
2550
+ {
2551
+ size_t nPrefixLength1 = 0;
2552
+ size_t nPrefixLength2 = 0;
2553
+ DWORD dwProvider = 0;
2554
+
2555
+ if(szFileName != NULL)
2556
+ {
2557
+ //
2558
+ // Determine the stream provider
2559
+ //
2560
+
2561
+ if(!_tcsnicmp(szFileName, _T("flat-"), 5))
2562
+ {
2563
+ dwProvider |= STREAM_PROVIDER_FLAT;
2564
+ nPrefixLength1 = 5;
2565
+ }
2566
+
2567
+ else if(!_tcsnicmp(szFileName, _T("part-"), 5))
2568
+ {
2569
+ dwProvider |= STREAM_PROVIDER_PARTIAL;
2570
+ nPrefixLength1 = 5;
2571
+ }
2572
+
2573
+ else if(!_tcsnicmp(szFileName, _T("mpqe-"), 5))
2574
+ {
2575
+ dwProvider |= STREAM_PROVIDER_MPQE;
2576
+ nPrefixLength1 = 5;
2577
+ }
2578
+
2579
+ else if(!_tcsnicmp(szFileName, _T("blk4-"), 5))
2580
+ {
2581
+ dwProvider |= STREAM_PROVIDER_BLOCK4;
2582
+ nPrefixLength1 = 5;
2583
+ }
2584
+
2585
+ //
2586
+ // Determine the base provider
2587
+ //
2588
+
2589
+ if(!_tcsnicmp(szFileName+nPrefixLength1, _T("file:"), 5))
2590
+ {
2591
+ dwProvider |= BASE_PROVIDER_FILE;
2592
+ nPrefixLength2 = 5;
2593
+ }
2594
+
2595
+ else if(!_tcsnicmp(szFileName+nPrefixLength1, _T("map:"), 4))
2596
+ {
2597
+ dwProvider |= BASE_PROVIDER_MAP;
2598
+ nPrefixLength2 = 4;
2599
+ }
2600
+
2601
+ else if(!_tcsnicmp(szFileName+nPrefixLength1, _T("http:"), 5))
2602
+ {
2603
+ dwProvider |= BASE_PROVIDER_HTTP;
2604
+ nPrefixLength2 = 5;
2605
+ }
2606
+
2607
+ // Only accept stream provider if we recognized the base provider
2608
+ if(nPrefixLength2 != 0)
2609
+ {
2610
+ // It is also allowed to put "//" after the base provider, e.g. "file://", "http://"
2611
+ if(szFileName[nPrefixLength1+nPrefixLength2] == '/' && szFileName[nPrefixLength1+nPrefixLength2+1] == '/')
2612
+ nPrefixLength2 += 2;
2613
+
2614
+ if(pdwProvider != NULL)
2615
+ *pdwProvider = dwProvider;
2616
+ return nPrefixLength1 + nPrefixLength2;
2617
+ }
2618
+ }
2619
+
2620
+ return 0;
2621
+ }
2622
+
2623
+ /**
2624
+ * Sets a download callback. Whenever the stream needs to download one or more blocks
2625
+ * from the server, the callback is called
2626
+ *
2627
+ * \a pStream Pointer to an open stream
2628
+ * \a pfnCallback Pointer to callback function
2629
+ * \a pvUserData Arbitrary user pointer passed to the download callback
2630
+ */
2631
+
2632
+ bool FileStream_SetCallback(TFileStream * pStream, SFILE_DOWNLOAD_CALLBACK pfnCallback, void * pvUserData)
2633
+ {
2634
+ TBlockStream * pBlockStream = (TBlockStream *)pStream;
2635
+
2636
+ if(pStream->BlockRead == NULL)
2637
+ {
2638
+ SetLastError(ERROR_NOT_SUPPORTED);
2639
+ return false;
2640
+ }
2641
+
2642
+ pBlockStream->pfnCallback = pfnCallback;
2643
+ pBlockStream->UserData = pvUserData;
2644
+ return true;
2645
+ }
2646
+
2647
+ /**
2648
+ * This function gives the block map. The 'pvBitmap' pointer must point to a buffer
2649
+ * of at least sizeof(STREAM_BLOCK_MAP) size. It can also have size of the complete
2650
+ * block map (i.e. sizeof(STREAM_BLOCK_MAP) + BitmapSize). In that case, the function
2651
+ * also copies the bit-based block map.
2652
+ *
2653
+ * \a pStream Pointer to an open stream
2654
+ * \a pvBitmap Pointer to buffer where the block map will be stored
2655
+ * \a cbBitmap Length of the buffer, of the block map
2656
+ * \a cbLengthNeeded Length of the bitmap, in bytes
2657
+ */
2658
+
2659
+ bool FileStream_GetBitmap(TFileStream * pStream, void * pvBitmap, DWORD cbBitmap, DWORD * pcbLengthNeeded)
2660
+ {
2661
+ TStreamBitmap * pBitmap = (TStreamBitmap *)pvBitmap;
2662
+ TBlockStream * pBlockStream = (TBlockStream *)pStream;
2663
+ ULONGLONG BlockOffset;
2664
+ LPBYTE Bitmap = (LPBYTE)(pBitmap + 1);
2665
+ DWORD BitmapSize;
2666
+ DWORD BlockCount;
2667
+ DWORD BlockSize;
2668
+ bool bResult = false;
2669
+
2670
+ // Retrieve the size of one block
2671
+ if(pStream->BlockCheck != NULL)
2672
+ {
2673
+ BlockCount = pBlockStream->BlockCount;
2674
+ BlockSize = pBlockStream->BlockSize;
2675
+ }
2676
+ else
2677
+ {
2678
+ BlockCount = (DWORD)((pStream->StreamSize + DEFAULT_BLOCK_SIZE - 1) / DEFAULT_BLOCK_SIZE);
2679
+ BlockSize = DEFAULT_BLOCK_SIZE;
2680
+ }
2681
+
2682
+ // Fill-in the variables
2683
+ BitmapSize = (BlockCount + 7) / 8;
2684
+
2685
+ // Give the number of blocks
2686
+ if(pcbLengthNeeded != NULL)
2687
+ pcbLengthNeeded[0] = sizeof(TStreamBitmap) + BitmapSize;
2688
+
2689
+ // If the length of the buffer is not enough
2690
+ if(pvBitmap != NULL && cbBitmap != 0)
2691
+ {
2692
+ // Give the STREAM_BLOCK_MAP structure
2693
+ if(cbBitmap >= sizeof(TStreamBitmap))
2694
+ {
2695
+ pBitmap->StreamSize = pStream->StreamSize;
2696
+ pBitmap->BitmapSize = BitmapSize;
2697
+ pBitmap->BlockCount = BlockCount;
2698
+ pBitmap->BlockSize = BlockSize;
2699
+ pBitmap->IsComplete = (pStream->BlockCheck != NULL) ? pBlockStream->IsComplete : 1;
2700
+ bResult = true;
2701
+ }
2702
+
2703
+ // Give the block bitmap, if enough space
2704
+ if(cbBitmap >= sizeof(TStreamBitmap) + BitmapSize)
2705
+ {
2706
+ // Version with bitmap present
2707
+ if(pStream->BlockCheck != NULL)
2708
+ {
2709
+ DWORD ByteIndex = 0;
2710
+ BYTE BitMask = 0x01;
2711
+
2712
+ // Initialize the map with zeros
2713
+ memset(Bitmap, 0, BitmapSize);
2714
+
2715
+ // Fill the map
2716
+ for(BlockOffset = 0; BlockOffset < pStream->StreamSize; BlockOffset += BlockSize)
2717
+ {
2718
+ // Set the bit if the block is present
2719
+ if(pBlockStream->BlockCheck(pStream, BlockOffset))
2720
+ Bitmap[ByteIndex] |= BitMask;
2721
+
2722
+ // Move bit position
2723
+ ByteIndex += (BitMask >> 0x07);
2724
+ BitMask = (BitMask >> 0x07) | (BitMask << 0x01);
2725
+ }
2726
+ }
2727
+ else
2728
+ {
2729
+ memset(Bitmap, 0xFF, BitmapSize);
2730
+ }
2731
+ }
2732
+ }
2733
+
2734
+ // Set last error value and return
2735
+ if(bResult == false)
2736
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
2737
+ return bResult;
2738
+ }
2739
+
2740
+ /**
2741
+ * Reads data from the stream
2742
+ *
2743
+ * - Returns true if the read operation succeeded and all bytes have been read
2744
+ * - Returns false if either read failed or not all bytes have been read
2745
+ * - If the pByteOffset is NULL, the function must read the data from the current file position
2746
+ * - The function can be called with dwBytesToRead = 0. In that case, pvBuffer is ignored
2747
+ * and the function just adjusts file pointer.
2748
+ *
2749
+ * \a pStream Pointer to an open stream
2750
+ * \a pByteOffset Pointer to file byte offset. If NULL, it reads from the current position
2751
+ * \a pvBuffer Pointer to data to be read
2752
+ * \a dwBytesToRead Number of bytes to read from the file
2753
+ *
2754
+ * \returns
2755
+ * - If the function reads the required amount of bytes, it returns true.
2756
+ * - If the function reads less than required bytes, it returns false and GetLastError() returns ERROR_HANDLE_EOF
2757
+ * - If the function fails, it reads false and GetLastError() returns an error code different from ERROR_HANDLE_EOF
2758
+ */
2759
+ bool FileStream_Read(TFileStream * pStream, ULONGLONG * pByteOffset, void * pvBuffer, DWORD dwBytesToRead)
2760
+ {
2761
+ assert(pStream->StreamRead != NULL);
2762
+ return pStream->StreamRead(pStream, pByteOffset, pvBuffer, dwBytesToRead);
2763
+ }
2764
+
2765
+ /**
2766
+ * This function writes data to the stream
2767
+ *
2768
+ * - Returns true if the write operation succeeded and all bytes have been written
2769
+ * - Returns false if either write failed or not all bytes have been written
2770
+ * - If the pByteOffset is NULL, the function must write the data to the current file position
2771
+ *
2772
+ * \a pStream Pointer to an open stream
2773
+ * \a pByteOffset Pointer to file byte offset. If NULL, it reads from the current position
2774
+ * \a pvBuffer Pointer to data to be written
2775
+ * \a dwBytesToWrite Number of bytes to write to the file
2776
+ */
2777
+ bool FileStream_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite)
2778
+ {
2779
+ if(pStream->dwFlags & STREAM_FLAG_READ_ONLY)
2780
+ {
2781
+ SetLastError(ERROR_ACCESS_DENIED);
2782
+ return false;
2783
+ }
2784
+
2785
+ assert(pStream->StreamWrite != NULL);
2786
+ return pStream->StreamWrite(pStream, pByteOffset, pvBuffer, dwBytesToWrite);
2787
+ }
2788
+
2789
+ /**
2790
+ * Returns the size of a file
2791
+ *
2792
+ * \a pStream Pointer to an open stream
2793
+ * \a FileSize Pointer where to store the file size
2794
+ */
2795
+ bool FileStream_GetSize(TFileStream * pStream, ULONGLONG * pFileSize)
2796
+ {
2797
+ assert(pStream->StreamGetSize != NULL);
2798
+ return pStream->StreamGetSize(pStream, pFileSize);
2799
+ }
2800
+
2801
+ /**
2802
+ * Sets the size of a file
2803
+ *
2804
+ * \a pStream Pointer to an open stream
2805
+ * \a NewFileSize File size to set
2806
+ */
2807
+ bool FileStream_SetSize(TFileStream * pStream, ULONGLONG NewFileSize)
2808
+ {
2809
+ if(pStream->dwFlags & STREAM_FLAG_READ_ONLY)
2810
+ {
2811
+ SetLastError(ERROR_ACCESS_DENIED);
2812
+ return false;
2813
+ }
2814
+
2815
+ assert(pStream->StreamResize != NULL);
2816
+ return pStream->StreamResize(pStream, NewFileSize);
2817
+ }
2818
+
2819
+ /**
2820
+ * This function returns the current file position
2821
+ * \a pStream
2822
+ * \a pByteOffset
2823
+ */
2824
+ bool FileStream_GetPos(TFileStream * pStream, ULONGLONG * pByteOffset)
2825
+ {
2826
+ assert(pStream->StreamGetPos != NULL);
2827
+ return pStream->StreamGetPos(pStream, pByteOffset);
2828
+ }
2829
+
2830
+ /**
2831
+ * Returns the last write time of a file
2832
+ *
2833
+ * \a pStream Pointer to an open stream
2834
+ * \a pFileType Pointer where to store the file last write time
2835
+ */
2836
+ bool FileStream_GetTime(TFileStream * pStream, ULONGLONG * pFileTime)
2837
+ {
2838
+ // Just use the saved filetime value
2839
+ *pFileTime = pStream->Base.File.FileTime;
2840
+ return true;
2841
+ }
2842
+
2843
+ /**
2844
+ * Returns the stream flags
2845
+ *
2846
+ * \a pStream Pointer to an open stream
2847
+ * \a pdwStreamFlags Pointer where to store the stream flags
2848
+ */
2849
+ bool FileStream_GetFlags(TFileStream * pStream, LPDWORD pdwStreamFlags)
2850
+ {
2851
+ *pdwStreamFlags = pStream->dwFlags;
2852
+ return true;
2853
+ }
2854
+
2855
+ /**
2856
+ * Switches a stream with another. Used for final phase of archive compacting.
2857
+ * Performs these steps:
2858
+ *
2859
+ * 1) Closes the handle to the existing MPQ
2860
+ * 2) Renames the temporary MPQ to the original MPQ, overwrites existing one
2861
+ * 3) Opens the MPQ stores the handle and stream position to the new stream structure
2862
+ *
2863
+ * \a pStream Pointer to an open stream
2864
+ * \a pNewStream Temporary ("working") stream (created during archive compacting)
2865
+ */
2866
+ bool FileStream_Replace(TFileStream * pStream, TFileStream * pNewStream)
2867
+ {
2868
+ // Only supported on flat files
2869
+ if((pStream->dwFlags & STREAM_PROVIDERS_MASK) != (STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE))
2870
+ {
2871
+ SetLastError(ERROR_NOT_SUPPORTED);
2872
+ return false;
2873
+ }
2874
+
2875
+ // Not supported on read-only streams
2876
+ if(pStream->dwFlags & STREAM_FLAG_READ_ONLY)
2877
+ {
2878
+ SetLastError(ERROR_ACCESS_DENIED);
2879
+ return false;
2880
+ }
2881
+
2882
+ // Close both stream's base providers
2883
+ pNewStream->BaseClose(pNewStream);
2884
+ pStream->BaseClose(pStream);
2885
+
2886
+ // Now we have to delete the (now closed) old file and rename the new file
2887
+ if(!BaseFile_Replace(pStream, pNewStream))
2888
+ return false;
2889
+
2890
+ // Now open the base file again
2891
+ if(!BaseFile_Open(pStream, pStream->szFileName, pStream->dwFlags))
2892
+ return false;
2893
+
2894
+ // Cleanup the new stream
2895
+ FileStream_Close(pNewStream);
2896
+ return true;
2897
+ }
2898
+
2899
+ /**
2900
+ * This function closes an archive file and frees any data buffers
2901
+ * that have been allocated for stream management. The function must also
2902
+ * support partially allocated structure, i.e. one or more buffers
2903
+ * can be NULL, if there was an allocation failure during the process
2904
+ *
2905
+ * \a pStream Pointer to an open stream
2906
+ */
2907
+ void FileStream_Close(TFileStream * pStream)
2908
+ {
2909
+ // Check if the stream structure is allocated at all
2910
+ if(pStream != NULL)
2911
+ {
2912
+ // Free the master stream, if any
2913
+ if(pStream->pMaster != NULL)
2914
+ FileStream_Close(pStream->pMaster);
2915
+ pStream->pMaster = NULL;
2916
+
2917
+ // Close the stream provider
2918
+ if(pStream->StreamClose != NULL)
2919
+ pStream->StreamClose(pStream);
2920
+
2921
+ // ... or close base stream, if any
2922
+ else if(pStream->BaseClose != NULL)
2923
+ pStream->BaseClose(pStream);
2924
+
2925
+ // Free the stream itself
2926
+ STORM_FREE(pStream);
2927
+ }
2928
+ }