summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorrobi <robi>2011-05-15 19:11:22 +0000
committerrobi <robi>2011-05-15 19:11:22 +0000
commit7c887a9e437e5e842a1ad0450101ee99be7ed626 (patch)
tree4b5bf0731104a90be151c3e4746da6e826e344f6 /src
parentc9ddfc8fe6e3356f3da578dae3c7b0276be32e39 (diff)
first step, magic_scan_engine ext4
Diffstat (limited to 'src')
-rw-r--r--src/ext4magic.c5
-rw-r--r--src/inode.c86
-rw-r--r--src/inode.h3
-rw-r--r--src/magic_block_scan.c124
4 files changed, 213 insertions, 5 deletions
diff --git a/src/ext4magic.c b/src/ext4magic.c
index f284870..5b0899a 100644
--- a/src/ext4magic.c
+++ b/src/ext4magic.c
@@ -1004,8 +1004,11 @@ if ((mode & COMMAND_INODE) && (mode & RECOVER_INODE))
imap = NULL;
if (bmap && (!(current_fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS)))
magic_block_scan3(des_dir, t_after);
- else
+ else{
if (bmap) printf("The MAGIC Funktion is currently only for ext3 filesystems available\n");
+// magic_block_scan4(des_dir,t_after);
+
+ }
}
clear_dir_list(dir);
}
diff --git a/src/inode.c b/src/inode.c
index ecc28a8..5ce54ad 100644
--- a/src/inode.c
+++ b/src/inode.c
@@ -891,6 +891,7 @@ struct ext2_inode_large* new_inode(){
struct ext2_inode_large *inode;
__u32 a_time;
time_t help_time;
+ struct ext3_extent_header *p_extent_header;
time( &help_time );
a_time = (__u32) help_time;
@@ -904,11 +905,96 @@ struct ext2_inode_large* new_inode(){
inode->i_links_count = 1 ;
if (current_fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) {
inode->i_flags = EXT4_EXTENTS_FL ;
+ p_extent_header = (struct ext3_extent_header*) inode->i_block;
+ p_extent_header->eh_magic = ext2fs_cpu_to_le16(EXT3_EXT_MAGIC) ;
+ p_extent_header->eh_max = ext2fs_cpu_to_le16(4);
}
return inode;
}
+//add extent to inode
+int inode_add_extent(struct ext2_inode_large* inode , blk_t blk , void *buf, int flag) {
+ struct ext3_extent_idx *idx;
+ struct ext3_extent_header *header;
+ struct ext3_extent_header *data_header;
+ struct ext3_extent *extent;
+ unsigned long long i_size;
+ __u32 l_block,l_count,l_start,i;
+
+ header = (struct ext3_extent_header*) inode->i_block;
+ if (flag && buf){
+ data_header = (struct ext3_extent_header*) buf;
+ if (ext2fs_le32_to_cpu(header->eh_entries) >= ext2fs_le32_to_cpu(header->eh_max)){
+ fprintf(stderr," Error: can not add a extent to inode\n");
+ return 0;
+ }
+ idx = (struct ext3_extent_idx*) (header + (ext2fs_le16_to_cpu(header->eh_entries) + 1));
+
+ if (! header->eh_entries)
+ header->eh_depth = ext2fs_cpu_to_le16(ext2fs_le16_to_cpu(data_header->eh_depth) +1);
+
+ idx->ei_leaf = ext2fs_cpu_to_le32(blk);
+ idx->ei_leaf_hi = 0;
+ idx->ei_unused = 0;
+ l_count = 0;
+ extent = (struct ext3_extent*)(data_header + 1);
+ l_start = ext2fs_le32_to_cpu(extent->ee_block);
+ for (i=1; i<=ext2fs_le16_to_cpu(data_header->eh_entries); i++){
+ l_count += ext2fs_le16_to_cpu(extent->ee_len);
+ l_block = ext2fs_le32_to_cpu(extent->ee_block) + ext2fs_le16_to_cpu(extent->ee_len) ;
+ extent++;
+ }
+
+ idx->ei_block = ext2fs_cpu_to_le32(l_start);
+ header->eh_entries = ext2fs_cpu_to_le16(ext2fs_le16_to_cpu(header->eh_entries) + 1 );
+//blockhex (stdout, (void*) inode->i_block, 0, 60);
+ i_size = (unsigned long long)(inode->i_size | ((unsigned long long)inode->i_size_high << 32));
+ i_size += (l_block * current_fs->blocksize);
+ inode->i_size = i_size & 0xffffffff ;
+ inode->i_size_high = i_size >> 32 ;
+ inode->i_blocks += ((l_count + 1) * (current_fs->blocksize / 512)) ;
+blockhex (stdout, (void*) inode, 0, 128);
+ }
+
+return 1;
+}
+
+
+
+//search the last data block ext4-inode
+blk_t get_last_block_ext4(struct ext2_inode_large* inode){
+ blk_t blk;
+ struct ext3_extent_idx *idx;
+ struct ext3_extent_header *header;
+ struct ext3_extent *extent;
+ unsigned char *buf = NULL;
+
+ buf = malloc(current_fs->blocksize);
+ if (!buf) return 0;
+
+ header = (struct ext3_extent_header*) inode->i_block;
+ while (ext2fs_le16_to_cpu(header->eh_depth)){
+ idx = (struct ext3_extent_idx*) (header + (ext2fs_le16_to_cpu(header->eh_entries)));
+
+ if(io_channel_read_blk ( current_fs->io,ext2fs_le32_to_cpu(idx->ei_leaf), 1, buf )){
+ fprintf(stderr,"Error read block %lu\n",ext2fs_le32_to_cpu(idx->ei_leaf));
+ return 0;
+ }
+
+ header = (struct ext3_extent_header*) buf ;
+
+ }
+ extent = (struct ext3_extent*)(header + ext2fs_le16_to_cpu(header->eh_entries));
+
+ blk = ext2fs_le32_to_cpu(extent->ee_start) + ext2fs_le16_to_cpu(extent->ee_len);
+
+ if (buf) free(buf);
+return --blk;
+}
+
+
+
//add a block to inode
int inode_add_block(struct ext2_inode_large* inode , blk_t blk , __u32 size) {
int i = 0 ;
diff --git a/src/inode.h b/src/inode.h
index 30eb16a..3588395 100644
--- a/src/inode.h
+++ b/src/inode.h
@@ -75,5 +75,8 @@ struct ext2_inode_large* new_inode(); //create a new inode
int inode_add_block(struct ext2_inode_large* , blk_t , __u32); //add a block to inode
int inode_add_meta_block(struct ext2_inode_large*, blk_t, blk_t*, blk_t*,unsigned char* ); //add the ext3 indirect Blocks to the inode
+//functions in develop
+int inode_add_extent(struct ext2_inode_large*, blk_t, void*, int); //add extent to inode
+blk_t get_last_block_ext4(struct ext2_inode_large*); //search the last data block ext4-inode
#endif
diff --git a/src/magic_block_scan.c b/src/magic_block_scan.c
index 743407f..5b72a31 100644
--- a/src/magic_block_scan.c
+++ b/src/magic_block_scan.c
@@ -158,7 +158,7 @@ static int file_data_correct_size(struct found_data_t* this, int size){
i_size -= (current_fs->blocksize - size);
this->inode->i_size = i_size & 0xffffffff ;
this->inode->i_size_high = i_size >> 32 ;
- if (i_size <= (12 * current_fs->blocksize)){
+ if ((i_size <= (12 * current_fs->blocksize))&&(!(this->inode->i_flags & EXT4_EXTENTS_FL))) {
if(this->inode->i_block[EXT2_IND_BLOCK]){
this->inode->i_block[EXT2_IND_BLOCK] = 0;
this->inode->i_block[EXT2_DIND_BLOCK] = 0;
@@ -326,14 +326,13 @@ static int check_meta4_block(unsigned char *block_buf, blk_t blk, __u32 size){
if(!((block_buf[0] == 0x0a) && (block_buf[1] == (unsigned char)0xf3)))
return 0;
- p_h16 = (__u16*)block_buf+2;
+ p_h16 = (__u16*)(block_buf+2);
h16 = ext2fs_le16_to_cpu(*p_h16);
- p_h16 = (__u16*)block_buf+4;
+ p_h16 = (__u16*)(block_buf+4);
if (ext2fs_le16_to_cpu(*p_h16) != (__u16)((current_fs->blocksize -12)/ 12))
return 0;
if ((!h16) || (h16 > ext2fs_le16_to_cpu(*p_h16)))
return 0;
-
return 1 ;
}
@@ -392,6 +391,14 @@ static int check_acl_block(unsigned char *block_buf, blk_t blk, __u32 size){
+static int add_ext4_extent_idx_data(struct found_data_t* this, void *buf, blk_t blk){
+ int ret;
+ ret = inode_add_extent(this->inode ,blk, buf, 1);
+ this->last = get_last_block_ext4(this->inode);
+ return ret;
+}
+
+
static int add_ext3_file_meta_data(struct found_data_t* this, unsigned char *buf, blk_t blk){
blk_t next_meta = 0;
@@ -1016,3 +1023,112 @@ if (cookie) magic_close(cookie);
if (cookie_f) magic_close(cookie_f);
} //end
+
+
+//FIXME NEW ---------------------------------------------------------------------------------------------------------
+//main of the magic_scan_engine for ext4
+int magic_block_scan4(char* des_dir, __u32 t_after){
+magic_t cookie = 0;
+magic_t cookie_f = 0;
+struct ext3_extent_header *p_extent_header;
+struct ext3_extent *p_extent;
+struct ext3_extent_idx *p_extent_idx;
+struct ext2fs_struct_loc_generic_bitmap *ds_bmap;
+struct found_data_t *file_data = NULL;
+blk_t blk[2] ;
+blk_t first_b;
+blk_t last_rec;
+unsigned char *v_buf = NULL;
+unsigned char *buf ;
+char *magic_buf = NULL;
+unsigned char *tmp_buf = NULL;
+int blocksize, ds_retval,count,i,ret;
+__u32 scan,follow;//, size;
+
+
+printf("MAGIC-3 : start ext4-magic-scan search. Experimental in develop \n");
+blocksize = current_fs->blocksize ;
+count = 0;
+blk[0] = 0;
+cookie = magic_open(MAGIC_MIME | MAGIC_NO_CHECK_COMPRESS | MAGIC_NO_CHECK_ELF );
+cookie_f = magic_open(MAGIC_NO_CHECK_COMPRESS | MAGIC_NO_CHECK_ELF | MAGIC_RAW );
+if ((! cookie) || magic_load(cookie, NULL) || (! cookie_f) || magic_load(cookie_f, NULL)){
+ fprintf(stderr,"ERROR: can't find libmagic\n");
+ goto errout;
+}
+v_buf = malloc(blocksize * (MAX_RANGE+1));
+buf = v_buf + blocksize ;
+tmp_buf = malloc(blocksize);
+magic_buf = malloc(100);
+if ((! v_buf) || (! magic_buf) || (! tmp_buf)){
+ fprintf(stderr,"ERROR: can't allocate memory\n");
+ goto errout;
+}
+
+ds_retval = init_block_bitmap_list(&d_bmap, t_after);
+while (ds_retval){
+ ds_retval = next_block_bitmap(d_bmap);
+ if (ds_retval == 2 )
+ continue;
+ if (d_bmap && ds_retval ){
+ ds_bmap = (struct ext2fs_struct_loc_generic_bitmap *) d_bmap;
+
+ count = 0;
+ blk[0] = 0;
+ follow = 0;
+ count = get_range(blk ,ds_bmap, buf);
+
+ while (count){
+#ifdef DEBUG_MAGIC_SCAN
+ printf(" %lu %lu %d\n", blk[0],blk[1],count);
+#endif
+ for (i=0 ; i< count; i++){
+// printf(">>>>> %lu \n",blk[0]+i);
+
+ if ((check_dir_block(buf +(i*blocksize), blk[0]+i,1)) ||
+ (check_acl_block(buf+(i*blocksize), blk[0]+i,1))){
+ ext2fs_mark_generic_bitmap(bmap, blk[0]+i);
+// printf ("<<> %lu DIR-BLOCK \n",blk[0]+i);
+ continue;
+ }
+ if (check_meta4_block(buf+(i*blocksize), blk[0]+i,1)){
+// printf ("<<> %lu IDX \n",blk[0]+i);
+ p_extent_header=(struct ext3_extent_header*)(buf+(i*blocksize));
+ if (! ext2fs_le16_to_cpu(p_extent_header->eh_depth)){ //FIXME Indextiefe
+ p_extent=(struct ext3_extent*)(p_extent_header +1) ;
+ if (! ext2fs_le32_to_cpu(p_extent->ee_block)) { //FIXME Fileanfang
+ first_b = ext2fs_le32_to_cpu(p_extent->ee_start);
+ if(( ext2fs_test_block_bitmap( bmap,first_b)) ||
+ (io_channel_read_blk (current_fs->io,first_b,1,tmp_buf ))){
+ fprintf(stderr,"ERROR: while read block %10lu\n",first_b);
+ }
+ else{
+ scan = magic_check_block(tmp_buf, cookie, cookie_f , magic_buf , blocksize ,first_b, 1);
+ file_data = new_file_data(first_b,scan,magic_buf,tmp_buf,&follow);
+ if ((file_data) &&
+ (add_ext4_extent_idx_data(file_data, (void*) p_extent_header, blk[0]+i))){
+ io_channel_read_blk (current_fs->io, file_data->last, 1, tmp_buf);
+ file_data = soft_border(des_dir, tmp_buf, file_data, &follow, 0 ,&last_rec, 0x7);
+ }
+ }
+ }
+ }
+ blk[0] = blk[0] - count + i;
+ i = count;
+ } //ext4meta
+
+ } //for i
+ blk[0] += (i)?i:1;
+ count = get_range(blk ,ds_bmap,buf);
+ } //count
+ } //ds_bmap
+}//ds_retval
+
+errout:
+if (v_buf) free(v_buf);
+if (tmp_buf) free(tmp_buf);
+if (magic_buf) free(magic_buf);
+if (cookie) magic_close(cookie);
+if (cookie_f) magic_close(cookie_f);
+}//funcion
+//--------END----------