3838#include "log.h"
3939#include "memmem.h"
4040#include "setdate.h"
41+ #include "file_doc.h"
4142
4243static void register_header_check_doc (file_stat_t * file_stat );
4344static void file_check_doc (file_recovery_t * file_recovery );
4445static int header_check_doc (const unsigned char * buffer , const unsigned int buffer_size , const unsigned int safe_header_only , const file_recovery_t * file_recovery , file_recovery_t * file_recovery_new );
4546static void file_rename_doc (file_recovery_t * file_recovery );
46- static uint32_t * OLE_load_FAT (FILE * IN , const struct OLE_HDR * header );
47- static uint32_t * OLE_load_MiniFAT (FILE * IN , const struct OLE_HDR * header , const uint32_t * fat , const unsigned int fat_entries );
47+ static uint32_t * OLE_load_FAT (FILE * IN , const struct OLE_HDR * header , const uint64_t offset );
48+ static uint32_t * OLE_load_MiniFAT (FILE * IN , const struct OLE_HDR * header , const uint32_t * fat , const unsigned int fat_entries , const uint64_t offset );
4849
4950const file_hint_t file_hint_doc = {
5051 .extension = "doc" ,
@@ -67,7 +68,7 @@ const char WilcomDesignInformationDDD[56]=
6768 'D' , '\0' , 'D' , '\0' , 'D' , '\0' , '\0' , '\0'
6869};
6970
70- static void file_check_doc (file_recovery_t * file_recovery )
71+ void file_check_doc_aux (file_recovery_t * file_recovery , const uint64_t offset )
7172{
7273 unsigned char buffer_header [512 ];
7374 uint64_t doc_file_size ;
@@ -76,9 +77,9 @@ static void file_check_doc(file_recovery_t *file_recovery)
7677 unsigned int freesect_count = 0 ;
7778 const struct OLE_HDR * header = (const struct OLE_HDR * )& buffer_header ;
7879 const uint64_t doc_file_size_org = file_recovery -> file_size ;
79- file_recovery -> file_size = 0 ;
80+ file_recovery -> file_size = offset ;
8081 /*reads first sector including OLE header */
81- if (my_fseek (file_recovery -> handle , 0 , SEEK_SET ) < 0 ||
82+ if (my_fseek (file_recovery -> handle , offset , SEEK_SET ) < 0 ||
8283 fread (& buffer_header , sizeof (buffer_header ), 1 , file_recovery -> handle ) != 1 )
8384 return ;
8485#ifdef DEBUG_OLE
@@ -92,7 +93,7 @@ static void file_check_doc(file_recovery_t *file_recovery)
9293 le32 (header -> num_extra_FAT_blocks )> 50 ||
9394 le32 (header -> num_FAT_blocks )> 109 + le32 (header -> num_extra_FAT_blocks )* ((1 <<le16 (header -> uSectorShift ))- 1 ))
9495 return ;
95- if ((fat = OLE_load_FAT (file_recovery -> handle , header ))== NULL )
96+ if ((fat = OLE_load_FAT (file_recovery -> handle , header , offset ))== NULL )
9697 {
9798#ifdef DEBUG_OLE
9899 log_info ("OLE_load_FAT failed\n" );
@@ -104,11 +105,12 @@ static void file_check_doc(file_recovery_t *file_recovery)
104105 i > 0 && le32 (fat [i ])== 0xFFFFFFFF ;
105106 i -- )
106107 freesect_count ++ ;
107- doc_file_size = ((1 + (le32 (header -> num_FAT_blocks )<<le16 (header -> uSectorShift ))/4 - freesect_count )<<le16 (header -> uSectorShift ));
108+ doc_file_size = offset + ((1 + (le32 (header -> num_FAT_blocks )<<le16 (header -> uSectorShift ))/4 - freesect_count )<<le16 (header -> uSectorShift ));
108109 if (doc_file_size > doc_file_size_org )
109110 {
110111#ifdef DEBUG_OLE
111- log_info ("doc_file_size=(1+(%u<<%u)/4-%u)<<%u\n" ,
112+ log_info ("doc_file_size=%llu + (1+(%u<<%u)/4-%u)<<%u\n" ,
113+ (unsigned long long )offset ,
112114 le32 (header -> num_FAT_blocks ), le16 (header -> uSectorShift ),
113115 freesect_count , le16 (header -> uSectorShift ));
114116 log_info ("doc_file_size %llu > doc_file_size_org %llu\n" ,
@@ -143,7 +145,7 @@ static void file_check_doc(file_recovery_t *file_recovery)
143145 free (fat );
144146 return ;
145147 }
146- if (my_fseek (file_recovery -> handle , ( 1 + block )<<le16 (header -> uSectorShift ), SEEK_SET )< 0 )
148+ if (my_fseek (file_recovery -> handle , offset + (( 1 + block )<<le16 (header -> uSectorShift ) ), SEEK_SET )< 0 )
147149 {
148150#ifdef DEBUG_OLE
149151 log_info ("fseek failed\n" );
@@ -168,7 +170,8 @@ static void file_check_doc(file_recovery_t *file_recovery)
168170 sid < (1 <<le16 (header -> uSectorShift ))/sizeof (struct OLE_DIR ) && dir_entry -> type != NO_ENTRY ;
169171 sid ++ ,dir_entry ++ )
170172 {
171- if (le32 (dir_entry -> start_block ) > 0 && le32 (dir_entry -> size ) > 0 &&
173+ if (offset +
174+ le32 (dir_entry -> start_block ) > 0 && le32 (dir_entry -> size ) > 0 &&
172175 ((le32 (dir_entry -> size ) >= le32 (header -> miniSectorCutoff )
173176 && le32 (dir_entry -> start_block ) > fat_entries ) ||
174177 le32 (dir_entry -> size ) > doc_file_size ))
@@ -189,6 +192,11 @@ static void file_check_doc(file_recovery_t *file_recovery)
189192 file_recovery -> file_size = doc_file_size ;
190193}
191194
195+ static void file_check_doc (file_recovery_t * file_recovery )
196+ {
197+ file_check_doc_aux (file_recovery , 0 );
198+ }
199+
192200static const char * ole_get_file_extension (const unsigned char * buffer , const unsigned int buffer_size )
193201{
194202 const struct OLE_HDR * header = (const struct OLE_HDR * )buffer ;
@@ -489,7 +497,7 @@ static int header_check_doc(const unsigned char *buffer, const unsigned int buff
489497 return 1 ;
490498}
491499
492- static uint32_t * OLE_load_FAT (FILE * IN , const struct OLE_HDR * header )
500+ static uint32_t * OLE_load_FAT (FILE * IN , const struct OLE_HDR * header , const uint64_t offset )
493501{
494502 uint32_t * fat ;
495503 uint32_t * dif ;
@@ -504,7 +512,7 @@ static uint32_t *OLE_load_FAT(FILE *IN, const struct OLE_HDR *header)
504512 i < le32 (header -> num_extra_FAT_blocks ) && block != 0xFFFFFFFF && block != 0xFFFFFFFE ;
505513 i ++ , block = le32 (dif [109 + i * (((1 <<le16 (header -> uSectorShift ))/4 )- 1 )]))
506514 {
507- if (my_fseek (IN , ( 1 + block )<<le16 (header -> uSectorShift ), SEEK_SET ) < 0 )
515+ if (my_fseek (IN , offset + (( 1 + block )<<le16 (header -> uSectorShift ) ), SEEK_SET ) < 0 )
508516 {
509517 free (dif );
510518 return NULL ;
@@ -525,7 +533,7 @@ static uint32_t *OLE_load_FAT(FILE *IN, const struct OLE_HDR *header)
525533 j < le32 (header -> num_FAT_blocks );
526534 j ++ , data += (1 <<le16 (header -> uSectorShift )))
527535 {
528- if (my_fseek (IN , ( 1 + le32 (dif [j ]))<<le16 (header -> uSectorShift ), SEEK_SET )< 0 )
536+ if (my_fseek (IN , offset + (( 1 + le32 (dif [j ]))<<le16 (header -> uSectorShift ) ), SEEK_SET )< 0 )
529537 {
530538 free (dif );
531539 free (fat );
@@ -545,7 +553,7 @@ static uint32_t *OLE_load_FAT(FILE *IN, const struct OLE_HDR *header)
545553
546554static void * OLE_read_stream (FILE * IN ,
547555 const uint32_t * fat , const unsigned int fat_entries , const unsigned int uSectorShift ,
548- const unsigned int block_start , const unsigned int len )
556+ const unsigned int block_start , const unsigned int len , const uint64_t offset )
549557{
550558 unsigned char * dataPt ;
551559 unsigned int block ;
@@ -560,7 +568,7 @@ static void *OLE_read_stream(FILE *IN,
560568 free (dataPt );
561569 return NULL ;
562570 }
563- if (my_fseek (IN , ( 1 + block )<<uSectorShift , SEEK_SET )< 0 )
571+ if (my_fseek (IN , offset + (( 1 + block )<<uSectorShift ) , SEEK_SET )< 0 )
564572 {
565573 free (dataPt );
566574 return NULL ;
@@ -574,7 +582,7 @@ static void *OLE_read_stream(FILE *IN,
574582 return dataPt ;
575583}
576584
577- static uint32_t * OLE_load_MiniFAT (FILE * IN , const struct OLE_HDR * header , const uint32_t * fat , const unsigned int fat_entries )
585+ static uint32_t * OLE_load_MiniFAT (FILE * IN , const struct OLE_HDR * header , const uint32_t * fat , const unsigned int fat_entries , const uint64_t offset )
578586{
579587 unsigned char * minifat_pos ;
580588 uint32_t * minifat ;
@@ -587,7 +595,7 @@ static uint32_t *OLE_load_MiniFAT(FILE *IN, const struct OLE_HDR *header, const
587595 block = le32 (header -> MiniFat_block );
588596 for (i = 0 ; i < le32 (header -> csectMiniFat ) && block < fat_entries ; i ++ )
589597 {
590- if (my_fseek (IN , (( uint64_t )1 + block ) << le16 (header -> uSectorShift ), SEEK_SET ) < 0 )
598+ if (my_fseek (IN , offset + ((( uint64_t )1 + block ) << le16 (header -> uSectorShift ) ), SEEK_SET ) < 0 )
591599 {
592600 free (minifat );
593601 return NULL ;
@@ -794,7 +802,8 @@ static void *OLE_read_ministream(unsigned char *ministream,
794802
795803static void OLE_parse_summary (FILE * file , const uint32_t * fat , const unsigned int fat_entries ,
796804 const struct OLE_HDR * header , const unsigned int ministream_block , const unsigned int ministream_size ,
797- const unsigned int block , const unsigned int len , const char * * ext , char * * title , time_t * file_time )
805+ const unsigned int block , const unsigned int len , const char * * ext , char * * title , time_t * file_time ,
806+ const uint64_t offset )
798807{
799808 unsigned char * summary = NULL ;
800809 if (len < 48 || len > 1024 * 1024 )
@@ -806,11 +815,11 @@ static void OLE_parse_summary(FILE *file, const uint32_t *fat, const unsigned in
806815 const unsigned int mini_fat_entries = (le32 (header -> csectMiniFat ) << le16 (header -> uSectorShift )) / 4 ;
807816 uint32_t * minifat ;
808817 unsigned char * ministream ;
809- if ((minifat = OLE_load_MiniFAT (file , header , fat , fat_entries ))== NULL )
818+ if ((minifat = OLE_load_MiniFAT (file , header , fat , fat_entries , offset ))== NULL )
810819 return ;
811820 ministream = (unsigned char * )OLE_read_stream (file ,
812821 fat , fat_entries , le16 (header -> uSectorShift ),
813- ministream_block , ministream_size );
822+ ministream_block , ministream_size , offset );
814823 if (ministream != NULL )
815824 {
816825 summary = (unsigned char * )OLE_read_ministream (ministream ,
@@ -824,7 +833,7 @@ static void OLE_parse_summary(FILE *file, const uint32_t *fat, const unsigned in
824833 else
825834 summary = (unsigned char * )OLE_read_stream (file ,
826835 fat , fat_entries , le16 (header -> uSectorShift ),
827- block , len );
836+ block , len , offset );
828837 if (summary != NULL )
829838 {
830839 OLE_parse_summary_aux (summary , len , ext , title , file_time );
@@ -864,7 +873,7 @@ static void file_rename_doc(file_recovery_t *file_recovery)
864873 fclose (file );
865874 return ;
866875 }
867- if ((fat = OLE_load_FAT (file , header ))== NULL )
876+ if ((fat = OLE_load_FAT (file , header , 0 ))== NULL )
868877 {
869878 fclose (file );
870879 return ;
@@ -1039,7 +1048,7 @@ static void file_rename_doc(file_recovery_t *file_recovery)
10391048 OLE_parse_summary (file , fat , fat_entries , header ,
10401049 ministream_block , ministream_size ,
10411050 le32 (dir_entry -> start_block ), le32 (dir_entry -> size ),
1042- & ext , & title , & file_time );
1051+ & ext , & title , & file_time , 0 );
10431052 }
10441053 else if (memcmp (dir_entry -> name ,"P\0o\0w\0e\0r\0P\0o\0i\0n\0t\0 \0D\0o\0c\0u\0m\0e\0n\0t\0\0\0" , 40 )== 0 )
10451054 ext = "ppt" ;
0 commit comments