Mercurial > libpst
changeset 44:d4606d460daf
more fixes for 64 bit format
author | carl |
---|---|
date | Tue, 08 Jan 2008 16:19:26 -0800 |
parents | f6db1f060a95 |
children | b961bcdadd0e |
files | regression/regression-tests.bash src/libpst.c src/libpst.h xml/libpst.in |
diffstat | 4 files changed, 411 insertions(+), 58 deletions(-) [+] |
line wrap: on
line diff
--- a/regression/regression-tests.bash Sun Jan 06 14:47:06 2008 -0800 +++ b/regression/regression-tests.bash Tue Jan 08 16:19:26 2008 -0800 @@ -7,6 +7,7 @@ mkdir output$i done + $val ../src/pst2ldif -b 'o=ams-cc.com, c=US' -c 'newPerson' ams.pst >ams.err 2>&1 $val ../src/readpst -cv -o output1 ams.pst >out1.err 2>&1 $val ../src/readpst -cl -r -o output2 ams.pst >out2.err 2>&1 @@ -14,9 +15,8 @@ $val ../src/readpst -M -o output4 ams.pst >out4.err 2>&1 $val ../src/readpst -o output5 mbmg.archive.pst >out5.err 2>&1 $val ../src/readpst -o output6 test.pst >out6.err 2>&1 - -$val ../src/readpst -o output7 -d dumper ams.pst >out7.err 2>&1 - ../src/readpstlog -f I dumper >dumperams.log +$val ../src/readpst -cv -o output7 -d dumper sample_64.pst >out7.err 2>&1 + ../src/readpstlog -f I dumper >sample_64.log $val ../src/lspst ams.pst >out8.err 2>&1 ../src/readpstlog -f I lspst.debug >lspst.log
--- a/src/libpst.c Sun Jan 06 14:47:06 2008 -0800 +++ b/src/libpst.c Tue Jan 08 16:19:26 2008 -0800 @@ -29,8 +29,8 @@ #include "libpst.h" #include "timeconv.h" -#define INDEX_DEPTH 0x4C -#define SECOND_DEPTH 0x5C +//efine INDEX_DEPTH 0x4C +//efine SECOND_DEPTH 0x5C #define INDEX_TYPE32 0x0E #define INDEX_TYPE64 0x17 @@ -124,7 +124,7 @@ 0xed, 0x9a, 0x64, 0x3f, 0xc1, 0x6c, 0xf9, 0xec}; /*0xff*/ -void dump_desc(off_t off, int depth, int i, pst_descn *desc_rec ) { // {{{ +void dump_desc(off_t off, int depth, int i, pst_descn *desc_rec ) { //desc_rec->d_id = 0x0102030405060708; DEBUG_INDEX(("%08x [%i] Item(%#x) = [d_id = %#llx, desc_id = %#llx, " "list_id = %#llx, parent_id = %#x, u1 = %#x] %#x %p %p\n", @@ -192,6 +192,9 @@ DEBUG_RET(); return -1; } + else { + WARN(("switching to 64 bit format...\n")); + } } // read encryption setting @@ -511,22 +514,41 @@ return 1; } - -#define BLOCK_SIZE 516 // index blocks -#define DESC_BLOCK_SIZE 516 // descriptor blocks -#define ITEM_COUNT_OFFSET 0x1f0 // count byte -#define LEVEL_INDICATOR_OFFSET 0x1f3 // node or leaf -#define BACKLINK_OFFSET 0x1f8 // backlink u1 value -#define ITEM_SIZE 12 -#define DESC_SIZE 16 -#define INDEX_COUNT_MAX 41 // max active items -#define DESC_COUNT_MAX 31 // max active items +#define BLOCK_SIZE32 516 // index blocks +#define DESC_BLOCK_SIZE32 516 // descriptor blocks +#define ITEM_COUNT_OFFSET32 0x1f0 // count byte +#define LEVEL_INDICATOR_OFFSET32 0x1f3 // node or leaf +#define BACKLINK_OFFSET32 0x1f8 // backlink u1 value +#define ITEM_SIZE32 12 +#define DESC_SIZE32 16 +#define INDEX_COUNT_MAX32 41 // max active items +#define DESC_COUNT_MAX32 31 // max active items + +#define BLOCK_SIZE64 512 // index blocks +#define DESC_BLOCK_SIZE64 512 // descriptor blocks +#define ITEM_COUNT_OFFSET64 0x1e8 // count byte +#define LEVEL_INDICATOR_OFFSET64 0x1eb // node or leaf +#define BACKLINK_OFFSET64 0x1f8 // backlink u1 value +#define ITEM_SIZE64 24 +#define DESC_SIZE64 32 +#define INDEX_COUNT_MAX64 20 // max active items +#define DESC_COUNT_MAX64 15 // max active items + +#define BLOCK_SIZE ((do_read64) ? BLOCK_SIZE64 : BLOCK_SIZE32) +#define DESC_BLOCK_SIZE ((do_read64) ? DESC_BLOCK_SIZE64 : DESC_BLOCK_SIZE32) +#define ITEM_COUNT_OFFSET ((do_read64) ? ITEM_COUNT_OFFSET64 : ITEM_COUNT_OFFSET32) +#define LEVEL_INDICATOR_OFFSET ((do_read64) ? LEVEL_INDICATOR_OFFSET64 : LEVEL_INDICATOR_OFFSET32) +#define BACKLINK_OFFSET ((do_read64) ? BACKLINK_OFFSET64 : BACKLINK_OFFSET32) +#define ITEM_SIZE ((do_read64) ? ITEM_SIZE64 : ITEM_SIZE32) +#define DESC_SIZE ((do_read64) ? DESC_SIZE64 : DESC_SIZE32) +#define INDEX_COUNT_MAX ((do_read64) ? INDEX_COUNT_MAX64 : INDEX_COUNT_MAX32) +#define DESC_COUNT_MAX ((do_read64) ? DESC_COUNT_MAX64 : DESC_COUNT_MAX32) int _pst_decode_desc( pst_descn *desc, char *buf ) { int r; if (do_read64) { - DEBUG_INDEX(("Decoding desc64 ")); + DEBUG_INDEX(("Decoding desc64\n")); DEBUG_HEXDUMPC(buf, sizeof(pst_descn), 0x10); memcpy(desc, buf, sizeof(pst_descn)); LE64_CPU(desc->d_id); @@ -538,7 +560,7 @@ } else { pst_desc32 d32; - DEBUG_INDEX(("Decoding desc32 ")); + DEBUG_INDEX(("Decoding desc32\n")); DEBUG_HEXDUMPC(buf, sizeof(pst_desc32), 0x10); memcpy(&d32, buf, sizeof(pst_desc32)); LE32_CPU(d32.d_id); @@ -559,7 +581,7 @@ int _pst_decode_table( struct _pst_table_ptr_structn *table, char *buf ) { int r; if (do_read64) { - DEBUG_INDEX(("Decoding table64")); + DEBUG_INDEX(("Decoding table64\n")); DEBUG_HEXDUMPC(buf, sizeof(struct _pst_table_ptr_structn), 0x10); memcpy(table, buf, sizeof(struct _pst_table_ptr_structn)); LE64_CPU(table->start); @@ -569,7 +591,7 @@ } else { struct _pst_table_ptr_struct32 t32; - DEBUG_INDEX(("Decoding table32")); + DEBUG_INDEX(("Decoding table32\n")); DEBUG_HEXDUMPC(buf, sizeof( struct _pst_table_ptr_struct32), 0x10); memcpy(&t32, buf, sizeof(struct _pst_table_ptr_struct32)); LE32_CPU(t32.start); @@ -587,7 +609,7 @@ int _pst_decode_index( pst_index *index, char *buf ) { int r; if (do_read64) { - DEBUG_INDEX(("Decoding index64")); + DEBUG_INDEX(("Decoding index64\n")); DEBUG_HEXDUMPC(buf, sizeof(pst_index), 0x10); memcpy(index, buf, sizeof(pst_index)); LE64_CPU(index->id); @@ -598,7 +620,7 @@ r = sizeof(pst_index); } else { pst_index32 index32; - DEBUG_INDEX(("Decoding index32")); + DEBUG_INDEX(("Decoding index32\n")); DEBUG_HEXDUMPC(buf, sizeof(pst_index32), 0x10); memcpy(&index32, buf, sizeof(pst_index32)); LE32_CPU(index32->id); @@ -638,7 +660,7 @@ return -1; } bptr = buf; - DEBUG_HEXDUMPC(buf, BLOCK_SIZE, ITEM_SIZE); + DEBUG_HEXDUMPC(buf, BLOCK_SIZE, ITEM_SIZE32); item_count = (int)(unsigned)(buf[ITEM_COUNT_OFFSET]); if (item_count > INDEX_COUNT_MAX) { DEBUG_WARN(("Item count %i too large, max is %i\n", item_count, INDEX_COUNT_MAX)); @@ -737,7 +759,7 @@ struct cache_list_node { pst_desc_ll *ptr; /** only used for lost and found lists */ - uint32_t parent; + uint64_t parent; struct cache_list_node *next; struct cache_list_node *prev; }; @@ -750,7 +772,7 @@ /** add the d_ptr descriptor into the global tree */ -void record_descriptor(pst_file *pf, pst_desc_ll *d_ptr, uint32_t parent_id) { +void record_descriptor(pst_file *pf, pst_desc_ll *d_ptr, uint64_t parent_id) { struct cache_list_node *lostfound_ptr = NULL; struct cache_list_node *cache_ptr = NULL; pst_desc_ll *parent = NULL; @@ -873,7 +895,7 @@ } if (buf[LEVEL_INDICATOR_OFFSET] == '\0') { // this node contains leaf pointers - DEBUG_HEXDUMPC(buf, DESC_BLOCK_SIZE, 16); + DEBUG_HEXDUMPC(buf, DESC_BLOCK_SIZE, DESC_SIZE32); if (item_count > DESC_COUNT_MAX) { DEBUG_WARN(("Item count %i too large, max is %i\n", item_count, DESC_COUNT_MAX)); if (buf) free(buf); @@ -987,7 +1009,7 @@ } } else { // this node contains node pointers - DEBUG_HEXDUMPC(buf, DESC_BLOCK_SIZE, ITEM_SIZE); + DEBUG_HEXDUMPC(buf, DESC_BLOCK_SIZE, ITEM_SIZE32); if (item_count > INDEX_COUNT_MAX) { DEBUG_WARN(("Item count %i too large, max is %i\n", item_count, INDEX_COUNT_MAX)); if (buf) free(buf); @@ -996,7 +1018,7 @@ } x = 0; while (x < item_count) { - bptr+=_pst_decode_table(&table, bptr); + bptr += _pst_decode_table(&table, bptr); x++; if (table.start == 0) break; if (x < item_count) { @@ -1046,7 +1068,7 @@ } -void* _pst_parse_item(pst_file *pf, pst_desc_ll *d_ptr) { +pst_item* _pst_parse_item(pst_file *pf, pst_desc_ll *d_ptr) { pst_num_array * list; pst_index2_ll *id2_head = NULL; pst_index_ll *id_ptr = NULL; @@ -1591,14 +1613,14 @@ //need UTF-16 zero-termination vbset(strbuf, na_ptr->items[x]->data, na_ptr->items[x]->size); vbappend(strbuf, "\0\0", 2); - DEBUG_INDEX(("Iconv in: ")); + DEBUG_INDEX(("Iconv in:\n")); DEBUG_HEXDUMPC(strbuf->b, strbuf->dlen, 0x10); vb_utf16to8(unibuf, strbuf->b, strbuf->dlen); free(na_ptr->items[x]->data); na_ptr->items[x]->size = unibuf->dlen; na_ptr->items[x]->data = xmalloc(unibuf->dlen); memcpy(na_ptr->items[x]->data, unibuf->b, unibuf->dlen); - DEBUG_INDEX(("Iconv out: ")); + DEBUG_INDEX(("Iconv out:\n")); DEBUG_HEXDUMPC(na_ptr->items[x]->data, na_ptr->items[x]->size, 0x10); } if (na_ptr->items[x]->type == 0) na_ptr->items[x]->type = table_rec.ref_type;
--- a/src/libpst.h Sun Jan 06 14:47:06 2008 -0800 +++ b/src/libpst.h Tue Jan 08 16:19:26 2008 -0800 @@ -61,9 +61,9 @@ #ifdef _MSC_VER #include "windows.h" -#define int32_t int +#define int32_t int #define uint32_t unsigned int -#define int16_t short int +#define int16_t short int #define uint16_t unsigned short int #endif // _MSC_VER @@ -505,7 +505,7 @@ int32_t _pst_build_id_ptr(pst_file *pf, off_t offset, int32_t depth, int64_t linku1, uint64_t start_val, uint64_t end_val); int32_t _pst_build_desc_ptr (pst_file *pf, off_t offset, int32_t depth, int64_t linku1, uint64_t *high_id, uint64_t start_id, uint64_t end_val); pst_item* _pst_getItem(pst_file *pf, pst_desc_ll *d_ptr); -void * _pst_parse_item (pst_file *pf, pst_desc_ll *d_ptr); +pst_item* _pst_parse_item (pst_file *pf, pst_desc_ll *d_ptr); pst_num_array * _pst_parse_block(pst_file *pf, uint32_t block_id, pst_index2_ll *i2_head); int32_t _pst_process(pst_num_array *list, pst_item *item, pst_item_attach *attach); int32_t _pst_free_list(pst_num_array *list);
--- a/xml/libpst.in Sun Jan 06 14:47:06 2008 -0800 +++ b/xml/libpst.in Tue Jan 08 16:19:26 2008 -0800 @@ -19,7 +19,7 @@ <refentry id="readpst.1"> <refentryinfo> - <date>2008-01-06</date> + <date>2008-01-08</date> </refentryinfo> <refmeta> @@ -212,7 +212,7 @@ <refentry id="lspst.1"> <refentryinfo> - <date>2008-01-06</date> + <date>2008-01-08</date> </refentryinfo> <refmeta> @@ -286,7 +286,7 @@ <refentry id="readpstlog.1"> <refentryinfo> - <date>2008-01-06</date> + <date>2008-01-08</date> </refentryinfo> <refmeta> @@ -461,7 +461,7 @@ <refentry id="pst2ldif.1"> <refentryinfo> - <date>2008-01-06</date> + <date>2008-01-08</date> </refentryinfo> <refmeta> @@ -585,7 +585,7 @@ <refentry id="pst.5"> <refentryinfo> - <date>2008-01-06</date> + <date>2008-01-08</date> </refentryinfo> <refmeta> @@ -610,13 +610,16 @@ <para> Each item in a .pst file is identified by two id values ID1 and ID2. There are two separate b-trees indexed by these ID1 and ID2 values. + Starting with Outlook 2003, the file format changed from one with 32 + bit pointers, to one with 64 bit pointers. We describe both formats + here. </para> </refsect1> - <refsect1 id='pst.file.header.5'> - <title>File Header</title> + <refsect1 id='pst.file.header.32.5'> + <title>32 bit File Header</title> <para> - The file header is located at offset 0 in the .pst file. + The 32 bit file header is located at offset 0 in the .pst file. </para> <literallayout class="monospaced"><![CDATA[ 0000 21 42 44 4e 49 f8 64 d9 53 4d 0e 00 13 00 01 01 @@ -654,7 +657,7 @@ 0000 signature [4 bytes] 0x4e444221 constant 000a indexType [1 byte] 0x0e constant -01cd encryptionType [1 byte] 0x01 constant +01cd encryptionType [1 byte] 0x01 in this case 00a8 total file size [4 bytes] 0x270400 in this case 00c0 backPointer1 [4 bytes] 0x021eb4 in this case 00c4 offsetIndex1 [4 bytes] 0x005400 in this case @@ -662,7 +665,11 @@ 00bc offsetIndex2 [4 bytes] 0x0c7e00 in this case ]]></literallayout> <para> - We only support index type 0x0E and encryption type 0x01. + We only support index types 0x0e and 0x17, and encryption types + 0x00 and 0x01. Index type 0x0e is the older 32 bit Outlook format. + Index type 0x17 is the newer 64 bit Outlook format. Encryption + type 0x00 is no encryption, and type 0x01 is the only other supported + encryption type. </para> <para> offsetIndex1 is the file offset of the root of the @@ -678,10 +685,62 @@ </para> </refsect1> - <refsect1 id='pst.file.node1.5'> - <title>Index 1 Node</title> + <refsect1 id='pst.file.header.64.5'> + <title>64 bit File Header</title> <para> - The index1 b-tree nodes are 516 byte blocks with the following format. + The 64 bit file header is located at offset 0 in the .pst file. + </para> + <literallayout class="monospaced"><![CDATA[ +0000 21 42 44 4e 03 02 23 b2 53 4d 17 00 13 00 01 01 +0010 00 00 00 00 00 00 00 00 04 00 00 00 01 00 00 00 +0020 8b 00 00 00 00 00 00 00 1d 00 00 00 00 04 00 00 +0030 00 04 00 00 04 04 00 00 00 40 00 00 02 00 01 00 +0040 00 04 00 00 00 04 00 00 00 04 00 00 00 80 00 00 +0050 00 04 00 00 00 04 00 00 00 04 00 00 00 04 00 00 +0060 04 04 00 00 04 04 00 00 04 04 00 00 00 04 00 00 +0070 00 04 00 00 00 04 00 00 00 04 00 00 00 04 00 00 +0080 00 04 00 00 00 04 00 00 00 04 00 00 00 04 00 00 +0090 00 04 00 00 00 04 00 00 00 04 00 00 00 04 00 00 +00a0 00 04 00 00 00 04 00 00 02 04 00 00 00 00 00 00 +00b0 00 00 00 00 00 00 00 00 00 24 04 00 00 00 00 00 +00c0 00 44 00 00 00 00 00 00 00 71 03 00 00 00 00 00 +00d0 00 22 00 00 00 00 00 00 83 00 00 00 00 00 00 00 +00e0 00 6a 00 00 00 00 00 00 8a 00 00 00 00 00 00 00 +00f0 00 60 00 00 00 00 00 00 01 00 00 00 00 00 00 00 +0100 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0180 7f ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +0190 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +01a0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +01b0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +01c0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +01d0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +01e0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +01f0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +0200 80 00 00 00 e8 00 00 00 00 00 00 00 c4 68 cb 89 + +0000 signature [4 bytes] 0x4e444221 constant +000a indexType [1 byte] 0x17 constant +0201 encryptionType [1 byte] 0x00 in this case +00b8 total file size [8 bytes] 0x042400 in this case +00e8 backPointer1 [8 bytes] 0x00008a in this case +00f0 offsetIndex1 [8 bytes] 0x006000 in this case +00d8 backPointer2 [8 bytes] 0x000083 in this case +00e0 offsetIndex2 [8 bytes] 0x006a00 in this case +]]></literallayout> + </refsect1> + + <refsect1 id='pst.file.node1.32.5'> + <title>32 bit Index 1 Node</title> + <para> + The 32 bit index1 b-tree nodes are 516 byte blocks with the + following format. </para> <literallayout class="monospaced"><![CDATA[ 0000 04 00 00 00 8a 1e 02 00 00 1c 0b 00 @@ -747,10 +806,81 @@ </para> </refsect1> - <refsect1 id='pst.file.leaf1.5'> - <title>Index 1 Leaf Node</title> + <refsect1 id='pst.file.node1.64.5'> + <title>64 bit Index 1 Node</title> <para> - The index1 b-tree leaf nodes are 516 byte blocks with the following format. + The 64 bit index1 b-tree nodes are 512 byte blocks with the + following format. + </para> + <literallayout class="monospaced"><![CDATA[ +0000 04 00 00 00 00 00 00 00 88 00 00 00 +000C 00 00 00 00 00 48 00 00 00 00 00 00 +0018 74 00 00 00 00 00 00 00 86 00 00 00 +0024 00 00 00 00 00 54 00 00 00 00 00 00 +0030 00 00 00 00 00 00 00 00 00 00 00 00 +003C 00 00 00 00 00 00 00 00 00 00 00 00 +0048 00 00 00 00 00 00 00 00 00 00 00 00 +0054 00 00 00 00 00 00 00 00 00 00 00 00 +0060 00 00 00 00 00 00 00 00 00 00 00 00 +006C 00 00 00 00 00 00 00 00 00 00 00 00 +0078 00 00 00 00 00 00 00 00 00 00 00 00 +0084 00 00 00 00 00 00 00 00 00 00 00 00 +0090 00 00 00 00 00 00 00 00 00 00 00 00 +009C 00 00 00 00 00 00 00 00 00 00 00 00 +00A8 00 00 00 00 00 00 00 00 00 00 00 00 +00B4 00 00 00 00 00 00 00 00 00 00 00 00 +00C0 00 00 00 00 00 00 00 00 00 00 00 00 +00CC 00 00 00 00 00 00 00 00 00 00 00 00 +00D8 00 00 00 00 00 00 00 00 00 00 00 00 +00E4 00 00 00 00 00 00 00 00 00 00 00 00 +00F0 00 00 00 00 00 00 00 00 00 00 00 00 +00FC 00 00 00 00 00 00 00 00 00 00 00 00 +0108 00 00 00 00 00 00 00 00 00 00 00 00 +0114 00 00 00 00 00 00 00 00 00 00 00 00 +0120 00 00 00 00 00 00 00 00 00 00 00 00 +012C 00 00 00 00 00 00 00 00 00 00 00 00 +0138 00 00 00 00 00 00 00 00 00 00 00 00 +0144 00 00 00 00 00 00 00 00 00 00 00 00 +0150 00 00 00 00 00 00 00 00 00 00 00 00 +015C 00 00 00 00 00 00 00 00 00 00 00 00 +0168 00 00 00 00 00 00 00 00 00 00 00 00 +0174 00 00 00 00 00 00 00 00 00 00 00 00 +0180 00 00 00 00 00 00 00 00 00 00 00 00 +018C 00 00 00 00 00 00 00 00 00 00 00 00 +0198 00 00 00 00 00 00 00 00 00 00 00 00 +01A4 00 00 00 00 00 00 00 00 00 00 00 00 +01B0 00 00 00 00 00 00 00 00 00 00 00 00 +01BC 00 00 00 00 00 00 00 00 00 00 00 00 +01C8 00 00 00 00 00 00 00 00 00 00 00 00 +01D4 00 00 00 00 00 00 00 00 00 00 00 00 +01E0 00 00 00 00 00 00 00 00 02 14 18 01 +01EC 00 00 00 00 80 80 8a 60 68 e5 b5 19 +01F8 8a 00 00 00 00 00 00 00 + +01e8 itemCount [1 byte] 0x02 in this case +01e9 maxItemCount [1 byte] 0x14 constant +01eb nodeLevel [1 byte] 0x01 in this case +01f8 backPointer [8 bytes] 0x00008a in this case +]]></literallayout> + <para> + The itemCount specifies the number of 24 byte records that + are active. The nodeLevel is non-zero for this style of nodes. + The leaf nodes have a different format. The backPointer must + match the backPointer from the triple that pointed to this node. + </para> + <para> + Each item in this node is a triple of (ID1, backPointer, offset) + where the offset points to the next deeper node in the tree, the + backPointer value must match the backPointer in that deeper node, + and ID1 is the lowest ID1 value in the subtree. + </para> + </refsect1> + + <refsect1 id='pst.file.leaf1.32.5'> + <title>32 bit Index 1 Leaf Node</title> + <para> + The 32 bit index1 b-tree leaf nodes are 516 byte blocks with the + following format. </para> <literallayout class="monospaced"><![CDATA[ 0000 04 00 00 00 00 58 00 00 64 00 0f 00 @@ -799,7 +929,7 @@ 01f0 itemCount [1 byte] 0x1f in this case 01f1 maxItemCount [1 byte] 0x29 constant -01f3 nodeLevel [1 byte] 0x00 in this case +01f3 nodeLevel [1 byte] 0x00 defines a leaf node 01f8 backPointer [4 bytes] 0x01675a in this case ]]></literallayout> <para> @@ -819,10 +949,84 @@ </para> </refsect1> - <refsect1 id='pst.file.node2.5'> - <title>Index 2 Node</title> + <refsect1 id='pst.file.leaf1.64.5'> + <title>64 bit Index 1 Leaf Node</title> <para> - The index2 b-tree nodes are 516 byte blocks with the following format. + The 64 bit index1 b-tree leaf nodes are 512 byte blocks with the + following format. + </para> + <literallayout class="monospaced"><![CDATA[ +0000 04 00 00 00 00 00 00 00 00 58 00 00 +000C 00 00 00 00 6c 00 05 00 00 00 00 00 +0018 08 00 00 00 00 00 00 00 80 58 00 00 +0024 00 00 00 00 b4 00 06 00 d8 22 37 08 +0030 0c 00 00 00 00 00 00 00 80 59 00 00 +003C 00 00 00 00 ac 00 07 00 d8 22 37 08 +0048 10 00 00 00 00 00 00 00 40 5a 00 00 +0054 00 00 00 00 bc 00 03 00 d8 22 37 08 +0060 14 00 00 00 00 00 00 00 40 5b 00 00 +006C 00 00 00 00 a4 00 02 00 d8 22 37 08 +0078 18 00 00 00 00 00 00 00 00 5c 00 00 +0084 00 00 00 00 64 00 02 00 d8 22 37 08 +0090 1c 00 00 00 00 00 00 00 80 5c 00 00 +009C 00 00 00 00 5c 00 02 00 d8 22 37 08 +00A8 24 00 00 00 00 00 00 00 80 5d 00 00 +00B4 00 00 00 00 72 00 02 00 d8 22 37 08 +00C0 34 00 00 00 00 00 00 00 00 70 00 00 +00CC 00 00 00 00 8c 00 02 00 00 0d 00 00 +00D8 38 00 00 00 00 00 00 00 c0 71 00 00 +00E4 00 00 00 00 5c 00 02 00 d8 22 9c 00 +00F0 40 00 00 00 00 00 00 00 40 72 00 00 +00FC 00 00 00 00 26 00 02 00 d8 22 9c 00 +0108 4c 00 00 00 00 00 00 00 80 5f 00 00 +0114 00 00 00 00 3e 00 02 00 d8 22 9c 00 +0120 5c 00 00 00 00 00 00 00 c0 76 00 00 +012C 00 00 00 00 8c 00 02 00 d8 22 9c 00 +0138 64 00 00 00 00 00 00 00 40 75 00 00 +0144 00 00 00 00 76 00 02 00 d8 22 9c 00 +0150 6c 00 00 00 00 00 00 00 c0 73 00 00 +015C 00 00 00 00 5e 00 02 00 d8 22 9c 00 +0168 70 00 00 00 00 00 00 00 80 72 00 00 +0174 00 00 00 00 1e 01 02 00 d8 22 9c 00 +0180 70 00 00 00 00 00 00 00 80 72 00 00 +018C 00 00 00 00 1e 01 02 00 d8 22 9c 00 +0198 70 00 00 00 00 00 00 00 80 72 00 00 +01A4 00 00 00 00 1e 01 02 00 d8 22 9c 00 +01B0 74 00 00 00 00 00 00 00 40 74 00 00 +01BC 00 00 00 00 e0 00 02 00 d8 22 9c 00 +01C8 7c 00 00 00 00 00 00 00 80 77 00 00 +01D4 00 00 00 00 dc 00 02 00 d8 22 9c 00 +01E0 00 00 00 00 00 00 00 00 10 14 18 00 +01EC 00 00 00 00 80 80 88 48 3f 50 0b 04 +01F8 88 00 00 00 00 00 00 00 + +01e8 itemCount [1 byte] 0x10 in this case +01e9 maxItemCount [1 byte] 0x14 constant +01eb nodeLevel [1 byte] 0x00 defines a leaf node +01f8 backPointer [8 bytes] 0x000088 in this case +]]></literallayout> + <para> + The itemCount specifies the number of 24 byte records that + are active. The nodeLevel is zero for these leaf nodes. + The backPointer must match the backPointer from the triple + that pointed to this node. + </para> + <para> + Each item in this node is a tuple of (ID1, offset, size, unknown) + The two low order bits of the ID1 value seem to be flags. I have + never seen a case with bit zero set. Bit one indicates that the + item is <emphasis>not</emphasis> encrypted. Note that references + to these ID1 values elsewhere may have the low order bit set (and + I don't know what that means), but when we do the search in this + tree we need to clear that bit so that we can find the correct item. + </para> + </refsect1> + + <refsect1 id='pst.file.node2.32.5'> + <title>32 bit Index 2 Node</title> + <para> + The 32 bit index2 b-tree nodes are 516 byte blocks with the + following format. </para> <literallayout class="monospaced"><![CDATA[ 0000 21 00 00 00 bb 1e 02 00 00 e2 0b 00 @@ -888,10 +1092,81 @@ </para> </refsect1> - <refsect1 id='pst.file.leaf2.5'> - <title>Index 2 Leaf Node</title> + <refsect1 id='pst.file.node2.64.5'> + <title>64 bit Index 2 Node</title> <para> - The index2 b-tree leaf nodes are 516 byte blocks with the following format. + The 64 bit index2 b-tree nodes are 512 byte blocks with the + following format. + </para> + <literallayout class="monospaced"><![CDATA[ +0000 21 00 00 00 00 00 00 00 77 00 00 00 +000C 00 00 00 00 00 56 00 00 00 00 00 00 +0018 4c 06 00 00 00 00 00 00 82 00 00 00 +0024 00 00 00 00 00 68 00 00 00 00 00 00 +0030 4f 80 00 00 00 00 00 00 84 00 00 00 +003C 00 00 00 00 00 6e 00 00 00 00 00 00 +0048 00 00 00 00 00 00 00 00 00 00 00 00 +0054 00 00 00 00 00 00 00 00 00 00 00 00 +0060 00 00 00 00 00 00 00 00 00 00 00 00 +006C 00 00 00 00 00 00 00 00 00 00 00 00 +0078 00 00 00 00 00 00 00 00 00 00 00 00 +0084 00 00 00 00 00 00 00 00 00 00 00 00 +0090 00 00 00 00 00 00 00 00 00 00 00 00 +009C 00 00 00 00 00 00 00 00 00 00 00 00 +00A8 00 00 00 00 00 00 00 00 00 00 00 00 +00B4 00 00 00 00 00 00 00 00 00 00 00 00 +00C0 00 00 00 00 00 00 00 00 00 00 00 00 +00CC 00 00 00 00 00 00 00 00 00 00 00 00 +00D8 00 00 00 00 00 00 00 00 00 00 00 00 +00E4 00 00 00 00 00 00 00 00 00 00 00 00 +00F0 00 00 00 00 00 00 00 00 00 00 00 00 +00FC 00 00 00 00 00 00 00 00 00 00 00 00 +0108 00 00 00 00 00 00 00 00 00 00 00 00 +0114 00 00 00 00 00 00 00 00 00 00 00 00 +0120 00 00 00 00 00 00 00 00 00 00 00 00 +012C 00 00 00 00 00 00 00 00 00 00 00 00 +0138 00 00 00 00 00 00 00 00 00 00 00 00 +0144 00 00 00 00 00 00 00 00 00 00 00 00 +0150 00 00 00 00 00 00 00 00 00 00 00 00 +015C 00 00 00 00 00 00 00 00 00 00 00 00 +0168 00 00 00 00 00 00 00 00 00 00 00 00 +0174 00 00 00 00 00 00 00 00 00 00 00 00 +0180 00 00 00 00 00 00 00 00 00 00 00 00 +018C 00 00 00 00 00 00 00 00 00 00 00 00 +0198 00 00 00 00 00 00 00 00 00 00 00 00 +01A4 00 00 00 00 00 00 00 00 00 00 00 00 +01B0 00 00 00 00 00 00 00 00 00 00 00 00 +01BC 00 00 00 00 00 00 00 00 00 00 00 00 +01C8 00 00 00 00 00 00 00 00 00 00 00 00 +01D4 00 00 00 00 00 00 00 00 00 00 00 00 +01E0 00 00 00 00 00 00 00 00 03 14 18 01 +01EC 00 00 00 00 81 81 83 6a 49 da f3 d3 +01F8 83 00 00 00 00 00 00 00 + +01e8 itemCount [1 byte] 0x03 in this case +01e9 maxItemCount [1 byte] 0x14 constant +01eb nodeLevel [1 byte] 0x01 in this case +01f8 backPointer [4 bytes] 0x000083 in this case +]]></literallayout> + <para> + The itemCount specifies the number of 24 byte records that + are active. The nodeLevel is non-zero for this style of nodes. + The leaf nodes have a different format. The backPointer must + match the backPointer from the triple that pointed to this node. + </para> + <para> + Each item in this node is a triple of (ID2, backPointer, offset) + where the offset points to the next deeper node in the tree, the + backPointer value must match the backPointer in that deeper node, + and ID2 is the lowest ID2 value in the subtree. + </para> + </refsect1> + + <refsect1 id='pst.file.leaf2.32.5'> + <title>32 bit Index 2 Leaf Node</title> + <para> + The 32 bit index2 b-tree leaf nodes are 516 byte blocks with the + following format. </para> <literallayout class="monospaced"><![CDATA[ 0000 21 00 00 00 38 e6 00 00 00 00 00 00 00 00 00 00 @@ -944,11 +1219,67 @@ </para> </refsect1> + <refsect1 id='pst.file.leaf2.64.5'> + <title>64 bit Index 2 Leaf Node</title> + <para> + The 64 bit index2 b-tree leaf nodes are 512 byte blocks with the + following format. + </para> + <literallayout class="monospaced"><![CDATA[ +0000 21 00 00 00 00 00 00 00 74 00 00 00 00 00 00 00 +0010 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 +0020 61 00 00 00 00 00 00 00 34 00 00 00 00 00 00 00 +0030 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 +0040 22 01 00 00 00 00 00 00 4c 00 00 00 00 00 00 00 +0050 00 00 00 00 00 00 00 00 22 01 00 00 02 00 00 00 +0060 2d 01 00 00 00 00 00 00 70 00 00 00 00 00 00 00 +0070 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 +0080 2e 01 00 00 00 00 00 00 08 00 00 00 00 00 00 00 +0090 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 +00A0 2f 01 00 00 00 00 00 00 0c 00 00 00 00 00 00 00 +00B0 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 +00C0 e1 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00D0 00 00 00 00 00 00 00 00 00 00 00 00 d8 e3 13 00 +00E0 01 02 00 00 00 00 00 00 8c 00 00 00 00 00 00 00 +00F0 00 00 00 00 00 00 00 00 00 00 00 00 b0 e3 13 00 +0100 61 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0110 00 00 00 00 00 00 00 00 00 00 00 00 d8 e3 13 00 +0120 0d 06 00 00 00 00 00 00 04 00 00 00 00 00 00 00 +0130 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 +0140 0e 06 00 00 00 00 00 00 08 00 00 00 00 00 00 00 +0150 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 +0160 0f 06 00 00 00 00 00 00 0c 00 00 00 00 00 00 00 +0170 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 +0180 10 06 00 00 00 00 00 00 10 00 00 00 00 00 00 00 +0190 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 +01A0 2b 06 00 00 00 00 00 00 24 00 00 00 00 00 00 00 +01B0 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 +01C0 71 06 00 00 00 00 00 00 18 00 00 00 00 00 00 00 +01D0 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 +01E0 00 00 00 00 00 00 00 00 0e 0f 20 00 00 00 00 00 +01F0 81 81 77 56 f8 32 43 49 77 00 00 00 00 00 00 00 + +01e8 itemCount [1 byte] 0x0e in this case +01e9 maxItemCount [1 byte] 0x0f constant +01eb nodeLevel [1 byte] 0x00 defines a leaf node +01f8 backPointer [4 bytes] 0x000077 in this case +]]></literallayout> + <para> + The itemCount specifies the number of 32 byte records that + are active. The nodeLevel is zero for these leaf nodes. + The backPointer must match the backPointer from the triple + that pointed to this node. + </para> + <para> + Each item in this node is a tuple of (ID2, DESC-ID1, LIST-ID1, PARENT-ID2) + </para> + </refsect1> + <refsect1 id='pst.file.list.5'> <title>Associated List Item</title> <para> Contains associations between id1 and id2 for the items controlled by the record. - In the above leaf node, we have a tuple of (0x61, 0x02a82c, 0x02a836, 0) + In the above 32 bit leaf node, we have a tuple of (0x61, 0x02a82c, 0x02a836, 0) 0x02a836 is the ID1 of the associated list, and we can lookup that ID1 value in the index1 b-tree to find the (offset,size) of the data in the .pst file. </para>