summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpixel <pixel>2007-07-09 16:34:30 +0000
committerpixel <pixel>2007-07-09 16:34:30 +0000
commitfabd02b4bb0c1df2b65ea682b29087a1776954ed (patch)
treed05674f049e83e1fd8919ad74bfee84304d6887f
parent2efe6f62b644ca93b7294de6dc83090542b2e4e2 (diff)
Adding basic file handling.
-rw-r--r--Makefile1
-rw-r--r--mpq-bios.c36
-rw-r--r--mpq-bios.h21
-rw-r--r--mpq-errors.c3
-rw-r--r--mpq-errors.h3
-rw-r--r--mpq-file.c12
-rw-r--r--mpq-file.h23
7 files changed, 97 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index 71f248d..abcf1e8 100644
--- a/Makefile
+++ b/Makefile
@@ -11,6 +11,7 @@ errors.c \
extract.c \
mpq-bios.c \
mpq-errors.c \
+mpq-file.c \
mpq-misc.c \
diff --git a/mpq-bios.c b/mpq-bios.c
index a093b84..055fa48 100644
--- a/mpq-bios.c
+++ b/mpq-bios.c
@@ -363,3 +363,39 @@ int __mpqlib_seek(mpq_archive_t * mpq_a, off_t off) {
int __mpqlib_read(mpq_archive_t * mpq_a, void * buffer, size_t size) {
return read_data(mpq_a, buffer, size);
}
+
+uint64_t mpqlib_ioctl(mpq_archive_t * mpq_a, enum mpqlib_ioctl_t command, int entry) {
+ switch(command) {
+ case MPQLIB_IOCTL_NO_ACTION:
+ return 0;
+ case MPQLIB_IOCTL_GET_FORMAT_VERSION:
+ return mpq_a->mpq_i->format_version;
+ case MPQLIB_IOCTL_GET_SECTOR_SIZE:
+ return mpq_a->mpq_i->sector_size;
+ case MPQLIB_IOCTL_GET_BLOCK_OFFSET:
+ case MPQLIB_IOCTL_GET_BLOCK_SIZE:
+ case MPQLIB_IOCTL_GET_FILE_SIZE:
+ case MPQLIB_IOCTL_GET_FLAGS:
+ if (entry >= mpq_a->mpq_i->block_table_entries) {
+ __mpqlib_errno = MPQLIB_ERROR_IOCTL_INVALID_ENTRY;
+ return -1;
+ }
+ switch (command) {
+ case MPQLIB_IOCTL_GET_BLOCK_OFFSET:
+ return mpq_a->mpq_i->blocks[entry].block_offset;
+ case MPQLIB_IOCTL_GET_BLOCK_SIZE:
+ return mpq_a->mpq_i->blocks[entry].block_size;
+ case MPQLIB_IOCTL_GET_FILE_SIZE:
+ return mpq_a->mpq_i->blocks[entry].file_size;
+ case MPQLIB_IOCTL_GET_FLAGS:
+ return mpq_a->mpq_i->blocks[entry].flags;
+ default:
+ // should never get there.
+ __mpqlib_errno = MPQLIB_ERROR_UNKNOWN;
+ return -1;
+ }
+ default:
+ __mpqlib_errno = MPQLIB_ERROR_INVALID_IOCTL;
+ return -1;
+ }
+}
diff --git a/mpq-bios.h b/mpq-bios.h
index 8eb3150..138367d 100644
--- a/mpq-bios.h
+++ b/mpq-bios.h
@@ -6,11 +6,27 @@
struct mpq_internals_t;
typedef struct {
- char * name;
-
struct mpq_internals_t * mpq_i;
} mpq_archive_t;
+#define MPQ_FLAGS_ISFILE 0x80000000
+#define MPQ_FLAGS_HAS_META 0x04000000
+#define MPQ_FLAGS_UNIT 0x01000000
+#define MPQ_FLAGS_ADJUST 0x00020000
+#define MPQ_FLAGS_ENCRYPTED 0x00010000
+#define MPQ_FLAGS_COMPRESSED 0x00000200
+#define MPQ_FLAGS_IMPLODED 0x00000100
+
+enum mpqlib_ioctl_t {
+ MPQLIB_IOCTL_NO_ACTION = 0,
+ MPQLIB_IOCTL_GET_FORMAT_VERSION,
+ MPQLIB_IOCTL_GET_SECTOR_SIZE,
+ MPQLIB_IOCTL_GET_BLOCK_OFFSET,
+ MPQLIB_IOCTL_GET_BLOCK_SIZE,
+ MPQLIB_IOCTL_GET_FILE_SIZE,
+ MPQLIB_IOCTL_GET_FLAGS,
+};
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -21,6 +37,7 @@ mpq_archive_t * mpqlib_reopen_archive(int fd);
void mpqlib_printtables(mpq_archive_t *);
void mpqlib_close_archive(mpq_archive_t *);
int mpqlib_find_hash_entry(mpq_archive_t *, const char * name, uint32_t language, uint32_t platform);
+uint64_t mpqlib_ioctl(mpq_archive_t *, enum mpqlib_ioctl_t command, int entry);
#ifdef __cplusplus
}
diff --git a/mpq-errors.c b/mpq-errors.c
index e0b8655..881e2b1 100644
--- a/mpq-errors.c
+++ b/mpq-errors.c
@@ -3,10 +3,13 @@
static const char * error_strings[] = {
"No error.",
+ "Unknown error - internal error.",
"Error opening file.",
"File specified isn't an MPQ archive.",
"Not enough memory.",
"File read error.",
+ "Invalid ioctl.",
+ "Invalid ioctl's file entry.",
};
static const char * wrong_errno = "Invalid error number - internal error.";
diff --git a/mpq-errors.h b/mpq-errors.h
index e7da789..047d31d 100644
--- a/mpq-errors.h
+++ b/mpq-errors.h
@@ -14,10 +14,13 @@ const char * mpqlib_error();
enum {
MPQLIB_ERROR_NO_ERROR = 0,
+ MPQLIB_ERROR_UNKNOWN,
MPQLIB_ERROR_OPEN,
MPQLIB_ERROR_NOT_MPQ_ARCHIVE,
MPQLIB_ERROR_MEMORY,
MPQLIB_ERROR_READ,
+ MPQLIB_ERROR_INVALID_IOCTL,
+ MPQLIB_ERROR_IOCTL_INVALID_ENTRY,
MPQLIB_ERRORS_MAX
};
diff --git a/mpq-file.c b/mpq-file.c
new file mode 100644
index 0000000..27cc9f2
--- /dev/null
+++ b/mpq-file.c
@@ -0,0 +1,12 @@
+#include "mpq-bios.h"
+#include "mpq-file.h"
+
+struct mpq_file_internals_t {
+ mpq_archive_t * mpq_a;
+ int entry;
+ int number_of_sectors;
+ int remaining_bytes;
+ char * buffer;
+ int current_sector;
+ uint32_t cursor;
+};
diff --git a/mpq-file.h b/mpq-file.h
new file mode 100644
index 0000000..d94a2cf
--- /dev/null
+++ b/mpq-file.h
@@ -0,0 +1,23 @@
+#ifndef __MPQ_FILE_H__
+#define __MPQ_FILE_H__
+
+#include "inttypes.h"
+
+struct mpq_file_internals_t;
+
+typedef struct {
+ struct mpq_file_internals_t * mpq_i;
+} mpq_file_t;
+
+enum mpqfile_seek_t {
+ MPQLIB_SEEK_SET,
+ MPQLIB_SEEK_CUR,
+ MPQLIB_SEEK_END,
+};
+
+mpq_file_t * mpqlib_open_file(mpq_archive_t * mpq_a, int entry);
+mpq_file_t * mpqlib_open_filename(mpq_archive_t * mpq_a, const char * fname);
+uint32_t mpqlib_read(mpq_file_t * mpq_f, void * buffer, uint32_t size);
+uint32_t mpqlib_seek(mpq_file_t, int32_t offset, enum mpqfile_seek_t);
+
+#endif