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)
|
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
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
|
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
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user