comparison src/libpst.c @ 150:06aa84023b48

rename some structure fields to reflect our better understanding of the pst format
author Carl Byington <carl@five-ten-sg.com>
date Thu, 05 Mar 2009 08:23:32 -0800
parents f9773b6368e0
children cda7c812ec01
comparison
equal deleted inserted replaced
149:f9773b6368e0 150:06aa84023b48
71 71
72 72
73 typedef struct pst_id2_assoc32 { 73 typedef struct pst_id2_assoc32 {
74 uint32_t id2; 74 uint32_t id2;
75 uint32_t id; 75 uint32_t id;
76 uint32_t table2; 76 uint32_t child_id;
77 } pst_id2_assoc32; 77 } pst_id2_assoc32;
78 78
79 79
80 typedef struct pst_id2_assoc { 80 typedef struct pst_id2_assoc {
81 uint32_t id2; // only 32 bit here? 81 uint32_t id2; // only 32 bit here
82 uint16_t unknown1; 82 uint16_t unknown1;
83 uint16_t unknown2; 83 uint16_t unknown2;
84 uint64_t id; 84 uint64_t id;
85 uint64_t table2; 85 uint64_t child_id;
86 } pst_id2_assoc; 86 } pst_id2_assoc;
87 87
88 88
89 typedef struct pst_table3_rec32 { 89 typedef struct pst_table3_rec32 {
90 uint32_t id; 90 uint32_t id;
101 uint16_t type; 101 uint16_t type;
102 uint32_t offset; 102 uint32_t offset;
103 } pst_block_hdr; 103 } pst_block_hdr;
104 104
105 105
106 // for "compressible" encryption, just a simple substitution cipher 106 /** for "compressible" encryption, just a simple substitution cipher,
107 // this is an array of the un-encrypted values. the un-encrypted value is in the position 107 * plaintext = comp_enc[ciphertext];
108 // of the encrypted value. ie the encrypted value 0x13 represents 0x02 108 * for "strong" encryption, this is the first rotor of an Enigma 3 rotor cipher.
109 */
109 static unsigned char comp_enc [] = { 110 static unsigned char comp_enc [] = {
110 0x47, 0xf1, 0xb4, 0xe6, 0x0b, 0x6a, 0x72, 0x48, 0x85, 0x4e, 0x9e, 0xeb, 0xe2, 0xf8, 0x94, 0x53, 111 0x47, 0xf1, 0xb4, 0xe6, 0x0b, 0x6a, 0x72, 0x48, 0x85, 0x4e, 0x9e, 0xeb, 0xe2, 0xf8, 0x94, 0x53,
111 0xe0, 0xbb, 0xa0, 0x02, 0xe8, 0x5a, 0x09, 0xab, 0xdb, 0xe3, 0xba, 0xc6, 0x7c, 0xc3, 0x10, 0xdd, 112 0xe0, 0xbb, 0xa0, 0x02, 0xe8, 0x5a, 0x09, 0xab, 0xdb, 0xe3, 0xba, 0xc6, 0x7c, 0xc3, 0x10, 0xdd,
112 0x39, 0x05, 0x96, 0x30, 0xf5, 0x37, 0x60, 0x82, 0x8c, 0xc9, 0x13, 0x4a, 0x6b, 0x1d, 0xf3, 0xfb, 113 0x39, 0x05, 0x96, 0x30, 0xf5, 0x37, 0x60, 0x82, 0x8c, 0xc9, 0x13, 0x4a, 0x6b, 0x1d, 0xf3, 0xfb,
113 0x8f, 0x26, 0x97, 0xca, 0x91, 0x17, 0x01, 0xc4, 0x32, 0x2d, 0x6e, 0x31, 0x95, 0xff, 0xd9, 0x23, 114 0x8f, 0x26, 0x97, 0xca, 0x91, 0x17, 0x01, 0xc4, 0x32, 0x2d, 0x6e, 0x31, 0x95, 0xff, 0xd9, 0x23,
123 0xfd, 0x9d, 0x18, 0x41, 0x7d, 0x93, 0xd8, 0x58, 0x2c, 0xce, 0xfe, 0x24, 0xaf, 0xde, 0xb8, 0x36, 124 0xfd, 0x9d, 0x18, 0x41, 0x7d, 0x93, 0xd8, 0x58, 0x2c, 0xce, 0xfe, 0x24, 0xaf, 0xde, 0xb8, 0x36,
124 0xc8, 0xa1, 0x80, 0xa6, 0x99, 0x98, 0xa8, 0x2f, 0x0e, 0x81, 0x65, 0x73, 0xe4, 0xc2, 0xa2, 0x8a, 125 0xc8, 0xa1, 0x80, 0xa6, 0x99, 0x98, 0xa8, 0x2f, 0x0e, 0x81, 0x65, 0x73, 0xe4, 0xc2, 0xa2, 0x8a,
125 0xd4, 0xe1, 0x11, 0xd0, 0x08, 0x8b, 0x2a, 0xf2, 0xed, 0x9a, 0x64, 0x3f, 0xc1, 0x6c, 0xf9, 0xec 126 0xd4, 0xe1, 0x11, 0xd0, 0x08, 0x8b, 0x2a, 0xf2, 0xed, 0x9a, 0x64, 0x3f, 0xc1, 0x6c, 0xf9, 0xec
126 }; 127 };
127 128
128 // for "strong" encryption, we have the two additional tables, 129 /** for "strong" encryption, this is the second rotor of an Enigma 3 rotor cipher.
129 // which (with the previous table) are used as the keys in an 130 */
130 // Enigma 3 rotor cipher
131 static unsigned char comp_high1 [] = { 131 static unsigned char comp_high1 [] = {
132 0x41, 0x36, 0x13, 0x62, 0xa8, 0x21, 0x6e, 0xbb, 0xf4, 0x16, 0xcc, 0x04, 0x7f, 0x64, 0xe8, 0x5d, 132 0x41, 0x36, 0x13, 0x62, 0xa8, 0x21, 0x6e, 0xbb, 0xf4, 0x16, 0xcc, 0x04, 0x7f, 0x64, 0xe8, 0x5d,
133 0x1e, 0xf2, 0xcb, 0x2a, 0x74, 0xc5, 0x5e, 0x35, 0xd2, 0x95, 0x47, 0x9e, 0x96, 0x2d, 0x9a, 0x88, 133 0x1e, 0xf2, 0xcb, 0x2a, 0x74, 0xc5, 0x5e, 0x35, 0xd2, 0x95, 0x47, 0x9e, 0x96, 0x2d, 0x9a, 0x88,
134 0x4c, 0x7d, 0x84, 0x3f, 0xdb, 0xac, 0x31, 0xb6, 0x48, 0x5f, 0xf6, 0xc4, 0xd8, 0x39, 0x8b, 0xe7, 134 0x4c, 0x7d, 0x84, 0x3f, 0xdb, 0xac, 0x31, 0xb6, 0x48, 0x5f, 0xf6, 0xc4, 0xd8, 0x39, 0x8b, 0xe7,
135 0x23, 0x3b, 0x38, 0x8e, 0xc8, 0xc1, 0xdf, 0x25, 0xb1, 0x20, 0xa5, 0x46, 0x60, 0x4e, 0x9c, 0xfb, 135 0x23, 0x3b, 0x38, 0x8e, 0xc8, 0xc1, 0xdf, 0x25, 0xb1, 0x20, 0xa5, 0x46, 0x60, 0x4e, 0x9c, 0xfb,
145 0xf3, 0x40, 0x54, 0x6f, 0xf0, 0xc6, 0x73, 0xb8, 0xd6, 0x3e, 0x65, 0x18, 0x44, 0x1f, 0xdd, 0x67, 145 0xf3, 0x40, 0x54, 0x6f, 0xf0, 0xc6, 0x73, 0xb8, 0xd6, 0x3e, 0x65, 0x18, 0x44, 0x1f, 0xdd, 0x67,
146 0x10, 0xf1, 0x0c, 0x19, 0xec, 0xae, 0x03, 0xa1, 0x14, 0x7b, 0xa9, 0x0b, 0xff, 0xf8, 0xa3, 0xc0, 146 0x10, 0xf1, 0x0c, 0x19, 0xec, 0xae, 0x03, 0xa1, 0x14, 0x7b, 0xa9, 0x0b, 0xff, 0xf8, 0xa3, 0xc0,
147 0xa2, 0x01, 0xf7, 0x2e, 0xbc, 0x24, 0x68, 0x75, 0x0d, 0xfe, 0xba, 0x2f, 0xb5, 0xd0, 0xda, 0x3d 147 0xa2, 0x01, 0xf7, 0x2e, 0xbc, 0x24, 0x68, 0x75, 0x0d, 0xfe, 0xba, 0x2f, 0xb5, 0xd0, 0xda, 0x3d
148 }; 148 };
149 149
150 /** for "strong" encryption, this is the third rotor of an Enigma 3 rotor cipher.
151 */
150 static unsigned char comp_high2 [] = { 152 static unsigned char comp_high2 [] = {
151 0x14, 0x53, 0x0f, 0x56, 0xb3, 0xc8, 0x7a, 0x9c, 0xeb, 0x65, 0x48, 0x17, 0x16, 0x15, 0x9f, 0x02, 153 0x14, 0x53, 0x0f, 0x56, 0xb3, 0xc8, 0x7a, 0x9c, 0xeb, 0x65, 0x48, 0x17, 0x16, 0x15, 0x9f, 0x02,
152 0xcc, 0x54, 0x7c, 0x83, 0x00, 0x0d, 0x0c, 0x0b, 0xa2, 0x62, 0xa8, 0x76, 0xdb, 0xd9, 0xed, 0xc7, 154 0xcc, 0x54, 0x7c, 0x83, 0x00, 0x0d, 0x0c, 0x0b, 0xa2, 0x62, 0xa8, 0x76, 0xdb, 0xd9, 0xed, 0xc7,
153 0xc5, 0xa4, 0xdc, 0xac, 0x85, 0x74, 0xd6, 0xd0, 0xa7, 0x9b, 0xae, 0x9a, 0x96, 0x71, 0x66, 0xc3, 155 0xc5, 0xa4, 0xdc, 0xac, 0x85, 0x74, 0xd6, 0xd0, 0xa7, 0x9b, 0xae, 0x9a, 0x96, 0x71, 0x66, 0xc3,
154 0x63, 0x99, 0xb8, 0xdd, 0x73, 0x92, 0x8e, 0x84, 0x7d, 0xa5, 0x5e, 0xd1, 0x5d, 0x93, 0xb1, 0x57, 156 0x63, 0x99, 0xb8, 0xdd, 0x73, 0x92, 0x8e, 0x84, 0x7d, 0xa5, 0x5e, 0xd1, 0x5d, 0x93, 0xb1, 0x57,
163 0xe9, 0xf3, 0xd5, 0x2f, 0x70, 0x20, 0xf2, 0x1f, 0x05, 0x67, 0xad, 0x55, 0x10, 0xce, 0xcd, 0xe3, 165 0xe9, 0xf3, 0xd5, 0x2f, 0x70, 0x20, 0xf2, 0x1f, 0x05, 0x67, 0xad, 0x55, 0x10, 0xce, 0xcd, 0xe3,
164 0x27, 0x3b, 0xda, 0xba, 0xd7, 0xc2, 0x26, 0xd4, 0x91, 0x1d, 0xd2, 0x1c, 0x22, 0x33, 0xf8, 0xfa, 166 0x27, 0x3b, 0xda, 0xba, 0xd7, 0xc2, 0x26, 0xd4, 0x91, 0x1d, 0xd2, 0x1c, 0x22, 0x33, 0xf8, 0xfa,
165 0xf1, 0x5a, 0xef, 0xcf, 0x90, 0xb6, 0x8b, 0xb5, 0xbd, 0xc0, 0xbf, 0x08, 0x97, 0x1e, 0x6c, 0xe2, 167 0xf1, 0x5a, 0xef, 0xcf, 0x90, 0xb6, 0x8b, 0xb5, 0xbd, 0xc0, 0xbf, 0x08, 0x97, 0x1e, 0x6c, 0xe2,
166 0x61, 0xe0, 0xc6, 0xc1, 0x59, 0xab, 0xbb, 0x58, 0xde, 0x5f, 0xdf, 0x60, 0x79, 0x7e, 0xb2, 0x8a 168 0x61, 0xe0, 0xc6, 0xc1, 0x59, 0xab, 0xbb, 0x58, 0xde, 0x5f, 0xdf, 0x60, 0x79, 0x7e, 0xb2, 0x8a
167 }; 169 };
170
168 171
169 int pst_open(pst_file *pf, char *name) { 172 int pst_open(pst_file *pf, char *name) {
170 int32_t sig; 173 int32_t sig;
171 174
172 unicode_init(); 175 unicode_init();
302 node->no_child = 0; 305 node->no_child = 0;
303 306
304 // find any orphan children of this node, and collect them 307 // find any orphan children of this node, and collect them
305 pst_desc_ll *n = pf->d_head; 308 pst_desc_ll *n = pf->d_head;
306 while (n) { 309 while (n) {
307 if (n->parent_id == node->id) { 310 if (n->parent_d_id == node->d_id) {
308 // found a child of this node 311 // found a child of this node
309 DEBUG_INDEX(("Found orphan child %#"PRIx64" of parent %#"PRIx64"\n", n->id, node->id)); 312 DEBUG_INDEX(("Found orphan child %#"PRIx64" of parent %#"PRIx64"\n", n->d_id, node->d_id));
310 pst_desc_ll *nn = n->next; 313 pst_desc_ll *nn = n->next;
311 pst_desc_ll *pp = n->prev; 314 pst_desc_ll *pp = n->prev;
312 node->no_child++; 315 node->no_child++;
313 n->parent = node; 316 n->parent = node;
314 add_descriptor_to_list(n, &node->child, &node->child_tail); 317 add_descriptor_to_list(n, &node->child, &node->child_tail);
320 n = n->next; 323 n = n->next;
321 } 324 }
322 } 325 }
323 326
324 // now hook this node into the global tree 327 // now hook this node into the global tree
325 if (node->parent_id == 0) { 328 if (node->parent_d_id == 0) {
326 // add top level node to the descriptor tree 329 // add top level node to the descriptor tree
327 //DEBUG_INDEX(("Null parent\n")); 330 //DEBUG_INDEX(("Null parent\n"));
328 add_descriptor_to_list(node, &pf->d_head, &pf->d_tail); 331 add_descriptor_to_list(node, &pf->d_head, &pf->d_tail);
329 } 332 }
330 else if (node->parent_id == node->id) { 333 else if (node->parent_d_id == node->d_id) {
331 // add top level node to the descriptor tree 334 // add top level node to the descriptor tree
332 DEBUG_INDEX(("%#"PRIx64" is its own parent. What is this world coming to?\n")); 335 DEBUG_INDEX(("%#"PRIx64" is its own parent. What is this world coming to?\n"));
333 add_descriptor_to_list(node, &pf->d_head, &pf->d_tail); 336 add_descriptor_to_list(node, &pf->d_head, &pf->d_tail);
334 } else { 337 } else {
335 //DEBUG_INDEX(("Searching for parent %#"PRIx64" of %#"PRIx64"\n", node->parent_id, node->id)); 338 //DEBUG_INDEX(("Searching for parent %#"PRIx64" of %#"PRIx64"\n", node->parent_id, node->id));
336 pst_desc_ll *parent = pst_getDptr(pf, node->parent_id); 339 pst_desc_ll *parent = pst_getDptr(pf, node->parent_d_id);
337 if (parent) { 340 if (parent) {
338 //DEBUG_INDEX(("Found parent %#"PRIx64"\n", node->parent_id)); 341 //DEBUG_INDEX(("Found parent %#"PRIx64"\n", node->parent_id));
339 parent->no_child++; 342 parent->no_child++;
340 node->parent = parent; 343 node->parent = parent;
341 add_descriptor_to_list(node, &parent->child, &parent->child_tail); 344 add_descriptor_to_list(node, &parent->child, &parent->child_tail);
342 } 345 }
343 else { 346 else {
344 DEBUG_INDEX(("No parent %#"PRIx64", have an orphan child %#"PRIx64"\n", node->parent_id, node->id)); 347 DEBUG_INDEX(("No parent %#"PRIx64", have an orphan child %#"PRIx64"\n", node->parent_d_id, node->d_id));
345 add_descriptor_to_list(node, &pf->d_head, &pf->d_tail); 348 add_descriptor_to_list(node, &pf->d_head, &pf->d_tail);
346 } 349 }
347 } 350 }
348 DEBUG_RET(); 351 DEBUG_RET();
349 } 352 }
354 * by an attachment containing an embedded rfc822 message. 357 * by an attachment containing an embedded rfc822 message.
355 * 358 *
356 * @param head pointer to the subtree to be copied 359 * @param head pointer to the subtree to be copied
357 * @return pointer to the new copy of the subtree 360 * @return pointer to the new copy of the subtree
358 */ 361 */
359 static pst_index2_ll* deep_copy(pst_index2_ll *head); 362 static pst_id2_ll* deep_copy(pst_id2_ll *head);
360 static pst_index2_ll* deep_copy(pst_index2_ll *head) 363 static pst_id2_ll* deep_copy(pst_id2_ll *head)
361 { 364 {
362 if (!head) return NULL; 365 if (!head) return NULL;
363 pst_index2_ll* me = (pst_index2_ll*) xmalloc(sizeof(pst_index2_ll)); 366 pst_id2_ll* me = (pst_id2_ll*) xmalloc(sizeof(pst_id2_ll));
364 me->id2 = head->id2; 367 me->id2 = head->id2;
365 me->id = head->id; 368 me->id = head->id;
366 me->child = deep_copy(head->child); 369 me->child = deep_copy(head->child);
367 me->next = deep_copy(head->next); 370 me->next = deep_copy(head->next);
368 return me; 371 return me;
387 } 390 }
388 DEBUG_INDEX(("looking for top of folder descriptor %#"PRIx32"\n", topid)); 391 DEBUG_INDEX(("looking for top of folder descriptor %#"PRIx32"\n", topid));
389 topnode = pst_getDptr(pf, (uint64_t)topid); 392 topnode = pst_getDptr(pf, (uint64_t)topid);
390 if (!topnode) { 393 if (!topnode) {
391 // add dummy top record to pickup orphan children 394 // add dummy top record to pickup orphan children
392 topnode = (pst_desc_ll*) xmalloc(sizeof(pst_desc_ll)); 395 topnode = (pst_desc_ll*) xmalloc(sizeof(pst_desc_ll));
393 topnode->id = topid; 396 topnode->d_id = topid;
394 topnode->parent_id = 0; 397 topnode->parent_d_id = 0;
395 topnode->list_index = NULL; 398 topnode->assoc_tree = NULL;
396 topnode->desc = NULL; 399 topnode->desc = NULL;
397 record_descriptor(pf, topnode); // add to the global tree 400 record_descriptor(pf, topnode); // add to the global tree
398 } 401 }
399 DEBUG_RET(); 402 DEBUG_RET();
400 return topnode; 403 return topnode;
401 } 404 }
517 520
518 int pst_load_extended_attributes(pst_file *pf) { 521 int pst_load_extended_attributes(pst_file *pf) {
519 // 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.
520 pst_desc_ll *p; 523 pst_desc_ll *p;
521 pst_num_array *na; 524 pst_num_array *na;
522 pst_index2_ll *id2_head = NULL; 525 pst_id2_ll *id2_head = NULL;
523 char *buffer=NULL, *headerbuffer=NULL; 526 char *buffer=NULL, *headerbuffer=NULL;
524 size_t bsize=0, hsize=0, bptr=0; 527 size_t bsize=0, hsize=0, bptr=0;
525 pst_x_attrib xattrib; 528 pst_x_attrib xattrib;
526 int32_t tint, err=0, x; 529 int32_t tint, err=0, x;
527 pst_x_attrib_ll *ptr, *p_head=NULL, *p_sh=NULL, *p_sh2=NULL; 530 pst_x_attrib_ll *ptr, *p_head=NULL, *p_sh=NULL, *p_sh2=NULL;
538 DEBUG_WARN(("desc is NULL for item 0x61. Cannot load Extended Attributes\n")); 541 DEBUG_WARN(("desc is NULL for item 0x61. Cannot load Extended Attributes\n"));
539 DEBUG_RET(); 542 DEBUG_RET();
540 return 0; 543 return 0;
541 } 544 }
542 545
543 if (p->list_index) { 546 if (p->assoc_tree) {
544 id2_head = pst_build_id2(pf, p->list_index); 547 id2_head = pst_build_id2(pf, p->assoc_tree);
545 pst_printID2ptr(id2_head); 548 pst_printID2ptr(id2_head);
546 } else { 549 } else {
547 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"));
548 } 551 }
549 552
694 DEBUG_INDEX(("Decoding desc32\n")); 697 DEBUG_INDEX(("Decoding desc32\n"));
695 DEBUG_HEXDUMPC(buf, sizeof(pst_desc32), 0x10); 698 DEBUG_HEXDUMPC(buf, sizeof(pst_desc32), 0x10);
696 memcpy(&d32, buf, sizeof(pst_desc32)); 699 memcpy(&d32, buf, sizeof(pst_desc32));
697 LE32_CPU(d32.d_id); 700 LE32_CPU(d32.d_id);
698 LE32_CPU(d32.desc_id); 701 LE32_CPU(d32.desc_id);
699 LE32_CPU(d32.list_id); 702 LE32_CPU(d32.tree_id);
700 LE32_CPU(d32.parent_id); 703 LE32_CPU(d32.parent_d_id);
701 desc->d_id = d32.d_id; 704 desc->d_id = d32.d_id;
702 desc->desc_id = d32.desc_id; 705 desc->desc_id = d32.desc_id;
703 desc->list_id = d32.list_id; 706 desc->tree_id = d32.tree_id;
704 desc->parent_id = d32.parent_id; 707 desc->parent_d_id = d32.parent_d_id;
705 desc->u1 = 0; 708 desc->u1 = 0;
706 r = sizeof(pst_desc32); 709 r = sizeof(pst_desc32);
707 } 710 }
708 return r; 711 return r;
709 } 712 }
710 713
778 DEBUG_INDEX(("Decoding assoc64\n")); 781 DEBUG_INDEX(("Decoding assoc64\n"));
779 DEBUG_HEXDUMPC(buf, sizeof(pst_id2_assoc), 0x10); 782 DEBUG_HEXDUMPC(buf, sizeof(pst_id2_assoc), 0x10);
780 memcpy(assoc, buf, sizeof(pst_id2_assoc)); 783 memcpy(assoc, buf, sizeof(pst_id2_assoc));
781 LE32_CPU(assoc->id2); 784 LE32_CPU(assoc->id2);
782 LE64_CPU(assoc->id); 785 LE64_CPU(assoc->id);
783 LE64_CPU(assoc->table2); 786 LE64_CPU(assoc->child_id);
784 r = sizeof(pst_id2_assoc); 787 r = sizeof(pst_id2_assoc);
785 } else { 788 } else {
786 pst_id2_assoc32 assoc32; 789 pst_id2_assoc32 assoc32;
787 DEBUG_INDEX(("Decoding assoc32\n")); 790 DEBUG_INDEX(("Decoding assoc32\n"));
788 DEBUG_HEXDUMPC(buf, sizeof(pst_id2_assoc32), 0x10); 791 DEBUG_HEXDUMPC(buf, sizeof(pst_id2_assoc32), 0x10);
789 memcpy(&assoc32, buf, sizeof(pst_id2_assoc32)); 792 memcpy(&assoc32, buf, sizeof(pst_id2_assoc32));
790 LE32_CPU(assoc32.id2); 793 LE32_CPU(assoc32.id2);
791 LE32_CPU(assoc32.id); 794 LE32_CPU(assoc32.id);
792 LE32_CPU(assoc32.table2); 795 LE32_CPU(assoc32.table2);
793 assoc->id2 = assoc32.id2; 796 assoc->id2 = assoc32.id2;
794 assoc->id = assoc32.id; 797 assoc->id = assoc32.id;
795 assoc->table2 = assoc32.table2; 798 assoc->child_id = assoc32.child_id;
796 r = sizeof(pst_id2_assoc32); 799 r = sizeof(pst_id2_assoc32);
797 } 800 }
798 return r; 801 return r;
799 } 802 }
800 803
819 } 822 }
820 return r; 823 return r;
821 } 824 }
822 825
823 826
827 /** Process the index1 b-tree from the pst file and create the
828 * pf->i_head linked list from it. This tree holds the location
829 * (offset and size) of lower level objects (0xbcec descriptor
830 * blocks, etc) in the pst file.
831 */
824 int pst_build_id_ptr(pst_file *pf, int64_t offset, int32_t depth, uint64_t linku1, uint64_t start_val, uint64_t end_val) { 832 int pst_build_id_ptr(pst_file *pf, int64_t offset, int32_t depth, uint64_t linku1, uint64_t start_val, uint64_t end_val) {
825 struct pst_table_ptr_structn table, table2; 833 struct pst_table_ptr_structn table, table2;
826 pst_index_ll *i_ptr=NULL; 834 pst_index_ll *i_ptr=NULL;
827 pst_index index; 835 pst_index index;
828 int32_t x, item_count; 836 int32_t x, item_count;
932 DEBUG_RET(); 940 DEBUG_RET();
933 return 0; 941 return 0;
934 } 942 }
935 943
936 944
945 /** Process the index2 b-tree from the pst file and create the
946 * pf->d_head tree from it. This tree holds descriptions of the
947 * higher level objects (email, contact, etc) in the pst file.
948 */
937 int pst_build_desc_ptr (pst_file *pf, int64_t offset, int32_t depth, uint64_t linku1, uint64_t start_val, uint64_t end_val) { 949 int pst_build_desc_ptr (pst_file *pf, int64_t offset, int32_t depth, uint64_t linku1, uint64_t start_val, uint64_t end_val) {
938 struct pst_table_ptr_structn table, table2; 950 struct pst_table_ptr_structn table, table2;
939 pst_descn desc_rec; 951 pst_descn desc_rec;
940 int32_t item_count; 952 int32_t item_count;
941 uint64_t old = start_val; 953 uint64_t old = start_val;
975 DEBUG_RET(); 987 DEBUG_RET();
976 return -1; 988 return -1;
977 } 989 }
978 for (x=0; x<item_count; x++) { 990 for (x=0; x<item_count; x++) {
979 bptr += pst_decode_desc(pf, &desc_rec, bptr); 991 bptr += pst_decode_desc(pf, &desc_rec, bptr);
980 DEBUG_INDEX(("[%i] Item(%#x) = [d_id = %#"PRIx64", desc_id = %#"PRIx64", list_id = %#"PRIx64", parent_id = %#x]\n", 992 DEBUG_INDEX(("[%i] Item(%#x) = [d_id = %#"PRIx64", desc_id = %#"PRIx64", tree_id = %#"PRIx64", parent_d_id = %#x]\n",
981 depth, x, desc_rec.d_id, desc_rec.desc_id, desc_rec.list_id, desc_rec.parent_id)); 993 depth, x, desc_rec.d_id, desc_rec.desc_id, desc_rec.tree_id, desc_rec.parent_d_id));
982 if ((desc_rec.d_id >= end_val) || (desc_rec.d_id < old)) { 994 if ((desc_rec.d_id >= end_val) || (desc_rec.d_id < old)) {
983 DEBUG_WARN(("This item isn't right. Must be corruption, or I got it wrong!\n")); 995 DEBUG_WARN(("This item isn't right. Must be corruption, or I got it wrong!\n"));
984 DEBUG_HEXDUMPC(buf, DESC_BLOCK_SIZE, 16); 996 DEBUG_HEXDUMPC(buf, DESC_BLOCK_SIZE, 16);
985 if (buf) free(buf); 997 if (buf) free(buf);
986 DEBUG_RET(); 998 DEBUG_RET();
993 if (buf) free(buf); 1005 if (buf) free(buf);
994 DEBUG_RET(); 1006 DEBUG_RET();
995 return -1; 1007 return -1;
996 } 1008 }
997 } 1009 }
998 DEBUG_INDEX(("New Record %#"PRIx64" with parent %#x\n", desc_rec.d_id, desc_rec.parent_id)); 1010 DEBUG_INDEX(("New Record %#"PRIx64" with parent %#x\n", desc_rec.d_id, desc_rec.parent_d_id));
999 { 1011 {
1000 pst_desc_ll *d_ptr = (pst_desc_ll*) xmalloc(sizeof(pst_desc_ll)); 1012 pst_desc_ll *d_ptr = (pst_desc_ll*) xmalloc(sizeof(pst_desc_ll));
1001 d_ptr->id = desc_rec.d_id; 1013 d_ptr->d_id = desc_rec.d_id;
1002 d_ptr->parent_id = desc_rec.parent_id; 1014 d_ptr->parent_d_id = desc_rec.parent_d_id;
1003 d_ptr->list_index = pst_getID(pf, desc_rec.list_id); 1015 d_ptr->assoc_tree = pst_getID(pf, desc_rec.tree_id);
1004 d_ptr->desc = pst_getID(pf, desc_rec.desc_id); 1016 d_ptr->desc = pst_getID(pf, desc_rec.desc_id);
1005 record_descriptor(pf, d_ptr); // add to the global tree 1017 record_descriptor(pf, d_ptr); // add to the global tree
1006 } 1018 }
1007 } 1019 }
1008 } else { 1020 } else {
1047 DEBUG_RET(); 1059 DEBUG_RET();
1048 return 0; 1060 return 0;
1049 } 1061 }
1050 1062
1051 1063
1052 pst_item* pst_parse_item(pst_file *pf, pst_desc_ll *d_ptr, pst_index2_ll *m_head) { 1064 /** Process a high level object from the pst file.
1065 */
1066 pst_item* pst_parse_item(pst_file *pf, pst_desc_ll *d_ptr, pst_id2_ll *m_head) {
1053 pst_num_array * list; 1067 pst_num_array * list;
1054 pst_index2_ll *id2_head = m_head; 1068 pst_id2_ll *id2_head = m_head;
1055 pst_index2_ll *id2_ptr = NULL; 1069 pst_id2_ll *id2_ptr = NULL;
1056 pst_item *item = NULL; 1070 pst_item *item = NULL;
1057 pst_item_attach *attach = NULL; 1071 pst_item_attach *attach = NULL;
1058 int32_t x; 1072 int32_t x;
1059 DEBUG_ENT("pst_parse_item"); 1073 DEBUG_ENT("pst_parse_item");
1060 if (!d_ptr) { 1074 if (!d_ptr) {
1067 DEBUG_WARN(("why is d_ptr->desc == NULL? I don't want to do anything else with this record\n")); 1081 DEBUG_WARN(("why is d_ptr->desc == NULL? I don't want to do anything else with this record\n"));
1068 DEBUG_RET(); 1082 DEBUG_RET();
1069 return NULL; 1083 return NULL;
1070 } 1084 }
1071 1085
1072 if (d_ptr->list_index) { 1086 if (d_ptr->assoc_tree) {
1073 if (m_head) { 1087 if (m_head) {
1074 DEBUG_WARN(("supplied master head, but have a list that is building a new id2_head")); 1088 DEBUG_WARN(("supplied master head, but have a list that is building a new id2_head"));
1075 m_head = NULL; 1089 m_head = NULL;
1076 } 1090 }
1077 id2_head = pst_build_id2(pf, d_ptr->list_index); 1091 id2_head = pst_build_id2(pf, d_ptr->assoc_tree);
1078 } 1092 }
1079 pst_printID2ptr(id2_head); 1093 pst_printID2ptr(id2_head);
1080 1094
1081 list = pst_parse_block(pf, d_ptr->desc->id, id2_head, NULL); 1095 list = pst_parse_block(pf, d_ptr->desc->id, id2_head, NULL);
1082 if (!list) { 1096 if (!list) {
1237 if (p6->needfree) free(p6->from); 1251 if (p6->needfree) free(p6->from);
1238 if (p7->needfree) free(p7->from); 1252 if (p7->needfree) free(p7->from);
1239 } 1253 }
1240 1254
1241 1255
1242 pst_num_array * pst_parse_block(pst_file *pf, uint64_t block_id, pst_index2_ll *i2_head, pst_num_array *na_head) { 1256 /** Process a low level descriptor block (0x0101, 0xbcec, 0x7cec) into a
1257 * list of objects, each of which contains a list of MAPI elements.
1258 *
1259 * @return list of objects
1260 */
1261 pst_num_array * pst_parse_block(pst_file *pf, uint64_t block_id, pst_id2_ll *i2_head, pst_num_array *na_head) {
1243 char *buf = NULL; 1262 char *buf = NULL;
1244 size_t read_size = 0; 1263 size_t read_size = 0;
1245 pst_subblocks subblocks; 1264 pst_subblocks subblocks;
1246 pst_num_array *na_ptr = NULL; 1265 pst_num_array *na_ptr = NULL;
1247 pst_block_offset_pointer block_offset1; 1266 pst_block_offset_pointer block_offset1;
1736 1755
1737 #define NULL_CHECK(x) { if (!x) { DEBUG_EMAIL(("NULL_CHECK: Null Found\n")); break;} } 1756 #define NULL_CHECK(x) { if (!x) { DEBUG_EMAIL(("NULL_CHECK: Null Found\n")); break;} }
1738 1757
1739 1758
1740 /** 1759 /**
1741 * process the list of items produced from parse_block() 1760 * process the list of objects produced from parse_block()
1742 * 1761 *
1743 * @param list pointer to the linked list of things from parse_block() 1762 * @param list pointer to the list of objects from parse_block()
1744 * @param item pointer to the item to be updated from the list. 1763 * @param item pointer to the high level item to be updated from the list.
1745 * this item may be an email, contact or other sort of item. 1764 * this item may be an email, contact or other sort of item.
1746 * the type of this item is generally set by the things 1765 * the type of this item is generally set by the MAPI elements
1747 * from the list. 1766 * from the list.
1748 * @param attach pointer to the linked list of attachment records. If 1767 * @param attach pointer to the list of attachment records. If
1749 * this is non-null, the length of the this attachment list 1768 * this is non-null, the length of the this attachment list
1750 * must be at least as large as the length of the list. 1769 * must be at least as large as the length of the objects list.
1751 * 1770 *
1752 * @return 0 for ok, -1 for error. 1771 * @return 0 for ok, -1 for error.
1753 */ 1772 */
1754 int pst_process(pst_num_array *list, pst_item *item, pst_item_attach *attach) { 1773 int pst_process(pst_num_array *list, pst_item *item, pst_item_attach *attach) {
1755 DEBUG_ENT("pst_process"); 1774 DEBUG_ENT("pst_process");
1786 char *pp = strchr(p, '"'); 1805 char *pp = strchr(p, '"');
1787 if (pp) { 1806 if (pp) {
1788 *pp = '\0'; 1807 *pp = '\0';
1789 char *set = strdup(p); 1808 char *set = strdup(p);
1790 *pp = '"'; 1809 *pp = '"';
1791 MALLOC_EMAIL(item); 1810 if (item->body_charset) free(item->body_charset);
1792 if (item->email->body_charset) free(item->email->body_charset); 1811 item->body_charset = set;
1793 item->email->body_charset = set;
1794 DEBUG_EMAIL(("body charset %s from content-type extra field\n", set)); 1812 DEBUG_EMAIL(("body charset %s from content-type extra field\n", set));
1795 } 1813 }
1796 } 1814 }
1797 } 1815 }
1798 } 1816 }
3109 MALLOC_CONTACT(item); 3127 MALLOC_CONTACT(item);
3110 LIST_COPY(item->contact->other_po_box, (char*)); 3128 LIST_COPY(item->contact->other_po_box, (char*));
3111 DEBUG_EMAIL(("%s\n", item->contact->other_po_box)); 3129 DEBUG_EMAIL(("%s\n", item->contact->other_po_box));
3112 break; 3130 break;
3113 case 0x3FDE: // PR_INTERNET_CPID 3131 case 0x3FDE: // PR_INTERNET_CPID
3114 MALLOC_EMAIL(item); 3132 memcpy(&(item->internet_cpid), list->items[x]->data, sizeof(item->internet_cpid));
3115 memcpy(&(item->email->internet_cpid), list->items[x]->data, sizeof(item->email->internet_cpid)); 3133 LE32_CPU(item->internet_cpid);
3116 LE32_CPU(item->email->internet_cpid); 3134 t = item->internet_cpid;
3117 t = item->email->internet_cpid;
3118 DEBUG_EMAIL(("Internet code page %i\n", (int)t)); 3135 DEBUG_EMAIL(("Internet code page %i\n", (int)t));
3119 break; 3136 break;
3120 case 0x3FFD: // PR_MESSAGE_CODEPAGE 3137 case 0x3FFD: // PR_MESSAGE_CODEPAGE
3121 MALLOC_EMAIL(item); 3138 memcpy(&(item->message_codepage), list->items[x]->data, sizeof(item->message_codepage));
3122 memcpy(&(item->email->message_codepage), list->items[x]->data, sizeof(item->email->message_codepage)); 3139 LE32_CPU(item->message_codepage);
3123 LE32_CPU(item->email->message_codepage); 3140 t = item->message_codepage;
3124 t = item->email->message_codepage;
3125 DEBUG_EMAIL(("Message code page %i\n", (int)t)); 3141 DEBUG_EMAIL(("Message code page %i\n", (int)t));
3126 break; 3142 break;
3127 case 0x65E3: // Entry ID? 3143 case 0x65E3: // Entry ID?
3128 DEBUG_EMAIL(("Entry ID - ")); 3144 DEBUG_EMAIL(("Entry ID - "));
3129 item->record_key = (char*) xmalloc(16+1); 3145 item->record_key = (char*) xmalloc(16+1);
3661 } 3677 }
3662 DEBUG_RET(); 3678 DEBUG_RET();
3663 } 3679 }
3664 3680
3665 3681
3666 void pst_free_id2(pst_index2_ll * head) { 3682 void pst_free_id2(pst_id2_ll * head) {
3667 pst_index2_ll *t; 3683 pst_id2_ll *t;
3668 DEBUG_ENT("pst_free_id2"); 3684 DEBUG_ENT("pst_free_id2");
3669 while (head) { 3685 while (head) {
3670 if (head->child) pst_free_id2(head->child); 3686 if (head->child) pst_free_id2(head->child);
3671 t = head->next; 3687 t = head->next;
3672 free(head); 3688 free(head);
3723 } 3739 }
3724 DEBUG_RET(); 3740 DEBUG_RET();
3725 } 3741 }
3726 3742
3727 3743
3728 pst_index2_ll * pst_build_id2(pst_file *pf, pst_index_ll* list) { 3744 pst_id2_ll * pst_build_id2(pst_file *pf, pst_index_ll* list) {
3729 pst_block_header block_head; 3745 pst_block_header block_head;
3730 pst_index2_ll *head = NULL, *tail = NULL; 3746 pst_id2_ll *head = NULL, *tail = NULL;
3731 uint16_t x = 0; 3747 uint16_t x = 0;
3732 char *b_ptr = NULL; 3748 char *b_ptr = NULL;
3733 char *buf = NULL; 3749 char *buf = NULL;
3734 pst_id2_assoc id2_rec; 3750 pst_id2_assoc id2_rec;
3735 pst_index_ll *i_ptr = NULL; 3751 pst_index_ll *i_ptr = NULL;
3736 pst_index2_ll *i2_ptr = NULL; 3752 pst_id2_ll *i2_ptr = NULL;
3737 DEBUG_ENT("pst_build_id2"); 3753 DEBUG_ENT("pst_build_id2");
3738 3754
3739 if (pst_read_block_size(pf, list->offset, list->size, &buf) < list->size) { 3755 if (pst_read_block_size(pf, list->offset, list->size, &buf) < list->size) {
3740 //an error occured in block read 3756 //an error occured in block read
3741 WARN(("block read error occured. offset = %#"PRIx64", size = %#"PRIx64"\n", list->offset, list->size)); 3757 WARN(("block read error occured. offset = %#"PRIx64", size = %#"PRIx64"\n", list->offset, list->size));
3760 list->id, block_head.count, list->offset)); 3776 list->id, block_head.count, list->offset));
3761 x = 0; 3777 x = 0;
3762 b_ptr = buf + ((pf->do_read64) ? 0x08 : 0x04); 3778 b_ptr = buf + ((pf->do_read64) ? 0x08 : 0x04);
3763 while (x < block_head.count) { 3779 while (x < block_head.count) {
3764 b_ptr += pst_decode_assoc(pf, &id2_rec, b_ptr); 3780 b_ptr += pst_decode_assoc(pf, &id2_rec, b_ptr);
3765 DEBUG_INDEX(("id2 = %#x, id = %#"PRIx64", table2 = %#"PRIx64"\n", id2_rec.id2, id2_rec.id, id2_rec.table2)); 3781 DEBUG_INDEX(("id2 = %#x, id = %#"PRIx64", child id = %#"PRIx64"\n", id2_rec.id2, id2_rec.id, id2_rec.child_id));
3766 if ((i_ptr = pst_getID(pf, id2_rec.id)) == NULL) { 3782 if ((i_ptr = pst_getID(pf, id2_rec.id)) == NULL) {
3767 DEBUG_WARN(("%#"PRIx64" - Not Found\n", id2_rec.id)); 3783 DEBUG_WARN(("%#"PRIx64" - Not Found\n", id2_rec.id));
3768 } else { 3784 } else {
3769 DEBUG_INDEX(("%#"PRIx64" - Offset %#"PRIx64", u1 %#"PRIx64", Size %"PRIi64"(%#"PRIx64")\n", 3785 DEBUG_INDEX(("%#"PRIx64" - Offset %#"PRIx64", u1 %#"PRIx64", Size %"PRIi64"(%#"PRIx64")\n",
3770 i_ptr->id, i_ptr->offset, i_ptr->u1, i_ptr->size, i_ptr->size)); 3786 i_ptr->id, i_ptr->offset, i_ptr->u1, i_ptr->size, i_ptr->size));
3771 // add it to the tree 3787 // add it to the tree
3772 i2_ptr = (pst_index2_ll*) xmalloc(sizeof(pst_index2_ll)); 3788 i2_ptr = (pst_id2_ll*) xmalloc(sizeof(pst_id2_ll));
3773 i2_ptr->id2 = id2_rec.id2; 3789 i2_ptr->id2 = id2_rec.id2;
3774 i2_ptr->id = i_ptr; 3790 i2_ptr->id = i_ptr;
3775 i2_ptr->child = NULL; 3791 i2_ptr->child = NULL;
3776 i2_ptr->next = NULL; 3792 i2_ptr->next = NULL;
3777 if (!head) head = i2_ptr; 3793 if (!head) head = i2_ptr;
3778 if (tail) tail->next = i2_ptr; 3794 if (tail) tail->next = i2_ptr;
3779 tail = i2_ptr; 3795 tail = i2_ptr;
3780 if (id2_rec.table2) { 3796 if (id2_rec.child_id) {
3781 if ((i_ptr = pst_getID(pf, id2_rec.table2)) == NULL) { 3797 if ((i_ptr = pst_getID(pf, id2_rec.child_id)) == NULL) {
3782 DEBUG_WARN(("Table2 [%#"PRIi64"] not found\n", id2_rec.table2)); 3798 DEBUG_WARN(("child id [%#"PRIi64"] not found\n", id2_rec.child_id));
3783 } 3799 }
3784 else { 3800 else {
3785 DEBUG_INDEX(("Going deeper for table2 [%#"PRIi64"]\n", id2_rec.table2));
3786 i2_ptr->child = pst_build_id2(pf, i_ptr); 3801 i2_ptr->child = pst_build_id2(pf, i_ptr);
3787 } 3802 }
3788 } 3803 }
3789 } 3804 }
3790 x++; 3805 x++;
3816 DEBUG_ENT("pst_freeItem"); 3831 DEBUG_ENT("pst_freeItem");
3817 if (item) { 3832 if (item) {
3818 if (item->email) { 3833 if (item->email) {
3819 SAFE_FREE(item->email->arrival_date); 3834 SAFE_FREE(item->email->arrival_date);
3820 SAFE_FREE(item->email->body); 3835 SAFE_FREE(item->email->body);
3821 SAFE_FREE(item->email->body_charset);
3822 SAFE_FREE(item->email->cc_address); 3836 SAFE_FREE(item->email->cc_address);
3823 SAFE_FREE(item->email->bcc_address); 3837 SAFE_FREE(item->email->bcc_address);
3824 SAFE_FREE(item->email->common_name); 3838 SAFE_FREE(item->email->common_name);
3825 SAFE_FREE(item->email->encrypted_body); 3839 SAFE_FREE(item->email->encrypted_body);
3826 SAFE_FREE(item->email->encrypted_htmlbody); 3840 SAFE_FREE(item->email->encrypted_htmlbody);
4001 SAFE_FREE(item->appointment->recurrence_start); 4015 SAFE_FREE(item->appointment->recurrence_start);
4002 SAFE_FREE(item->appointment->recurrence_end); 4016 SAFE_FREE(item->appointment->recurrence_end);
4003 free(item->appointment); 4017 free(item->appointment);
4004 } 4018 }
4005 SAFE_FREE(item->ascii_type); 4019 SAFE_FREE(item->ascii_type);
4020 SAFE_FREE(item->body_charset);
4006 SAFE_FREE(item->comment); 4021 SAFE_FREE(item->comment);
4007 SAFE_FREE(item->create_date); 4022 SAFE_FREE(item->create_date);
4008 SAFE_FREE(item->file_as); 4023 SAFE_FREE(item->file_as);
4009 SAFE_FREE(item->modify_date); 4024 SAFE_FREE(item->modify_date);
4010 SAFE_FREE(item->outlook_version); 4025 SAFE_FREE(item->outlook_version);
4019 * The offset might be zero, in which case we have no data, so return a pair of null pointers. 4034 * The offset might be zero, in which case we have no data, so return a pair of null pointers.
4020 * Or, the offset might end in 0xf, so it is an id2 pointer, in which case we read the id2 block. 4035 * Or, the offset might end in 0xf, so it is an id2 pointer, in which case we read the id2 block.
4021 * Otherwise, the high order 16 bits of offset is the index into the subblocks, and 4036 * Otherwise, the high order 16 bits of offset is the index into the subblocks, and
4022 * the (low order 16 bits of offset)>>4 is an index into the table of offsets in the subblock. 4037 * the (low order 16 bits of offset)>>4 is an index into the table of offsets in the subblock.
4023 */ 4038 */
4024 int pst_getBlockOffsetPointer(pst_file *pf, pst_index2_ll *i2_head, pst_subblocks *subblocks, uint32_t offset, pst_block_offset_pointer *p) { 4039 int pst_getBlockOffsetPointer(pst_file *pf, pst_id2_ll *i2_head, pst_subblocks *subblocks, uint32_t offset, pst_block_offset_pointer *p) {
4025 size_t size; 4040 size_t size;
4026 pst_block_offset block_offset; 4041 pst_block_offset block_offset;
4027 DEBUG_ENT("pst_getBlockOffsetPointer"); 4042 DEBUG_ENT("pst_getBlockOffsetPointer");
4028 if (p->needfree) free(p->from); 4043 if (p->needfree) free(p->from);
4029 p->from = NULL; 4044 p->from = NULL;
4114 DEBUG_RET(); 4129 DEBUG_RET();
4115 return ptr; 4130 return ptr;
4116 } 4131 }
4117 4132
4118 4133
4119 pst_index2_ll *pst_getID2(pst_index2_ll *head, uint64_t id2) { 4134 pst_id2_ll *pst_getID2(pst_id2_ll *head, uint64_t id2) {
4120 DEBUG_ENT("pst_getID2"); 4135 DEBUG_ENT("pst_getID2");
4121 DEBUG_INDEX(("looking for id2 = %#"PRIx64"\n", id2)); 4136 DEBUG_INDEX(("looking for id2 = %#"PRIx64"\n", id2));
4122 pst_index2_ll *ptr = head; 4137 pst_id2_ll *ptr = head;
4123 while (ptr) { 4138 while (ptr) {
4124 if (ptr->id2 == id2) break; 4139 if (ptr->id2 == id2) break;
4125 if (ptr->child) { 4140 if (ptr->child) {
4126 pst_index2_ll *rc = pst_getID2(ptr->child, id2); 4141 pst_id2_ll *rc = pst_getID2(ptr->child, id2);
4127 if (rc) { 4142 if (rc) {
4128 DEBUG_RET(); 4143 DEBUG_RET();
4129 return rc; 4144 return rc;
4130 } 4145 }
4131 } 4146 }
4144 4159
4145 /** 4160 /**
4146 * find the id in the descriptor tree rooted at pf->d_head 4161 * find the id in the descriptor tree rooted at pf->d_head
4147 * 4162 *
4148 * @param pf global pst file pointer 4163 * @param pf global pst file pointer
4149 * @param id the id we are looking for 4164 * @param d_id the id we are looking for
4150 * 4165 *
4151 * @return pointer to the pst_desc_ll node in the descriptor tree 4166 * @return pointer to the pst_desc_ll node in the descriptor tree
4152 */ 4167 */
4153 pst_desc_ll* pst_getDptr(pst_file *pf, uint64_t id) { 4168 pst_desc_ll* pst_getDptr(pst_file *pf, uint64_t d_id) {
4154 pst_desc_ll *ptr = pf->d_head; 4169 pst_desc_ll *ptr = pf->d_head;
4155 DEBUG_ENT("pst_getDptr"); 4170 DEBUG_ENT("pst_getDptr");
4156 while (ptr && (ptr->id != id)) { 4171 while (ptr && (ptr->d_id != d_id)) {
4157 //DEBUG_INDEX(("Looking for %#"PRIx64" at node %#"PRIx64" with parent %#"PRIx64"\n", id, ptr->id, ptr->parent_id)); 4172 //DEBUG_INDEX(("Looking for %#"PRIx64" at node %#"PRIx64" with parent %#"PRIx64"\n", id, ptr->d_id, ptr->parent_d_id));
4158 if (ptr->child) { 4173 if (ptr->child) {
4159 ptr = ptr->child; 4174 ptr = ptr->child;
4160 continue; 4175 continue;
4161 } 4176 }
4162 while (!ptr->next && ptr->parent) { 4177 while (!ptr->next && ptr->parent) {
4170 4185
4171 4186
4172 void pst_printDptr(pst_file *pf, pst_desc_ll *ptr) { 4187 void pst_printDptr(pst_file *pf, pst_desc_ll *ptr) {
4173 DEBUG_ENT("pst_printDptr"); 4188 DEBUG_ENT("pst_printDptr");
4174 while (ptr) { 4189 while (ptr) {
4175 DEBUG_INDEX(("%#"PRIx64" [%i] desc=%#"PRIx64", list=%#"PRIx64"\n", ptr->id, ptr->no_child, 4190 DEBUG_INDEX(("%#"PRIx64" [%i] desc=%#"PRIx64", assoc tree=%#"PRIx64"\n", ptr->d_id, ptr->no_child,
4176 (ptr->desc ? ptr->desc->id : (uint64_t)0), 4191 (ptr->desc ? ptr->desc->id : (uint64_t)0),
4177 (ptr->list_index ? ptr->list_index->id : (uint64_t)0))); 4192 (ptr->assoc_tree ? ptr->assoc_tree->id : (uint64_t)0)));
4178 if (ptr->child) { 4193 if (ptr->child) {
4179 pst_printDptr(pf, ptr->child); 4194 pst_printDptr(pf, ptr->child);
4180 } 4195 }
4181 ptr = ptr->next; 4196 ptr = ptr->next;
4182 } 4197 }
4193 } 4208 }
4194 DEBUG_RET(); 4209 DEBUG_RET();
4195 } 4210 }
4196 4211
4197 4212
4198 void pst_printID2ptr(pst_index2_ll *ptr) { 4213 void pst_printID2ptr(pst_id2_ll *ptr) {
4199 DEBUG_ENT("pst_printID2ptr"); 4214 DEBUG_ENT("pst_printID2ptr");
4200 while (ptr) { 4215 while (ptr) {
4201 DEBUG_INDEX(("%#"PRIx64" id=%#"PRIx64"\n", ptr->id2, (ptr->id ? ptr->id->id : (uint64_t)0))); 4216 DEBUG_INDEX(("%#"PRIx64" id=%#"PRIx64"\n", ptr->id2, (ptr->id ? ptr->id->id : (uint64_t)0)));
4202 if (ptr->child) pst_printID2ptr(ptr->child); 4217 if (ptr->child) pst_printID2ptr(ptr->child);
4203 ptr = ptr->next; 4218 ptr = ptr->next;
4415 return rsize; 4430 return rsize;
4416 } 4431 }
4417 4432
4418 4433
4419 #define PST_PTR_BLOCK_SIZE 0x120 4434 #define PST_PTR_BLOCK_SIZE 0x120
4420 size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_index2_ll *id2_head, char** buf) { 4435 size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_id2_ll *id2_head, char** buf) {
4421 size_t ret; 4436 size_t ret;
4422 pst_index2_ll* ptr; 4437 pst_id2_ll* ptr;
4423 pst_holder h = {buf, NULL, 0}; 4438 pst_holder h = {buf, NULL, 0};
4424 DEBUG_ENT("pst_ff_getID2block"); 4439 DEBUG_ENT("pst_ff_getID2block");
4425 ptr = pst_getID2(id2_head, id2); 4440 ptr = pst_getID2(id2_head, id2);
4426 4441
4427 if (!ptr) { 4442 if (!ptr) {