summaryrefslogtreecommitdiff
path: root/mpq-bios.c
diff options
context:
space:
mode:
authorpixel <pixel>2007-07-06 07:19:32 +0000
committerpixel <pixel>2007-07-06 07:19:32 +0000
commit5537df7e088d8b67c82ae058bbf496f906778291 (patch)
tree35eb14302d8f66860d278ea8b47c54c7f6fe6574 /mpq-bios.c
parente12fcb08a14de1f5738e0162bba50cdbf87dee47 (diff)
Basic archive opening done.
Diffstat (limited to 'mpq-bios.c')
-rw-r--r--mpq-bios.c58
1 files changed, 55 insertions, 3 deletions
diff --git a/mpq-bios.c b/mpq-bios.c
index e37a462..bbca00c 100644
--- a/mpq-bios.c
+++ b/mpq-bios.c
@@ -6,6 +6,7 @@
#include <stdlib.h>
#include <string.h>
+#include "MPQCryptography.h"
#include "mpq-bios.h"
#include "mpq-errors.h"
#include "errors.h"
@@ -140,6 +141,11 @@ mpq_archive_t * mpqlib_reopen_archive(int fd) {
mpq_header_t mpq_h;
mpq_hash_t * mpq_hashs;
mpq_block_t * mpq_blocks;
+ uint16_t * mpq_extblocks = NULL;
+ int i;
+
+ /****TODO****/
+ /* Implement endianess a bit everywhere */
if (!(mpq_i = (struct mpq_internals_t *) malloc(sizeof(struct mpq_internals_t)))) {
__mpqlib_errno = MPQLIB_ERROR_MEMORY;
@@ -213,15 +219,61 @@ mpq_archive_t * mpqlib_reopen_archive(int fd) {
return NULL;
}
- lseek64(fd, mpq_i->hash_table_offset, SEEK_SET);
-
+ if (lseek64(fd, mpq_i->hash_table_offset, SEEK_SET) != mpq_i->hash_table_offset)
+ read_error();
if (!read_data(mpq_a, mpq_hashs, mpq_i->hash_table_entries * sizeof(mpq_hash_t)))
read_error();
+ if (lseek64(fd, mpq_i->block_table_offset, SEEK_SET) != mpq_i->block_table_offset)
+ read_error();
if (!read_data(mpq_a, mpq_blocks, mpq_i->block_table_entries * sizeof(mpq_block_t)))
read_error();
- // decrypt everything now.
+ if (mpq_i->extended_block_table_offset) {
+ if (lseek64(fd, mpq_i->block_table_offset, SEEK_SET))
+ read_error();
+
+ if (!(mpq_extblocks = (uint16_t *) malloc(mpq_i->block_table_entries * sizeof(uint16_t)))) {
+ __mpqlib_errno = MPQLIB_ERROR_MEMORY;
+ free_archive(mpq_a);
+ free(mpq_hashs);
+ free(mpq_blocks);
+ return NULL;
+ }
+
+ if (!read_data(mpq_a, mpq_blocks, mpq_i->block_table_entries * sizeof(mpq_block_t))) {
+ free(mpq_extblocks);
+ read_error();
+ }
+ }
+
+ __mpqlib_decrypt(mpq_hashs, mpq_i->hash_table_entries * sizeof(mpq_block_t), __mpqlib_hash_cstring("(hash table)", 3), 1);
+ __mpqlib_decrypt(mpq_blocks, mpq_i->block_table_entries * sizeof(mpq_block_t), __mpqlib_hash_cstring("(block table)", 3), 1);
+
+ for (i = 0; i < mpq_i->hash_table_entries; i++) {
+ /****TODO****/
+ /* Implement various checks of the hash table. */
+ mpq_i->hashs[i].file_path_hasha = mpq_hashs[i].file_path_hasha;
+ mpq_i->hashs[i].file_path_hashb = mpq_hashs[i].file_path_hashb;
+ mpq_i->hashs[i].language = mpq_hashs[i].language;
+ mpq_i->hashs[i].platform = mpq_hashs[i].platform;
+ mpq_i->hashs[i].file_block_index = mpq_hashs[i].file_block_index;
+ }
+
+ for (i = 0; i < mpq_i->block_table_entries; i++) {
+ /****TODO****/
+ /* Implement various checks of the block table. */
+ mpq_i->blocks[i].block_offset = mpq_blocks[i].block_offset + (mpq_extblocks ? (((uint64_t) mpq_extblocks[i]) << 32): 0);
+ mpq_i->blocks[i].block_size = mpq_blocks[i].block_size;
+ mpq_i->blocks[i].file_size = mpq_blocks[i].file_size;
+ mpq_i->blocks[i].flags = mpq_blocks[i].flags;
+ }
+
+ if (mpq_extblocks)
+ free(mpq_extblocks);
+
+ free(mpq_blocks);
+ free(mpq_hashs);
return mpq_a;
}