summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2013-11-01 13:42:51 +0100
committerChristophe Grenier <grenier@cgsecurity.org>2013-11-01 13:42:51 +0100
commitb58be737f078928b6e1dc3cabc77bec20b059ece (patch)
treefff7ad10fc6993a247d4b9d2cc88d00c466ed8de
parent0bf23249bb4ea2bf930148bfd59a13342cdedd76 (diff)
new functions is_fat_directory() and fat_get_cluster_from_entry()
rename sectors() to fat_sectors()
-rw-r--r--src/Makefile.am6
-rw-r--r--src/fat.c25
-rw-r--r--src/fat.h6
-rw-r--r--src/fat_adv.c90
-rw-r--r--src/fat_cluster.c7
-rw-r--r--src/fat_common.c19
-rw-r--r--src/fat_dir.c11
-rw-r--r--src/fat_dir.h2
-rw-r--r--src/fat_unformat.c15
-rw-r--r--src/fatn.c9
-rw-r--r--src/fatp.c3
-rw-r--r--src/file_dir.c7
-rw-r--r--src/file_fat.c7
-rw-r--r--src/hpfs.c3
-rw-r--r--src/psearchn.c2
-rw-r--r--src/qpsearch.cpp2
16 files changed, 116 insertions, 98 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index d2bca53..bfaf06d 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 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
+fs_C = analyse.c bfs.c bsd.c btrfs.c cramfs.c exfat.c fat.c fat_common.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 fat_common.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
@@ -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 ext2_common.c 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 fat_common.h suspend_no.c
CLEANFILES = nodist_qphotorec_SOURCES
DISTCLEANFILES = *~ core
diff --git a/src/fat.c b/src/fat.c
index 0450544..aea5407 100644
--- a/src/fat.c
+++ b/src/fat.c
@@ -43,6 +43,8 @@
#include "intrf.h"
#include "log.h"
#include "log_part.h"
+#include "fat_common.h"
+
extern const arch_fnct_t arch_i386;
extern const arch_fnct_t arch_mac;
@@ -81,7 +83,7 @@ static int log_fat_info(const struct fat_boot_sector*fh1, const upart_type_t upa
log_info("reserved %u\n", le16(fh1->reserved));
log_info("fats %u\n", fh1->fats);
log_info("dir_entries %u\n", get_dir_entries(fh1));
- log_info("sectors %u\n", sectors(fh1));
+ log_info("sectors %u\n", fat_sectors(fh1));
log_info("media %02X\n", fh1->media);
log_info("fat_length %u\n", le16(fh1->fat_length));
log_info("secs_track %u\n", le16(fh1->secs_track));
@@ -129,7 +131,7 @@ int log_fat2_info(const struct fat_boot_sector*fh1, const struct fat_boot_sector
log_info("reserved %u %u\n", le16(fh1->reserved),le16(fh2->reserved));
log_info("fats %u %u\n", fh1->fats,fh2->fats);
log_info("dir_entries %u %u\n", get_dir_entries(fh1),get_dir_entries(fh2));
- log_info("sectors %u %u\n", sectors(fh1),sectors(fh2));
+ log_info("sectors %u %u\n", fat_sectors(fh1),fat_sectors(fh2));
log_info("media %02X %02X\n", fh1->media,fh2->media);
log_info("fat_length %u %u\n", le16(fh1->fat_length),le16(fh2->fat_length));
log_info("secs_track %u %u\n", le16(fh1->secs_track),le16(fh2->secs_track));
@@ -484,7 +486,7 @@ int test_FAT(disk_t *disk_car, const struct fat_boot_sector *fat_header, partiti
return 1;
}
fat_length=le16(fat_header->fat_length)>0?le16(fat_header->fat_length):le32(fat_header->fat32_length);
- part_size=(sectors(fat_header)>0?sectors(fat_header):le32(fat_header->total_sect));
+ part_size=(fat_sectors(fat_header)>0?fat_sectors(fat_header):le32(fat_header->total_sect));
start_fat1=le16(fat_header->reserved);
start_fat2=start_fat1+(fat_header->fats>1?fat_length:0);
start_data=start_fat1+fat_header->fats*fat_length+(get_dir_entries(fat_header)*32+fat_sector_size(fat_header)-1)/fat_sector_size(fat_header);
@@ -509,7 +511,7 @@ int test_FAT(disk_t *disk_car, const struct fat_boot_sector *fat_header, partiti
offset2head(disk_car,partition->part_offset),
offset2sector(disk_car,partition->part_offset));
}
- if(sectors(fat_header)==0)
+ if(fat_sectors(fat_header)==0)
{
screen_buffer_add(msg_CHKFAT_SIZE);
log_error(msg_CHKFAT_SIZE);
@@ -594,7 +596,7 @@ int test_FAT(disk_t *disk_car, const struct fat_boot_sector *fat_header, partiti
offset2head(disk_car,partition->part_offset),
offset2sector(disk_car,partition->part_offset));
}
- if(sectors(fat_header)!=0)
+ if(fat_sectors(fat_header)!=0)
{
screen_buffer_add(msg_CHKFAT_SIZE);
log_error(msg_CHKFAT_SIZE);
@@ -743,15 +745,6 @@ int comp_FAT(disk_t *disk, const partition_t *partition, const unsigned long int
return 0;
}
-unsigned int fat_sector_size(const struct fat_boot_sector *fat_header)
-{ return (fat_header->sector_size[1]<<8)+fat_header->sector_size[0]; }
-
-unsigned int get_dir_entries(const struct fat_boot_sector *fat_header)
-{ return (fat_header->dir_entries[1]<<8)+fat_header->dir_entries[0]; }
-
-unsigned int sectors(const struct fat_boot_sector *fat_header)
-{ return (fat_header->sectors[1]<<8)+fat_header->sectors[0]; }
-
unsigned long int fat32_get_free_count(const unsigned char *boot_fat32, const unsigned int sector_size)
{
return (boot_fat32[sector_size+0x1E8+3]<<24)+(boot_fat32[sector_size+0x1E8+2]<<16)+(boot_fat32[sector_size+0x1E8+1]<<8)+boot_fat32[sector_size+0x1E8];
@@ -766,7 +759,7 @@ int recover_FAT(disk_t *disk_car, const struct fat_boot_sector*fat_header, parti
{
if(test_FAT(disk_car, fat_header, partition, verbose, dump_ind))
return 1;
- partition->part_size=(uint64_t)(sectors(fat_header)>0?sectors(fat_header):le32(fat_header->total_sect)) *
+ partition->part_size=(uint64_t)(fat_sectors(fat_header)>0?fat_sectors(fat_header):le32(fat_header->total_sect)) *
fat_sector_size(fat_header);
/* test_FAT has set partition->upart_type */
partition->sborg_offset=0;
@@ -794,7 +787,7 @@ int recover_FAT(disk_t *disk_car, const struct fat_boot_sector*fat_header, parti
offset2head(disk_car,partition->part_offset),
offset2sector(disk_car,partition->part_offset));
}
- if(sectors(fat_header)!=0)
+ if(fat_sectors(fat_header)!=0)
partition->part_type_i386=P_16FAT;
else if(offset2cylinder(disk_car,partition->part_offset+partition->part_size-1)<=1024)
partition->part_type_i386=P_16FATBD;
diff --git a/src/fat.h b/src/fat.h
index bed329e..935e991 100644
--- a/src/fat.h
+++ b/src/fat.h
@@ -88,7 +88,7 @@ struct msdos_dir_entry {
uint16_t date; /* 18 */
uint16_t start; /* 1A */
uint32_t size; /* 1C file size (in bytes) */
-};
+} __attribute__ ((__packed__));
/* Up to 13 characters of the name */
struct msdos_dir_slot {
@@ -114,9 +114,6 @@ int is_part_fat(const partition_t *partition);
int is_part_fat12(const partition_t *partition);
int is_part_fat16(const partition_t *partition);
int is_part_fat32(const partition_t *partition);
-unsigned int get_dir_entries(const struct fat_boot_sector *fat_header);
-unsigned int fat_sector_size(const struct fat_boot_sector *fat_header);
-unsigned int sectors(const struct fat_boot_sector *fat_header);
unsigned int fat32_get_prev_cluster(disk_t *disk,const partition_t *partition, const unsigned int fat_offset, const unsigned int cluster, const unsigned int no_of_cluster);
int fat32_free_info(disk_t *disk,const partition_t *partition, const unsigned int fat_offset, const unsigned int no_of_cluster, unsigned int *next_free, unsigned int*free_count);
unsigned long int fat32_get_free_count(const unsigned char *boot_fat32, const unsigned int sector_size);
@@ -151,7 +148,6 @@ int test_FAT(disk_t *disk, const struct fat_boot_sector *fat_header, partition_t
int recover_OS2MB(const disk_t *disk, const struct fat_boot_sector*fat_header, partition_t *partition, const int verbose, const int dump_ind);
int check_OS2MB(disk_t *disk, partition_t *partition, const int verbose);
int check_VFAT_volume_name(const char *name, const unsigned int max_size);
-
#ifdef __cplusplus
} /* closing brace for extern "C" */
#endif
diff --git a/src/fat_adv.c b/src/fat_adv.c
index 8c17fec..63d93f2 100644
--- a/src/fat_adv.c
+++ b/src/fat_adv.c
@@ -41,6 +41,7 @@
#include "types.h"
#include "common.h"
#include "fat.h"
+#include "fat_common.h"
#include "lang.h"
#include "fnctdsk.h"
#include "intrf.h"
@@ -156,21 +157,18 @@ static int check_FAT_dir_entry(const unsigned char *entry, const unsigned int en
static unsigned long int get_subdirectory(disk_t *disk_car,const uint64_t hd_offset,const unsigned long int i)
{
unsigned char buffer[DEFAULT_SECTOR_SIZE];
+ const struct msdos_dir_entry *entry1=(const struct msdos_dir_entry *)&buffer[0];
+ const struct msdos_dir_entry *entry2=(const struct msdos_dir_entry *)&buffer[0x20];
if(disk_car->pread(disk_car, &buffer, sizeof(buffer), hd_offset) != sizeof(buffer))
{
log_error("fat_dir, get_subdirectory(), can't read directory\n");
return 1;
}
-/* dump_ncurses(buffer,DEFAULT_SECTOR_SIZE); */
- /* 12345678123*/
- if(memcmp(&buffer[0],". ",8+3)!=0)
- return 1;
- if((unsigned)((buffer[0x15]<<24)|(buffer[0x14]<<16)|(buffer[0x1B]<<8)|buffer[0x1A])!=i)
- return 1;
- /* 12345678123*/
- if(memcmp(&buffer[0x20],".. ",8+3)!=0)
- return 1;
- return (buffer[0x35]<<24)+(buffer[0x34]<<16)+(buffer[0x3B]<<8)+buffer[0x3A];
+ if(!is_fat_directory(buffer))
+ return 1;
+ if(fat_get_cluster_from_entry(entry1) != i)
+ return 1;
+ return fat_get_cluster_from_entry(entry2);
}
#ifdef HAVE_NCURSES
@@ -357,6 +355,8 @@ static unsigned int fat32_find_root_cluster(disk_t *disk_car,const partition_t *
partition->part_offset + (start_data + (uint64_t)(root_cluster - 2) * sectors_per_cluster) *
disk_car->sector_size) == cluster_size)
{
+ const struct msdos_dir_entry *entry1=(const struct msdos_dir_entry *)&buffer[0];
+ const struct msdos_dir_entry *entry2=(const struct msdos_dir_entry *)&buffer[0x20];
if(verbose>1)
{
log_verbose("fat32_find_root_cluster test cluster=%lu\n",root_cluster);
@@ -364,22 +364,17 @@ static unsigned int fat32_find_root_cluster(disk_t *disk_car,const partition_t *
dump_ncurses(buffer,cluster_size);
*/
}
- if((memcmp(&buffer[0],". ",8+3)==0) &&
- (buffer[0xB]!=ATTR_EXT && (buffer[0xB]&ATTR_DIR)!=0))
+ if(buffer[0]=='.' && is_fat_directory(buffer))
{ /* Directory found */
- unsigned long int cluster=(buffer[1*0x20+0x15]<<24)+(buffer[1*0x20+0x14]<<16)+
- (buffer[1*0x20+0x1B]<<8)+buffer[1*0x20+0x1A];
- if((memcmp(&buffer[0x20],".. ",8+3)==0) &&
- (buffer[1*0x20+0xB]!=ATTR_EXT && (buffer[1*0x20+0xB]&ATTR_DIR)!=0) && (cluster==0)
- && (buffer[0x40]!=0)) /* First-level directory */
+ if(fat_get_cluster_from_entry(entry2)==0 &&
+ buffer[0x40]!=0) /* First-level directory with files */
{
file_info_t dir_list = {
.list = TD_LIST_HEAD_INIT(dir_list.list),
.name = NULL
};
log_info("First-level directory found at cluster %lu\n",root_cluster);
- /* dump_ncurses(buffer,cluster_size); */
- dir_fat_aux(buffer, cluster_size, cluster_size, 0, &dir_list);
+ dir_fat_aux(buffer, cluster_size, 0, &dir_list);
if(verbose>0)
{
dir_aff_log(NULL, &dir_list);
@@ -395,11 +390,11 @@ static unsigned int fat32_find_root_cluster(disk_t *disk_car,const partition_t *
delete_list_file(&dir_list);
}
}
- else if( memcmp(&buffer[0*0x20],&buffer[1*0x20],0x20)!=0)
+ else if(memcmp(entry1, entry2, 0x20)!=0)
{ /* Potential root directory */
unsigned int i,found=1;
int etat=0,nb_subdir=0,nb_subdir_ok=0;
- for(i=0;found && (i<cluster_size/0x20);i++)
+ for(i=0; found && i<cluster_size/0x20; i++)
{
int res=check_FAT_dir_entry(&buffer[i*0x20],i);
if(verbose>2)
@@ -428,10 +423,10 @@ static unsigned int fat32_find_root_cluster(disk_t *disk_car,const partition_t *
}
for(i=0;found && (i<cluster_size/32);i++)
{
+ const struct msdos_dir_entry *entry=(const struct msdos_dir_entry *)&buffer[i*0x20];
if((buffer[i*0x20]!=DELETED_FLAG) && (buffer[i*0x20+0xB]!= ATTR_EXT && (buffer[i*0x20+0xB]&ATTR_DIR)!=0)) /* Test directory */
{
- unsigned int cluster=(buffer[i*0x20+0x15]<<24)+(buffer[i*0x20+0x14]<<16)+
- (buffer[i*0x20+0x1B]<<8)+buffer[i*0x20+0x1A];
+ const unsigned int cluster=fat_get_cluster_from_entry(entry);
/* log_debug("cluster %u\n",cluster); */
if(cluster>2+no_of_cluster ||
get_subdirectory(disk_car,
@@ -510,7 +505,7 @@ static unsigned int fat32_find_root_cluster(disk_t *disk_car,const partition_t *
};
const file_info_t *file1=td_list_entry(dir_list.list.next, file_info_t, list);
const file_info_t *file2=td_list_entry(file1->list.next, file_info_t, list);
- dir_fat_aux(buffer, cluster_size, cluster_size, 0, &dir_list);
+ dir_fat_aux(buffer, cluster_size, 0, &dir_list);
if(!td_list_empty(&dir_list.list) && (&file2->list==&dir_list.list || file1->st_ino!=file2->st_ino))
{
int test_date=1;
@@ -695,10 +690,13 @@ static int fat32_create_rootdir(disk_t *disk_car,const partition_t *partition, c
}
#ifdef DEBUG
{
- file_info_t *dir_list;
- dir_list=dir_fat_aux(buffer, cluster_size, cluster_size, 0);
+ file_info_t dir_list = {
+ .list = TD_LIST_HEAD_INIT(dir_list.list),
+ .name = NULL
+ };
+ dir_fat_aux(buffer, cluster_size, 0, &dir_list);
dir_aff_log(NULL, dir_list);
- delete_list_file(dir_list);
+ delete_list_file(&dir_list);
}
#endif
free(buffer);
@@ -839,12 +837,8 @@ static int analyse_dir_entries2(disk_t *disk_car,const partition_t *partition, c
free(buffer_dir);
return 0;
}
- {
- const uint64_t start_data=reserved+fats*fat_length+(root_size_max+(disk_car->sector_size/32)-1)/(disk_car->sector_size/32);
- const unsigned int sectors_per_cluster=calcul_sectors_per_cluster(upart_type,partition->part_size/disk_car->sector_size-start_data,fat_length,disk_car->sector_size);
- dir_fat_aux(buffer_dir, root_dir_size, sectors_per_cluster*disk_car->sector_size,
- (partition->upart_type==UP_FAT12?FLAG_LIST_MASK12:FLAG_LIST_MASK16), &dir_list);
- }
+ dir_fat_aux(buffer_dir, root_dir_size,
+ (partition->upart_type==UP_FAT12?FLAG_LIST_MASK12:FLAG_LIST_MASK16), &dir_list);
if(verbose>1)
{
dir_aff_log(NULL, &dir_list);
@@ -873,16 +867,13 @@ static int analyse_dir_entries2(disk_t *disk_car,const partition_t *partition, c
if((unsigned)disk_car->pread(disk_car, buffer_dir, disk_car->sector_size,
partition->part_offset + (start_data + (uint64_t)(new_inode - 2) * sectors_per_cluster) * disk_car->sector_size) == disk_car->sector_size)
{
- if(memcmp(&buffer_dir[0],". ",8+3)==0 &&
- memcmp(&buffer_dir[0x20],".. ",8+3)==0)
+ if(buffer_dir[0]=='.' && is_fat_directory(buffer_dir))
{
- const unsigned long int cluster=(buffer_dir[0*0x20+0x15]<<24)+(buffer_dir[0*0x20+0x14]<<16)+
- (buffer_dir[0*0x20+0x1B]<<8)+buffer_dir[0*0x20+0x1A];
- const unsigned long int cluster_prev=(buffer_dir[1*0x20+0x15]<<24)+(buffer_dir[1*0x20+0x14]<<16)+
- (buffer_dir[1*0x20+0x1B]<<8)+buffer_dir[1*0x20+0x1A];
+ const unsigned long int cluster=fat_get_cluster_from_entry((const struct msdos_dir_entry *)&buffer_dir[0]);
+ const unsigned long int cluster_prev=fat_get_cluster_from_entry((const struct msdos_dir_entry *)&buffer_dir[0x20]);
if(verbose>1)
{
- log_verbose("Cluster %lu, directory .. found link to %lu\n",cluster,cluster_prev);
+ log_verbose("Cluster %lu, directory .. found link to %lu\n", cluster, cluster_prev);
}
if(cluster_prev==0 && cluster==new_inode)
{
@@ -2336,10 +2327,18 @@ int repair_FAT_table(disk_t *disk_car, partition_t *partition, const int verbose
if((unsigned)disk_car->pread(disk_car, buffer, disk_car->sector_size, partition->part_offset) != disk_car->sector_size)
{
display_message("repair_FAT_table: Can't read boot sector\n");
+ free(buffer);
+#ifdef HAVE_NCURSES
+ delwin(window);
+ (void) clearok(stdscr, TRUE);
+#ifdef HAVE_TOUCHWIN
+ touchwin(stdscr);
+#endif
+#endif
return 1;
}
fat_length=le16(fat_header->fat_length)>0?le16(fat_header->fat_length):le32(fat_header->fat32_length);
- part_size=(sectors(fat_header)>0?sectors(fat_header):le32(fat_header->total_sect));
+ part_size=(fat_sectors(fat_header)>0?fat_sectors(fat_header):le32(fat_header->total_sect));
start_fat1=le16(fat_header->reserved);
fats=fat_header->fats;
start_data=start_fat1+fats*fat_length+(get_dir_entries(fat_header)*32+disk_car->sector_size-1)/disk_car->sector_size;
@@ -2349,7 +2348,16 @@ int repair_FAT_table(disk_t *disk_car, partition_t *partition, const int verbose
free(buffer);
}
if(fats==0 || fats>2)
+ {
+#ifdef HAVE_NCURSES
+ delwin(window);
+ (void) clearok(stdscr, TRUE);
+#ifdef HAVE_TOUCHWIN
+ touchwin(stdscr);
+#endif
+#endif
return 1;
+ }
{
const unsigned int buffer_size=(partition->upart_type==UP_FAT12?2*disk_car->sector_size:disk_car->sector_size);
fat_status_t fat_status[2];
diff --git a/src/fat_cluster.c b/src/fat_cluster.c
index fb6b958..f735f2d 100644
--- a/src/fat_cluster.c
+++ b/src/fat_cluster.c
@@ -37,6 +37,8 @@
#include "intrfn.h"
#include "log.h"
#include "fat_cluster.h"
+#include "fat.h"
+#include "fat_common.h"
/* Using a couple of inodes of "." directory entries, get the cluster size and where the first cluster begins.
* */
@@ -81,10 +83,9 @@ int find_sectors_per_cluster(disk_t *disk_car, partition_t *partition, const int
#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)
+ if(buffer[0]=='.' && is_fat_directory(buffer))
{
- unsigned long int cluster=(buffer[0*0x20+0x15]<<24) + (buffer[0*0x20+0x14]<<16) +
- (buffer[0*0x20+0x1B]<<8) + buffer[0*0x20+0x1A];
+ const unsigned long int cluster=fat_get_cluster_from_entry((const struct msdos_dir_entry *)buffer);
log_info("sector %lu, cluster %lu\n",
(unsigned long)(offset/disk_car->sector_size), cluster);
sector_cluster[nbr_subdir].cluster=cluster;
diff --git a/src/fat_common.c b/src/fat_common.c
index e6a6bee..ab1f181 100644
--- a/src/fat_common.c
+++ b/src/fat_common.c
@@ -23,9 +23,13 @@
#include <config.h>
#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
#include "types.h"
#include "common.h"
#include "fat.h"
+#include "fat_common.h"
unsigned int fat_sector_size(const struct fat_boot_sector *fat_header)
{ return (fat_header->sector_size[1]<<8)+fat_header->sector_size[0]; }
@@ -33,6 +37,19 @@ unsigned int fat_sector_size(const struct fat_boot_sector *fat_header)
unsigned int get_dir_entries(const struct fat_boot_sector *fat_header)
{ return (fat_header->dir_entries[1]<<8)+fat_header->dir_entries[0]; }
-unsigned int sectors(const struct fat_boot_sector *fat_header)
+unsigned int fat_sectors(const struct fat_boot_sector *fat_header)
{ return (fat_header->sectors[1]<<8)+fat_header->sectors[0]; }
+unsigned int fat_get_cluster_from_entry(const struct msdos_dir_entry *entry)
+{
+ return (((unsigned long int)le16(entry->starthi))<<16) | le16(entry->start);
+}
+
+int is_fat_directory(const unsigned char *buffer)
+{
+ return(buffer[0]=='.' &&
+ memcmp(buffer, ". ", 8+3)==0 &&
+ memcmp(&buffer[0x20], ".. ", 8+3)==0 &&
+ buffer[0xB]!=ATTR_EXT && (buffer[0xB]&ATTR_DIR)!=0 &&
+ buffer[1*0x20+0xB]!=ATTR_EXT && (buffer[1*0x20+0xB]&ATTR_DIR)!=0);
+}
diff --git a/src/fat_dir.c b/src/fat_dir.c
index 5619e62..faa739e 100644
--- a/src/fat_dir.c
+++ b/src/fat_dir.c
@@ -41,6 +41,7 @@
#include "types.h"
#include "common.h"
#include "fat.h"
+#include "fat_common.h"
#include "lang.h"
#include "intrf.h"
#include "dir.h"
@@ -69,7 +70,7 @@ static inline void fat16_towchar(wchar_t *dst, const uint8_t *src, size_t len)
}
}
-int dir_fat_aux(const unsigned char*buffer, const unsigned int size, const unsigned int cluster_size, const unsigned int param, file_info_t *dir_list)
+int dir_fat_aux(const unsigned char*buffer, const unsigned int size, const unsigned int param, file_info_t *dir_list)
{
const struct msdos_dir_entry *de=(const struct msdos_dir_entry*)buffer;
wchar_t unicode[1000];
@@ -349,7 +350,7 @@ static int fat_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *d
fat_method_t fat_meth=FAT_FOLLOW_CLUSTER;
memset(buffer_dir,0,cluster_size*NBR_CLUSTER_MAX);
fat_length=le16(fat_header->fat_length)>0?le16(fat_header->fat_length):le32(fat_header->fat32_length);
- part_size=(sectors(fat_header)>0?sectors(fat_header):le32(fat_header->total_sect));
+ part_size=(fat_sectors(fat_header)>0?fat_sectors(fat_header):le32(fat_header->total_sect));
start_fat1=le16(fat_header->reserved);
start_data=start_fat1+fat_header->fats*fat_length+(get_dir_entries(fat_header)*32+disk_car->sector_size-1)/disk_car->sector_size;
no_of_cluster=(part_size-start_data)/fat_header->sectors_per_cluster;
@@ -406,7 +407,7 @@ static int fat_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *d
}
}
if(nbr_cluster>0)
- dir_fat_aux(buffer_dir, cluster_size*nbr_cluster, cluster_size, dir_data->param, dir_list);
+ dir_fat_aux(buffer_dir, cluster_size*nbr_cluster, dir_data->param, dir_list);
free(buffer_dir);
return 0;
}
@@ -432,7 +433,7 @@ static int fat1x_rootdir(disk_t *disk_car, const partition_t *partition, const d
log_error("FAT 1x: Can't read root directory.\n");
/* Don't return yet, it may have been a partial read */
}
- res=dir_fat_aux(buffer_dir, root_size, fat_header->sectors_per_cluster * fat_sector_size(fat_header), dir_data->param, dir_list);
+ res=dir_fat_aux(buffer_dir, root_size, dir_data->param, dir_list);
free(buffer_dir);
return res;
}
@@ -501,7 +502,7 @@ static int fat_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *
}
cluster = file->st_ino;
fat_length=le16(fat_header->fat_length)>0?le16(fat_header->fat_length):le32(fat_header->fat32_length);
- part_size=(sectors(fat_header)>0?sectors(fat_header):le32(fat_header->total_sect));
+ part_size=(fat_sectors(fat_header)>0?fat_sectors(fat_header):le32(fat_header->total_sect));
start_fat1=le16(fat_header->reserved);
start_data=start_fat1+fat_header->fats*fat_length+(get_dir_entries(fat_header)*32+disk_car->sector_size-1)/disk_car->sector_size;
no_of_cluster=(part_size-start_data)/sectors_per_cluster;
diff --git a/src/fat_dir.h b/src/fat_dir.h
index 2e2290e..4988260 100644
--- a/src/fat_dir.h
+++ b/src/fat_dir.h
@@ -23,7 +23,7 @@
extern "C" {
#endif
-int dir_fat_aux(const unsigned char*buffer, const unsigned int size, const unsigned int cluster_size, const unsigned int param, file_info_t *dir_list);
+int dir_fat_aux(const unsigned char*buffer, const unsigned int size, const unsigned int param, file_info_t *dir_list);
dir_partition_t dir_partition_fat_init(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const int verbose);
#ifdef __cplusplus
diff --git a/src/fat_unformat.c b/src/fat_unformat.c
index 84a1532..73783fe 100644
--- a/src/fat_unformat.c
+++ b/src/fat_unformat.c
@@ -41,6 +41,7 @@
#include "intrf.h"
#include "intrfn.h"
#include "dir.h"
+#include "fat.h"
#include "fat_dir.h"
#include "list.h"
#include "filegen.h"
@@ -51,6 +52,7 @@
#include "fat_unformat.h"
#include "pnext.h"
#include "setdate.h"
+#include "fat_common.h"
#define READ_SIZE 4*1024*1024
static int pfind_sectors_per_cluster(disk_t *disk, partition_t *partition, const int verbose, unsigned int *sectors_per_cluster, uint64_t *offset_org, alloc_data_t *list_search_space)
@@ -79,12 +81,9 @@ static int pfind_sectors_per_cluster(disk_t *disk, partition_t *partition, const
while(current_search_space!=list_search_space && nbr_subdir<10)
{
const uint64_t old_offset=offset;
- if(buffer[0]=='.' &&
- memcmp(buffer, ". ", 8+3)==0 &&
- memcmp(&buffer[0x20], ".. ", 8+3)==0)
+ if(buffer[0]=='.' && is_fat_directory(buffer))
{
- const unsigned long int cluster=(buffer[0*0x20+0x15]<<24) + (buffer[0*0x20+0x14]<<16) +
- (buffer[0*0x20+0x1B]<<8) + buffer[0*0x20+0x1A];
+ const unsigned long int cluster=fat_get_cluster_from_entry((const struct msdos_dir_entry *)buffer);
log_info("sector %lu, cluster %lu\n",
(unsigned long)(offset/disk->sector_size), cluster);
sector_cluster[nbr_subdir].cluster=cluster;
@@ -237,15 +236,13 @@ static pstatus_t fat_unformat_aux(struct ph_param *params, const struct ph_optio
disk->pread(disk, buffer, READ_SIZE, offset);
for(;offset < offset_end; offset+=cluster_size)
{
- if(buffer[0]=='.' &&
- memcmp(buffer, ". ", 8+3)==0 &&
- memcmp(&buffer[0x20], ".. ", 8+3)==0)
+ if(buffer[0]=='.' && is_fat_directory(buffer))
{
file_info_t dir_list = {
.list = TD_LIST_HEAD_INIT(dir_list.list),
.name = NULL
};
- dir_fat_aux(buffer,read_size,0,0, &dir_list);
+ dir_fat_aux(buffer, read_size, 0, &dir_list);
if(!td_list_empty(&dir_list.list))
{
struct td_list_head *file_walker = NULL;
diff --git a/src/fatn.c b/src/fatn.c
index c139a03..f86a704 100644
--- a/src/fatn.c
+++ b/src/fatn.c
@@ -32,6 +32,7 @@
#include "intrfn.h"
#include "fat.h"
#include "fatn.h"
+#include "fat_common.h"
int dump_fat_info_ncurses(const struct fat_boot_sector*fh1, const upart_type_t upart_type, const unsigned int sector_size)
{
@@ -52,8 +53,8 @@ int dump_fat_info_ncurses(const struct fat_boot_sector*fh1, const upart_type_t u
}
wprintw(stdscr,"cluster_size %u\n", fh1->sectors_per_cluster);
wprintw(stdscr,"reserved %u\n", le16(fh1->reserved));
- if(sectors(fh1)!=0)
- wprintw(stdscr,"sectors %u\n", sectors(fh1));
+ if(fat_sectors(fh1)!=0)
+ wprintw(stdscr,"sectors %u\n", fat_sectors(fh1));
if(le32(fh1->total_sect)!=0)
wprintw(stdscr,"total_sect %u\n", (unsigned int)le32(fh1->total_sect));
if(upart_type==UP_FAT32)
@@ -99,8 +100,8 @@ int dump_2fat_info_ncurses(const struct fat_boot_sector*fh1, const struct fat_bo
}
wprintw(stdscr,"cluster_size %u %u\n", fh1->sectors_per_cluster, fh2->sectors_per_cluster);
wprintw(stdscr,"reserved %u %u\n", le16(fh1->reserved),le16(fh2->reserved));
- if(sectors(fh1)!=0 || sectors(fh2)!=0)
- wprintw(stdscr,"sectors %u %u\n", sectors(fh1), sectors(fh2));
+ if(fat_sectors(fh1)!=0 || fat_sectors(fh2)!=0)
+ wprintw(stdscr,"sectors %u %u\n", fat_sectors(fh1), fat_sectors(fh2));
if(le32(fh1->total_sect)!=0 || le32(fh2->total_sect)!=0)
wprintw(stdscr,"total_sect %u %u\n", (unsigned int)le32(fh1->total_sect), (unsigned int)le32(fh2->total_sect));
if(upart_type==UP_FAT32)
diff --git a/src/fatp.c b/src/fatp.c
index 2b0f886..359abb3 100644
--- a/src/fatp.c
+++ b/src/fatp.c
@@ -33,6 +33,7 @@
#include "filegen.h"
#include "fatp.h"
#include "fat.h"
+#include "fat_common.h"
#include "log.h"
static void fat16_remove_used_space(disk_t *disk_car,const partition_t *partition, alloc_data_t *list_search_space, const unsigned int fat_offset, const unsigned int no_of_cluster, const unsigned int start_data, const unsigned int cluster_size, const unsigned int sector_size);
@@ -200,7 +201,7 @@ unsigned int fat_remove_used_space(disk_t *disk_car, const partition_t *partitio
return 0;
}
fat_length=le16(fat_header->fat_length)>0?le16(fat_header->fat_length):le32(fat_header->fat32_length);
- part_size=(sectors(fat_header)>0?sectors(fat_header):le32(fat_header->total_sect));
+ part_size=(fat_sectors(fat_header)>0?fat_sectors(fat_header):le32(fat_header->total_sect));
start_fat1=le16(fat_header->reserved);
start_data=start_fat1+fat_header->fats*fat_length+(get_dir_entries(fat_header)*32+sector_size-1)/sector_size;
no_of_cluster=(part_size-start_data)/fat_header->sectors_per_cluster;
diff --git a/src/file_dir.c b/src/file_dir.c
index fcd7c2f..a82788d 100644
--- a/src/file_dir.c
+++ b/src/file_dir.c
@@ -36,6 +36,7 @@
#include "fat.h"
#include "dir.h"
#include "fat_dir.h"
+#include "fat_common.h"
static void register_header_check_dir(file_stat_t *file_stat);
static int header_check_dir(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);
@@ -61,9 +62,9 @@ static void file_rename_fatdir(const char *old_filename)
return;
buffer_size=fread(buffer, 1, sizeof(buffer), file);
fclose(file);
- if(buffer_size<10)
+ if(buffer_size<32)
return;
- cluster=(buffer[0x15]<<24)|(buffer[0x14]<<16)|(buffer[0x1B]<<8)|buffer[0x1A];
+ cluster=fat_get_cluster_from_entry((const struct msdos_dir_entry *)&buffer[0]);
sprintf(buffer_cluster, "cluster_%u", cluster);
file_rename(old_filename, buffer_cluster, strlen(buffer_cluster), 0, NULL, 1);
}
@@ -78,7 +79,7 @@ static int data_check_fatdir(const unsigned char *buffer, const unsigned int buf
static int header_check_dir(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 msdos_dir_entry *de=(const struct msdos_dir_entry*)buffer;
- if(memcmp(&buffer[0x20],".. ",8+3)!=0)
+ if(!is_fat_directory(buffer))
return 0;
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_dir.extension;
diff --git a/src/file_fat.c b/src/file_fat.c
index de9f0d2..49969e7 100644
--- a/src/file_fat.c
+++ b/src/file_fat.c
@@ -36,6 +36,7 @@
#include "log.h"
#include "memmem.h"
#include "fat.h"
+#include "fat_common.h"
static void register_header_check_fat(file_stat_t *file_stat);
static int header_check_fat(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);
@@ -89,7 +90,7 @@ static int header_check_fat(const unsigned char *buffer, const unsigned int buff
if(fat_header->media!=0xF0 && fat_header->media<0xF8)
return 0;
fat_length=le16(fat_header->fat_length)>0?le16(fat_header->fat_length):le32(fat_header->fat32_length);
- part_size=(sectors(fat_header)>0?sectors(fat_header):le32(fat_header->total_sect));
+ part_size=(fat_sectors(fat_header)>0?fat_sectors(fat_header):le32(fat_header->total_sect));
start_fat1=le16(fat_header->reserved);
start_data=start_fat1+fat_header->fats*fat_length+(get_dir_entries(fat_header)*32+fat_sector_size(fat_header)-1)/fat_sector_size(fat_header);
no_of_cluster=(part_size-start_data)/fat_header->sectors_per_cluster;
@@ -114,7 +115,7 @@ static int header_check_fat(const unsigned char *buffer, const unsigned int buff
else
{
/* FAT32 */
- if(sectors(fat_header)!=0)
+ if(fat_sectors(fat_header)!=0)
return 0;
if(get_dir_entries(fat_header)!=0)
return 0;
@@ -127,7 +128,7 @@ static int header_check_fat(const unsigned char *buffer, const unsigned int buff
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_fat.extension;
file_recovery_new->calculated_file_size=(uint64_t)
- (sectors(fat_header)>0?sectors(fat_header):le32(fat_header->total_sect)) *
+ (fat_sectors(fat_header)>0?fat_sectors(fat_header):le32(fat_header->total_sect)) *
fat_sector_size(fat_header);
file_recovery_new->data_check=&data_check_size;
file_recovery_new->file_check=&file_check_size;
diff --git a/src/hpfs.c b/src/hpfs.c
index 4c47bca..3dd629c 100644
--- a/src/hpfs.c
+++ b/src/hpfs.c
@@ -31,6 +31,7 @@
#include "types.h"
#include "common.h"
#include "fat.h"
+#include "fat_common.h"
#include "hpfs.h"
#include "fnctdsk.h"
#include "intrf.h"
@@ -57,7 +58,7 @@ static int test_HPFS(disk_t *disk_car,const struct fat_boot_sector *hpfs_header,
}
if(dump_ind!=0)
dump_log(buffer, DEFAULT_SECTOR_SIZE);
- partition->part_size=(uint64_t)(sectors(hpfs_header)>0?sectors(hpfs_header):le32(hpfs_header->total_sect)) *
+ partition->part_size=(uint64_t)(fat_sectors(hpfs_header)>0?fat_sectors(hpfs_header):le32(hpfs_header->total_sect)) *
fat_sector_size(hpfs_header);
partition->upart_type=UP_HPFS;
return 0;
diff --git a/src/psearchn.c b/src/psearchn.c
index 0c1fd9b..89335c0 100644
--- a/src/psearchn.c
+++ b/src/psearchn.c
@@ -233,7 +233,7 @@ pstatus_t photorec_aux(struct ph_param *params, const struct ph_options *options
.list = TD_LIST_HEAD_INIT(dir_list.list),
.name = NULL
};
- dir_fat_aux(buffer,read_size,0,0, &dir_list);
+ dir_fat_aux(buffer, read_size, 0, &dir_list);
if(!td_list_empty(&dir_list.list))
{
log_info("Sector %lu\n",
diff --git a/src/qpsearch.cpp b/src/qpsearch.cpp
index 45af322..06a10e0 100644
--- a/src/qpsearch.cpp
+++ b/src/qpsearch.cpp
@@ -229,7 +229,7 @@ pstatus_t QPhotorec::photorec_aux(alloc_data_t *list_search_space)
.list = TD_LIST_HEAD_INIT(dir_list.list),
.name = NULL
};
- dir_fat_aux(buffer,read_size,0,0, &dir_list);
+ dir_fat_aux(buffer, read_size, 0, &dir_list);
if(!td_list_empty(&dir_list.list))
{
log_info("Sector %lu\n",