Mercurial > libpst
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)); |