00001 #ifdef _MSC_VER
00002 #include <Windows.h>
00003 #endif
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include <ctype.h>
00007 #include <string.h>
00008 #include <errno.h>
00009 #include <sys/stat.h>
00010 #include <sys/types.h>
00011
00012 #include "logger.h"
00013 #include "pldstr.h"
00014 #include "bt-int.h"
00015 #include "bytedecoders.h"
00016 #include "olestream-unwrap.h"
00017 #include "ole.h"
00018
00020 #define OLE_SECTORID_FREE -1
00021 #define OLE_SECTORID_ENDOFCHAIN -2
00022 #define OLE_SECTORID_SAT -3
00023 #define OLE_SECTORID_MSAT -4
00025 #include "MALLOC.h"
00026
00027
00028
00029 #define header_id(x) ((x) +0)
00030 #define header_clid(x) ((x) +0x08)
00031 #define header_minor_version(x) ((x) +0x18)
00032 #define header_dll_version(x) ((x) +0x1a)
00033 #define header_byte_order(x) ((x) +0x1c)
00034 #define header_sector_shift(x) ((x) +0x1e)
00035 #define header_mini_sector_shift(x) ((x) +0x20)
00036 #define header_fat_sector_count(x) ((x) +0x2c)
00037 #define header_directory_stream_start_sector(x) ((x) +0x30)
00038 #define header_mini_cutoff_size(x) ((x) +0x38)
00039 #define header_mini_fat_start(x) ((x) +0x3c)
00040 #define header_mini_fat_sector_count(x) ((x) +0x40)
00041 #define header_dif_start_sector(x) ((x) +0x44)
00042 #define header_dif_sector_count(x) ((x) +0x48)
00043 #define header_fat_sectors(x) ((x) +0x4c)
00044
00045
00046 #define pps_rawname(x) ((x) +0)
00047 #define pps_sizeofname(x) ((x) +0x40)
00048 #define pps_type(x) ((x) +0x42)
00049 #define pps_previouspps(x) ((x) +0x44)
00050 #define pps_nextpps(x) ((x) +0x48)
00051 #define pps_directorypps(x) ((x) +0x4c)
00052 #define pps_time1seconds(x) ((x) +0x64)
00053 #define pps_time1days(x) ((x) +0x68)
00054 #define pps_time2seconds(x) ((x) +0x6c)
00055 #define pps_time2days(x) ((x) +0x70)
00056 #define pps_propertystart(x) ((x) +0x74)
00057 #define pps_sizeofproperty(x) ((x) +0x78)
00058
00059
00060 #define LEN_BYTE 1
00061 #define LEN_USHORT 2
00062 #define LEN_ULONG 4
00063
00064
00065 #define STGTY_INVALID 0
00066 #define STGTY_STORAGE 1
00067 #define STGTY_STREAM 2
00068 #define STGTY_LOCKBYTES 3
00069 #define STGTY_PROPERTY 4
00070 #define STGTY_ROOT 5
00071
00072
00073 #define DE_RED 0
00074 #define DE_BLACK 1
00075
00076 #define DOLE if (OLE_DNORMAL(ole->debug))
00077 #define VOLE if (ole->verbose)
00078
00079
00080 unsigned char OLE_id_v2[]={ 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1 };
00081 unsigned char OLE_id_v1[]={ 0x0e, 0x11, 0xfc, 0x0d, 0xd0, 0xcf, 0x11, 0xe0 };
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 int OLE_version( void )
00099 {
00100 fprintf(stderr,"ripOLE: %s\n", LIBOLE_VERSION);
00101
00102 return 0;
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 int OLE_init( struct OLE_object *ole )
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 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 int OLE_dir_init(struct OLE_directory_entry *dir )
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 };
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 int OLE_set_verbose( struct OLE_object *ole, int level )
00198 {
00199 ole->verbose = level;
00200 return OLE_OK;
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 int OLE_set_quiet( struct OLE_object *ole, int level )
00222 {
00223 ole->quiet = level;
00224 ole->verbose = 0;
00225 ole->debug = 0;
00226
00227 return OLE_OK;
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 int OLE_set_debug( struct OLE_object *ole, int level )
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 }
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 int OLE_set_save_unknown_streams( struct OLE_object *ole, int level )
00273 {
00274 ole->save_unknown_streams = level;
00275
00276 return OLE_OK;
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 int OLE_sectorpos( struct OLE_object *ole, int SID )
00302 {
00303 int pos = 0;
00304
00305 pos = 512 +(SID *ole->header.sector_size);
00306
00307 return pos;
00308 }
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 int OLE_get_block( struct OLE_object *ole, int block_index, unsigned char *block_buffer )
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
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
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
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 }
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 int OLE_get_miniblock( struct OLE_object *ole, int block_index, unsigned char *block_buffer )
00415 {
00416
00417
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 }
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 int OLE_dbstosbs( char *raw_string, size_t byte_count, char *clean_string, int clean_string_len )
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 }
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 int OLE_print_string( char *string, size_t char_count)
00485 {
00486 while (char_count--)
00487 {
00488 printf("%c",*string);
00489 string += 2;
00490 }
00491 return OLE_OK;
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 int OLE_print_sector( struct OLE_object *ole, char *sector, unsigned int bytes)
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 }
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 int OLE_is_file_OLE( struct OLE_object *ole )
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 }
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573 int OLE_get_header( struct OLE_object *ole )
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 }
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602 int OLE_convert_header( struct OLE_object *ole )
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 }
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671 int OLE_header_sanity_check( struct OLE_object *ole )
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 }
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706 int OLE_print_header( struct OLE_object *ole )
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
00750 for (i = 0; i < h->fat_sector_count; i++)
00751 {
00752 if (i >= OLE_HEADER_FAT_SECTOR_COUNT_LIMIT) break;
00753 printf("FAT[%d] = %d\n", i, h->FAT[i]);
00754 }
00755
00756 return OLE_OK;
00757 }
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776 int OLE_convert_directory( struct OLE_object *ole, unsigned char *buf, struct OLE_directory_entry *dir )
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 }
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863 int OLE_print_directory( struct OLE_object *ole, struct OLE_directory_entry *dir )
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 }
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908 int OLE_load_FAT( struct OLE_object *ole )
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
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
00940
00941
00942
00943
00944
00945
00946
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
00960
00961
00962
00963
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
00980 }
00981
00982
00983
00984
00985
00986
00987
00988 fat_block_end = fat_block +ole->header.sector_size -LEN_ULONG;
00989
00990
00991
00992
00993
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
01015
01016
01017
01018
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
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
01066
01067
01068
01069
01070
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 }
01079
01080 if (fat_block) FREE(fat_block);
01081 }
01082
01083 }
01084
01085 return OLE_OK;
01086 }
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106 int OLE_follow_chain( struct OLE_object *ole, int FAT_sector_start )
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
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
01144
01145 if (next_sector == current_sector) break;
01146
01147
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 }
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188 int OLE_follow_minichain( struct OLE_object *ole, int miniFAT_sector_start )
01189 {
01190
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
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
01205
01206
01207
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
01237
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 }
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263 unsigned char *OLE_load_minichain( struct OLE_object *ole, int miniFAT_sector_start )
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
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
01281
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
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
01308
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 }
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340 unsigned char *OLE_load_chain( struct OLE_object *ole, int FAT_sector_start )
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
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 }
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426 int OLE_open_file( struct OLE_object *ole, char *fullpath )
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 }
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477 int OLE_open_directory( struct OLE_object *ole, char *directory )
01478 {
01479 int result=0;
01480
01481 #ifndef _MSC_VER
01482 result = mkdir( directory, S_IRWXU );
01483 #else
01484 result = CreateDirectory( directory,NULL);
01485
01486
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 }
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516 int OLE_set_filename_report_fn( struct OLE_object *ole, int (*ptr_to_fn)(char *) )
01517 {
01518 ole->filename_report_fn = ptr_to_fn;
01519 return OLE_OK;
01520 }
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541 int OLE_store_stream( struct OLE_object *ole, char *stream_name, char *directory, char *stream, size_t stream_size )
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 }
01574 }
01575
01576 if (full_path) FREE(full_path);
01577
01578 return OLE_OK;
01579 }
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597 int OLE_decode_file_done( struct OLE_object *ole )
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 }
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626 int OLE_terminate_and_return( struct OLE_object *ole, int result )
01627 {
01628 OLE_decode_file_done(ole);
01629 return result;
01630 }
01631
01632
01633 #ifdef RIPOLE_WALK_TREE
01634 int OLE_walk_tree( struct OLE_object *ole, char *fname, char *decode_path, int depth )
01635 {
01636
01639 if (depth > 100) return 0;
01640 if (ole->total_file_count > 10000) return 0;
01641 if (element_type < 0) return 0;
01642
01643 switch (element_type) {
01644
01645 case STGTY_ROOT:
01649 DOLE LOGGER_log("%s:%d:OLE_walk_tree:DEBUG: Loading ministream/SmallBlockArray",FL);
01650 ole->ministream = OLE_load_chain( ole, adir->start_sector );
01651 if (ole->ministream == NULL) return OLEER_MINISTREAM_READ_FAIL;
01652 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: ministream done",FL);
01653 }
01654
01655 } else if (adir->element_type == STGTY_STORAGE) {
01659 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: Item is directory, start child is at index %d\n",FL,i);
01660 ole->ministream = OLE_load_chain( ole, adir->start_sector );
01661 if (ole->ministream == NULL) return OLEER_MINISTREAM_READ_FAIL;
01662 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: DIRECTORY ministream done",FL);
01663
01664
01665 }
01666 #endif
01667
01668
01669
01670 int OLE_decode_stream( struct OLE_object *ole, struct OLE_directory_entry *adir, char *decode_path )
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
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
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
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 }
01737
01738 else 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 }
01750
01751
01752
01753 if (stream_data) FREE(stream_data);
01754
01755 return result;
01756 }
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774 int OLE_decode_file( struct OLE_object *ole, char *fname, char *decode_path )
01775 {
01776 unsigned char *current_property, *property_limit;
01777 int result = 0;
01778 int i;
01779
01780
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
01786
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
01792
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
01798
01799
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
01820
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
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
01866
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
01876
01877 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: DIRECTORY ministream done",FL);
01878
01879 } else if (adir->element_type == STGTY_STREAM) {
01883
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
01892
01893
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
01902
01903 current_property += 128;
01904 i++;
01905
01906 }
01907
01908 DOLE LOGGER_log("%s:%d:OLE_decode_file:DEBUG: Finished",FL);
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919 return OLE_OK;
01920 }