Mercurial > libpst
diff src/libpst.c @ 50:fb3818370dd6 stable-0-6-4
more fixes for 64 bit format
author | carl |
---|---|
date | Sat, 19 Jan 2008 16:30:16 -0800 |
parents | 17654fbdf76b |
children | 06c0262ad689 |
line wrap: on
line diff
--- a/src/libpst.c Sat Jan 19 10:47:16 2008 -0800 +++ b/src/libpst.c Sat Jan 19 16:30:16 2008 -0800 @@ -64,23 +64,28 @@ uint32_t u1; uint32_t offset; }; + + struct pst_table_ptr_structn{ uint64_t start; uint64_t u1; uint64_t offset; }; + typedef struct pst_block_header { uint16_t type; uint16_t count; } pst_block_header; + typedef struct pst_id2_assoc32 { uint32_t id2; uint32_t id; uint32_t table2; } pst_id2_assoc32; + typedef struct pst_id2_assoc { uint32_t id2; // only 32 bit here? uint16_t unknown1; @@ -89,15 +94,24 @@ uint64_t table2; } pst_id2_assoc; + typedef struct pst_table3_rec32 { uint32_t id; } pst_table3_rec32; //for type 3 (0x0101) blocks + typedef struct pst_table3_rec { uint64_t id; } pst_table3_rec; //for type 3 (0x0101) blocks +typedef struct pst_block_hdr { + uint16_t index_offset; + uint16_t type; + uint32_t offset; +} pst_block_hdr; + + // this is an array of the un-encrypted values. the un-encrypted value is in the position // of the encrypted value. ie the encrypted value 0x13 represents 0x02 // 0 1 2 3 4 5 6 7 @@ -1306,12 +1320,8 @@ unsigned char* ind2_end = NULL; unsigned char* ind2_ptr = NULL; pst_x_attrib_ll *mapptr; - - struct { - uint16_t index_offset; - uint16_t type; - uint32_t offset; - } block_hdr; + pst_block_hdr block_hdr; + pst_table3_rec table3_rec; //for type 3 (0x0101) blocks struct { unsigned char seven_c; @@ -1345,8 +1355,6 @@ uint8_t slot; } table2_rec; //for type 2 (0x7CEC) blocks - pst_table3_rec table3_rec; //for type 3 (0x0101) blocks - DEBUG_ENT("pst_parse_block"); if ((read_size = pst_ff_getIDblock_dec(pf, block_id, &buf)) == 0) { WARN(("Error reading block id %#llx\n", block_id)); @@ -1370,10 +1378,10 @@ DEBUG_EMAIL(("block header (index_offset=%#hx, type=%#hx, offset=%#hx)\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset)); if (block_hdr.index_offset == (uint16_t)0x0101) { //type 3 + size_t i; + char *b_ptr = buf + 8; subblocks.subblock_count = block_hdr.type; subblocks.subs = malloc(sizeof(pst_subblock) * subblocks.subblock_count); - size_t i; - char *b_ptr = buf + 8; for (i=0; i<subblocks.subblock_count; i++) { b_ptr += pst_decode_type3(pf, &table3_rec, b_ptr); subblocks.subs[i].buf = NULL; @@ -1397,7 +1405,7 @@ } else { // setup the subblock descriptors, but we only have one block - subblocks.subblock_count = 1; + subblocks.subblock_count = (size_t)1; subblocks.subs = malloc(sizeof(pst_subblock)); subblocks.subs[0].buf = buf; subblocks.subs[0].read_size = read_size; @@ -1551,7 +1559,7 @@ table_rec.type = table2_rec.type; table_rec.ref_type = table2_rec.ref_type; table_rec.value = 0; - if ((ind2_end - ind2_ptr) >= (table2_rec.ind2_off + table2_rec.size)) { + if ((ind2_end - ind2_ptr) >= (int)(table2_rec.ind2_off + table2_rec.size)) { size_t n = table2_rec.size; size_t m = sizeof(table_rec.value); if (n <= m) { @@ -1671,7 +1679,7 @@ } } else { - value_size = block_offset7.to - block_offset7.from; + value_size = (size_t)(block_offset7.to - block_offset7.from); na_ptr->items[x]->size = value_size; na_ptr->items[x]->type = table_rec.ref_type; na_ptr->items[x]->data = xmalloc(value_size+1); @@ -1863,6 +1871,8 @@ item->type = PST_TYPE_JOURNAL; else if (pst_strincmp("IPM.Appointment", item->ascii_type, 15) == 0) item->type = PST_TYPE_APPOINTMENT; + else if (pst_strincmp("IPM.Task", item->ascii_type, 8) == 0) + item->type = PST_TYPE_TASK; else item->type = PST_TYPE_OTHER; @@ -2245,7 +2255,9 @@ DEBUG_EMAIL(("Attachment Size - ")); NULL_CHECK(attach); MOVE_NEXT(attach); - memcpy(&(attach->size), list->items[x]->data, sizeof(attach->size)); + t = (*(int32_t*)list->items[x]->data); + LE32_CPU(t); + attach->size = (size_t)t; DEBUG_EMAIL(("%i\n", attach->size)); break; case 0x0FF9: // PR_RECORD_KEY Record Header 1 @@ -3205,6 +3217,18 @@ LIST_COPY(item->appointment->location, (char*)); DEBUG_EMAIL(("%s\n", item->appointment->location)); break; + case 0x820d: // Appointment start + DEBUG_EMAIL(("Appointment Date Start - ")); + MALLOC_APPOINTMENT(item); + LIST_COPY(item->appointment->start, (FILETIME*)); + DEBUG_EMAIL(("%s\n", fileTimeToAscii(item->appointment->start))); + break; + case 0x820e: // Appointment end + DEBUG_EMAIL(("Appointment Date End - ")); + MALLOC_APPOINTMENT(item); + LIST_COPY(item->appointment->end, (FILETIME*)); + DEBUG_EMAIL(("%s\n", fileTimeToAscii(item->appointment->end))); + break; case 0x8214: // Label for an appointment DEBUG_EMAIL(("Label for appointment - ")); MALLOC_APPOINTMENT(item); @@ -3246,32 +3270,84 @@ item->appointment->all_day = 0; } break; + case 0x8231: // Recurrence type + // 1: Daily + // 2: Weekly + // 3: Monthly + // 4: Yearly + DEBUG_EMAIL(("Appointment reccurs - ")); + MALLOC_APPOINTMENT(item); + memcpy(&(item->appointment->recurrence_type), list->items[x]->data, sizeof(item->appointment->recurrence_type)); + LE32_CPU(item->appointment->recurrence_type); + switch (item->appointment->recurrence_type) { + case PST_APP_RECUR_DAILY: + DEBUG_EMAIL(("Daily\n")); break; + case PST_APP_RECUR_WEEKLY: + DEBUG_EMAIL(("Weekly\n")); break; + case PST_APP_RECUR_MONTHLY: + DEBUG_EMAIL(("Monthly\n")); break; + case PST_APP_RECUR_YEARLY: + DEBUG_EMAIL(("Yearly\n")); break; + default: + DEBUG_EMAIL(("Unknown Value: %d\n", item->appointment->recurrence_type)); break; + } + break; + case 0x8232: // Recurrence description + DEBUG_EMAIL(("Appointment recurrence description - ")); + MALLOC_APPOINTMENT(item); + LIST_COPY(item->appointment->recurrence, (char*)); + DEBUG_EMAIL(("%s\n", item->appointment->recurrence)); + break; case 0x8234: // TimeZone as String DEBUG_EMAIL(("TimeZone of times - ")); MALLOC_APPOINTMENT(item); LIST_COPY(item->appointment->timezonestring, (char*)); DEBUG_EMAIL(("%s\n", item->appointment->timezonestring)); break; - case 0x8235: // Appointment start time - DEBUG_EMAIL(("Appointment Start Time - ")); + case 0x8235: // Recurrence start date + DEBUG_EMAIL(("Recurrence Start Date - ")); + MALLOC_APPOINTMENT(item); + LIST_COPY(item->appointment->recurrence_start, (FILETIME*)); + DEBUG_EMAIL(("%s\n", fileTimeToAscii(item->appointment->recurrence_start))); + break; + case 0x8236: // Recurrence end date + DEBUG_EMAIL(("Recurrence End Date - ")); MALLOC_APPOINTMENT(item); - LIST_COPY(item->appointment->start, (FILETIME*)); - DEBUG_EMAIL(("%s\n", fileTimeToAscii((FILETIME*)item->appointment->start))); - break; - case 0x8236: // Appointment end time - DEBUG_EMAIL(("Appointment End Time - ")); + LIST_COPY(item->appointment->recurrence_end, (FILETIME*)); + DEBUG_EMAIL(("%s\n", fileTimeToAscii(item->appointment->recurrence_end))); + break; + case 0x8501: // Reminder minutes before appointment start + DEBUG_EMAIL(("Alarm minutes - ")); + MALLOC_APPOINTMENT(item); + memcpy(&(item->appointment->alarm_minutes), list->items[x]->data, sizeof(item->appointment->alarm_minutes)); + LE32_CPU(item->appointment->alarm_minutes); + DEBUG_EMAIL(("%i\n", item->appointment->alarm_minutes)); + break; + case 0x8503: // Reminder alarm + DEBUG_EMAIL(("Reminder alarm - ")); MALLOC_APPOINTMENT(item); - LIST_COPY(item->appointment->end, (FILETIME*)); - DEBUG_EMAIL(("%s\n", fileTimeToAscii((FILETIME*)item->appointment->start))); - break; - case 0x8516: // Journal time start - DEBUG_EMAIL(("Duplicate Time Start - ")); + if (*(int16_t*)list->items[x]->data != 0) { + DEBUG_EMAIL(("True\n")); + item->appointment->alarm = 1; + } else { + DEBUG_EMAIL(("False\n")); + item->appointment->alarm = 0; + } + break; + case 0x8516: + DEBUG_EMAIL(("Appointment Start Date 3 - ")); DEBUG_EMAIL(("%s\n", fileTimeToAscii((FILETIME*)list->items[x]->data))); break; - case 0x8517: // Journal time end - DEBUG_EMAIL(("Duplicate Time End - ")); + case 0x8517: + DEBUG_EMAIL(("Appointment End Date 3 - ")); DEBUG_EMAIL(("%s\n", fileTimeToAscii((FILETIME*)list->items[x]->data))); break; + case 0x851f: // Play reminder sound filename + DEBUG_EMAIL(("Appointment reminder sound filename - ")); + MALLOC_APPOINTMENT(item); + LIST_COPY(item->appointment->alarm_filename, (char*)); + DEBUG_EMAIL(("%s\n", item->appointment->alarm_filename)); + break; case 0x8530: // Followup DEBUG_EMAIL(("Followup String - ")); MALLOC_CONTACT(item); @@ -3726,9 +3802,13 @@ if (item->appointment) { SAFE_FREE(item->appointment->location); SAFE_FREE(item->appointment->reminder); + SAFE_FREE(item->appointment->alarm_filename); SAFE_FREE(item->appointment->start); SAFE_FREE(item->appointment->end); SAFE_FREE(item->appointment->timezonestring); + SAFE_FREE(item->appointment->recurrence); + SAFE_FREE(item->appointment->recurrence_start); + SAFE_FREE(item->appointment->recurrence_end); free(item->appointment); } SAFE_FREE(item->ascii_type); @@ -3771,6 +3851,10 @@ p->needfree = 1; } else { + if (p->from) { + DEBUG_WARN(("size zero but non-null pointer\n")); + free(p->from); + } p->from = p->to = NULL; } } @@ -4123,6 +4207,14 @@ } +/** + * Get an ID block from file using _pst_ff_getIDblock and decrypt if necessary + * @param pf PST file structure + * @param id ID of block to retrieve + * @param b Reference to pointer that will be set to new block. Any memory + pointed to by buffer will be free()d beforehand + * @return Size of block pointed to by *b + */ size_t pst_ff_getIDblock_dec(pst_file *pf, uint64_t id, unsigned char **b) { size_t r; int noenc = (int)(id & 2); // disable encryption @@ -4138,6 +4230,14 @@ } +/** + * Read a block of data from file into memory + * @param pf PST file + * @param id identifier of block to read + * @param b reference to pointer to buffer. If this pointer + is non-NULL, it will first be free()d + * @return size of block read into memory + */ size_t pst_ff_getIDblock(pst_file *pf, uint64_t id, unsigned char** b) { pst_index_ll *rec; size_t rsize = 0; @@ -4173,6 +4273,7 @@ #define PST_PTR_BLOCK_SIZE 0x120 size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_index2_ll *id2_head, unsigned char** buf) { + size_t ret; pst_index_ll* ptr; pst_holder h = {buf, NULL, 0, "", 0}; DEBUG_ENT("pst_ff_getID2block"); @@ -4183,8 +4284,9 @@ DEBUG_RET(); return 0; } + ret = pst_ff_getID2data(pf, ptr, &h); DEBUG_RET(); - return pst_ff_getID2data(pf, ptr, &h); + return ret; } @@ -4228,6 +4330,9 @@ uint32_t x, b; unsigned char * buf3 = NULL, *buf2 = NULL, *t; unsigned char fdepth; + unsigned char *b_ptr; + pst_block_hdr block_hdr; + pst_table3_rec table3_rec; //for type 3 (0x0101) blocks DEBUG_ENT("pst_ff_compile_ID"); a = pst_ff_getIDblock(pf, id, &buf3); @@ -4235,10 +4340,15 @@ if (buf3) free(buf3); return 0; } - if ((buf3[0] != 0x1)) { // if bit 8 is set) { - // if ((buf3)[0] != 0x1 && (buf3)[1] > 4) { - DEBUG_WARN(("WARNING: buffer doesn't start with 0x1, but I expected it to or doesn't have it's two-bit set!\n")); - DEBUG_WARN(("Treating as normal buffer\n")); + DEBUG_HEXDUMPC(buf3, a, 0x10); + memcpy(&block_hdr, buf3, sizeof(block_hdr)); + LE16_CPU(block_hdr.index_offset); + LE16_CPU(block_hdr.type); + LE32_CPU(block_hdr.offset); + DEBUG_EMAIL(("block header (index_offset=%#hx, type=%#hx, offset=%#x)\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset)); + + if (block_hdr.index_offset != (uint16_t)0x0101) { //type 3 + DEBUG_WARN(("WARNING: not a type 0x0101 buffer, Treating as normal buffer\n")); if (pf->encryption) (void)pst_decrypt(buf3, a, pf->encryption); if (h->buf) *(h->buf) = buf3; @@ -4258,64 +4368,45 @@ DEBUG_RET(); return a; } - memcpy (&count, &(buf3[2]), sizeof(int16_t)); - LE16_CPU(count); - memcpy (&fdepth, &(buf3[1]), sizeof(char)); - DEBUG_READ(("Seen index to blocks. Depth is %i\n", fdepth)); - DEBUG_READ(("There are %i ids here\n", count)); - - y = 0; - while (y < count) { - memcpy(&x, &buf3[0x08+(y*4)], sizeof(int32_t)); - LE32_CPU(x); - if (fdepth == 0x1) { - if ((z = pst_ff_getIDblock(pf, x, &buf2)) == 0) { - DEBUG_WARN(("call to getIDblock returned zero %i\n", z)); - if (buf2) free(buf2); - free(buf3); - return z; + count = block_hdr.type; + b_ptr = buf3 + 8; + for (y=0; y<count; y++) { + b_ptr += pst_decode_type3(pf, &table3_rec, b_ptr); + z = pst_ff_getIDblock_dec(pf, table3_rec.id, &buf2); + if (!z) { + DEBUG_WARN(("call to getIDblock returned zero %i\n", z)); + if (buf2) free(buf2); + free(buf3); + return z; + } + if (h->buf) { + *(h->buf) = realloc(*(h->buf), size+z+1); + DEBUG_READ(("appending read data of size %i onto main buffer from pos %i\n", z, size)); + memcpy(&((*(h->buf))[size]), buf2, z); + } else if ((h->base64 == 1) && h->fp) { + // include any byte left over from the last one encoding + buf2 = (char*)realloc(buf2, z+h->base64_extra); + memmove(buf2+h->base64_extra, buf2, z); + memcpy(buf2, h->base64_extra_chars, h->base64_extra); + z += h->base64_extra; + + b = z % 3; // find out how many bytes will be left over after the encoding. + // and save them + memcpy(h->base64_extra_chars, &(buf2[z-b]), b); + h->base64_extra = b; + t = base64_encode(buf2, z-b); + if (t) { + DEBUG_READ(("writing %i bytes to file as base64 [%i]. Currently %i\n", z, strlen(t), size)); + (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); + free(t); // caught by valgrind } - if (pf->encryption) (void)pst_decrypt(buf2, z, pf->encryption); - if (h->buf) { - *(h->buf) = realloc(*(h->buf), size+z+1); - DEBUG_READ(("appending read data of size %i onto main buffer from pos %i\n", z, size)); - memcpy(&((*(h->buf))[size]), buf2, z); - } else if ((h->base64 == 1) && h->fp) { - // include any byte left over from the last one encoding - buf2 = (char*)realloc(buf2, z+h->base64_extra); - memmove(buf2+h->base64_extra, buf2, z); - memcpy(buf2, h->base64_extra_chars, h->base64_extra); - z += h->base64_extra; - - b = z % 3; // find out how many bytes will be left over after the encoding. - // and save them - memcpy(h->base64_extra_chars, &(buf2[z-b]), b); - h->base64_extra = b; - t = base64_encode(buf2, z-b); - if (t) { - DEBUG_READ(("writing %i bytes to file as base64 [%i]. Currently %i\n", z, strlen(t), size)); - (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); - free(t); // caught by valgrind - } - } else if (h->fp) { - DEBUG_READ(("writing %i bytes to file. Currently %i\n", z, size)); - (void)pst_fwrite(buf2, (size_t)1, z, h->fp); - } else { - // h-> does not specify any output - } - size += z; - y++; + } else if (h->fp) { + DEBUG_READ(("writing %i bytes to file. Currently %i\n", z, size)); + (void)pst_fwrite(buf2, (size_t)1, z, h->fp); + } else { + // h-> does not specify any output } - else { - if ((z = pst_ff_compile_ID(pf, x, h, size)) == 0) { - DEBUG_WARN(("recursive called returned zero %i\n", z)); - free(buf3); - DEBUG_RET(); - return z; - } - size = z; - y++; - } + size += z; } free(buf3); if (buf2) free(buf2);