Mercurial > libpst
comparison src/libpst.c @ 48:f66078abed38
more fixes for 64 bit format
author | carl |
---|---|
date | Fri, 18 Jan 2008 15:07:12 -0800 |
parents | 5fb8d997feed |
children | 17654fbdf76b |
comparison
equal
deleted
inserted
replaced
47:5fb8d997feed | 48:f66078abed38 |
---|---|
2 * libpst.c | 2 * libpst.c |
3 * Part of the LibPST project | 3 * Part of the LibPST project |
4 * Written by David Smith | 4 * Written by David Smith |
5 * dave.s@earthcorp.com | 5 * dave.s@earthcorp.com |
6 */ | 6 */ |
7 #include "define.h" | |
8 | |
7 #include <stdio.h> | 9 #include <stdio.h> |
8 #include <stdlib.h> | 10 #include <stdlib.h> |
9 #include <time.h> | 11 #include <time.h> |
10 #include <string.h> | 12 #include <string.h> |
11 #include <ctype.h> | 13 #include <ctype.h> |
13 #include <wchar.h> | 15 #include <wchar.h> |
14 #include <signal.h> | 16 #include <signal.h> |
15 #include <errno.h> | 17 #include <errno.h> |
16 #include <sys/stat.h> // mkdir | 18 #include <sys/stat.h> // mkdir |
17 #include <fcntl.h> // for Win32 definition of _O_BINARY | 19 #include <fcntl.h> // for Win32 definition of _O_BINARY |
18 #include "define.h" | |
19 #include "libstrfunc.h" | 20 #include "libstrfunc.h" |
20 #include "vbuf.h" | 21 #include "vbuf.h" |
21 | 22 |
22 #define ASSERT(x) { if(!(x)) raise( SIGSEGV ); } | 23 #define ASSERT(x) { if(!(x)) raise( SIGSEGV ); } |
23 | 24 |
31 #include "timeconv.h" | 32 #include "timeconv.h" |
32 //efine INDEX_DEPTH 0x4C | 33 //efine INDEX_DEPTH 0x4C |
33 //efine SECOND_DEPTH 0x5C | 34 //efine SECOND_DEPTH 0x5C |
34 #define INDEX_TYPE32 0x0E | 35 #define INDEX_TYPE32 0x0E |
35 #define INDEX_TYPE64 0x17 | 36 #define INDEX_TYPE64 0x17 |
37 #define INDEX_TYPE_OFFSET (off_t)0x0A | |
36 | 38 |
37 #define FILE_SIZE_POINTER32 (off_t)0xA8 | 39 #define FILE_SIZE_POINTER32 (off_t)0xA8 |
38 #define INDEX_POINTER32 (off_t)0xC4 | 40 #define INDEX_POINTER32 (off_t)0xC4 |
39 #define INDEX_BACK32 (off_t)0xC0 | 41 #define INDEX_BACK32 (off_t)0xC0 |
40 #define SECOND_POINTER32 (off_t)0xBC | 42 #define SECOND_POINTER32 (off_t)0xBC |
41 #define SECOND_BACK32 (off_t)0xB8 | 43 #define SECOND_BACK32 (off_t)0xB8 |
42 #define INDEX_TYPE_OFFSET32 (off_t)0x0A | |
43 #define ENC_OFFSET32 (off_t)0x1CD | 44 #define ENC_OFFSET32 (off_t)0x1CD |
44 | 45 |
45 #define FILE_SIZE_POINTER64 (off_t)0xB8 | 46 #define FILE_SIZE_POINTER64 (off_t)0xB8 |
46 #define INDEX_POINTER64 (off_t)0xF0 | 47 #define INDEX_POINTER64 (off_t)0xF0 |
47 #define INDEX_BACK64 (off_t)0xE8 | 48 #define INDEX_BACK64 (off_t)0xE8 |
48 #define SECOND_POINTER64 (off_t)0xE0 | 49 #define SECOND_POINTER64 (off_t)0xE0 |
49 #define SECOND_BACK64 (off_t)0xD8 | 50 #define SECOND_BACK64 (off_t)0xD8 |
50 #define INDEX_TYPE_OFFSET64 (off_t)0x0A | |
51 #define ENC_OFFSET64 (off_t)0x201 | 51 #define ENC_OFFSET64 (off_t)0x201 |
52 | 52 |
53 #define FILE_SIZE_POINTER ((pf->do_read64) ? FILE_SIZE_POINTER64 : FILE_SIZE_POINTER32) | 53 #define FILE_SIZE_POINTER ((pf->do_read64) ? FILE_SIZE_POINTER64 : FILE_SIZE_POINTER32) |
54 #define INDEX_POINTER ((pf->do_read64) ? INDEX_POINTER64 : INDEX_POINTER32) | 54 #define INDEX_POINTER ((pf->do_read64) ? INDEX_POINTER64 : INDEX_POINTER32) |
55 #define INDEX_BACK ((pf->do_read64) ? INDEX_BACK64 : INDEX_BACK32) | 55 #define INDEX_BACK ((pf->do_read64) ? INDEX_BACK64 : INDEX_BACK32) |
56 #define SECOND_POINTER ((pf->do_read64) ? SECOND_POINTER64 : SECOND_POINTER32) | 56 #define SECOND_POINTER ((pf->do_read64) ? SECOND_POINTER64 : SECOND_POINTER32) |
57 #define SECOND_BACK ((pf->do_read64) ? SECOND_BACK64 : SECOND_BACK32) | 57 #define SECOND_BACK ((pf->do_read64) ? SECOND_BACK64 : SECOND_BACK32) |
58 #define INDEX_TYPE_OFFSET ((pf->do_read64) ? INDEX_TYPE_OFFSET64 : INDEX_TYPE_OFFSET32) | |
59 #define INDEX_TYPE ((pf->do_read64) ? INDEX_TYPE64 : INDEX_TYPE32) | |
60 #define ENC_OFFSET ((pf->do_read64) ? ENC_OFFSET64 : ENC_OFFSET32) | 58 #define ENC_OFFSET ((pf->do_read64) ? ENC_OFFSET64 : ENC_OFFSET32) |
61 | 59 |
62 #define PST_SIGNATURE 0x4E444221 | 60 #define PST_SIGNATURE 0x4E444221 |
63 | 61 |
64 | 62 |
83 uint32_t id; | 81 uint32_t id; |
84 uint32_t table2; | 82 uint32_t table2; |
85 } pst_id2_assoc32; | 83 } pst_id2_assoc32; |
86 | 84 |
87 typedef struct pst_id2_assoc { | 85 typedef struct pst_id2_assoc { |
88 uint64_t id2; | 86 uint32_t id2; // only 32 bit here? |
87 uint16_t unknown1; | |
88 uint16_t unknown2; | |
89 uint64_t id; | 89 uint64_t id; |
90 uint64_t table2; | 90 uint64_t table2; |
91 } pst_id2_assoc; | 91 } pst_id2_assoc; |
92 | |
93 typedef struct pst_table3_rec32 { | |
94 uint32_t id; | |
95 } pst_table3_rec32; //for type 3 (0x0101) blocks | |
96 | |
97 typedef struct pst_table3_rec { | |
98 uint64_t id; | |
99 } pst_table3_rec; //for type 3 (0x0101) blocks | |
100 | |
92 | 101 |
93 // this is an array of the un-encrypted values. the un-encrypted value is in the position | 102 // this is an array of the un-encrypted values. the un-encrypted value is in the position |
94 // of the encrypted value. ie the encrypted value 0x13 represents 0x02 | 103 // of the encrypted value. ie the encrypted value 0x13 represents 0x02 |
95 // 0 1 2 3 4 5 6 7 | 104 // 0 1 2 3 4 5 6 7 |
96 // 8 9 a b c d e f | 105 // 8 9 a b c d e f |
168 DEBUG_RET(); | 177 DEBUG_RET(); |
169 return -1; | 178 return -1; |
170 } | 179 } |
171 | 180 |
172 // read index type | 181 // read index type |
173 pf->do_read64 = 0; // start with 32 bit format | |
174 (void)pst_getAtPos(pf->fp, INDEX_TYPE_OFFSET, &(pf->ind_type), sizeof(pf->ind_type)); | 182 (void)pst_getAtPos(pf->fp, INDEX_TYPE_OFFSET, &(pf->ind_type), sizeof(pf->ind_type)); |
175 DEBUG_INFO(("index_type = %i\n", pf->ind_type)); | 183 DEBUG_INFO(("index_type = %i\n", pf->ind_type)); |
176 if (pf->ind_type != INDEX_TYPE) { | 184 switch (pf->ind_type) { |
177 // try with 64 bit format | 185 case INDEX_TYPE32 : |
178 pf->do_read64 = 1; | 186 pf->do_read64 = 0; |
179 if (pf->ind_type != INDEX_TYPE) { | 187 break; |
188 case INDEX_TYPE64 : | |
189 pf->do_read64 = 1; | |
190 break; | |
191 default: | |
180 WARN(("unknown .pst format, possibly newer than Outlook 2003 PST file?\n")); | 192 WARN(("unknown .pst format, possibly newer than Outlook 2003 PST file?\n")); |
181 DEBUG_RET(); | 193 DEBUG_RET(); |
182 return -1; | 194 return -1; |
183 } | |
184 else { | |
185 WARN(("switching to 64 bit format...\n")); | |
186 } | |
187 } | 195 } |
188 | 196 |
189 // read encryption setting | 197 // read encryption setting |
190 (void)pst_getAtPos(pf->fp, ENC_OFFSET, &(pf->encryption), sizeof(pf->encryption)); | 198 (void)pst_getAtPos(pf->fp, ENC_OFFSET, &(pf->encryption), sizeof(pf->encryption)); |
191 DEBUG_INFO(("encrypt = %i\n", pf->encryption)); | 199 DEBUG_INFO(("encrypt = %i\n", pf->encryption)); |
192 | 200 |
193 pf->index2_back = pst_getIntAtPos(pf, SECOND_BACK); | 201 pf->index2_back = pst_getIntAtPos(pf, SECOND_BACK); |
194 pf->index2 = pst_getIntAtPos(pf, SECOND_POINTER); | 202 pf->index2 = pst_getIntAtPos(pf, SECOND_POINTER); |
195 pf->size = pst_getIntAtPos(pf, FILE_SIZE_POINTER); | 203 pf->size = pst_getIntAtPos(pf, FILE_SIZE_POINTER); |
196 DEBUG_INFO(("Pointer2 is %#llx, count %lli[%#llx]\n", pf->index2, pf->index2_back, pf->index2_back)); | 204 DEBUG_INFO(("Pointer2 is %#llx, back pointer2 is %#llx\n", pf->index2, pf->index2_back)); |
197 | 205 |
198 pf->index1_back = pst_getIntAtPos(pf, INDEX_BACK); | 206 pf->index1_back = pst_getIntAtPos(pf, INDEX_BACK); |
199 pf->index1 = pst_getIntAtPos(pf, INDEX_POINTER); | 207 pf->index1 = pst_getIntAtPos(pf, INDEX_POINTER); |
200 DEBUG_INFO(("Pointer1 is %#llx, count %lli[%#llx]\n", pf->index1, pf->index1_back, pf->index1_back)); | 208 DEBUG_INFO(("Pointer1 is %#llx, back pointer2 is %#llx\n", pf->index1, pf->index1_back)); |
201 | 209 |
202 DEBUG_RET(); | 210 DEBUG_RET(); |
203 return 0; | 211 return 0; |
204 } | 212 } |
205 | 213 |
398 (void)pst_printID2ptr(id2_head); | 406 (void)pst_printID2ptr(id2_head); |
399 } else { | 407 } else { |
400 DEBUG_WARN(("Have not been able to fetch any id2 values for item 0x61. Brace yourself!\n")); | 408 DEBUG_WARN(("Have not been able to fetch any id2 values for item 0x61. Brace yourself!\n")); |
401 } | 409 } |
402 | 410 |
403 na = pst_parse_block(pf, p->desc->id, id2_head); | 411 na = pst_parse_block(pf, p->desc->id, id2_head, NULL); |
404 if (!na) { | 412 if (!na) { |
405 DEBUG_WARN(("Cannot process desc block for item 0x61. Not loading extended Attributes\n")); | 413 DEBUG_WARN(("Cannot process desc block for item 0x61. Not loading extended Attributes\n")); |
406 if (id2_head) pst_free_id2(id2_head); | 414 if (id2_head) pst_free_id2(id2_head); |
407 DEBUG_RET(); | 415 DEBUG_RET(); |
408 return 0; | 416 return 0; |
637 size_t r; | 645 size_t r; |
638 if (pf->do_read64) { | 646 if (pf->do_read64) { |
639 DEBUG_INDEX(("Decoding assoc64\n")); | 647 DEBUG_INDEX(("Decoding assoc64\n")); |
640 DEBUG_HEXDUMPC(buf, sizeof(pst_id2_assoc), 0x10); | 648 DEBUG_HEXDUMPC(buf, sizeof(pst_id2_assoc), 0x10); |
641 memcpy(assoc, buf, sizeof(pst_id2_assoc)); | 649 memcpy(assoc, buf, sizeof(pst_id2_assoc)); |
642 LE64_CPU(assoc->id2); | 650 LE32_CPU(assoc->id2); |
643 LE64_CPU(assoc->id); | 651 LE64_CPU(assoc->id); |
644 LE64_CPU(assoc->table2); | 652 LE64_CPU(assoc->table2); |
645 r = sizeof(pst_id2_assoc); | 653 r = sizeof(pst_id2_assoc); |
646 } else { | 654 } else { |
647 pst_id2_assoc32 assoc32; | 655 pst_id2_assoc32 assoc32; |
658 } | 666 } |
659 return r; | 667 return r; |
660 } | 668 } |
661 | 669 |
662 | 670 |
671 static size_t pst_decode_type3(pst_file *pf, pst_table3_rec *table3_rec, char *buf); | |
672 static size_t pst_decode_type3(pst_file *pf, pst_table3_rec *table3_rec, char *buf) { | |
673 size_t r; | |
674 if (pf->do_read64) { | |
675 DEBUG_INDEX(("Decoding table3 64\n")); | |
676 DEBUG_HEXDUMPC(buf, sizeof(pst_table3_rec), 0x10); | |
677 memcpy(table3_rec, buf, sizeof(pst_table3_rec)); | |
678 LE64_CPU(table3_rec->id); | |
679 r = sizeof(pst_table3_rec); | |
680 } else { | |
681 pst_table3_rec32 table3_rec32; | |
682 DEBUG_INDEX(("Decoding table3 32\n")); | |
683 DEBUG_HEXDUMPC(buf, sizeof(pst_table3_rec32), 0x10); | |
684 memcpy(&table3_rec32, buf, sizeof(pst_table3_rec32)); | |
685 LE32_CPU(table3_rec32.id); | |
686 table3_rec->id = table3_rec32.id; | |
687 r = sizeof(pst_table3_rec32); | |
688 } | |
689 return r; | |
690 } | |
691 | |
692 | |
663 int pst_build_id_ptr(pst_file *pf, off_t offset, int32_t depth, uint64_t linku1, uint64_t start_val, uint64_t end_val) { | 693 int pst_build_id_ptr(pst_file *pf, off_t offset, int32_t depth, uint64_t linku1, uint64_t start_val, uint64_t end_val) { |
664 struct pst_table_ptr_structn table, table2; | 694 struct pst_table_ptr_structn table, table2; |
665 pst_index_ll *i_ptr=NULL; | 695 pst_index_ll *i_ptr=NULL; |
666 pst_index index; | 696 pst_index index; |
667 int32_t x, item_count; | 697 int32_t x, item_count; |
668 uint64_t old = start_val; | 698 uint64_t old = start_val; |
669 char *buf = NULL, *bptr; | 699 char *buf = NULL, *bptr; |
670 | 700 |
671 DEBUG_ENT("pst_build_id_ptr"); | 701 DEBUG_ENT("pst_build_id_ptr"); |
672 DEBUG_INDEX(("offset %x depth %i linku1 %llx start %llx end %llx\n", offset, depth, linku1, start_val, end_val)); | 702 DEBUG_INDEX(("offset %llx depth %i linku1 %llx start %llx end %llx\n", offset, depth, linku1, start_val, end_val)); |
673 if (end_val <= start_val) { | 703 if (end_val <= start_val) { |
674 DEBUG_WARN(("The end value is BEFORE the start value. This function will quit. Soz. [start:%#llx, end:%#llx]\n", start_val, end_val)); | 704 DEBUG_WARN(("The end value is BEFORE the start value. This function will quit. Soz. [start:%#llx, end:%#llx]\n", start_val, end_val)); |
675 DEBUG_RET(); | 705 DEBUG_RET(); |
676 return -1; | 706 return -1; |
677 } | 707 } |
876 int pst_build_desc_ptr (pst_file *pf, off_t offset, int32_t depth, uint64_t linku1, uint64_t *high_id, uint64_t start_val, uint64_t end_val) { | 906 int pst_build_desc_ptr (pst_file *pf, off_t offset, int32_t depth, uint64_t linku1, uint64_t *high_id, uint64_t start_val, uint64_t end_val) { |
877 struct pst_table_ptr_structn table, table2; | 907 struct pst_table_ptr_structn table, table2; |
878 pst_descn desc_rec; | 908 pst_descn desc_rec; |
879 pst_desc_ll *d_ptr=NULL, *parent=NULL; | 909 pst_desc_ll *d_ptr=NULL, *parent=NULL; |
880 int32_t x, item_count; | 910 int32_t x, item_count; |
881 uint32_t old = start_val; | 911 uint64_t old = start_val; |
882 char *buf = NULL, *bptr; | 912 char *buf = NULL, *bptr; |
883 struct cache_list_node *cache_ptr = NULL; | 913 struct cache_list_node *cache_ptr = NULL; |
884 struct cache_list_node *lostfound_ptr = NULL; | 914 struct cache_list_node *lostfound_ptr = NULL; |
885 struct cache_list_node *lostfound_shd = NULL; | 915 struct cache_list_node *lostfound_shd = NULL; |
886 struct cache_list_node *lostfound_tmp = NULL; | 916 struct cache_list_node *lostfound_tmp = NULL; |
1117 (void)pst_printID2ptr(id2_head); | 1147 (void)pst_printID2ptr(id2_head); |
1118 } else { | 1148 } else { |
1119 DEBUG_WARN(("Have not been able to fetch any id2 values for this item. Brace yourself!\n")); | 1149 DEBUG_WARN(("Have not been able to fetch any id2 values for this item. Brace yourself!\n")); |
1120 } | 1150 } |
1121 | 1151 |
1122 list = pst_parse_block(pf, d_ptr->desc->id, id2_head); | 1152 list = pst_parse_block(pf, d_ptr->desc->id, id2_head, NULL); |
1123 if (!list) { | 1153 if (!list) { |
1124 DEBUG_WARN(("pst_parse_block() returned an error for d_ptr->desc->id [%#llx]\n", d_ptr->desc->id)); | 1154 DEBUG_WARN(("pst_parse_block() returned an error for d_ptr->desc->id [%#llx]\n", d_ptr->desc->id)); |
1125 if (id2_head) pst_free_id2(id2_head); | 1155 if (id2_head) pst_free_id2(id2_head); |
1126 DEBUG_RET(); | 1156 DEBUG_RET(); |
1127 return NULL; | 1157 return NULL; |
1148 free(item->attach); | 1178 free(item->attach); |
1149 item->attach = attach; | 1179 item->attach = attach; |
1150 } | 1180 } |
1151 | 1181 |
1152 DEBUG_EMAIL(("ATTACHMENT processing attachment\n")); | 1182 DEBUG_EMAIL(("ATTACHMENT processing attachment\n")); |
1153 if ((list = pst_parse_block(pf, id_ptr->id, id2_head)) == NULL) { | 1183 if ((list = pst_parse_block(pf, id_ptr->id, id2_head, NULL)) == NULL) { |
1154 DEBUG_WARN(("ERROR error processing main attachment record\n")); | 1184 DEBUG_WARN(("ERROR error processing main attachment record\n")); |
1155 if (item) pst_freeItem(item); | 1185 if (item) pst_freeItem(item); |
1156 if (id2_head) pst_free_id2(id2_head); | 1186 if (id2_head) pst_free_id2(id2_head); |
1157 DEBUG_RET(); | 1187 DEBUG_RET(); |
1158 return NULL; | 1188 return NULL; |
1185 while (attach) { | 1215 while (attach) { |
1186 if ((id_ptr = pst_getID2(id2_head, attach->id2_val))) { | 1216 if ((id_ptr = pst_getID2(id2_head, attach->id2_val))) { |
1187 // id_ptr is a record describing the attachment | 1217 // id_ptr is a record describing the attachment |
1188 // we pass NULL instead of id2_head cause we don't want it to | 1218 // we pass NULL instead of id2_head cause we don't want it to |
1189 // load all the extra stuff here. | 1219 // load all the extra stuff here. |
1190 if ((list = pst_parse_block(pf, id_ptr->id, NULL)) == NULL) { | 1220 if ((list = pst_parse_block(pf, id_ptr->id, NULL, NULL)) == NULL) { |
1191 DEBUG_WARN(("ERROR error processing an attachment record\n")); | 1221 DEBUG_WARN(("ERROR error processing an attachment record\n")); |
1192 attach = attach->next; | 1222 attach = attach->next; |
1193 continue; | 1223 continue; |
1194 } | 1224 } |
1195 if (pst_process(list, item, attach)) { | 1225 if (pst_process(list, item, attach)) { |
1246 if (p6->needfree) free(p6->from); | 1276 if (p6->needfree) free(p6->from); |
1247 if (p7->needfree) free(p7->from); | 1277 if (p7->needfree) free(p7->from); |
1248 } | 1278 } |
1249 | 1279 |
1250 | 1280 |
1251 pst_num_array * pst_parse_block(pst_file *pf, uint64_t block_id, pst_index2_ll *i2_head) { | 1281 pst_num_array * pst_parse_block(pst_file *pf, uint64_t block_id, pst_index2_ll *i2_head, pst_num_array *na_head) { |
1252 unsigned char *buf = NULL; | 1282 unsigned char *buf = NULL; |
1253 pst_num_array *na_ptr = NULL, *na_head = NULL; | 1283 pst_num_array *na_ptr = NULL; |
1254 pst_block_offset_pointer block_offset1; | 1284 pst_block_offset_pointer block_offset1; |
1255 pst_block_offset_pointer block_offset2; | 1285 pst_block_offset_pointer block_offset2; |
1256 pst_block_offset_pointer block_offset3; | 1286 pst_block_offset_pointer block_offset3; |
1257 pst_block_offset_pointer block_offset4; | 1287 pst_block_offset_pointer block_offset4; |
1258 pst_block_offset_pointer block_offset5; | 1288 pst_block_offset_pointer block_offset5; |
1273 unsigned char* ind2_ptr = NULL; | 1303 unsigned char* ind2_ptr = NULL; |
1274 size_t read_size=0; | 1304 size_t read_size=0; |
1275 pst_x_attrib_ll *mapptr; | 1305 pst_x_attrib_ll *mapptr; |
1276 | 1306 |
1277 struct { | 1307 struct { |
1278 uint16_t type; | |
1279 uint16_t ref_type; | |
1280 uint32_t value; | |
1281 } table_rec; //for type 1 (0xBCEC) blocks | |
1282 struct { | |
1283 uint16_t ref_type; | |
1284 uint16_t type; | |
1285 uint16_t ind2_off; | |
1286 uint8_t size; | |
1287 uint8_t slot; | |
1288 } table2_rec; //for type 2 (0x7CEC) blocks | |
1289 struct { | |
1290 uint32_t id; | |
1291 } table3_rec; //for type 3 (0x0101) blocks | |
1292 struct { | |
1293 uint16_t index_offset; | 1308 uint16_t index_offset; |
1294 uint16_t type; | 1309 uint16_t type; |
1295 uint32_t offset; | 1310 uint32_t offset; |
1296 } block_hdr; | 1311 } block_hdr; |
1312 | |
1297 struct { | 1313 struct { |
1298 unsigned char seven_c; | 1314 unsigned char seven_c; |
1299 unsigned char item_count; | 1315 unsigned char item_count; |
1300 uint16_t u1; | 1316 uint16_t u1; |
1301 uint16_t u2; | 1317 uint16_t u2; |
1304 uint32_t b_five_offset; | 1320 uint32_t b_five_offset; |
1305 uint32_t ind2_offset; | 1321 uint32_t ind2_offset; |
1306 uint16_t u7; | 1322 uint16_t u7; |
1307 uint16_t u8; | 1323 uint16_t u8; |
1308 } seven_c_blk; | 1324 } seven_c_blk; |
1325 | |
1309 struct _type_d_rec { | 1326 struct _type_d_rec { |
1310 uint32_t id; | 1327 uint32_t id; |
1311 uint32_t u1; | 1328 uint32_t u1; |
1312 } * type_d_rec; | 1329 } * type_d_rec; |
1330 | |
1331 struct { | |
1332 uint16_t type; | |
1333 uint16_t ref_type; | |
1334 uint32_t value; | |
1335 } table_rec; //for type 1 (0xBCEC) blocks | |
1336 | |
1337 struct { | |
1338 uint16_t ref_type; | |
1339 uint16_t type; | |
1340 uint16_t ind2_off; | |
1341 uint8_t size; | |
1342 uint8_t slot; | |
1343 } table2_rec; //for type 2 (0x7CEC) blocks | |
1344 | |
1345 pst_table3_rec table3_rec; //for type 3 (0x0101) blocks | |
1313 | 1346 |
1314 DEBUG_ENT("pst_parse_block"); | 1347 DEBUG_ENT("pst_parse_block"); |
1315 if ((read_size = pst_ff_getIDblock_dec(pf, block_id, &buf)) == 0) { | 1348 if ((read_size = pst_ff_getIDblock_dec(pf, block_id, &buf)) == 0) { |
1316 WARN(("Error reading block id %#llx\n", block_id)); | 1349 WARN(("Error reading block id %#llx\n", block_id)); |
1317 if (buf) free (buf); | 1350 if (buf) free (buf); |
1329 | 1362 |
1330 memcpy(&block_hdr, buf, sizeof(block_hdr)); | 1363 memcpy(&block_hdr, buf, sizeof(block_hdr)); |
1331 LE16_CPU(block_hdr.index_offset); | 1364 LE16_CPU(block_hdr.index_offset); |
1332 LE16_CPU(block_hdr.type); | 1365 LE16_CPU(block_hdr.type); |
1333 LE32_CPU(block_hdr.offset); | 1366 LE32_CPU(block_hdr.offset); |
1334 DEBUG_EMAIL(("block header (index_offset=%#hx, type=%#hx, offset=%#hx\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset)); | 1367 DEBUG_EMAIL(("block header (index_offset=%#hx, type=%#hx, offset=%#hx)\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset)); |
1335 | 1368 |
1336 ind_ptr = block_hdr.index_offset; | 1369 ind_ptr = block_hdr.index_offset; |
1337 | 1370 |
1338 if (block_hdr.type == (uint16_t)0xBCEC) { //type 1 | 1371 if (block_hdr.type == (uint16_t)0xBCEC) { //type 1 |
1339 block_type = 1; | 1372 block_type = 1; |
1438 ind2_end = block_offset6.to; | 1471 ind2_end = block_offset6.to; |
1439 } | 1472 } |
1440 else if (block_hdr.index_offset == (uint16_t)0x0101) { //type 3 | 1473 else if (block_hdr.index_offset == (uint16_t)0x0101) { //type 3 |
1441 unsigned char *buf2 = NULL; | 1474 unsigned char *buf2 = NULL; |
1442 uint16_t n = block_hdr.type; // count | 1475 uint16_t n = block_hdr.type; // count |
1443 size_t m = sizeof(table3_rec); | |
1444 uint16_t i; | 1476 uint16_t i; |
1445 block_type = 3; | 1477 block_type = 3; |
1478 char *b_ptr = buf + 8; | |
1446 for (i=0; i<n; i++) { | 1479 for (i=0; i<n; i++) { |
1447 memcpy(&table3_rec, buf+8+i*m, m); | 1480 b_ptr += pst_decode_type3(pf, &table3_rec, b_ptr); |
1448 LE32_CPU(table3_rec.id); | 1481 //(void)pst_ff_getIDblock_dec(pf, table3_rec.id, &buf2); |
1449 (void)pst_ff_getIDblock_dec(pf, table3_rec.id, &buf2); | 1482 //if (buf2) free(buf2); |
1450 if (buf2) free(buf2); | 1483 //buf2 = NULL; |
1451 buf2 = NULL; | 1484 na_head = pst_parse_block(pf, table3_rec.id, i2_head, na_head); // !! this is still not correct |
1452 } | 1485 } |
1453 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); | 1486 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); |
1454 DEBUG_RET(); | 1487 DEBUG_RET(); |
1455 return NULL; | 1488 return na_head; |
1456 } else { | 1489 } else { |
1457 WARN(("ERROR: Unknown block constant - %#hx for id %#llx\n", block_hdr.type, block_id)); | 1490 WARN(("ERROR: Unknown block constant - %#hx for id %#llx\n", block_hdr.type, block_id)); |
1458 DEBUG_HEXDUMPC(buf, read_size,0x10); | 1491 DEBUG_HEXDUMPC(buf, read_size,0x10); |
1459 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); | 1492 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); |
1460 DEBUG_RET(); | 1493 DEBUG_RET(); |
1465 for (count_rec=0; count_rec<num_recs; count_rec++) { | 1498 for (count_rec=0; count_rec<num_recs; count_rec++) { |
1466 na_ptr = (pst_num_array*) xmalloc(sizeof(pst_num_array)); | 1499 na_ptr = (pst_num_array*) xmalloc(sizeof(pst_num_array)); |
1467 memset(na_ptr, 0, sizeof(pst_num_array)); | 1500 memset(na_ptr, 0, sizeof(pst_num_array)); |
1468 na_ptr->next = na_head; | 1501 na_ptr->next = na_head; |
1469 na_head = na_ptr; | 1502 na_head = na_ptr; |
1470 // allocate an array of count num_recs to contain sizeof(structpst_num_item) | 1503 // allocate an array of count num_recs to contain sizeof(struct pst_num_item) |
1471 na_ptr->items = (struct pst_num_item**) xmalloc(sizeof(struct pst_num_item)*num_list); | 1504 na_ptr->items = (struct pst_num_item**) xmalloc(sizeof(struct pst_num_item)*num_list); |
1472 na_ptr->count_item = num_list; | 1505 na_ptr->count_item = num_list; |
1473 na_ptr->orig_count = num_list; | 1506 na_ptr->orig_count = num_list; |
1474 na_ptr->count_array = (int32_t)num_recs; // each record will have a record of the total number of records | 1507 na_ptr->count_array = (int32_t)num_recs; // each record will have a record of the total number of records |
1475 for (x=0; x<num_list; x++) na_ptr->items[x] = NULL; | 1508 for (x=0; x<num_list; x++) na_ptr->items[x] = NULL; |
1677 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); | 1710 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); |
1678 DEBUG_RET(); | 1711 DEBUG_RET(); |
1679 return na_head; | 1712 return na_head; |
1680 } | 1713 } |
1681 | 1714 |
1715 // This version of free does NULL check first | |
1716 #define SAFE_FREE(x) {if (x) free(x);} | |
1717 | |
1682 | 1718 |
1683 // check if item->email is NULL, and init if so | 1719 // check if item->email is NULL, and init if so |
1684 #define MALLOC_EMAIL(x) { if (!x->email) { x->email = (pst_item_email*) xmalloc(sizeof(pst_item_email)); memset(x->email, 0, sizeof(pst_item_email) );} } | 1720 #define MALLOC_EMAIL(x) { if (!x->email) { x->email = (pst_item_email*) xmalloc(sizeof(pst_item_email)); memset(x->email, 0, sizeof(pst_item_email) );} } |
1685 #define MALLOC_FOLDER(x) { if (!x->folder) { x->folder = (pst_item_folder*) xmalloc(sizeof(pst_item_folder)); memset(x->folder, 0, sizeof(pst_item_folder) );} } | 1721 #define MALLOC_FOLDER(x) { if (!x->folder) { x->folder = (pst_item_folder*) xmalloc(sizeof(pst_item_folder)); memset(x->folder, 0, sizeof(pst_item_folder) );} } |
1686 #define MALLOC_CONTACT(x) { if (!x->contact) { x->contact = (pst_item_contact*) xmalloc(sizeof(pst_item_contact)); memset(x->contact, 0, sizeof(pst_item_contact) );} } | 1722 #define MALLOC_CONTACT(x) { if (!x->contact) { x->contact = (pst_item_contact*) xmalloc(sizeof(pst_item_contact)); memset(x->contact, 0, sizeof(pst_item_contact) );} } |
1692 targ = type realloc(targ, list->items[x]->size+1); \ | 1728 targ = type realloc(targ, list->items[x]->size+1); \ |
1693 memcpy(targ, list->items[x]->data, list->items[x]->size); \ | 1729 memcpy(targ, list->items[x]->data, list->items[x]->size); \ |
1694 memset(((char*)targ)+list->items[x]->size, 0, (size_t)1); \ | 1730 memset(((char*)targ)+list->items[x]->size, 0, (size_t)1); \ |
1695 } | 1731 } |
1696 // malloc space and copy the current item's data and size | 1732 // malloc space and copy the current item's data and size |
1697 #define LIST_COPY_SIZE(targ, type, mysize) { \ | 1733 #define LIST_COPY_SIZE(targ, type, mysize) { \ |
1698 mysize = list->items[x]->size; \ | 1734 mysize = list->items[x]->size; \ |
1699 targ = type realloc(targ, mysize); \ | 1735 if (mysize) { \ |
1700 memcpy(targ, list->items[x]->data, mysize); \ | 1736 targ = type realloc(targ, mysize); \ |
1737 memcpy(targ, list->items[x]->data, mysize); \ | |
1738 } \ | |
1739 else { \ | |
1740 SAFE_FREE(targ); \ | |
1741 targ = NULL; \ | |
1742 } \ | |
1701 } | 1743 } |
1702 | 1744 |
1703 #define NULL_CHECK(x) { if (!x) { DEBUG_EMAIL(("NULL_CHECK: Null Found\n")); break;} } | 1745 #define NULL_CHECK(x) { if (!x) { DEBUG_EMAIL(("NULL_CHECK: Null Found\n")); break;} } |
1704 | 1746 |
1705 #define MOVE_NEXT(targ) { \ | 1747 #define MOVE_NEXT(targ) { \ |
3441 list->id, block_head.count, list->offset)); | 3483 list->id, block_head.count, list->offset)); |
3442 x = 0; | 3484 x = 0; |
3443 b_ptr = buf + ((pf->do_read64) ? 0x08 : 0x04); | 3485 b_ptr = buf + ((pf->do_read64) ? 0x08 : 0x04); |
3444 while (x < block_head.count) { | 3486 while (x < block_head.count) { |
3445 b_ptr += pst_decode_assoc(pf, &id2_rec, b_ptr); | 3487 b_ptr += pst_decode_assoc(pf, &id2_rec, b_ptr); |
3446 // memcpy(&id2_rec, &(buf[b_ptr]), sizeof(id2_rec)); | 3488 DEBUG_INDEX(("\tid2 = %#x, id = %#llx, table2 = %#llx\n", id2_rec.id2, id2_rec.id, id2_rec.table2)); |
3447 // LE32_CPU(id2_rec.id2); | |
3448 // LE32_CPU(id2_rec.id); | |
3449 // LE32_CPU(id2_rec.table2); | |
3450 // | |
3451 // b_ptr += sizeof(id2_rec); | |
3452 DEBUG_INDEX(("\tid2 = %#llx, id = %#llx, table2 = %#llx\n", id2_rec.id2, id2_rec.id, id2_rec.table2)); | |
3453 if ((i_ptr = pst_getID(pf, id2_rec.id)) == NULL) { | 3489 if ((i_ptr = pst_getID(pf, id2_rec.id)) == NULL) { |
3454 DEBUG_WARN(("\t\t%#llx - Not Found\n", id2_rec.id)); | 3490 DEBUG_WARN(("\t\t%#llx - Not Found\n", id2_rec.id)); |
3455 } else { | 3491 } else { |
3456 DEBUG_INDEX(("\t\t%#llx - Offset %#llx, u1 %#llx, Size %lli(%#llx)\n", i_ptr->id, i_ptr->offset, i_ptr->u1, i_ptr->size, i_ptr->size)); | 3492 DEBUG_INDEX(("\t\t%#llx - Offset %#llx, u1 %#llx, Size %lli(%#llx)\n", i_ptr->id, i_ptr->offset, i_ptr->u1, i_ptr->size, i_ptr->size)); |
3457 // add it to the linked list | 3493 // add it to the linked list |
3491 if (buf) free (buf); | 3527 if (buf) free (buf); |
3492 DEBUG_RET(); | 3528 DEBUG_RET(); |
3493 return head; | 3529 return head; |
3494 } | 3530 } |
3495 | 3531 |
3496 | |
3497 // This version of free does NULL check first | |
3498 #define SAFE_FREE(x) {if (x) free(x);} | |
3499 | 3532 |
3500 void pst_freeItem(pst_item *item) { | 3533 void pst_freeItem(pst_item *item) { |
3501 pst_item_attach *t; | 3534 pst_item_attach *t; |
3502 pst_item_extra_field *et; | 3535 pst_item_extra_field *et; |
3503 | 3536 |
4072 size_t pst_ff_getIDblock(pst_file *pf, uint64_t id, unsigned char** b) { | 4105 size_t pst_ff_getIDblock(pst_file *pf, uint64_t id, unsigned char** b) { |
4073 pst_index_ll *rec; | 4106 pst_index_ll *rec; |
4074 size_t rsize = 0; | 4107 size_t rsize = 0; |
4075 DEBUG_ENT("pst_ff_getIDblock"); | 4108 DEBUG_ENT("pst_ff_getIDblock"); |
4076 if ((rec = pst_getID(pf, id)) == NULL) { | 4109 if ((rec = pst_getID(pf, id)) == NULL) { |
4077 DEBUG_INDEX(("Cannot find ID %#x\n", id)); | 4110 DEBUG_INDEX(("Cannot find ID %#llx\n", id)); |
4078 DEBUG_RET(); | 4111 DEBUG_RET(); |
4079 return 0; | 4112 return 0; |
4080 } | 4113 } |
4081 (void)fseek(pf->fp, rec->offset, SEEK_SET); | 4114 (void)fseek(pf->fp, rec->offset, SEEK_SET); |
4082 if (*b) { | 4115 if (*b) { |
4083 DEBUG_INDEX(("freeing old memory in b\n")); | 4116 DEBUG_INDEX(("freeing old memory in b\n")); |
4084 free(*b); | 4117 free(*b); |
4085 } | 4118 } |
4086 | 4119 |
4087 DEBUG_INDEX(("id = %#x, record size = %#x, offset = %#x\n", id, rec->size, rec->offset)); | 4120 DEBUG_INDEX(("id = %#llx, record size = %#x, offset = %#x\n", id, rec->size, rec->offset)); |
4088 *b = (char*) xmalloc(rec->size+1); | 4121 *b = (char*) xmalloc(rec->size+1); |
4089 rsize = fread(*b, (size_t)1, rec->size, pf->fp); | 4122 rsize = fread(*b, (size_t)1, rec->size, pf->fp); |
4090 if (rsize != rec->size) { | 4123 if (rsize != rec->size) { |
4091 DEBUG_WARN(("Didn't read all the size. fread returned less [%i instead of %i]\n", rsize, rec->size)); | 4124 DEBUG_WARN(("Didn't read all the size. fread returned less [%i instead of %i]\n", rsize, rec->size)); |
4092 if (feof(pf->fp)) { | 4125 if (feof(pf->fp)) { |
4357 return x; | 4390 return x; |
4358 } | 4391 } |
4359 | 4392 |
4360 | 4393 |
4361 char *pst_rfc2426_escape(char *str) { | 4394 char *pst_rfc2426_escape(char *str) { |
4362 static char* buf = NULL; | 4395 static char* buf = NULL; |
4396 static size_t buflen = 0; | |
4363 char *ret, *a, *b; | 4397 char *ret, *a, *b; |
4364 size_t x = 0; | 4398 size_t x = 0; |
4365 int y, z; | 4399 int y, z; |
4366 DEBUG_ENT("rfc2426_escape"); | 4400 DEBUG_ENT("rfc2426_escape"); |
4367 if (!str) | 4401 if (!str) |
4377 if (y == 0 && z == 0) | 4411 if (y == 0 && z == 0) |
4378 // there isn't any extra space required | 4412 // there isn't any extra space required |
4379 ret = str; | 4413 ret = str; |
4380 else { | 4414 else { |
4381 x = strlen(str) + y - z + 1; // don't forget room for the NUL | 4415 x = strlen(str) + y - z + 1; // don't forget room for the NUL |
4382 buf = (char*) realloc(buf, x); | 4416 if (x > buflen) { |
4417 buf = (char*) realloc(buf, x); | |
4418 buflen = x; | |
4419 } | |
4383 a = str; | 4420 a = str; |
4384 b = buf; | 4421 b = buf; |
4385 while (*a != '\0') { | 4422 while (*a != '\0') { |
4386 switch (*a) { | 4423 switch (*a) { |
4387 case ',' : | 4424 case ',' : |