From 2eae3954257ce352d1a43b09b3dd06b6fd632390 Mon Sep 17 00:00:00 2001 From: Christophe Grenier Date: Sun, 7 Nov 2010 11:20:27 +0100 Subject: [PATCH] PhotoRec: detect asf/wmv video file size --- src/file_asf.c | 62 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/src/file_asf.c b/src/file_asf.c index d049b8de..c0ff20f4 100644 --- a/src/file_asf.c +++ b/src/file_asf.c @@ -2,7 +2,7 @@ File: file_asf.c - Copyright (C) 1998-2007 Christophe GRENIER + Copyright (C) 1998-2010 Christophe GRENIER This software is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,7 +29,7 @@ #include #include "types.h" #include "filegen.h" -#include "log.h" +#include "common.h" static void register_header_check_asf(file_stat_t *file_stat); static int header_check_asf(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); @@ -51,18 +51,62 @@ static void register_header_check_asf(file_stat_t *file_stat) register_header_check(0, asf_header,sizeof(asf_header), &header_check_asf, file_stat); } +struct asf_header_obj_s { + unsigned char object_id[16]; + uint64_t object_size; + uint32_t nbr_header_obj; + char reserved1; /* 1 */ + char reserved2; /* 2 */ +} __attribute__ ((__packed__)); + +struct asf_file_prop_s { + unsigned char object_id[16]; + uint64_t object_size; + unsigned char file_id[16]; + uint64_t file_size; + uint64_t file_date; +} __attribute__ ((__packed__)); + static int header_check_asf(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) { - if(memcmp(buffer,asf_header,sizeof(asf_header))==0) + static const unsigned char asf_header_id[16]= { + 0x30, 0x26, 0xb2, 0x75, 0x8e, 0x66, 0xcf, 0x11, + 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c + }; + static const unsigned char asf_file_prop_id[16]= { + 0xa1, 0xdc, 0xab, 0x8c, 0x47, 0xa9, 0xcf, 0x11, + 0x8e, 0xe4, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 + }; + if(memcmp(buffer, asf_header_id, sizeof(asf_header_id))==0) + { + unsigned int i; + const struct asf_header_obj_s *asf_header_obj=(const struct asf_header_obj_s *)buffer; + const struct asf_file_prop_s *asf_file_prop=(const struct asf_file_prop_s*)(asf_header_obj+1); + reset_file_recovery(file_recovery_new); + file_recovery_new->extension=file_hint_asf.extension; + for(i=0; + inbr_header_obj) && + (const unsigned char *)(asf_file_prop+1) < buffer + buffer_size; + i++) + { + if(memcmp(asf_file_prop->object_id, asf_file_prop_id, sizeof(asf_file_prop_id))==0) + { + file_recovery_new->calculated_file_size=le64(asf_file_prop->file_size); + file_recovery_new->data_check=&data_check_size; + file_recovery_new->file_check=&file_check_size; + return 1; + } + if( le64(asf_file_prop->object_size)==0 || + le64(asf_file_prop->object_size)>1024*1024) + return 1; + asf_file_prop=(const struct asf_file_prop_s *)((const char *)asf_file_prop + le64(asf_file_prop->object_size)); + } + return 1; + } + if(memcmp(buffer, asf_header, sizeof(asf_header))==0) { reset_file_recovery(file_recovery_new); file_recovery_new->extension=file_hint_asf.extension; - /* - file_recovery_new->calculated_file_size=(uint64_t)buffer[70]+(((uint64_t)buffer[71])<<8)+(((uint64_t)buffer[72])<<16)+(((uint64_t)buffer[73])<<24); - log_info("asf calculated_file_size %llu\n", (long long unsigned)file_recovery_new->calculated_file_size); - file_recovery_new->data_check=&data_check_size; - file_recovery_new->file_check=&file_check_size; - */ return 1; } return 0;