Mercurial > libpst
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) { |