comparison src/libpst.c @ 44:d4606d460daf

more fixes for 64 bit format
author carl
date Tue, 08 Jan 2008 16:19:26 -0800
parents f6db1f060a95
children b961bcdadd0e
comparison
equal deleted inserted replaced
43:f6db1f060a95 44:d4606d460daf
27 # include <unistd.h> 27 # include <unistd.h>
28 #endif //ifdef _MSC_VER 28 #endif //ifdef _MSC_VER
29 29
30 #include "libpst.h" 30 #include "libpst.h"
31 #include "timeconv.h" 31 #include "timeconv.h"
32 #define INDEX_DEPTH 0x4C 32 //efine INDEX_DEPTH 0x4C
33 #define SECOND_DEPTH 0x5C 33 //efine SECOND_DEPTH 0x5C
34 #define INDEX_TYPE32 0x0E 34 #define INDEX_TYPE32 0x0E
35 #define INDEX_TYPE64 0x17 35 #define INDEX_TYPE64 0x17
36 36
37 #define FILE_SIZE_POINTER32 0xA8 37 #define FILE_SIZE_POINTER32 0xA8
38 #define INDEX_POINTER32 0xC4 38 #define INDEX_POINTER32 0xC4
122 0x0e, 0x81, 0x65, 0x73, 0xe4, 0xc2, 0xa2, 0x8a, /*0xef*/ 122 0x0e, 0x81, 0x65, 0x73, 0xe4, 0xc2, 0xa2, 0x8a, /*0xef*/
123 0xd4, 0xe1, 0x11, 0xd0, 0x08, 0x8b, 0x2a, 0xf2, 123 0xd4, 0xe1, 0x11, 0xd0, 0x08, 0x8b, 0x2a, 0xf2,
124 0xed, 0x9a, 0x64, 0x3f, 0xc1, 0x6c, 0xf9, 0xec}; /*0xff*/ 124 0xed, 0x9a, 0x64, 0x3f, 0xc1, 0x6c, 0xf9, 0xec}; /*0xff*/
125 125
126 126
127 void dump_desc(off_t off, int depth, int i, pst_descn *desc_rec ) { // {{{ 127 void dump_desc(off_t off, int depth, int i, pst_descn *desc_rec ) {
128 //desc_rec->d_id = 0x0102030405060708; 128 //desc_rec->d_id = 0x0102030405060708;
129 DEBUG_INDEX(("%08x [%i] Item(%#x) = [d_id = %#llx, desc_id = %#llx, " 129 DEBUG_INDEX(("%08x [%i] Item(%#x) = [d_id = %#llx, desc_id = %#llx, "
130 "list_id = %#llx, parent_id = %#x, u1 = %#x] %#x %p %p\n", 130 "list_id = %#llx, parent_id = %#x, u1 = %#x] %#x %p %p\n",
131 off, 131 off,
132 depth, i, desc_rec->d_id, 132 depth, i, desc_rec->d_id,
189 do_read64 = 1; 189 do_read64 = 1;
190 if (pf->ind_type != INDEX_TYPE) { 190 if (pf->ind_type != INDEX_TYPE) {
191 WARN(("unknown .pst format, possibly newer than Outlook 2003 PST file?\n")); 191 WARN(("unknown .pst format, possibly newer than Outlook 2003 PST file?\n"));
192 DEBUG_RET(); 192 DEBUG_RET();
193 return -1; 193 return -1;
194 }
195 else {
196 WARN(("switching to 64 bit format...\n"));
194 } 197 }
195 } 198 }
196 199
197 // read encryption setting 200 // read encryption setting
198 _pst_getAtPos(pf->fp, ENC_OFFSET, &(pf->encryption), sizeof(unsigned char)); 201 _pst_getAtPos(pf->fp, ENC_OFFSET, &(pf->encryption), sizeof(unsigned char));
509 pf->x_head = p_head; 512 pf->x_head = p_head;
510 DEBUG_RET(); 513 DEBUG_RET();
511 return 1; 514 return 1;
512 } 515 }
513 516
514 517 #define BLOCK_SIZE32 516 // index blocks
515 #define BLOCK_SIZE 516 // index blocks 518 #define DESC_BLOCK_SIZE32 516 // descriptor blocks
516 #define DESC_BLOCK_SIZE 516 // descriptor blocks 519 #define ITEM_COUNT_OFFSET32 0x1f0 // count byte
517 #define ITEM_COUNT_OFFSET 0x1f0 // count byte 520 #define LEVEL_INDICATOR_OFFSET32 0x1f3 // node or leaf
518 #define LEVEL_INDICATOR_OFFSET 0x1f3 // node or leaf 521 #define BACKLINK_OFFSET32 0x1f8 // backlink u1 value
519 #define BACKLINK_OFFSET 0x1f8 // backlink u1 value 522 #define ITEM_SIZE32 12
520 #define ITEM_SIZE 12 523 #define DESC_SIZE32 16
521 #define DESC_SIZE 16 524 #define INDEX_COUNT_MAX32 41 // max active items
522 #define INDEX_COUNT_MAX 41 // max active items 525 #define DESC_COUNT_MAX32 31 // max active items
523 #define DESC_COUNT_MAX 31 // max active items 526
527 #define BLOCK_SIZE64 512 // index blocks
528 #define DESC_BLOCK_SIZE64 512 // descriptor blocks
529 #define ITEM_COUNT_OFFSET64 0x1e8 // count byte
530 #define LEVEL_INDICATOR_OFFSET64 0x1eb // node or leaf
531 #define BACKLINK_OFFSET64 0x1f8 // backlink u1 value
532 #define ITEM_SIZE64 24
533 #define DESC_SIZE64 32
534 #define INDEX_COUNT_MAX64 20 // max active items
535 #define DESC_COUNT_MAX64 15 // max active items
536
537 #define BLOCK_SIZE ((do_read64) ? BLOCK_SIZE64 : BLOCK_SIZE32)
538 #define DESC_BLOCK_SIZE ((do_read64) ? DESC_BLOCK_SIZE64 : DESC_BLOCK_SIZE32)
539 #define ITEM_COUNT_OFFSET ((do_read64) ? ITEM_COUNT_OFFSET64 : ITEM_COUNT_OFFSET32)
540 #define LEVEL_INDICATOR_OFFSET ((do_read64) ? LEVEL_INDICATOR_OFFSET64 : LEVEL_INDICATOR_OFFSET32)
541 #define BACKLINK_OFFSET ((do_read64) ? BACKLINK_OFFSET64 : BACKLINK_OFFSET32)
542 #define ITEM_SIZE ((do_read64) ? ITEM_SIZE64 : ITEM_SIZE32)
543 #define DESC_SIZE ((do_read64) ? DESC_SIZE64 : DESC_SIZE32)
544 #define INDEX_COUNT_MAX ((do_read64) ? INDEX_COUNT_MAX64 : INDEX_COUNT_MAX32)
545 #define DESC_COUNT_MAX ((do_read64) ? DESC_COUNT_MAX64 : DESC_COUNT_MAX32)
524 546
525 547
526 int _pst_decode_desc( pst_descn *desc, char *buf ) { 548 int _pst_decode_desc( pst_descn *desc, char *buf ) {
527 int r; 549 int r;
528 if (do_read64) { 550 if (do_read64) {
529 DEBUG_INDEX(("Decoding desc64 ")); 551 DEBUG_INDEX(("Decoding desc64\n"));
530 DEBUG_HEXDUMPC(buf, sizeof(pst_descn), 0x10); 552 DEBUG_HEXDUMPC(buf, sizeof(pst_descn), 0x10);
531 memcpy(desc, buf, sizeof(pst_descn)); 553 memcpy(desc, buf, sizeof(pst_descn));
532 LE64_CPU(desc->d_id); 554 LE64_CPU(desc->d_id);
533 LE64_CPU(desc->desc_id); 555 LE64_CPU(desc->desc_id);
534 LE64_CPU(desc->list_id); 556 LE64_CPU(desc->list_id);
536 LE32_CPU(desc->u1); 558 LE32_CPU(desc->u1);
537 r = sizeof(pst_descn); 559 r = sizeof(pst_descn);
538 } 560 }
539 else { 561 else {
540 pst_desc32 d32; 562 pst_desc32 d32;
541 DEBUG_INDEX(("Decoding desc32 ")); 563 DEBUG_INDEX(("Decoding desc32\n"));
542 DEBUG_HEXDUMPC(buf, sizeof(pst_desc32), 0x10); 564 DEBUG_HEXDUMPC(buf, sizeof(pst_desc32), 0x10);
543 memcpy(&d32, buf, sizeof(pst_desc32)); 565 memcpy(&d32, buf, sizeof(pst_desc32));
544 LE32_CPU(d32.d_id); 566 LE32_CPU(d32.d_id);
545 LE32_CPU(d32.desc_id); 567 LE32_CPU(d32.desc_id);
546 LE32_CPU(d32.list_id); 568 LE32_CPU(d32.list_id);
557 579
558 580
559 int _pst_decode_table( struct _pst_table_ptr_structn *table, char *buf ) { 581 int _pst_decode_table( struct _pst_table_ptr_structn *table, char *buf ) {
560 int r; 582 int r;
561 if (do_read64) { 583 if (do_read64) {
562 DEBUG_INDEX(("Decoding table64")); 584 DEBUG_INDEX(("Decoding table64\n"));
563 DEBUG_HEXDUMPC(buf, sizeof(struct _pst_table_ptr_structn), 0x10); 585 DEBUG_HEXDUMPC(buf, sizeof(struct _pst_table_ptr_structn), 0x10);
564 memcpy(table, buf, sizeof(struct _pst_table_ptr_structn)); 586 memcpy(table, buf, sizeof(struct _pst_table_ptr_structn));
565 LE64_CPU(table->start); 587 LE64_CPU(table->start);
566 LE64_CPU(table->u1); 588 LE64_CPU(table->u1);
567 LE64_CPU(table->offset); 589 LE64_CPU(table->offset);
568 r =sizeof(struct _pst_table_ptr_structn); 590 r =sizeof(struct _pst_table_ptr_structn);
569 } 591 }
570 else { 592 else {
571 struct _pst_table_ptr_struct32 t32; 593 struct _pst_table_ptr_struct32 t32;
572 DEBUG_INDEX(("Decoding table32")); 594 DEBUG_INDEX(("Decoding table32\n"));
573 DEBUG_HEXDUMPC(buf, sizeof( struct _pst_table_ptr_struct32), 0x10); 595 DEBUG_HEXDUMPC(buf, sizeof( struct _pst_table_ptr_struct32), 0x10);
574 memcpy(&t32, buf, sizeof(struct _pst_table_ptr_struct32)); 596 memcpy(&t32, buf, sizeof(struct _pst_table_ptr_struct32));
575 LE32_CPU(t32.start); 597 LE32_CPU(t32.start);
576 LE32_CPU(t32.u1); 598 LE32_CPU(t32.u1);
577 LE32_CPU(t32.offset); 599 LE32_CPU(t32.offset);
585 607
586 608
587 int _pst_decode_index( pst_index *index, char *buf ) { 609 int _pst_decode_index( pst_index *index, char *buf ) {
588 int r; 610 int r;
589 if (do_read64) { 611 if (do_read64) {
590 DEBUG_INDEX(("Decoding index64")); 612 DEBUG_INDEX(("Decoding index64\n"));
591 DEBUG_HEXDUMPC(buf, sizeof(pst_index), 0x10); 613 DEBUG_HEXDUMPC(buf, sizeof(pst_index), 0x10);
592 memcpy(index, buf, sizeof(pst_index)); 614 memcpy(index, buf, sizeof(pst_index));
593 LE64_CPU(index->id); 615 LE64_CPU(index->id);
594 LE64_CPU(index->offset); 616 LE64_CPU(index->offset);
595 LE16_CPU(index->size); 617 LE16_CPU(index->size);
596 LE16_CPU(index->u0); 618 LE16_CPU(index->u0);
597 LE16_CPU(index->u1); 619 LE16_CPU(index->u1);
598 r = sizeof(pst_index); 620 r = sizeof(pst_index);
599 } else { 621 } else {
600 pst_index32 index32; 622 pst_index32 index32;
601 DEBUG_INDEX(("Decoding index32")); 623 DEBUG_INDEX(("Decoding index32\n"));
602 DEBUG_HEXDUMPC(buf, sizeof(pst_index32), 0x10); 624 DEBUG_HEXDUMPC(buf, sizeof(pst_index32), 0x10);
603 memcpy(&index32, buf, sizeof(pst_index32)); 625 memcpy(&index32, buf, sizeof(pst_index32));
604 LE32_CPU(index32->id); 626 LE32_CPU(index32->id);
605 LE32_CPU(index32->offset); 627 LE32_CPU(index32->offset);
606 LE16_CPU(index32->size); 628 LE16_CPU(index32->size);
636 if (buf) free(buf); 658 if (buf) free(buf);
637 DEBUG_RET(); 659 DEBUG_RET();
638 return -1; 660 return -1;
639 } 661 }
640 bptr = buf; 662 bptr = buf;
641 DEBUG_HEXDUMPC(buf, BLOCK_SIZE, ITEM_SIZE); 663 DEBUG_HEXDUMPC(buf, BLOCK_SIZE, ITEM_SIZE32);
642 item_count = (int)(unsigned)(buf[ITEM_COUNT_OFFSET]); 664 item_count = (int)(unsigned)(buf[ITEM_COUNT_OFFSET]);
643 if (item_count > INDEX_COUNT_MAX) { 665 if (item_count > INDEX_COUNT_MAX) {
644 DEBUG_WARN(("Item count %i too large, max is %i\n", item_count, INDEX_COUNT_MAX)); 666 DEBUG_WARN(("Item count %i too large, max is %i\n", item_count, INDEX_COUNT_MAX));
645 if (buf) free(buf); 667 if (buf) free(buf);
646 DEBUG_RET(); 668 DEBUG_RET();
735 list and check it each time you read a new item. 757 list and check it each time you read a new item.
736 */ 758 */
737 struct cache_list_node { 759 struct cache_list_node {
738 pst_desc_ll *ptr; 760 pst_desc_ll *ptr;
739 /** only used for lost and found lists */ 761 /** only used for lost and found lists */
740 uint32_t parent; 762 uint64_t parent;
741 struct cache_list_node *next; 763 struct cache_list_node *next;
742 struct cache_list_node *prev; 764 struct cache_list_node *prev;
743 }; 765 };
744 struct cache_list_node *cache_head; 766 struct cache_list_node *cache_head;
745 struct cache_list_node *cache_tail; 767 struct cache_list_node *cache_tail;
748 770
749 771
750 /** 772 /**
751 add the d_ptr descriptor into the global tree 773 add the d_ptr descriptor into the global tree
752 */ 774 */
753 void record_descriptor(pst_file *pf, pst_desc_ll *d_ptr, uint32_t parent_id) { 775 void record_descriptor(pst_file *pf, pst_desc_ll *d_ptr, uint64_t parent_id) {
754 struct cache_list_node *lostfound_ptr = NULL; 776 struct cache_list_node *lostfound_ptr = NULL;
755 struct cache_list_node *cache_ptr = NULL; 777 struct cache_list_node *cache_ptr = NULL;
756 pst_desc_ll *parent = NULL; 778 pst_desc_ll *parent = NULL;
757 779
758 if (parent_id == 0 || parent_id == d_ptr->id) { 780 if (parent_id == 0 || parent_id == d_ptr->id) {
871 DEBUG_RET(); 893 DEBUG_RET();
872 return -1; 894 return -1;
873 } 895 }
874 if (buf[LEVEL_INDICATOR_OFFSET] == '\0') { 896 if (buf[LEVEL_INDICATOR_OFFSET] == '\0') {
875 // this node contains leaf pointers 897 // this node contains leaf pointers
876 DEBUG_HEXDUMPC(buf, DESC_BLOCK_SIZE, 16); 898 DEBUG_HEXDUMPC(buf, DESC_BLOCK_SIZE, DESC_SIZE32);
877 if (item_count > DESC_COUNT_MAX) { 899 if (item_count > DESC_COUNT_MAX) {
878 DEBUG_WARN(("Item count %i too large, max is %i\n", item_count, DESC_COUNT_MAX)); 900 DEBUG_WARN(("Item count %i too large, max is %i\n", item_count, DESC_COUNT_MAX));
879 if (buf) free(buf); 901 if (buf) free(buf);
880 DEBUG_RET(); 902 DEBUG_RET();
881 return -1; 903 return -1;
985 } 1007 }
986 } 1008 }
987 } 1009 }
988 } else { 1010 } else {
989 // this node contains node pointers 1011 // this node contains node pointers
990 DEBUG_HEXDUMPC(buf, DESC_BLOCK_SIZE, ITEM_SIZE); 1012 DEBUG_HEXDUMPC(buf, DESC_BLOCK_SIZE, ITEM_SIZE32);
991 if (item_count > INDEX_COUNT_MAX) { 1013 if (item_count > INDEX_COUNT_MAX) {
992 DEBUG_WARN(("Item count %i too large, max is %i\n", item_count, INDEX_COUNT_MAX)); 1014 DEBUG_WARN(("Item count %i too large, max is %i\n", item_count, INDEX_COUNT_MAX));
993 if (buf) free(buf); 1015 if (buf) free(buf);
994 DEBUG_RET(); 1016 DEBUG_RET();
995 return -1; 1017 return -1;
996 } 1018 }
997 x = 0; 1019 x = 0;
998 while (x < item_count) { 1020 while (x < item_count) {
999 bptr+=_pst_decode_table(&table, bptr); 1021 bptr += _pst_decode_table(&table, bptr);
1000 x++; 1022 x++;
1001 if (table.start == 0) break; 1023 if (table.start == 0) break;
1002 if (x < item_count) { 1024 if (x < item_count) {
1003 _pst_decode_table(&table2, bptr); 1025 _pst_decode_table(&table2, bptr);
1004 } 1026 }
1044 DEBUG_RET(); 1066 DEBUG_RET();
1045 return 0; 1067 return 0;
1046 } 1068 }
1047 1069
1048 1070
1049 void* _pst_parse_item(pst_file *pf, pst_desc_ll *d_ptr) { 1071 pst_item* _pst_parse_item(pst_file *pf, pst_desc_ll *d_ptr) {
1050 pst_num_array * list; 1072 pst_num_array * list;
1051 pst_index2_ll *id2_head = NULL; 1073 pst_index2_ll *id2_head = NULL;
1052 pst_index_ll *id_ptr = NULL; 1074 pst_index_ll *id_ptr = NULL;
1053 pst_item *item = NULL; 1075 pst_item *item = NULL;
1054 pst_item_attach *attach = NULL; 1076 pst_item_attach *attach = NULL;
1589 VBUF_STATIC(strbuf, 1024); 1611 VBUF_STATIC(strbuf, 1024);
1590 VBUF_STATIC(unibuf, 1024); 1612 VBUF_STATIC(unibuf, 1024);
1591 //need UTF-16 zero-termination 1613 //need UTF-16 zero-termination
1592 vbset(strbuf, na_ptr->items[x]->data, na_ptr->items[x]->size); 1614 vbset(strbuf, na_ptr->items[x]->data, na_ptr->items[x]->size);
1593 vbappend(strbuf, "\0\0", 2); 1615 vbappend(strbuf, "\0\0", 2);
1594 DEBUG_INDEX(("Iconv in: ")); 1616 DEBUG_INDEX(("Iconv in:\n"));
1595 DEBUG_HEXDUMPC(strbuf->b, strbuf->dlen, 0x10); 1617 DEBUG_HEXDUMPC(strbuf->b, strbuf->dlen, 0x10);
1596 vb_utf16to8(unibuf, strbuf->b, strbuf->dlen); 1618 vb_utf16to8(unibuf, strbuf->b, strbuf->dlen);
1597 free(na_ptr->items[x]->data); 1619 free(na_ptr->items[x]->data);
1598 na_ptr->items[x]->size = unibuf->dlen; 1620 na_ptr->items[x]->size = unibuf->dlen;
1599 na_ptr->items[x]->data = xmalloc(unibuf->dlen); 1621 na_ptr->items[x]->data = xmalloc(unibuf->dlen);
1600 memcpy(na_ptr->items[x]->data, unibuf->b, unibuf->dlen); 1622 memcpy(na_ptr->items[x]->data, unibuf->b, unibuf->dlen);
1601 DEBUG_INDEX(("Iconv out: ")); 1623 DEBUG_INDEX(("Iconv out:\n"));
1602 DEBUG_HEXDUMPC(na_ptr->items[x]->data, na_ptr->items[x]->size, 0x10); 1624 DEBUG_HEXDUMPC(na_ptr->items[x]->data, na_ptr->items[x]->size, 0x10);
1603 } 1625 }
1604 if (na_ptr->items[x]->type == 0) na_ptr->items[x]->type = table_rec.ref_type; 1626 if (na_ptr->items[x]->type == 0) na_ptr->items[x]->type = table_rec.ref_type;
1605 } else { 1627 } else {
1606 WARN(("ERROR Unknown ref_type %#x\n", table_rec.ref_type)); 1628 WARN(("ERROR Unknown ref_type %#x\n", table_rec.ref_type));