Mercurial > libpst
comparison src/libpst.c @ 52:034641c26ab9
code cleanup
author | carl |
---|---|
date | Thu, 31 Jan 2008 08:03:30 -0800 |
parents | 06c0262ad689 |
children | a8b772313ff4 |
comparison
equal
deleted
inserted
replaced
51:06c0262ad689 | 52:034641c26ab9 |
---|---|
38 #define FILE_SIZE_POINTER32 (off_t)0xA8 | 38 #define FILE_SIZE_POINTER32 (off_t)0xA8 |
39 #define INDEX_POINTER32 (off_t)0xC4 | 39 #define INDEX_POINTER32 (off_t)0xC4 |
40 #define INDEX_BACK32 (off_t)0xC0 | 40 #define INDEX_BACK32 (off_t)0xC0 |
41 #define SECOND_POINTER32 (off_t)0xBC | 41 #define SECOND_POINTER32 (off_t)0xBC |
42 #define SECOND_BACK32 (off_t)0xB8 | 42 #define SECOND_BACK32 (off_t)0xB8 |
43 #define ENC_OFFSET32 (off_t)0x1CD | 43 #define ENC_TYPE32 (off_t)0x1CD |
44 | 44 |
45 #define FILE_SIZE_POINTER64 (off_t)0xB8 | 45 #define FILE_SIZE_POINTER64 (off_t)0xB8 |
46 #define INDEX_POINTER64 (off_t)0xF0 | 46 #define INDEX_POINTER64 (off_t)0xF0 |
47 #define INDEX_BACK64 (off_t)0xE8 | 47 #define INDEX_BACK64 (off_t)0xE8 |
48 #define SECOND_POINTER64 (off_t)0xE0 | 48 #define SECOND_POINTER64 (off_t)0xE0 |
49 #define SECOND_BACK64 (off_t)0xD8 | 49 #define SECOND_BACK64 (off_t)0xD8 |
50 #define ENC_OFFSET64 (off_t)0x201 | 50 #define ENC_TYPE64 (off_t)0x201 |
51 | 51 |
52 #define FILE_SIZE_POINTER ((pf->do_read64) ? FILE_SIZE_POINTER64 : FILE_SIZE_POINTER32) | 52 #define FILE_SIZE_POINTER ((pf->do_read64) ? FILE_SIZE_POINTER64 : FILE_SIZE_POINTER32) |
53 #define INDEX_POINTER ((pf->do_read64) ? INDEX_POINTER64 : INDEX_POINTER32) | 53 #define INDEX_POINTER ((pf->do_read64) ? INDEX_POINTER64 : INDEX_POINTER32) |
54 #define INDEX_BACK ((pf->do_read64) ? INDEX_BACK64 : INDEX_BACK32) | 54 #define INDEX_BACK ((pf->do_read64) ? INDEX_BACK64 : INDEX_BACK32) |
55 #define SECOND_POINTER ((pf->do_read64) ? SECOND_POINTER64 : SECOND_POINTER32) | 55 #define SECOND_POINTER ((pf->do_read64) ? SECOND_POINTER64 : SECOND_POINTER32) |
56 #define SECOND_BACK ((pf->do_read64) ? SECOND_BACK64 : SECOND_BACK32) | 56 #define SECOND_BACK ((pf->do_read64) ? SECOND_BACK64 : SECOND_BACK32) |
57 #define ENC_OFFSET ((pf->do_read64) ? ENC_OFFSET64 : ENC_OFFSET32) | 57 #define ENC_TYPE ((pf->do_read64) ? ENC_TYPE64 : ENC_TYPE32) |
58 | 58 |
59 #define PST_SIGNATURE 0x4E444221 | 59 #define PST_SIGNATURE 0x4E444221 |
60 | 60 |
61 | 61 |
62 struct pst_table_ptr_struct32{ | 62 struct pst_table_ptr_struct32{ |
174 DEBUG_RET(); | 174 DEBUG_RET(); |
175 return -1; | 175 return -1; |
176 } | 176 } |
177 | 177 |
178 // Check pst file magic | 178 // Check pst file magic |
179 if (fread(&sig, sizeof(sig), (size_t)1, pf->fp) == 0) { | 179 if (pst_getAtPos(pf, 0, &sig, sizeof(sig)) != sizeof(sig)) { |
180 (void)fclose(pf->fp); | 180 (void)fclose(pf->fp); |
181 WARN(("cannot read signature from PST file. Closing on error\n")); | 181 WARN(("cannot read signature from PST file. Closing on error\n")); |
182 DEBUG_RET(); | 182 DEBUG_RET(); |
183 return -1; | 183 return -1; |
184 } | 184 } |
190 DEBUG_RET(); | 190 DEBUG_RET(); |
191 return -1; | 191 return -1; |
192 } | 192 } |
193 | 193 |
194 // read index type | 194 // read index type |
195 (void)pst_getAtPos(pf->fp, INDEX_TYPE_OFFSET, &(pf->ind_type), sizeof(pf->ind_type)); | 195 (void)pst_getAtPos(pf, INDEX_TYPE_OFFSET, &(pf->ind_type), sizeof(pf->ind_type)); |
196 DEBUG_INFO(("index_type = %i\n", pf->ind_type)); | 196 DEBUG_INFO(("index_type = %i\n", pf->ind_type)); |
197 switch (pf->ind_type) { | 197 switch (pf->ind_type) { |
198 case INDEX_TYPE32 : | 198 case INDEX_TYPE32 : |
199 pf->do_read64 = 0; | 199 pf->do_read64 = 0; |
200 break; | 200 break; |
206 DEBUG_RET(); | 206 DEBUG_RET(); |
207 return -1; | 207 return -1; |
208 } | 208 } |
209 | 209 |
210 // read encryption setting | 210 // read encryption setting |
211 (void)pst_getAtPos(pf->fp, ENC_OFFSET, &(pf->encryption), sizeof(pf->encryption)); | 211 (void)pst_getAtPos(pf, ENC_TYPE, &(pf->encryption), sizeof(pf->encryption)); |
212 DEBUG_INFO(("encrypt = %i\n", pf->encryption)); | 212 DEBUG_INFO(("encrypt = %i\n", pf->encryption)); |
213 | 213 |
214 pf->index2_back = pst_getIntAtPos(pf, SECOND_BACK); | 214 pf->index2_back = pst_getIntAtPos(pf, SECOND_BACK); |
215 pf->index2 = pst_getIntAtPos(pf, SECOND_POINTER); | 215 pf->index2 = pst_getIntAtPos(pf, SECOND_POINTER); |
216 pf->size = pst_getIntAtPos(pf, FILE_SIZE_POINTER); | 216 pf->size = pst_getIntAtPos(pf, FILE_SIZE_POINTER); |
262 DEBUG_RET(); | 262 DEBUG_RET(); |
263 return ret; | 263 return ret; |
264 } | 264 } |
265 | 265 |
266 | 266 |
267 size_t pst_attach_to_mem(pst_file *pf, pst_item_attach *attach, unsigned char **b){ | 267 size_t pst_attach_to_mem(pst_file *pf, pst_item_attach *attach, char **b){ |
268 size_t size=0; | 268 size_t size=0; |
269 pst_index_ll *ptr; | 269 pst_index_ll *ptr; |
270 pst_holder h = {b, NULL, 0, "", 0}; | 270 pst_holder h = {b, NULL, 0, "", 0}; |
271 DEBUG_ENT("pst_attach_to_mem"); | 271 DEBUG_ENT("pst_attach_to_mem"); |
272 if (attach->id_val != (uint64_t)-1) { | 272 if (attach->id_val != (uint64_t)-1) { |
393 int pst_load_extended_attributes(pst_file *pf) { | 393 int pst_load_extended_attributes(pst_file *pf) { |
394 // for PST files this will load up ID2 0x61 and check it's "list" attribute. | 394 // for PST files this will load up ID2 0x61 and check it's "list" attribute. |
395 pst_desc_ll *p; | 395 pst_desc_ll *p; |
396 pst_num_array *na; | 396 pst_num_array *na; |
397 pst_index2_ll *id2_head = NULL; | 397 pst_index2_ll *id2_head = NULL; |
398 unsigned char *buffer=NULL, *headerbuffer=NULL; | 398 char *buffer=NULL, *headerbuffer=NULL; |
399 size_t bsize=0, hsize=0, bptr=0; | 399 size_t bsize=0, hsize=0, bptr=0; |
400 pst_x_attrib xattrib; | 400 pst_x_attrib xattrib; |
401 int32_t tint, err=0, x; | 401 int32_t tint, err=0, x; |
402 pst_x_attrib_ll *ptr, *p_head=NULL, *p_sh=NULL, *p_sh2=NULL; | 402 pst_x_attrib_ll *ptr, *p_head=NULL, *p_sh=NULL, *p_sh2=NULL; |
403 | 403 |
404 DEBUG_ENT("pst_loadExtendedAttributes"); | 404 DEBUG_ENT("pst_loadExtendedAttributes"); |
405 if ((p = pst_getDptr(pf, (uint64_t)0x61)) == NULL) { | 405 p = pst_getDptr(pf, (uint64_t)0x61); |
406 if (!p) { | |
406 DEBUG_WARN(("Cannot find DescID 0x61 for loading the Extended Attributes\n")); | 407 DEBUG_WARN(("Cannot find DescID 0x61 for loading the Extended Attributes\n")); |
407 DEBUG_RET(); | 408 DEBUG_RET(); |
408 return 0; | 409 return 0; |
409 } | 410 } |
410 | 411 |
525 pf->x_head = p_head; | 526 pf->x_head = p_head; |
526 DEBUG_RET(); | 527 DEBUG_RET(); |
527 return 1; | 528 return 1; |
528 } | 529 } |
529 | 530 |
530 #define BLOCK_SIZE32 516 // index blocks | 531 |
531 #define DESC_BLOCK_SIZE32 516 // descriptor blocks | |
532 #define ITEM_COUNT_OFFSET32 0x1f0 // count byte | 532 #define ITEM_COUNT_OFFSET32 0x1f0 // count byte |
533 #define LEVEL_INDICATOR_OFFSET32 0x1f3 // node or leaf | 533 #define LEVEL_INDICATOR_OFFSET32 0x1f3 // node or leaf |
534 #define BACKLINK_OFFSET32 0x1f8 // backlink u1 value | 534 #define BACKLINK_OFFSET32 0x1f8 // backlink u1 value |
535 #define ITEM_SIZE32 12 | 535 #define ITEM_SIZE32 12 |
536 #define DESC_SIZE32 16 | 536 #define DESC_SIZE32 16 |
537 #define INDEX_COUNT_MAX32 41 // max active items | 537 #define INDEX_COUNT_MAX32 41 // max active items |
538 #define DESC_COUNT_MAX32 31 // max active items | 538 #define DESC_COUNT_MAX32 31 // max active items |
539 | 539 |
540 #define BLOCK_SIZE64 512 // index blocks | |
541 #define DESC_BLOCK_SIZE64 512 // descriptor blocks | |
542 #define ITEM_COUNT_OFFSET64 0x1e8 // count byte | 540 #define ITEM_COUNT_OFFSET64 0x1e8 // count byte |
543 #define LEVEL_INDICATOR_OFFSET64 0x1eb // node or leaf | 541 #define LEVEL_INDICATOR_OFFSET64 0x1eb // node or leaf |
544 #define BACKLINK_OFFSET64 0x1f8 // backlink u1 value | 542 #define BACKLINK_OFFSET64 0x1f8 // backlink u1 value |
545 #define ITEM_SIZE64 24 | 543 #define ITEM_SIZE64 24 |
546 #define DESC_SIZE64 32 | 544 #define DESC_SIZE64 32 |
547 #define INDEX_COUNT_MAX64 20 // max active items | 545 #define INDEX_COUNT_MAX64 20 // max active items |
548 #define DESC_COUNT_MAX64 15 // max active items | 546 #define DESC_COUNT_MAX64 15 // max active items |
549 | 547 |
550 #define BLOCK_SIZE (size_t)((pf->do_read64) ? BLOCK_SIZE64 : BLOCK_SIZE32) | 548 #define BLOCK_SIZE 512 // index blocks |
551 #define DESC_BLOCK_SIZE (size_t)((pf->do_read64) ? DESC_BLOCK_SIZE64 : DESC_BLOCK_SIZE32) | 549 #define DESC_BLOCK_SIZE 512 // descriptor blocks |
552 #define ITEM_COUNT_OFFSET (size_t)((pf->do_read64) ? ITEM_COUNT_OFFSET64 : ITEM_COUNT_OFFSET32) | 550 #define ITEM_COUNT_OFFSET (size_t)((pf->do_read64) ? ITEM_COUNT_OFFSET64 : ITEM_COUNT_OFFSET32) |
553 #define LEVEL_INDICATOR_OFFSET (size_t)((pf->do_read64) ? LEVEL_INDICATOR_OFFSET64 : LEVEL_INDICATOR_OFFSET32) | 551 #define LEVEL_INDICATOR_OFFSET (size_t)((pf->do_read64) ? LEVEL_INDICATOR_OFFSET64 : LEVEL_INDICATOR_OFFSET32) |
554 #define BACKLINK_OFFSET (size_t)((pf->do_read64) ? BACKLINK_OFFSET64 : BACKLINK_OFFSET32) | 552 #define BACKLINK_OFFSET (size_t)((pf->do_read64) ? BACKLINK_OFFSET64 : BACKLINK_OFFSET32) |
555 #define ITEM_SIZE (size_t)((pf->do_read64) ? ITEM_SIZE64 : ITEM_SIZE32) | 553 #define ITEM_SIZE (size_t)((pf->do_read64) ? ITEM_SIZE64 : ITEM_SIZE32) |
556 #define DESC_SIZE (size_t)((pf->do_read64) ? DESC_SIZE64 : DESC_SIZE32) | 554 #define DESC_SIZE (size_t)((pf->do_read64) ? DESC_SIZE64 : DESC_SIZE32) |
1294 if (p7->needfree) free(p7->from); | 1292 if (p7->needfree) free(p7->from); |
1295 } | 1293 } |
1296 | 1294 |
1297 | 1295 |
1298 pst_num_array * pst_parse_block(pst_file *pf, uint64_t block_id, pst_index2_ll *i2_head, pst_num_array *na_head) { | 1296 pst_num_array * pst_parse_block(pst_file *pf, uint64_t block_id, pst_index2_ll *i2_head, pst_num_array *na_head) { |
1299 unsigned char *buf = NULL; | 1297 char *buf = NULL; |
1300 size_t read_size = 0; | 1298 size_t read_size = 0; |
1301 pst_subblocks subblocks; | 1299 pst_subblocks subblocks; |
1302 pst_num_array *na_ptr = NULL; | 1300 pst_num_array *na_ptr = NULL; |
1303 pst_block_offset_pointer block_offset1; | 1301 pst_block_offset_pointer block_offset1; |
1304 pst_block_offset_pointer block_offset2; | 1302 pst_block_offset_pointer block_offset2; |
1305 pst_block_offset_pointer block_offset3; | 1303 pst_block_offset_pointer block_offset3; |
4003 DEBUG_RET(); | 4001 DEBUG_RET(); |
4004 return (p->from) ? 0 : 1; | 4002 return (p->from) ? 0 : 1; |
4005 } | 4003 } |
4006 | 4004 |
4007 | 4005 |
4008 int pst_getBlockOffset(unsigned char *buf, size_t read_size, uint32_t i_offset, uint32_t offset, pst_block_offset *p) { | 4006 int pst_getBlockOffset(char *buf, size_t read_size, uint32_t i_offset, uint32_t offset, pst_block_offset *p) { |
4009 uint32_t low = offset & 0xf; | 4007 uint32_t low = offset & 0xf; |
4010 uint32_t of1 = offset >> 4; | 4008 uint32_t of1 = offset >> 4; |
4011 DEBUG_ENT("pst_getBlockOffset"); | 4009 DEBUG_ENT("pst_getBlockOffset"); |
4012 if (!p || !buf || !i_offset || low || (i_offset+2+of1+sizeof(*p) > read_size)) { | 4010 if (!p || !buf || !i_offset || low || (i_offset+2+of1+sizeof(*p) > read_size)) { |
4013 DEBUG_WARN(("p is NULL or buf is NULL or offset is 0 or offset has low bits or beyond read size (%p, %p, %#x, %i, %i)\n", p, buf, offset, read_size, i_offset)); | 4011 DEBUG_WARN(("p is NULL or buf is NULL or offset is 0 or offset has low bits or beyond read size (%p, %p, %#x, %i, %i)\n", p, buf, offset, read_size, i_offset)); |
4019 LE16_CPU(p->from); | 4017 LE16_CPU(p->from); |
4020 LE16_CPU(p->to); | 4018 LE16_CPU(p->to); |
4021 DEBUG_WARN(("get block offset finds from=%i(%#x), to=%i(%#x)\n", p->from, p->from, p->to, p->to)); | 4019 DEBUG_WARN(("get block offset finds from=%i(%#x), to=%i(%#x)\n", p->from, p->from, p->to, p->to)); |
4022 if (p->from > p->to) { | 4020 if (p->from > p->to) { |
4023 DEBUG_WARN(("get block offset from > to")); | 4021 DEBUG_WARN(("get block offset from > to")); |
4022 DEBUG_RET(); | |
4024 return 0; | 4023 return 0; |
4025 } | 4024 } |
4026 DEBUG_RET(); | 4025 DEBUG_RET(); |
4027 return 1; | 4026 return 1; |
4028 } | 4027 } |
4052 } | 4051 } |
4053 | 4052 |
4054 | 4053 |
4055 pst_index_ll * pst_getID2(pst_index2_ll *ptr, uint64_t id) { | 4054 pst_index_ll * pst_getID2(pst_index2_ll *ptr, uint64_t id) { |
4056 DEBUG_ENT("pst_getID2"); | 4055 DEBUG_ENT("pst_getID2"); |
4057 DEBUG_INDEX(("Head = %p\n", ptr)); | 4056 DEBUG_INDEX(("Head = %p id = %#llx\n", ptr, id)); |
4058 DEBUG_INDEX(("Trying to find %#x\n", id)); | |
4059 while (ptr && (ptr->id2 != id)) { | 4057 while (ptr && (ptr->id2 != id)) { |
4060 ptr = ptr->next; | 4058 ptr = ptr->next; |
4061 } | 4059 } |
4062 if (ptr) { | 4060 if (ptr) { |
4063 if (ptr->id) {DEBUG_INDEX(("Found value %#llx\n", ptr->id->id)); } | 4061 if (ptr->id) {DEBUG_INDEX(("Found value %#llx\n", ptr->id->id)); } |
4131 } | 4129 } |
4132 DEBUG_RET(); | 4130 DEBUG_RET(); |
4133 } | 4131 } |
4134 | 4132 |
4135 | 4133 |
4134 /** | |
4135 * Read a block of data from file into memory | |
4136 * @param pf PST file | |
4137 * @param offset offset in the pst file of the data | |
4138 * @param size size of the block to be read | |
4139 * @param buf reference to pointer to buffer. If this pointer | |
4140 is non-NULL, it will first be free()d | |
4141 * @return size of block read into memory | |
4142 */ | |
4136 size_t pst_read_block_size(pst_file *pf, off_t offset, size_t size, char **buf) { | 4143 size_t pst_read_block_size(pst_file *pf, off_t offset, size_t size, char **buf) { |
4137 off_t fpos; | |
4138 size_t rsize; | 4144 size_t rsize; |
4139 | |
4140 DEBUG_ENT("pst_read_block_size"); | 4145 DEBUG_ENT("pst_read_block_size"); |
4141 DEBUG_READ(("Reading block from %#x, %i bytes\n", offset, size)); | 4146 DEBUG_READ(("Reading block from %#x, %i bytes\n", offset, size)); |
4142 | 4147 |
4143 fpos = ftell(pf->fp); | |
4144 (void)fseek(pf->fp, offset, SEEK_SET); | |
4145 if (*buf) { | 4148 if (*buf) { |
4146 DEBUG_READ(("Freeing old memory\n")); | 4149 DEBUG_READ(("Freeing old memory\n")); |
4147 free(*buf); | 4150 free(*buf); |
4148 } | 4151 } |
4149 | 4152 *buf = (char*) xmalloc(size); |
4150 *buf = (void*) xmalloc(size); | 4153 |
4151 rsize = fread(*buf, (size_t)1, size, pf->fp); | 4154 rsize = pst_getAtPos(pf, offset, *buf, size); |
4152 if (rsize != size) { | 4155 if (rsize != size) { |
4153 DEBUG_WARN(("Didn't read all that I could. fread returned less [%i instead of %i]\n", rsize, size)); | 4156 DEBUG_WARN(("Didn't read all the data. fread returned less [%i instead of %i]\n", rsize, size)); |
4154 if (feof(pf->fp)) { | 4157 if (feof(pf->fp)) { |
4155 DEBUG_WARN(("We tried to read past the end of the file at [offset %#x, size %#x]\n", offset, size)); | 4158 DEBUG_WARN(("We tried to read past the end of the file at [offset %#x, size %#x]\n", offset, size)); |
4156 } else if (ferror(pf->fp)) { | 4159 } else if (ferror(pf->fp)) { |
4157 DEBUG_WARN(("Error is set on file stream.\n")); | 4160 DEBUG_WARN(("Error is set on file stream.\n")); |
4158 } else { | 4161 } else { |
4159 DEBUG_WARN(("I can't tell why it failed\n")); | 4162 DEBUG_WARN(("I can't tell why it failed\n")); |
4160 } | 4163 } |
4161 size = rsize; | 4164 } |
4162 } | 4165 |
4163 | |
4164 (void)fseek(pf->fp, fpos, SEEK_SET); | |
4165 DEBUG_RET(); | 4166 DEBUG_RET(); |
4166 return size; | 4167 return rsize; |
4167 } | 4168 } |
4168 | 4169 |
4169 | 4170 |
4170 int pst_decrypt(unsigned char *buf, size_t size, unsigned char type) { | 4171 int pst_decrypt(unsigned char *buf, size_t size, unsigned char type) { |
4171 size_t x = 0; | 4172 size_t x = 0; |
4212 | 4213 |
4213 uint64_t pst_getIntAtPos(pst_file *pf, off_t pos ) { | 4214 uint64_t pst_getIntAtPos(pst_file *pf, off_t pos ) { |
4214 uint64_t buf64; | 4215 uint64_t buf64; |
4215 uint32_t buf32; | 4216 uint32_t buf32; |
4216 if (pf->do_read64) { | 4217 if (pf->do_read64) { |
4217 (void)pst_getAtPos(pf->fp, pos, &buf64, sizeof(buf64)); | 4218 (void)pst_getAtPos(pf, pos, &buf64, sizeof(buf64)); |
4218 LE64_CPU(buf64); | 4219 LE64_CPU(buf64); |
4219 return buf64; | 4220 return buf64; |
4220 } | 4221 } |
4221 else { | 4222 else { |
4222 (void)pst_getAtPos(pf->fp, pos, &buf32, sizeof(buf32)); | 4223 (void)pst_getAtPos(pf, pos, &buf32, sizeof(buf32)); |
4223 LE32_CPU(buf32); | 4224 LE32_CPU(buf32); |
4224 return buf32; | 4225 return buf32; |
4225 } | 4226 } |
4226 } | 4227 } |
4227 | 4228 |
4228 | 4229 /** |
4229 int pst_getAtPos(FILE *fp, off_t pos, void* buf, size_t size) { | 4230 * Read part of the pst file. |
4231 * | |
4232 * @param pf PST file structure | |
4233 * @param pos offset of the data in the pst file | |
4234 * @param buf buffer to contain the data | |
4235 * @param size size of the buffer and the amount of data to be read | |
4236 * @return actual read size, 0 if seek error | |
4237 */ | |
4238 | |
4239 size_t pst_getAtPos(pst_file *pf, off_t pos, void* buf, size_t size) { | |
4240 size_t rc; | |
4230 DEBUG_ENT("pst_getAtPos"); | 4241 DEBUG_ENT("pst_getAtPos"); |
4231 if (fseek(fp, pos, SEEK_SET) == -1) { | 4242 // pst_block_recorder **t = &pf->block_head; |
4243 // pst_block_recorder *p = pf->block_head; | |
4244 // while (p && ((p->offset+p->size) <= pos)) { | |
4245 // t = &p->next; | |
4246 // p = p->next; | |
4247 // } | |
4248 // if (p && (p->offset <= pos) && (pos < (p->offset+p->size))) { | |
4249 // // bump the count | |
4250 // p->readcount++; | |
4251 // } else { | |
4252 // // add a new block | |
4253 // pst_block_recorder *tail = *t; | |
4254 // p = (pst_block_recorder*)xmalloc(sizeof(*p)); | |
4255 // *t = p; | |
4256 // p->next = tail; | |
4257 // p->offset = pos; | |
4258 // p->size = size; | |
4259 // p->readcount = 1; | |
4260 // } | |
4261 // DEBUG_MAIN(("pst file old offset %#llx old size %#x read count %i offset %#llx size %#x\n", | |
4262 // p->offset, p->size, p->readcount, pos, size)); | |
4263 | |
4264 if (fseek(pf->fp, pos, SEEK_SET) == -1) { | |
4232 DEBUG_RET(); | 4265 DEBUG_RET(); |
4233 return 1; | 4266 return 0; |
4234 } | 4267 } |
4235 if (fread(buf, (size_t)1, size, fp) < size) { | 4268 rc = fread(buf, (size_t)1, size, pf->fp); |
4236 DEBUG_RET(); | |
4237 return 2; | |
4238 } | |
4239 DEBUG_RET(); | 4269 DEBUG_RET(); |
4240 return 0; | 4270 return rc; |
4241 } | 4271 } |
4242 | 4272 |
4243 | 4273 |
4244 /** | 4274 /** |
4245 * Get an ID block from file using _pst_ff_getIDblock and decrypt if necessary | 4275 * Get an ID block from file using _pst_ff_getIDblock and decrypt if necessary |
4246 * @param pf PST file structure | 4276 * |
4247 * @param id ID of block to retrieve | 4277 * @param pf PST file structure |
4248 * @param b Reference to pointer that will be set to new block. Any memory | 4278 * @param id ID of block to retrieve |
4249 pointed to by buffer will be free()d beforehand | 4279 * @param buf Reference to pointer that will be set to new block. Any memory |
4250 * @return Size of block pointed to by *b | 4280 pointed to by buffer will be free()d beforehand |
4281 * @return Size of block pointed to by *b | |
4251 */ | 4282 */ |
4252 size_t pst_ff_getIDblock_dec(pst_file *pf, uint64_t id, unsigned char **b) { | 4283 size_t pst_ff_getIDblock_dec(pst_file *pf, uint64_t id, char **buf) { |
4253 size_t r; | 4284 size_t r; |
4254 int noenc = (int)(id & 2); // disable encryption | 4285 int noenc = (int)(id & 2); // disable encryption |
4255 DEBUG_ENT("pst_ff_getIDblock_dec"); | 4286 DEBUG_ENT("pst_ff_getIDblock_dec"); |
4256 DEBUG_INDEX(("for id %#x\n", id)); | 4287 DEBUG_INDEX(("for id %#x\n", id)); |
4257 r = pst_ff_getIDblock(pf, id, b); | 4288 r = pst_ff_getIDblock(pf, id, buf); |
4258 if ((pf->encryption) && !(noenc)) { | 4289 if ((pf->encryption) && !(noenc)) { |
4259 (void)pst_decrypt(*b, r, pf->encryption); | 4290 (void)pst_decrypt(*buf, r, pf->encryption); |
4260 } | 4291 } |
4261 DEBUG_HEXDUMPC(*b, r, 16); | 4292 DEBUG_HEXDUMPC(*buf, r, 16); |
4262 DEBUG_RET(); | 4293 DEBUG_RET(); |
4263 return r; | 4294 return r; |
4264 } | 4295 } |
4265 | 4296 |
4266 | 4297 |
4267 /** | 4298 /** |
4268 * Read a block of data from file into memory | 4299 * Read a block of data from file into memory |
4269 * @param pf PST file | 4300 * @param pf PST file |
4270 * @param id identifier of block to read | 4301 * @param id identifier of block to read |
4271 * @param b reference to pointer to buffer. If this pointer | 4302 * @param buf reference to pointer to buffer. If this pointer |
4272 is non-NULL, it will first be free()d | 4303 is non-NULL, it will first be free()d |
4273 * @return size of block read into memory | 4304 * @return size of block read into memory |
4274 */ | 4305 */ |
4275 size_t pst_ff_getIDblock(pst_file *pf, uint64_t id, unsigned char** b) { | 4306 size_t pst_ff_getIDblock(pst_file *pf, uint64_t id, char** buf) { |
4276 pst_index_ll *rec; | 4307 pst_index_ll *rec; |
4277 size_t rsize = 0; | 4308 size_t rsize; |
4278 DEBUG_ENT("pst_ff_getIDblock"); | 4309 DEBUG_ENT("pst_ff_getIDblock"); |
4279 if ((rec = pst_getID(pf, id)) == NULL) { | 4310 rec = pst_getID(pf, id); |
4311 if (!rec) { | |
4280 DEBUG_INDEX(("Cannot find ID %#llx\n", id)); | 4312 DEBUG_INDEX(("Cannot find ID %#llx\n", id)); |
4281 DEBUG_RET(); | 4313 DEBUG_RET(); |
4282 return 0; | 4314 return 0; |
4283 } | 4315 } |
4284 (void)fseek(pf->fp, rec->offset, SEEK_SET); | |
4285 if (*b) { | |
4286 DEBUG_INDEX(("freeing old memory in b\n")); | |
4287 free(*b); | |
4288 } | |
4289 | |
4290 DEBUG_INDEX(("id = %#llx, record size = %#x, offset = %#x\n", id, rec->size, rec->offset)); | 4316 DEBUG_INDEX(("id = %#llx, record size = %#x, offset = %#x\n", id, rec->size, rec->offset)); |
4291 *b = (char*) xmalloc(rec->size+1); | 4317 rsize = pst_read_block_size(pf, rec->offset, rec->size, buf); |
4292 rsize = fread(*b, (size_t)1, rec->size, pf->fp); | |
4293 if (rsize != rec->size) { | |
4294 DEBUG_WARN(("Didn't read all the size. fread returned less [%i instead of %i]\n", rsize, rec->size)); | |
4295 if (feof(pf->fp)) { | |
4296 DEBUG_WARN(("We tried to read past the end of the file [offset %#x, size %#x]\n", rec->offset, rec->size)); | |
4297 } else if (ferror(pf->fp)) { | |
4298 DEBUG_WARN(("Some error occured on the file stream\n")); | |
4299 } else { | |
4300 DEBUG_WARN(("No error has been set on the file stream\n")); | |
4301 } | |
4302 } | |
4303 DEBUG_RET(); | 4318 DEBUG_RET(); |
4304 return rsize; | 4319 return rsize; |
4305 } | 4320 } |
4306 | 4321 |
4307 | 4322 |
4308 #define PST_PTR_BLOCK_SIZE 0x120 | 4323 #define PST_PTR_BLOCK_SIZE 0x120 |
4309 size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_index2_ll *id2_head, unsigned char** buf) { | 4324 size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_index2_ll *id2_head, char** buf) { |
4310 size_t ret; | 4325 size_t ret; |
4311 pst_index_ll* ptr; | 4326 pst_index_ll* ptr; |
4312 pst_holder h = {buf, NULL, 0, "", 0}; | 4327 pst_holder h = {buf, NULL, 0, "", 0}; |
4313 DEBUG_ENT("pst_ff_getID2block"); | 4328 DEBUG_ENT("pst_ff_getID2block"); |
4314 ptr = pst_getID2(id2_head, id2); | 4329 ptr = pst_getID2(id2_head, id2); |
4324 } | 4339 } |
4325 | 4340 |
4326 | 4341 |
4327 size_t pst_ff_getID2data(pst_file *pf, pst_index_ll *ptr, pst_holder *h) { | 4342 size_t pst_ff_getID2data(pst_file *pf, pst_index_ll *ptr, pst_holder *h) { |
4328 size_t ret; | 4343 size_t ret; |
4329 unsigned char *b = NULL, *t; | 4344 char *b = NULL, *t; |
4330 DEBUG_ENT("pst_ff_getID2data"); | 4345 DEBUG_ENT("pst_ff_getID2data"); |
4331 if (!(ptr->id & 0x02)) { | 4346 if (!(ptr->id & 0x02)) { |
4332 ret = pst_ff_getIDblock_dec(pf, ptr->id, &b); | 4347 ret = pst_ff_getIDblock_dec(pf, ptr->id, &b); |
4333 if (h->buf) { | 4348 if (h->buf) { |
4334 *(h->buf) = b; | 4349 *(h->buf) = b; |
4349 } else { | 4364 } else { |
4350 // here we will assume it is a block that points to others | 4365 // here we will assume it is a block that points to others |
4351 DEBUG_READ(("Assuming it is a multi-block record because of it's id\n")); | 4366 DEBUG_READ(("Assuming it is a multi-block record because of it's id\n")); |
4352 ret = pst_ff_compile_ID(pf, ptr->id, h, (size_t)0); | 4367 ret = pst_ff_compile_ID(pf, ptr->id, h, (size_t)0); |
4353 } | 4368 } |
4354 if (h->buf && *h->buf) | 4369 // bogus null termination off the end of the buffer!! |
4355 (*(h->buf))[ret]='\0'; | 4370 //if (h->buf && *h->buf) (*(h->buf))[ret]='\0'; |
4356 DEBUG_RET(); | 4371 DEBUG_RET(); |
4357 return ret; | 4372 return ret; |
4358 } | 4373 } |
4359 | 4374 |
4360 | 4375 |
4361 size_t pst_ff_compile_ID(pst_file *pf, uint64_t id, pst_holder *h, size_t size) { | 4376 size_t pst_ff_compile_ID(pst_file *pf, uint64_t id, pst_holder *h, size_t size) { |
4362 size_t z, a, b; | 4377 size_t z, a, b; |
4363 uint16_t count, y; | 4378 uint16_t count, y; |
4364 unsigned char * buf3 = NULL, *buf2 = NULL, *t; | 4379 char * buf3 = NULL, *buf2 = NULL, *t; |
4365 unsigned char *b_ptr; | 4380 char *b_ptr; |
4366 pst_block_hdr block_hdr; | 4381 pst_block_hdr block_hdr; |
4367 pst_table3_rec table3_rec; //for type 3 (0x0101) blocks | 4382 pst_table3_rec table3_rec; //for type 3 (0x0101) blocks |
4368 | 4383 |
4369 DEBUG_ENT("pst_ff_compile_ID"); | 4384 DEBUG_ENT("pst_ff_compile_ID"); |
4370 a = pst_ff_getIDblock(pf, id, &buf3); | 4385 a = pst_ff_getIDblock(pf, id, &buf3); |
4371 if (!a) { | 4386 if (!a) { |
4372 if (buf3) free(buf3); | 4387 if (buf3) free(buf3); |
4388 DEBUG_RET(); | |
4373 return 0; | 4389 return 0; |
4374 } | 4390 } |
4375 DEBUG_HEXDUMPC(buf3, a, 0x10); | 4391 DEBUG_HEXDUMPC(buf3, a, 0x10); |
4376 memcpy(&block_hdr, buf3, sizeof(block_hdr)); | 4392 memcpy(&block_hdr, buf3, sizeof(block_hdr)); |
4377 LE16_CPU(block_hdr.index_offset); | 4393 LE16_CPU(block_hdr.index_offset); |
4407 z = pst_ff_getIDblock_dec(pf, table3_rec.id, &buf2); | 4423 z = pst_ff_getIDblock_dec(pf, table3_rec.id, &buf2); |
4408 if (!z) { | 4424 if (!z) { |
4409 DEBUG_WARN(("call to getIDblock returned zero %i\n", z)); | 4425 DEBUG_WARN(("call to getIDblock returned zero %i\n", z)); |
4410 if (buf2) free(buf2); | 4426 if (buf2) free(buf2); |
4411 free(buf3); | 4427 free(buf3); |
4428 DEBUG_RET(); | |
4412 return z; | 4429 return z; |
4413 } | 4430 } |
4414 if (h->buf) { | 4431 if (h->buf) { |
4415 *(h->buf) = realloc(*(h->buf), size+z+1); | 4432 *(h->buf) = realloc(*(h->buf), size+z+1); |
4416 DEBUG_READ(("appending read data of size %i onto main buffer from pos %i\n", z, size)); | 4433 DEBUG_READ(("appending read data of size %i onto main buffer from pos %i\n", z, size)); |