comparison src/libpst.c @ 49:17654fbdf76b

more fixes for 64 bit format
author carl
date Sat, 19 Jan 2008 10:47:16 -0800
parents f66078abed38
children fb3818370dd6
comparison
equal deleted inserted replaced
48:f66078abed38 49:17654fbdf76b
28 # include <unistd.h> 28 # include <unistd.h>
29 #endif //ifdef _MSC_VER 29 #endif //ifdef _MSC_VER
30 30
31 #include "libpst.h" 31 #include "libpst.h"
32 #include "timeconv.h" 32 #include "timeconv.h"
33 //efine INDEX_DEPTH 0x4C 33
34 //efine SECOND_DEPTH 0x5C
35 #define INDEX_TYPE32 0x0E 34 #define INDEX_TYPE32 0x0E
36 #define INDEX_TYPE64 0x17 35 #define INDEX_TYPE64 0x17
37 #define INDEX_TYPE_OFFSET (off_t)0x0A 36 #define INDEX_TYPE_OFFSET (off_t)0x0A
38 37
39 #define FILE_SIZE_POINTER32 (off_t)0xA8 38 #define FILE_SIZE_POINTER32 (off_t)0xA8
252 251
253 252
254 size_t pst_attach_to_mem(pst_file *pf, pst_item_attach *attach, unsigned char **b){ 253 size_t pst_attach_to_mem(pst_file *pf, pst_item_attach *attach, unsigned char **b){
255 size_t size=0; 254 size_t size=0;
256 pst_index_ll *ptr; 255 pst_index_ll *ptr;
257 struct holder h = {b, NULL, 0, "", 0}; 256 pst_holder h = {b, NULL, 0, "", 0};
258 DEBUG_ENT("pst_attach_to_mem"); 257 DEBUG_ENT("pst_attach_to_mem");
259 if (attach->id_val != (uint64_t)-1) { 258 if (attach->id_val != (uint64_t)-1) {
260 ptr = pst_getID(pf, attach->id_val); 259 ptr = pst_getID(pf, attach->id_val);
261 if (ptr) { 260 if (ptr) {
262 size = pst_ff_getID2data(pf, ptr, &h); 261 size = pst_ff_getID2data(pf, ptr, &h);
273 } 272 }
274 273
275 274
276 size_t pst_attach_to_file(pst_file *pf, pst_item_attach *attach, FILE* fp) { 275 size_t pst_attach_to_file(pst_file *pf, pst_item_attach *attach, FILE* fp) {
277 pst_index_ll *ptr; 276 pst_index_ll *ptr;
278 struct holder h = {NULL, fp, 0, "", 0}; 277 pst_holder h = {NULL, fp, 0, "", 0};
279 size_t size; 278 size_t size;
280 DEBUG_ENT("pst_attach_to_file"); 279 DEBUG_ENT("pst_attach_to_file");
281 if (attach->id_val != (uint64_t)-1) { 280 if (attach->id_val != (uint64_t)-1) {
282 ptr = pst_getID(pf, attach->id_val); 281 ptr = pst_getID(pf, attach->id_val);
283 if (ptr) { 282 if (ptr) {
297 } 296 }
298 297
299 298
300 size_t pst_attach_to_file_base64(pst_file *pf, pst_item_attach *attach, FILE* fp) { 299 size_t pst_attach_to_file_base64(pst_file *pf, pst_item_attach *attach, FILE* fp) {
301 pst_index_ll *ptr; 300 pst_index_ll *ptr;
302 struct holder h = {NULL, fp, 1, "", 0}; 301 pst_holder h = {NULL, fp, 1, "", 0};
303 size_t size; 302 size_t size;
304 char *c; 303 char *c;
305 DEBUG_ENT("pst_attach_to_file_base64"); 304 DEBUG_ENT("pst_attach_to_file_base64");
306 if (attach->id_val != (uint64_t)-1) { 305 if (attach->id_val != (uint64_t)-1) {
307 ptr = pst_getID(pf, attach->id_val); 306 ptr = pst_getID(pf, attach->id_val);
1251 DEBUG_RET(); 1250 DEBUG_RET();
1252 return item; 1251 return item;
1253 } 1252 }
1254 1253
1255 1254
1256 static void freeall(unsigned char *buf, pst_block_offset_pointer *p1, 1255 static void freeall(pst_subblocks *subs, pst_block_offset_pointer *p1,
1257 pst_block_offset_pointer *p2, 1256 pst_block_offset_pointer *p2,
1258 pst_block_offset_pointer *p3, 1257 pst_block_offset_pointer *p3,
1259 pst_block_offset_pointer *p4, 1258 pst_block_offset_pointer *p4,
1260 pst_block_offset_pointer *p5, 1259 pst_block_offset_pointer *p5,
1261 pst_block_offset_pointer *p6, 1260 pst_block_offset_pointer *p6,
1262 pst_block_offset_pointer *p7); 1261 pst_block_offset_pointer *p7);
1263 static void freeall(unsigned char *buf, pst_block_offset_pointer *p1, 1262 static void freeall(pst_subblocks *subs, pst_block_offset_pointer *p1,
1264 pst_block_offset_pointer *p2, 1263 pst_block_offset_pointer *p2,
1265 pst_block_offset_pointer *p3, 1264 pst_block_offset_pointer *p3,
1266 pst_block_offset_pointer *p4, 1265 pst_block_offset_pointer *p4,
1267 pst_block_offset_pointer *p5, 1266 pst_block_offset_pointer *p5,
1268 pst_block_offset_pointer *p6, 1267 pst_block_offset_pointer *p6,
1269 pst_block_offset_pointer *p7) { 1268 pst_block_offset_pointer *p7) {
1270 if (buf) free(buf); 1269 size_t i;
1270 for (i=0; i<subs->subblock_count; i++) {
1271 if (subs->subs[i].buf) free(subs->subs[i].buf);
1272 }
1273 free(subs->subs);
1271 if (p1->needfree) free(p1->from); 1274 if (p1->needfree) free(p1->from);
1272 if (p2->needfree) free(p2->from); 1275 if (p2->needfree) free(p2->from);
1273 if (p3->needfree) free(p3->from); 1276 if (p3->needfree) free(p3->from);
1274 if (p4->needfree) free(p4->from); 1277 if (p4->needfree) free(p4->from);
1275 if (p5->needfree) free(p5->from); 1278 if (p5->needfree) free(p5->from);
1278 } 1281 }
1279 1282
1280 1283
1281 pst_num_array * pst_parse_block(pst_file *pf, uint64_t block_id, pst_index2_ll *i2_head, pst_num_array *na_head) { 1284 pst_num_array * pst_parse_block(pst_file *pf, uint64_t block_id, pst_index2_ll *i2_head, pst_num_array *na_head) {
1282 unsigned char *buf = NULL; 1285 unsigned char *buf = NULL;
1286 size_t read_size = 0;
1287 pst_subblocks subblocks;
1283 pst_num_array *na_ptr = NULL; 1288 pst_num_array *na_ptr = NULL;
1284 pst_block_offset_pointer block_offset1; 1289 pst_block_offset_pointer block_offset1;
1285 pst_block_offset_pointer block_offset2; 1290 pst_block_offset_pointer block_offset2;
1286 pst_block_offset_pointer block_offset3; 1291 pst_block_offset_pointer block_offset3;
1287 pst_block_offset_pointer block_offset4; 1292 pst_block_offset_pointer block_offset4;
1293 int count_rec; 1298 int count_rec;
1294 int32_t num_list; 1299 int32_t num_list;
1295 int32_t cur_list; 1300 int32_t cur_list;
1296 int block_type; 1301 int block_type;
1297 uint32_t rec_size = 0; 1302 uint32_t rec_size = 0;
1298 uint32_t ind_ptr;
1299 unsigned char* list_start; 1303 unsigned char* list_start;
1300 unsigned char* fr_ptr; 1304 unsigned char* fr_ptr;
1301 unsigned char* to_ptr; 1305 unsigned char* to_ptr;
1302 unsigned char* ind2_end = NULL; 1306 unsigned char* ind2_end = NULL;
1303 unsigned char* ind2_ptr = NULL; 1307 unsigned char* ind2_ptr = NULL;
1304 size_t read_size=0;
1305 pst_x_attrib_ll *mapptr; 1308 pst_x_attrib_ll *mapptr;
1306 1309
1307 struct { 1310 struct {
1308 uint16_t index_offset; 1311 uint16_t index_offset;
1309 uint16_t type; 1312 uint16_t type;
1364 LE16_CPU(block_hdr.index_offset); 1367 LE16_CPU(block_hdr.index_offset);
1365 LE16_CPU(block_hdr.type); 1368 LE16_CPU(block_hdr.type);
1366 LE32_CPU(block_hdr.offset); 1369 LE32_CPU(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)); 1370 DEBUG_EMAIL(("block header (index_offset=%#hx, type=%#hx, offset=%#hx)\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset));
1368 1371
1369 ind_ptr = block_hdr.index_offset; 1372 if (block_hdr.index_offset == (uint16_t)0x0101) { //type 3
1373 subblocks.subblock_count = block_hdr.type;
1374 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++) {
1378 b_ptr += pst_decode_type3(pf, &table3_rec, b_ptr);
1379 subblocks.subs[i].buf = NULL;
1380 subblocks.subs[i].read_size = pst_ff_getIDblock_dec(pf, table3_rec.id, &subblocks.subs[i].buf);
1381 if (subblocks.subs[i].buf) {
1382 memcpy(&block_hdr, subblocks.subs[i].buf, sizeof(block_hdr));
1383 LE16_CPU(block_hdr.index_offset);
1384 subblocks.subs[i].i_offset = block_hdr.index_offset;
1385 }
1386 else {
1387 subblocks.subs[i].read_size = 0;
1388 subblocks.subs[i].i_offset = 0;
1389 }
1390 }
1391 free(buf);
1392 memcpy(&block_hdr, subblocks.subs[0].buf, sizeof(block_hdr));
1393 LE16_CPU(block_hdr.index_offset);
1394 LE16_CPU(block_hdr.type);
1395 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));
1397 }
1398 else {
1399 // setup the subblock descriptors, but we only have one block
1400 subblocks.subblock_count = 1;
1401 subblocks.subs = malloc(sizeof(pst_subblock));
1402 subblocks.subs[0].buf = buf;
1403 subblocks.subs[0].read_size = read_size;
1404 subblocks.subs[0].i_offset = block_hdr.index_offset;
1405 }
1370 1406
1371 if (block_hdr.type == (uint16_t)0xBCEC) { //type 1 1407 if (block_hdr.type == (uint16_t)0xBCEC) { //type 1
1372 block_type = 1; 1408 block_type = 1;
1373 1409
1374 if (pst_getBlockOffsetPointer(pf, i2_head, buf, read_size, ind_ptr, block_hdr.offset, &block_offset1)) { 1410 if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, block_hdr.offset, &block_offset1)) {
1375 DEBUG_WARN(("internal error (bc.b5 offset %#x) in reading block id %#x\n", block_hdr.offset, block_id)); 1411 DEBUG_WARN(("internal error (bc.b5 offset %#x) in reading block id %#x\n", block_hdr.offset, block_id));
1376 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1412 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1377 DEBUG_RET(); 1413 DEBUG_RET();
1378 return NULL; 1414 return NULL;
1379 } 1415 }
1380 memcpy(&table_rec, block_offset1.from, sizeof(table_rec)); 1416 memcpy(&table_rec, block_offset1.from, sizeof(table_rec));
1381 LE16_CPU(table_rec.type); 1417 LE16_CPU(table_rec.type);
1384 DEBUG_EMAIL(("table_rec (type=%#hx, ref_type=%#hx, value=%#x)\n", table_rec.type, table_rec.ref_type, table_rec.value)); 1420 DEBUG_EMAIL(("table_rec (type=%#hx, ref_type=%#hx, value=%#x)\n", table_rec.type, table_rec.ref_type, table_rec.value));
1385 1421
1386 if (table_rec.type != (uint16_t)0x02B5) { 1422 if (table_rec.type != (uint16_t)0x02B5) {
1387 WARN(("Unknown second block constant - %#hx for id %#llx\n", table_rec.type, block_id)); 1423 WARN(("Unknown second block constant - %#hx for id %#llx\n", table_rec.type, block_id));
1388 DEBUG_HEXDUMPC(buf, sizeof(table_rec), 0x10); 1424 DEBUG_HEXDUMPC(buf, sizeof(table_rec), 0x10);
1389 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1425 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1390 DEBUG_RET(); 1426 DEBUG_RET();
1391 return NULL; 1427 return NULL;
1392 } 1428 }
1393 1429
1394 if (pst_getBlockOffsetPointer(pf, i2_head, buf, read_size, ind_ptr, table_rec.value, &block_offset2)) { 1430 if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, table_rec.value, &block_offset2)) {
1395 DEBUG_WARN(("internal error (bc.b5.desc offset) in reading block id %#x\n", table_rec.value, block_id)); 1431 DEBUG_WARN(("internal error (bc.b5.desc offset) in reading block id %#x\n", table_rec.value, block_id));
1396 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1432 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1397 DEBUG_RET(); 1433 DEBUG_RET();
1398 return NULL; 1434 return NULL;
1399 } 1435 }
1400 list_start = block_offset2.from; 1436 list_start = block_offset2.from;
1401 to_ptr = block_offset2.to; 1437 to_ptr = block_offset2.to;
1403 num_recs = 1; // only going to be one object in these blocks 1439 num_recs = 1; // only going to be one object in these blocks
1404 } 1440 }
1405 else if (block_hdr.type == (uint16_t)0x7CEC) { //type 2 1441 else if (block_hdr.type == (uint16_t)0x7CEC) { //type 2
1406 block_type = 2; 1442 block_type = 2;
1407 1443
1408 if (pst_getBlockOffsetPointer(pf, i2_head, buf, read_size, ind_ptr, block_hdr.offset, &block_offset3)) { 1444 if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, block_hdr.offset, &block_offset3)) {
1409 DEBUG_WARN(("internal error (7c.7c offset %#x) in reading block id %#x\n", block_hdr.offset, block_id)); 1445 DEBUG_WARN(("internal error (7c.7c offset %#x) in reading block id %#x\n", block_hdr.offset, block_id));
1410 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1446 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1411 DEBUG_RET(); 1447 DEBUG_RET();
1412 return NULL; 1448 return NULL;
1413 } 1449 }
1414 fr_ptr = block_offset3.from; //now got pointer to "7C block" 1450 fr_ptr = block_offset3.from; //now got pointer to "7C block"
1415 memset(&seven_c_blk, 0, sizeof(seven_c_blk)); 1451 memset(&seven_c_blk, 0, sizeof(seven_c_blk));
1425 1461
1426 list_start = fr_ptr + sizeof(seven_c_blk); // the list of item numbers start after this record 1462 list_start = fr_ptr + sizeof(seven_c_blk); // the list of item numbers start after this record
1427 1463
1428 if (seven_c_blk.seven_c != 0x7C) { // this would mean it isn't a 7C block! 1464 if (seven_c_blk.seven_c != 0x7C) { // this would mean it isn't a 7C block!
1429 WARN(("Error. There isn't a 7C where I want to see 7C!\n")); 1465 WARN(("Error. There isn't a 7C where I want to see 7C!\n"));
1430 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1466 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1431 DEBUG_RET(); 1467 DEBUG_RET();
1432 return NULL; 1468 return NULL;
1433 } 1469 }
1434 1470
1435 rec_size = seven_c_blk.rec_size; 1471 rec_size = seven_c_blk.rec_size;
1436 num_list = (int32_t)(unsigned)seven_c_blk.item_count; 1472 num_list = (int32_t)(unsigned)seven_c_blk.item_count;
1437 1473
1438 if (pst_getBlockOffsetPointer(pf, i2_head, buf, read_size, ind_ptr, seven_c_blk.b_five_offset, &block_offset4)) { 1474 if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, seven_c_blk.b_five_offset, &block_offset4)) {
1439 DEBUG_WARN(("internal error (7c.b5 offset %#x) in reading block id %#x\n", seven_c_blk.b_five_offset, block_id)); 1475 DEBUG_WARN(("internal error (7c.b5 offset %#x) in reading block id %#x\n", seven_c_blk.b_five_offset, block_id));
1440 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1476 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1441 DEBUG_RET(); 1477 DEBUG_RET();
1442 return NULL; 1478 return NULL;
1443 } 1479 }
1444 memcpy(&table_rec, block_offset4.from, sizeof(table_rec)); 1480 memcpy(&table_rec, block_offset4.from, sizeof(table_rec));
1445 LE16_CPU(table_rec.type); 1481 LE16_CPU(table_rec.type);
1446 LE16_CPU(table_rec.ref_type); 1482 LE16_CPU(table_rec.ref_type);
1447 LE32_CPU(table_rec.value); 1483 LE32_CPU(table_rec.value);
1448 1484
1449 if (table_rec.type != (uint16_t)0x04B5) { // different constant than a type 1 record 1485 if (table_rec.type != (uint16_t)0x04B5) { // different constant than a type 1 record
1450 WARN(("Unknown second block constant - %#hx for id %#llx\n", table_rec.type, block_id)); 1486 WARN(("Unknown second block constant - %#hx for id %#llx\n", table_rec.type, block_id));
1451 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1487 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1452 DEBUG_RET(); 1488 DEBUG_RET();
1453 return NULL; 1489 return NULL;
1454 } 1490 }
1455 1491
1456 if (pst_getBlockOffsetPointer(pf, i2_head, buf, read_size, ind_ptr, table_rec.value, &block_offset5)) { 1492 if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, table_rec.value, &block_offset5)) {
1457 DEBUG_WARN(("internal error (7c.5b.desc offset %#x) in reading block id %#llx\n", table_rec.value, block_id)); 1493 DEBUG_WARN(("internal error (7c.5b.desc offset %#x) in reading block id %#llx\n", table_rec.value, block_id));
1458 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1494 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1459 DEBUG_RET(); 1495 DEBUG_RET();
1460 return NULL; 1496 return NULL;
1461 } 1497 }
1462 num_recs = (block_offset5.to - block_offset5.from) / 6; // this will give the number of records in this block 1498 num_recs = (block_offset5.to - block_offset5.from) / 6; // this will give the number of records in this block
1463 1499
1464 if (pst_getBlockOffsetPointer(pf, i2_head, buf, read_size, ind_ptr, seven_c_blk.ind2_offset, &block_offset6)) { 1500 if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, seven_c_blk.ind2_offset, &block_offset6)) {
1465 DEBUG_WARN(("internal error (7c.ind2 offset %#x) in reading block id %#x\n", seven_c_blk.ind2_offset, block_id)); 1501 DEBUG_WARN(("internal error (7c.ind2 offset %#x) in reading block id %#x\n", seven_c_blk.ind2_offset, block_id));
1466 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1502 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1467 DEBUG_RET(); 1503 DEBUG_RET();
1468 return NULL; 1504 return NULL;
1469 } 1505 }
1470 ind2_ptr = block_offset6.from; 1506 ind2_ptr = block_offset6.from;
1471 ind2_end = block_offset6.to; 1507 ind2_end = block_offset6.to;
1472 } 1508 }
1473 else if (block_hdr.index_offset == (uint16_t)0x0101) { //type 3 1509 else {
1474 unsigned char *buf2 = NULL;
1475 uint16_t n = block_hdr.type; // count
1476 uint16_t i;
1477 block_type = 3;
1478 char *b_ptr = buf + 8;
1479 for (i=0; i<n; i++) {
1480 b_ptr += pst_decode_type3(pf, &table3_rec, b_ptr);
1481 //(void)pst_ff_getIDblock_dec(pf, table3_rec.id, &buf2);
1482 //if (buf2) free(buf2);
1483 //buf2 = NULL;
1484 na_head = pst_parse_block(pf, table3_rec.id, i2_head, na_head); // !! this is still not correct
1485 }
1486 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1487 DEBUG_RET();
1488 return na_head;
1489 } else {
1490 WARN(("ERROR: Unknown block constant - %#hx for id %#llx\n", block_hdr.type, block_id)); 1510 WARN(("ERROR: Unknown block constant - %#hx for id %#llx\n", block_hdr.type, block_id));
1491 DEBUG_HEXDUMPC(buf, read_size,0x10); 1511 DEBUG_HEXDUMPC(buf, read_size,0x10);
1492 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1512 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1493 DEBUG_RET(); 1513 DEBUG_RET();
1494 return NULL; 1514 return NULL;
1495 } 1515 }
1496 1516
1497 DEBUG_EMAIL(("Mallocing number of records %i\n", num_recs)); 1517 DEBUG_EMAIL(("Mallocing number of records %i\n", num_recs));
1498 for (count_rec=0; count_rec<num_recs; count_rec++) { 1518 for (count_rec=0; count_rec<num_recs; count_rec++) {
1499 na_ptr = (pst_num_array*) xmalloc(sizeof(pst_num_array)); 1519 na_ptr = (pst_num_array*) xmalloc(sizeof(pst_num_array));
1500 memset(na_ptr, 0, sizeof(pst_num_array)); 1520 memset(na_ptr, 0, sizeof(pst_num_array));
1501 na_ptr->next = na_head; 1521 na_ptr->next = na_head;
1502 na_head = na_ptr; 1522 na_head = na_ptr;
1503 // allocate an array of count num_recs to contain sizeof(struct pst_num_item) 1523 // allocate an array of count num_recs to contain sizeof(pst_num_item)
1504 na_ptr->items = (struct pst_num_item**) xmalloc(sizeof(struct pst_num_item)*num_list); 1524 na_ptr->items = (pst_num_item**) xmalloc(sizeof(pst_num_item)*num_list);
1505 na_ptr->count_item = num_list; 1525 na_ptr->count_item = num_list;
1506 na_ptr->orig_count = num_list; 1526 na_ptr->orig_count = num_list;
1507 na_ptr->count_array = (int32_t)num_recs; // each record will have a record of the total number of records 1527 na_ptr->count_array = (int32_t)num_recs; // each record will have a record of the total number of records
1508 for (x=0; x<num_list; x++) na_ptr->items[x] = NULL; 1528 for (x=0; x<num_list; x++) na_ptr->items[x] = NULL;
1509 x = 0; 1529 x = 0;
1548 read_size, ind2_end-ind2_ptr+table2_rec.ind2_off, table2_rec.size)); 1568 read_size, ind2_end-ind2_ptr+table2_rec.ind2_off, table2_rec.size));
1549 } 1569 }
1550 fr_ptr += sizeof(table2_rec); 1570 fr_ptr += sizeof(table2_rec);
1551 } else { 1571 } else {
1552 WARN(("Missing code for block_type %i\n", block_type)); 1572 WARN(("Missing code for block_type %i\n", block_type));
1553 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1573 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1554 if (na_head) pst_free_list(na_head); 1574 if (na_head) pst_free_list(na_head);
1555 DEBUG_RET(); 1575 DEBUG_RET();
1556 return NULL; 1576 return NULL;
1557 } 1577 }
1558 DEBUG_EMAIL(("reading block %i (type=%#x, ref_type=%#x, value=%#x)\n", 1578 DEBUG_EMAIL(("reading block %i (type=%#x, ref_type=%#x, value=%#x)\n",
1559 x, table_rec.type, table_rec.ref_type, table_rec.value)); 1579 x, table_rec.type, table_rec.ref_type, table_rec.value));
1560 1580
1561 if (!na_ptr->items[x]) { 1581 if (!na_ptr->items[x]) {
1562 na_ptr->items[x] = (struct pst_num_item*) xmalloc(sizeof(struct pst_num_item)); 1582 na_ptr->items[x] = (pst_num_item*) xmalloc(sizeof(pst_num_item));
1563 } 1583 }
1564 memset(na_ptr->items[x], 0, sizeof(struct pst_num_item)); //init it 1584 memset(na_ptr->items[x], 0, sizeof(pst_num_item)); //init it
1565 1585
1566 // check here to see if the id of the attribute is a mapped one 1586 // check here to see if the id of the attribute is a mapped one
1567 mapptr = pf->x_head; 1587 mapptr = pf->x_head;
1568 while (mapptr && (mapptr->map < table_rec.type)) mapptr = mapptr->next; 1588 while (mapptr && (mapptr->map < table_rec.type)) mapptr = mapptr->next;
1569 if (mapptr && (mapptr->map == table_rec.type)) { 1589 if (mapptr && (mapptr->map == table_rec.type)) {
1633 na_ptr->items[x]->size = value_size; 1653 na_ptr->items[x]->size = value_size;
1634 na_ptr->items[x]->type = table_rec.ref_type; 1654 na_ptr->items[x]->type = table_rec.ref_type;
1635 na_ptr->items[x]->data = xmalloc(value_size); 1655 na_ptr->items[x]->data = xmalloc(value_size);
1636 memcpy(na_ptr->items[x]->data, value_pointer, value_size); 1656 memcpy(na_ptr->items[x]->data, value_pointer, value_size);
1637 } 1657 }
1638 else if (pst_getBlockOffsetPointer(pf, i2_head, buf, read_size, ind_ptr, table_rec.value, &block_offset7)) { 1658 else if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, table_rec.value, &block_offset7)) {
1639 if ((table_rec.value & 0xf) == (uint32_t)0xf) { 1659 if ((table_rec.value & 0xf) == (uint32_t)0xf) {
1640 DEBUG_WARN(("failed to get block offset for table_rec.value of %#x to be read later.\n", table_rec.value)); 1660 DEBUG_WARN(("failed to get block offset for table_rec.value of %#x to be read later.\n", table_rec.value));
1641 na_ptr->items[x]->size = 0; 1661 na_ptr->items[x]->size = 0;
1642 na_ptr->items[x]->data = NULL; 1662 na_ptr->items[x]->data = NULL;
1643 na_ptr->items[x]->type = table_rec.value; 1663 na_ptr->items[x]->type = table_rec.value;
1695 DEBUG_HEXDUMPC(na_ptr->items[x]->data, na_ptr->items[x]->size, 0x10); 1715 DEBUG_HEXDUMPC(na_ptr->items[x]->data, na_ptr->items[x]->size, 0x10);
1696 } 1716 }
1697 if (na_ptr->items[x]->type == 0) na_ptr->items[x]->type = table_rec.ref_type; 1717 if (na_ptr->items[x]->type == 0) na_ptr->items[x]->type = table_rec.ref_type;
1698 } else { 1718 } else {
1699 WARN(("ERROR Unknown ref_type %#hx\n", table_rec.ref_type)); 1719 WARN(("ERROR Unknown ref_type %#hx\n", table_rec.ref_type));
1700 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1720 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1701 if (na_head) pst_free_list(na_head); 1721 if (na_head) pst_free_list(na_head);
1702 DEBUG_RET(); 1722 DEBUG_RET();
1703 return NULL; 1723 return NULL;
1704 } 1724 }
1705 x++; 1725 x++;
1706 } 1726 }
1707 DEBUG_EMAIL(("increasing ind2_ptr by %i [%#x] bytes. Was %#x, Now %#x\n", rec_size, rec_size, ind2_ptr, ind2_ptr+rec_size)); 1727 DEBUG_EMAIL(("increasing ind2_ptr by %i [%#x] bytes. Was %#x, Now %#x\n", rec_size, rec_size, ind2_ptr, ind2_ptr+rec_size));
1708 ind2_ptr += rec_size; 1728 ind2_ptr += rec_size;
1709 } 1729 }
1710 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1730 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1711 DEBUG_RET(); 1731 DEBUG_RET();
1712 return na_head; 1732 return na_head;
1713 } 1733 }
1714 1734
1715 // This version of free does NULL check first 1735 // This version of free does NULL check first
1779 DEBUG_EMAIL(("#%d - id: %#x type: %#x length: %#x\n", x, list->items[x]->id, list->items[x]->type, list->items[x]->size)); 1799 DEBUG_EMAIL(("#%d - id: %#x type: %#x length: %#x\n", x, list->items[x]->id, list->items[x]->type, list->items[x]->size));
1780 1800
1781 switch (list->items[x]->id) { 1801 switch (list->items[x]->id) {
1782 case PST_ATTRIB_HEADER: // CUSTOM attribute for saying the Extra Headers 1802 case PST_ATTRIB_HEADER: // CUSTOM attribute for saying the Extra Headers
1783 DEBUG_EMAIL(("Extra Field - ")); 1803 DEBUG_EMAIL(("Extra Field - "));
1784 ef = (pst_item_extra_field*) xmalloc(sizeof(pst_item_extra_field)); 1804 if (list->items[x]->extra) {
1785 memset(ef, 0, sizeof(pst_item_extra_field)); 1805 ef = (pst_item_extra_field*) xmalloc(sizeof(pst_item_extra_field));
1786 ef->field_name = (char*) xmalloc(strlen(list->items[x]->extra)+1); 1806 memset(ef, 0, sizeof(pst_item_extra_field));
1787 strcpy(ef->field_name, list->items[x]->extra); 1807 ef->field_name = (char*) xmalloc(strlen(list->items[x]->extra)+1);
1788 LIST_COPY(ef->value, (char*)); 1808 strcpy(ef->field_name, list->items[x]->extra);
1789 ef->next = item->extra_fields; 1809 LIST_COPY(ef->value, (char*));
1790 item->extra_fields = ef; 1810 ef->next = item->extra_fields;
1791 DEBUG_EMAIL(("\"%s\" = \"%s\"\n", ef->field_name, ef->value)); 1811 item->extra_fields = ef;
1812 DEBUG_EMAIL(("\"%s\" = \"%s\"\n", ef->field_name, ef->value));
1813 }
1814 else {
1815 DEBUG_EMAIL(("NULL extra field\n"));
1816 }
1792 break; 1817 break;
1793 case 0x0002: // PR_ALTERNATE_RECIPIENT_ALLOWED 1818 case 0x0002: // PR_ALTERNATE_RECIPIENT_ALLOWED
1794 // If set to true, the sender allows this email to be autoforwarded 1819 // If set to true, the sender allows this email to be autoforwarded
1795 DEBUG_EMAIL(("AutoForward allowed - ")); 1820 DEBUG_EMAIL(("AutoForward allowed - "));
1796 MALLOC_EMAIL(item); 1821 MALLOC_EMAIL(item);
3720 3745
3721 3746
3722 /** 3747 /**
3723 * The offset might be zero, in which case we have no data, so return a pair of null pointers. 3748 * The offset might be zero, in which case we have no data, so return a pair of null pointers.
3724 * Or, the offset might end in 0xf, so it is an id2 pointer, in which case we read the id2 block. 3749 * Or, the offset might end in 0xf, so it is an id2 pointer, in which case we read the id2 block.
3725 * Otherwise, the offset>>4 is an index into the table of offsets in the buffer. 3750 * Otherwise, the high order 16 bits of offset is the index into the subblocks, and
3751 * the (low order 16 bits of offset)>>4 is an index into the table of offsets in the subblock.
3726 */ 3752 */
3727 int pst_getBlockOffsetPointer(pst_file *pf, pst_index2_ll *i2_head, unsigned char *buf, size_t read_size, uint32_t i_offset, uint32_t offset, pst_block_offset_pointer *p) { 3753 int pst_getBlockOffsetPointer(pst_file *pf, pst_index2_ll *i2_head, pst_subblocks *subblocks, uint32_t offset, pst_block_offset_pointer *p) {
3728 size_t size; 3754 size_t size;
3729 pst_block_offset block_offset; 3755 pst_block_offset block_offset;
3730 DEBUG_ENT("pst_getBlockOffsetPointer"); 3756 DEBUG_ENT("pst_getBlockOffsetPointer");
3731 if (p->needfree) free(p->from); 3757 if (p->needfree) free(p->from);
3732 p->from = NULL; 3758 p->from = NULL;
3759 p->to = NULL;
3733 p->needfree = 0; 3760 p->needfree = 0;
3734 if (!offset) { 3761 if (!offset) {
3762 // no data
3735 p->from = p->to = NULL; 3763 p->from = p->to = NULL;
3736 } 3764 }
3737 else if ((offset & 0xf) == (uint32_t)0xf) { 3765 else if ((offset & 0xf) == (uint32_t)0xf) {
3766 // external index reference
3738 DEBUG_WARN(("Found id2 %#x value. Will follow it\n", offset)); 3767 DEBUG_WARN(("Found id2 %#x value. Will follow it\n", offset));
3739 size = pst_ff_getID2block(pf, offset, i2_head, &(p->from)); 3768 size = pst_ff_getID2block(pf, offset, i2_head, &(p->from));
3740 if (size) { 3769 if (size) {
3741 p->to = p->from + size; 3770 p->to = p->from + size;
3742 p->needfree = 1; 3771 p->needfree = 1;
3743 } 3772 }
3744 else { 3773 else {
3745 p->from = p->to = NULL; 3774 p->from = p->to = NULL;
3746 } 3775 }
3747 } 3776 }
3748 else if (pst_getBlockOffset(buf, read_size, i_offset, offset, &block_offset)) {
3749 p->from = p->to = NULL;
3750 }
3751 else { 3777 else {
3752 p->from = buf + block_offset.from; 3778 // internal index reference
3753 p->to = buf + block_offset.to; 3779 size_t subindex = offset >> 16;
3780 size_t suboffset = offset & 0xffff;
3781 if (subindex < subblocks->subblock_count) {
3782 if (pst_getBlockOffset(subblocks->subs[subindex].buf,
3783 subblocks->subs[subindex].read_size,
3784 subblocks->subs[subindex].i_offset,
3785 suboffset, &block_offset)) {
3786 p->from = subblocks->subs[subindex].buf + block_offset.from;
3787 p->to = subblocks->subs[subindex].buf + block_offset.to;
3788 }
3789 }
3754 } 3790 }
3755 DEBUG_RET(); 3791 DEBUG_RET();
3756 return (p->from) ? 0 : 1; 3792 return (p->from) ? 0 : 1;
3757 } 3793 }
3758 3794
3762 uint32_t of1 = offset >> 4; 3798 uint32_t of1 = offset >> 4;
3763 DEBUG_ENT("pst_getBlockOffset"); 3799 DEBUG_ENT("pst_getBlockOffset");
3764 if (!p || !buf || !i_offset || low || (i_offset+2+of1+sizeof(*p) > read_size)) { 3800 if (!p || !buf || !i_offset || low || (i_offset+2+of1+sizeof(*p) > read_size)) {
3765 DEBUG_WARN(("p is NULL or buf is NULL or offset is 0 or offset has low bits or beyond read size (%p, %p, %#x, %i, %i)\n", p, buf, offset, read_size, i_offset)); 3801 DEBUG_WARN(("p is NULL or buf is NULL or offset is 0 or offset has low bits or beyond read size (%p, %p, %#x, %i, %i)\n", p, buf, offset, read_size, i_offset));
3766 DEBUG_RET(); 3802 DEBUG_RET();
3767 return -1; 3803 return 0;
3768 } 3804 }
3769 memcpy(&(p->from), &(buf[(i_offset+2)+of1]), sizeof(p->from)); 3805 memcpy(&(p->from), &(buf[(i_offset+2)+of1]), sizeof(p->from));
3770 memcpy(&(p->to), &(buf[(i_offset+2)+of1+sizeof(p->from)]), sizeof(p->to)); 3806 memcpy(&(p->to), &(buf[(i_offset+2)+of1+sizeof(p->from)]), sizeof(p->to));
3771 LE16_CPU(p->from); 3807 LE16_CPU(p->from);
3772 LE16_CPU(p->to); 3808 LE16_CPU(p->to);
3773 DEBUG_WARN(("get block offset finds from=%i(%#x), to=%i(%#x)\n", p->from, p->from, p->to, p->to)); 3809 DEBUG_WARN(("get block offset finds from=%i(%#x), to=%i(%#x)\n", p->from, p->from, p->to, p->to));
3774 if (p->from > p->to) { 3810 if (p->from > p->to) {
3775 DEBUG_WARN(("get block offset from > to")); 3811 DEBUG_WARN(("get block offset from > to"));
3776 return -1; 3812 return 0;
3777 } 3813 }
3778 DEBUG_RET(); 3814 DEBUG_RET();
3779 return 0; 3815 return 1;
3780 } 3816 }
3781 3817
3782 3818
3783 pst_index_ll* pst_getID(pst_file* pf, uint64_t id) { 3819 pst_index_ll* pst_getID(pst_file* pf, uint64_t id) {
3784 pst_index_ll *ptr = NULL; 3820 pst_index_ll *ptr = NULL;
4136 4172
4137 4173
4138 #define PST_PTR_BLOCK_SIZE 0x120 4174 #define PST_PTR_BLOCK_SIZE 0x120
4139 size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_index2_ll *id2_head, unsigned char** buf) { 4175 size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_index2_ll *id2_head, unsigned char** buf) {
4140 pst_index_ll* ptr; 4176 pst_index_ll* ptr;
4141 // size_t ret; 4177 pst_holder h = {buf, NULL, 0, "", 0};
4142 struct holder h = {buf, NULL, 0, "", 0};
4143 DEBUG_ENT("pst_ff_getID2block"); 4178 DEBUG_ENT("pst_ff_getID2block");
4144 ptr = pst_getID2(id2_head, id2); 4179 ptr = pst_getID2(id2_head, id2);
4145 4180
4146 if (!ptr) { 4181 if (!ptr) {
4147 DEBUG_INDEX(("Cannot find id2 value %#x\n", id2)); 4182 DEBUG_INDEX(("Cannot find id2 value %#x\n", id2));
4151 DEBUG_RET(); 4186 DEBUG_RET();
4152 return pst_ff_getID2data(pf, ptr, &h); 4187 return pst_ff_getID2data(pf, ptr, &h);
4153 } 4188 }
4154 4189
4155 4190
4156 size_t pst_ff_getID2data(pst_file *pf, pst_index_ll *ptr, struct holder *h) { 4191 size_t pst_ff_getID2data(pst_file *pf, pst_index_ll *ptr, pst_holder *h) {
4157 size_t ret; 4192 size_t ret;
4158 unsigned char *b = NULL, *t; 4193 unsigned char *b = NULL, *t;
4159 DEBUG_ENT("pst_ff_getID2data"); 4194 DEBUG_ENT("pst_ff_getID2data");
4160 if (!(ptr->id & 0x02)) { 4195 if (!(ptr->id & 0x02)) {
4161 ret = pst_ff_getIDblock_dec(pf, ptr->id, &b); 4196 ret = pst_ff_getIDblock_dec(pf, ptr->id, &b);
4185 DEBUG_RET(); 4220 DEBUG_RET();
4186 return ret; 4221 return ret;
4187 } 4222 }
4188 4223
4189 4224
4190 size_t pst_ff_compile_ID(pst_file *pf, uint64_t id, struct holder *h, size_t size) { 4225 size_t pst_ff_compile_ID(pst_file *pf, uint64_t id, pst_holder *h, size_t size) {
4191 size_t z, a; 4226 size_t z, a;
4192 uint16_t count, y; 4227 uint16_t count, y;
4193 uint32_t x, b; 4228 uint32_t x, b;
4194 unsigned char * buf3 = NULL, *buf2 = NULL, *t; 4229 unsigned char * buf3 = NULL, *buf2 = NULL, *t;
4195 unsigned char fdepth; 4230 unsigned char fdepth;