summaryrefslogtreecommitdiff
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
parente12fcb08a14de1f5738e0162bba50cdbf87dee47 (diff)
Basic archive opening done.
-rw-r--r--MPQCryptography.c9
-rw-r--r--MPQCryptography.h4
-rw-r--r--mpq-bios.c58
3 files changed, 64 insertions, 7 deletions
diff --git a/MPQCryptography.c b/MPQCryptography.c
index 5cd29d3..798d80e 100644
--- a/MPQCryptography.c
+++ b/MPQCryptography.c
@@ -23,6 +23,9 @@
static int crypt_table_initialized = 0;
static uint32_t crypt_table[0x500];
+/****TODO****/
+/* Re-implement various endianess fixes. */
+
static void memrev(unsigned char *buf, size_t count)
{
unsigned char *r;
@@ -72,8 +75,9 @@ void __mpqlib_init_cryptography()
ERR_load_crypto_strings();
}
-void __mpqlib_encrypt(char *data, uint32_t length, uint32_t key, bool disable_input_swapping)
+void __mpqlib_encrypt(void *_data, uint32_t length, uint32_t key, bool disable_input_swapping)
{
+ char * data = (char *) _data;
assert(crypt_table_initialized);
assert(data);
@@ -108,8 +112,9 @@ void __mpqlib_encrypt(char *data, uint32_t length, uint32_t key, bool disable_in
}
}
-void __mpqlib_decrypt(char *data, uint32_t length, uint32_t key, bool disable_output_swapping)
+void __mpqlib_decrypt(void *_data, uint32_t length, uint32_t key, bool disable_output_swapping)
{
+ char * data = (char *) _data;
assert(crypt_table_initialized);
assert(data);
diff --git a/MPQCryptography.h b/MPQCryptography.h
index e8af48e..b1d621e 100644
--- a/MPQCryptography.h
+++ b/MPQCryptography.h
@@ -27,9 +27,9 @@ extern "C" {
const uint32_t *__mpqlib_get_cryptography_table(void);
- void __mpqlib_encrypt(char *data, uint32_t length, uint32_t key,
+ void __mpqlib_encrypt(void *data, uint32_t length, uint32_t key,
bool disable_input_swapping);
- void __mpqlib_decrypt(char *data, uint32_t length, uint32_t key,
+ void __mpqlib_decrypt(void *data, uint32_t length, uint32_t key,
bool disable_output_swapping);
uint32_t __mpqlib_hash_cstring(const char *string, uint32_t type);
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;
}