stormlib 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }