mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-04-05 20:31:00 +08:00
build problem with 0.002
This commit is contained in:
parent
5710389374
commit
c461a46d22
39
HACKERS
39
HACKERS
@ -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)
|
||||
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
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
-----------
|
||||
|
||||
|
7
README
7
README
@ -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
|
||||
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).
|
||||
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
|
||||
camber@ais.org
|
||||
|
@ -77,6 +77,15 @@ typedef struct {
|
||||
GArray *columns;
|
||||
} 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 {
|
||||
char name[MDB_MAX_OBJ_NAME+1];
|
||||
} MdbColumnProp;
|
||||
@ -90,6 +99,7 @@ typedef struct {
|
||||
extern MdbHandle *mdb_alloc_handle();
|
||||
extern void mdb_free_handle(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 int mdb_get_int16(MdbHandle *mdb, int offset);
|
||||
|
@ -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 rows;
|
||||
@ -118,7 +118,7 @@ int next_pg, next_pg_off;
|
||||
fprintf(stdout,"YES! next pg = %04x %d\n",next_pg, next_pg);
|
||||
continue;
|
||||
}
|
||||
if (mdb_catalog_entry(mdb, i, &entry)) {
|
||||
if (mdb_read_catalog_entry(mdb, i, &entry)) {
|
||||
data = g_memdup(&entry,sizeof(MdbCatalogEntry));
|
||||
mdb->catalog = g_list_append(mdb->catalog, data);
|
||||
}
|
||||
@ -134,7 +134,7 @@ int next_pg, next_pg_off;
|
||||
rows = mdb_catalog_rows(mdb);
|
||||
for (i=0;i<rows;i++) {
|
||||
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));
|
||||
mdb->catalog = g_list_append(mdb->catalog, data);
|
||||
}
|
||||
|
@ -46,3 +46,17 @@ MdbCatalogEntry *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);
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
int num_cols, num_rows, data_pgs, first_dpg;
|
||||
int len, i;
|
||||
int cur_col, cur_name;
|
||||
int col_type, col_size;
|
||||
int col_start, name_start;
|
||||
char name[MDB_MAX_OBJ_NAME+1];
|
||||
int name_sz;
|
||||
MdbTableDef *table;
|
||||
MdbHandle *mdb = entry->mdb;
|
||||
|
||||
mdb_read_pg(mdb, entry->table_pg);
|
||||
len = mdb_get_int16(mdb,8);
|
||||
num_rows = mdb_get_int32(mdb,12);
|
||||
num_cols = mdb_get_int16(mdb,25);
|
||||
data_pgs = mdb_get_int32(mdb,27);
|
||||
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);
|
||||
table = mdb_read_table(entry);
|
||||
fprintf(stdout,"number of datarows = %d\n",table->num_rows);
|
||||
fprintf(stdout,"number of columns = %d\n",table->num_cols);
|
||||
fprintf(stdout,"number of datapages = %d\n",table->num_pgs);
|
||||
fprintf(stdout,"first data page = %d\n",table->first_data_pg);
|
||||
|
||||
col_start = 43 + (data_pgs * 8);
|
||||
name_start = col_start + (num_cols * 18);
|
||||
col_start = 43 + (table->num_pgs * 8);
|
||||
name_start = col_start + (table->num_cols * 18);
|
||||
|
||||
cur_col = col_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_size = mdb_get_int16(mdb,cur_col+16);
|
||||
|
||||
@ -106,4 +120,3 @@ MdbHandle *mdb = entry->mdb;
|
||||
cur_name += name_sz + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,19 @@
|
||||
/* MDB Tools - A library for reading MS Access database file
|
||||
* Copyright (C) 2000 Brian Bruns
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "mdbtools.h"
|
||||
|
@ -1,7 +1,8 @@
|
||||
/* MDB Tools - A library for reading MS Access database file
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
@ -25,7 +26,8 @@ int rows;
|
||||
int i;
|
||||
unsigned char buf[2048];
|
||||
MdbHandle *mdb;
|
||||
MdbCatalogEntry entry;
|
||||
MdbCatalogEntry *entry;
|
||||
GList *l;
|
||||
|
||||
|
||||
if (argc<2) {
|
||||
@ -35,14 +37,12 @@ MdbCatalogEntry entry;
|
||||
|
||||
mdb = mdb_open(argv[1]);
|
||||
|
||||
mdb_read_pg(mdb, MDB_CATALOG_PG);
|
||||
rows = mdb_catalog_rows(mdb);
|
||||
mdb_read_catalog(mdb, MDB_TABLE);
|
||||
|
||||
for (i=0;i<rows;i++) {
|
||||
if (mdb_catalog_entry(mdb, i, &entry)) {
|
||||
if (!strcmp(entry.object_name,argv[2])) {
|
||||
mdb_table_dump(&entry);
|
||||
}
|
||||
for (l=g_list_first(mdb->catalog);l;l=g_list_next(l)) {
|
||||
entry = l->data;
|
||||
if (!strcmp(entry->object_name,argv[2])) {
|
||||
mdb_table_dump(entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user