- Get rid of crt dependencies.

- Fix all printfs to VfatPrint function (which calls appropriate callback).

svn path=/trunk/; revision=35104
This commit is contained in:
Aleksey Bragin 2008-08-04 16:04:56 +00:00
parent 9a37df12d7
commit 799a04653b
11 changed files with 215 additions and 179 deletions

View file

@ -58,55 +58,55 @@ static void dump_boot(DOS_FS *fs,struct boot_sector *b,unsigned lss)
{ {
unsigned short sectors; unsigned short sectors;
printf("Boot sector contents:\n"); VfatPrint("Boot sector contents:\n");
if (!atari_format) { if (!atari_format) {
char id[9]; char id[9];
strncpy(id,(char*)b->system_id,8); strncpy(id,(char*)b->system_id,8);
id[8] = 0; id[8] = 0;
printf("System ID \"%s\"\n",id); VfatPrint("System ID \"%s\"\n",id);
} }
else { else {
/* On Atari, a 24 bit serial number is stored at offset 8 of the boot /* On Atari, a 24 bit serial number is stored at offset 8 of the boot
* sector */ * sector */
printf("Serial number 0x%x\n", VfatPrint("Serial number 0x%x\n",
b->system_id[5] | (b->system_id[6]<<8) | (b->system_id[7]<<16)); b->system_id[5] | (b->system_id[6]<<8) | (b->system_id[7]<<16));
} }
printf("Media byte 0x%02x (%s)\n",b->media,get_media_descr(b->media)); VfatPrint("Media byte 0x%02x (%s)\n",b->media,get_media_descr(b->media));
printf("%10d bytes per logical sector\n",GET_UNALIGNED_W(b->sector_size)); VfatPrint("%10d bytes per logical sector\n",GET_UNALIGNED_W(b->sector_size));
printf("%10d bytes per cluster\n",fs->cluster_size); VfatPrint("%10d bytes per cluster\n",fs->cluster_size);
printf("%10d reserved sector%s\n",CF_LE_W(b->reserved), VfatPrint("%10d reserved sector%s\n",CF_LE_W(b->reserved),
CF_LE_W(b->reserved) == 1 ? "" : "s"); CF_LE_W(b->reserved) == 1 ? "" : "s");
printf("First FAT starts at byte %llu (sector %llu)\n", VfatPrint("First FAT starts at byte %llu (sector %llu)\n",
(__u64)fs->fat_start, (__u64)fs->fat_start,
(__u64)fs->fat_start/lss); (__u64)fs->fat_start/lss);
printf("%10d FATs, %d bit entries\n",b->fats,fs->fat_bits); VfatPrint("%10d FATs, %d bit entries\n",b->fats,fs->fat_bits);
printf("%10d bytes per FAT (= %u sectors)\n",fs->fat_size, VfatPrint("%10d bytes per FAT (= %u sectors)\n",fs->fat_size,
fs->fat_size/lss); fs->fat_size/lss);
if (!fs->root_cluster) { if (!fs->root_cluster) {
printf("Root directory starts at byte %llu (sector %llu)\n", VfatPrint("Root directory starts at byte %llu (sector %llu)\n",
(__u64)fs->root_start, (__u64)fs->root_start,
(__u64)fs->root_start/lss); (__u64)fs->root_start/lss);
printf("%10d root directory entries\n",fs->root_entries); VfatPrint("%10d root directory entries\n",fs->root_entries);
} }
else { else {
printf( "Root directory start at cluster %lu (arbitrary size)\n", VfatPrint( "Root directory start at cluster %lu (arbitrary size)\n",
fs->root_cluster); fs->root_cluster);
} }
printf("Data area starts at byte %llu (sector %llu)\n", VfatPrint("Data area starts at byte %llu (sector %llu)\n",
(__u64)fs->data_start, (__u64)fs->data_start,
(__u64)fs->data_start/lss); (__u64)fs->data_start/lss);
printf("%10lu data clusters (%llu bytes)\n",fs->clusters, VfatPrint("%10lu data clusters (%llu bytes)\n",fs->clusters,
(__u64)fs->clusters*fs->cluster_size); (__u64)fs->clusters*fs->cluster_size);
printf("%u sectors/track, %u heads\n",CF_LE_W(b->secs_track), VfatPrint("%u sectors/track, %u heads\n",CF_LE_W(b->secs_track),
CF_LE_W(b->heads)); CF_LE_W(b->heads));
printf("%10u hidden sectors\n", VfatPrint("%10u hidden sectors\n",
atari_format ? atari_format ?
/* On Atari, the hidden field is only 16 bit wide and unused */ /* On Atari, the hidden field is only 16 bit wide and unused */
(((unsigned char *)&b->hidden)[0] | (((unsigned char *)&b->hidden)[0] |
((unsigned char *)&b->hidden)[1] << 8) : ((unsigned char *)&b->hidden)[1] << 8) :
CF_LE_L(b->hidden)); CF_LE_L(b->hidden));
sectors = GET_UNALIGNED_W( b->sectors ); sectors = GET_UNALIGNED_W( b->sectors );
printf("%10u sectors total\n", sectors ? sectors : CF_LE_L(b->total_sect)); VfatPrint("%10u sectors total\n", sectors ? sectors : CF_LE_L(b->total_sect));
} }
static void check_backup_boot(DOS_FS *fs, struct boot_sector *b, int lss) static void check_backup_boot(DOS_FS *fs, struct boot_sector *b, int lss)
@ -114,14 +114,14 @@ static void check_backup_boot(DOS_FS *fs, struct boot_sector *b, int lss)
struct boot_sector b2; struct boot_sector b2;
if (!fs->backupboot_start) { if (!fs->backupboot_start) {
printf( "There is no backup boot sector.\n" ); VfatPrint( "There is no backup boot sector.\n" );
if (CF_LE_W(b->reserved) < 3) { if (CF_LE_W(b->reserved) < 3) {
printf( "And there is no space for creating one!\n" ); VfatPrint( "And there is no space for creating one!\n" );
return; return;
} }
if (interactive) if (interactive)
printf( "1) Create one\n2) Do without a backup\n" ); VfatPrint( "1) Create one\n2) Do without a backup\n" );
else printf( " Auto-creating backup boot block.\n" ); else VfatPrint( " Auto-creating backup boot block.\n" );
if (!interactive || get_key("12","?") == '1') { if (!interactive || get_key("12","?") == '1') {
int bbs; int bbs;
/* The usual place for the backup boot sector is sector 6. Choose /* The usual place for the backup boot sector is sector 6. Choose
@ -138,7 +138,7 @@ static void check_backup_boot(DOS_FS *fs, struct boot_sector *b, int lss)
fs_write(fs->backupboot_start,sizeof(*b),b); fs_write(fs->backupboot_start,sizeof(*b),b);
fs_write((off_t)offsetof(struct boot_sector,backup_boot), fs_write((off_t)offsetof(struct boot_sector,backup_boot),
sizeof(b->backup_boot),&b->backup_boot); sizeof(b->backup_boot),&b->backup_boot);
printf( "Created backup of boot sector in sector %d\n", bbs ); VfatPrint( "Created backup of boot sector in sector %d\n", bbs );
return; return;
} }
else return; else return;
@ -151,27 +151,27 @@ static void check_backup_boot(DOS_FS *fs, struct boot_sector *b, int lss)
int i, pos, first = 1; int i, pos, first = 1;
char buf[20]; char buf[20];
printf( "There are differences between boot sector and its backup.\n" ); VfatPrint( "There are differences between boot sector and its backup.\n" );
printf( "Differences: (offset:original/backup)\n " ); VfatPrint( "Differences: (offset:original/backup)\n " );
pos = 2; pos = 2;
for( p = (__u8 *)b, q = (__u8 *)&b2, i = 0; i < sizeof(b2); for( p = (__u8 *)b, q = (__u8 *)&b2, i = 0; i < sizeof(b2);
++p, ++q, ++i ) { ++p, ++q, ++i ) {
if (*p != *q) { if (*p != *q) {
sprintf( buf, "%s%u:%02x/%02x", first ? "" : ", ", sprintf( buf, "%s%u:%02x/%02x", first ? "" : ", ",
(unsigned)(p-(__u8 *)b), *p, *q ); (unsigned)(p-(__u8 *)b), *p, *q );
if (pos + strlen(buf) > 78) printf( "\n " ), pos = 2; if (pos + strlen(buf) > 78) VfatPrint( "\n " ), pos = 2;
printf( "%s", buf ); VfatPrint( "%s", buf );
pos += strlen(buf); pos += strlen(buf);
first = 0; first = 0;
} }
} }
printf( "\n" ); VfatPrint( "\n" );
if (interactive) if (interactive)
printf( "1) Copy original to backup\n" VfatPrint( "1) Copy original to backup\n"
"2) Copy backup to original\n" "2) Copy backup to original\n"
"3) No action\n" ); "3) No action\n" );
else printf( " Not automatically fixing this.\n" ); else VfatPrint( " Not automatically fixing this.\n" );
switch (interactive ? get_key("123","?") : '3') { switch (interactive ? get_key("123","?") : '3') {
case '1': case '1':
fs_write(fs->backupboot_start,sizeof(*b),b); fs_write(fs->backupboot_start,sizeof(*b),b);
@ -199,10 +199,10 @@ static void read_fsinfo(DOS_FS *fs, struct boot_sector *b,int lss)
struct info_sector i; struct info_sector i;
if (!b->info_sector) { if (!b->info_sector) {
printf( "No FSINFO sector\n" ); VfatPrint( "No FSINFO sector\n" );
if (interactive) if (interactive)
printf( "1) Create one\n2) Do without FSINFO\n" ); VfatPrint( "1) Create one\n2) Do without FSINFO\n" );
else printf( " Not automatically creating it.\n" ); else VfatPrint( " Not automatically creating it.\n" );
if (interactive && get_key("12","?") == '1') { if (interactive && get_key("12","?") == '1') {
/* search for a free reserved sector (not boot sector and not /* search for a free reserved sector (not boot sector and not
* backup boot sector) */ * backup boot sector) */
@ -221,7 +221,7 @@ static void read_fsinfo(DOS_FS *fs, struct boot_sector *b,int lss)
sizeof(b->info_sector),&b->info_sector); sizeof(b->info_sector),&b->info_sector);
} }
else { else {
printf( "No free reserved sector found -- " VfatPrint( "No free reserved sector found -- "
"no space for FSINFO sector!\n" ); "no space for FSINFO sector!\n" );
return; return;
} }
@ -235,22 +235,22 @@ static void read_fsinfo(DOS_FS *fs, struct boot_sector *b,int lss)
if (i.magic != CT_LE_L(0x41615252) || if (i.magic != CT_LE_L(0x41615252) ||
i.signature != CT_LE_L(0x61417272) || i.signature != CT_LE_L(0x61417272) ||
i.boot_sign != CT_LE_W(0xaa55)) { i.boot_sign != CT_LE_W(0xaa55)) {
printf( "FSINFO sector has bad magic number(s):\n" ); VfatPrint( "FSINFO sector has bad magic number(s):\n" );
if (i.magic != CT_LE_L(0x41615252)) if (i.magic != CT_LE_L(0x41615252))
printf( " Offset %llu: 0x%08x != expected 0x%08x\n", VfatPrint( " Offset %llu: 0x%08x != expected 0x%08x\n",
(__u64)offsetof(struct info_sector,magic), (__u64)offsetof(struct info_sector,magic),
CF_LE_L(i.magic),0x41615252); CF_LE_L(i.magic),0x41615252);
if (i.signature != CT_LE_L(0x61417272)) if (i.signature != CT_LE_L(0x61417272))
printf( " Offset %llu: 0x%08x != expected 0x%08x\n", VfatPrint( " Offset %llu: 0x%08x != expected 0x%08x\n",
(__u64)offsetof(struct info_sector,signature), (__u64)offsetof(struct info_sector,signature),
CF_LE_L(i.signature),0x61417272); CF_LE_L(i.signature),0x61417272);
if (i.boot_sign != CT_LE_W(0xaa55)) if (i.boot_sign != CT_LE_W(0xaa55))
printf( " Offset %llu: 0x%04x != expected 0x%04x\n", VfatPrint( " Offset %llu: 0x%04x != expected 0x%04x\n",
(__u64)offsetof(struct info_sector,boot_sign), (__u64)offsetof(struct info_sector,boot_sign),
CF_LE_W(i.boot_sign),0xaa55); CF_LE_W(i.boot_sign),0xaa55);
if (interactive) if (interactive)
printf( "1) Correct\n2) Don't correct (FSINFO invalid then)\n" ); VfatPrint( "1) Correct\n2) Don't correct (FSINFO invalid then)\n" );
else printf( " Auto-correcting it.\n" ); else VfatPrint( " Auto-correcting it.\n" );
if (!interactive || get_key("12","?") == '1') { if (!interactive || get_key("12","?") == '1') {
init_fsinfo(&i); init_fsinfo(&i);
fs_write(fs->fsinfo_start,sizeof(i),&i); fs_write(fs->fsinfo_start,sizeof(i),&i);
@ -280,7 +280,7 @@ void read_boot(DOS_FS *fs)
fs->nfats = b.fats; fs->nfats = b.fats;
sectors = GET_UNALIGNED_W(b.sectors); sectors = GET_UNALIGNED_W(b.sectors);
total_sectors = sectors ? sectors : CF_LE_L(b.total_sect); total_sectors = sectors ? sectors : CF_LE_L(b.total_sect);
if (verbose) printf("Checking we can access the last sector of the filesystem\n"); if (verbose) VfatPrint("Checking we can access the last sector of the filesystem\n");
/* Can't access last odd sector anyway, so round down */ /* Can't access last odd sector anyway, so round down */
fs_test((loff_t)((total_sectors & ~1)-1)*(loff_t)logical_sector_size, fs_test((loff_t)((total_sectors & ~1)-1)*(loff_t)logical_sector_size,
logical_sector_size); logical_sector_size);
@ -306,12 +306,12 @@ void read_boot(DOS_FS *fs)
* (root_entries != 0), we handle the root dir the old way. Give a * (root_entries != 0), we handle the root dir the old way. Give a
* warning, but convertig to a root dir in a cluster chain seems * warning, but convertig to a root dir in a cluster chain seems
* to complex for now... */ * to complex for now... */
printf( "Warning: FAT32 root dir not in cluster chain! " VfatPrint( "Warning: FAT32 root dir not in cluster chain! "
"Compability mode...\n" ); "Compability mode...\n" );
else if (!fs->root_cluster && !fs->root_entries) else if (!fs->root_cluster && !fs->root_entries)
die("No root directory!"); die("No root directory!");
else if (fs->root_cluster && fs->root_entries) else if (fs->root_cluster && fs->root_entries)
printf( "Warning: FAT32 root dir is in a cluster chain, but " VfatPrint( "Warning: FAT32 root dir is in a cluster chain, but "
"a separate root dir\n" "a separate root dir\n"
" area is defined. Cannot fix this easily.\n" ); " area is defined. Cannot fix this easily.\n" );

View file

@ -198,15 +198,22 @@ time_t date_dos2unix(unsigned short time,unsigned short date)
static char *file_stat(DOS_FILE *file) static char *file_stat(DOS_FILE *file)
{ {
static char temp[100]; static char temp[100];
struct tm *tm;
char tmp[100]; char tmp[100];
time_t date; time_t date;
LARGE_INTEGER time;
TIME_FIELDS time_fields;
date = date_dos2unix(CF_LE_W(file->dir_ent.time),CF_LE_W(file-> date = date_dos2unix(CF_LE_W(file->dir_ent.time),CF_LE_W(file->
dir_ent.date)); dir_ent.date));
tm = localtime(&date);
strftime(tmp,99,"%H:%M:%S %b %d %Y",tm); RtlSecondsSince1970ToTime(date, &time);
sprintf(temp," Size %u bytes, date %s",CF_LE_L(file->dir_ent.size),tmp); RtlTimeToTimeFields(&time, &time_fields);
_snprintf(tmp, sizeof(tmp), "%d:%d:%d %d.%d.%d",
time_fields.Hour, time_fields.Minute, time_fields.Second,
time_fields.Day, time_fields.Month, time_fields.Year);
_snprintf(temp, sizeof(temp), " Size %u bytes, date %s",CF_LE_L(file->dir_ent.size),tmp);
return temp; return temp;
} }
@ -322,15 +329,16 @@ static void auto_rename(DOS_FILE *file)
static void rename_file(DOS_FILE *file) static void rename_file(DOS_FILE *file)
{ {
unsigned char name[46]; //unsigned char name[46];
unsigned char *walk,*here; //unsigned char *walk,*here;
if (!file->offset) { if (!file->offset) {
printf( "Cannot rename FAT32 root dir\n" ); VfatPrint( "Cannot rename FAT32 root dir\n" );
return; /* cannot rename FAT32 root dir */ return; /* cannot rename FAT32 root dir */
} }
while (1) { while (1) {
printf("New name: "); VfatPrint("New name: ");
#if 0
fflush(stdout); fflush(stdout);
if (fgets((char*)name,45,stdin)) { if (fgets((char*)name,45,stdin)) {
if ((here = (unsigned char*)strchr((char*)name,'\n'))) *here = 0; if ((here = (unsigned char*)strchr((char*)name,'\n'))) *here = 0;
@ -343,6 +351,9 @@ static void rename_file(DOS_FILE *file)
return; return;
} }
} }
#else
return;
#endif
} }
} }
@ -353,18 +364,18 @@ static int handle_dot(DOS_FS *fs,DOS_FILE *file,int dots)
name = strncmp((char*)file->dir_ent.name,MSDOS_DOT,MSDOS_NAME) ? ".." : "."; name = strncmp((char*)file->dir_ent.name,MSDOS_DOT,MSDOS_NAME) ? ".." : ".";
if (!(file->dir_ent.attr & ATTR_DIR)) { if (!(file->dir_ent.attr & ATTR_DIR)) {
printf("%s\n Is a non-directory.\n",path_name(file)); VfatPrint("%s\n Is a non-directory.\n",path_name(file));
if (interactive) if (interactive)
printf("1) Drop it\n2) Auto-rename\n3) Rename\n" VfatPrint("1) Drop it\n2) Auto-rename\n3) Rename\n"
"4) Convert to directory\n"); "4) Convert to directory\n");
else printf(" Auto-renaming it.\n"); else VfatPrint(" Auto-renaming it.\n");
switch (interactive ? get_key("1234","?") : '2') { switch (interactive ? get_key("1234","?") : '2') {
case '1': case '1':
drop_file(fs,file); drop_file(fs,file);
return 1; return 1;
case '2': case '2':
auto_rename(file); auto_rename(file);
printf(" Renamed to %s\n",file_name(file->dir_ent.name)); VfatPrint(" Renamed to %s\n",file_name(file->dir_ent.name));
return 0; return 0;
case '3': case '3':
rename_file(file); rename_file(file);
@ -376,7 +387,7 @@ static int handle_dot(DOS_FS *fs,DOS_FILE *file,int dots)
} }
} }
if (!dots) { if (!dots) {
printf("Root contains directory \"%s\". Dropping it.\n",name); VfatPrint("Root contains directory \"%s\". Dropping it.\n",name);
drop_file(fs,file); drop_file(fs,file);
return 1; return 1;
} }
@ -392,14 +403,14 @@ static int check_file(DOS_FS *fs,DOS_FILE *file)
if (file->dir_ent.attr & ATTR_DIR) { if (file->dir_ent.attr & ATTR_DIR) {
if (CF_LE_L(file->dir_ent.size)) { if (CF_LE_L(file->dir_ent.size)) {
printf("%s\n Directory has non-zero size. Fixing it.\n", VfatPrint("%s\n Directory has non-zero size. Fixing it.\n",
path_name(file)); path_name(file));
MODIFY(file,size,CT_LE_L(0)); MODIFY(file,size,CT_LE_L(0));
} }
if (file->parent && !strncmp((char*)file->dir_ent.name,MSDOS_DOT,MSDOS_NAME)) { if (file->parent && !strncmp((char*)file->dir_ent.name,MSDOS_DOT,MSDOS_NAME)) {
expect = FSTART(file->parent,fs); expect = FSTART(file->parent,fs);
if (FSTART(file,fs) != expect) { if (FSTART(file,fs) != expect) {
printf("%s\n Start (%ld) does not point to parent (%ld)\n", VfatPrint("%s\n Start (%ld) does not point to parent (%ld)\n",
path_name(file),FSTART(file,fs),expect); path_name(file),FSTART(file,fs),expect);
MODIFY_START(file,expect,fs); MODIFY_START(file,expect,fs);
} }
@ -411,21 +422,21 @@ static int check_file(DOS_FS *fs,DOS_FILE *file)
if (fs->root_cluster && expect == fs->root_cluster) if (fs->root_cluster && expect == fs->root_cluster)
expect = 0; expect = 0;
if (FSTART(file,fs) != expect) { if (FSTART(file,fs) != expect) {
printf("%s\n Start (%lu) does not point to .. (%lu)\n", VfatPrint("%s\n Start (%lu) does not point to .. (%lu)\n",
path_name(file),FSTART(file,fs),expect); path_name(file),FSTART(file,fs),expect);
MODIFY_START(file,expect,fs); MODIFY_START(file,expect,fs);
} }
return 0; return 0;
} }
if (FSTART(file,fs)==0){ if (FSTART(file,fs)==0){
printf ("%s\n Start does point to root directory. Deleting dir. \n", VfatPrint ("%s\n Start does point to root directory. Deleting dir. \n",
path_name(file)); path_name(file));
MODIFY(file,name[0],DELETED_FLAG); MODIFY(file,name[0],DELETED_FLAG);
return 0; return 0;
} }
} }
if (FSTART(file,fs) >= fs->clusters+2) { if (FSTART(file,fs) >= fs->clusters+2) {
printf("%s\n Start cluster beyond limit (%lu > %lu). Truncating file.\n", VfatPrint("%s\n Start cluster beyond limit (%lu > %lu). Truncating file.\n",
path_name(file),FSTART(file,fs),fs->clusters+1); path_name(file),FSTART(file,fs),fs->clusters+1);
if (!file->offset) if (!file->offset)
die( "Bad FAT32 root directory! (bad start cluster)\n" ); die( "Bad FAT32 root directory! (bad start cluster)\n" );
@ -435,7 +446,7 @@ static int check_file(DOS_FS *fs,DOS_FILE *file)
for (curr = FSTART(file,fs) ? FSTART(file,fs) : for (curr = FSTART(file,fs) ? FSTART(file,fs) :
-1; curr != -1; curr = next_cluster(fs,curr)) { -1; curr != -1; curr = next_cluster(fs,curr)) {
if (!fs->fat[curr].value || bad_cluster(fs,curr)) { if (!fs->fat[curr].value || bad_cluster(fs,curr)) {
printf("%s\n Contains a %s cluster (%lu). Assuming EOF.\n", VfatPrint("%s\n Contains a %s cluster (%lu). Assuming EOF.\n",
path_name(file),fs->fat[curr].value ? "bad" : "free",curr); path_name(file),fs->fat[curr].value ? "bad" : "free",curr);
if (prev) set_fat(fs,prev,-1); if (prev) set_fat(fs,prev,-1);
else if (!file->offset) else if (!file->offset)
@ -445,7 +456,7 @@ static int check_file(DOS_FS *fs,DOS_FILE *file)
} }
if (!(file->dir_ent.attr & ATTR_DIR) && CF_LE_L(file->dir_ent.size) <= if (!(file->dir_ent.attr & ATTR_DIR) && CF_LE_L(file->dir_ent.size) <=
clusters*fs->cluster_size) { clusters*fs->cluster_size) {
printf("%s\n File size is %u bytes, cluster chain length is > %lu " VfatPrint("%s\n File size is %u bytes, cluster chain length is > %lu "
"bytes.\n Truncating file to %u bytes.\n",path_name(file), "bytes.\n Truncating file to %u bytes.\n",path_name(file),
CF_LE_L(file->dir_ent.size),clusters*fs->cluster_size, CF_LE_L(file->dir_ent.size),clusters*fs->cluster_size,
CF_LE_L(file->dir_ent.size)); CF_LE_L(file->dir_ent.size));
@ -454,8 +465,8 @@ static int check_file(DOS_FS *fs,DOS_FILE *file)
} }
if ((owner = get_owner(fs,curr))) { if ((owner = get_owner(fs,curr))) {
int do_trunc = 0; int do_trunc = 0;
printf("%s and\n",path_name(owner)); VfatPrint("%s and\n",path_name(owner));
printf("%s\n share clusters.\n",path_name(file)); VfatPrint("%s\n share clusters.\n",path_name(file));
clusters2 = 0; clusters2 = 0;
for (walk = FSTART(owner,fs); walk > 0 && walk != -1; walk = for (walk = FSTART(owner,fs); walk > 0 && walk != -1; walk =
next_cluster(fs,walk)) next_cluster(fs,walk))
@ -463,20 +474,20 @@ static int check_file(DOS_FS *fs,DOS_FILE *file)
else clusters2++; else clusters2++;
restart = file->dir_ent.attr & ATTR_DIR; restart = file->dir_ent.attr & ATTR_DIR;
if (!owner->offset) { if (!owner->offset) {
printf( " Truncating second to %lu bytes because first " VfatPrint( " Truncating second to %lu bytes because first "
"is FAT32 root dir.\n", clusters2*fs->cluster_size ); "is FAT32 root dir.\n", clusters2*fs->cluster_size );
do_trunc = 2; do_trunc = 2;
} }
else if (!file->offset) { else if (!file->offset) {
printf( " Truncating first to %lu bytes because second " VfatPrint( " Truncating first to %lu bytes because second "
"is FAT32 root dir.\n", clusters*fs->cluster_size ); "is FAT32 root dir.\n", clusters*fs->cluster_size );
do_trunc = 1; do_trunc = 1;
} }
else if (interactive) else if (interactive)
printf("1) Truncate first to %lu bytes%s\n" VfatPrint("1) Truncate first to %lu bytes%s\n"
"2) Truncate second to %lu bytes\n",clusters*fs->cluster_size, "2) Truncate second to %lu bytes\n",clusters*fs->cluster_size,
restart ? " and restart" : "",clusters2*fs->cluster_size); restart ? " and restart" : "",clusters2*fs->cluster_size);
else printf(" Truncating second to %lu bytes.\n",clusters2* else VfatPrint(" Truncating second to %lu bytes.\n",clusters2*
fs->cluster_size); fs->cluster_size);
if (do_trunc != 2 && if (do_trunc != 2 &&
(do_trunc == 1 || (do_trunc == 1 ||
@ -515,7 +526,7 @@ static int check_file(DOS_FS *fs,DOS_FILE *file)
} }
if (!(file->dir_ent.attr & ATTR_DIR) && CF_LE_L(file->dir_ent.size) > if (!(file->dir_ent.attr & ATTR_DIR) && CF_LE_L(file->dir_ent.size) >
clusters*fs->cluster_size) { clusters*fs->cluster_size) {
printf("%s\n File size is %u bytes, cluster chain length is %lu bytes." VfatPrint("%s\n File size is %u bytes, cluster chain length is %lu bytes."
"\n Truncating file to %lu bytes.\n",path_name(file),CF_LE_L(file-> "\n Truncating file to %lu bytes.\n",path_name(file),CF_LE_L(file->
dir_ent.size),clusters*fs->cluster_size,clusters*fs->cluster_size); dir_ent.size),clusters*fs->cluster_size,clusters*fs->cluster_size);
MODIFY(file,size,CT_LE_L(clusters*fs->cluster_size)); MODIFY(file,size,CT_LE_L(clusters*fs->cluster_size));
@ -547,10 +558,10 @@ static int check_dir(DOS_FS *fs,DOS_FILE **root,int dots)
if (bad_name((*walk)->dir_ent.name)) bad++; if (bad_name((*walk)->dir_ent.name)) bad++;
else good++; else good++;
if (*root && parent && good+bad > 4 && bad > good/2) { if (*root && parent && good+bad > 4 && bad > good/2) {
printf("%s\n Has a large number of bad entries. (%d/%d)\n", VfatPrint("%s\n Has a large number of bad entries. (%d/%d)\n",
path_name(parent),bad,good+bad); path_name(parent),bad,good+bad);
if (!dots) printf( " Not dropping root directory.\n" ); if (!dots) VfatPrint( " Not dropping root directory.\n" );
else if (!interactive) printf(" Not dropping it in auto-mode.\n"); else if (!interactive) VfatPrint(" Not dropping it in auto-mode.\n");
else if (get_key("yn","Drop directory ? (y/n)") == 'y') { else if (get_key("yn","Drop directory ? (y/n)") == 'y') {
truncate_file(fs,parent,0); truncate_file(fs,parent,0);
MODIFY(parent,name[0],DELETED_FLAG); MODIFY(parent,name[0],DELETED_FLAG);
@ -572,11 +583,11 @@ static int check_dir(DOS_FS *fs,DOS_FILE **root,int dots)
} }
if (!((*walk)->dir_ent.attr & ATTR_VOLUME) && if (!((*walk)->dir_ent.attr & ATTR_VOLUME) &&
bad_name((*walk)->dir_ent.name)) { bad_name((*walk)->dir_ent.name)) {
printf("%s\n Bad file name.\n",path_name(*walk)); VfatPrint("%s\n Bad file name.\n",path_name(*walk));
if (interactive) if (interactive)
printf("1) Drop file\n2) Rename file\n3) Auto-rename\n" VfatPrint("1) Drop file\n2) Rename file\n3) Auto-rename\n"
"4) Keep it\n"); "4) Keep it\n");
else printf(" Auto-renaming it.\n"); else VfatPrint(" Auto-renaming it.\n");
switch (interactive ? get_key("1234","?") : '3') { switch (interactive ? get_key("1234","?") : '3') {
case '1': case '1':
drop_file(fs,*walk); drop_file(fs,*walk);
@ -588,7 +599,7 @@ static int check_dir(DOS_FS *fs,DOS_FILE **root,int dots)
break; break;
case '3': case '3':
auto_rename(*walk); auto_rename(*walk);
printf(" Renamed to %s\n",file_name((*walk)->dir_ent. VfatPrint(" Renamed to %s\n",file_name((*walk)->dir_ent.
name)); name));
break; break;
case '4': case '4':
@ -602,14 +613,14 @@ static int check_dir(DOS_FS *fs,DOS_FILE **root,int dots)
while (*scan && !skip) { while (*scan && !skip) {
if (!((*scan)->dir_ent.attr & ATTR_VOLUME) && if (!((*scan)->dir_ent.attr & ATTR_VOLUME) &&
!strncmp((char*)(*walk)->dir_ent.name,(char*)(*scan)->dir_ent.name,MSDOS_NAME)) { !strncmp((char*)(*walk)->dir_ent.name,(char*)(*scan)->dir_ent.name,MSDOS_NAME)) {
printf("%s\n Duplicate directory entry.\n First %s\n", VfatPrint("%s\n Duplicate directory entry.\n First %s\n",
path_name(*walk),file_stat(*walk)); path_name(*walk),file_stat(*walk));
printf(" Second %s\n",file_stat(*scan)); VfatPrint(" Second %s\n",file_stat(*scan));
if (interactive) if (interactive)
printf("1) Drop first\n2) Drop second\n3) Rename first\n" VfatPrint("1) Drop first\n2) Drop second\n3) Rename first\n"
"4) Rename second\n5) Auto-rename first\n" "4) Rename second\n5) Auto-rename first\n"
"6) Auto-rename second\n"); "6) Auto-rename second\n");
else printf(" Auto-renaming second.\n"); else VfatPrint(" Auto-renaming second.\n");
switch (interactive ? get_key("123456","?") : '6') { switch (interactive ? get_key("123456","?") : '6') {
case '1': case '1':
drop_file(fs,*walk); drop_file(fs,*walk);
@ -622,22 +633,22 @@ static int check_dir(DOS_FS *fs,DOS_FILE **root,int dots)
continue; continue;
case '3': case '3':
rename_file(*walk); rename_file(*walk);
printf(" Renamed to %s\n",path_name(*walk)); VfatPrint(" Renamed to %s\n",path_name(*walk));
redo = 1; redo = 1;
break; break;
case '4': case '4':
rename_file(*scan); rename_file(*scan);
printf(" Renamed to %s\n",path_name(*walk)); VfatPrint(" Renamed to %s\n",path_name(*walk));
redo = 1; redo = 1;
break; break;
case '5': case '5':
auto_rename(*walk); auto_rename(*walk);
printf(" Renamed to %s\n",file_name((*walk)->dir_ent. VfatPrint(" Renamed to %s\n",file_name((*walk)->dir_ent.
name)); name));
break; break;
case '6': case '6':
auto_rename(*scan); auto_rename(*scan);
printf(" Renamed to %s\n",file_name((*scan)->dir_ent. VfatPrint(" Renamed to %s\n",file_name((*scan)->dir_ent.
name)); name));
break; break;
} }
@ -653,10 +664,10 @@ static int check_dir(DOS_FS *fs,DOS_FILE **root,int dots)
} }
} }
if (dots && !dot) if (dots && !dot)
printf("%s\n \".\" is missing. Can't fix this yet.\n", VfatPrint("%s\n \".\" is missing. Can't fix this yet.\n",
path_name(parent)); path_name(parent));
if (dots && !dotdot) if (dots && !dotdot)
printf("%s\n \"..\" is missing. Can't fix this yet.\n", VfatPrint("%s\n \"..\" is missing. Can't fix this yet.\n",
path_name(parent)); path_name(parent));
return 0; return 0;
} }
@ -673,7 +684,7 @@ static void test_file(DOS_FS *fs,DOS_FILE *file,int read_test)
next_clu = next_cluster(fs,walk); next_clu = next_cluster(fs,walk);
if ((owner = get_owner(fs,walk))) { if ((owner = get_owner(fs,walk))) {
if (owner == file) { if (owner == file) {
printf("%s\n Circular cluster chain. Truncating to %lu " VfatPrint("%s\n Circular cluster chain. Truncating to %lu "
"cluster%s.\n",path_name(file),clusters,clusters == 1 ? "" : "cluster%s.\n",path_name(file),clusters,clusters == 1 ? "" :
"s"); "s");
if (prev) set_fat(fs,prev,-1); if (prev) set_fat(fs,prev,-1);
@ -690,7 +701,7 @@ static void test_file(DOS_FS *fs,DOS_FILE *file,int read_test)
clusters++; clusters++;
} }
else { else {
printf("%s\n Cluster %lu (%lu) is unreadable. Skipping it.\n", VfatPrint("%s\n Cluster %lu (%lu) is unreadable. Skipping it.\n",
path_name(file),clusters,walk); path_name(file),clusters,walk);
if (prev) set_fat(fs,prev,next_cluster(fs,walk)); if (prev) set_fat(fs,prev,next_cluster(fs,walk));
else MODIFY_START(file,next_cluster(fs,walk),fs); else MODIFY_START(file,next_cluster(fs,walk),fs);
@ -723,7 +734,7 @@ static void undelete(DOS_FS *fs,DOS_FILE *file)
if (prev) set_fat(fs,prev,-1); if (prev) set_fat(fs,prev,-1);
else MODIFY_START(file,0,fs); else MODIFY_START(file,0,fs);
if (left) if (left)
printf("Warning: Did only undelete %lu of %lu cluster%s.\n",clusters-left, VfatPrint("Warning: Did only undelete %lu of %lu cluster%s.\n",clusters-left,
clusters,clusters == 1 ? "" : "s"); clusters,clusters == 1 ? "" : "s");
} }
@ -779,10 +790,10 @@ static void add_file(DOS_FS *fs,DOS_FILE ***chain,DOS_FILE *parent,
**chain = new; **chain = new;
*chain = &new->next; *chain = &new->next;
if (list) { if (list) {
printf("Checking file %s",path_name(new)); VfatPrint("Checking file %s",path_name(new));
if (new->lfn) if (new->lfn)
printf(" (%s)", file_name(new->dir_ent.name) ); VfatPrint(" (%s)", file_name(new->dir_ent.name) );
printf("\n"); VfatPrint("\n");
} }
if (offset && if (offset &&
strncmp((char*)de.name,MSDOS_DOT,MSDOS_NAME) != 0 && strncmp((char*)de.name,MSDOS_DOT,MSDOS_NAME) != 0 &&

View file

@ -9,7 +9,7 @@
loff_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern); loff_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern);
/* Allocate a free slot in the root directory for a new file. The file name is /* Allocate a free slot in the root directory for a new file. The file name is
constructed after 'pattern', which must include a %d type format for printf constructed after 'pattern', which must include a %d type format for VfatPrint
and expand to exactly 11 characters. The name actually used is written into and expand to exactly 11 characters. The name actually used is written into
the 'de' structure, the rest of *de is cleared. The offset returned is to the 'de' structure, the rest of *de is cleared. The offset returned is to
where in the filesystem the entry belongs. */ where in the filesystem the entry belongs. */

View file

@ -23,34 +23,48 @@ void die(char *msg,...)
va_list args; va_list args;
va_start(args,msg); va_start(args,msg);
vfprintf(stderr,msg,args); //vfprintf(stderr,msg,args);
DPRINT1("Unrecoverable problem!\n");
va_end(args); va_end(args);
fprintf(stderr,"\n"); //fprintf(stderr,"\n");
exit(1); //exit(1);
} }
void pdie(char *msg,...) void pdie(char *msg,...)
{ {
va_list args; va_list args;
va_start(args,msg); va_start(args,msg);
vfprintf(stderr,msg,args); //vfprintf(stderr,msg,args);
DPRINT1("Unrecoverable problem!\n");
va_end(args); va_end(args);
fprintf(stderr,":%s\n",strerror(errno)); //fprintf(stderr,":%s\n",strerror(errno));
exit(1); //exit(1);
DbgBreakPoint();
} }
void *alloc(int size) void *alloc(int size)
{ {
void *this; void *ptr;
if ((this = malloc(size))) return this; ptr = RtlAllocateHeap(RtlGetProcessHeap (),
pdie("malloc"); 0,
return NULL; /* for GCC */ size);
if (ptr == NULL)
{
DPRINT1("Allocation failed!\n");
return NULL;
}
return ptr;
} }
void free(void *ptr)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, ptr);
}
void *qalloc(void **root,int size) void *qalloc(void **root,int size)
{ {
@ -87,10 +101,11 @@ int min(int a,int b)
char get_key(char *valid,char *prompt) char get_key(char *valid,char *prompt)
{ {
#if 0
int ch,okay; int ch,okay;
while (1) { while (1) {
if (prompt) printf("%s ",prompt); if (prompt) VfatPrint("%s ",prompt);
fflush(stdout); fflush(stdout);
while (ch = getchar(), ch == ' ' || ch == '\t'); while (ch = getchar(), ch == ' ' || ch == '\t');
if (ch == EOF) exit(1); if (ch == EOF) exit(1);
@ -98,8 +113,11 @@ char get_key(char *valid,char *prompt)
while (ch = getchar(), ch != '\n' && ch != EOF); while (ch = getchar(), ch != '\n' && ch != EOF);
if (ch == EOF) exit(1); if (ch == EOF) exit(1);
if (okay) return okay; if (okay) return okay;
printf("Invalid input.\n"); VfatPrint("Invalid input.\n");
} }
#else
return 0;
#endif
} }
/* Local Variables: */ /* Local Variables: */

View file

@ -8,17 +8,17 @@
#define _COMMON_H #define _COMMON_H
//void die(char *msg,...) __attribute((noreturn)); //void die(char *msg,...) __attribute((noreturn));
__declspec(noreturn) void die(char *msg,...); void die(char *msg,...);
/* Displays a prinf-style message and terminates the program. */ /* Displays a prinf-style message and terminates the program. */
//void pdie(char *msg,...) __attribute((noreturn)); //void pdie(char *msg,...) __attribute((noreturn));
__declspec(noreturn) void pdie(char *msg,...); void pdie(char *msg,...);
/* Like die, but appends an error message according to the state of errno. */ /* Like die, but appends an error message according to the state of errno. */
void *alloc(int size); void *alloc(int size);
void free(void *ptr);
/* mallocs SIZE bytes and returns a pointer to the data. Terminates the program /* mallocs SIZE bytes and returns a pointer to the data. Terminates the program
if malloc fails. */ if malloc fails. */

View file

@ -35,7 +35,10 @@ typedef __int64 ll_t;
//#include <linux/version.h> //#include <linux/version.h>
//# include "types.h" //# include "types.h"
# include "byteorder.h"
#ifdef _M_IX86
#include "byteorder.h"
#endif
#include "msdos_fs.h" #include "msdos_fs.h"

View file

@ -71,30 +71,30 @@ void read_fat(DOS_FS *fs)
first_ok = (first_media.value & FAT_EXTD(fs)) == FAT_EXTD(fs); first_ok = (first_media.value & FAT_EXTD(fs)) == FAT_EXTD(fs);
second_ok = (second_media.value & FAT_EXTD(fs)) == FAT_EXTD(fs); second_ok = (second_media.value & FAT_EXTD(fs)) == FAT_EXTD(fs);
if (first_ok && !second_ok) { if (first_ok && !second_ok) {
printf("FATs differ - using first FAT.\n"); VfatPrint("FATs differ - using first FAT.\n");
fs_write(fs->fat_start+fs->fat_size,eff_size,use = first); fs_write(fs->fat_start+fs->fat_size,eff_size,use = first);
} }
if (!first_ok && second_ok) { if (!first_ok && second_ok) {
printf("FATs differ - using second FAT.\n"); VfatPrint("FATs differ - using second FAT.\n");
fs_write(fs->fat_start,eff_size,use = second); fs_write(fs->fat_start,eff_size,use = second);
} }
if (first_ok && second_ok) { if (first_ok && second_ok) {
if (interactive) { if (interactive) {
printf("FATs differ but appear to be intact. Use which FAT ?\n" VfatPrint("FATs differ but appear to be intact. Use which FAT ?\n"
"1) Use first FAT\n2) Use second FAT\n"); "1) Use first FAT\n2) Use second FAT\n");
if (get_key("12","?") == '1') if (get_key("12","?") == '1')
fs_write(fs->fat_start+fs->fat_size,eff_size,use = first); fs_write(fs->fat_start+fs->fat_size,eff_size,use = first);
else fs_write(fs->fat_start,eff_size,use = second); else fs_write(fs->fat_start,eff_size,use = second);
} }
else { else {
printf("FATs differ but appear to be intact. Using first " VfatPrint("FATs differ but appear to be intact. Using first "
"FAT.\n"); "FAT.\n");
fs_write(fs->fat_start+fs->fat_size,eff_size,use = first); fs_write(fs->fat_start+fs->fat_size,eff_size,use = first);
} }
} }
if (!first_ok && !second_ok) { if (!first_ok && !second_ok) {
printf("Both FATs appear to be corrupt. Giving up.\n"); VfatPrint("Both FATs appear to be corrupt. Giving up.\n");
exit(1); //exit(1);
} }
} }
fs->fat = qalloc(&mem_queue,sizeof(FAT_ENTRY)*(fs->clusters+2)); fs->fat = qalloc(&mem_queue,sizeof(FAT_ENTRY)*(fs->clusters+2));
@ -102,7 +102,7 @@ void read_fat(DOS_FS *fs)
for (i = 2; i < fs->clusters+2; i++) for (i = 2; i < fs->clusters+2; i++)
if (fs->fat[i].value >= fs->clusters+2 && if (fs->fat[i].value >= fs->clusters+2 &&
(fs->fat[i].value < FAT_MIN_BAD(fs))) { (fs->fat[i].value < FAT_MIN_BAD(fs))) {
printf("Cluster %ld out of range (%ld > %ld). Setting to EOF.\n", VfatPrint("Cluster %ld out of range (%ld > %ld). Setting to EOF.\n",
i-2,fs->fat[i].value,fs->clusters+2-1); i-2,fs->fat[i].value,fs->clusters+2-1);
set_fat(fs,i,-1); set_fat(fs,i,-1);
} }
@ -115,8 +115,8 @@ void read_fat(DOS_FS *fs)
void set_fat(DOS_FS *fs,unsigned long cluster,unsigned long new) void set_fat(DOS_FS *fs,unsigned long cluster,unsigned long new)
{ {
unsigned char data[4]; unsigned char data[4];
int size; int size = 0;
loff_t offs; loff_t offs = 0LL;
if ((long)new == -1) if ((long)new == -1)
new = FAT_EOF(fs); new = FAT_EOF(fs);
@ -200,11 +200,11 @@ void fix_bad(DOS_FS *fs)
unsigned long i; unsigned long i;
if (verbose) if (verbose)
printf("Checking for bad clusters.\n"); VfatPrint("Checking for bad clusters.\n");
for (i = 2; i < fs->clusters+2; i++) for (i = 2; i < fs->clusters+2; i++)
if (!get_owner(fs,i) && !FAT_IS_BAD(fs,fs->fat[i].value)) if (!get_owner(fs,i) && !FAT_IS_BAD(fs,fs->fat[i].value))
if (!fs_test(cluster_start(fs,i),fs->cluster_size)) { if (!fs_test(cluster_start(fs,i),fs->cluster_size)) {
printf("Cluster %lu is unreadable.\n",i); VfatPrint("Cluster %lu is unreadable.\n",i);
set_fat(fs,i,-2); set_fat(fs,i,-2);
} }
} }
@ -216,7 +216,7 @@ void reclaim_free(DOS_FS *fs)
unsigned long i; unsigned long i;
if (verbose) if (verbose)
printf("Checking for unused clusters.\n"); VfatPrint("Checking for unused clusters.\n");
reclaimed = 0; reclaimed = 0;
for (i = 2; i < fs->clusters+2; i++) for (i = 2; i < fs->clusters+2; i++)
if (!get_owner(fs,i) && fs->fat[i].value && if (!get_owner(fs,i) && fs->fat[i].value &&
@ -225,7 +225,7 @@ void reclaim_free(DOS_FS *fs)
reclaimed++; reclaimed++;
} }
if (reclaimed) if (reclaimed)
printf("Reclaimed %d unused cluster%s (%d bytes).\n",reclaimed, VfatPrint("Reclaimed %d unused cluster%s (%d bytes).\n",reclaimed,
reclaimed == 1 ? "" : "s",reclaimed*fs->cluster_size); reclaimed == 1 ? "" : "s",reclaimed*fs->cluster_size);
} }
@ -262,7 +262,7 @@ void reclaim_file(DOS_FS *fs)
unsigned long i,next,walk; unsigned long i,next,walk;
if (verbose) if (verbose)
printf("Reclaiming unconnected clusters.\n"); VfatPrint("Reclaiming unconnected clusters.\n");
for (i = 2; i < fs->clusters+2; i++) fs->fat[i].prev = 0; for (i = 2; i < fs->clusters+2; i++) fs->fat[i].prev = 0;
for (i = 2; i < fs->clusters+2; i++) { for (i = 2; i < fs->clusters+2; i++) {
next = fs->fat[i].value; next = fs->fat[i].value;
@ -282,7 +282,7 @@ void reclaim_file(DOS_FS *fs)
die("Internal error: prev going below zero"); die("Internal error: prev going below zero");
set_fat(fs,i,-1); set_fat(fs,i,-1);
changed = 1; changed = 1;
printf("Broke cycle at cluster %lu in free chain.\n",i); VfatPrint("Broke cycle at cluster %lu in free chain.\n",i);
break; break;
} }
} }
@ -305,7 +305,7 @@ void reclaim_file(DOS_FS *fs)
fs_write(offset,sizeof(DIR_ENT),&de); fs_write(offset,sizeof(DIR_ENT),&de);
} }
if (reclaimed) if (reclaimed)
printf("Reclaimed %d unused cluster%s (%d bytes) in %d chain%s.\n", VfatPrint("Reclaimed %d unused cluster%s (%d bytes) in %d chain%s.\n",
reclaimed,reclaimed == 1 ? "" : "s",reclaimed*fs->cluster_size,files, reclaimed,reclaimed == 1 ? "" : "s",reclaimed*fs->cluster_size,files,
files == 1 ? "" : "s"); files == 1 ? "" : "s");
} }
@ -325,23 +325,23 @@ unsigned long update_free(DOS_FS *fs)
return free; return free;
if (verbose) if (verbose)
printf("Checking free cluster summary.\n"); VfatPrint("Checking free cluster summary.\n");
if (fs->free_clusters >= 0) { if (fs->free_clusters >= 0) {
if (free != fs->free_clusters) { if (free != fs->free_clusters) {
printf( "Free cluster summary wrong (%ld vs. really %ld)\n", VfatPrint( "Free cluster summary wrong (%ld vs. really %ld)\n",
fs->free_clusters,free); fs->free_clusters,free);
if (interactive) if (interactive)
printf( "1) Correct\n2) Don't correct\n" ); VfatPrint( "1) Correct\n2) Don't correct\n" );
else printf( " Auto-correcting.\n" ); else VfatPrint( " Auto-correcting.\n" );
if (!interactive || get_key("12","?") == '1') if (!interactive || get_key("12","?") == '1')
do_set = 1; do_set = 1;
} }
} }
else { else {
printf( "Free cluster summary uninitialized (should be %ld)\n", free ); VfatPrint( "Free cluster summary uninitialized (should be %ld)\n", free );
if (interactive) if (interactive)
printf( "1) Set it\n2) Leave it uninitialized\n" ); VfatPrint( "1) Set it\n2) Leave it uninitialized\n" );
else printf( " Auto-setting.\n" ); else VfatPrint( " Auto-setting.\n" );
if (!interactive || get_key("12","?") == '1') if (!interactive || get_key("12","?") == '1')
do_set = 1; do_set = 1;
} }

View file

@ -5,6 +5,9 @@
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998 /* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */ * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
/* Need to define this so that islower isn't inlined
(ntdll doesn't export isctype) */
#define __NO_CTYPE_INLINES
#include "vfatlib.h" #include "vfatlib.h"
@ -50,7 +53,6 @@ char *file_name(unsigned char *fixed)
return path; return path;
} }
int file_cvt(unsigned char *name,unsigned char *fixed) int file_cvt(unsigned char *name,unsigned char *fixed)
{ {
unsigned char c; unsigned char c;
@ -61,13 +63,13 @@ int file_cvt(unsigned char *name,unsigned char *fixed)
while (*name) { while (*name) {
c = *name; c = *name;
if (c < ' ' || c > 0x7e || strchr("*?<>|\"/",c)) { if (c < ' ' || c > 0x7e || strchr("*?<>|\"/",c)) {
printf("Invalid character in name. Use \\ooo for special " VfatPrint("Invalid character in name. Use \\ooo for special "
"characters.\n"); "characters.\n");
return 0; return 0;
} }
if (c == '.') { if (c == '.') {
if (ext) { if (ext) {
printf("Duplicate dots in name.\n"); VfatPrint("Duplicate dots in name.\n");
return 0; return 0;
} }
while (size--) *fixed++ = ' '; while (size--) *fixed++ = ' ';
@ -80,13 +82,13 @@ int file_cvt(unsigned char *name,unsigned char *fixed)
c = 0; c = 0;
for (cnt = 3; cnt; cnt--) { for (cnt = 3; cnt; cnt--) {
if (*name < '0' || *name > '7') { if (*name < '0' || *name > '7') {
printf("Invalid octal character.\n"); VfatPrint("Invalid octal character.\n");
return 0; return 0;
} }
c = c*8+*name++-'0'; c = c*8+*name++-'0';
} }
if (cnt < 4) { if (cnt < 4) {
printf("Expected three octal digits.\n"); VfatPrint("Expected three octal digits.\n");
return 0; return 0;
} }
name += 3; name += 3;
@ -119,7 +121,7 @@ void file_add(char *path,FD_TYPE type)
path++; path++;
while (1) { while (1) {
if ((here = strchr(path,'/'))) *here = 0; if ((here = strchr(path,'/'))) *here = 0;
if (!file_cvt((unsigned char*)path,(unsigned char *)name)) exit(2); if (!file_cvt((unsigned char*)path,(unsigned char *)name)) {return; /*exit(2);*/}
for (walk = *current; walk; walk = walk->next) for (walk = *current; walk; walk = walk->next)
if (!here && (!strncmp(name,walk->name,MSDOS_NAME) || (type == if (!here && (!strncmp(name,walk->name,MSDOS_NAME) || (type ==
fdt_undelete && !strncmp(name+1,walk->name+1,MSDOS_NAME-1)))) fdt_undelete && !strncmp(name+1,walk->name+1,MSDOS_NAME-1))))
@ -190,12 +192,12 @@ void file_modify(FDSC **curr,unsigned char *fixed)
die("Internal error: file_find failed"); die("Internal error: file_find failed");
switch ((*this)->type) { switch ((*this)->type) {
case fdt_drop: case fdt_drop:
printf("Dropping %s\n",file_name(fixed)); VfatPrint("Dropping %s\n",file_name(fixed));
*fixed = DELETED_FLAG; *fixed = DELETED_FLAG;
break; break;
case fdt_undelete: case fdt_undelete:
*fixed = *(*this)->name; *fixed = *(*this)->name;
printf("Undeleting %s\n",file_name(fixed)); VfatPrint("Undeleting %s\n",file_name(fixed));
break; break;
default: default:
die("Internal error: file_modify"); die("Internal error: file_modify");
@ -214,7 +216,7 @@ static void report_unused(FDSC *this)
next = this->next; next = this->next;
if (this->first) report_unused(this->first); if (this->first) report_unused(this->first);
else if (this->type != fdt_none) else if (this->type != fdt_none)
printf("Warning: did not %s file %s\n",this->type == fdt_drop ? VfatPrint("Warning: did not %s file %s\n",this->type == fdt_drop ?
"drop" : "undelete",file_name((unsigned char*)this->name)); "drop" : "undelete",file_name((unsigned char*)this->name));
free(this); free(this);
this = next; this = next;

View file

@ -66,7 +66,7 @@ void fs_open(PUNICODE_STRING DriveRoot,int rw)
FILE_SYNCHRONOUS_IO_ALERT); FILE_SYNCHRONOUS_IO_ALERT);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("NtOpenFile() failed with status 0x%.08x\n", Status); DPRINT1("NtOpenFile() failed with status 0x%.08x\n", Status);
return; return;
} }
@ -86,7 +86,7 @@ void fs_read(loff_t pos,int size,void *data)
const loff_t seekpos_aligned = pos - (pos % 512); // TMN: const loff_t seekpos_aligned = pos - (pos % 512); // TMN:
const size_t seek_delta = (size_t)(pos - seekpos_aligned); // TMN: const size_t seek_delta = (size_t)(pos - seekpos_aligned); // TMN:
const size_t readsize = (size_t)(pos - seekpos_aligned) + readsize_aligned; // TMN: const size_t readsize = (size_t)(pos - seekpos_aligned) + readsize_aligned; // TMN:
char* tmpBuf = malloc(readsize_aligned); // TMN: char* tmpBuf = alloc(readsize_aligned); // TMN:
if (llseek(fd,seekpos_aligned,0) != seekpos_aligned) pdie("Seek to %I64d",pos); if (llseek(fd,seekpos_aligned,0) != seekpos_aligned) pdie("Seek to %I64d",pos);
if ((got = read(fd,tmpBuf,readsize_aligned)) < 0) pdie("Read %d bytes at %I64d",size,pos); if ((got = read(fd,tmpBuf,readsize_aligned)) < 0) pdie("Read %d bytes at %I64d",size,pos);
assert(got >= size); assert(got >= size);
@ -274,7 +274,7 @@ static int WIN32read(HANDLE FileHandle, void *buf, unsigned int len)
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("NtReadFile() failed (Status %lx)\n", Status); DPRINT1("NtReadFile() failed (Status %lx)\n", Status);
return -1; return -1;
} }
@ -298,7 +298,7 @@ static int WIN32write(HANDLE FileHandle, void *buf, unsigned int len)
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("NtWriteFile() failed (Status %lx)\n", Status); DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
return -1; return -1;
} }

View file

@ -162,23 +162,23 @@ void lfn_add_slot( DIR_ENT *de, loff_t dir_offset )
* checksum ok: clear start bit */ * checksum ok: clear start bit */
/* XXX: Should delay that until next LFN known (then can better /* XXX: Should delay that until next LFN known (then can better
* display the name) */ * display the name) */
printf( "A new long file name starts within an old one.\n" ); VfatPrint( "A new long file name starts within an old one.\n" );
if ((lfn->id & LFN_ID_SLOTMASK) == lfn_slot && if ((lfn->id & LFN_ID_SLOTMASK) == lfn_slot &&
lfn->alias_checksum == lfn_checksum) { lfn->alias_checksum == lfn_checksum) {
char *part1 = CNV_THIS_PART(lfn); char *part1 = CNV_THIS_PART(lfn);
char *part2 = CNV_PARTS_SO_FAR(); char *part2 = CNV_PARTS_SO_FAR();
printf( " It could be that the LFN start bit is wrong here\n" VfatPrint( " It could be that the LFN start bit is wrong here\n"
" if \"%s\" seems to match \"%s\".\n", part1, part2 ); " if \"%s\" seems to match \"%s\".\n", part1, part2 );
free( part1 ); free( part1 );
free( part2 ); free( part2 );
can_clear = 1; can_clear = 1;
} }
if (interactive) { if (interactive) {
printf( "1: Delete previous LFN\n2: Leave it as it is.\n" ); VfatPrint( "1: Delete previous LFN\n2: Leave it as it is.\n" );
if (can_clear) if (can_clear)
printf( "3: Clear start bit and concatenate LFNs\n" ); VfatPrint( "3: Clear start bit and concatenate LFNs\n" );
} }
else printf( " Not auto-correcting this.\n" ); else VfatPrint( " Not auto-correcting this.\n" );
if (interactive) { if (interactive) {
switch( get_key( can_clear ? "123" : "12", "?" )) { switch( get_key( can_clear ? "123" : "12", "?" )) {
case '1': case '1':
@ -207,14 +207,14 @@ void lfn_add_slot( DIR_ENT *de, loff_t dir_offset )
* lost */ * lost */
/* Fixes: 1) delete LFN, 2) set start bit */ /* Fixes: 1) delete LFN, 2) set start bit */
char *part = CNV_THIS_PART(lfn); char *part = CNV_THIS_PART(lfn);
printf( "Long filename fragment \"%s\" found outside a LFN " VfatPrint( "Long filename fragment \"%s\" found outside a LFN "
"sequence.\n (Maybe the start bit is missing on the " "sequence.\n (Maybe the start bit is missing on the "
"last fragment)\n", part ); "last fragment)\n", part );
if (interactive) { if (interactive) {
printf( "1: Delete fragment\n2: Leave it as it is.\n" VfatPrint( "1: Delete fragment\n2: Leave it as it is.\n"
"3: Set start bit\n" ); "3: Set start bit\n" );
} }
else printf( " Not auto-correcting this.\n" ); else VfatPrint( " Not auto-correcting this.\n" );
if (interactive) { if (interactive) {
switch( get_key( "123", "?" )) { switch( get_key( "123", "?" )) {
case '1': case '1':
@ -247,24 +247,24 @@ void lfn_add_slot( DIR_ENT *de, loff_t dir_offset )
* are ok?, maybe only if checksum is ok?) (Attention: space * are ok?, maybe only if checksum is ok?) (Attention: space
* for name was allocated before!) */ * for name was allocated before!) */
int can_fix = 0; int can_fix = 0;
printf( "Unexpected long filename sequence number " VfatPrint( "Unexpected long filename sequence number "
"(%d vs. expected %d).\n", "(%d vs. expected %d).\n",
(lfn->id & LFN_ID_SLOTMASK), lfn_slot ); (lfn->id & LFN_ID_SLOTMASK), lfn_slot );
if (lfn->alias_checksum == lfn_checksum) { if (lfn->alias_checksum == lfn_checksum) {
char *part1 = CNV_THIS_PART(lfn); char *part1 = CNV_THIS_PART(lfn);
char *part2 = CNV_PARTS_SO_FAR(); char *part2 = CNV_PARTS_SO_FAR();
printf( " It could be that just the number is wrong\n" VfatPrint( " It could be that just the number is wrong\n"
" if \"%s\" seems to match \"%s\".\n", part1, part2 ); " if \"%s\" seems to match \"%s\".\n", part1, part2 );
free( part1 ); free( part1 );
free( part2 ); free( part2 );
can_fix = 1; can_fix = 1;
} }
if (interactive) { if (interactive) {
printf( "1: Delete LFN\n2: Leave it as it is (and ignore LFN so far)\n" ); VfatPrint( "1: Delete LFN\n2: Leave it as it is (and ignore LFN so far)\n" );
if (can_fix) if (can_fix)
printf( "3: Correct sequence number\n" ); VfatPrint( "3: Correct sequence number\n" );
} }
else printf( " Not auto-correcting this.\n" ); else VfatPrint( " Not auto-correcting this.\n" );
if (interactive) { if (interactive) {
switch( get_key( can_fix ? "123" : "12", "?" )) { switch( get_key( can_fix ? "123" : "12", "?" )) {
case '1': case '1':
@ -288,14 +288,14 @@ void lfn_add_slot( DIR_ENT *de, loff_t dir_offset )
/* checksum mismatch */ /* checksum mismatch */
/* Causes: 1) checksum field here destroyed */ /* Causes: 1) checksum field here destroyed */
/* Fixes: 1) delete LFN, 2) fix checksum */ /* Fixes: 1) delete LFN, 2) fix checksum */
printf( "Checksum in long filename part wrong " VfatPrint( "Checksum in long filename part wrong "
"(%02x vs. expected %02x).\n", "(%02x vs. expected %02x).\n",
lfn->alias_checksum, lfn_checksum ); lfn->alias_checksum, lfn_checksum );
if (interactive) { if (interactive) {
printf( "1: Delete LFN\n2: Leave it as it is.\n" VfatPrint( "1: Delete LFN\n2: Leave it as it is.\n"
"3: Correct checksum\n" ); "3: Correct checksum\n" );
} }
else printf( " Not auto-correcting this.\n" ); else VfatPrint( " Not auto-correcting this.\n" );
if (interactive) { if (interactive) {
switch( get_key( "123", "?" )) { switch( get_key( "123", "?" )) {
case '1': case '1':
@ -324,11 +324,11 @@ void lfn_add_slot( DIR_ENT *de, loff_t dir_offset )
} }
if (lfn->reserved != 0) { if (lfn->reserved != 0) {
printf( "Reserved field in VFAT long filename slot is not 0 " VfatPrint( "Reserved field in VFAT long filename slot is not 0 "
"(but 0x%02x).\n", lfn->reserved ); "(but 0x%02x).\n", lfn->reserved );
if (interactive) if (interactive)
printf( "1: Fix.\n2: Leave it.\n" ); VfatPrint( "1: Fix.\n2: Leave it.\n" );
else printf( "Auto-setting to 0.\n" ); else VfatPrint( "Auto-setting to 0.\n" );
if (!interactive || get_key("12","?") == '1') { if (!interactive || get_key("12","?") == '1') {
lfn->reserved = 0; lfn->reserved = 0;
fs_write( dir_offset+offsetof(LFN_ENT,reserved), fs_write( dir_offset+offsetof(LFN_ENT,reserved),
@ -336,11 +336,11 @@ void lfn_add_slot( DIR_ENT *de, loff_t dir_offset )
} }
} }
if (lfn->start != CT_LE_W(0)) { if (lfn->start != CT_LE_W(0)) {
printf( "Start cluster field in VFAT long filename slot is not 0 " VfatPrint( "Start cluster field in VFAT long filename slot is not 0 "
"(but 0x%04x).\n", lfn->start ); "(but 0x%04x).\n", lfn->start );
if (interactive) if (interactive)
printf( "1: Fix.\n2: Leave it.\n" ); VfatPrint( "1: Fix.\n2: Leave it.\n" );
else printf( "Auto-setting to 0.\n" ); else VfatPrint( "Auto-setting to 0.\n" );
if (!interactive || get_key("12","?") == '1') { if (!interactive || get_key("12","?") == '1') {
lfn->start = CT_LE_W(0); lfn->start = CT_LE_W(0);
fs_write( dir_offset+offsetof(LFN_ENT,start), fs_write( dir_offset+offsetof(LFN_ENT,start),
@ -363,7 +363,7 @@ char *lfn_get( DIR_ENT *de )
#if 0 #if 0
if (de->lcase) if (de->lcase)
printf( "lcase=%02x\n",de->lcase ); VfatPrint( "lcase=%02x\n",de->lcase );
#endif #endif
if (lfn_slot == -1) if (lfn_slot == -1)
@ -378,16 +378,16 @@ char *lfn_get( DIR_ENT *de )
* 3) renumber entries and truncate name */ * 3) renumber entries and truncate name */
char *long_name = CNV_PARTS_SO_FAR(); char *long_name = CNV_PARTS_SO_FAR();
char *short_name = file_name(de->name); char *short_name = file_name(de->name);
printf( "Unfinished long file name \"%s\".\n" VfatPrint( "Unfinished long file name \"%s\".\n"
" (Start may have been overwritten by %s)\n", " (Start may have been overwritten by %s)\n",
long_name, short_name ); long_name, short_name );
free( long_name ); free( long_name );
if (interactive) { if (interactive) {
printf( "1: Delete LFN\n2: Leave it as it is.\n" VfatPrint( "1: Delete LFN\n2: Leave it as it is.\n"
"3: Fix numbering (truncates long name and attaches " "3: Fix numbering (truncates long name and attaches "
"it to short name %s)\n", short_name ); "it to short name %s)\n", short_name );
} }
else printf( " Not auto-correcting this.\n" ); else VfatPrint( " Not auto-correcting this.\n" );
if (interactive) { if (interactive) {
switch( get_key( "123", "?" )) { switch( get_key( "123", "?" )) {
case '1': case '1':
@ -418,16 +418,16 @@ char *lfn_get( DIR_ENT *de )
/* Fixes: 1) Fix checksum in LFN entries */ /* Fixes: 1) Fix checksum in LFN entries */
char *long_name = CNV_PARTS_SO_FAR(); char *long_name = CNV_PARTS_SO_FAR();
char *short_name = file_name(de->name); char *short_name = file_name(de->name);
printf( "Wrong checksum for long file name \"%s\".\n" VfatPrint( "Wrong checksum for long file name \"%s\".\n"
" (Short name %s may have changed without updating the long name)\n", " (Short name %s may have changed without updating the long name)\n",
long_name, short_name ); long_name, short_name );
free( long_name ); free( long_name );
if (interactive) { if (interactive) {
printf( "1: Delete LFN\n2: Leave it as it is.\n" VfatPrint( "1: Delete LFN\n2: Leave it as it is.\n"
"3: Fix checksum (attaches to short name %s)\n", "3: Fix checksum (attaches to short name %s)\n",
short_name ); short_name );
} }
else printf( " Not auto-correcting this.\n" ); else VfatPrint( " Not auto-correcting this.\n" );
if (interactive) { if (interactive) {
switch( get_key( "123", "?" )) { switch( get_key( "123", "?" )) {
case '1': case '1':
@ -460,10 +460,10 @@ void lfn_check_orphaned(void)
return; return;
long_name = CNV_PARTS_SO_FAR(); long_name = CNV_PARTS_SO_FAR();
printf("Orphaned long file name part \"%s\"\n", long_name); VfatPrint("Orphaned long file name part \"%s\"\n", long_name);
if (interactive) if (interactive)
printf( "1: Delete.\n2: Leave it.\n" ); VfatPrint( "1: Delete.\n2: Leave it.\n" );
else printf( " Auto-deleting.\n" ); else VfatPrint( " Auto-deleting.\n" );
if (!interactive || get_key("12","?") == '1') { if (!interactive || get_key("12","?") == '1') {
clear_lfn_slots(0, lfn_parts - 1); clear_lfn_slots(0, lfn_parts - 1);
} }

View file

@ -4,7 +4,9 @@
/* /*
* The MS-DOS filesystem constants/structures * The MS-DOS filesystem constants/structures
*/ */
#ifdef _M_IX86
#include "byteorder.h" #include "byteorder.h"
#endif
#define SECTOR_SIZE 512 /* sector size (bytes) */ #define SECTOR_SIZE 512 /* sector size (bytes) */
#define SECTOR_BITS 9 /* log2(SECTOR_SIZE) */ #define SECTOR_BITS 9 /* log2(SECTOR_SIZE) */