summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2013-08-28 08:29:32 +0200
committerChristophe Grenier <grenier@cgsecurity.org>2013-08-28 08:29:32 +0200
commitda8028ea3fb282cee6fd54f4ac8c8a53dacfa967 (patch)
treed52e4641fd338d51423cd1bc9f38e120d3e60ad6 /src
parented174946a0dd7c01650e43edec55d56a3373284a (diff)
TestDisk: handle ext4 with 64 bit blocks (EXT4_FEATURE_INCOMPAT_64BIT)
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am8
-rw-r--r--src/ext2.c45
-rw-r--r--src/ext2.h54
-rw-r--r--src/ext2_common.c92
-rw-r--r--src/ext2_common.h32
-rw-r--r--src/file_ext.c18
-rw-r--r--src/file_ext2.c18
7 files changed, 188 insertions, 79 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 00c86ed..d2bca53 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -17,8 +17,8 @@ EXTRA_PROGRAMS = photorecf
base_C = autoset.c common.c crc.c ewf.c fnctdsk.c hdaccess.c hdcache.c hdwin32.c hidden.c hpa_dco.c intrf.c iso.c list_sort.c log.c log_part.c misc.c msdos.c parti386.c partgpt.c parthumax.c partmac.c partsun.c partnone.c partxbox.c io_redir.c ntfs_io.c ntfs_utl.c partauto.c sudo.c unicode.c win32.c
base_H = alignio.h autoset.h common.h crc.h ewf.h fnctdsk.h hdaccess.h hdwin32.h hidden.h guid_cmp.h guid_cpy.h hdcache.h hpa_dco.h intrf.h iso.h iso9660.h lang.h list.h list_sort.h log.h log_part.h misc.h types.h io_redir.h msdos.h ntfs_utl.h parti386.h partgpt.h parthumax.h partmac.h partsun.h partxbox.h partauto.h sudo.h unicode.h win32.h
-fs_C = analyse.c bfs.c bsd.c btrfs.c cramfs.c exfat.c fat.c fatx.c ext2.c jfs.c gfs2.c hfs.c hfsp.c hpfs.c luks.c lvm.c md.c netware.c ntfs.c rfs.c savehdr.c sun.c swap.c sysv.c ufs.c vmfs.c wbfs.c xfs.c zfs.c
-fs_H = analyse.h bfs.h bsd.h btrfs.h cramfs.h exfat.h fat.h fatx.h ext2.h jfs_superblock.h jfs.h gfs2.h hfs.h hfsp.h hpfs.h luks.h lvm.h md.h netware.h ntfs.h rfs.h savehdr.h sun.h swap.h sysv.h ufs.h vmfs.h wbfs.h xfs.h zfs.h
+fs_C = analyse.c bfs.c bsd.c btrfs.c cramfs.c exfat.c fat.c fatx.c ext2.c ext2_common.c jfs.c gfs2.c hfs.c hfsp.c hpfs.c luks.c lvm.c md.c netware.c ntfs.c rfs.c savehdr.c sun.c swap.c sysv.c ufs.c vmfs.c wbfs.c xfs.c zfs.c
+fs_H = analyse.h bfs.h bsd.h btrfs.h cramfs.h exfat.h fat.h fatx.h ext2.h ext2_common.h jfs_superblock.h jfs.h gfs2.h hfs.h hfsp.h hpfs.h luks.h lvm.h md.h netware.h ntfs.h rfs.h savehdr.h sun.h swap.h sysv.h ufs.h vmfs.h wbfs.h xfs.h zfs.h
testdisk_ncurses_C = addpart.c addpartn.c adv.c askloc.c chgarch.c chgarchn.c chgtype.c chgtypen.c dimage.c dirn.c dirpart.c diskacc.c diskcapa.c edit.c ext2_sb.c ext2_sbn.c fat1x.c fat32.c fat_adv.c fat_cluster.c fatn.c geometry.c geometryn.c godmode.c hiddenn.c intrface.c intrfn.c nodisk.c ntfs_adv.c ntfs_fix.c ntfs_udl.c parti386n.c partgptn.c partmacn.c partsunn.c partxboxn.c tanalyse.c tbanner.c tdelete.c tdiskop.c tdisksel.c testdisk.c texfat.c thfs.c tload.c tlog.c tmbrcode.c tntfs.c toptions.c tpartwr.c
testdisk_ncurses_H = addpart.h addpartn.h adv.h askloc.h chgarch.h chgarchn.h chgtype.h chgtypen.h dimage.h dirn.h dirpart.h diskacc.h diskcapa.h edit.h ext2_sb.h ext2_sbn.h fat1x.h fat32.h fat_adv.h fat_cluster.h fatn.h geometry.h geometryn.h godmode.h hiddenn.h intrface.h intrfn.h nodisk.h ntfs_fix.h ntfs_udl.h partgptn.h parti386n.h partmacn.h partsunn.h partxboxn.h tanalyse.h tdelete.h tdiskop.h tdisksel.h texfat.h thfs.h tload.h tlog.h tmbrcode.h tntfs.h toptions.h tpartwr.h
@@ -292,7 +292,7 @@ file_C = filegen.c \
file_xz.c \
file_zip.c
-file_H = ext2.h filegen.h file_jpg.h file_sp3.h file_tar.h file_tiff.h file_txt.h ole.h pe.h suspend.h
+file_H = ext2.h ext2_common.h filegen.h file_jpg.h file_sp3.h file_tar.h file_tiff.h file_txt.h ole.h pe.h suspend.h
photorec_C = photorec.c phcfg.c addpart.c dir.c exfatp.c ext2grp.c ext2_dir.c ext2p.c fat_dir.c fatp.c file_found.c geometry.c ntfs_dir.c ntfsp.c poptions.c sessionp.c setdate.c dfxml.c list.c
@@ -309,7 +309,7 @@ qphotorec_SOURCES = qmainrec.cpp qphotorec.cpp qphotorec.h qphotorec.qrc qphbs.c
nodist_qphotorec_SOURCES = moc_qphotorec.cpp rcc_qphotorec.cpp
-fidentify_SOURCES = fidentify.c common.c common.h phcfg.c phcfg.h setdate.c setdate.h $(file_C) $(file_H) log.c log.h crc.c crc.h fat_common.c suspend_no.c
+fidentify_SOURCES = fidentify.c common.c common.h phcfg.c phcfg.h setdate.c setdate.h $(file_C) $(file_H) log.c log.h crc.c crc.h ext2_common.c fat_common.c suspend_no.c
CLEANFILES = nodist_qphotorec_SOURCES
DISTCLEANFILES = *~ core
diff --git a/src/ext2.c b/src/ext2.c
index f9402e4..86f2f58 100644
--- a/src/ext2.c
+++ b/src/ext2.c
@@ -33,12 +33,12 @@
#include "types.h"
#include "common.h"
#include "ext2.h"
+#include "ext2_common.h"
#include "fnctdsk.h"
#include "log.h"
#include "guid_cpy.h"
static int set_EXT2_info(const struct ext2_super_block *sb, partition_t *partition, const int verbose);
-static int test_EXT2(const struct ext2_super_block *sb, partition_t *partition);
int check_EXT2(disk_t *disk_car,partition_t *partition,const int verbose)
{
@@ -119,7 +119,7 @@ int recover_EXT2(disk_t *disk, const struct ext2_super_block *sb,partition_t *pa
partition->part_type_mac=PMAC_LINUX;
partition->part_type_sun=PSUN_LINUX;
partition->part_type_gpt=GPT_ENT_TYPE_LINUX_DATA;
- partition->part_size=(uint64_t)le32(sb->s_blocks_count)*(EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size));
+ partition->part_size=td_ext2fs_blocks_count(sb) * EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size);
guid_cpy(&partition->part_uuid, (const efi_guid_t *)&sb->s_uuid);
if(verbose>0)
{
@@ -148,12 +148,12 @@ int recover_EXT2(disk_t *disk, const struct ext2_super_block *sb,partition_t *pa
{
log_info("recover_EXT2: s_block_group_nr=%u/%u, s_mnt_count=%u/%u, s_blocks_per_group=%u, s_inodes_per_group=%u\n",
le16(sb->s_block_group_nr),
- (unsigned int)(le32(sb->s_blocks_count)/le32(sb->s_blocks_per_group)),
+ (unsigned int)(td_ext2fs_blocks_count(sb) /le32(sb->s_blocks_per_group)),
le16(sb->s_mnt_count), le16(sb->s_max_mnt_count),
(unsigned int)le32(sb->s_blocks_per_group),
(unsigned int)le32(sb->s_inodes_per_group));
log_info("recover_EXT2: s_blocksize=%u\n", partition->blocksize);
- log_info("recover_EXT2: s_blocks_count %u\n", (unsigned int)le32(sb->s_blocks_count));
+ log_info("recover_EXT2: s_blocks_count %lu\n", (long unsigned int)td_ext2fs_blocks_count(sb));
if(disk==NULL)
log_info("recover_EXT2: part_size %lu\n", (long unsigned)(partition->part_size / DEFAULT_SECTOR_SIZE));
else
@@ -161,40 +161,3 @@ int recover_EXT2(disk_t *disk, const struct ext2_super_block *sb,partition_t *pa
}
return 0;
}
-
-static int test_EXT2(const struct ext2_super_block *sb, partition_t *partition)
-{
- /* There is a little offset ... */
- if(le16(sb->s_magic)!=EXT2_SUPER_MAGIC)
- return 1;
- if (le32(sb->s_free_blocks_count) > le32(sb->s_blocks_count)) return 2;
- if (le32(sb->s_free_inodes_count) > le32(sb->s_inodes_count)) return 3;
- if (le16(sb->s_errors)!=0 &&
- (le16(sb->s_errors) != EXT2_ERRORS_CONTINUE) &&
- (le16(sb->s_errors) != EXT2_ERRORS_RO) &&
- (le16(sb->s_errors) != EXT2_ERRORS_PANIC))
- return 4;
- if ((le16(sb->s_state) & ~(EXT2_VALID_FS | EXT2_ERROR_FS))!=0)
- return 5;
- if (le32(sb->s_blocks_count) == 0) /* reject empty filesystem */
- return 6;
- if(le32(sb->s_log_block_size)>2) /* block size max = 4096, can be 8192 on alpha */
- return 7;
- if(partition==NULL)
- return 0;
- if(partition->part_size!=0 &&
- partition->part_size<(uint64_t)le32(sb->s_blocks_count)*(EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size)))
- return 8;
- if(EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_HUGE_FILE)!=0 ||
- EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_GDT_CSUM)!=0 ||
- EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_DIR_NLINK)!=0 ||
- EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)!=0 ||
- EXT2_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_64BIT)!=0 ||
- EXT2_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_MMP)!=0)
- partition->upart_type=UP_EXT4;
- else if(EXT2_HAS_COMPAT_FEATURE(sb,EXT3_FEATURE_COMPAT_HAS_JOURNAL)!=0)
- partition->upart_type=UP_EXT3;
- else
- partition->upart_type=UP_EXT2;
- return 0;
-}
diff --git a/src/ext2.h b/src/ext2.h
index efabe22..68bffea 100644
--- a/src/ext2.h
+++ b/src/ext2.h
@@ -148,8 +148,58 @@ struct ext2_super_block {
*/
uint8_t s_prealloc_blocks; /* Nr of blocks to try to preallocate*/
uint8_t s_prealloc_dir_blocks; /* Nr to preallocate for dirs */
- uint16_t s_padding1;
- uint32_t s_reserved[204]; /* Padding to the end of the block */
+ uint16_t s_reserved_gdt_blocks; /* Per group table for online growth */
+ /*
+ * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set.
+ */
+ uint8_t s_journal_uuid[16]; /* uuid of journal superblock */
+ uint32_t s_journal_inum; /* inode number of journal file */
+ uint32_t s_journal_dev; /* device number of journal file */
+ uint32_t s_last_orphan; /* start of list of inodes to delete */
+ uint32_t s_hash_seed[4]; /* HTREE hash seed */
+ uint8_t s_def_hash_version; /* Default hash version to use */
+ uint8_t s_jnl_backup_type; /* Default type of journal backup */
+ uint16_t s_desc_size; /* Group desc. size: INCOMPAT_64BIT */
+ uint32_t s_default_mount_opts;
+ uint32_t s_first_meta_bg; /* First metablock group */
+ uint32_t s_mkfs_time; /* When the filesystem was created */
+ uint32_t s_jnl_blocks[17]; /* Backup of the journal inode */
+ uint32_t s_blocks_count_hi; /* Blocks count high 32bits */
+ uint32_t s_r_blocks_count_hi; /* Reserved blocks count high 32 bits*/
+ uint32_t s_free_blocks_hi; /* Free blocks count */
+ uint16_t s_min_extra_isize; /* All inodes have at least # bytes */
+ uint16_t s_want_extra_isize; /* New inodes should reserve # bytes */
+ uint32_t s_flags; /* Miscellaneous flags */
+ uint16_t s_raid_stride; /* RAID stride */
+ uint16_t s_mmp_update_interval; /* # seconds to wait in MMP checking */
+ uint64_t s_mmp_block; /* Block for multi-mount protection */
+ uint32_t s_raid_stripe_width; /* blocks on all data disks (N*stride)*/
+ uint8_t s_log_groups_per_flex; /* FLEX_BG group size */
+ uint8_t s_reserved_char_pad;
+ uint16_t s_reserved_pad; /* Padding to next 32bits */
+ uint64_t s_kbytes_written; /* nr of lifetime kilobytes written */
+ uint32_t s_snapshot_inum; /* Inode number of active snapshot */
+ uint32_t s_snapshot_id; /* sequential ID of active snapshot */
+ uint64_t s_snapshot_r_blocks_count; /* reserved blocks for active
+ snapshot's future use */
+ uint32_t s_snapshot_list; /* inode number of the head of the on-disk snapshot list */
+ uint32_t s_error_count; /* number of fs errors */
+ uint32_t s_first_error_time; /* first time an error happened */
+ uint32_t s_first_error_ino; /* inode involved in first error */
+ uint64_t s_first_error_block; /* block involved of first error */
+ uint8_t s_first_error_func[32]; /* function where the error happened */
+ uint32_t s_first_error_line; /* line number where error happened */
+ uint32_t s_last_error_time; /* most recent time of an error */
+ uint32_t s_last_error_ino; /* inode involved in last error */
+ uint32_t s_last_error_line; /* line number where error happened */
+ uint64_t s_last_error_block; /* block involved of last error */
+ uint8_t s_last_error_func[32]; /* function where the error happened */
+ uint8_t s_mount_opts[64];
+ uint32_t s_usr_quota_inum; /* inode number of user quota file */
+ uint32_t s_grp_quota_inum; /* inode number of group quota file */
+ uint32_t s_overhead_blocks; /* overhead blocks/clusters in fs */
+ uint32_t s_reserved[108]; /* Padding to the end of the block */
+ uint32_t s_checksum; /* crc32c(superblock) */
};
int check_EXT2(disk_t *disk_car,partition_t *partition,const int verbose);
int recover_EXT2(disk_t *disk_car, const struct ext2_super_block *sb,partition_t *partition,const int verbose, const int dump_ind);
diff --git a/src/ext2_common.c b/src/ext2_common.c
new file mode 100644
index 0000000..021bcf0
--- /dev/null
+++ b/src/ext2_common.c
@@ -0,0 +1,92 @@
+/*
+
+ File: ext2_common.c
+
+ Copyright (C) 1998-2013 Christophe GRENIER <grenier@cgsecurity.org>
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include "types.h"
+#include "common.h"
+#include "ext2.h"
+#include "ext2_common.h"
+
+uint64_t td_ext2fs_blocks_count(const struct ext2_super_block *super)
+{
+ return le32(super->s_blocks_count) |
+ (EXT2_HAS_INCOMPAT_FEATURE(super, EXT4_FEATURE_INCOMPAT_64BIT) ?
+ (uint64_t) le32(super->s_blocks_count_hi) << 32 : 0);
+}
+
+uint64_t td_ext2fs_free_blocks_count(const struct ext2_super_block *super)
+{
+ return le32(super->s_free_blocks_count) |
+ (EXT2_HAS_INCOMPAT_FEATURE(super, EXT4_FEATURE_INCOMPAT_64BIT) ?
+ (uint64_t) le32(super->s_free_blocks_hi) << 32 : 0);
+}
+
+int test_EXT2(const struct ext2_super_block *sb, partition_t *partition)
+{
+ /* There is a little offset ... */
+ if(le16(sb->s_magic)!=EXT2_SUPER_MAGIC)
+ return 1;
+ if (td_ext2fs_free_blocks_count(sb) > td_ext2fs_blocks_count(sb))
+ return 2;
+ if (le32(sb->s_free_inodes_count) > le32(sb->s_inodes_count))
+ return 3;
+ if (le16(sb->s_errors)!=0 &&
+ (le16(sb->s_errors) != EXT2_ERRORS_CONTINUE) &&
+ (le16(sb->s_errors) != EXT2_ERRORS_RO) &&
+ (le16(sb->s_errors) != EXT2_ERRORS_PANIC))
+ return 4;
+ if ((le16(sb->s_state) & ~(EXT2_VALID_FS | EXT2_ERROR_FS))!=0)
+ return 5;
+ if(td_ext2fs_blocks_count(sb) == 0) /* reject empty filesystem */
+ return 6;
+ if(le32(sb->s_log_block_size)>2) /* block size max = 4096, can be 8192 on alpha */
+ return 7;
+ if(le32(sb->s_blocks_per_group)==0)
+ return 8;
+ if(partition==NULL)
+ return 0;
+ if(partition->part_size!=0 &&
+ partition->part_size < td_ext2fs_blocks_count(sb) *
+ (EXT2_MIN_BLOCK_SIZE<<le32(sb->s_log_block_size)))
+ return 8;
+ if(EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_HUGE_FILE)!=0 ||
+ EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_GDT_CSUM)!=0 ||
+ EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_DIR_NLINK)!=0 ||
+ EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)!=0 ||
+ EXT2_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_64BIT)!=0 ||
+ EXT2_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_MMP)!=0)
+ partition->upart_type=UP_EXT4;
+ else if(EXT2_HAS_COMPAT_FEATURE(sb,EXT3_FEATURE_COMPAT_HAS_JOURNAL)!=0)
+ partition->upart_type=UP_EXT3;
+ else
+ partition->upart_type=UP_EXT2;
+ return 0;
+}
diff --git a/src/ext2_common.h b/src/ext2_common.h
new file mode 100644
index 0000000..4958621
--- /dev/null
+++ b/src/ext2_common.h
@@ -0,0 +1,32 @@
+/*
+
+ File: ext2_common.h
+
+ Copyright (C) 2013 Christophe GRENIER <grenier@cgsecurity.org>
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write the Free Software Foundation, Inc., 51
+ Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint64_t td_ext2fs_blocks_count(const struct ext2_super_block *super);
+uint64_t td_ext2fs_free_blocks_count(const struct ext2_super_block *super);
+int test_EXT2(const struct ext2_super_block *sb, partition_t *partition);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
diff --git a/src/file_ext.c b/src/file_ext.c
index 5ce48a3..dd7eb1b 100644
--- a/src/file_ext.c
+++ b/src/file_ext.c
@@ -30,6 +30,7 @@
#include "types.h"
#include "common.h"
#include "ext2.h"
+#include "ext2_common.h"
#include "filegen.h"
static void register_header_check_ext2_sb(file_stat_t *file_stat);
@@ -66,22 +67,7 @@ static void file_rename_ext(const char *old_filename)
static int header_check_ext2_sb(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)
{
const struct ext2_super_block *sb=(const struct ext2_super_block *)buffer;
- if(le16(sb->s_magic)!=EXT2_SUPER_MAGIC)
- return 0;
- if (le32(sb->s_free_blocks_count) >= le32(sb->s_blocks_count))
- return 0;
- if (le32(sb->s_free_inodes_count) >= le32(sb->s_inodes_count))
- return 0;
- if (le16(sb->s_errors)!=0 &&
- (le16(sb->s_errors) != EXT2_ERRORS_CONTINUE) &&
- (le16(sb->s_errors) != EXT2_ERRORS_RO) &&
- (le16(sb->s_errors) != EXT2_ERRORS_PANIC))
- return 0;
- if ((le16(sb->s_state) & ~(EXT2_VALID_FS | EXT2_ERROR_FS))!=0)
- return 0;
- if (le32(sb->s_blocks_count) == 0) /* reject empty filesystem */
- return 0;
- if(le32(sb->s_log_block_size)>2) /* block size max = 4096, can be 8192 on alpha */
+ if(test_EXT2(sb, NULL)!=0)
return 0;
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_ext2_sb.extension;
diff --git a/src/file_ext2.c b/src/file_ext2.c
index 46a16d7..41506b1 100644
--- a/src/file_ext2.c
+++ b/src/file_ext2.c
@@ -30,6 +30,7 @@
#include "types.h"
#include "common.h"
#include "ext2.h"
+#include "ext2_common.h"
#include "filegen.h"
static void register_header_check_ext2_fs(file_stat_t *file_stat);
@@ -55,22 +56,7 @@ static void register_header_check_ext2_fs(file_stat_t *file_stat)
static int header_check_ext2_fs(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)
{
const struct ext2_super_block *sb=(const struct ext2_super_block *)&buffer[0x400];
- if(le16(sb->s_magic)!=EXT2_SUPER_MAGIC)
- return 0;
- if (le32(sb->s_free_blocks_count) >= le32(sb->s_blocks_count))
- return 0;
- if (le32(sb->s_free_inodes_count) >= le32(sb->s_inodes_count))
- return 0;
- if (le16(sb->s_errors)!=0 &&
- (le16(sb->s_errors) != EXT2_ERRORS_CONTINUE) &&
- (le16(sb->s_errors) != EXT2_ERRORS_RO) &&
- (le16(sb->s_errors) != EXT2_ERRORS_PANIC))
- return 0;
- if ((le16(sb->s_state) & ~(EXT2_VALID_FS | EXT2_ERROR_FS))!=0)
- return 0;
- if (le32(sb->s_blocks_count) == 0) /* reject empty filesystem */
- return 0;
- if(le32(sb->s_log_block_size)>2) /* block size max = 4096, can be 8192 on alpha */
+ if(test_EXT2(sb, NULL)!=0)
return 0;
if(le16(sb->s_block_group_nr)!=0)
return 0;