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>