diff --git a/ChangeLog b/ChangeLog index 2b3787b..466b572 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Wed Mar 16 06:41:57 CST 2005 Jeff Smith + * include/mdbtools.h: + * src/libmdb/data.c: Improve OLE-related functions + Sun Mar 13 15:22:11 CST 2005 Jeff Smith * src/util/mdb-export.c: * src/util/mdb-ver.c: Fix a couple of leaks diff --git a/include/mdbtools.h b/include/mdbtools.h index d7705a9..8e3e44b 100644 --- a/include/mdbtools.h +++ b/include/mdbtools.h @@ -277,8 +277,7 @@ typedef struct { int cur_value_start; int cur_value_len; /* MEMO/OLE readers */ - guint32 cur_blob_pg; - int cur_blob_row; + guint32 cur_blob_pg_row; int chunk_size; /* numerics only */ int col_prec; diff --git a/src/libmdb/data.c b/src/libmdb/data.c index 412e56e..9662f20 100644 --- a/src/libmdb/data.c +++ b/src/libmdb/data.c @@ -326,7 +326,7 @@ int mdb_read_next_dpg(MdbTableDef *table) do { if (!mdb_read_pg(mdb, table->cur_phys_pg++)) return 0; - } while (mdb->pg_buf[0]!=0x01 || mdb_pg_get_int32(mdb, 4)!=entry->table_pg); + } while (mdb->pg_buf[0]!=0x01 || mdb_get_int32(mdb->pg_buf, 4)!=entry->table_pg); /* fprintf(stderr,"returning new page %ld\n", table->cur_phys_pg); */ return table->cur_phys_pg; } @@ -381,7 +381,7 @@ mdb_fetch_row(MdbTableDef *table) } mdb_read_pg(mdb, pg); } else { - rows = mdb_pg_get_int16(mdb,fmt->row_count_offset); + rows = mdb_get_int16(mdb->pg_buf,fmt->row_count_offset); /* if at end of page, find a new page */ if (table->cur_row >= rows) { @@ -440,32 +440,25 @@ int i; int mdb_ole_read_next(MdbHandle *mdb, MdbColumn *col, void *ole_ptr) { - guint16 ole_len; - guint16 ole_flags; + guint32 ole_len; char *buf; int pg_row, row_start; int len; - ole_len = mdb_get_int16(ole_ptr, 0); - ole_flags = mdb_get_int16(ole_ptr, 2); + ole_len = mdb_get_int32(ole_ptr, 0); - if (ole_flags == 0x8000) { - /* inline fields don't have a next */ + if ((ole_len & 0x80000000) + || (ole_len & 0x40000000)) { + /* inline or single-page fields don't have a next */ return 0; - } else if (ole_flags == 0x4000) { - /* 0x4000 flagged ole's are contained on one page and thus - * should be handled entirely with mdb_ole_read() */ - return 0; - } else if (ole_flags == 0x0000) { - pg_row = (col->cur_blob_pg << 8) & col->cur_blob_row; - if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) { + } else { + if (mdb_find_pg_row(mdb, col->cur_blob_pg_row, + &buf, &row_start, &len)) { return 0; } if (col->bind_ptr) - memcpy(col->bind_ptr, buf + row_start, len); - pg_row = mdb_get_int32(buf, row_start); - col->cur_blob_pg = pg_row >> 8; - col->cur_blob_row = pg_row & 0xff; + memcpy(col->bind_ptr, buf + row_start + 4, len - 4); + col->cur_blob_pg_row = mdb_get_int32(buf, row_start); return len; } @@ -474,20 +467,18 @@ mdb_ole_read_next(MdbHandle *mdb, MdbColumn *col, void *ole_ptr) int mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, int chunk_size) { - guint16 ole_len; - guint16 ole_flags; + guint32 ole_len; char *buf; int pg_row, row_start; int len; - ole_len = mdb_get_int16(ole_ptr, 0); - ole_flags = mdb_get_int16(ole_ptr, 2); - mdb_debug(MDB_DEBUG_OLE,"ole len = %d ole flags = %08x", - ole_len, ole_flags); + ole_len = mdb_get_int32(ole_ptr, 0); + mdb_debug(MDB_DEBUG_OLE,"ole len = %d ole flags = %02x", + ole_len & 0x00ffffff, ole_len >> 24); col->chunk_size = chunk_size; - if (ole_flags == 0x8000) { + if (ole_len & 0x80000000) { /* inline ole field, if we can satisfy it, then do it */ len = col->cur_value_len - MDB_MEMO_OVERHEAD; if (chunk_size >= len) { @@ -500,14 +491,14 @@ mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, int chunk_size) } else { return 0; } - } else if (ole_flags == 0x4000) { - pg_row = mdb_get_int32(ole_ptr, 4); - col->cur_blob_pg = pg_row >> 8; - col->cur_blob_row = pg_row & 0xff; + } else if (ole_len & 0x40000000) { + col->cur_blob_pg_row = mdb_get_int32(ole_ptr, 4); mdb_debug(MDB_DEBUG_OLE,"ole row = %d ole pg = %ld", - col->cur_blob_row, col->cur_blob_pg); + col->cur_blob_pg_row & 0xff, + col->cur_blob_pg_row >> 8); - if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) { + if (mdb_find_pg_row(mdb, col->cur_blob_pg_row, + &buf, &row_start, &len)) { return 0; } mdb_debug(MDB_DEBUG_OLE,"start %d len %d", row_start, len); @@ -518,35 +509,29 @@ mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, int chunk_size) buffer_dump(col->bind_ptr, 0, 16); } return len; - } else if (ole_flags == 0x0000) { - pg_row = mdb_get_int32(ole_ptr, 4); - col->cur_blob_pg = pg_row >> 8; - col->cur_blob_row = pg_row & 0xff; + } else if (ole_len & 0xff000000 == 0) { + col->cur_blob_pg_row = mdb_get_int32(ole_ptr, 4); - if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) { + if (mdb_find_pg_row(mdb, col->cur_blob_pg_row, + &buf, &row_start, &len)) { return 0; } - if (col->bind_ptr) - memcpy(col->bind_ptr, buf + row_start, len); - - pg_row = mdb_get_int32(buf, row_start); - col->cur_blob_pg = pg_row >> 8; - col->cur_blob_row = pg_row & 0xff; + memcpy(col->bind_ptr, buf + row_start + 4, len - 4); + col->cur_blob_pg_row = mdb_get_int32(buf, row_start); return len; } else { - fprintf(stderr,"Unhandled ole field flags = %04x\n", ole_flags); + fprintf(stderr,"Unhandled ole field flags = %02x\n", ole_len >> 24); return 0; } } int mdb_copy_ole(MdbHandle *mdb, char *dest, int start, int size) { - guint16 ole_len; - guint16 ole_flags; + guint32 ole_len; guint32 row_start, pg_row; guint32 len; - char *buf; + char *buf, *pg_buf = mdb->pg_buf; if (sizepg_buf[start + MDB_MEMO_OVERHEAD], - size - MDB_MEMO_OVERHEAD); + if (dest) memcpy(dest, pg_buf + start + MDB_MEMO_OVERHEAD, len); return len; - } else if (ole_flags == 0x4000) { - pg_row = mdb_get_int32(mdb->pg_buf, start+4); + } else if (ole_len & 0x40000000) { + /* single page */ + pg_row = mdb_get_int32(pg_buf, start+4); mdb_debug(MDB_DEBUG_OLE,"Reading LVAL page %06x", pg_row >> 8); if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) { @@ -577,11 +561,14 @@ int mdb_copy_ole(MdbHandle *mdb, char *dest, int start, int size) if (dest) memcpy(dest, buf + row_start, len); return len; - } else if (ole_flags == 0x0000) { + } else if (ole_len & 0xff000000 == 0) { // assume all flags in MSB + /* multi-page */ int cur = 0; - pg_row = mdb_get_int32(mdb->pg_buf, start+4); - mdb_debug(MDB_DEBUG_OLE,"Reading LVAL page %06x", pg_row >> 8); + pg_row = mdb_get_int32(pg_buf, start+4); do { + mdb_debug(MDB_DEBUG_OLE,"Reading LVAL page %06x", + pg_row >> 8); + if (mdb_find_pg_row(mdb,pg_row,&buf,&row_start,&len)) { return 0; } @@ -598,7 +585,7 @@ int mdb_copy_ole(MdbHandle *mdb, char *dest, int start, int size) } while ((pg_row >> 8)); return cur; } else { - fprintf(stderr,"Unhandled ole field flags = %04x\n", ole_flags); + fprintf(stderr, "Unhandled ole field flags = %02x\n", ole_len >> 24); return 0; } } @@ -607,7 +594,7 @@ static char *mdb_memo_to_string(MdbHandle *mdb, int start, int size) guint32 memo_len; guint32 row_start, pg_row; guint32 len; - char *buf; + char *buf, *pg_buf = mdb->pg_buf; char *text = (char *) g_malloc(MDB_BIND_SIZE); if (sizepg_buf, start, start + MDB_MEMO_OVERHEAD - 1); + buffer_dump(pg_buf, start, start + MDB_MEMO_OVERHEAD - 1); #endif /* The 32 bit integer at offset 0 is the length of the memo field * with some flags in the high bits. * The 32 bit integer at offset 4 contains page and row information. */ - memo_len = mdb_pg_get_int32(mdb, start); + memo_len = mdb_get_int32(pg_buf, start); if (memo_len & 0x80000000) { /* inline memo field */ - mdb_unicode2ascii(mdb, &mdb->pg_buf[start + MDB_MEMO_OVERHEAD], + mdb_unicode2ascii(mdb, pg_buf + start + MDB_MEMO_OVERHEAD, size - MDB_MEMO_OVERHEAD, text, MDB_BIND_SIZE); return text; } else if (memo_len & 0x40000000) { /* single-page memo field */ - pg_row = mdb_get_int32(mdb->pg_buf, start+4); + pg_row = mdb_get_int32(pg_buf, start+4); #if MDB_DEBUG printf("Reading LVAL page %06x\n", pg_row >> 8); #endif @@ -647,14 +634,13 @@ static char *mdb_memo_to_string(MdbHandle *mdb, int start, int size) #endif mdb_unicode2ascii(mdb, buf + row_start, len, text, MDB_BIND_SIZE); return text; - } else { + } else if (memo_len & 0xff000000 == 0) { // assume all flags in MSB /* multi-page memo field */ guint32 tmpoff = 0; char *tmp; - memo_len &= 0x3fffffff; tmp = (char *) g_malloc(memo_len); - pg_row = mdb_get_int32(mdb->pg_buf, start+4); + pg_row = mdb_get_int32(pg_buf, start+4); do { #if MDB_DEBUG printf("Reading LVAL page %06x\n", pg_row >> 8); @@ -680,11 +666,9 @@ static char *mdb_memo_to_string(MdbHandle *mdb, int start, int size) mdb_unicode2ascii(mdb, tmp, tmpoff, text, MDB_BIND_SIZE); g_free(tmp); return text; -/* } else { - fprintf(stderr,"Unhandled memo field flags = %04x\n", memo_flags); + fprintf(stderr, "Unhandled memo field flags = %02x\n", memo_len >> 24); return ""; -*/ } } static char *