#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <string.h>#include <errno.h>#include <sys/stat.h>#include <sys/types.h>#include "logger.h"#include "pldstr.h"#include "bt-int.h"#include "bytedecoders.h"#include "olestream-unwrap.h"#include "ole.h"#include "MALLOC.h"Include dependency graph for ole.c:

Go to the source code of this file.
Defines | |
| #define | OLE_SECTORID_FREE -1 |
| #define | OLE_SECTORID_ENDOFCHAIN -2 |
| #define | OLE_SECTORID_SAT -3 |
| #define | OLE_SECTORID_MSAT -4 |
| #define | header_id(x) ((x) +0) |
| #define | header_clid(x) ((x) +0x08) |
| #define | header_minor_version(x) ((x) +0x18) |
| #define | header_dll_version(x) ((x) +0x1a) |
| #define | header_byte_order(x) ((x) +0x1c) |
| #define | header_sector_shift(x) ((x) +0x1e) |
| #define | header_mini_sector_shift(x) ((x) +0x20) |
| #define | header_fat_sector_count(x) ((x) +0x2c) |
| #define | header_directory_stream_start_sector(x) ((x) +0x30) |
| #define | header_mini_cutoff_size(x) ((x) +0x38) |
| #define | header_mini_fat_start(x) ((x) +0x3c) |
| #define | header_mini_fat_sector_count(x) ((x) +0x40) |
| #define | header_dif_start_sector(x) ((x) +0x44) |
| #define | header_dif_sector_count(x) ((x) +0x48) |
| #define | header_fat_sectors(x) ((x) +0x4c) |
| #define | pps_rawname(x) ((x) +0) |
| #define | pps_sizeofname(x) ((x) +0x40) |
| #define | pps_type(x) ((x) +0x42) |
| #define | pps_previouspps(x) ((x) +0x44) |
| #define | pps_nextpps(x) ((x) +0x48) |
| #define | pps_directorypps(x) ((x) +0x4c) |
| #define | pps_time1seconds(x) ((x) +0x64) |
| #define | pps_time1days(x) ((x) +0x68) |
| #define | pps_time2seconds(x) ((x) +0x6c) |
| #define | pps_time2days(x) ((x) +0x70) |
| #define | pps_propertystart(x) ((x) +0x74) |
| #define | pps_sizeofproperty(x) ((x) +0x78) |
| #define | LEN_BYTE 1 |
| #define | LEN_USHORT 2 |
| #define | LEN_ULONG 4 |
| #define | STGTY_INVALID 0 |
| #define | STGTY_STORAGE 1 |
| #define | STGTY_STREAM 2 |
| #define | STGTY_LOCKBYTES 3 |
| #define | STGTY_PROPERTY 4 |
| #define | STGTY_ROOT 5 |
| #define | DE_RED 0 |
| #define | DE_BLACK 1 |
| #define | DOLE if (OLE_DNORMAL(ole->debug)) |
| #define | VOLE if (ole->verbose) |
Functions | |
| int | OLE_version (void) |
| int | OLE_init (struct OLE_object *ole) |
| int | OLE_dir_init (struct OLE_directory_entry *dir) |
| int | OLE_set_verbose (struct OLE_object *ole, int level) |
| int | OLE_set_quiet (struct OLE_object *ole, int level) |
| int | OLE_set_debug (struct OLE_object *ole, int level) |
| int | OLE_set_save_unknown_streams (struct OLE_object *ole, int level) |
| int | OLE_sectorpos (struct OLE_object *ole, int SID) |
| int | OLE_get_block (struct OLE_object *ole, int block_index, unsigned char *block_buffer) |
| int | OLE_get_miniblock (struct OLE_object *ole, int block_index, unsigned char *block_buffer) |
| int | OLE_dbstosbs (char *raw_string, size_t byte_count, char *clean_string, int clean_string_len) |
| int | OLE_print_string (char *string, size_t char_count) |
| int | OLE_print_sector (struct OLE_object *ole, char *sector, unsigned int bytes) |
| int | OLE_is_file_OLE (struct OLE_object *ole) |
| int | OLE_get_header (struct OLE_object *ole) |
| int | OLE_convert_header (struct OLE_object *ole) |
| int | OLE_header_sanity_check (struct OLE_object *ole) |
| int | OLE_print_header (struct OLE_object *ole) |
| int | OLE_convert_directory (struct OLE_object *ole, unsigned char *buf, struct OLE_directory_entry *dir) |
| int | OLE_print_directory (struct OLE_object *ole, struct OLE_directory_entry *dir) |
| int | OLE_load_FAT (struct OLE_object *ole) |
| int | OLE_follow_chain (struct OLE_object *ole, int FAT_sector_start) |
| int | OLE_follow_minichain (struct OLE_object *ole, int miniFAT_sector_start) |
| unsigned char * | OLE_load_minichain (struct OLE_object *ole, int miniFAT_sector_start) |
| unsigned char * | OLE_load_chain (struct OLE_object *ole, int FAT_sector_start) |
| int | OLE_open_file (struct OLE_object *ole, char *fullpath) |
| int | OLE_open_directory (struct OLE_object *ole, char *directory) |
| int | OLE_set_filename_report_fn (struct OLE_object *ole, int(*ptr_to_fn)(char *)) |
| int | OLE_store_stream (struct OLE_object *ole, char *stream_name, char *directory, char *stream, size_t stream_size) |
| int | OLE_decode_file_done (struct OLE_object *ole) |
| int | OLE_terminate_and_return (struct OLE_object *ole, int result) |
| int | OLE_decode_stream (struct OLE_object *ole, struct OLE_directory_entry *adir, char *decode_path) |
| int | OLE_decode_file (struct OLE_object *ole, char *fname, char *decode_path) |
Variables | |
| unsigned char | OLE_id_v2 [] = { 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1 } |
| unsigned char | OLE_id_v1 [] = { 0x0e, 0x11, 0xfc, 0x0d, 0xd0, 0xcf, 0x11, 0xe0 } |
| #define DOLE if (OLE_DNORMAL(ole->debug)) |
Definition at line 76 of file ole.c.
Referenced by OLE_convert_directory(), OLE_decode_file(), OLE_decode_stream(), OLE_follow_chain(), OLE_follow_minichain(), OLE_get_block(), OLE_load_chain(), OLE_load_FAT(), OLE_load_minichain(), and OLE_open_file().
| #define LEN_ULONG 4 |
Definition at line 62 of file ole.c.
Referenced by OLE_convert_header(), OLE_follow_chain(), OLE_follow_minichain(), OLE_load_chain(), OLE_load_FAT(), and OLE_load_minichain().
| #define OLE_SECTORID_ENDOFCHAIN -2 |
Definition at line 21 of file ole.c.
Referenced by OLE_follow_chain(), OLE_follow_minichain(), and OLE_load_minichain().
| #define OLE_SECTORID_FREE -1 |
Sector ID values (predefined)
Definition at line 20 of file ole.c.
Referenced by OLE_follow_chain(), OLE_follow_minichain(), and OLE_load_minichain().
| #define OLE_SECTORID_MSAT -4 |
Definition at line 23 of file ole.c.
Referenced by OLE_follow_chain(), OLE_follow_minichain(), and OLE_load_minichain().
| #define OLE_SECTORID_SAT -3 |
Definition at line 22 of file ole.c.
Referenced by OLE_follow_chain(), OLE_follow_minichain(), and OLE_load_minichain().
| #define STGTY_INVALID 0 |
| #define STGTY_ROOT 5 |
| #define STGTY_STORAGE 1 |
| #define STGTY_STREAM 2 |
| #define VOLE if (ole->verbose) |
Definition at line 77 of file ole.c.
Referenced by OLE_get_block(), OLE_load_chain(), and OLE_load_FAT().
| int OLE_convert_directory | ( | struct OLE_object * | ole, | |
| unsigned char * | buf, | |||
| struct OLE_directory_entry * | dir | |||
| ) |
Definition at line 776 of file ole.c.
References dir, DOLE, FL, get_1byte_value(), get_2byte_value(), get_4byte_value(), LOGGER_log(), memcpy(), memset(), OLE_DIRECTORY_ELEMENT_NAME_SIZE, and OLE_OK.
Referenced by OLE_decode_file().
00777 { 00783 memset( dir->element_name, '\0', OLE_DIRECTORY_ELEMENT_NAME_SIZE); 00784 00791 memcpy( dir->element_name, buf, OLE_DIRECTORY_ELEMENT_NAME_SIZE ); 00792 00797 dir->element_name_byte_count = get_2byte_value( buf + 0x40 ); 00798 00807 dir->element_type = get_1byte_value( buf +0x42 ); 00808 00813 dir->element_colour = get_1byte_value( buf +0x43 ); 00814 00816 dir->left_child = get_4byte_value( buf +0x44 ); 00817 00819 dir->right_child = get_4byte_value( buf +0x48 ); 00820 00821 00825 dir->root = get_4byte_value( buf +0x4c ); 00826 00827 memcpy( dir->class, buf +0x50, 16 ); 00828 dir->userflags = get_4byte_value( buf +0x60 ); 00829 memcpy( dir->timestamps, buf +0x64, 16 ); 00832 dir->start_sector = get_4byte_value( buf +0x74 ); 00833 00835 DOLE LOGGER_log("%s:%d:OLE_directory_entry:DEBUG: stream size = 0x%x %x %x %x" 00836 ,FL 00837 ,*(buf +0x78) 00838 ,*(buf +0x79) 00839 ,*(buf +0x7A) 00840 ,*(buf +0x7B) 00841 ); 00842 dir->stream_size = get_4byte_value( buf +0x78 ); 00843 00844 return OLE_OK; 00845 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int OLE_convert_header | ( | struct OLE_object * | ole | ) |
Definition at line 602 of file ole.c.
References OLE_object::file_size, get_2byte_value(), get_4byte_value(), h, OLE_object::header, OLE_object::header_block, header_byte_order, header_dif_sector_count, header_dif_start_sector, header_directory_stream_start_sector, header_dll_version, header_fat_sector_count, header_fat_sectors, header_mini_cutoff_size, header_mini_fat_sector_count, header_mini_fat_start, header_mini_sector_shift, header_minor_version, header_sector_shift, i, OLE_object::last_sector, LEN_ULONG, OLE_HEADER_FAT_SECTOR_COUNT_LIMIT, and OLE_OK.
Referenced by OLE_decode_file().
00603 { 00604 struct OLE_header *h; 00605 unsigned char *hb; 00606 unsigned char *fat_start; 00607 unsigned int i; 00608 00609 h = &(ole->header); 00610 hb = ole->header_block; 00611 00618 h->minor_version = get_2byte_value(header_minor_version(hb)); 00619 h->dll_version = get_2byte_value(header_dll_version(hb)); 00620 h->byte_order = get_2byte_value(header_byte_order(hb)); 00621 h->sector_shift = get_2byte_value(header_sector_shift(hb)); 00622 h->sector_size = 1 << h->sector_shift; 00623 00624 h->mini_sector_shift = get_2byte_value(header_mini_sector_shift(hb)); 00625 h->mini_sector_size = 1 << h->mini_sector_shift; 00626 00627 h->fat_sector_count = get_4byte_value(header_fat_sector_count(hb)); 00628 h->directory_stream_start_sector = get_4byte_value(header_directory_stream_start_sector(hb)); 00629 h->mini_cutoff_size = get_4byte_value(header_mini_cutoff_size(hb)); 00630 h->mini_fat_start = get_4byte_value(header_mini_fat_start(hb)); 00631 h->mini_fat_sector_count = get_4byte_value(header_mini_fat_sector_count(hb)); 00632 h->dif_start_sector = get_4byte_value(header_dif_start_sector(hb)); 00633 h->dif_sector_count = get_4byte_value(header_dif_sector_count(hb)); 00634 00639 ole->last_sector = ole->file_size >> h->sector_shift; 00640 00642 fat_start = header_fat_sectors(hb); 00643 for (i = 0; i < h->fat_sector_count; i++) 00644 { 00645 if (i >= OLE_HEADER_FAT_SECTOR_COUNT_LIMIT) break; 00646 h->FAT[i] = get_4byte_value( fat_start +(LEN_ULONG *i)); 00647 } 00648 00649 return OLE_OK; 00650 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int OLE_dbstosbs | ( | char * | raw_string, | |
| size_t | byte_count, | |||
| char * | clean_string, | |||
| int | clean_string_len | |||
| ) |
Definition at line 445 of file ole.c.
Referenced by OLE_decode_file(), OLE_decode_stream(), and OLE_print_directory().
00446 { 00447 char *limit = raw_string +byte_count -1; 00448 00449 clean_string_len--; 00450 00451 while ((raw_string < limit)&&(byte_count >0)&&(byte_count--)&&(clean_string_len--)) 00452 { 00453 int v = (char)*raw_string; 00454 00455 if (isprint(v)) 00456 { 00457 *clean_string = v; 00458 clean_string++; 00459 } 00460 00461 raw_string += 2; 00462 } 00463 *clean_string = '\0'; 00464 00465 return OLE_OK; 00466 }
Here is the caller graph for this function:

| int OLE_decode_file | ( | struct OLE_object * | ole, | |
| char * | fname, | |||
| char * | decode_path | |||
| ) |
Definition at line 1774 of file ole.c.
References OLE_header::directory_stream_start_sector, DOLE, OLE_directory_entry::element_colour, OLE_directory_entry::element_name, OLE_directory_entry::element_name_byte_count, OLE_directory_entry::element_type, FL, get_1byte_value(), OLE_object::header, i, OLE_object::last_chain_size, LOGGER_log(), memset(), OLE_header::mini_fat_start, OLE_object::miniFAT, OLE_object::ministream, NULL, OLE_convert_directory(), OLE_convert_header(), OLE_dbstosbs(), OLE_decode_stream(), OLE_dir_init(), OLE_get_header(), OLE_header_sanity_check(), OLE_load_chain(), OLE_load_FAT(), OLE_OK, OLE_open_directory(), OLE_open_file(), OLE_print_directory(), OLE_print_header(), OLEER_DECODE_NULL_FILENAME, OLEER_DECODE_NULL_OBJECT, OLEER_DECODE_NULL_PATH, OLEER_INSANE_OLE_FILE, OLEER_PROPERTIES_READ_FAIL, OLE_object::properties, result, OLE_directory_entry::start_sector, STGTY_INVALID, STGTY_ROOT, STGTY_STORAGE, and STGTY_STREAM.
Referenced by ripole().
01775 { 01776 unsigned char *current_property, *property_limit; 01777 int result = 0; 01778 int i; 01779 01780 /* Reject any bad paramters.*/ 01781 if (ole == NULL) return OLEER_DECODE_NULL_OBJECT; 01782 if (fname == NULL) return OLEER_DECODE_NULL_FILENAME; 01783 if (decode_path == NULL) return OLEER_DECODE_NULL_PATH; 01784 01785 /* We need to gain access to the OLE2 data file, without*/ 01786 /* this pretty much everything is pointless.*/ 01787 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: opening %s", FL, fname ); 01788 result = OLE_open_file( ole, fname ); 01789 if (result != 0) return result; 01790 01791 /* Try create the output directory which we're using*/ 01792 /* to write the decoded files out to.*/ 01793 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: opening output directory %s", FL, decode_path); 01794 result = OLE_open_directory( ole, decode_path ); 01795 if (result != 0) return result; 01796 01797 /* In order to successfully decode an OLE2 stream, we have to read*/ 01798 /* and understand the first 512 bytes of the file, this is the */ 01799 /* OLE2 header. */ 01800 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: Getting main header", FL); 01801 result = OLE_get_header( ole ); 01802 if (result != 0) return result; 01803 01804 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: Converting main header", FL); 01805 result = OLE_convert_header( ole ); 01806 if (result != 0) return result; 01807 01808 result = OLE_header_sanity_check( ole ); 01809 if (result > 0) return OLEER_INSANE_OLE_FILE; 01810 01811 DOLE OLE_print_header( ole ); 01812 01813 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: Loading FAT", FL); 01814 result = OLE_load_FAT( ole ); 01815 if (result != 0) return result; 01816 01817 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: Loading miniFAT chain", FL); 01818 ole->miniFAT = OLE_load_chain( ole, ole->header.mini_fat_start ); 01819 /* commented out by Serge Steer for Scilab*/ 01820 /* if (ole->miniFAT == NULL) return OLEER_MINIFAT_READ_FAIL;*/ 01821 01822 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: Loading Directory stream chain", FL); 01823 ole->properties = OLE_load_chain( ole, ole->header.directory_stream_start_sector ); 01824 if (ole->properties == NULL) return OLEER_PROPERTIES_READ_FAIL; 01825 01826 i=0; 01827 current_property = ole->properties; 01828 property_limit = current_property +ole->last_chain_size ; 01829 /* while(1)*/ 01830 while (current_property < property_limit) 01831 { 01832 struct OLE_directory_entry a_dir_object, *adir; 01833 int property_value=0; 01834 01835 adir = &a_dir_object; 01836 01837 OLE_dir_init(adir); 01838 01839 property_value = get_1byte_value(current_property); 01840 if (property_value < 1) break; 01841 01842 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG:--------- DIRECTORY INDEX: %d",FL,i); 01843 01844 OLE_convert_directory( ole, current_property, adir ); 01845 01846 DOLE { 01847 LOGGER_log("%s:%d:OLE_decode_file:DEBUG: Printing directory details...",FL); 01848 OLE_print_directory( ole, adir); 01849 LOGGER_log("%s:%d:OLE_decode_file:DEBUG: End of directory details",FL); 01850 } 01851 01852 if (adir->element_colour > 1) break; 01853 01854 if ((adir->element_type == STGTY_INVALID)||(adir->element_type > STGTY_ROOT)) 01855 { 01856 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: breaking out due to element type %d",FL, adir->element_type); 01857 break; 01858 01859 } else if (adir->element_type == STGTY_ROOT){ 01863 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: Loading ministream/SmallBlockArray",FL); 01864 ole->ministream = OLE_load_chain( ole, adir->start_sector ); 01865 /* commented out by Serge Steer for Scilab*/ 01866 /*if (ole->ministream == NULL) return OLEER_MINISTREAM_READ_FAIL;*/ 01867 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: ministream done",FL); 01868 01869 } else if (adir->element_type == STGTY_STORAGE) { 01873 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: Item is directory, start child is at index %d\n",FL,i); 01874 ole->ministream = OLE_load_chain( ole, adir->start_sector ); 01875 /* commented out by Serge Steer for Scilab*/ 01876 /*if (ole->ministream == NULL) return OLEER_MINISTREAM_READ_FAIL;*/ 01877 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: DIRECTORY ministream done",FL); 01878 01879 } else if (adir->element_type == STGTY_STREAM) { 01883 /* due to ole.c bugs we restrict here steams to decode to Workbooks (Excel) */ 01884 char element_name[64]; 01885 memset(element_name, '\0', 64); 01886 OLE_dbstosbs( adir->element_name, adir->element_name_byte_count, element_name, 64 ); 01887 01888 if ((strcmp(element_name,"Workbook")==0)||(strcmp(element_name,"Book")==0)) { 01889 OLE_decode_stream( ole, adir, decode_path ); 01890 } 01891 /*end of replacment code */ 01892 /* Original code */ 01893 /* OLE_decode_stream( ole, adir, decode_path );*/ 01894 } else { 01898 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: Element type %d does not need to be handled",FL,adir->element_type); 01899 } 01900 01901 /* Jump to the next property record, which*/ 01902 /* is always 128 bytes ahead.*/ 01903 current_property += 128; 01904 i++; 01905 01906 } /* While there are still more directory entries to read in.*/ 01907 01908 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: Finished",FL); 01909 01910 /* 01911 if (ole->f) fclose(ole->f); 01912 fclose(ole->f); 01913 if (ole->FAT) FREE(ole->FAT); 01914 if (ole->miniFAT) FREE(ole->miniFAT); 01915 if (ole->ministream) FREE(ole->ministream); 01916 if (ole->properties) FREE(ole->properties); 01917 */ 01918 01919 return OLE_OK; 01920 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int OLE_decode_file_done | ( | struct OLE_object * | ole | ) |
Definition at line 1597 of file ole.c.
References OLE_object::f, OLE_object::FAT, FREE, OLE_object::miniFAT, OLE_object::ministream, and OLE_object::properties.
Referenced by OLE_terminate_and_return(), and ripole().
01598 { 01599 if (ole->f) fclose(ole->f); 01601 if (ole->FAT) FREE(ole->FAT); 01602 if (ole->miniFAT) FREE(ole->miniFAT); 01603 if (ole->ministream) FREE(ole->ministream); 01604 if (ole->properties) FREE(ole->properties); 01605 01606 return 0; 01607 }
Here is the caller graph for this function:

| int OLE_decode_stream | ( | struct OLE_object * | ole, | |
| struct OLE_directory_entry * | adir, | |||
| char * | decode_path | |||
| ) |
Definition at line 1670 of file ole.c.
References OLE_object::debug, DOLE, OLE_directory_entry::element_name, OLE_directory_entry::element_name_byte_count, OLE_object::filename_report_fn, FL, FREE, OLE_object::header, LOGGER_log(), memset(), OLE_header::mini_cutoff_size, NULL, OLE_dbstosbs(), OLE_load_chain(), OLE_load_minichain(), OLE_store_stream(), OLEER_MINISTREAM_STREAM_READ_FAIL, OLEER_NORMALSTREAM_STREAM_READ_FAIL, OLEUNWRAP_decodestream(), OLEUNWRAP_init(), OLEUNWRAP_set_debug(), OLEUNWRAP_set_filename_report_fn(), OLEUNWRAP_set_save_unknown_streams(), OLEUNWRAP_set_verbose(), OLEUW_STREAM_NOT_DECODED, PLD_dprintf(), result, OLE_object::save_unknown_streams, OLE_directory_entry::start_sector, OLE_directory_entry::stream_size, and OLE_object::verbose.
Referenced by OLE_decode_file().
01671 { 01672 char *stream_data; 01673 struct OLEUNWRAP_object oleuw; 01674 int decode_result = OLEUW_STREAM_NOT_DECODED; 01675 char element_name[64]; 01676 int result = 0; 01677 01678 memset(element_name, '\0', 64); 01679 OLE_dbstosbs( adir->element_name, adir->element_name_byte_count, element_name, 64 ); 01680 01681 DOLE LOGGER_log("%s:%d:OLE_decode_stream:DEBUG: Decoding stream '%s'",FL, element_name); 01682 01683 DOLE LOGGER_log("%s:%d:OLE_decode_stream:DEBUG: Initializing stream unwrapper",FL); 01684 OLEUNWRAP_init(&oleuw); 01685 OLEUNWRAP_set_debug(&oleuw,ole->debug); 01686 OLEUNWRAP_set_verbose(&oleuw,ole->verbose); 01687 OLEUNWRAP_set_filename_report_fn(&oleuw, ole->filename_report_fn); 01688 OLEUNWRAP_set_save_unknown_streams(&oleuw, ole->save_unknown_streams); 01689 DOLE LOGGER_log("%s:%d:OLE_decode_stream:DEBUG: Unwrap engine set.",FL); 01690 01691 if (adir->stream_size >= ole->header.mini_cutoff_size) 01692 { 01696 DOLE LOGGER_log("%s:%d:OLE_decode_stream:DEBUG: Loading normal sized chain starting at sector %d",FL, adir->start_sector); 01697 stream_data = OLE_load_chain( ole, adir->start_sector ); 01698 if (stream_data == NULL) 01699 { 01700 DOLE LOGGER_log("%s:%d:OLE_decode_stream:DEBUG: Terminating from stream data being NULL ",FL); 01701 /*OLE_decode_file_done(ole);*/ 01702 return OLEER_MINISTREAM_STREAM_READ_FAIL; 01703 } 01704 DOLE LOGGER_log("%s:%d:OLE_decode_stream:DEBUG: Normal decode START. element name ='%s' stream size = '%ld'",FL, element_name, adir->stream_size); 01705 decode_result = OLEUNWRAP_decodestream( &oleuw, element_name, stream_data, adir->stream_size, decode_path ); 01706 DOLE LOGGER_log("%s:%d:OLE_decode_stream:DEBUG: Normal decode done.",FL); 01707 } else { 01708 01709 01713 DOLE LOGGER_log("%s:%d:OLE_decode_stream:DEBUG: Minichain loader, starting at sector %d" 01714 ,FL 01715 ,adir->start_sector 01716 ); 01717 stream_data = OLE_load_minichain( ole, adir->start_sector ); 01718 if (stream_data == NULL) 01719 { 01720 DOLE LOGGER_log("%s:%d:OLE_decode_stream:DEBUG: Ministream was non-existant, terminating",FL); 01721 /*OLE_decode_file_done(ole);*/ 01722 return OLEER_NORMALSTREAM_STREAM_READ_FAIL; 01723 } 01724 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: Mini decode START.",FL); 01725 decode_result = OLEUNWRAP_decodestream( &oleuw, element_name, stream_data, adir->stream_size, decode_path ); 01726 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: Mini decode done.",FL); 01727 } 01728 01729 /* Added for Scilab */ 01730 if ((stream_data != NULL)&&(decode_result == OLEUW_STREAM_NOT_DECODED)&& 01731 (ole->save_unknown_streams==2)&&((strcmp(element_name,"Workbook")==0)||(strcmp(element_name,"Book")==0))) 01732 { 01733 strcpy(element_name,"Workbook"); 01734 OLE_store_stream( ole, element_name, decode_path, stream_data, adir->stream_size ); 01735 01736 } /* If we needed to save an unknown stream*/ 01737 01738 else /* end Scilab addition */if ((stream_data != NULL)&&(decode_result == OLEUW_STREAM_NOT_DECODED)&&(ole->save_unknown_streams)) 01739 { 01740 char *lfname; 01741 01742 lfname = PLD_dprintf("ole-stream.%d",adir->start_sector); 01743 if (lfname != NULL) 01744 { 01745 DOLE LOGGER_log("%s:%d:OLE_decode_stream:DEBUG: Saving stream to %s",FL,lfname); 01746 OLE_store_stream( ole, lfname, decode_path, stream_data, adir->stream_size ); 01747 FREE(lfname); 01748 } 01749 } /* If we needed to save an unknown stream*/ 01750 01751 /* Clean up an stream_data which we may have */ 01752 /* read in from the chain-loader.*/ 01753 if (stream_data) FREE(stream_data); 01754 01755 return result; 01756 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int OLE_dir_init | ( | struct OLE_directory_entry * | dir | ) |
Definition at line 160 of file ole.c.
References dir, memset(), and OLE_DIRECTORY_ELEMENT_NAME_SIZE.
Referenced by OLE_decode_file().
00161 { 00162 memset(dir->element_name,'\0', OLE_DIRECTORY_ELEMENT_NAME_SIZE); 00163 dir->element_name_byte_count = 0; 00164 00165 dir->element_type = 0; 00166 dir->element_colour = 0; 00167 00168 dir->left_child = 0; 00169 dir->right_child = 0; 00170 dir->root = 0; 00171 00172 dir->class[0] = '\0'; 00173 dir->userflags = 0; 00174 dir->timestamps[0] = '\0'; 00175 dir->start_sector = 0; 00176 dir->stream_size = 0; 00177 00178 return 0; 00179 };
Here is the call graph for this function:

Here is the caller graph for this function:

| int OLE_follow_chain | ( | struct OLE_object * | ole, | |
| int | FAT_sector_start | |||
| ) |
Definition at line 1106 of file ole.c.
References BTI_add(), BTI_done(), BTI_init(), DOLE, OLE_object::FAT, OLE_object::FAT_limit, FL, get_4byte_value(), OLE_object::last_sector, LEN_ULONG, LOGGER_log(), n, OLE_SECTORID_ENDOFCHAIN, OLE_SECTORID_FREE, OLE_SECTORID_MSAT, and OLE_SECTORID_SAT.
Referenced by OLE_load_chain().
01107 { 01108 int current_sector = FAT_sector_start; 01109 int chain_length=0; 01110 int last_sector_of_file = ole->last_sector; 01111 int break_out = 0; 01112 struct bti_node *n; 01113 01114 BTI_init(&n); 01115 01116 if (FAT_sector_start < 0) return 0; 01117 01118 DOLE LOGGER_log("%s:%d:OLE_follow_chain:DEBUG: Starting chain follow at sector %d",FL, FAT_sector_start ); 01119 01120 do { 01121 int next_sector; 01122 unsigned char *next_sector_location; 01123 01124 next_sector_location = ole->FAT +(LEN_ULONG *current_sector); 01125 if (next_sector_location > (ole->FAT_limit -4)) { 01126 DOLE LOGGER_log("%s:%d:OLE_follow_chain:DEBUG: ERROR: Next sector was outside of the limits of this file (%ld > %ld)",FL, next_sector_location, ole->FAT_limit); 01127 break; 01128 } 01129 01130 /*next_sector = get_4byte_value( ole->FAT +(LEN_ULONG *current_sector));*/ 01131 next_sector = get_4byte_value( next_sector_location ); 01132 01133 if (BTI_add(&n, next_sector) != 0) 01134 { 01135 DOLE LOGGER_log("%s:%d:OLE_follow_chain:DEBUG: Sector collision, terminating chain traversal",FL); 01136 chain_length=-1; 01137 01138 break; 01139 } 01140 01141 DOLE LOGGER_log("%s:%d:OLE_follow_chain:DEBUG: 0x%0X:%d)->(0x%0X:%d)\n",FL, current_sector, current_sector, next_sector, next_sector); 01142 01143 /* 20040729-10H37 Added this to prevent endless loop which sometimes occurs at sector 0*/ 01144 01145 if (next_sector == current_sector) break; 01146 01147 /* fflush(stdout);*/ 01148 current_sector = next_sector; 01149 chain_length++; 01150 01152 switch (current_sector) { 01153 case OLE_SECTORID_MSAT: 01154 case OLE_SECTORID_SAT: 01155 case OLE_SECTORID_ENDOFCHAIN: 01156 case OLE_SECTORID_FREE: 01157 break_out=1; 01158 break; 01159 default: 01160 break_out=0; 01161 }; 01162 01163 if (current_sector < 0) break_out = 1; 01164 01165 } while ((break_out==0)&&(current_sector < last_sector_of_file)); 01166 01167 BTI_done(&n); 01168 01169 return chain_length; 01170 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int OLE_follow_minichain | ( | struct OLE_object * | ole, | |
| int | miniFAT_sector_start | |||
| ) |
Definition at line 1188 of file ole.c.
References DOLE, FL, get_4byte_value(), LEN_ULONG, LOGGER_log(), OLE_object::miniFAT, OLE_SECTORID_ENDOFCHAIN, OLE_SECTORID_FREE, OLE_SECTORID_MSAT, and OLE_SECTORID_SAT.
Referenced by OLE_load_minichain().
01189 { 01190 /*unsigned int current_sector = miniFAT_sector_start;*/ 01191 int current_sector = miniFAT_sector_start; 01192 int chain_length=0; 01193 int break_out = 0; 01194 01195 DOLE LOGGER_log("%s:%d:OLE_follow_minichain:DEBUG: Starting at sector %d",FL, miniFAT_sector_start); 01196 01197 if (miniFAT_sector_start < 0) return 0; 01198 01199 do { 01200 /*unsigned int next_sector;*/ 01201 int next_sector; 01202 01203 DOLE LOGGER_log("%s:%d:OLE_follow_minichain:DEBUG: Requesting 4-byte value at '%d'",FL, ole->miniFAT +(LEN_ULONG *current_sector)); 01204 /* next text commented out because ole->miniFAT_limit is set to null ans vever change 01205 if (ole->miniFAT +(LEN_ULONG *current_sector) > ole->miniFAT_limit) { 01206 DOLE LOGGER_log("%s:%d:OLE_follow_minichain:DEBUG: Requested location is out of bounds\n",FL); 01207 return 0; 01208 } 01209 */ 01210 01211 next_sector = get_4byte_value( ole->miniFAT +(LEN_ULONG *current_sector)); 01212 01213 DOLE LOGGER_log("%s:%d:OLE_follow_minichain:DEBUG: Current Msector(0x%0X:%d)->next(0x%0X:%d)\n", FL, current_sector, current_sector, next_sector, next_sector); 01214 01218 if (current_sector == next_sector) break; 01219 01220 chain_length++; 01221 current_sector = next_sector; 01222 01224 switch (current_sector) { 01225 case OLE_SECTORID_MSAT: 01226 case OLE_SECTORID_SAT: 01227 case OLE_SECTORID_ENDOFCHAIN: 01228 case OLE_SECTORID_FREE: 01229 break_out=1; 01230 break; 01231 default: 01232 break_out=0; 01233 }; 01234 01235 DOLE LOGGER_log("%s:%d:OLE_follow_minichain:DEBUG: current sector = %d",FL,current_sector); 01236 /* Test changed Serge Steer Scilab */ 01237 /* } while ((break_out==0) &&(current_sector <= ole->last_sector));*/ 01238 } while ((break_out==0)); 01239 DOLE LOGGER_log("%s:%d:OLE_follow_minichain:DEBUG: Done. Chainlength=%d",FL, chain_length); 01240 01241 return chain_length; 01242 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int OLE_get_block | ( | struct OLE_object * | ole, | |
| int | block_index, | |||
| unsigned char * | block_buffer | |||
| ) |
Definition at line 328 of file ole.c.
References bb, DOLE, errno, OLE_object::f, FL, FREE, OLE_object::header, LOGGER_log(), MALLOC, memcpy(), NULL, offset, OLE_OK, OLE_sectorpos(), OLEER_GET_BLOCK_READ, OLEER_GET_BLOCK_SEEK, OLE_header::sector_size, SEEK_SET, strerror(), and VOLE.
Referenced by OLE_get_header(), OLE_load_chain(), and OLE_load_FAT().
00329 { 00330 if (block_buffer == NULL) 00331 { 00332 LOGGER_log("%s:%d:OLE_get_block:ERROR: Block buffer is NULL",FL); 00333 return -1; 00334 } 00335 00336 if (ole->f != NULL) 00337 { 00338 int read_count = 0; 00339 int fseek_result = 0; 00340 size_t offset = 0; 00341 unsigned char *bb = NULL; 00342 00343 bb = MALLOC(sizeof(unsigned char) *ole->header.sector_size); 00344 if (bb == NULL) 00345 { 00346 LOGGER_log("%s:%d:OLE_get_block:ERROR: Cannot allocate %d bytes for OLE block",FL, ole->header.sector_size); 00347 return -1; 00348 } 00349 00350 DOLE LOGGER_log("%s:%d:OLE_get_block:DEBUG: BlockIndex=%d, Buffer=0x%x",FL, block_index, block_buffer); 00351 00352 /*20051211-2343:PLD: offset = (block_index +1) << ole->header.sector_shift;*/ 00353 offset = OLE_sectorpos(ole, block_index); 00354 00355 DOLE LOGGER_log("%s:%d:OLE_get_block:DEBUG: Read offset in file = 0x%x size to read= 0x%x",FL,offset,ole->header.sector_size); 00356 00357 fseek_result = fseek(ole->f, offset, SEEK_SET); 00358 if (fseek_result != 0) 00359 { 00360 if (bb != NULL) { FREE(bb); bb = NULL; } 00361 LOGGER_log("%s:%d:OLE_get_block:ERROR: Seek failure (block=%d:%d)",FL, block_index,offset, strerror(errno)); 00362 return OLEER_GET_BLOCK_SEEK; 00363 } 00364 00365 /*read_count = fread(block_buffer, sizeof(unsigned char), ole->header.sector_size, ole->f);*/ 00366 read_count = fread(bb, sizeof(unsigned char), ole->header.sector_size, ole->f); 00367 DOLE LOGGER_log("%s:%d:OLE_get_block:DEBUG: Read %d byte of data",FL,read_count); 00368 if (read_count != (int)ole->header.sector_size) 00369 { 00370 if (bb != NULL){ FREE(bb); bb = NULL; } 00371 VOLE LOGGER_log("%s:%d:Mismatch in bytes read. Requested %d, got %d\n", FL, ole->header.sector_size, read_count); 00372 return OLEER_GET_BLOCK_READ; 00373 } 00374 00375 DOLE LOGGER_log("%s:%d:OLE_get_block:DEBUG: Copying over memory read from file",FL); 00376 00377 memcpy(block_buffer, bb, ole->header.sector_size); 00378 00379 DOLE LOGGER_log("%s:%d:OLE_get_block:DEBUG: memory block copied to block_buffer",FL); 00380 00381 /* We're now done with BB, dispose of it */ 00382 if (bb) { FREE(bb); bb = NULL; } 00383 00384 DOLE LOGGER_log("%s:%d:OLE_get_block:DEBUG: Disposed of temporary bb block",FL); 00385 00386 } else { 00387 LOGGER_log("%s:%d:OLE_get_block:ERROR: OLE file is closed\n",FL); 00388 return -1; 00389 } 00390 00391 DOLE LOGGER_log("%s:%d:OLE_get_block:DEBUG: Done",FL); 00392 00393 return OLE_OK; 00394 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int OLE_get_header | ( | struct OLE_object * | ole | ) |
Definition at line 573 of file ole.c.
References OLE_object::header, OLE_object::header_block, OLE_get_block(), OLE_HEADER_BLOCK_SIZE, OLE_is_file_OLE(), OLE_OK, OLEER_NOT_OLE_FILE, result, and OLE_header::sector_size.
Referenced by OLE_decode_file().
00574 { 00575 int result = 0; 00576 ole->header.sector_size = OLE_HEADER_BLOCK_SIZE; 00577 result = OLE_get_block( ole, -1, ole->header_block ); 00578 00579 if (OLE_is_file_OLE( ole ) == 0) 00580 { 00581 return OLEER_NOT_OLE_FILE; 00582 } 00583 00584 return OLE_OK; 00585 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int OLE_get_miniblock | ( | struct OLE_object * | ole, | |
| int | block_index, | |||
| unsigned char * | block_buffer | |||
| ) |
Definition at line 414 of file ole.c.
References OLE_object::header, memcpy(), OLE_header::mini_sector_shift, OLE_header::mini_sector_size, OLE_object::ministream, offset, and OLE_OK.
Referenced by OLE_load_minichain().
00415 { 00416 /* This code may refer memory outside of the allocated one for ole->ministream * 00417 in case of VBA Streams Serge Steer 26/01/2007*/ 00418 if (ole->ministream) 00419 { 00420 int offset = block_index << ole->header.mini_sector_shift; 00421 memcpy( block_buffer, ole->ministream +offset, ole->header.mini_sector_size); 00422 } 00423 00424 return OLE_OK; 00425 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int OLE_header_sanity_check | ( | struct OLE_object * | ole | ) |
Definition at line 671 of file ole.c.
References OLE_object::file_size, h, and OLE_object::header.
Referenced by OLE_decode_file().
00672 { 00673 int insanity=0; 00674 int max_sectors; 00675 struct OLE_header *h; 00676 00677 h = &(ole->header); 00678 00679 max_sectors = ole->file_size / h->sector_size; 00680 00681 if (h->sector_shift > 20) insanity++; 00682 if (h->mini_sector_shift > 10) insanity++; 00683 if (h->fat_sector_count < 0) insanity++; 00684 if (h->fat_sector_count > (unsigned int)max_sectors) insanity++; 00685 if (h->directory_stream_start_sector > (unsigned int) max_sectors) insanity++; 00686 00687 return insanity; 00688 }
Here is the caller graph for this function:

| int OLE_init | ( | struct OLE_object * | ole | ) |
Definition at line 121 of file ole.c.
References OLE_object::debug, OLE_object::f, OLE_object::FAT, OLE_object::FAT_limit, OLE_object::file_size, OLE_object::filename_report_fn, OLE_object::header, OLE_object::header_block, OLE_header::mini_sector_shift, OLE_object::miniFAT, OLE_object::miniFAT_limit, OLE_object::ministream, NULL, OLE_OK, OLE_object::properties, OLE_object::quiet, OLE_header::sector_shift, and OLE_object::verbose.
Referenced by ripole().
00122 { 00123 ole->debug = 0; 00124 ole->verbose = 0; 00125 ole->quiet = 0; 00126 ole->filename_report_fn = NULL; 00127 ole->f = NULL; 00128 ole->file_size = 0; 00129 00130 ole->FAT = NULL; 00131 ole->FAT_limit = NULL; 00132 ole->miniFAT = NULL; 00133 ole->miniFAT_limit = NULL; 00134 00135 ole->header_block[0] = '\0'; 00136 ole->ministream = NULL; 00137 ole->properties = NULL; 00138 00139 ole->header.sector_shift = 0; 00140 ole->header.mini_sector_shift = 0; 00141 00142 return OLE_OK; 00143 }
Here is the caller graph for this function:

| int OLE_is_file_OLE | ( | struct OLE_object * | ole | ) |
Definition at line 548 of file ole.c.
References OLE_object::header_block, memcmp(), OLE_id_v1, and OLE_id_v2.
Referenced by OLE_get_header().
00549 { 00550 00551 if (memcmp(OLE_id_v1, ole->header_block, sizeof(OLE_id_v1))==0) return 1; 00552 if (memcmp(OLE_id_v2, ole->header_block, sizeof(OLE_id_v2))==0) return 1; 00553 00554 return 0; 00555 00556 }
Here is the call graph for this function:

Here is the caller graph for this function:

| unsigned char* OLE_load_chain | ( | struct OLE_object * | ole, | |
| int | FAT_sector_start | |||
| ) |
Definition at line 1340 of file ole.c.
References buffer, DOLE, OLE_object::error, OLE_object::FAT, FL, FREE, get_4byte_value(), OLE_object::header, OLE_object::last_chain_size, LEN_ULONG, LOGGER_log(), MALLOC, NULL, offset, OLE_follow_chain(), OLE_get_block(), OLE_OK, OLE_header::sector_shift, OLE_header::sector_size, and VOLE.
Referenced by OLE_decode_file(), and OLE_decode_stream().
01341 { 01342 01343 int chain_length = 0; 01344 int current_sector = FAT_sector_start; 01345 unsigned char *buffer = NULL; 01346 unsigned char *bp = NULL; 01347 01348 01349 ole->last_chain_size = 0; 01350 01351 if (FAT_sector_start < 0) return NULL; 01352 01353 DOLE LOGGER_log("%s:%d:OLE_load_chain:DEBUG: Loading chain, starting at sector %d",FL,FAT_sector_start); 01354 01355 chain_length = OLE_follow_chain( ole, FAT_sector_start ); 01356 DOLE LOGGER_log("%s:%d:OLE_load_chain:DEBUG: %d sectors need to be loaded",FL,chain_length); 01357 01358 if (chain_length > 0) 01359 { 01360 size_t offset; 01361 01362 offset = ole->last_chain_size = chain_length << ole->header.sector_shift; 01363 bp = buffer = MALLOC( (offset) *sizeof(unsigned char)); 01364 if (buffer == NULL) 01365 { 01366 LOGGER_log("%s:%d:OLE_load_chain:ERROR: Cannot allocate %d bytes for OLE chain",FL,offset); 01367 return NULL; 01368 } 01369 01370 if (buffer != NULL) 01371 { 01372 int tick = 0; 01373 unsigned char *bp_limit; 01374 bp_limit = bp +offset; 01375 01376 do { 01377 int next_sector; 01378 01379 DOLE LOGGER_log("%s:%d:OLE_load_chain:DEBUG: Loading sector[%d] %d",FL, tick, current_sector ); 01380 01381 ole->error = OLE_get_block( ole, current_sector, bp ); 01382 if (ole->error != OLE_OK) 01383 { 01384 /*FREE5 if (bp != NULL) FREE(bp);*/ 01385 return NULL; 01386 } 01387 01388 bp += ole->header.sector_size; 01389 if (bp > bp_limit) { 01390 if (buffer != NULL) { FREE(buffer); bp = buffer = NULL; } 01391 VOLE LOGGER_log("%s:%d:OLE_load_chain:ERROR: Load-chain went over memory boundary",FL); 01392 return NULL; 01393 }; 01394 01395 next_sector = get_4byte_value( ole->FAT +(LEN_ULONG *current_sector)); 01396 current_sector = next_sector; 01397 tick++; 01398 } while ((current_sector >= 0)&&(current_sector <= ole->last_sector)); 01399 } 01400 } 01401 DOLE LOGGER_log("%s:%d:OLE_load_chain:DEBUG: Done loading chain",FL); 01402 01403 return buffer; 01404 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int OLE_load_FAT | ( | struct OLE_object * | ole | ) |
Definition at line 908 of file ole.c.
References OLE_object::debug, OLE_header::dif_sector_count, OLE_header::dif_start_sector, DOLE, OLE_object::FAT, OLE_header::FAT, OLE_object::FAT_limit, OLE_header::fat_sector_count, FL, FREE, get_4byte_value(), OLE_object::header, i, LEN_ULONG, LOGGER_log(), MALLOC, NULL, OLE_DPEDANTIC, OLE_get_block(), OLE_HEADER_FAT_SECTOR_COUNT_LIMIT, OLE_OK, OLE_print_sector(), OLEER_MEMORY_OVERFLOW, OLE_header::sector_shift, OLE_header::sector_size, and VOLE.
Referenced by OLE_decode_file().
00909 { 00910 unsigned int FAT_size; 00911 00912 FAT_size = ole->header.fat_sector_count << ole->header.sector_shift; 00913 DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG:Allocating for %d sectors (%d bytes) \n" 00914 ,FL,ole->header.fat_sector_count, FAT_size); 00915 00916 ole->FAT = MALLOC( FAT_size *sizeof(unsigned char)); 00917 ole->FAT_limit = ole->FAT +FAT_size; 00918 if (ole->FAT != NULL) 00919 { 00920 unsigned int i; 00921 unsigned char *fat_position = ole->FAT; 00922 unsigned int sector_count = ole->header.fat_sector_count; 00923 00924 if (sector_count > OLE_HEADER_FAT_SECTOR_COUNT_LIMIT) 00925 { 00926 sector_count = OLE_HEADER_FAT_SECTOR_COUNT_LIMIT; 00927 DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: sector count greater than limit; set to %d",FL, sector_count); 00928 } 00929 00930 /* Load in all our primary-FAT sectors from the OLE file*/ 00931 for (i = 0; i < sector_count; i++) 00932 { 00933 int getblock_result = 0; 00934 00935 DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: Loading sector %d",FL, i); 00936 getblock_result = OLE_get_block(ole, ole->header.FAT[i], fat_position); 00937 if (getblock_result != 0) 00938 { 00939 /* if the get block fails, return the error - but keep the FAT*/ 00940 /* pointer alive - so that we can facilitate debugging*/ 00941 /* otherwise the caller is always going to get a NULL pointer*/ 00942 /* and have no idea to what extent the data was read.*/ 00943 00944 /* This behavior may be changed later - but for now (beta development)*/ 00945 /* it'll be okay to leave it here - just make sure we know to*/ 00946 /* free the FAT block later.*/ 00947 00948 return getblock_result; 00949 } 00950 00951 fat_position += ole->header.sector_size; 00952 if (fat_position > ole->FAT_limit) 00953 { 00954 LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: FAT boundary limit exceeded %p > %p", FL, fat_position, ole->FAT_limit); 00955 return -1; 00956 } 00957 } 00958 00959 /* If our DIF count is > 0, this means we have a pretty big*/ 00960 /* file on hand (> 7Mb) and thus we now have to do some*/ 00961 /* fancy double-dereferenced sector request - enough to */ 00962 /* twist your brain if you're not alert, you have been*/ 00963 /* warned.*/ 00964 00965 if (ole->header.dif_sector_count > 0) 00966 { 00967 unsigned char *fat_block; 00968 unsigned char *fat_block_end; 00969 unsigned int current_sector = ole->header.dif_start_sector; 00970 00971 DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: Allocating %d bytes to fat_block\n",FL, ole->header.sector_size); 00972 00973 fat_block = MALLOC( ole->header.sector_size ); 00974 00975 if (fat_block == NULL) 00976 { 00977 LOGGER_log("%s:%d:OLE_load_FAT:ERROR: Unable to allocate %d bytes\n", FL, ole->header.sector_size); 00978 return -1; 00979 /* exit(1);*/ 00980 } 00981 00982 /* We need to know where the end of this block is - because it's*/ 00983 /* used to show us where the NEXT FAT block is going to come from*/ 00984 /* NOTE - this only occurs if we do have another block, else */ 00985 /* we'll simply have to just realise that we don't need any more*/ 00986 /* blocks and stop with this one.*/ 00987 00988 fat_block_end = fat_block +ole->header.sector_size -LEN_ULONG; 00989 00990 /* We know we've got 'dif_sector_count' blocks to read, each of*/ 00991 /* these blocks hold no more than 127 sector addresses which*/ 00992 /* contain the actual FAT data we're after (this is the double*/ 00993 /* dereference bit that twists your brain )*/ 00994 00995 DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: Loading DIF sectors (count = %d)",FL,ole->header.dif_sector_count); 00996 00997 for (i = 0; i < ole->header.dif_sector_count; i++) 00998 { 00999 int import_sector; 01000 unsigned char *DIF = fat_block; 01001 int tick = 0; 01002 int getblock_result; 01003 01004 DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: Reading DIF/XBAT index-data[%d] from sector 0x%x",FL,i,current_sector); 01005 getblock_result = OLE_get_block(ole, current_sector, fat_block); 01006 if (getblock_result != OLE_OK) 01007 { 01008 if (fat_block) FREE(fat_block); 01009 return getblock_result; 01010 } 01011 01012 if (OLE_DPEDANTIC(ole->debug)) OLE_print_sector(ole, fat_block, ole->header.sector_size); 01013 01014 /* Now, traverse this block until we hit a < 0*/ 01015 /* If we get what is a non-valid sector value*/ 01016 /* we know we've reached the end of the valid*/ 01017 /* sectors from which to read more extended FAT*/ 01018 /* data.*/ 01019 01020 do { 01021 import_sector = get_4byte_value( DIF ); 01022 DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: import sector = 0x%x",FL,import_sector); 01023 if (import_sector >= 0) 01024 { 01025 if (fat_position +ole->header.sector_size <= ole->FAT_limit) 01026 { 01027 DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: Reading DIF/XBAT-data[%d] from sector 0x%x",FL,tick,import_sector); 01028 getblock_result = OLE_get_block(ole, import_sector, fat_position); 01029 if (getblock_result != OLE_OK) 01030 { 01031 LOGGER_log("%s:%d:OLE_load_FAT:ERROR: Not able to load block, import sector = 0x%x, fat position = 0x%x",FL, import_sector, fat_position); 01032 if (fat_block) FREE(fat_block); 01033 return getblock_result; 01034 } 01035 01036 fat_position += ole->header.sector_size; 01037 DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: FAT position = 0x%x (start = 0x%x, end = 0x%x)" 01038 ,FL 01039 ,fat_position 01040 ,fat_block 01041 ,ole->FAT_limit 01042 ); 01043 01044 /*if (fat_position +ole->header.sector_size > ole->FAT_limit)*/ 01045 if (fat_position > ole->FAT_limit) 01046 { 01047 DOLE LOGGER_log("%s:%d:OLE_load_FAT:ERROR: FAT memory boundary limit exceeded %p >= %p",FL,fat_position,ole->FAT_limit); 01048 if (fat_block) FREE(fat_block); 01049 return OLEER_MEMORY_OVERFLOW; 01050 } 01051 tick++; 01052 DIF += LEN_ULONG; 01053 } else { 01054 LOGGER_log("%s:%d:OLE_load_FAT:ERROR: FAT memory boundary limit exceeded %p >= %p",FL,fat_position,ole->FAT_limit); 01055 if (fat_block) FREE(fat_block); 01056 return OLEER_MEMORY_OVERFLOW; 01057 } 01058 } else { 01059 VOLE LOGGER_log("%s:%d:OLE_load_FAT:ERROR: sector request was negative (%d)",FL, import_sector); 01060 } 01061 01062 DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: DIF = 0x%x",FL,DIF); 01063 } while ((import_sector >= 0)&&(DIF < fat_block_end)); 01064 01065 /* Get the next sector of DIF/XBAT data ...*/ 01066 01067 /* If we still have more sectors full of extended FAT*/ 01068 /* sectors that we have to read, then we neet to*/ 01069 /* obtain the address of the next FAT-sector filled*/ 01070 /* sector*/ 01071 01072 if ( i < ole->header.dif_sector_count -1 ) 01073 { 01074 current_sector = get_4byte_value( fat_block_end ); 01075 DOLE LOGGER_log("%s:%d:OLE_load_FAT:DEBUG: Next DIF/XBAT index sector located at 0x%x",FL,current_sector); 01076 if (current_sector < 0) break; 01077 } 01078 } /* For every DIF/XBAT sector we're supposed to read*/ 01079 01080 if (fat_block) FREE(fat_block); 01081 } /* If we have DIF/XBAT sectors to read into the FAT*/ 01082 01083 } /* If we managed to allocate memory for our FAT table*/ 01084 01085 return OLE_OK; 01086 }
Here is the call graph for this function:

Here is the caller graph for this function:

| unsigned char* OLE_load_minichain | ( | struct OLE_object * | ole, | |
| int | miniFAT_sector_start | |||
| ) |
Definition at line 1263 of file ole.c.
References buffer, DOLE, FL, get_4byte_value(), OLE_object::header, LEN_ULONG, LOGGER_log(), MALLOC, OLE_header::mini_sector_size, OLE_object::miniFAT, NULL, OLE_follow_minichain(), OLE_get_miniblock(), OLE_SECTORID_ENDOFCHAIN, OLE_SECTORID_FREE, OLE_SECTORID_MSAT, and OLE_SECTORID_SAT.
Referenced by OLE_decode_stream().
01264 { 01265 01266 int chain_length = 0; 01267 int current_sector = miniFAT_sector_start; 01268 unsigned char *buffer; 01269 unsigned char *bp; 01270 int break_out = 0; 01271 01272 DOLE LOGGER_log("%s:%d:OLE_load_minichain:DEBUG: Loading minichain starting at %d",FL, miniFAT_sector_start); 01273 01274 /* Added this sanity checking 2003 Aug 28*/ 01275 if (miniFAT_sector_start < 0) return NULL; 01276 01277 chain_length = OLE_follow_minichain( ole, miniFAT_sector_start ); 01278 DOLE LOGGER_log("%s:%d:OLE_load_minichain:DEBUG: Found %d mini-sectors to load (%d bytes)\n",FL, chain_length, chain_length *ole->header.mini_sector_size); 01279 01280 /* 20040911-21H59*/ 01281 /* If our chain is 0 length, then there's nothing to return*/ 01282 if (chain_length == 0) return NULL; 01283 01284 bp = buffer = MALLOC( chain_length *ole->header.mini_sector_size *sizeof(unsigned char)); 01285 if (buffer != NULL) 01286 { 01287 do { 01288 int next_sector; 01289 01290 DOLE LOGGER_log("%s:%d:OLE_load_minichain:DEBUG: Loading sector %d",FL, current_sector); 01291 OLE_get_miniblock( ole, current_sector, bp ); 01292 bp += ole->header.mini_sector_size; 01293 01294 next_sector = get_4byte_value( ole->miniFAT +(LEN_ULONG *current_sector)); 01295 current_sector = next_sector; 01296 /* NEXT LINES ADDED TO BE COHERENT WITH OLE_follow_minichain ABOVE Serge Steer Scilab */ 01297 switch (current_sector) { 01298 case OLE_SECTORID_MSAT: 01299 case OLE_SECTORID_SAT: 01300 case OLE_SECTORID_ENDOFCHAIN: 01301 case OLE_SECTORID_FREE: 01302 break_out=1; 01303 break; 01304 default: 01305 break_out=0; 01306 }; 01307 /* Test changed Serge Steer Scilab */ 01308 /* } while ((current_sector != OLE_SECTORID_ENDOFCHAIN)&&(current_sector >= 0)&&(current_sector <= ole->last_sector));*/ 01309 01310 } while ((break_out==0)); 01311 01312 } else { 01313 LOGGER_log("%s:%d:OLE_get_miniblock:ERROR: Failed to allocate enough memory for miniChain",FL); 01314 } 01315 01316 DOLE LOGGER_log("%s:%d:OLE_load_minichain:DEBUG: Done. buffer=%p",FL, buffer); 01317 01318 return buffer; 01319 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int OLE_open_directory | ( | struct OLE_object * | ole, | |
| char * | directory | |||
| ) |
Definition at line 1477 of file ole.c.
References errno, FL, LOGGER_log(), NULL, OLE_OK, result, and strerror().
Referenced by OLE_decode_file().
01478 { 01479 int result=0; 01480 01481 #ifndef _MSC_VER 01482 result = mkdir( directory, S_IRWXU ); 01483 #else 01484 result = CreateDirectory( directory,NULL); 01485 /* If the function succeeds, the return value is nonzero. 01486 If the function fails, the return value is zero. */ 01487 if (result) result=0; 01488 #endif 01489 if ((result != 0)&&(errno != EEXIST)) 01490 { 01491 LOGGER_log("%s:%d:OLE_open_directory:ERROR: %s",FL,strerror(errno)); 01492 } else result = OLE_OK; 01493 01494 return result; 01495 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int OLE_open_file | ( | struct OLE_object * | ole, | |
| char * | fullpath | |||
| ) |
Definition at line 1426 of file ole.c.
References DOLE, errno, f(), OLE_object::f, OLE_object::file_size, FL, OLE_object::last_sector, LOGGER_log(), NULL, OLE_OK, OLEER_BAD_INPUT_FILE, OLEER_NOT_OLE_FILE, OLE_object::quiet, stat, and strerror().
Referenced by OLE_decode_file().
01427 { 01428 struct stat st; 01429 int stat_result; 01430 FILE *f; 01431 01432 stat_result = stat(fullpath, &st); 01433 if (stat_result != 0) { 01434 DOLE LOGGER_log("%s:%d:OLE_open_file:ERROR: Cannot locate file '%s' for opening (%s)",FL, fullpath, strerror(errno)); 01435 return OLEER_BAD_INPUT_FILE; 01436 } 01437 01438 DOLE LOGGER_log("%s:%d:OLE_open_file:DEBUG: File size of %s = %ld",FL, fullpath, st.st_size); 01439 if ((stat_result == 0) && (st.st_size < 512)) return OLEER_NOT_OLE_FILE; 01440 01441 ole->file_size = st.st_size; 01442 01443 f = fopen(fullpath,"rb"); 01444 if (f == NULL) 01445 { 01446 ole->f = NULL; 01447 if (ole->quiet == 0) 01448 { 01449 LOGGER_log("%s:%d:OLE_open_file:ERROR:Cannot open %s for reading (%s)\n",FL,fullpath, strerror(errno)); 01450 } 01451 return -1; 01452 } else { 01453 ole->f = f; 01454 ole->file_size = st.st_size; 01455 ole->last_sector = -1; 01456 } 01457 return OLE_OK; 01458 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int OLE_print_directory | ( | struct OLE_object * | ole, | |
| struct OLE_directory_entry * | dir | |||
| ) |
Definition at line 863 of file ole.c.
References dir, OLE_dbstosbs(), and OLE_OK.
Referenced by OLE_decode_file().
00864 { 00865 char element[64]; 00866 OLE_dbstosbs( dir->element_name, dir->element_name_byte_count, element, sizeof(element) ); 00867 00868 printf( 00869 "Element Name = %s\n" 00870 "Element type = %d\n" 00871 "Element colour = %d\n" 00872 "Left Child = %d\n" 00873 "Right Child = %d\n" 00874 "Root = %d\n" 00875 "User flags = %d\n" 00876 "Start sector = %d\n" 00877 "Stream Size = %d\n" 00878 ,element 00879 ,dir->element_type 00880 ,dir->element_colour 00881 ,dir->left_child 00882 ,dir->right_child 00883 ,dir->root 00884 ,dir->userflags 00885 ,dir->start_sector 00886 ,dir->stream_size 00887 ); 00888 00889 return OLE_OK; 00890 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int OLE_print_header | ( | struct OLE_object * | ole | ) |
Definition at line 706 of file ole.c.
References h, OLE_object::header, i, OLE_HEADER_FAT_SECTOR_COUNT_LIMIT, and OLE_OK.
Referenced by OLE_decode_file().
00707 { 00708 unsigned int i; 00709 struct OLE_header *h; 00710 00711 h = &(ole->header); 00712 00713 printf( "Minor version = %d\n" 00714 "DLL version = %d\n" 00715 "Byte order = %d\n\n" 00716 00717 "Sector shift = %d\n" 00718 "Sector size = %d\n" 00719 "Mini Sector shift = %d\n" 00720 "Mini sector size = %d\n\n" 00721 00722 "FAT sector count = %d\n" 00723 "First FAT sector = %d\n\n" 00724 00725 "Maximum ministream size = %d\n\n" 00726 00727 "First MiniFAT sector = %d\n" 00728 "MiniFAT sector count = %d\n\n" 00729 00730 "First DIF sector = %d\n" 00731 "DIF sector count = %d\n" 00732 "--------------------------------\n" 00733 ,h->minor_version 00734 ,h->dll_version 00735 ,h->byte_order 00736 ,h->sector_shift 00737 ,h->sector_size 00738 ,h->mini_sector_shift 00739 ,h->mini_sector_size 00740 ,h->fat_sector_count 00741 ,h->directory_stream_start_sector 00742 ,h->mini_cutoff_size 00743 ,h->mini_fat_start 00744 ,h->mini_fat_sector_count 00745 ,h->dif_start_sector 00746 ,h->dif_sector_count 00747 ); 00748 00749 /* Print out the FAT chain*/ 00750 for (i = 0; i < h->fat_sector_count; i++) 00751 { 00752 if (i >= OLE_HEADER_FAT_SECTOR_COUNT_LIMIT) break; /* We can't read beyond the 109th sector location*/ 00753 printf("FAT[%d] = %d\n", i, h->FAT[i]); 00754 } 00755 00756 return OLE_OK; 00757 }
Here is the caller graph for this function:

| int OLE_print_sector | ( | struct OLE_object * | ole, | |
| char * | sector, | |||
| unsigned int | bytes | |||
| ) |
Definition at line 509 of file ole.c.
Referenced by OLE_load_FAT().
00510 { 00511 int current_byte; 00512 int ubytes = bytes; 00513 00514 printf("\n"); 00515 for (current_byte = 0; current_byte < ubytes; current_byte++ ) 00516 { 00517 printf("%02X ", *(sector +current_byte)); 00518 if (((current_byte+1) %32)==0) { 00519 int j; 00520 for (j = current_byte -31; j <=current_byte; j++) 00521 { 00522 if (isalnum(*(sector +j))) printf("%c",*(sector+j)); 00523 else printf("."); 00524 } 00525 printf("\n"); 00526 } 00527 } 00528 printf("\n"); 00529 00530 return OLE_OK; 00531 }
Here is the caller graph for this function:

| int OLE_print_string | ( | char * | string, | |
| size_t | char_count | |||
| ) |
| int OLE_sectorpos | ( | struct OLE_object * | ole, | |
| int | SID | |||
| ) |
Definition at line 301 of file ole.c.
References OLE_object::header, pos, and OLE_header::sector_size.
Referenced by OLE_get_block().
00302 { 00303 int pos = 0; 00304 00305 pos = 512 +(SID *ole->header.sector_size); 00306 00307 return pos; 00308 }
Here is the caller graph for this function:

| int OLE_set_debug | ( | struct OLE_object * | ole, | |
| int | level | |||
| ) |
Definition at line 247 of file ole.c.
References OLE_object::debug, FL, LOGGER_log(), and OLE_OK.
Referenced by ripole(), and ROLE_set_parameters().
00248 { 00249 ole->debug = level; 00250 if (ole->debug > 0) LOGGER_log("%s:%d:OLE_set_debug: Debug level set to %d",FL, ole->debug); 00251 00252 return OLE_OK; 00253 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int OLE_set_filename_report_fn | ( | struct OLE_object * | ole, | |
| int(*)(char *) | ptr_to_fn | |||
| ) |
Definition at line 1516 of file ole.c.
References OLE_object::filename_report_fn, and OLE_OK.
Referenced by ripole().
01517 { 01518 ole->filename_report_fn = ptr_to_fn; 01519 return OLE_OK; 01520 }
Here is the caller graph for this function:

| int OLE_set_quiet | ( | struct OLE_object * | ole, | |
| int | level | |||
| ) |
Definition at line 221 of file ole.c.
References OLE_object::debug, OLE_OK, OLE_object::quiet, and OLE_object::verbose.
00222 { 00223 ole->quiet = level; 00224 ole->verbose = 0; 00225 ole->debug = 0; 00226 00227 return OLE_OK; 00228 }
| int OLE_set_save_unknown_streams | ( | struct OLE_object * | ole, | |
| int | level | |||
| ) |
Definition at line 272 of file ole.c.
References OLE_OK, and OLE_object::save_unknown_streams.
Referenced by ripole(), and ROLE_set_parameters().
00273 { 00274 ole->save_unknown_streams = level; 00275 00276 return OLE_OK; 00277 }
Here is the caller graph for this function:

| int OLE_set_verbose | ( | struct OLE_object * | ole, | |
| int | level | |||
| ) |
Definition at line 197 of file ole.c.
References OLE_OK, and OLE_object::verbose.
Referenced by ripole(), and ROLE_set_parameters().
Here is the caller graph for this function:

| int OLE_store_stream | ( | struct OLE_object * | ole, | |
| char * | stream_name, | |||
| char * | directory, | |||
| char * | stream, | |||
| size_t | stream_size | |||
| ) |
Definition at line 1541 of file ole.c.
References errno, f(), OLE_object::filename_report_fn, FL, FREE, LOGGER_log(), NULL, OLE_OK, OLE_VNORMAL, PLD_dprintf(), strerror(), and OLE_object::verbose.
Referenced by OLE_decode_stream().
01542 { 01543 char *full_path = NULL; 01544 01545 full_path = PLD_dprintf("%s/%s", directory, stream_name); 01546 if (full_path == NULL) 01547 { 01548 LOGGER_log("%s:%d:OLE_store_stream:ERROR: Cannot compose full filename string from '%s' and '%s'", FL, directory, stream_name); 01549 return -1; 01550 } else { 01551 FILE *f; 01552 01553 f = fopen(full_path,"wb"); 01554 if (f == NULL) 01555 { 01556 LOGGER_log("%s:%d:OLE_store_stream:ERROR: Cannot open %s for writing (%s)",FL, full_path, strerror(errno)); 01557 if (full_path) FREE(full_path); 01558 return -1; 01559 } else { 01560 size_t written_bytes; 01561 01562 written_bytes = fwrite( stream, 1, stream_size, f ); 01563 if (written_bytes != stream_size) 01564 { 01565 LOGGER_log("%s:%d:OLE_store_stream:WARNING: Only wrote %d of %d bytes to file %s",FL,written_bytes,stream_size,full_path); 01566 } 01567 fclose(f); 01568 01569 if ((OLE_VNORMAL(ole->verbose))&&(ole->filename_report_fn != NULL)) 01570 { 01571 ole->filename_report_fn( stream_name ); 01572 } 01573 } /* if file is valid*/ 01574 } /* if full_path is valid*/ 01575 01576 if (full_path) FREE(full_path); 01577 01578 return OLE_OK; 01579 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int OLE_terminate_and_return | ( | struct OLE_object * | ole, | |
| int | result | |||
| ) |
Definition at line 1626 of file ole.c.
References OLE_decode_file_done().
01627 { 01628 OLE_decode_file_done(ole); 01629 return result; 01630 }
Here is the call graph for this function:

| int OLE_version | ( | void | ) |
Definition at line 98 of file ole.c.
References LIBOLE_VERSION.
00099 { 00100 fprintf(stderr,"ripOLE: %s\n", LIBOLE_VERSION); 00101 00102 return 0; 00103 }
| unsigned char OLE_id_v1[] = { 0x0e, 0x11, 0xfc, 0x0d, 0xd0, 0xcf, 0x11, 0xe0 } |
| unsigned char OLE_id_v2[] = { 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1 } |
1.5.1