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));