summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpixel <pixel>2007-07-11 14:23:29 +0000
committerpixel <pixel>2007-07-11 14:23:29 +0000
commit26fcbbdd26a389b6979a966ae8dd49a40a6a1d05 (patch)
treebbf63c4080bcba14aa7d02176dc23b920a70514c
parent2b81447acc91685dbfb6419282a0f53b6ac3eaa0 (diff)
Adding comments.
-rw-r--r--MPQCryptography.c5
-rw-r--r--extract.c4
-rw-r--r--int-bios.h4
-rw-r--r--mpq-bios.c31
-rw-r--r--mpq-errors.c1
-rw-r--r--mpq-errors.h1
-rw-r--r--mpq-file.c15
-rw-r--r--mpq-fs.c16
-rw-r--r--mpq-misc.c4
9 files changed, 81 insertions, 0 deletions
diff --git a/MPQCryptography.c b/MPQCryptography.c
index 798d80e..464a410 100644
--- a/MPQCryptography.c
+++ b/MPQCryptography.c
@@ -7,6 +7,11 @@
*
*/
+/*
+ * Ripped for mpqlib - all endinaness stuff has been killed.
+ * Other than that, this is the exact same code.
+ */
+
#include <assert.h>
#include <string.h>
#include <zlib.h>
diff --git a/extract.c b/extract.c
index 2bd47e9..905ee83 100644
--- a/extract.c
+++ b/extract.c
@@ -18,6 +18,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+
+/*
+ * Ripped from libmpq and compacted into this one large file.
+ */
#include <stdlib.h>
#include <stdio.h>
diff --git a/int-bios.h b/int-bios.h
index 1508218..83676f9 100644
--- a/int-bios.h
+++ b/int-bios.h
@@ -3,6 +3,10 @@
#include <mpq-bios.h>
+/*
+ * Internal BIOS functions.
+ */
+
int __mpqlib_seek(struct mpq_archive_t *, uint64_t);
int __mpqlib_read(struct mpq_archive_t *, void *, uint32_t);
diff --git a/mpq-bios.c b/mpq-bios.c
index 88da2ac..8251b95 100644
--- a/mpq-bios.c
+++ b/mpq-bios.c
@@ -14,6 +14,10 @@
#include "errors.h"
#include "inttypes.h"
+/*
+ * MPQ header.
+ */
+
typedef struct {
/* basic version of the header. */
char magic[4];
@@ -33,6 +37,10 @@ typedef struct {
uint16_t block_table_offset_high;
} __attribute__ ((packed)) mpq_header_t;
+/*
+ * One hash entry.
+ */
+
typedef struct {
uint32_t file_path_hasha;
uint32_t file_path_hashb;
@@ -41,6 +49,10 @@ typedef struct {
uint32_t file_block_index;
} __attribute__ ((packed)) mpq_hash_t;
+/*
+ * One block entry.
+ */
+
typedef struct {
uint32_t block_offset;
uint32_t block_size;
@@ -48,6 +60,11 @@ typedef struct {
uint32_t flags;
} __attribute__ ((packed)) mpq_block_t;
+
+/*
+ * This are our internal structures.
+ */
+
typedef struct {
uint32_t file_path_hasha;
uint32_t file_path_hashb;
@@ -169,15 +186,18 @@ struct mpq_archive_t * mpqlib_reopen_archive(int fd) {
mpq_a->closeit = 0;
mpq_a->fd = fd;
+ /* Reading the main header, and doing basic checks. */
if (read(fd, &mpq_h, STD_HEADER_SIZE) != STD_HEADER_SIZE)
no_mpq();
if (strncmp(mpq_h.magic, "MPQ\x1a", 4))
no_mpq();
+ /* format_version can only be 0 or 1 - the latter beeing for Burning Crusade */
if ((mpq_h.format_version | 1) != 1)
no_mpq();
+ /* If the format is extended, let's read the extra data, otherwise let's fill it with zeroes */
if (mpq_h.format_version == 1) {
if (!read_data(mpq_a, ((char *)(&mpq_h)) + STD_HEADER_SIZE, EXT_HEADER_SIZE))
no_mpq();
@@ -187,6 +207,7 @@ struct mpq_archive_t * mpqlib_reopen_archive(int fd) {
mpq_h.block_table_offset_high = 0;
}
+ /* Let's start copying / interpreting / rebuilding basic header data */
mpq_a->header_size = mpq_h.header_size;
mpq_a->archive_size = mpq_h.archive_size;
mpq_a->format_version = mpq_h.format_version;
@@ -198,6 +219,7 @@ struct mpq_archive_t * mpqlib_reopen_archive(int fd) {
mpq_a->block_table_entries = mpq_h.block_table_entries;
mpq_a->extended_block_table_offset = mpq_h.extended_block_table_offset;
+ /* Allocation and reading of our hash and block tables */
if (!(mpq_a->hashs = (hash_t *) malloc(mpq_a->hash_table_entries * sizeof(hash_t)))) {
__mpqlib_errno = MPQLIB_ERROR_MEMORY;
free(mpq_a);
@@ -252,9 +274,11 @@ struct mpq_archive_t * mpqlib_reopen_archive(int fd) {
}
}
+ /* Hash and block table are (easily) encrypted - let's decrypt them before going on any further */
__mpqlib_decrypt(mpq_hashs, mpq_a->hash_table_entries * sizeof(mpq_block_t), __mpqlib_hash_cstring("(hash table)", 3), 1);
__mpqlib_decrypt(mpq_blocks, mpq_a->block_table_entries * sizeof(mpq_block_t), __mpqlib_hash_cstring("(block table)", 3), 1);
+ /* Copying / interpreting / rebuilding of the hash table. */
for (i = 0; i < mpq_a->hash_table_entries; i++) {
/****TODO****/
/* Implement various checks of the hash table. */
@@ -265,6 +289,7 @@ struct mpq_archive_t * mpqlib_reopen_archive(int fd) {
mpq_a->hashs[i].file_block_index = mpq_hashs[i].file_block_index;
}
+ /* Copying / interpreting / rebuilding of the block table. */
for (i = 0; i < mpq_a->block_table_entries; i++) {
/****TODO****/
/* Implement various checks of the block table. */
@@ -274,6 +299,7 @@ struct mpq_archive_t * mpqlib_reopen_archive(int fd) {
mpq_a->blocks[i].flags = mpq_blocks[i].flags;
}
+ /* All done, let's clean up and exit. */
if (mpq_extblocks)
free(mpq_extblocks);
@@ -283,6 +309,10 @@ struct mpq_archive_t * mpqlib_reopen_archive(int fd) {
return mpq_a;
}
+/*
+ * Verbose display of an archive.
+ */
+
void mpqlib_printtables(struct mpq_archive_t * mpq_a) {
int i;
@@ -327,6 +357,7 @@ int mpqlib_find_hash_entry_by_name(struct mpq_archive_t * mpq_a, const char * na
int mpqlib_find_hash_entry_by_hash(struct mpq_archive_t * mpq_a, uint32_t h, uint32_t hA, uint32_t hB, uint32_t language, uint32_t platform) {
int i;
+ /* The hash table is a true one, pre-built. We can access it as-it, speeding up the searches drastically. */
for (i = h & (mpq_a->hash_table_entries - 1); i < mpq_a->hash_table_entries; i++) {
if ((mpq_a->hashs[i].file_path_hasha == hA) &&
(mpq_a->hashs[i].file_path_hashb == hB) &&
diff --git a/mpq-errors.c b/mpq-errors.c
index 780b305..856ae12 100644
--- a/mpq-errors.c
+++ b/mpq-errors.c
@@ -10,6 +10,7 @@ static const char * error_strings[] = {
"File read error.",
"Invalid ioctl.",
"Invalid ioctl's file entry.",
+ "File not found.",
"Entry isn't a file.",
"Imploded compression not supported yet.",
"File isn't flagged as compressed - not supported yet.",
diff --git a/mpq-errors.h b/mpq-errors.h
index f452904..d9918c4 100644
--- a/mpq-errors.h
+++ b/mpq-errors.h
@@ -21,6 +21,7 @@ enum {
MPQLIB_ERROR_READ,
MPQLIB_ERROR_INVALID_IOCTL,
MPQLIB_ERROR_IOCTL_INVALID_ENTRY,
+ MPQLIB_ERROR_FILE_NOT_FOUND,
MPQLIB_ERROR_NOT_A_FILE,
MPQLIB_ERROR_NOT_SUPPORTED,
MPQLIB_ERROR_NOT_COMPRESSED,
diff --git a/mpq-file.c b/mpq-file.c
index 7bafd2f..f6a26d8 100644
--- a/mpq-file.c
+++ b/mpq-file.c
@@ -33,7 +33,10 @@ struct mpq_file_t * mpqlib_open_file(struct mpq_archive_t * mpq_a, int entry) {
__mpqlib_errno = MPQLIB_ERROR_NO_ERROR;
+ /* Basic checks of the entry. */
+
if (mpqlib_ioctl(mpq_a, MPQLIB_IOCTL_ENTRY_EXISTS, entry)) {
+ __mpqlib_errno = MPQLIB_ERROR_FILE_NOT_FOUND;
return NULL;
}
@@ -49,6 +52,7 @@ struct mpq_file_t * mpqlib_open_file(struct mpq_archive_t * mpq_a, int entry) {
return NULL;
}
+ // We won't support anything else than compressed files yet.
if (!(flags & MPQ_FLAGS_COMPRESSED)) {
__mpqlib_errno = MPQLIB_ERROR_NOT_COMPRESSED;
return NULL;
@@ -61,6 +65,7 @@ struct mpq_file_t * mpqlib_open_file(struct mpq_archive_t * mpq_a, int entry) {
r->sector_size = mpqlib_ioctl(mpq_a, MPQLIB_IOCTL_GET_SECTOR_SIZE, 0);
+ /* Allocating and filling up the mpq_file_t structure. */
if (!(r->buffer = malloc(r->sector_size))) {
free(r);
__mpqlib_errno = MPQLIB_ERROR_MEMORY;
@@ -95,6 +100,7 @@ struct mpq_file_t * mpqlib_open_file(struct mpq_archive_t * mpq_a, int entry) {
return NULL;
}
+ /* Reading the offset table and building the size table */
__mpqlib_seek(mpq_a, r->offset);
for (i = 0; i <= r->number_of_sectors; i++) {
__mpqlib_read(mpq_a, &o, 4);
@@ -128,6 +134,7 @@ static int cache_sector(struct mpq_file_t * mpq_f, int sector) {
static char in_buf[MPQ_BUFSIZ];
int r = 1;
+ /* current_sector should be initialized to -1 */
if (mpq_f->current_sector != sector) {
int il, ol;
__mpqlib_seek(mpq_f->mpq_a, mpq_f->offsets[sector]);
@@ -145,6 +152,10 @@ static int cache_sector(struct mpq_file_t * mpq_f, int sector) {
return r;
}
+/*
+ * The read function will call itself recursively, in order to split the calls across the sectors.
+ */
+
uint32_t mpqlib_read(struct mpq_file_t * mpq_f, void * _buffer, uint32_t size) {
char * buffer = (char *) _buffer;
int sector_begin, sector_end;
@@ -155,6 +166,7 @@ uint32_t mpqlib_read(struct mpq_file_t * mpq_f, void * _buffer, uint32_t size) {
uint32_t first_sector_begins, last_sector_ends;
+ /* Computing various cursors and stuff. */
if ((size + mpq_f->cursor) >= mpq_f->file_size)
size = mpq_f->file_size - mpq_f->cursor;
@@ -171,17 +183,20 @@ uint32_t mpqlib_read(struct mpq_file_t * mpq_f, void * _buffer, uint32_t size) {
last_sector_ends = mpq_f->sector_size;
}
+ /* Let's ask for the first sector */
if (!cache_sector(mpq_f, sector_begin)) {
__mpqlib_errno = MPQLIB_ERROR_COMPRESSION;
return 0;
}
+ /* If we've hit the end sector, let's just copy that over and exit. */
if (sector_begin == sector_end) {
memcpy(buffer, mpq_f->buffer + first_sector_begins, size);
mpq_f->cursor += size;
return size;
}
+ /* Else, let's compute the cluster size, copy that chunk, and recurse. */
cl_size = mpq_f->sector_size - first_sector_begins;
memcpy(buffer, mpq_f->buffer + first_sector_begins, cl_size);
mpq_f->cursor += cl_size;
diff --git a/mpq-fs.c b/mpq-fs.c
index b4c8fd7..ae9ed02 100644
--- a/mpq-fs.c
+++ b/mpq-fs.c
@@ -28,6 +28,9 @@ static char * strtoupper(char * _str) {
return _str;
}
+/*
+ * The 'new' keyword is abusive: the function returns an existing entry if it matches, allowing overrites.
+ */
static directory_list * new_directory_list(directory_list * parent, struct mpq_archive_t * mpq_a, const char * name) {
directory_list * r;
@@ -49,6 +52,9 @@ static directory_list * new_directory_list(directory_list * parent, struct mpq_a
return r;
}
+/*
+ * Recursively adds a new entry into our directory structure.
+ */
static directory_list * add_file_r(directory_list * parent, struct mpq_archive_t * mpq_a, char * fname, int entry) {
char * bs;
directory_list * r;
@@ -81,6 +87,9 @@ static directory_list * add_file(struct mpq_archive_t * mpq_a, char * fname) {
return add_file_r(root, mpq_a, fname, entry);
}
+/*
+ * Adds an opened archive file into the system, and try to automagically import the list file.
+ */
void mpqlib_fs_add_archive(struct mpq_archive_t * mpq_a) {
struct mpq_file_t * listfile;
char * buffer;
@@ -105,6 +114,9 @@ void mpqlib_fs_add_archive(struct mpq_archive_t * mpq_a) {
mpqlib_close(listfile);
}
+/*
+ * Generalistic function to add an archive to the directory structure using a custom listfile.
+ */
void mpqlib_fs_attach_listfile(struct mpq_archive_t * mpq_a, const char * listfile) {
char fname[MAX_FNAME];
const char * p;
@@ -112,6 +124,7 @@ void mpqlib_fs_attach_listfile(struct mpq_archive_t * mpq_a, const char * listfi
for (p = listfile, fnp = fname; *p; p++) {
switch (*p) {
+ /* Each entry in the listfile may be separated by CR, LF, and/or ';'. */
case '\r':
case '\n':
case ';':
@@ -127,6 +140,9 @@ void mpqlib_fs_attach_listfile(struct mpq_archive_t * mpq_a, const char * listfi
}
}
+/*
+ * Recursively find a file.
+ */
static directory_list * find_file_r(directory_list * parent, char * fname) {
char * bs;
directory_list * r;
diff --git a/mpq-misc.c b/mpq-misc.c
index 9e1ff5d..aa2d958 100644
--- a/mpq-misc.c
+++ b/mpq-misc.c
@@ -1,6 +1,10 @@
#include "mpq-misc.h"
#include "MPQCryptography.h"
+/*
+ * The various string hashing function.
+ */
+
uint32_t mpqlib_hash_filename(const char * str) {
return __mpqlib_hash_cstring(str, 0);
}