build problem with 0.002

This commit is contained in:
brianb 2000-03-04 17:31:07 +00:00
parent 5710389374
commit c461a46d22
8 changed files with 118 additions and 46 deletions

39
HACKERS
View File

@ -89,11 +89,11 @@ course of action has been to stop at the first non-printable character
After the name there is sometimes have (not yet determined why only sometimes) After the name there is sometimes have (not yet determined why only sometimes)
a page pointer and offset to the KKD records (see below). There is also pointer to other catalog pages, but I'm not really sure how to parse those. a page pointer and offset to the KKD records (see below). There is also pointer to other catalog pages, but I'm not really sure how to parse those.
Column Definition Table Definition
----------------- -----------------
The second and third bytes of each catalog entry store a 16 bit page pointer to The second and third bytes of each catalog entry store a 16 bit page pointer to
a column definition, including name, type, size, number of datarows, a pointer a table definition, including name, type, size, number of datarows, a pointer
to the first data page, and possibly more. I haven't fully figured this out so what follows is rough. to the first data page, and possibly more. I haven't fully figured this out so what follows is rough.
The header to table definition pages start look something like this: The header to table definition pages start look something like this:
@ -144,6 +144,41 @@ Column Type may be one of the following (not complete).
Following the 18 byte column records begins the column names, listed in order Following the 18 byte column records begins the column names, listed in order
with a 1 byte size prefix preceding each name. with a 1 byte size prefix preceding each name.
Data Rows
---------
The header of a data page looks like this:
+------+---------+--------------------------------------------------------+
| 0x01 | 1 byte | Page type |
| 0x01 | 1 byte | Unknown |
| ???? | 2 bytes | Unknown |
| ???? | 2 bytes | Page pointer to table definition |
| 0x00 | 2 bytes | Unknown |
| ???? | 4 bytes | number of rows of data in this table |
+------+---------+--------------------------------------------------------+
| Iterate for the number of records |
+-------------------------------------------------------------------------+
| ???? | 2 bytes | offset to the records location on this page |
+-------------------------------------------------------------------------+
Each data row looks like this:
+------+---------+--------------------------------------------------------+
| ???? | 1 byte | Number of columns stored in this row |
| ???? | n bytes | Fixed length columns |
| ???? | n bytes | Variable length columns |
| ???? | 1 byte | length of data from beginning of record |
| ???? | n bytes | offset from start of row for each variable length col |
| ???? | 1 byte | number of variable length columns |
| ???? | 1 byte | Unknown |
+------+---------+--------------------------------------------------------+
Note: it is possible for the offset to the beginning of a variable length
column to require more than one byte (if the sum of the lengths of columns is
greater than 255). I have no idea how this is represented in the data as I
have not looked at tables large enough for this to occur yet.
KKD Records KKD Records
----------- -----------

7
README
View File

@ -1,6 +1,6 @@
This is mdbtools version 0.001 This is mdbtools version 0.002
This software is very, very pre-pre-pre-pre-alpha (did I make my point?), so This software is very, very pre-pre-pre-alpha (did I make my point?), so
unless you know C and probably a little something about databases and reverse unless you know C and probably a little something about databases and reverse
engineering file formats, you're welcome to try it out but don't expect much if anything to work. engineering file formats, you're welcome to try it out but don't expect much if anything to work.
@ -19,7 +19,8 @@ mdb-dump -- a simple hex dump utility that I've been using to look at mdb files
prcat -- print the catalog table from an mdb file (try offset 9000). prcat -- print the catalog table from an mdb file (try offset 9000).
prkkd -- prints some info about a KKD record given the offset to it. prkkd -- prints some info about a KKD record given the offset to it.
If you're interested in digging into the project let me know, and I'll try to get a mailing list together.
Check out http://mdbtools.sourceforge.net for CVS, mailing list and similar.
Brian Bruns Brian Bruns
camber@ais.org camber@ais.org

View File

@ -77,6 +77,15 @@ typedef struct {
GArray *columns; GArray *columns;
} MdbCatalogEntry; } MdbCatalogEntry;
typedef struct {
char name[MDB_MAX_OBJ_NAME+1];
int num_cols;
int num_rows;
int num_pgs;
int first_data_pg;
GArray *columns;
} MdbTableDef;
typedef struct { typedef struct {
char name[MDB_MAX_OBJ_NAME+1]; char name[MDB_MAX_OBJ_NAME+1];
} MdbColumnProp; } MdbColumnProp;
@ -90,6 +99,7 @@ typedef struct {
extern MdbHandle *mdb_alloc_handle(); extern MdbHandle *mdb_alloc_handle();
extern void mdb_free_handle(MdbHandle *mdb); extern void mdb_free_handle(MdbHandle *mdb);
extern void mdb_free_catalog(MdbHandle *mdb); extern void mdb_free_catalog(MdbHandle *mdb);
extern MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry);
extern size_t mdb_read_pg(MdbHandle *mdb, unsigned long pg); extern size_t mdb_read_pg(MdbHandle *mdb, unsigned long pg);
extern int mdb_get_int16(MdbHandle *mdb, int offset); extern int mdb_get_int16(MdbHandle *mdb, int offset);

View File

@ -42,7 +42,7 @@ static char *type_name[] = {"Form",
} }
} }
MdbCatalogEntry *mdb_catalog_entry(MdbHandle *mdb, int rowid, MdbCatalogEntry *entry) MdbCatalogEntry *mdb_read_catalog_entry(MdbHandle *mdb, int rowid, MdbCatalogEntry *entry)
{ {
int offset; int offset;
int rows; int rows;
@ -118,7 +118,7 @@ int next_pg, next_pg_off;
fprintf(stdout,"YES! next pg = %04x %d\n",next_pg, next_pg); fprintf(stdout,"YES! next pg = %04x %d\n",next_pg, next_pg);
continue; continue;
} }
if (mdb_catalog_entry(mdb, i, &entry)) { if (mdb_read_catalog_entry(mdb, i, &entry)) {
data = g_memdup(&entry,sizeof(MdbCatalogEntry)); data = g_memdup(&entry,sizeof(MdbCatalogEntry));
mdb->catalog = g_list_append(mdb->catalog, data); mdb->catalog = g_list_append(mdb->catalog, data);
} }
@ -134,7 +134,7 @@ int next_pg, next_pg_off;
rows = mdb_catalog_rows(mdb); rows = mdb_catalog_rows(mdb);
for (i=0;i<rows;i++) { for (i=0;i<rows;i++) {
if (mdb->pg_buf[11 + 2 * i] & 0x40) continue; if (mdb->pg_buf[11 + 2 * i] & 0x40) continue;
if (mdb_catalog_entry(mdb, i, &entry)) { if (mdb_read_catalog_entry(mdb, i, &entry)) {
data = g_memdup(&entry,sizeof(MdbCatalogEntry)); data = g_memdup(&entry,sizeof(MdbCatalogEntry));
mdb->catalog = g_list_append(mdb->catalog, data); mdb->catalog = g_list_append(mdb->catalog, data);
} }

View File

@ -46,3 +46,17 @@ MdbCatalogEntry *entryp;
g_free(entryp); g_free(entryp);
} }
} }
MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry)
{
MdbTableDef *table;
table = (MdbTableDef *) malloc(sizeof(MdbTableDef));
memset(table, '\0', sizeof(MdbTableDef));
strcpy(table->name, entry->object_name);
return table;
}
void mdb_free_tabledef(MdbTableDef *table)
{
if (table) free(table);
}

View File

@ -58,39 +58,53 @@ unsigned char mdb_col_needs_size(int col_type)
} }
} }
/* MdbTableDef *mdb_read_table(MdbCatalogEntry *entry)
** {
*/ MdbTableDef *table;
MdbHandle *mdb = entry->mdb;
int len, i;
table = mdb_alloc_tabledef(entry);
mdb_read_pg(mdb, entry->table_pg);
len = mdb_get_int16(mdb,8);
table->num_rows = mdb_get_int32(mdb,12);
table->num_cols = mdb_get_int16(mdb,25);
table->num_pgs = mdb_get_int32(mdb,27);
table->first_data_pg = mdb_get_int16(mdb,36);
return table;
}
MdbColumn *mdb_read_column(MdbTableDef *table)
{
}
void mdb_table_dump(MdbCatalogEntry *entry) void mdb_table_dump(MdbCatalogEntry *entry)
{ {
int num_cols, num_rows, data_pgs, first_dpg;
int len, i; int len, i;
int cur_col, cur_name; int cur_col, cur_name;
int col_type, col_size; int col_type, col_size;
int col_start, name_start; int col_start, name_start;
char name[MDB_MAX_OBJ_NAME+1]; char name[MDB_MAX_OBJ_NAME+1];
int name_sz; int name_sz;
MdbTableDef *table;
MdbHandle *mdb = entry->mdb; MdbHandle *mdb = entry->mdb;
mdb_read_pg(mdb, entry->table_pg); table = mdb_read_table(entry);
len = mdb_get_int16(mdb,8); fprintf(stdout,"number of datarows = %d\n",table->num_rows);
num_rows = mdb_get_int32(mdb,12); fprintf(stdout,"number of columns = %d\n",table->num_cols);
num_cols = mdb_get_int16(mdb,25); fprintf(stdout,"number of datapages = %d\n",table->num_pgs);
data_pgs = mdb_get_int32(mdb,27); fprintf(stdout,"first data page = %d\n",table->first_data_pg);
first_dpg = mdb_get_int16(mdb,36);
fprintf(stdout,"number of datarows = %d\n",num_rows);
fprintf(stdout,"number of columns = %d\n",num_cols);
fprintf(stdout,"number of datapages = %d\n",data_pgs);
fprintf(stdout,"first data page = %d\n",first_dpg);
col_start = 43 + (data_pgs * 8); col_start = 43 + (table->num_pgs * 8);
name_start = col_start + (num_cols * 18); name_start = col_start + (table->num_cols * 18);
cur_col = col_start; cur_col = col_start;
cur_name = name_start; cur_name = name_start;
for (i=0;i<num_cols;i++) { for (i=0;i<table->num_cols;i++) {
col_type = mdb->pg_buf[cur_col]; col_type = mdb->pg_buf[cur_col];
col_size = mdb_get_int16(mdb,cur_col+16); col_size = mdb_get_int16(mdb,cur_col+16);
@ -106,4 +120,3 @@ MdbHandle *mdb = entry->mdb;
cur_name += name_sz + 1; cur_name += name_sz + 1;
} }
} }

View File

@ -1,20 +1,19 @@
/* MDB Tools - A library for reading MS Access database file /* MDB Tools - A library for reading MS Access database file
* Copyright (C) 2000 Brian Bruns * Copyright (C) 2000 Brian Bruns
* *
* This library is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or modify
* modify it under the terms of the GNU Library General Public * it under the terms of the GNU General Public License as published by
* License as published by the Free Software Foundation; either * the Free Software Foundation; either version 2 of the License, or
* version 2 of the License, or (at your option) any later version. * (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Library General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU Library General Public * You should have received a copy of the GNU General Public License
* License along with this library; if not, write to the * along with this program; if not, write to the Free Software
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Boston, MA 02111-1307, USA.
*/ */
#include "mdbtools.h" #include "mdbtools.h"

View File

@ -1,7 +1,8 @@
/* MDB Tools - A library for reading MS Access database file /* MDB Tools - A library for reading MS Access database file
* Copyright (C) 2000 Brian Bruns * Copyright (C) 2000 Brian Bruns
* *
* This library is free software; you can redistribute it and/or *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public * modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version. * version 2 of the License, or (at your option) any later version.
@ -25,7 +26,8 @@ int rows;
int i; int i;
unsigned char buf[2048]; unsigned char buf[2048];
MdbHandle *mdb; MdbHandle *mdb;
MdbCatalogEntry entry; MdbCatalogEntry *entry;
GList *l;
if (argc<2) { if (argc<2) {
@ -35,14 +37,12 @@ MdbCatalogEntry entry;
mdb = mdb_open(argv[1]); mdb = mdb_open(argv[1]);
mdb_read_pg(mdb, MDB_CATALOG_PG); mdb_read_catalog(mdb, MDB_TABLE);
rows = mdb_catalog_rows(mdb);
for (i=0;i<rows;i++) { for (l=g_list_first(mdb->catalog);l;l=g_list_next(l)) {
if (mdb_catalog_entry(mdb, i, &entry)) { entry = l->data;
if (!strcmp(entry.object_name,argv[2])) { if (!strcmp(entry->object_name,argv[2])) {
mdb_table_dump(&entry); mdb_table_dump(entry);
}
} }
} }