[patch] Re: Proposed changes to HACKING doc
Nirgal Vourgère <[email protected]> Sun, 6 Mar 2011 11:10:15 +0000
| Newsgroups | gmane.comp.db.mdb-tools.devel |
|---|---|
| Message-ID | <[email protected]> |
I tried to make a patch out of all that, since there is some really good stuff, and I believe it's easier for Brian to merge. I discarded a few things, like the renaming of fields, because it would not match the source code anymore. It's complex enough reading it... HACKING does help. On Monday 28 February 2011 08:25:17 dw wrote: > 8) The definitions for index information seem to be wrong. > (...) > Lastly > | ???? | 1 byte | primary_key | 0x01 if this index is primary | > Should be > | ???? | 1 byte | index_flags | see MDB_IDX_* flags | I disagree with that one. The flags are above, in the jet3 39 bytes index blocks, ot jet 4 52 bytes one. > So, when walking the list of index definitions, you use num_idx to tell > you how many indices there are. Then for each index, you use > index_Cols_index to index into the column definitions table to find the > columns for that index. The reason num_idx and num_idx_col might be > different is not because some of the indices are "real" (whatever that > was supposed to mean), but simply because more than one index uses the > same column list. I've seen this happen if there is one index that > includes nulls, and one that doesn't. FYI Type 2 extra "indexes" are the reverse of contraints, probably used to optimized cascade updates. These ones don't have matching columns definitions blocks. > I have a re-written mdb_read_indices that (I believe) correctly parses > this data if anyone is interested. It wouldn't hurt to publish that to the list, would it? I did that several times, and often had bad surprises, like when there are so many indexes that index definitions cover several DB pages... ------------------------------------------------------------------------------ What You Don't Know About Data Connectivity CAN Hurt You This paper provides an overview of data connectivity, details its effect on application quality, and explores various alternative solutions. http://p.sf.net/sfu/progress-d2d _______________________________________________ mdbtools-dev mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mdbtools-dev
HACKING.diff
(text/x-patch, 8 KB)
Author: dw <[email protected]> Source: http://sourceforge.net/mailarchive/forum.php?thread_name=6CA6EF5D-A660-4FF4-94EA-E789A7D83D0E%40gmail.com&forum_name=mdbtools-dev Index: mdbtools-0.6pre1/HACKING =================================================================== --- mdbtools-0.6pre1.orig/HACKING +++ mdbtools-0.6pre1/HACKING @@ -78,9 +78,13 @@ types. However, it contains things like Jet version, encryption keys, and name of the creating program. -Offset 0x14 contains the Jet version of this database: 0x00 for 3, 0x01 for 4. +Offset 0x14 contains the Jet version of this database: 0x00 for 3, 0x01 for 4, +0x02 for 5, 0x03 for Access 2010. This is used by the mdb-ver utility to determine the Jet version. +The 14 bytes starting at 0x42 are the (encrypted) database password. + +The 4 bytes at 0x3e on the Database Definition Page are the database key. Data Pages ---------- @@ -220,6 +224,13 @@ The length (partial if type 2) for the memo is: memo_page_len = offset_stop - offset_start +Update: The bitmask can't be an entire byte long. +OLE fields can hold up to 1gig. That requires at least 30 bits, leaving only 2 +bits for flags. Maybe sometimes 0xC0000000 is ignored? +See http://office.microsoft.com/en-us/access-help/access-2007-specifications-HA010030739.aspx +Number of characters in a Memo field: 65,535 when entering data through the +user interface; 2 gigabytes of character storage when entering data +programmatically. That would mean 31 bits for length. LVAL (Long Value) Pages ----------------------- @@ -286,7 +297,7 @@ | ???? | 2 bytes | num_var_cols| Number of variable columns in table | | ???? | 2 bytes | num_cols | Number of columns in table (repeat) | | ???? | 4 bytes | num_idx | Number of indexes in table | -| ???? | 4 bytes | num_real_idx| Number of indexes in table (repeat) | +| ???? | 4 bytes | num_real_idx| Number of index entries | | ???? | 4 bytes | used_pages | Points to a record containing the | | | | | usage bitmask for this table. | | ???? | 4 bytes | free_pages | Points to a similar record as above, | @@ -307,7 +318,7 @@ | ???? | 1 byte | precision | precision if numeric column | | ???? | 1 byte | scale | scale if numeric column | | ???? | 2 bytes | ??? | | -| ???? | 1 byte | bitmask | low order bit indicates variable columns | +| ???? | 1 byte | bitmask | See Column flags bellow | | ???? | 2 bytes | offset_F | Offset for fixed length columns | | ???? | 2 bytes | col_len | Length of the column (0 if memo) | +-------------------------------------------------------------------------+ @@ -331,7 +342,7 @@ +-------------------------------------------------------------------------+ | ???? | 4 bytes | index_num | Number of the index | | | | |(warn: not always in the sequential order)| -| ???? | 4 bytes | index_num2 | Number of the index (repeat) | +| ???? | 4 bytes | index_num2 | Index into index cols list | | 0x00 | 1 byte | ??? | | | 0xFF | 4 bytes | ??? | | | 0x00 | 4 bytes | ??? | | @@ -343,8 +354,11 @@ | ???? | 1 byte | idx_name_len| len of the name of the index | | ???? | n bytes | idx_name | Name of the index | +-------------------------------------------------------------------------+ -| ???? | n bytes | ??? | | -| 0xFF | 2 bytes | ??? | End of the tableDef ? | +| Iterate while col_num != 0xffff | ++-------------------------------------------------------------------------+ +| ???? | 2 bytes | col_num | Column number with variable length | +| ???? | 4 bytes | arg1 | | +| ???? | 4 bytes | arg2 | | +-------------------------------------------------------------------------+ +-------------------------------------------------------------------------+ @@ -363,7 +377,7 @@ | ???? | 2 bytes | num_var_cols| Number of variable columns in table | | ???? | 2 bytes | num_cols | Number of columns in table (repeat) | | ???? | 4 bytes | num_idx | Number of indexes in table | -| ???? | 4 bytes | num_real_idx| Number of indexes in table (repeat) | +| ???? | 4 bytes | num_real_idx| Number of index entries | | ???? | 4 bytes | used_pages | Points to a record containing the | | | | | usage bitmask for this table. | | ???? | 4 bytes | free_pages | Points to a similar record as above, | @@ -382,8 +396,8 @@ | ???? | 2 bytes | col_num | Column Number (includes deleted columns) | | ???? | 2 bytes | offset_V | Offset for variable length columns | | ???? | 2 bytes | col_num | Column Number | -| ???? | 4 bytes | ??? | prec/scale? verify | -| ???? | 1 byte | bitmask | low order bit indicates variable columns | +| ???? | 4 bytes | ??? | prec/scale? or LCID (0x409=English)? | +| ???? | 1 byte | bitmask | See column flags bellow | | ???? | 1 byte | ??? | seems to be 1 when variable len | | 0000 | 4 bytes | ??? | | | ???? | 2 bytes | offset_F | Offset for fixed length columns | @@ -413,7 +427,7 @@ | ???? | 4 bytes | unknown | matches first unknown definition block | | ???? | 4 bytes | index_num | Number of the index | | | | |(warn: not always in the sequential order)| -| ???? | 4 bytes | index_num2 | Number of the index (repeat) | +| ???? | 4 bytes | index_num2 | Index into index cols list | | 0x00 | 1 byte | ??? | | | 0xFF | 4 bytes | ??? | | | 0x00 | 4 bytes | ??? | | @@ -426,9 +440,18 @@ | ???? | 2 bytes | idx_name_len| len of the name of the index | | ???? | n bytes | idx_name | Name of the index (UCS-2) | +-------------------------------------------------------------------------+ -| ???? | n bytes | ??? | | -| 0xFF | 2 bytes | ??? | End of the tableDef ? | +| Iterate while col_num != 0xffff | +-------------------------------------------------------------------------+ +| ???? | 2 bytes | col_num | Column number with variable length | +| ???? | 4 bytes | arg1 | | +| ???? | 4 bytes | arg2 | | ++-------------------------------------------------------------------------+ + +Columns flags (not complete): +0x01: variable length column +0x02: can be null +0x04: is auto long +0x40: is auto guid Index flags (not complete): 0x01 Unique @@ -444,11 +467,11 @@ MONEY = 0x05 /* Currency (64 bits) */ FLOAT = 0x06 /* Single (32 bits) */ DOUBLE = 0x07 /* Double (64 bits) */ - SDATETIME = 0x08 /* Short Date/Time (64 bits) */ + DATETIME = 0x08 /* Date/Time (64 bits) */ BINARY = 0x09 /* Binary (255 bytes) */ TEXT = 0x0A /* Text (255 bytes) */ - OLE = 0x0B /* OLE */ - MEMO = 0x0C /* Memo, Hyperlink */ + OLE = 0x0B /* OLE = Long binary */ + MEMO = 0x0C /* Memo = Long text*/ UNKNOWN_0D = 0x0D UNKNOWN_0E = 0x0E REPID = 0x0F /* GUID */