From 5537df7e088d8b67c82ae058bbf496f906778291 Mon Sep 17 00:00:00 2001 From: pixel Date: Fri, 6 Jul 2007 07:19:32 +0000 Subject: Basic archive opening done. --- mpq-bios.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) (limited to 'mpq-bios.c') 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 #include +#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; } -- cgit v1.2.3