Mercurial > libpst
comparison src/libpst.c @ 50:fb3818370dd6 stable-0-6-4
more fixes for 64 bit format
author | carl |
---|---|
date | Sat, 19 Jan 2008 16:30:16 -0800 |
parents | 17654fbdf76b |
children | 06c0262ad689 |
comparison
equal
deleted
inserted
replaced
49:17654fbdf76b | 50:fb3818370dd6 |
---|---|
62 struct pst_table_ptr_struct32{ | 62 struct pst_table_ptr_struct32{ |
63 uint32_t start; | 63 uint32_t start; |
64 uint32_t u1; | 64 uint32_t u1; |
65 uint32_t offset; | 65 uint32_t offset; |
66 }; | 66 }; |
67 | |
68 | |
67 struct pst_table_ptr_structn{ | 69 struct pst_table_ptr_structn{ |
68 uint64_t start; | 70 uint64_t start; |
69 uint64_t u1; | 71 uint64_t u1; |
70 uint64_t offset; | 72 uint64_t offset; |
71 }; | 73 }; |
72 | 74 |
75 | |
73 typedef struct pst_block_header { | 76 typedef struct pst_block_header { |
74 uint16_t type; | 77 uint16_t type; |
75 uint16_t count; | 78 uint16_t count; |
76 } pst_block_header; | 79 } pst_block_header; |
80 | |
77 | 81 |
78 typedef struct pst_id2_assoc32 { | 82 typedef struct pst_id2_assoc32 { |
79 uint32_t id2; | 83 uint32_t id2; |
80 uint32_t id; | 84 uint32_t id; |
81 uint32_t table2; | 85 uint32_t table2; |
82 } pst_id2_assoc32; | 86 } pst_id2_assoc32; |
87 | |
83 | 88 |
84 typedef struct pst_id2_assoc { | 89 typedef struct pst_id2_assoc { |
85 uint32_t id2; // only 32 bit here? | 90 uint32_t id2; // only 32 bit here? |
86 uint16_t unknown1; | 91 uint16_t unknown1; |
87 uint16_t unknown2; | 92 uint16_t unknown2; |
88 uint64_t id; | 93 uint64_t id; |
89 uint64_t table2; | 94 uint64_t table2; |
90 } pst_id2_assoc; | 95 } pst_id2_assoc; |
91 | 96 |
97 | |
92 typedef struct pst_table3_rec32 { | 98 typedef struct pst_table3_rec32 { |
93 uint32_t id; | 99 uint32_t id; |
94 } pst_table3_rec32; //for type 3 (0x0101) blocks | 100 } pst_table3_rec32; //for type 3 (0x0101) blocks |
95 | 101 |
102 | |
96 typedef struct pst_table3_rec { | 103 typedef struct pst_table3_rec { |
97 uint64_t id; | 104 uint64_t id; |
98 } pst_table3_rec; //for type 3 (0x0101) blocks | 105 } pst_table3_rec; //for type 3 (0x0101) blocks |
106 | |
107 | |
108 typedef struct pst_block_hdr { | |
109 uint16_t index_offset; | |
110 uint16_t type; | |
111 uint32_t offset; | |
112 } pst_block_hdr; | |
99 | 113 |
100 | 114 |
101 // this is an array of the un-encrypted values. the un-encrypted value is in the position | 115 // this is an array of the un-encrypted values. the un-encrypted value is in the position |
102 // of the encrypted value. ie the encrypted value 0x13 represents 0x02 | 116 // of the encrypted value. ie the encrypted value 0x13 represents 0x02 |
103 // 0 1 2 3 4 5 6 7 | 117 // 0 1 2 3 4 5 6 7 |
1304 unsigned char* fr_ptr; | 1318 unsigned char* fr_ptr; |
1305 unsigned char* to_ptr; | 1319 unsigned char* to_ptr; |
1306 unsigned char* ind2_end = NULL; | 1320 unsigned char* ind2_end = NULL; |
1307 unsigned char* ind2_ptr = NULL; | 1321 unsigned char* ind2_ptr = NULL; |
1308 pst_x_attrib_ll *mapptr; | 1322 pst_x_attrib_ll *mapptr; |
1309 | 1323 pst_block_hdr block_hdr; |
1310 struct { | 1324 pst_table3_rec table3_rec; //for type 3 (0x0101) blocks |
1311 uint16_t index_offset; | |
1312 uint16_t type; | |
1313 uint32_t offset; | |
1314 } block_hdr; | |
1315 | 1325 |
1316 struct { | 1326 struct { |
1317 unsigned char seven_c; | 1327 unsigned char seven_c; |
1318 unsigned char item_count; | 1328 unsigned char item_count; |
1319 uint16_t u1; | 1329 uint16_t u1; |
1343 uint16_t ind2_off; | 1353 uint16_t ind2_off; |
1344 uint8_t size; | 1354 uint8_t size; |
1345 uint8_t slot; | 1355 uint8_t slot; |
1346 } table2_rec; //for type 2 (0x7CEC) blocks | 1356 } table2_rec; //for type 2 (0x7CEC) blocks |
1347 | 1357 |
1348 pst_table3_rec table3_rec; //for type 3 (0x0101) blocks | |
1349 | |
1350 DEBUG_ENT("pst_parse_block"); | 1358 DEBUG_ENT("pst_parse_block"); |
1351 if ((read_size = pst_ff_getIDblock_dec(pf, block_id, &buf)) == 0) { | 1359 if ((read_size = pst_ff_getIDblock_dec(pf, block_id, &buf)) == 0) { |
1352 WARN(("Error reading block id %#llx\n", block_id)); | 1360 WARN(("Error reading block id %#llx\n", block_id)); |
1353 if (buf) free (buf); | 1361 if (buf) free (buf); |
1354 DEBUG_RET(); | 1362 DEBUG_RET(); |
1368 LE16_CPU(block_hdr.type); | 1376 LE16_CPU(block_hdr.type); |
1369 LE32_CPU(block_hdr.offset); | 1377 LE32_CPU(block_hdr.offset); |
1370 DEBUG_EMAIL(("block header (index_offset=%#hx, type=%#hx, offset=%#hx)\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset)); | 1378 DEBUG_EMAIL(("block header (index_offset=%#hx, type=%#hx, offset=%#hx)\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset)); |
1371 | 1379 |
1372 if (block_hdr.index_offset == (uint16_t)0x0101) { //type 3 | 1380 if (block_hdr.index_offset == (uint16_t)0x0101) { //type 3 |
1381 size_t i; | |
1382 char *b_ptr = buf + 8; | |
1373 subblocks.subblock_count = block_hdr.type; | 1383 subblocks.subblock_count = block_hdr.type; |
1374 subblocks.subs = malloc(sizeof(pst_subblock) * subblocks.subblock_count); | 1384 subblocks.subs = malloc(sizeof(pst_subblock) * subblocks.subblock_count); |
1375 size_t i; | |
1376 char *b_ptr = buf + 8; | |
1377 for (i=0; i<subblocks.subblock_count; i++) { | 1385 for (i=0; i<subblocks.subblock_count; i++) { |
1378 b_ptr += pst_decode_type3(pf, &table3_rec, b_ptr); | 1386 b_ptr += pst_decode_type3(pf, &table3_rec, b_ptr); |
1379 subblocks.subs[i].buf = NULL; | 1387 subblocks.subs[i].buf = NULL; |
1380 subblocks.subs[i].read_size = pst_ff_getIDblock_dec(pf, table3_rec.id, &subblocks.subs[i].buf); | 1388 subblocks.subs[i].read_size = pst_ff_getIDblock_dec(pf, table3_rec.id, &subblocks.subs[i].buf); |
1381 if (subblocks.subs[i].buf) { | 1389 if (subblocks.subs[i].buf) { |
1395 LE32_CPU(block_hdr.offset); | 1403 LE32_CPU(block_hdr.offset); |
1396 DEBUG_EMAIL(("block header (index_offset=%#hx, type=%#hx, offset=%#hx)\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset)); | 1404 DEBUG_EMAIL(("block header (index_offset=%#hx, type=%#hx, offset=%#hx)\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset)); |
1397 } | 1405 } |
1398 else { | 1406 else { |
1399 // setup the subblock descriptors, but we only have one block | 1407 // setup the subblock descriptors, but we only have one block |
1400 subblocks.subblock_count = 1; | 1408 subblocks.subblock_count = (size_t)1; |
1401 subblocks.subs = malloc(sizeof(pst_subblock)); | 1409 subblocks.subs = malloc(sizeof(pst_subblock)); |
1402 subblocks.subs[0].buf = buf; | 1410 subblocks.subs[0].buf = buf; |
1403 subblocks.subs[0].read_size = read_size; | 1411 subblocks.subs[0].read_size = read_size; |
1404 subblocks.subs[0].i_offset = block_hdr.index_offset; | 1412 subblocks.subs[0].i_offset = block_hdr.index_offset; |
1405 } | 1413 } |
1549 | 1557 |
1550 // table_rec and table2_rec are arranged differently, so assign the values across | 1558 // table_rec and table2_rec are arranged differently, so assign the values across |
1551 table_rec.type = table2_rec.type; | 1559 table_rec.type = table2_rec.type; |
1552 table_rec.ref_type = table2_rec.ref_type; | 1560 table_rec.ref_type = table2_rec.ref_type; |
1553 table_rec.value = 0; | 1561 table_rec.value = 0; |
1554 if ((ind2_end - ind2_ptr) >= (table2_rec.ind2_off + table2_rec.size)) { | 1562 if ((ind2_end - ind2_ptr) >= (int)(table2_rec.ind2_off + table2_rec.size)) { |
1555 size_t n = table2_rec.size; | 1563 size_t n = table2_rec.size; |
1556 size_t m = sizeof(table_rec.value); | 1564 size_t m = sizeof(table_rec.value); |
1557 if (n <= m) { | 1565 if (n <= m) { |
1558 memcpy(&table_rec.value, ind2_ptr + table2_rec.ind2_off, n); | 1566 memcpy(&table_rec.value, ind2_ptr + table2_rec.ind2_off, n); |
1559 } | 1567 } |
1669 na_ptr->count_item --; //we will be skipping a row | 1677 na_ptr->count_item --; //we will be skipping a row |
1670 continue; | 1678 continue; |
1671 } | 1679 } |
1672 } | 1680 } |
1673 else { | 1681 else { |
1674 value_size = block_offset7.to - block_offset7.from; | 1682 value_size = (size_t)(block_offset7.to - block_offset7.from); |
1675 na_ptr->items[x]->size = value_size; | 1683 na_ptr->items[x]->size = value_size; |
1676 na_ptr->items[x]->type = table_rec.ref_type; | 1684 na_ptr->items[x]->type = table_rec.ref_type; |
1677 na_ptr->items[x]->data = xmalloc(value_size+1); | 1685 na_ptr->items[x]->data = xmalloc(value_size+1); |
1678 memcpy(na_ptr->items[x]->data, block_offset7.from, value_size); | 1686 memcpy(na_ptr->items[x]->data, block_offset7.from, value_size); |
1679 na_ptr->items[x]->data[value_size] = '\0'; // it might be a string, null terminate it. | 1687 na_ptr->items[x]->data[value_size] = '\0'; // it might be a string, null terminate it. |
1861 item->type = PST_TYPE_REPORT; | 1869 item->type = PST_TYPE_REPORT; |
1862 else if (pst_strincmp("IPM.Activity", item->ascii_type, 12) == 0) | 1870 else if (pst_strincmp("IPM.Activity", item->ascii_type, 12) == 0) |
1863 item->type = PST_TYPE_JOURNAL; | 1871 item->type = PST_TYPE_JOURNAL; |
1864 else if (pst_strincmp("IPM.Appointment", item->ascii_type, 15) == 0) | 1872 else if (pst_strincmp("IPM.Appointment", item->ascii_type, 15) == 0) |
1865 item->type = PST_TYPE_APPOINTMENT; | 1873 item->type = PST_TYPE_APPOINTMENT; |
1874 else if (pst_strincmp("IPM.Task", item->ascii_type, 8) == 0) | |
1875 item->type = PST_TYPE_TASK; | |
1866 else | 1876 else |
1867 item->type = PST_TYPE_OTHER; | 1877 item->type = PST_TYPE_OTHER; |
1868 | 1878 |
1869 DEBUG_EMAIL(("%s\n", item->ascii_type)); | 1879 DEBUG_EMAIL(("%s\n", item->ascii_type)); |
1870 break; | 1880 break; |
2243 break; | 2253 break; |
2244 case 0x0E20: // PR_ATTACH_SIZE binary Attachment data in record | 2254 case 0x0E20: // PR_ATTACH_SIZE binary Attachment data in record |
2245 DEBUG_EMAIL(("Attachment Size - ")); | 2255 DEBUG_EMAIL(("Attachment Size - ")); |
2246 NULL_CHECK(attach); | 2256 NULL_CHECK(attach); |
2247 MOVE_NEXT(attach); | 2257 MOVE_NEXT(attach); |
2248 memcpy(&(attach->size), list->items[x]->data, sizeof(attach->size)); | 2258 t = (*(int32_t*)list->items[x]->data); |
2259 LE32_CPU(t); | |
2260 attach->size = (size_t)t; | |
2249 DEBUG_EMAIL(("%i\n", attach->size)); | 2261 DEBUG_EMAIL(("%i\n", attach->size)); |
2250 break; | 2262 break; |
2251 case 0x0FF9: // PR_RECORD_KEY Record Header 1 | 2263 case 0x0FF9: // PR_RECORD_KEY Record Header 1 |
2252 DEBUG_EMAIL(("Record Key 1 - ")); | 2264 DEBUG_EMAIL(("Record Key 1 - ")); |
2253 LIST_COPY(item->record_key, (char*)); | 2265 LIST_COPY(item->record_key, (char*)); |
3202 case 0x8208: // Location of an appointment | 3214 case 0x8208: // Location of an appointment |
3203 DEBUG_EMAIL(("Appointment Location - ")); | 3215 DEBUG_EMAIL(("Appointment Location - ")); |
3204 MALLOC_APPOINTMENT(item); | 3216 MALLOC_APPOINTMENT(item); |
3205 LIST_COPY(item->appointment->location, (char*)); | 3217 LIST_COPY(item->appointment->location, (char*)); |
3206 DEBUG_EMAIL(("%s\n", item->appointment->location)); | 3218 DEBUG_EMAIL(("%s\n", item->appointment->location)); |
3219 break; | |
3220 case 0x820d: // Appointment start | |
3221 DEBUG_EMAIL(("Appointment Date Start - ")); | |
3222 MALLOC_APPOINTMENT(item); | |
3223 LIST_COPY(item->appointment->start, (FILETIME*)); | |
3224 DEBUG_EMAIL(("%s\n", fileTimeToAscii(item->appointment->start))); | |
3225 break; | |
3226 case 0x820e: // Appointment end | |
3227 DEBUG_EMAIL(("Appointment Date End - ")); | |
3228 MALLOC_APPOINTMENT(item); | |
3229 LIST_COPY(item->appointment->end, (FILETIME*)); | |
3230 DEBUG_EMAIL(("%s\n", fileTimeToAscii(item->appointment->end))); | |
3207 break; | 3231 break; |
3208 case 0x8214: // Label for an appointment | 3232 case 0x8214: // Label for an appointment |
3209 DEBUG_EMAIL(("Label for appointment - ")); | 3233 DEBUG_EMAIL(("Label for appointment - ")); |
3210 MALLOC_APPOINTMENT(item); | 3234 MALLOC_APPOINTMENT(item); |
3211 memcpy(&(item->appointment->label), list->items[x]->data, sizeof(item->appointment->label)); | 3235 memcpy(&(item->appointment->label), list->items[x]->data, sizeof(item->appointment->label)); |
3244 } else { | 3268 } else { |
3245 DEBUG_EMAIL(("False\n")); | 3269 DEBUG_EMAIL(("False\n")); |
3246 item->appointment->all_day = 0; | 3270 item->appointment->all_day = 0; |
3247 } | 3271 } |
3248 break; | 3272 break; |
3273 case 0x8231: // Recurrence type | |
3274 // 1: Daily | |
3275 // 2: Weekly | |
3276 // 3: Monthly | |
3277 // 4: Yearly | |
3278 DEBUG_EMAIL(("Appointment reccurs - ")); | |
3279 MALLOC_APPOINTMENT(item); | |
3280 memcpy(&(item->appointment->recurrence_type), list->items[x]->data, sizeof(item->appointment->recurrence_type)); | |
3281 LE32_CPU(item->appointment->recurrence_type); | |
3282 switch (item->appointment->recurrence_type) { | |
3283 case PST_APP_RECUR_DAILY: | |
3284 DEBUG_EMAIL(("Daily\n")); break; | |
3285 case PST_APP_RECUR_WEEKLY: | |
3286 DEBUG_EMAIL(("Weekly\n")); break; | |
3287 case PST_APP_RECUR_MONTHLY: | |
3288 DEBUG_EMAIL(("Monthly\n")); break; | |
3289 case PST_APP_RECUR_YEARLY: | |
3290 DEBUG_EMAIL(("Yearly\n")); break; | |
3291 default: | |
3292 DEBUG_EMAIL(("Unknown Value: %d\n", item->appointment->recurrence_type)); break; | |
3293 } | |
3294 break; | |
3295 case 0x8232: // Recurrence description | |
3296 DEBUG_EMAIL(("Appointment recurrence description - ")); | |
3297 MALLOC_APPOINTMENT(item); | |
3298 LIST_COPY(item->appointment->recurrence, (char*)); | |
3299 DEBUG_EMAIL(("%s\n", item->appointment->recurrence)); | |
3300 break; | |
3249 case 0x8234: // TimeZone as String | 3301 case 0x8234: // TimeZone as String |
3250 DEBUG_EMAIL(("TimeZone of times - ")); | 3302 DEBUG_EMAIL(("TimeZone of times - ")); |
3251 MALLOC_APPOINTMENT(item); | 3303 MALLOC_APPOINTMENT(item); |
3252 LIST_COPY(item->appointment->timezonestring, (char*)); | 3304 LIST_COPY(item->appointment->timezonestring, (char*)); |
3253 DEBUG_EMAIL(("%s\n", item->appointment->timezonestring)); | 3305 DEBUG_EMAIL(("%s\n", item->appointment->timezonestring)); |
3254 break; | 3306 break; |
3255 case 0x8235: // Appointment start time | 3307 case 0x8235: // Recurrence start date |
3256 DEBUG_EMAIL(("Appointment Start Time - ")); | 3308 DEBUG_EMAIL(("Recurrence Start Date - ")); |
3257 MALLOC_APPOINTMENT(item); | 3309 MALLOC_APPOINTMENT(item); |
3258 LIST_COPY(item->appointment->start, (FILETIME*)); | 3310 LIST_COPY(item->appointment->recurrence_start, (FILETIME*)); |
3259 DEBUG_EMAIL(("%s\n", fileTimeToAscii((FILETIME*)item->appointment->start))); | 3311 DEBUG_EMAIL(("%s\n", fileTimeToAscii(item->appointment->recurrence_start))); |
3260 break; | 3312 break; |
3261 case 0x8236: // Appointment end time | 3313 case 0x8236: // Recurrence end date |
3262 DEBUG_EMAIL(("Appointment End Time - ")); | 3314 DEBUG_EMAIL(("Recurrence End Date - ")); |
3263 MALLOC_APPOINTMENT(item); | 3315 MALLOC_APPOINTMENT(item); |
3264 LIST_COPY(item->appointment->end, (FILETIME*)); | 3316 LIST_COPY(item->appointment->recurrence_end, (FILETIME*)); |
3265 DEBUG_EMAIL(("%s\n", fileTimeToAscii((FILETIME*)item->appointment->start))); | 3317 DEBUG_EMAIL(("%s\n", fileTimeToAscii(item->appointment->recurrence_end))); |
3266 break; | 3318 break; |
3267 case 0x8516: // Journal time start | 3319 case 0x8501: // Reminder minutes before appointment start |
3268 DEBUG_EMAIL(("Duplicate Time Start - ")); | 3320 DEBUG_EMAIL(("Alarm minutes - ")); |
3321 MALLOC_APPOINTMENT(item); | |
3322 memcpy(&(item->appointment->alarm_minutes), list->items[x]->data, sizeof(item->appointment->alarm_minutes)); | |
3323 LE32_CPU(item->appointment->alarm_minutes); | |
3324 DEBUG_EMAIL(("%i\n", item->appointment->alarm_minutes)); | |
3325 break; | |
3326 case 0x8503: // Reminder alarm | |
3327 DEBUG_EMAIL(("Reminder alarm - ")); | |
3328 MALLOC_APPOINTMENT(item); | |
3329 if (*(int16_t*)list->items[x]->data != 0) { | |
3330 DEBUG_EMAIL(("True\n")); | |
3331 item->appointment->alarm = 1; | |
3332 } else { | |
3333 DEBUG_EMAIL(("False\n")); | |
3334 item->appointment->alarm = 0; | |
3335 } | |
3336 break; | |
3337 case 0x8516: | |
3338 DEBUG_EMAIL(("Appointment Start Date 3 - ")); | |
3269 DEBUG_EMAIL(("%s\n", fileTimeToAscii((FILETIME*)list->items[x]->data))); | 3339 DEBUG_EMAIL(("%s\n", fileTimeToAscii((FILETIME*)list->items[x]->data))); |
3270 break; | 3340 break; |
3271 case 0x8517: // Journal time end | 3341 case 0x8517: |
3272 DEBUG_EMAIL(("Duplicate Time End - ")); | 3342 DEBUG_EMAIL(("Appointment End Date 3 - ")); |
3273 DEBUG_EMAIL(("%s\n", fileTimeToAscii((FILETIME*)list->items[x]->data))); | 3343 DEBUG_EMAIL(("%s\n", fileTimeToAscii((FILETIME*)list->items[x]->data))); |
3344 break; | |
3345 case 0x851f: // Play reminder sound filename | |
3346 DEBUG_EMAIL(("Appointment reminder sound filename - ")); | |
3347 MALLOC_APPOINTMENT(item); | |
3348 LIST_COPY(item->appointment->alarm_filename, (char*)); | |
3349 DEBUG_EMAIL(("%s\n", item->appointment->alarm_filename)); | |
3274 break; | 3350 break; |
3275 case 0x8530: // Followup | 3351 case 0x8530: // Followup |
3276 DEBUG_EMAIL(("Followup String - ")); | 3352 DEBUG_EMAIL(("Followup String - ")); |
3277 MALLOC_CONTACT(item); | 3353 MALLOC_CONTACT(item); |
3278 LIST_COPY(item->contact->followup, (char*)); | 3354 LIST_COPY(item->contact->followup, (char*)); |
3724 free(item->journal); | 3800 free(item->journal); |
3725 } | 3801 } |
3726 if (item->appointment) { | 3802 if (item->appointment) { |
3727 SAFE_FREE(item->appointment->location); | 3803 SAFE_FREE(item->appointment->location); |
3728 SAFE_FREE(item->appointment->reminder); | 3804 SAFE_FREE(item->appointment->reminder); |
3805 SAFE_FREE(item->appointment->alarm_filename); | |
3729 SAFE_FREE(item->appointment->start); | 3806 SAFE_FREE(item->appointment->start); |
3730 SAFE_FREE(item->appointment->end); | 3807 SAFE_FREE(item->appointment->end); |
3731 SAFE_FREE(item->appointment->timezonestring); | 3808 SAFE_FREE(item->appointment->timezonestring); |
3809 SAFE_FREE(item->appointment->recurrence); | |
3810 SAFE_FREE(item->appointment->recurrence_start); | |
3811 SAFE_FREE(item->appointment->recurrence_end); | |
3732 free(item->appointment); | 3812 free(item->appointment); |
3733 } | 3813 } |
3734 SAFE_FREE(item->ascii_type); | 3814 SAFE_FREE(item->ascii_type); |
3735 SAFE_FREE(item->comment); | 3815 SAFE_FREE(item->comment); |
3736 SAFE_FREE(item->create_date); | 3816 SAFE_FREE(item->create_date); |
3769 if (size) { | 3849 if (size) { |
3770 p->to = p->from + size; | 3850 p->to = p->from + size; |
3771 p->needfree = 1; | 3851 p->needfree = 1; |
3772 } | 3852 } |
3773 else { | 3853 else { |
3854 if (p->from) { | |
3855 DEBUG_WARN(("size zero but non-null pointer\n")); | |
3856 free(p->from); | |
3857 } | |
3774 p->from = p->to = NULL; | 3858 p->from = p->to = NULL; |
3775 } | 3859 } |
3776 } | 3860 } |
3777 else { | 3861 else { |
3778 // internal index reference | 3862 // internal index reference |
4121 DEBUG_RET(); | 4205 DEBUG_RET(); |
4122 return 0; | 4206 return 0; |
4123 } | 4207 } |
4124 | 4208 |
4125 | 4209 |
4210 /** | |
4211 * Get an ID block from file using _pst_ff_getIDblock and decrypt if necessary | |
4212 * @param pf PST file structure | |
4213 * @param id ID of block to retrieve | |
4214 * @param b Reference to pointer that will be set to new block. Any memory | |
4215 pointed to by buffer will be free()d beforehand | |
4216 * @return Size of block pointed to by *b | |
4217 */ | |
4126 size_t pst_ff_getIDblock_dec(pst_file *pf, uint64_t id, unsigned char **b) { | 4218 size_t pst_ff_getIDblock_dec(pst_file *pf, uint64_t id, unsigned char **b) { |
4127 size_t r; | 4219 size_t r; |
4128 int noenc = (int)(id & 2); // disable encryption | 4220 int noenc = (int)(id & 2); // disable encryption |
4129 DEBUG_ENT("pst_ff_getIDblock_dec"); | 4221 DEBUG_ENT("pst_ff_getIDblock_dec"); |
4130 DEBUG_INDEX(("for id %#x\n", id)); | 4222 DEBUG_INDEX(("for id %#x\n", id)); |
4136 DEBUG_RET(); | 4228 DEBUG_RET(); |
4137 return r; | 4229 return r; |
4138 } | 4230 } |
4139 | 4231 |
4140 | 4232 |
4233 /** | |
4234 * Read a block of data from file into memory | |
4235 * @param pf PST file | |
4236 * @param id identifier of block to read | |
4237 * @param b reference to pointer to buffer. If this pointer | |
4238 is non-NULL, it will first be free()d | |
4239 * @return size of block read into memory | |
4240 */ | |
4141 size_t pst_ff_getIDblock(pst_file *pf, uint64_t id, unsigned char** b) { | 4241 size_t pst_ff_getIDblock(pst_file *pf, uint64_t id, unsigned char** b) { |
4142 pst_index_ll *rec; | 4242 pst_index_ll *rec; |
4143 size_t rsize = 0; | 4243 size_t rsize = 0; |
4144 DEBUG_ENT("pst_ff_getIDblock"); | 4244 DEBUG_ENT("pst_ff_getIDblock"); |
4145 if ((rec = pst_getID(pf, id)) == NULL) { | 4245 if ((rec = pst_getID(pf, id)) == NULL) { |
4171 } | 4271 } |
4172 | 4272 |
4173 | 4273 |
4174 #define PST_PTR_BLOCK_SIZE 0x120 | 4274 #define PST_PTR_BLOCK_SIZE 0x120 |
4175 size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_index2_ll *id2_head, unsigned char** buf) { | 4275 size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_index2_ll *id2_head, unsigned char** buf) { |
4276 size_t ret; | |
4176 pst_index_ll* ptr; | 4277 pst_index_ll* ptr; |
4177 pst_holder h = {buf, NULL, 0, "", 0}; | 4278 pst_holder h = {buf, NULL, 0, "", 0}; |
4178 DEBUG_ENT("pst_ff_getID2block"); | 4279 DEBUG_ENT("pst_ff_getID2block"); |
4179 ptr = pst_getID2(id2_head, id2); | 4280 ptr = pst_getID2(id2_head, id2); |
4180 | 4281 |
4181 if (!ptr) { | 4282 if (!ptr) { |
4182 DEBUG_INDEX(("Cannot find id2 value %#x\n", id2)); | 4283 DEBUG_INDEX(("Cannot find id2 value %#x\n", id2)); |
4183 DEBUG_RET(); | 4284 DEBUG_RET(); |
4184 return 0; | 4285 return 0; |
4185 } | 4286 } |
4287 ret = pst_ff_getID2data(pf, ptr, &h); | |
4186 DEBUG_RET(); | 4288 DEBUG_RET(); |
4187 return pst_ff_getID2data(pf, ptr, &h); | 4289 return ret; |
4188 } | 4290 } |
4189 | 4291 |
4190 | 4292 |
4191 size_t pst_ff_getID2data(pst_file *pf, pst_index_ll *ptr, pst_holder *h) { | 4293 size_t pst_ff_getID2data(pst_file *pf, pst_index_ll *ptr, pst_holder *h) { |
4192 size_t ret; | 4294 size_t ret; |
4226 size_t z, a; | 4328 size_t z, a; |
4227 uint16_t count, y; | 4329 uint16_t count, y; |
4228 uint32_t x, b; | 4330 uint32_t x, b; |
4229 unsigned char * buf3 = NULL, *buf2 = NULL, *t; | 4331 unsigned char * buf3 = NULL, *buf2 = NULL, *t; |
4230 unsigned char fdepth; | 4332 unsigned char fdepth; |
4333 unsigned char *b_ptr; | |
4334 pst_block_hdr block_hdr; | |
4335 pst_table3_rec table3_rec; //for type 3 (0x0101) blocks | |
4231 | 4336 |
4232 DEBUG_ENT("pst_ff_compile_ID"); | 4337 DEBUG_ENT("pst_ff_compile_ID"); |
4233 a = pst_ff_getIDblock(pf, id, &buf3); | 4338 a = pst_ff_getIDblock(pf, id, &buf3); |
4234 if (!a) { | 4339 if (!a) { |
4235 if (buf3) free(buf3); | 4340 if (buf3) free(buf3); |
4236 return 0; | 4341 return 0; |
4237 } | 4342 } |
4238 if ((buf3[0] != 0x1)) { // if bit 8 is set) { | 4343 DEBUG_HEXDUMPC(buf3, a, 0x10); |
4239 // if ((buf3)[0] != 0x1 && (buf3)[1] > 4) { | 4344 memcpy(&block_hdr, buf3, sizeof(block_hdr)); |
4240 DEBUG_WARN(("WARNING: buffer doesn't start with 0x1, but I expected it to or doesn't have it's two-bit set!\n")); | 4345 LE16_CPU(block_hdr.index_offset); |
4241 DEBUG_WARN(("Treating as normal buffer\n")); | 4346 LE16_CPU(block_hdr.type); |
4347 LE32_CPU(block_hdr.offset); | |
4348 DEBUG_EMAIL(("block header (index_offset=%#hx, type=%#hx, offset=%#x)\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset)); | |
4349 | |
4350 if (block_hdr.index_offset != (uint16_t)0x0101) { //type 3 | |
4351 DEBUG_WARN(("WARNING: not a type 0x0101 buffer, Treating as normal buffer\n")); | |
4242 if (pf->encryption) (void)pst_decrypt(buf3, a, pf->encryption); | 4352 if (pf->encryption) (void)pst_decrypt(buf3, a, pf->encryption); |
4243 if (h->buf) | 4353 if (h->buf) |
4244 *(h->buf) = buf3; | 4354 *(h->buf) = buf3; |
4245 else if (h->base64 == 1 && h->fp) { | 4355 else if (h->base64 == 1 && h->fp) { |
4246 t = base64_encode(buf3, a); | 4356 t = base64_encode(buf3, a); |
4256 // h-> does not specify any output | 4366 // h-> does not specify any output |
4257 } | 4367 } |
4258 DEBUG_RET(); | 4368 DEBUG_RET(); |
4259 return a; | 4369 return a; |
4260 } | 4370 } |
4261 memcpy (&count, &(buf3[2]), sizeof(int16_t)); | 4371 count = block_hdr.type; |
4262 LE16_CPU(count); | 4372 b_ptr = buf3 + 8; |
4263 memcpy (&fdepth, &(buf3[1]), sizeof(char)); | 4373 for (y=0; y<count; y++) { |
4264 DEBUG_READ(("Seen index to blocks. Depth is %i\n", fdepth)); | 4374 b_ptr += pst_decode_type3(pf, &table3_rec, b_ptr); |
4265 DEBUG_READ(("There are %i ids here\n", count)); | 4375 z = pst_ff_getIDblock_dec(pf, table3_rec.id, &buf2); |
4266 | 4376 if (!z) { |
4267 y = 0; | 4377 DEBUG_WARN(("call to getIDblock returned zero %i\n", z)); |
4268 while (y < count) { | 4378 if (buf2) free(buf2); |
4269 memcpy(&x, &buf3[0x08+(y*4)], sizeof(int32_t)); | 4379 free(buf3); |
4270 LE32_CPU(x); | 4380 return z; |
4271 if (fdepth == 0x1) { | 4381 } |
4272 if ((z = pst_ff_getIDblock(pf, x, &buf2)) == 0) { | 4382 if (h->buf) { |
4273 DEBUG_WARN(("call to getIDblock returned zero %i\n", z)); | 4383 *(h->buf) = realloc(*(h->buf), size+z+1); |
4274 if (buf2) free(buf2); | 4384 DEBUG_READ(("appending read data of size %i onto main buffer from pos %i\n", z, size)); |
4275 free(buf3); | 4385 memcpy(&((*(h->buf))[size]), buf2, z); |
4276 return z; | 4386 } else if ((h->base64 == 1) && h->fp) { |
4387 // include any byte left over from the last one encoding | |
4388 buf2 = (char*)realloc(buf2, z+h->base64_extra); | |
4389 memmove(buf2+h->base64_extra, buf2, z); | |
4390 memcpy(buf2, h->base64_extra_chars, h->base64_extra); | |
4391 z += h->base64_extra; | |
4392 | |
4393 b = z % 3; // find out how many bytes will be left over after the encoding. | |
4394 // and save them | |
4395 memcpy(h->base64_extra_chars, &(buf2[z-b]), b); | |
4396 h->base64_extra = b; | |
4397 t = base64_encode(buf2, z-b); | |
4398 if (t) { | |
4399 DEBUG_READ(("writing %i bytes to file as base64 [%i]. Currently %i\n", z, strlen(t), size)); | |
4400 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); | |
4401 free(t); // caught by valgrind | |
4277 } | 4402 } |
4278 if (pf->encryption) (void)pst_decrypt(buf2, z, pf->encryption); | 4403 } else if (h->fp) { |
4279 if (h->buf) { | 4404 DEBUG_READ(("writing %i bytes to file. Currently %i\n", z, size)); |
4280 *(h->buf) = realloc(*(h->buf), size+z+1); | 4405 (void)pst_fwrite(buf2, (size_t)1, z, h->fp); |
4281 DEBUG_READ(("appending read data of size %i onto main buffer from pos %i\n", z, size)); | 4406 } else { |
4282 memcpy(&((*(h->buf))[size]), buf2, z); | 4407 // h-> does not specify any output |
4283 } else if ((h->base64 == 1) && h->fp) { | 4408 } |
4284 // include any byte left over from the last one encoding | 4409 size += z; |
4285 buf2 = (char*)realloc(buf2, z+h->base64_extra); | |
4286 memmove(buf2+h->base64_extra, buf2, z); | |
4287 memcpy(buf2, h->base64_extra_chars, h->base64_extra); | |
4288 z += h->base64_extra; | |
4289 | |
4290 b = z % 3; // find out how many bytes will be left over after the encoding. | |
4291 // and save them | |
4292 memcpy(h->base64_extra_chars, &(buf2[z-b]), b); | |
4293 h->base64_extra = b; | |
4294 t = base64_encode(buf2, z-b); | |
4295 if (t) { | |
4296 DEBUG_READ(("writing %i bytes to file as base64 [%i]. Currently %i\n", z, strlen(t), size)); | |
4297 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); | |
4298 free(t); // caught by valgrind | |
4299 } | |
4300 } else if (h->fp) { | |
4301 DEBUG_READ(("writing %i bytes to file. Currently %i\n", z, size)); | |
4302 (void)pst_fwrite(buf2, (size_t)1, z, h->fp); | |
4303 } else { | |
4304 // h-> does not specify any output | |
4305 } | |
4306 size += z; | |
4307 y++; | |
4308 } | |
4309 else { | |
4310 if ((z = pst_ff_compile_ID(pf, x, h, size)) == 0) { | |
4311 DEBUG_WARN(("recursive called returned zero %i\n", z)); | |
4312 free(buf3); | |
4313 DEBUG_RET(); | |
4314 return z; | |
4315 } | |
4316 size = z; | |
4317 y++; | |
4318 } | |
4319 } | 4410 } |
4320 free(buf3); | 4411 free(buf3); |
4321 if (buf2) free(buf2); | 4412 if (buf2) free(buf2); |
4322 DEBUG_RET(); | 4413 DEBUG_RET(); |
4323 return size; | 4414 return size; |