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;