comparison src/libpst.c @ 153:0b1766da9be8

use AM_ICONV for better portability of the library location. structure renaming to be more specific.
author Carl Byington <carl@five-ten-sg.com>
date Thu, 12 Mar 2009 15:17:32 -0700
parents edebaf0e87d2
children 581fab9f1dc7
comparison
equal deleted inserted replaced
152:edebaf0e87d2 153:0b1766da9be8
182 return -1; 182 return -1;
183 } 183 }
184 memset(pf, 0, sizeof(*pf)); 184 memset(pf, 0, sizeof(*pf));
185 185
186 if ((pf->fp = fopen(name, "rb")) == NULL) { 186 if ((pf->fp = fopen(name, "rb")) == NULL) {
187 WARN(("cannot open PST file. Error\n")); 187 perror("Error opening PST file");
188 DEBUG_RET(); 188 DEBUG_RET();
189 return -1; 189 return -1;
190 } 190 }
191 191
192 // Check pst file magic 192 // Check pst file magic
519 519
520 520
521 int pst_load_extended_attributes(pst_file *pf) { 521 int pst_load_extended_attributes(pst_file *pf) {
522 // for PST files this will load up ID2 0x61 and check it's "list" attribute. 522 // for PST files this will load up ID2 0x61 and check it's "list" attribute.
523 pst_desc_ll *p; 523 pst_desc_ll *p;
524 pst_num_array *na; 524 pst_mapi_object *na;
525 pst_id2_ll *id2_head = NULL; 525 pst_id2_ll *id2_head = NULL;
526 char *buffer=NULL, *headerbuffer=NULL; 526 char *buffer=NULL, *headerbuffer=NULL;
527 size_t bsize=0, hsize=0, bptr=0; 527 size_t bsize=0, hsize=0, bptr=0;
528 pst_x_attrib xattrib; 528 pst_x_attrib xattrib;
529 int32_t tint, err=0, x; 529 int32_t tint, err=0, x;
548 pst_printID2ptr(id2_head); 548 pst_printID2ptr(id2_head);
549 } else { 549 } else {
550 DEBUG_WARN(("Have not been able to fetch any id2 values for item 0x61. Brace yourself!\n")); 550 DEBUG_WARN(("Have not been able to fetch any id2 values for item 0x61. Brace yourself!\n"));
551 } 551 }
552 552
553 na = pst_parse_block(pf, p->desc->id, id2_head, NULL); 553 na = pst_parse_block(pf, p->desc->id, id2_head);
554 if (!na) { 554 if (!na) {
555 DEBUG_WARN(("Cannot process desc block for item 0x61. Not loading extended Attributes\n")); 555 DEBUG_WARN(("Cannot process desc block for item 0x61. Not loading extended Attributes\n"));
556 pst_free_id2(id2_head); 556 pst_free_id2(id2_head);
557 DEBUG_RET(); 557 DEBUG_RET();
558 return 0; 558 return 0;
559 } 559 }
560 560
561 for (x=0; x < na->count_item; x++) { 561 for (x=0; x < na->count_elements; x++) {
562 if (na->items[x]->id == (uint32_t)0x0003) { 562 if (na->elements[x]->mapi_id == (uint32_t)0x0003) {
563 buffer = na->items[x]->data; 563 buffer = na->elements[x]->data;
564 bsize = na->items[x]->size; 564 bsize = na->elements[x]->size;
565 } else if (na->items[x]->id == (uint32_t)0x0004) { 565 } else if (na->elements[x]->mapi_id == (uint32_t)0x0004) {
566 headerbuffer = na->items[x]->data; 566 headerbuffer = na->elements[x]->data;
567 hsize = na->items[x]->size; 567 hsize = na->elements[x]->size;
568 } else { 568 } else {
569 // leave them null 569 // leave them null
570 } 570 }
571 } 571 }
572 572
1062 1062
1063 1063
1064 /** Process a high level object from the pst file. 1064 /** Process a high level object from the pst file.
1065 */ 1065 */
1066 pst_item* pst_parse_item(pst_file *pf, pst_desc_ll *d_ptr, pst_id2_ll *m_head) { 1066 pst_item* pst_parse_item(pst_file *pf, pst_desc_ll *d_ptr, pst_id2_ll *m_head) {
1067 pst_num_array * list; 1067 pst_mapi_object * list;
1068 pst_id2_ll *id2_head = m_head; 1068 pst_id2_ll *id2_head = m_head;
1069 pst_id2_ll *id2_ptr = NULL; 1069 pst_id2_ll *id2_ptr = NULL;
1070 pst_item *item = NULL; 1070 pst_item *item = NULL;
1071 pst_item_attach *attach = NULL; 1071 pst_item_attach *attach = NULL;
1072 int32_t x; 1072 int32_t x;
1090 } 1090 }
1091 id2_head = pst_build_id2(pf, d_ptr->assoc_tree); 1091 id2_head = pst_build_id2(pf, d_ptr->assoc_tree);
1092 } 1092 }
1093 pst_printID2ptr(id2_head); 1093 pst_printID2ptr(id2_head);
1094 1094
1095 list = pst_parse_block(pf, d_ptr->desc->id, id2_head, NULL); 1095 list = pst_parse_block(pf, d_ptr->desc->id, id2_head);
1096 if (!list) { 1096 if (!list) {
1097 DEBUG_WARN(("pst_parse_block() returned an error for d_ptr->desc->id [%#"PRIx64"]\n", d_ptr->desc->id)); 1097 DEBUG_WARN(("pst_parse_block() returned an error for d_ptr->desc->id [%#"PRIx64"]\n", d_ptr->desc->id));
1098 if (!m_head) pst_free_id2(id2_head); 1098 if (!m_head) pst_free_id2(id2_head);
1099 DEBUG_RET(); 1099 DEBUG_RET();
1100 return NULL; 1100 return NULL;
1114 pst_free_list(list); 1114 pst_free_list(list);
1115 1115
1116 if ((id2_ptr = pst_getID2(id2_head, (uint64_t)0x692))) { 1116 if ((id2_ptr = pst_getID2(id2_head, (uint64_t)0x692))) {
1117 // DSN/MDN reports? 1117 // DSN/MDN reports?
1118 DEBUG_EMAIL(("DSN/MDN processing\n")); 1118 DEBUG_EMAIL(("DSN/MDN processing\n"));
1119 list = pst_parse_block(pf, id2_ptr->id->id, id2_head, NULL); 1119 list = pst_parse_block(pf, id2_ptr->id->id, id2_head);
1120 if (!list) { 1120 if (!list) {
1121 DEBUG_WARN(("ERROR error processing main DSN/MDN record\n")); 1121 DEBUG_WARN(("ERROR error processing main DSN/MDN record\n"));
1122 if (!m_head) pst_free_id2(id2_head); 1122 if (!m_head) pst_free_id2(id2_head);
1123 DEBUG_RET(); 1123 DEBUG_RET();
1124 return item; 1124 return item;
1125 } 1125 }
1126 for (x=0; x < list->count_array; x++) { 1126 for (x=0; x < list->count_objects; x++) {
1127 attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach)); 1127 attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach));
1128 memset(attach, 0, sizeof(pst_item_attach)); 1128 memset(attach, 0, sizeof(pst_item_attach));
1129 attach->next = item->attach; 1129 attach->next = item->attach;
1130 item->attach = attach; 1130 item->attach = attach;
1131 } 1131 }
1140 pst_free_list(list); 1140 pst_free_list(list);
1141 } 1141 }
1142 1142
1143 if ((id2_ptr = pst_getID2(id2_head, (uint64_t)0x671))) { 1143 if ((id2_ptr = pst_getID2(id2_head, (uint64_t)0x671))) {
1144 DEBUG_EMAIL(("ATTACHMENT processing attachment\n")); 1144 DEBUG_EMAIL(("ATTACHMENT processing attachment\n"));
1145 list = pst_parse_block(pf, id2_ptr->id->id, id2_head, NULL); 1145 list = pst_parse_block(pf, id2_ptr->id->id, id2_head);
1146 if (!list) { 1146 if (!list) {
1147 DEBUG_WARN(("ERROR error processing main attachment record\n")); 1147 DEBUG_WARN(("ERROR error processing main attachment record\n"));
1148 if (!m_head) pst_free_id2(id2_head); 1148 if (!m_head) pst_free_id2(id2_head);
1149 DEBUG_RET(); 1149 DEBUG_RET();
1150 return item; 1150 return item;
1151 } 1151 }
1152 for (x=0; x < list->count_array; x++) { 1152 for (x=0; x < list->count_objects; x++) {
1153 attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach)); 1153 attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach));
1154 memset(attach, 0, sizeof(pst_item_attach)); 1154 memset(attach, 0, sizeof(pst_item_attach));
1155 attach->next = item->attach; 1155 attach->next = item->attach;
1156 item->attach = attach; 1156 item->attach = attach;
1157 } 1157 }
1174 if ((id2_ptr = pst_getID2(id2_head, attach->id2_val))) { 1174 if ((id2_ptr = pst_getID2(id2_head, attach->id2_val))) {
1175 DEBUG_WARN(("initial attachment id2 found id %#"PRIx64"\n", id2_ptr->id->id)); 1175 DEBUG_WARN(("initial attachment id2 found id %#"PRIx64"\n", id2_ptr->id->id));
1176 // id_ptr is a record describing the attachment 1176 // id_ptr is a record describing the attachment
1177 // we pass NULL instead of id2_head cause we don't want it to 1177 // we pass NULL instead of id2_head cause we don't want it to
1178 // load all the extra stuff here. 1178 // load all the extra stuff here.
1179 list = pst_parse_block(pf, id2_ptr->id->id, NULL, NULL); 1179 list = pst_parse_block(pf, id2_ptr->id->id, NULL);
1180 if (!list) { 1180 if (!list) {
1181 DEBUG_WARN(("ERROR error processing an attachment record\n")); 1181 DEBUG_WARN(("ERROR error processing an attachment record\n"));
1182 attach = attach->next; 1182 attach = attach->next;
1183 continue; 1183 continue;
1184 } 1184 }
1185 if (list->count_array > 1) { 1185 if (list->count_objects > 1) {
1186 DEBUG_WARN(("ERROR probably fatal, list count array will overrun attach structure.\n")); 1186 DEBUG_WARN(("ERROR probably fatal, list count array will overrun attach structure.\n"));
1187 } 1187 }
1188 if (pst_process(list, item, attach)) { 1188 if (pst_process(list, item, attach)) {
1189 DEBUG_WARN(("ERROR pst_process() failed with an attachment\n")); 1189 DEBUG_WARN(("ERROR pst_process() failed with an attachment\n"));
1190 pst_free_list(list); 1190 pst_free_list(list);
1244 if (p7->needfree) free(p7->from); 1244 if (p7->needfree) free(p7->from);
1245 } 1245 }
1246 1246
1247 1247
1248 /** Process a low level descriptor block (0x0101, 0xbcec, 0x7cec) into a 1248 /** Process a low level descriptor block (0x0101, 0xbcec, 0x7cec) into a
1249 * list of objects, each of which contains a list of MAPI elements. 1249 * list of MAPI objects, each of which contains a list of MAPI elements.
1250 * 1250 *
1251 * @return list of objects 1251 * @return list of MAPI objects
1252 */ 1252 */
1253 pst_num_array * pst_parse_block(pst_file *pf, uint64_t block_id, pst_id2_ll *i2_head, pst_num_array *na_head) { 1253 pst_mapi_object * pst_parse_block(pst_file *pf, uint64_t block_id, pst_id2_ll *i2_head) {
1254 pst_mapi_object *mo_head = NULL;
1254 char *buf = NULL; 1255 char *buf = NULL;
1255 size_t read_size = 0; 1256 size_t read_size = 0;
1256 pst_subblocks subblocks; 1257 pst_subblocks subblocks;
1257 pst_num_array *na_ptr = NULL; 1258 pst_mapi_object *mo_ptr = NULL;
1258 pst_block_offset_pointer block_offset1; 1259 pst_block_offset_pointer block_offset1;
1259 pst_block_offset_pointer block_offset2; 1260 pst_block_offset_pointer block_offset2;
1260 pst_block_offset_pointer block_offset3; 1261 pst_block_offset_pointer block_offset3;
1261 pst_block_offset_pointer block_offset4; 1262 pst_block_offset_pointer block_offset4;
1262 pst_block_offset_pointer block_offset5; 1263 pst_block_offset_pointer block_offset5;
1478 return NULL; 1479 return NULL;
1479 } 1480 }
1480 1481
1481 DEBUG_EMAIL(("Mallocing number of records %i\n", num_recs)); 1482 DEBUG_EMAIL(("Mallocing number of records %i\n", num_recs));
1482 for (count_rec=0; count_rec<num_recs; count_rec++) { 1483 for (count_rec=0; count_rec<num_recs; count_rec++) {
1483 na_ptr = (pst_num_array*) xmalloc(sizeof(pst_num_array)); 1484 mo_ptr = (pst_mapi_object*) xmalloc(sizeof(pst_mapi_object));
1484 memset(na_ptr, 0, sizeof(pst_num_array)); 1485 memset(mo_ptr, 0, sizeof(pst_mapi_object));
1485 na_ptr->next = na_head; 1486 mo_ptr->next = mo_head;
1486 na_head = na_ptr; 1487 mo_head = mo_ptr;
1487 // allocate an array of count num_recs to contain sizeof(pst_num_item) 1488 // allocate an array of count num_recs to contain sizeof(pst_mapi_element)
1488 na_ptr->items = (pst_num_item**) xmalloc(sizeof(pst_num_item)*num_list); 1489 mo_ptr->elements = (pst_mapi_element**) xmalloc(sizeof(pst_mapi_element)*num_list);
1489 na_ptr->count_item = num_list; 1490 mo_ptr->count_elements = num_list;
1490 na_ptr->orig_count = num_list; 1491 mo_ptr->orig_count = num_list;
1491 na_ptr->count_array = (int32_t)num_recs; // each record will have a record of the total number of records 1492 mo_ptr->count_objects = (int32_t)num_recs; // each record will have a record of the total number of records
1492 for (x=0; x<num_list; x++) na_ptr->items[x] = NULL; 1493 for (x=0; x<num_list; x++) mo_ptr->elements[x] = NULL;
1493 x = 0; 1494 x = 0;
1494 1495
1495 DEBUG_EMAIL(("going to read %i (%#x) items\n", na_ptr->count_item, na_ptr->count_item)); 1496 DEBUG_EMAIL(("going to read %i (%#x) items\n", mo_ptr->count_elements, mo_ptr->count_elements));
1496 1497
1497 fr_ptr = list_start; // initialize fr_ptr to the start of the list. 1498 fr_ptr = list_start; // initialize fr_ptr to the start of the list.
1498 for (cur_list=0; cur_list<num_list; cur_list++) { //we will increase fr_ptr as we progress through index 1499 for (cur_list=0; cur_list<num_list; cur_list++) { //we will increase fr_ptr as we progress through index
1499 char* value_pointer = NULL; // needed for block type 2 with values larger than 4 bytes 1500 char* value_pointer = NULL; // needed for block type 2 with values larger than 4 bytes
1500 size_t value_size = 0; 1501 size_t value_size = 0;
1533 } 1534 }
1534 fr_ptr += sizeof(table2_rec); 1535 fr_ptr += sizeof(table2_rec);
1535 } else { 1536 } else {
1536 WARN(("Missing code for block_type %i\n", block_type)); 1537 WARN(("Missing code for block_type %i\n", block_type));
1537 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1538 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1538 pst_free_list(na_head); 1539 pst_free_list(mo_head);
1539 DEBUG_RET(); 1540 DEBUG_RET();
1540 return NULL; 1541 return NULL;
1541 } 1542 }
1542 DEBUG_EMAIL(("reading block %i (type=%#x, ref_type=%#x, value=%#x)\n", 1543 DEBUG_EMAIL(("reading block %i (type=%#x, ref_type=%#x, value=%#x)\n",
1543 x, table_rec.type, table_rec.ref_type, table_rec.value)); 1544 x, table_rec.type, table_rec.ref_type, table_rec.value));
1544 1545
1545 if (!na_ptr->items[x]) { 1546 if (!mo_ptr->elements[x]) {
1546 na_ptr->items[x] = (pst_num_item*) xmalloc(sizeof(pst_num_item)); 1547 mo_ptr->elements[x] = (pst_mapi_element*) xmalloc(sizeof(pst_mapi_element));
1547 } 1548 }
1548 memset(na_ptr->items[x], 0, sizeof(pst_num_item)); //init it 1549 memset(mo_ptr->elements[x], 0, sizeof(pst_mapi_element)); //init it
1549 1550
1550 // check here to see if the id of the attribute is a mapped one 1551 // check here to see if the id of the attribute is a mapped one
1551 mapptr = pf->x_head; 1552 mapptr = pf->x_head;
1552 while (mapptr && (mapptr->map < table_rec.type)) mapptr = mapptr->next; 1553 while (mapptr && (mapptr->map < table_rec.type)) mapptr = mapptr->next;
1553 if (mapptr && (mapptr->map == table_rec.type)) { 1554 if (mapptr && (mapptr->map == table_rec.type)) {
1554 if (mapptr->mytype == PST_MAP_ATTRIB) { 1555 if (mapptr->mytype == PST_MAP_ATTRIB) {
1555 na_ptr->items[x]->id = *((uint32_t*)mapptr->data); 1556 mo_ptr->elements[x]->mapi_id = *((uint32_t*)mapptr->data);
1556 DEBUG_EMAIL(("Mapped attrib %#x to %#x\n", table_rec.type, na_ptr->items[x]->id)); 1557 DEBUG_EMAIL(("Mapped attrib %#x to %#x\n", table_rec.type, mo_ptr->elements[x]->mapi_id));
1557 } else if (mapptr->mytype == PST_MAP_HEADER) { 1558 } else if (mapptr->mytype == PST_MAP_HEADER) {
1558 DEBUG_EMAIL(("Internet Header mapping found %#x\n", table_rec.type)); 1559 DEBUG_EMAIL(("Internet Header mapping found %#x\n", table_rec.type));
1559 na_ptr->items[x]->id = (uint32_t)PST_ATTRIB_HEADER; 1560 mo_ptr->elements[x]->mapi_id = (uint32_t)PST_ATTRIB_HEADER;
1560 na_ptr->items[x]->extra = mapptr->data; 1561 mo_ptr->elements[x]->extra = mapptr->data;
1561 } 1562 }
1562 else { 1563 else {
1563 DEBUG_WARN(("Missing assertion failure\n")); 1564 DEBUG_WARN(("Missing assertion failure\n"));
1564 // nothing, should be assertion failure here 1565 // nothing, should be assertion failure here
1565 } 1566 }
1566 } else { 1567 } else {
1567 na_ptr->items[x]->id = table_rec.type; 1568 mo_ptr->elements[x]->mapi_id = table_rec.type;
1568 } 1569 }
1569 na_ptr->items[x]->type = 0; // checked later before it is set 1570 mo_ptr->elements[x]->type = 0; // checked later before it is set
1570 /* Reference Types 1571 /* Reference Types
1571 0x0002 - Signed 16bit value 1572 0x0002 - Signed 16bit value
1572 0x0003 - Signed 32bit value 1573 0x0003 - Signed 32bit value
1573 0x0004 - 4-byte floating point 1574 0x0004 - 4-byte floating point
1574 0x0005 - Floating point double 1575 0x0005 - Floating point double
1591 1592
1592 if (table_rec.ref_type == (uint16_t)0x0002 || 1593 if (table_rec.ref_type == (uint16_t)0x0002 ||
1593 table_rec.ref_type == (uint16_t)0x0003 || 1594 table_rec.ref_type == (uint16_t)0x0003 ||
1594 table_rec.ref_type == (uint16_t)0x000b) { 1595 table_rec.ref_type == (uint16_t)0x000b) {
1595 //contains 32 bits of data 1596 //contains 32 bits of data
1596 na_ptr->items[x]->size = sizeof(int32_t); 1597 mo_ptr->elements[x]->size = sizeof(int32_t);
1597 na_ptr->items[x]->type = table_rec.ref_type; 1598 mo_ptr->elements[x]->type = table_rec.ref_type;
1598 na_ptr->items[x]->data = xmalloc(sizeof(int32_t)); 1599 mo_ptr->elements[x]->data = xmalloc(sizeof(int32_t));
1599 memcpy(na_ptr->items[x]->data, &(table_rec.value), sizeof(int32_t)); 1600 memcpy(mo_ptr->elements[x]->data, &(table_rec.value), sizeof(int32_t));
1600 // are we missing an LE32_CPU() call here? table_rec.value is still 1601 // are we missing an LE32_CPU() call here? table_rec.value is still
1601 // in the original order. 1602 // in the original order.
1602 1603
1603 } else if (table_rec.ref_type == (uint16_t)0x0005 || 1604 } else if (table_rec.ref_type == (uint16_t)0x0005 ||
1604 table_rec.ref_type == (uint16_t)0x000d || 1605 table_rec.ref_type == (uint16_t)0x000d ||
1616 //contains index reference to data 1617 //contains index reference to data
1617 LE32_CPU(table_rec.value); 1618 LE32_CPU(table_rec.value);
1618 if (value_pointer) { 1619 if (value_pointer) {
1619 // in a type 2 block, with a value that is more than 4 bytes 1620 // in a type 2 block, with a value that is more than 4 bytes
1620 // directly stored in this block. 1621 // directly stored in this block.
1621 na_ptr->items[x]->size = value_size; 1622 mo_ptr->elements[x]->size = value_size;
1622 na_ptr->items[x]->type = table_rec.ref_type; 1623 mo_ptr->elements[x]->type = table_rec.ref_type;
1623 na_ptr->items[x]->data = xmalloc(value_size); 1624 mo_ptr->elements[x]->data = xmalloc(value_size);
1624 memcpy(na_ptr->items[x]->data, value_pointer, value_size); 1625 memcpy(mo_ptr->elements[x]->data, value_pointer, value_size);
1625 } 1626 }
1626 else if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, table_rec.value, &block_offset7)) { 1627 else if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, table_rec.value, &block_offset7)) {
1627 if ((table_rec.value & 0xf) == (uint32_t)0xf) { 1628 if ((table_rec.value & 0xf) == (uint32_t)0xf) {
1628 DEBUG_WARN(("failed to get block offset for table_rec.value of %#x to be read later.\n", table_rec.value)); 1629 DEBUG_WARN(("failed to get block offset for table_rec.value of %#x to be read later.\n", table_rec.value));
1629 na_ptr->items[x]->size = 0; 1630 mo_ptr->elements[x]->size = 0;
1630 na_ptr->items[x]->data = NULL; 1631 mo_ptr->elements[x]->data = NULL;
1631 na_ptr->items[x]->type = table_rec.value; 1632 mo_ptr->elements[x]->type = table_rec.value;
1632 } 1633 }
1633 else { 1634 else {
1634 if (table_rec.value) { 1635 if (table_rec.value) {
1635 DEBUG_WARN(("failed to get block offset for table_rec.value of %#x\n", table_rec.value)); 1636 DEBUG_WARN(("failed to get block offset for table_rec.value of %#x\n", table_rec.value));
1636 } 1637 }
1637 na_ptr->count_item --; //we will be skipping a row 1638 mo_ptr->count_elements --; //we will be skipping a row
1638 continue; 1639 continue;
1639 } 1640 }
1640 } 1641 }
1641 else { 1642 else {
1642 value_size = (size_t)(block_offset7.to - block_offset7.from); 1643 value_size = (size_t)(block_offset7.to - block_offset7.from);
1643 na_ptr->items[x]->size = value_size; 1644 mo_ptr->elements[x]->size = value_size;
1644 na_ptr->items[x]->type = table_rec.ref_type; 1645 mo_ptr->elements[x]->type = table_rec.ref_type;
1645 na_ptr->items[x]->data = xmalloc(value_size+1); 1646 mo_ptr->elements[x]->data = xmalloc(value_size+1);
1646 memcpy(na_ptr->items[x]->data, block_offset7.from, value_size); 1647 memcpy(mo_ptr->elements[x]->data, block_offset7.from, value_size);
1647 na_ptr->items[x]->data[value_size] = '\0'; // it might be a string, null terminate it. 1648 mo_ptr->elements[x]->data[value_size] = '\0'; // it might be a string, null terminate it.
1648 } 1649 }
1649 if (table_rec.ref_type == (uint16_t)0xd) { 1650 if (table_rec.ref_type == (uint16_t)0xd) {
1650 // there is still more to do for the type of 0xD embedded objects 1651 // there is still more to do for the type of 0xD embedded objects
1651 type_d_rec = (struct _type_d_rec*) na_ptr->items[x]->data; 1652 type_d_rec = (struct _type_d_rec*) mo_ptr->elements[x]->data;
1652 LE32_CPU(type_d_rec->id); 1653 LE32_CPU(type_d_rec->id);
1653 na_ptr->items[x]->size = pst_ff_getID2block(pf, type_d_rec->id, i2_head, &(na_ptr->items[x]->data)); 1654 mo_ptr->elements[x]->size = pst_ff_getID2block(pf, type_d_rec->id, i2_head, &(mo_ptr->elements[x]->data));
1654 if (!na_ptr->items[x]->size){ 1655 if (!mo_ptr->elements[x]->size){
1655 DEBUG_WARN(("not able to read the ID2 data. Setting to be read later. %#x\n", type_d_rec->id)); 1656 DEBUG_WARN(("not able to read the ID2 data. Setting to be read later. %#x\n", type_d_rec->id));
1656 na_ptr->items[x]->type = type_d_rec->id; // fetch before freeing data, alias pointer 1657 mo_ptr->elements[x]->type = type_d_rec->id; // fetch before freeing data, alias pointer
1657 free(na_ptr->items[x]->data); 1658 free(mo_ptr->elements[x]->data);
1658 na_ptr->items[x]->data = NULL; 1659 mo_ptr->elements[x]->data = NULL;
1659 } 1660 }
1660 } 1661 }
1661 if (table_rec.ref_type == (uint16_t)0x1f) { 1662 if (table_rec.ref_type == (uint16_t)0x1f) {
1662 // there is more to do for the type 0x1f unicode strings 1663 // there is more to do for the type 0x1f unicode strings
1663 size_t rc; 1664 size_t rc;
1669 // splint barfed on the following lines 1670 // splint barfed on the following lines
1670 //VBUF_STATIC(strbuf, 1024); 1671 //VBUF_STATIC(strbuf, 1024);
1671 //VBUF_STATIC(unibuf, 1024); 1672 //VBUF_STATIC(unibuf, 1024);
1672 1673
1673 //need UTF-16 zero-termination 1674 //need UTF-16 zero-termination
1674 vbset(strbuf, na_ptr->items[x]->data, na_ptr->items[x]->size); 1675 vbset(strbuf, mo_ptr->elements[x]->data, mo_ptr->elements[x]->size);
1675 vbappend(strbuf, "\0\0", (size_t)2); 1676 vbappend(strbuf, "\0\0", (size_t)2);
1676 DEBUG_INDEX(("Iconv in:\n")); 1677 DEBUG_INDEX(("Iconv in:\n"));
1677 DEBUG_HEXDUMPC(strbuf->b, strbuf->dlen, 0x10); 1678 DEBUG_HEXDUMPC(strbuf->b, strbuf->dlen, 0x10);
1678 rc = vb_utf16to8(unibuf, strbuf->b, strbuf->dlen); 1679 rc = vb_utf16to8(unibuf, strbuf->b, strbuf->dlen);
1679 if (rc == (size_t)-1) { 1680 if (rc == (size_t)-1) {
1680 free(unibuf->b); 1681 free(unibuf->b);
1681 DEBUG_EMAIL(("Failed to convert utf-16 to utf-8\n")); 1682 DEBUG_EMAIL(("Failed to convert utf-16 to utf-8\n"));
1682 } 1683 }
1683 else { 1684 else {
1684 free(na_ptr->items[x]->data); 1685 free(mo_ptr->elements[x]->data);
1685 na_ptr->items[x]->size = unibuf->dlen; 1686 mo_ptr->elements[x]->size = unibuf->dlen;
1686 na_ptr->items[x]->data = xmalloc(unibuf->dlen); 1687 mo_ptr->elements[x]->data = xmalloc(unibuf->dlen);
1687 memcpy(na_ptr->items[x]->data, unibuf->b, unibuf->dlen); 1688 memcpy(mo_ptr->elements[x]->data, unibuf->b, unibuf->dlen);
1688 } 1689 }
1689 DEBUG_INDEX(("Iconv out:\n")); 1690 DEBUG_INDEX(("Iconv out:\n"));
1690 DEBUG_HEXDUMPC(na_ptr->items[x]->data, na_ptr->items[x]->size, 0x10); 1691 DEBUG_HEXDUMPC(mo_ptr->elements[x]->data, mo_ptr->elements[x]->size, 0x10);
1691 } 1692 }
1692 if (na_ptr->items[x]->type == 0) na_ptr->items[x]->type = table_rec.ref_type; 1693 if (mo_ptr->elements[x]->type == 0) mo_ptr->elements[x]->type = table_rec.ref_type;
1693 } else { 1694 } else {
1694 WARN(("ERROR Unknown ref_type %#hx\n", table_rec.ref_type)); 1695 WARN(("ERROR Unknown ref_type %#hx\n", table_rec.ref_type));
1695 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1696 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1696 pst_free_list(na_head); 1697 pst_free_list(mo_head);
1697 DEBUG_RET(); 1698 DEBUG_RET();
1698 return NULL; 1699 return NULL;
1699 } 1700 }
1700 x++; 1701 x++;
1701 } 1702 }
1702 DEBUG_EMAIL(("increasing ind2_ptr by %i [%#x] bytes. Was %#x, Now %#x\n", rec_size, rec_size, ind2_ptr, ind2_ptr+rec_size)); 1703 DEBUG_EMAIL(("increasing ind2_ptr by %i [%#x] bytes. Was %#x, Now %#x\n", rec_size, rec_size, ind2_ptr, ind2_ptr+rec_size));
1703 ind2_ptr += rec_size; 1704 ind2_ptr += rec_size;
1704 } 1705 }
1705 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1706 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1706 DEBUG_RET(); 1707 DEBUG_RET();
1707 return na_head; 1708 return mo_head;
1708 } 1709 }
1709 1710
1710 1711
1711 // This version of free does NULL check first 1712 // This version of free does NULL check first
1712 #define SAFE_FREE(x) {if (x) free(x);} 1713 #define SAFE_FREE(x) {if (x) free(x);}
1720 #define MALLOC_JOURNAL(x) { if (!x->journal) { x->journal = (pst_item_journal*) xmalloc(sizeof(pst_item_journal)); memset(x->journal, 0, sizeof(pst_item_journal) );} } 1721 #define MALLOC_JOURNAL(x) { if (!x->journal) { x->journal = (pst_item_journal*) xmalloc(sizeof(pst_item_journal)); memset(x->journal, 0, sizeof(pst_item_journal) );} }
1721 #define MALLOC_APPOINTMENT(x) { if (!x->appointment) { x->appointment = (pst_item_appointment*) xmalloc(sizeof(pst_item_appointment)); memset(x->appointment, 0, sizeof(pst_item_appointment) );} } 1722 #define MALLOC_APPOINTMENT(x) { if (!x->appointment) { x->appointment = (pst_item_appointment*) xmalloc(sizeof(pst_item_appointment)); memset(x->appointment, 0, sizeof(pst_item_appointment) );} }
1722 1723
1723 // malloc space and copy the current item's data null terminated 1724 // malloc space and copy the current item's data null terminated
1724 #define LIST_COPY(targ, type) { \ 1725 #define LIST_COPY(targ, type) { \
1725 targ = type realloc(targ, list->items[x]->size+1); \ 1726 targ = type realloc(targ, list->elements[x]->size+1); \
1726 memcpy(targ, list->items[x]->data, list->items[x]->size); \ 1727 memcpy(targ, list->elements[x]->data, list->elements[x]->size); \
1727 memset(((char*)targ)+list->items[x]->size, 0, (size_t)1); \ 1728 memset(((char*)targ)+list->elements[x]->size, 0, (size_t)1); \
1728 } 1729 }
1729 1730
1730 #define LIST_COPY_BOOL(label, targ) { \ 1731 #define LIST_COPY_BOOL(label, targ) { \
1731 if (*(int16_t*)list->items[x]->data) { \ 1732 if (*(int16_t*)list->elements[x]->data) { \
1732 DEBUG_EMAIL((label" - True\n")); \ 1733 DEBUG_EMAIL((label" - True\n")); \
1733 targ = 1; \ 1734 targ = 1; \
1734 } else { \ 1735 } else { \
1735 DEBUG_EMAIL((label" - False\n")); \ 1736 DEBUG_EMAIL((label" - False\n")); \
1736 targ = 0; \ 1737 targ = 0; \
1751 MALLOC_APPOINTMENT(item); \ 1752 MALLOC_APPOINTMENT(item); \
1752 LIST_COPY_BOOL(label, targ) \ 1753 LIST_COPY_BOOL(label, targ) \
1753 } 1754 }
1754 1755
1755 #define LIST_COPY_INT16_N(label, targ) { \ 1756 #define LIST_COPY_INT16_N(label, targ) { \
1756 memcpy(&(targ), list->items[x]->data, sizeof(targ)); \ 1757 memcpy(&(targ), list->elements[x]->data, sizeof(targ)); \
1757 LE16_CPU(targ); \ 1758 LE16_CPU(targ); \
1758 } 1759 }
1759 1760
1760 #define LIST_COPY_INT16(label, targ) { \ 1761 #define LIST_COPY_INT16(label, targ) { \
1761 LIST_COPY_INT16_N(label, targ); \ 1762 LIST_COPY_INT16_N(label, targ); \
1762 DEBUG_EMAIL((label" - %i %#x\n", (int)targ, (int)targ)); \ 1763 DEBUG_EMAIL((label" - %i %#x\n", (int)targ, (int)targ)); \
1763 } 1764 }
1764 1765
1765 #define LIST_COPY_INT32_N(label, targ) { \ 1766 #define LIST_COPY_INT32_N(label, targ) { \
1766 memcpy(&(targ), list->items[x]->data, sizeof(targ)); \ 1767 memcpy(&(targ), list->elements[x]->data, sizeof(targ)); \
1767 LE32_CPU(targ); \ 1768 LE32_CPU(targ); \
1768 } 1769 }
1769 1770
1770 #define LIST_COPY_INT32(label, targ) { \ 1771 #define LIST_COPY_INT32(label, targ) { \
1771 LIST_COPY_INT32_N(label, targ); \ 1772 LIST_COPY_INT32_N(label, targ); \
1848 1849
1849 // malloc space and copy the current item's data null terminated 1850 // malloc space and copy the current item's data null terminated
1850 // including the utf8 flag 1851 // including the utf8 flag
1851 #define LIST_COPY_STR(label, targ) { \ 1852 #define LIST_COPY_STR(label, targ) { \
1852 LIST_COPY(targ.str, (char*)); \ 1853 LIST_COPY(targ.str, (char*)); \
1853 targ.is_utf8 = (list->items[x]->type == 0x1f) ? 1 : 0; \ 1854 targ.is_utf8 = (list->elements[x]->type == 0x1f) ? 1 : 0; \
1854 DEBUG_EMAIL((label" - unicode %d - %s\n", targ.is_utf8, targ.str)); \ 1855 DEBUG_EMAIL((label" - unicode %d - %s\n", targ.is_utf8, targ.str)); \
1855 } 1856 }
1856 1857
1857 #define LIST_COPY_EMAIL_STR(label, targ) { \ 1858 #define LIST_COPY_EMAIL_STR(label, targ) { \
1858 MALLOC_EMAIL(item); \ 1859 MALLOC_EMAIL(item); \
1875 } 1876 }
1876 1877
1877 // malloc space and copy the item filetime 1878 // malloc space and copy the item filetime
1878 #define LIST_COPY_TIME(label, targ) { \ 1879 #define LIST_COPY_TIME(label, targ) { \
1879 targ = (FILETIME*) realloc(targ, sizeof(FILETIME)); \ 1880 targ = (FILETIME*) realloc(targ, sizeof(FILETIME)); \
1880 memcpy(targ, list->items[x]->data, list->items[x]->size); \ 1881 memcpy(targ, list->elements[x]->data, list->elements[x]->size); \
1881 LE32_CPU(targ->dwLowDateTime); \ 1882 LE32_CPU(targ->dwLowDateTime); \
1882 LE32_CPU(targ->dwHighDateTime); \ 1883 LE32_CPU(targ->dwHighDateTime); \
1883 DEBUG_EMAIL((label" - %s", fileTimeToAscii(targ))); \ 1884 DEBUG_EMAIL((label" - %s", fileTimeToAscii(targ))); \
1884 } 1885 }
1885 1886
1903 LIST_COPY_TIME(label, targ); \ 1904 LIST_COPY_TIME(label, targ); \
1904 } 1905 }
1905 1906
1906 // malloc space and copy the current item's data and size 1907 // malloc space and copy the current item's data and size
1907 #define LIST_COPY_SIZE(targ, type, mysize) { \ 1908 #define LIST_COPY_SIZE(targ, type, mysize) { \
1908 mysize = list->items[x]->size; \ 1909 mysize = list->elements[x]->size; \
1909 if (mysize) { \ 1910 if (mysize) { \
1910 targ = type realloc(targ, mysize); \ 1911 targ = type realloc(targ, mysize); \
1911 memcpy(targ, list->items[x]->data, mysize); \ 1912 memcpy(targ, list->elements[x]->data, mysize); \
1912 } \ 1913 } \
1913 else { \ 1914 else { \
1914 SAFE_FREE(targ); \ 1915 SAFE_FREE(targ); \
1915 targ = NULL; \ 1916 targ = NULL; \
1916 } \ 1917 } \
1924 1925
1925 #define NULL_CHECK(x) { if (!x) { DEBUG_EMAIL(("NULL_CHECK: Null Found\n")); break;} } 1926 #define NULL_CHECK(x) { if (!x) { DEBUG_EMAIL(("NULL_CHECK: Null Found\n")); break;} }
1926 1927
1927 1928
1928 /** 1929 /**
1929 * process the list of objects produced from parse_block() 1930 * process the list of MAPI objects produced from parse_block()
1930 * 1931 *
1931 * @param list pointer to the list of objects from parse_block() 1932 * @param list pointer to the list of MAPI objects from parse_block()
1932 * @param item pointer to the high level item to be updated from the list. 1933 * @param item pointer to the high level item to be updated from the list.
1933 * this item may be an email, contact or other sort of item. 1934 * this item may be an email, contact or other sort of item.
1934 * the type of this item is generally set by the MAPI elements 1935 * the type of this item is generally set by the MAPI elements
1935 * from the list. 1936 * from the list.
1936 * @param attach pointer to the list of attachment records. If 1937 * @param attach pointer to the list of attachment records. If
1937 * this is non-null, the length of the this attachment list 1938 * this is non-null, the length of the this attachment list
1938 * must be at least as large as the length of the objects list. 1939 * must be at least as large as the length of the MAPI objects list.
1939 * 1940 *
1940 * @return 0 for ok, -1 for error. 1941 * @return 0 for ok, -1 for error.
1941 */ 1942 */
1942 int pst_process(pst_num_array *list, pst_item *item, pst_item_attach *attach) { 1943 int pst_process(pst_mapi_object *list, pst_item *item, pst_item_attach *attach) {
1943 DEBUG_ENT("pst_process"); 1944 DEBUG_ENT("pst_process");
1944 if (!item) { 1945 if (!item) {
1945 DEBUG_EMAIL(("item cannot be NULL.\n")); 1946 DEBUG_EMAIL(("item cannot be NULL.\n"));
1946 DEBUG_RET(); 1947 DEBUG_RET();
1947 return -1; 1948 return -1;
1948 } 1949 }
1949 1950
1950 while (list) { 1951 while (list) {
1951 int32_t x; 1952 int32_t x;
1952 for (x=0; x<list->count_item; x++) { 1953 for (x=0; x<list->count_elements; x++) {
1953 int32_t t; 1954 int32_t t;
1954 pst_item_extra_field *ef; 1955 pst_item_extra_field *ef;
1955 // check here to see if the id is one that is mapped. 1956 // check here to see if the id is one that is mapped.
1956 DEBUG_EMAIL(("#%d - id: %#x type: %#x length: %#x\n", x, list->items[x]->id, list->items[x]->type, list->items[x]->size)); 1957 DEBUG_EMAIL(("#%d - mapi-id: %#x type: %#x length: %#x\n", x, list->elements[x]->mapi_id, list->elements[x]->type, list->elements[x]->size));
1957 1958
1958 switch (list->items[x]->id) { 1959 switch (list->elements[x]->mapi_id) {
1959 case PST_ATTRIB_HEADER: // CUSTOM attribute for saying the Extra Headers 1960 case PST_ATTRIB_HEADER: // CUSTOM attribute for saying the Extra Headers
1960 if (list->items[x]->extra) { 1961 if (list->elements[x]->extra) {
1961 ef = (pst_item_extra_field*) xmalloc(sizeof(pst_item_extra_field)); 1962 ef = (pst_item_extra_field*) xmalloc(sizeof(pst_item_extra_field));
1962 memset(ef, 0, sizeof(pst_item_extra_field)); 1963 memset(ef, 0, sizeof(pst_item_extra_field));
1963 ef->field_name = (char*) xmalloc(strlen(list->items[x]->extra)+1); 1964 ef->field_name = (char*) xmalloc(strlen(list->elements[x]->extra)+1);
1964 strcpy(ef->field_name, list->items[x]->extra); 1965 strcpy(ef->field_name, list->elements[x]->extra);
1965 LIST_COPY(ef->value, (char*)); 1966 LIST_COPY(ef->value, (char*));
1966 ef->next = item->extra_fields; 1967 ef->next = item->extra_fields;
1967 item->extra_fields = ef; 1968 item->extra_fields = ef;
1968 DEBUG_EMAIL(("Extra Field - \"%s\" = \"%s\"\n", ef->field_name, ef->value)); 1969 DEBUG_EMAIL(("Extra Field - \"%s\" = \"%s\"\n", ef->field_name, ef->value));
1969 if (strcmp(ef->field_name, "content-type") == 0) { 1970 if (strcmp(ef->field_name, "content-type") == 0) {
2051 LIST_COPY_EMAIL_ENUM("Sensitivity", item->email->sensitivity, 0, 4, "None", "Personal", "Private", "Company Confidential"); 2052 LIST_COPY_EMAIL_ENUM("Sensitivity", item->email->sensitivity, 0, 4, "None", "Personal", "Private", "Company Confidential");
2052 break; 2053 break;
2053 case 0x0037: // PR_SUBJECT raw subject 2054 case 0x0037: // PR_SUBJECT raw subject
2054 { 2055 {
2055 int off = 0; 2056 int off = 0;
2056 if ((list->items[x]->size > 2) && (((uint8_t)list->items[x]->data[0]) < 0x20)) { 2057 if ((list->elements[x]->size > 2) && (((uint8_t)list->elements[x]->data[0]) < 0x20)) {
2057 off = 2; 2058 off = 2;
2058 } 2059 }
2059 list->items[x]->data += off; 2060 list->elements[x]->data += off;
2060 list->items[x]->size -= off; 2061 list->elements[x]->size -= off;
2061 LIST_COPY_STR("Raw Subject", item->subject); 2062 LIST_COPY_STR("Raw Subject", item->subject);
2062 list->items[x]->size += off; 2063 list->elements[x]->size += off;
2063 list->items[x]->data -= off; 2064 list->elements[x]->data -= off;
2064 } 2065 }
2065 break; 2066 break;
2066 case 0x0039: // PR_CLIENT_SUBMIT_TIME Date Email Sent/Created 2067 case 0x0039: // PR_CLIENT_SUBMIT_TIME Date Email Sent/Created
2067 LIST_COPY_EMAIL_TIME("Date sent", item->email->sent_date); 2068 LIST_COPY_EMAIL_TIME("Date sent", item->email->sent_date);
2068 break; 2069 break;
2210 // 0x100 - RN Pending 2211 // 0x100 - RN Pending
2211 // 0x200 - NRN Pending 2212 // 0x200 - NRN Pending
2212 LIST_COPY_EMAIL_INT32("Message Flags", item->email->flag); 2213 LIST_COPY_EMAIL_INT32("Message Flags", item->email->flag);
2213 break; 2214 break;
2214 case 0x0E08: // PR_MESSAGE_SIZE Total size of a message object 2215 case 0x0E08: // PR_MESSAGE_SIZE Total size of a message object
2215 LIST_COPY_EMAIL_INT32("Message Size", item->message_size); 2216 LIST_COPY_INT32("Message Size", item->message_size);
2216 break; 2217 break;
2217 case 0x0E0A: // PR_SENTMAIL_ENTRYID 2218 case 0x0E0A: // PR_SENTMAIL_ENTRYID
2218 // folder that this message is sent to after submission 2219 // folder that this message is sent to after submission
2219 LIST_COPY_EMAIL_ENTRYID("Sentmail EntryID", item->email->sentmail_folder); 2220 LIST_COPY_EMAIL_ENTRYID("Sentmail EntryID", item->email->sentmail_folder);
2220 break; 2221 break;
2232 attach->size = (size_t)t; 2233 attach->size = (size_t)t;
2233 break; 2234 break;
2234 case 0x0FF9: // PR_RECORD_KEY Record Header 1 2235 case 0x0FF9: // PR_RECORD_KEY Record Header 1
2235 DEBUG_EMAIL(("Record Key 1 - ")); 2236 DEBUG_EMAIL(("Record Key 1 - "));
2236 LIST_COPY(item->record_key, (char*)); 2237 LIST_COPY(item->record_key, (char*));
2237 item->record_key_size = list->items[x]->size; 2238 item->record_key_size = list->elements[x]->size;
2238 DEBUG_EMAIL_HEXPRINT(item->record_key, item->record_key_size); 2239 DEBUG_EMAIL_HEXPRINT(item->record_key, item->record_key_size);
2239 DEBUG_EMAIL(("\n")); 2240 DEBUG_EMAIL(("\n"));
2240 break; 2241 break;
2241 case 0x1000: // PR_BODY 2242 case 0x1000: // PR_BODY
2242 LIST_COPY_EMAIL_STR("Plain Text body", item->body); 2243 LIST_COPY_STR("Plain Text body", item->body);
2243 break; 2244 break;
2244 case 0x1001: // PR_REPORT_TEXT 2245 case 0x1001: // PR_REPORT_TEXT
2245 LIST_COPY_EMAIL_STR("Report Text", item->email->report_text); 2246 LIST_COPY_EMAIL_STR("Report Text", item->email->report_text);
2246 break; 2247 break;
2247 case 0x1006: // PR_RTF_SYNC_BODY_CRC 2248 case 0x1006: // PR_RTF_SYNC_BODY_CRC
2291 break; 2292 break;
2292 case 0x3004: // PR_COMMENT Comment for item - usually folders 2293 case 0x3004: // PR_COMMENT Comment for item - usually folders
2293 LIST_COPY_STR("Comment", item->comment); 2294 LIST_COPY_STR("Comment", item->comment);
2294 break; 2295 break;
2295 case 0x3007: // PR_CREATION_TIME Date 4 - Creation Date? 2296 case 0x3007: // PR_CREATION_TIME Date 4 - Creation Date?
2296 LIST_COPY_EMAIL_TIME("Date 4 (Item Creation Date)", item->create_date); 2297 LIST_COPY_TIME("Date 4 (Item Creation Date)", item->create_date);
2297 break; 2298 break;
2298 case 0x3008: // PR_LAST_MODIFICATION_TIME Date 5 - Modify Date 2299 case 0x3008: // PR_LAST_MODIFICATION_TIME Date 5 - Modify Date
2299 LIST_COPY_EMAIL_TIME("Date 5 (Modify Date)", item->modify_date); 2300 LIST_COPY_TIME("Date 5 (Modify Date)", item->modify_date);
2300 break; 2301 break;
2301 case 0x300B: // PR_SEARCH_KEY Record Header 2 2302 case 0x300B: // PR_SEARCH_KEY Record Header 2
2302 DEBUG_EMAIL(("Record Search 2 -- NOT HANDLED\n")); 2303 DEBUG_EMAIL(("Record Search 2 -- NOT HANDLED\n"));
2303 break; 2304 break;
2304 case 0x35DF: // PR_VALID_FOLDER_MASK 2305 case 0x35DF: // PR_VALID_FOLDER_MASK
2368 // associated content are items that are attached to this folder 2369 // associated content are items that are attached to this folder
2369 // but are hidden from users 2370 // but are hidden from users
2370 LIST_COPY_FOLDER_INT32("Associate Content count", item->folder->assoc_count); 2371 LIST_COPY_FOLDER_INT32("Associate Content count", item->folder->assoc_count);
2371 break; 2372 break;
2372 case 0x3701: // PR_ATTACH_DATA_OBJ binary data of attachment 2373 case 0x3701: // PR_ATTACH_DATA_OBJ binary data of attachment
2373 DEBUG_EMAIL(("Binary Data [Size %i] - ", list->items[x]->size)); 2374 DEBUG_EMAIL(("Binary Data [Size %i] - ", list->elements[x]->size));
2374 NULL_CHECK(attach); 2375 NULL_CHECK(attach);
2375 if (!list->items[x]->data) { //special case 2376 if (!list->elements[x]->data) { //special case
2376 attach->id2_val = list->items[x]->type; 2377 attach->id2_val = list->elements[x]->type;
2377 DEBUG_EMAIL(("Seen a Reference. The data hasn't been loaded yet. [%#"PRIx64"][%#x]\n", 2378 DEBUG_EMAIL(("Seen a Reference. The data hasn't been loaded yet. [%#"PRIx64"][%#x]\n",
2378 attach->id2_val, list->items[x]->type)); 2379 attach->id2_val, list->elements[x]->type));
2379 } else { 2380 } else {
2380 LIST_COPY(attach->data, (char*)); 2381 LIST_COPY(attach->data, (char*));
2381 attach->size = list->items[x]->size; 2382 attach->size = list->elements[x]->size;
2382 DEBUG_EMAIL(("NOT PRINTED\n")); 2383 DEBUG_EMAIL(("NOT PRINTED\n"));
2383 } 2384 }
2384 break; 2385 break;
2385 case 0x3704: // PR_ATTACH_FILENAME Attachment filename (8.3) 2386 case 0x3704: // PR_ATTACH_FILENAME Attachment filename (8.3)
2386 NULL_CHECK(attach); 2387 NULL_CHECK(attach);
2662 LIST_COPY_INT32("Message code page", item->message_codepage); 2663 LIST_COPY_INT32("Message code page", item->message_codepage);
2663 break; 2664 break;
2664 case 0x65E3: // Entry ID? 2665 case 0x65E3: // Entry ID?
2665 DEBUG_EMAIL(("Entry ID - ")); 2666 DEBUG_EMAIL(("Entry ID - "));
2666 item->record_key = (char*) xmalloc(16+1); 2667 item->record_key = (char*) xmalloc(16+1);
2667 memcpy(item->record_key, &(list->items[x]->data[1]), 16); //skip first byte 2668 memcpy(item->record_key, &(list->elements[x]->data[1]), 16); //skip first byte
2668 item->record_key[16]='\0'; 2669 item->record_key[16]='\0';
2669 item->record_key_size=16; 2670 item->record_key_size=16;
2670 DEBUG_EMAIL_HEXPRINT((char*)item->record_key, 16); 2671 DEBUG_EMAIL_HEXPRINT((char*)item->record_key, 16);
2671 break; 2672 break;
2672 case 0x67F2: // ID2 value of the attachments proper record 2673 case 0x67F2: // ID2 value of the attachments proper record
2673 DEBUG_EMAIL(("Attachment ID2 value - ")); 2674 DEBUG_EMAIL(("Attachment ID2 value - "));
2674 if (attach) { 2675 if (attach) {
2675 uint32_t tempid; 2676 uint32_t tempid;
2676 memcpy(&(tempid), list->items[x]->data, sizeof(tempid)); 2677 memcpy(&(tempid), list->elements[x]->data, sizeof(tempid));
2677 LE32_CPU(tempid); 2678 LE32_CPU(tempid);
2678 attach->id2_val = tempid; 2679 attach->id2_val = tempid;
2679 DEBUG_EMAIL(("%#"PRIx64"\n", attach->id2_val)); 2680 DEBUG_EMAIL(("%#"PRIx64"\n", attach->id2_val));
2680 } else { 2681 } else {
2681 DEBUG_EMAIL(("NOT AN ATTACHMENT: %#x\n", list->items[x]->id)); 2682 DEBUG_EMAIL(("NOT AN ATTACHMENT: %#x\n", list->elements[x]->mapi_id));
2682 } 2683 }
2683 break; 2684 break;
2684 case 0x67FF: // Extra Property Identifier (Password CheckSum) 2685 case 0x67FF: // Extra Property Identifier (Password CheckSum)
2685 LIST_COPY_STORE_INT32("Password checksum", item->message_store->pwd_chksum); 2686 LIST_COPY_STORE_INT32("Password checksum", item->message_store->pwd_chksum);
2686 break; 2687 break;
2816 break; 2817 break;
2817 case 0x8503: // Reminder alarm 2818 case 0x8503: // Reminder alarm
2818 LIST_COPY_APPT_BOOL("Reminder alarm", item->appointment->alarm); 2819 LIST_COPY_APPT_BOOL("Reminder alarm", item->appointment->alarm);
2819 break; 2820 break;
2820 case 0x8516: // Common start 2821 case 0x8516: // Common start
2821 DEBUG_EMAIL(("Common Start Date - %s\n", fileTimeToAscii((FILETIME*)list->items[x]->data))); 2822 DEBUG_EMAIL(("Common Start Date - %s\n", fileTimeToAscii((FILETIME*)list->elements[x]->data)));
2822 break; 2823 break;
2823 case 0x8517: // Common end 2824 case 0x8517: // Common end
2824 DEBUG_EMAIL(("Common End Date - %s\n", fileTimeToAscii((FILETIME*)list->items[x]->data))); 2825 DEBUG_EMAIL(("Common End Date - %s\n", fileTimeToAscii((FILETIME*)list->elements[x]->data)));
2825 break; 2826 break;
2826 case 0x851f: // Play reminder sound filename 2827 case 0x851f: // Play reminder sound filename
2827 LIST_COPY_APPT_STR("Appointment reminder sound filename", item->appointment->alarm_filename); 2828 LIST_COPY_APPT_STR("Appointment reminder sound filename", item->appointment->alarm_filename);
2828 break; 2829 break;
2829 case 0x8530: // Followup 2830 case 0x8530: // Followup
2852 break; 2853 break;
2853 case 0x8712: // Journal Type Description 2854 case 0x8712: // Journal Type Description
2854 LIST_COPY_JOURNAL_STR("Journal description", item->journal->description); 2855 LIST_COPY_JOURNAL_STR("Journal description", item->journal->description);
2855 break; 2856 break;
2856 default: 2857 default:
2857 if (list->items[x]->type == (uint32_t)0x0002) { 2858 if (list->elements[x]->type == (uint32_t)0x0002) {
2858 DEBUG_EMAIL(("Unknown type %#x 16bit int = %hi\n", list->items[x]->id, 2859 DEBUG_EMAIL(("Unknown type %#x 16bit int = %hi\n", list->elements[x]->mapi_id,
2859 *(int16_t*)list->items[x]->data)); 2860 *(int16_t*)list->elements[x]->data));
2860 2861
2861 } else if (list->items[x]->type == (uint32_t)0x0003) { 2862 } else if (list->elements[x]->type == (uint32_t)0x0003) {
2862 DEBUG_EMAIL(("Unknown type %#x 32bit int = %i\n", list->items[x]->id, 2863 DEBUG_EMAIL(("Unknown type %#x 32bit int = %i\n", list->elements[x]->mapi_id,
2863 *(int32_t*)list->items[x]->data)); 2864 *(int32_t*)list->elements[x]->data));
2864 2865
2865 } else if (list->items[x]->type == (uint32_t)0x0004) { 2866 } else if (list->elements[x]->type == (uint32_t)0x0004) {
2866 DEBUG_EMAIL(("Unknown type %#x 4-byte floating [size = %#x]\n", list->items[x]->id, 2867 DEBUG_EMAIL(("Unknown type %#x 4-byte floating [size = %#x]\n", list->elements[x]->mapi_id,
2867 list->items[x]->size)); 2868 list->elements[x]->size));
2868 DEBUG_HEXDUMP(list->items[x]->data, list->items[x]->size); 2869 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size);
2869 2870
2870 } else if (list->items[x]->type == (uint32_t)0x0005) { 2871 } else if (list->elements[x]->type == (uint32_t)0x0005) {
2871 DEBUG_EMAIL(("Unknown type %#x double floating [size = %#x]\n", list->items[x]->id, 2872 DEBUG_EMAIL(("Unknown type %#x double floating [size = %#x]\n", list->elements[x]->mapi_id,
2872 list->items[x]->size)); 2873 list->elements[x]->size));
2873 DEBUG_HEXDUMP(list->items[x]->data, list->items[x]->size); 2874 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size);
2874 2875
2875 } else if (list->items[x]->type == (uint32_t)0x0006) { 2876 } else if (list->elements[x]->type == (uint32_t)0x0006) {
2876 DEBUG_EMAIL(("Unknown type %#x signed 64bit int = %"PRIi64"\n", list->items[x]->id, 2877 DEBUG_EMAIL(("Unknown type %#x signed 64bit int = %"PRIi64"\n", list->elements[x]->mapi_id,
2877 *(int64_t*)list->items[x]->data)); 2878 *(int64_t*)list->elements[x]->data));
2878 DEBUG_HEXDUMP(list->items[x]->data, list->items[x]->size); 2879 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size);
2879 2880
2880 } else if (list->items[x]->type == (uint32_t)0x0007) { 2881 } else if (list->elements[x]->type == (uint32_t)0x0007) {
2881 DEBUG_EMAIL(("Unknown type %#x application time [size = %#x]\n", list->items[x]->id, 2882 DEBUG_EMAIL(("Unknown type %#x application time [size = %#x]\n", list->elements[x]->mapi_id,
2882 list->items[x]->size)); 2883 list->elements[x]->size));
2883 DEBUG_HEXDUMP(list->items[x]->data, list->items[x]->size); 2884 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size);
2884 2885
2885 } else if (list->items[x]->type == (uint32_t)0x000a) { 2886 } else if (list->elements[x]->type == (uint32_t)0x000a) {
2886 DEBUG_EMAIL(("Unknown type %#x 32bit error value = %i\n", list->items[x]->id, 2887 DEBUG_EMAIL(("Unknown type %#x 32bit error value = %i\n", list->elements[x]->mapi_id,
2887 *(int32_t*)list->items[x]->data)); 2888 *(int32_t*)list->elements[x]->data));
2888 2889
2889 } else if (list->items[x]->type == (uint32_t)0x000b) { 2890 } else if (list->elements[x]->type == (uint32_t)0x000b) {
2890 DEBUG_EMAIL(("Unknown type %#x 16bit boolean = %s [%hi]\n", list->items[x]->id, 2891 DEBUG_EMAIL(("Unknown type %#x 16bit boolean = %s [%hi]\n", list->elements[x]->mapi_id,
2891 (*((int16_t*)list->items[x]->data)!=0?"True":"False"), 2892 (*((int16_t*)list->elements[x]->data)!=0?"True":"False"),
2892 *((int16_t*)list->items[x]->data))); 2893 *((int16_t*)list->elements[x]->data)));
2893 2894
2894 } else if (list->items[x]->type == (uint32_t)0x000d) { 2895 } else if (list->elements[x]->type == (uint32_t)0x000d) {
2895 DEBUG_EMAIL(("Unknown type %#x Embedded object [size = %#x]\n", list->items[x]->id, 2896 DEBUG_EMAIL(("Unknown type %#x Embedded object [size = %#x]\n", list->elements[x]->mapi_id,
2896 list->items[x]->size)); 2897 list->elements[x]->size));
2897 DEBUG_HEXDUMP(list->items[x]->data, list->items[x]->size); 2898 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size);
2898 2899
2899 } else if (list->items[x]->type == (uint32_t)0x0014) { 2900 } else if (list->elements[x]->type == (uint32_t)0x0014) {
2900 DEBUG_EMAIL(("Unknown type %#x signed 64bit int = %"PRIi64"\n", list->items[x]->id, 2901 DEBUG_EMAIL(("Unknown type %#x signed 64bit int = %"PRIi64"\n", list->elements[x]->mapi_id,
2901 *(int64_t*)list->items[x]->data)); 2902 *(int64_t*)list->elements[x]->data));
2902 DEBUG_HEXDUMP(list->items[x]->data, list->items[x]->size); 2903 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size);
2903 2904
2904 } else if (list->items[x]->type == (uint32_t)0x001e) { 2905 } else if (list->elements[x]->type == (uint32_t)0x001e) {
2905 DEBUG_EMAIL(("Unknown type %#x String Data = \"%s\"\n", list->items[x]->id, 2906 DEBUG_EMAIL(("Unknown type %#x String Data = \"%s\"\n", list->elements[x]->mapi_id,
2906 list->items[x]->data)); 2907 list->elements[x]->data));
2907 2908
2908 } else if (list->items[x]->type == (uint32_t)0x001f) { 2909 } else if (list->elements[x]->type == (uint32_t)0x001f) {
2909 DEBUG_EMAIL(("Unknown type %#x Unicode String Data [size = %#x]\n", list->items[x]->id, 2910 DEBUG_EMAIL(("Unknown type %#x Unicode String Data [size = %#x]\n", list->elements[x]->mapi_id,
2910 list->items[x]->size)); 2911 list->elements[x]->size));
2911 DEBUG_HEXDUMP(list->items[x]->data, list->items[x]->size); 2912 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size);
2912 2913
2913 } else if (list->items[x]->type == (uint32_t)0x0040) { 2914 } else if (list->elements[x]->type == (uint32_t)0x0040) {
2914 DEBUG_EMAIL(("Unknown type %#x Date = \"%s\"\n", list->items[x]->id, 2915 DEBUG_EMAIL(("Unknown type %#x Date = \"%s\"\n", list->elements[x]->mapi_id,
2915 fileTimeToAscii((FILETIME*)list->items[x]->data))); 2916 fileTimeToAscii((FILETIME*)list->elements[x]->data)));
2916 2917
2917 } else if (list->items[x]->type == (uint32_t)0x0048) { 2918 } else if (list->elements[x]->type == (uint32_t)0x0048) {
2918 DEBUG_EMAIL(("Unknown type %#x OLE GUID [size = %#x]\n", list->items[x]->id, 2919 DEBUG_EMAIL(("Unknown type %#x OLE GUID [size = %#x]\n", list->elements[x]->mapi_id,
2919 list->items[x]->size)); 2920 list->elements[x]->size));
2920 DEBUG_HEXDUMP(list->items[x]->data, list->items[x]->size); 2921 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size);
2921 2922
2922 } else if (list->items[x]->type == (uint32_t)0x0102) { 2923 } else if (list->elements[x]->type == (uint32_t)0x0102) {
2923 DEBUG_EMAIL(("Unknown type %#x Binary Data [size = %#x]\n", list->items[x]->id, 2924 DEBUG_EMAIL(("Unknown type %#x Binary Data [size = %#x]\n", list->elements[x]->mapi_id,
2924 list->items[x]->size)); 2925 list->elements[x]->size));
2925 DEBUG_HEXDUMP(list->items[x]->data, list->items[x]->size); 2926 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size);
2926 2927
2927 } else if (list->items[x]->type == (uint32_t)0x1003) { 2928 } else if (list->elements[x]->type == (uint32_t)0x1003) {
2928 DEBUG_EMAIL(("Unknown type %#x Array of 32 bit values [size = %#x]\n", list->items[x]->id, 2929 DEBUG_EMAIL(("Unknown type %#x Array of 32 bit values [size = %#x]\n", list->elements[x]->mapi_id,
2929 list->items[x]->size)); 2930 list->elements[x]->size));
2930 DEBUG_HEXDUMP(list->items[x]->data, list->items[x]->size); 2931 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size);
2931 2932
2932 } else if (list->items[x]->type == (uint32_t)0x1014) { 2933 } else if (list->elements[x]->type == (uint32_t)0x1014) {
2933 DEBUG_EMAIL(("Unknown type %#x Array of 64 bit values [siize = %#x]\n", list->items[x]->id, 2934 DEBUG_EMAIL(("Unknown type %#x Array of 64 bit values [siize = %#x]\n", list->elements[x]->mapi_id,
2934 list->items[x]->size)); 2935 list->elements[x]->size));
2935 DEBUG_HEXDUMP(list->items[x]->data, list->items[x]->size); 2936 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size);
2936 2937
2937 } else if (list->items[x]->type == (uint32_t)0x101E) { 2938 } else if (list->elements[x]->type == (uint32_t)0x101E) {
2938 DEBUG_EMAIL(("Unknown type %#x Array of Strings [size = %#x]\n", list->items[x]->id, 2939 DEBUG_EMAIL(("Unknown type %#x Array of Strings [size = %#x]\n", list->elements[x]->mapi_id,
2939 list->items[x]->size)); 2940 list->elements[x]->size));
2940 DEBUG_HEXDUMP(list->items[x]->data, list->items[x]->size); 2941 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size);
2941 2942
2942 } else if (list->items[x]->type == (uint32_t)0x101F) { 2943 } else if (list->elements[x]->type == (uint32_t)0x101F) {
2943 DEBUG_EMAIL(("Unknown type %#x Array of Unicode Strings [size = %#x]\n", list->items[x]->id, 2944 DEBUG_EMAIL(("Unknown type %#x Array of Unicode Strings [size = %#x]\n", list->elements[x]->mapi_id,
2944 list->items[x]->size)); 2945 list->elements[x]->size));
2945 DEBUG_HEXDUMP(list->items[x]->data, list->items[x]->size); 2946 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size);
2946 2947
2947 } else if (list->items[x]->type == (uint32_t)0x1102) { 2948 } else if (list->elements[x]->type == (uint32_t)0x1102) {
2948 DEBUG_EMAIL(("Unknown type %#x Array of binary data blobs [size = %#x]\n", list->items[x]->id, 2949 DEBUG_EMAIL(("Unknown type %#x Array of binary data blobs [size = %#x]\n", list->elements[x]->mapi_id,
2949 list->items[x]->size)); 2950 list->elements[x]->size));
2950 DEBUG_HEXDUMP(list->items[x]->data, list->items[x]->size); 2951 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size);
2951 2952
2952 } else { 2953 } else {
2953 DEBUG_EMAIL(("Unknown type %#x Not Printable [%#x]\n", list->items[x]->id, 2954 DEBUG_EMAIL(("Unknown type %#x Not Printable [%#x]\n", list->elements[x]->mapi_id,
2954 list->items[x]->type)); 2955 list->elements[x]->type));
2955 DEBUG_HEXDUMP(list->items[x]->data, list->items[x]->size); 2956 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size);
2956 } 2957 }
2957 2958
2958 if (list->items[x]->data) { 2959 if (list->elements[x]->data) {
2959 free(list->items[x]->data); 2960 free(list->elements[x]->data);
2960 list->items[x]->data = NULL; 2961 list->elements[x]->data = NULL;
2961 } 2962 }
2962 } 2963 }
2963 } 2964 }
2964 list = list->next; 2965 list = list->next;
2965 if (attach) attach = attach->next; 2966 if (attach) attach = attach->next;
2967 DEBUG_RET(); 2968 DEBUG_RET();
2968 return 0; 2969 return 0;
2969 } 2970 }
2970 2971
2971 2972
2972 void pst_free_list(pst_num_array *list) { 2973 void pst_free_list(pst_mapi_object *list) {
2973 pst_num_array *l; 2974 pst_mapi_object *l;
2974 DEBUG_ENT("pst_free_list"); 2975 DEBUG_ENT("pst_free_list");
2975 while (list) { 2976 while (list) {
2976 if (list->items) { 2977 if (list->elements) {
2977 int32_t x; 2978 int32_t x;
2978 for (x=0; x < list->orig_count; x++) { 2979 for (x=0; x < list->orig_count; x++) {
2979 if (list->items[x]) { 2980 if (list->elements[x]) {
2980 if (list->items[x]->data) free(list->items[x]->data); 2981 if (list->elements[x]->data) free(list->elements[x]->data);
2981 free(list->items[x]); 2982 free(list->elements[x]);
2982 } 2983 }
2983 } 2984 }
2984 free(list->items); 2985 free(list->elements);
2985 } 2986 }
2986 l = list->next; 2987 l = list->next;
2987 free (list); 2988 free (list);
2988 list = l; 2989 list = l;
2989 } 2990 }
4119 case 28595 : return "iso-8859-5"; 4120 case 28595 : return "iso-8859-5";
4120 case 28596 : return "iso-8859-6"; 4121 case 28596 : return "iso-8859-6";
4121 case 28597 : return "iso-8859-7"; 4122 case 28597 : return "iso-8859-7";
4122 case 28598 : return "iso-8859-8"; 4123 case 28598 : return "iso-8859-8";
4123 case 28599 : return "iso-8859-9"; 4124 case 28599 : return "iso-8859-9";
4125 case 28600 : return "iso-8859-10";
4126 case 28601 : return "iso-8859-11";
4127 case 28602 : return "iso-8859-12";
4128 case 28603 : return "iso-8859-13";
4129 case 28604 : return "iso-8859-14";
4130 case 28605 : return "iso-8859-15";
4131 case 28606 : return "iso-8859-16";
4124 case 50220 : return "iso-2022-jp"; 4132 case 50220 : return "iso-2022-jp";
4125 case 50221 : return "csiso2022jp"; 4133 case 50221 : return "csiso2022jp";
4126 case 51932 : return "euc-jp"; 4134 case 51932 : return "euc-jp";
4127 case 51949 : return "euc-kr"; 4135 case 51949 : return "euc-kr";
4128 case 65000 : return "utf-7"; 4136 case 65000 : return "utf-7";
4146 (item->internet_cpid) ? codepage(item->internet_cpid) : 4154 (item->internet_cpid) ? codepage(item->internet_cpid) :
4147 "utf-8"; 4155 "utf-8";
4148 } 4156 }
4149 4157
4150 4158
4151 /** Convert str to utf8 if possible. Null strings are preserved 4159 /** Convert str to utf8 if possible; null strings are preserved.
4152 * 4160 *
4153 * @param item pointer to the mapi item of interest 4161 * @param item pointer to the mapi item of interest
4154 * &param str pointer to the mapi string of interest 4162 * @param str pointer to the mapi string of interest
4155 */ 4163 */
4156 void pst_convert_utf8_null(pst_item *item, pst_string *str) 4164 void pst_convert_utf8_null(pst_item *item, pst_string *str)
4157 { 4165 {
4158 if (!str->str) return; 4166 if (!str->str) return;
4159 pst_convert_utf8(item, str); 4167 pst_convert_utf8(item, str);
4160 } 4168 }
4161 4169
4162 4170
4163 /** Convert str to utf8 if possible. Null strings are converted into empty strings. 4171 /** Convert str to utf8 if possible; null strings are converted into empty strings.
4164 * 4172 *
4165 * @param item pointer to the mapi item of interest 4173 * @param item pointer to the mapi item of interest
4166 * &param str pointer to the mapi string of interest 4174 * @param str pointer to the mapi string of interest
4167 */ 4175 */
4168 void pst_convert_utf8(pst_item *item, pst_string *str) 4176 void pst_convert_utf8(pst_item *item, pst_string *str)
4169 { 4177 {
4170 if (str->is_utf8) return; 4178 if (str->is_utf8) return;
4171 if (!str->str) { 4179 if (!str->str) {