summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2009-02-16 19:59:12 +0100
committerChristophe Grenier <grenier@cgsecurity.org>2009-02-16 19:59:12 +0100
commit1bb6df5595fd5ae52aebf20ca87d30f44fa507b4 (patch)
tree642a12b0b21962cef0674ec2ccccf38cca09af82 /src
parentac32ef6ddff1231a65b2c114fec6f1d55975b950 (diff)
Move find_sectors_per_cluster() and no_of_cluster2part_type() to a separated file
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am4
-rw-r--r--src/fat_adv.c194
-rw-r--r--src/fat_cluster.c234
-rw-r--r--src/fat_cluster.h34
4 files changed, 271 insertions, 195 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 945df38..578755b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,8 +19,8 @@ base_H = alignio.h common.h crc.h ewf.h fnctdsk.h hdaccess.h hdwin32.h hidden.
fs_C = analyse.c bfs.c bsd.c cramfs.c fat.c fatx.c ext2.c jfs.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 xfs.c
fs_H = analyse.h bfs.h bsd.h cramfs.h fat.h fatx.h ext2.h jfs_superblock.h jfs.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 xfs.h
-testdisk_ncurses_C = addpart.c adv.c askloc.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 fatn.c geometry.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 thfs.c tload.c tlog.c tmbrcode.c tntfs.c toptions.c tpartwr.c
-testdisk_ncurses_H = addpart.h adv.h askloc.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 fatn.h geometry.h godmode.h hiddenn.h intrface.h intrfn.h nodisk.h ntfs_udl.h partgptn.h parti386n.h partmacn.h partsunn.h partxboxn.h tanalyse.h tdelete.h tdiskop.h tdisksel.h thfs.h tload.h tlog.h tmbrcode.h tntfs.h toptions.h tpartwr.h
+testdisk_ncurses_C = addpart.c adv.c askloc.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 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 thfs.c tload.c tlog.c tmbrcode.c tntfs.c toptions.c tpartwr.c
+testdisk_ncurses_H = addpart.h adv.h askloc.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 godmode.h hiddenn.h intrface.h intrfn.h nodisk.h ntfs_udl.h partgptn.h parti386n.h partmacn.h partsunn.h partxboxn.h tanalyse.h tdelete.h tdiskop.h tdisksel.h thfs.h tload.h tlog.h tmbrcode.h tntfs.h toptions.h tpartwr.h
testdisk_SOURCES = $(base_C) $(base_H) $(fs_C) $(fs_H) $(testdisk_ncurses_C) $(testdisk_ncurses_H) dir.c dir.h ext2_dir.c ext2_dir.h ext2_inc.h fat_dir.c fat_dir.h ntfs_dir.c ntfs_dir.h ntfs_inc.h rfs_dir.c rfs_dir.h $(ICON_TESTDISK) next.c next.h
diff --git a/src/fat_adv.c b/src/fat_adv.c
index 9e19138..ef63c0c 100644
--- a/src/fat_adv.c
+++ b/src/fat_adv.c
@@ -52,6 +52,7 @@
#include "log.h"
#include "log_part.h"
#include "fat_adv.h"
+#include "fat_cluster.h"
#ifdef HAVE_NCURSES
#include "fatn.h"
#endif
@@ -60,15 +61,7 @@
#define INTER_FAT_ASK_Y 23
extern const char *monstr[];
-typedef struct sector_cluster_struct sector_cluster_t;
typedef struct info_offset_struct info_offset_t;
-typedef struct cluster_offset_struct cluster_offset_t;
-
-struct sector_cluster_struct
-{
- unsigned int sector;
- unsigned int cluster;
-};
struct info_offset_struct
{
@@ -77,25 +70,15 @@ struct info_offset_struct
unsigned int fat_type;
};
-struct cluster_offset_struct
-{
- unsigned int sectors_per_cluster;
- unsigned long int offset;
- unsigned int nbr;
- unsigned int first_sol;
-};
static upart_type_t fat_find_info(disk_t *disk_car,unsigned int*reserved, unsigned int*fat_length, const partition_t *partition,const uint64_t max_offset,const int p_fat12,const int p_fat16,const int p_fat32,const int verbose,const int dump_ind,const int interface, const unsigned int expert, unsigned int *fats);
static int fat_find_type(disk_t *disk_car,const partition_t *partition,const uint64_t max_offset,const int p_fat12,const int p_fat16,const int p_fat32,const int verbose,const int dump_ind,const int interface,unsigned int *nbr_offset,info_offset_t *info_offset, const unsigned int max_nbr_offset);
static unsigned int fat_find_fat_start(const unsigned char *buffer,const int p_fat12, const int p_fat16, const int p_fat32,unsigned long int*fat_offset, const unsigned int sector_size);
-static upart_type_t no_of_cluster2part_type(const unsigned long int no_of_cluster);
static void create_fat_boot_sector(disk_t *disk_car, partition_t *partition, const unsigned int reserved, const int verbose, const unsigned int dir_entries, const unsigned long int root_cluster, const unsigned int sectors_per_cluster, const unsigned int fat_length,const int interface, const upart_type_t upart_type, const unsigned int fats, char **current_cmd);
static unsigned int fat32_find_root_cluster(disk_t *disk_car,const partition_t *partition,const unsigned int sectors_per_cluster, const unsigned long int no_of_cluster, const unsigned int reserved, const unsigned int fat_length, const int interface, const int verbose, const unsigned int expert, const unsigned int first_free_cluster, const unsigned int fats);
static int write_FAT_boot_code_aux(unsigned char *buffer);
-static int find_sectors_per_cluster(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind,const int interface, unsigned int *sectors_per_cluster, uint64_t *offset);
static int find_dir_entries(disk_t *disk_car,const partition_t *partition, const unsigned int offset,const int verbose);
-static int find_sectors_per_cluster_aux(const sector_cluster_t *sector_cluster, const unsigned int nbr_sector_cluster,unsigned int *sectors_per_cluster, uint64_t *offset, const int verbose, const unsigned long int part_size_in_sectors);
static int analyse_dir_entries(disk_t *disk_car,const partition_t *partition, const unsigned int offset, const int verbose);
static int analyse_dir_entries2(disk_t *disk_car,const partition_t *partition, const unsigned int reserved, const unsigned int fat_length,const int verbose, unsigned int root_size_max,const upart_type_t upart_type, const unsigned int fats);
static int calcul_sectors_per_cluster(const upart_type_t upart_type, const unsigned long int data_size, const unsigned int fat_length, const unsigned int sector_size);
@@ -1866,181 +1849,6 @@ static upart_type_t select_fat_info(const info_offset_t *info_offset, const unsi
}
#endif
-/* Using a couple of inodes of "." directory entries, get the cluster size and where the first cluster begins.
- * */
-static int find_sectors_per_cluster(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind,const int interface, unsigned int *sectors_per_cluster, uint64_t *offset_org)
-{
- unsigned int nbr_subdir=0;
- sector_cluster_t sector_cluster[10];
- {
- uint64_t offset;
- uint64_t skip_offset;
- int ind_stop=0;
- unsigned char *buffer=(unsigned char *)MALLOC(disk_car->sector_size);
-#ifdef HAVE_NCURSES
- if(interface)
- {
- wmove(stdscr,22,0);
- wattrset(stdscr, A_REVERSE);
- waddstr(stdscr," Stop ");
- wattroff(stdscr, A_REVERSE);
- }
-#endif
- /* 2 fats, maximum cluster size=128 */
- skip_offset=(uint64_t)((partition->part_size-32*disk_car->sector_size)/disk_car->sector_size/128*1.5/disk_car->sector_size*2)*disk_car->sector_size;
- if(verbose>0)
- {
- log_verbose("find_sectors_per_cluster skip_sectors=%lu (skip_offset=%lu)\n",
- (unsigned long)(skip_offset/disk_car->sector_size),
- (unsigned long)skip_offset);
- }
- for(offset=skip_offset;(offset<partition->part_size)&&!ind_stop&&(nbr_subdir<10);offset+=disk_car->sector_size)
- {
-#ifdef HAVE_NCURSES
- if(interface>0 && ((offset&(1024*disk_car->sector_size-1))==0))
- {
- wmove(stdscr,9,0);
- wclrtoeol(stdscr);
- wprintw(stdscr,"Search subdirectory %10lu/%lu %u",(unsigned long)(offset/disk_car->sector_size),(unsigned long)(partition->part_size/disk_car->sector_size),nbr_subdir);
- wrefresh(stdscr);
- ind_stop|=check_enter_key_or_s(stdscr);
- }
-#endif
- if((unsigned)disk_car->pread(disk_car, buffer, disk_car->sector_size, partition->part_offset + offset) == disk_car->sector_size)
- {
- if(memcmp(&buffer[0],". ",8+3)==0 && memcmp(&buffer[0x20],".. ",8+3)==0)
- {
- unsigned long int cluster=(buffer[0*0x20+0x15]<<24) + (buffer[0*0x20+0x14]<<16) +
- (buffer[0*0x20+0x1B]<<8) + buffer[0*0x20+0x1A];
- log_info("sector %lu, cluster %lu\n",
- (unsigned long)(offset/disk_car->sector_size), cluster);
- sector_cluster[nbr_subdir].cluster=cluster;
- sector_cluster[nbr_subdir].sector=offset/disk_car->sector_size;
- nbr_subdir++;
-#ifdef HAVE_NCURSES
- if(dump_ind>0)
- dump_ncurses(buffer,disk_car->sector_size);
-#endif
- }
- }
- }
- free(buffer);
- }
- return find_sectors_per_cluster_aux(sector_cluster,nbr_subdir,sectors_per_cluster,offset_org,verbose,partition->part_size/disk_car->sector_size);
-}
-
-static int find_sectors_per_cluster_aux(const sector_cluster_t *sector_cluster, const unsigned int nbr_sector_cluster,unsigned int *sectors_per_cluster, uint64_t *offset, const int verbose, const unsigned long int part_size_in_sectors)
-{
- cluster_offset_t *cluster_offset;
- unsigned int i,j;
- unsigned int nbr_sol=0;
- if(nbr_sector_cluster<2)
- return 0;
- cluster_offset=(cluster_offset_t *)MALLOC(nbr_sector_cluster*nbr_sector_cluster*sizeof(cluster_offset_t));
- log_info("find_sectors_per_cluster_aux\n");
- for(i=0;i<nbr_sector_cluster-1;i++)
- {
- for(j=i+1;j<nbr_sector_cluster;j++)
- {
- if(sector_cluster[j].cluster > sector_cluster[i].cluster)
- {
- unsigned int sectors_per_cluster_tmp=(sector_cluster[j].sector-sector_cluster[i].sector)/(sector_cluster[j].cluster-sector_cluster[i].cluster);
- switch(sectors_per_cluster_tmp)
- {
- case 1:
- case 2:
- case 4:
- case 8:
- case 16:
- case 32:
- case 64:
- case 128:
- if(sector_cluster[i].sector > (uint64_t)(sector_cluster[i].cluster-2) * sectors_per_cluster_tmp)
- {
- unsigned int sol_cur;
- unsigned int found=0;
- uint64_t offset_tmp=sector_cluster[i].sector-(uint64_t)(sector_cluster[i].cluster-2)*sectors_per_cluster_tmp;
- for(sol_cur=0;sol_cur<nbr_sol && !found;sol_cur++)
- {
- if(cluster_offset[sol_cur].sectors_per_cluster==sectors_per_cluster_tmp &&
- cluster_offset[sol_cur].offset==offset_tmp)
- {
- if(cluster_offset[sol_cur].first_sol==i)
- {
- cluster_offset[sol_cur].nbr++;
- }
- /* log_debug("sectors_per_cluster=%u offset=%lu nbr=%u\n",cluster_offset[sol_cur].sectors_per_cluster,cluster_offset[sol_cur].offset,cluster_offset[sol_cur].nbr); */
- found=1;
- }
- }
- if(!found)
- {
- cluster_offset[nbr_sol].sectors_per_cluster=sectors_per_cluster_tmp;
- cluster_offset[nbr_sol].offset=offset_tmp;
- cluster_offset[nbr_sol].nbr=1;
- cluster_offset[nbr_sol].first_sol=i;
- nbr_sol++;
- }
- }
- break;
- }
- }
- }
- }
- /* Show results */
- {
- unsigned int nbr_max=0;
- for(i=0;i<nbr_sol;i++)
- {
- if(verbose>0)
- {
- log_verbose("sectors_per_cluster=%u offset=%lu nbr=%u ",
- cluster_offset[i].sectors_per_cluster,
- cluster_offset[i].offset,
- cluster_offset[i].nbr);
- switch(no_of_cluster2part_type((part_size_in_sectors-cluster_offset[i].offset)/cluster_offset[i].sectors_per_cluster))
- {
- case UP_FAT12:
- log_info("FAT : 12\n");
- break;
- case UP_FAT16:
- log_info("FAT : 16\n");
- break;
- case UP_FAT32:
- log_info("FAT : 32\n");
- break;
- default: /* No compiler warning */
- break;
- }
- }
- if(cluster_offset[i].nbr>nbr_max)
- {
- nbr_max=cluster_offset[i].nbr;
- *sectors_per_cluster=cluster_offset[i].sectors_per_cluster;
- *offset=cluster_offset[i].offset;
- }
- }
- free(cluster_offset);
- if(nbr_max==0)
- return 0;
- log_info("Selected: sectors_per_cluster=%u offset=%lu nbr=%u\n", *sectors_per_cluster,
- (long unsigned int)(*offset),nbr_max);
- return 1;
- }
-}
-
-static upart_type_t no_of_cluster2part_type(const unsigned long int no_of_cluster)
-{
- if(no_of_cluster<65525)
- {
- if(no_of_cluster<4085)
- return UP_FAT12;
- else
- return UP_FAT16;
- }
- return UP_FAT32;
-}
-
int rebuild_FAT_BS(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind,const int interface,const unsigned int expert, char**current_cmd)
{
unsigned long int data_size;
diff --git a/src/fat_cluster.c b/src/fat_cluster.c
new file mode 100644
index 0000000..6268c8b
--- /dev/null
+++ b/src/fat_cluster.c
@@ -0,0 +1,234 @@
+/*
+
+ File: fat_cluster.c
+
+ Copyright (C) 1998-2009 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_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include "types.h"
+#include "common.h"
+#include "intrf.h"
+#include "intrfn.h"
+#include "log.h"
+#include "fat_cluster.h"
+
+typedef struct sector_cluster_struct sector_cluster_t;
+typedef struct cluster_offset_struct cluster_offset_t;
+
+struct sector_cluster_struct
+{
+ unsigned int sector;
+ unsigned int cluster;
+};
+
+struct cluster_offset_struct
+{
+ unsigned int sectors_per_cluster;
+ unsigned long int offset;
+ unsigned int nbr;
+ unsigned int first_sol;
+};
+
+static int find_sectors_per_cluster_aux(const sector_cluster_t *sector_cluster, const unsigned int nbr_sector_cluster,unsigned int *sectors_per_cluster, uint64_t *offset, const int verbose, const unsigned long int part_size_in_sectors);
+
+/* Using a couple of inodes of "." directory entries, get the cluster size and where the first cluster begins.
+ * */
+int find_sectors_per_cluster(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind,const int interface, unsigned int *sectors_per_cluster, uint64_t *offset_org)
+{
+ unsigned int nbr_subdir=0;
+ sector_cluster_t sector_cluster[10];
+ {
+ uint64_t offset;
+ uint64_t skip_offset;
+ int ind_stop=0;
+ unsigned char *buffer=(unsigned char *)MALLOC(disk_car->sector_size);
+#ifdef HAVE_NCURSES
+ if(interface)
+ {
+ wmove(stdscr,22,0);
+ wattrset(stdscr, A_REVERSE);
+ waddstr(stdscr," Stop ");
+ wattroff(stdscr, A_REVERSE);
+ }
+#endif
+ /* 2 fats, maximum cluster size=128 */
+ skip_offset=(uint64_t)((partition->part_size-32*disk_car->sector_size)/disk_car->sector_size/128*1.5/disk_car->sector_size*2)*disk_car->sector_size;
+ if(verbose>0)
+ {
+ log_verbose("find_sectors_per_cluster skip_sectors=%lu (skip_offset=%lu)\n",
+ (unsigned long)(skip_offset/disk_car->sector_size),
+ (unsigned long)skip_offset);
+ }
+ for(offset=skip_offset;(offset<partition->part_size)&&!ind_stop&&(nbr_subdir<10);offset+=disk_car->sector_size)
+ {
+#ifdef HAVE_NCURSES
+ if(interface>0 && ((offset&(1024*disk_car->sector_size-1))==0))
+ {
+ wmove(stdscr,9,0);
+ wclrtoeol(stdscr);
+ wprintw(stdscr,"Search subdirectory %10lu/%lu %u",(unsigned long)(offset/disk_car->sector_size),(unsigned long)(partition->part_size/disk_car->sector_size),nbr_subdir);
+ wrefresh(stdscr);
+ ind_stop|=check_enter_key_or_s(stdscr);
+ }
+#endif
+ if((unsigned)disk_car->pread(disk_car, buffer, disk_car->sector_size, partition->part_offset + offset) == disk_car->sector_size)
+ {
+ if(memcmp(&buffer[0],". ",8+3)==0 && memcmp(&buffer[0x20],".. ",8+3)==0)
+ {
+ unsigned long int cluster=(buffer[0*0x20+0x15]<<24) + (buffer[0*0x20+0x14]<<16) +
+ (buffer[0*0x20+0x1B]<<8) + buffer[0*0x20+0x1A];
+ log_info("sector %lu, cluster %lu\n",
+ (unsigned long)(offset/disk_car->sector_size), cluster);
+ sector_cluster[nbr_subdir].cluster=cluster;
+ sector_cluster[nbr_subdir].sector=offset/disk_car->sector_size;
+ nbr_subdir++;
+#ifdef HAVE_NCURSES
+ if(dump_ind>0)
+ dump_ncurses(buffer,disk_car->sector_size);
+#endif
+ }
+ }
+ }
+ free(buffer);
+ }
+ return find_sectors_per_cluster_aux(sector_cluster,nbr_subdir,sectors_per_cluster,offset_org,verbose,partition->part_size/disk_car->sector_size);
+}
+
+static int find_sectors_per_cluster_aux(const sector_cluster_t *sector_cluster, const unsigned int nbr_sector_cluster,unsigned int *sectors_per_cluster, uint64_t *offset, const int verbose, const unsigned long int part_size_in_sectors)
+{
+ cluster_offset_t *cluster_offset;
+ unsigned int i,j;
+ unsigned int nbr_sol=0;
+ if(nbr_sector_cluster<2)
+ return 0;
+ cluster_offset=(cluster_offset_t *)MALLOC(nbr_sector_cluster*nbr_sector_cluster*sizeof(cluster_offset_t));
+ log_info("find_sectors_per_cluster_aux\n");
+ for(i=0;i<nbr_sector_cluster-1;i++)
+ {
+ for(j=i+1;j<nbr_sector_cluster;j++)
+ {
+ if(sector_cluster[j].cluster > sector_cluster[i].cluster)
+ {
+ unsigned int sectors_per_cluster_tmp=(sector_cluster[j].sector-sector_cluster[i].sector)/(sector_cluster[j].cluster-sector_cluster[i].cluster);
+ switch(sectors_per_cluster_tmp)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ case 32:
+ case 64:
+ case 128:
+ if(sector_cluster[i].sector > (uint64_t)(sector_cluster[i].cluster-2) * sectors_per_cluster_tmp)
+ {
+ unsigned int sol_cur;
+ unsigned int found=0;
+ uint64_t offset_tmp=sector_cluster[i].sector-(uint64_t)(sector_cluster[i].cluster-2)*sectors_per_cluster_tmp;
+ for(sol_cur=0;sol_cur<nbr_sol && !found;sol_cur++)
+ {
+ if(cluster_offset[sol_cur].sectors_per_cluster==sectors_per_cluster_tmp &&
+ cluster_offset[sol_cur].offset==offset_tmp)
+ {
+ if(cluster_offset[sol_cur].first_sol==i)
+ {
+ cluster_offset[sol_cur].nbr++;
+ }
+ /* log_debug("sectors_per_cluster=%u offset=%lu nbr=%u\n",cluster_offset[sol_cur].sectors_per_cluster,cluster_offset[sol_cur].offset,cluster_offset[sol_cur].nbr); */
+ found=1;
+ }
+ }
+ if(!found)
+ {
+ cluster_offset[nbr_sol].sectors_per_cluster=sectors_per_cluster_tmp;
+ cluster_offset[nbr_sol].offset=offset_tmp;
+ cluster_offset[nbr_sol].nbr=1;
+ cluster_offset[nbr_sol].first_sol=i;
+ nbr_sol++;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ /* Show results */
+ {
+ unsigned int nbr_max=0;
+ for(i=0;i<nbr_sol;i++)
+ {
+ if(verbose>0)
+ {
+ log_verbose("sectors_per_cluster=%u offset=%lu nbr=%u ",
+ cluster_offset[i].sectors_per_cluster,
+ cluster_offset[i].offset,
+ cluster_offset[i].nbr);
+ switch(no_of_cluster2part_type((part_size_in_sectors-cluster_offset[i].offset)/cluster_offset[i].sectors_per_cluster))
+ {
+ case UP_FAT12:
+ log_info("FAT : 12\n");
+ break;
+ case UP_FAT16:
+ log_info("FAT : 16\n");
+ break;
+ case UP_FAT32:
+ log_info("FAT : 32\n");
+ break;
+ default: /* No compiler warning */
+ break;
+ }
+ }
+ if(cluster_offset[i].nbr>nbr_max)
+ {
+ nbr_max=cluster_offset[i].nbr;
+ *sectors_per_cluster=cluster_offset[i].sectors_per_cluster;
+ *offset=cluster_offset[i].offset;
+ }
+ }
+ free(cluster_offset);
+ if(nbr_max==0)
+ return 0;
+ log_info("Selected: sectors_per_cluster=%u offset=%lu nbr=%u\n", *sectors_per_cluster,
+ (long unsigned int)(*offset),nbr_max);
+ return 1;
+ }
+}
+
+upart_type_t no_of_cluster2part_type(const unsigned long int no_of_cluster)
+{
+ if(no_of_cluster<65525)
+ {
+ if(no_of_cluster<4085)
+ return UP_FAT12;
+ else
+ return UP_FAT16;
+ }
+ return UP_FAT32;
+}
+
diff --git a/src/fat_cluster.h b/src/fat_cluster.h
new file mode 100644
index 0000000..0a0483f
--- /dev/null
+++ b/src/fat_cluster.h
@@ -0,0 +1,34 @@
+/*
+
+ File: fat_cluster.h
+
+ Copyright (C) 2008-2009 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.
+
+ */
+#ifndef _FAT_CLUSTER_H
+#define _FAT_CLUSTER_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int find_sectors_per_cluster(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind,const int interface, unsigned int *sectors_per_cluster, uint64_t *offset);
+upart_type_t no_of_cluster2part_type(const unsigned long int no_of_cluster);
+
+#ifdef __cplusplus
+} /* closing brace for extern "c" */
+#endif
+#endif