[VFATLIB] Upgrade fsck.fat to 4.1

Also make it easier to sync in the future.
This commit is contained in:
Pierre Schweitzer 2018-05-28 23:18:25 +02:00
parent 9f3169b295
commit 469289ed5c
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
14 changed files with 676 additions and 374 deletions

View file

@ -20,3 +20,6 @@ The following FSD are shared with: https://github.com/Microsoft/Windows-driver-s
reactos/drivers/filesystems/fastfat_new # Synced to 2817004
reactos/drivers/filesystems/cdfs_new # Synced to f73e552
The following FS libs are shared with: https://github.com/dosfstools/dosfstools
reactos/sdk/lib/fslib/vfatlib/check # Synced to 4.1

View file

@ -30,7 +30,6 @@
#define NDEBUG
#include <debug.h>
#define ROUND_TO_MULTIPLE(n,m) ((n) && (m) ? (n)+(m)-1-((n)-1)%(m) : 0)
/* don't divide by zero */
@ -42,29 +41,21 @@ static struct {
uint8_t media;
const char *descr;
} mediabytes[] = {
{ 0xf0, "5.25\" or 3.5\" HD floppy" },
{ 0xf8, "hard disk" },
{ 0xf9, "3.5\" 720k floppy 2s/80tr/9sec or "
"5.25\" 1.2M floppy 2s/80tr/15sec" },
{ 0xfa, "5.25\" 320k floppy 1s/80tr/8sec" },
{ 0xfb, "3.5\" 640k floppy 2s/80tr/8sec" },
{ 0xfc, "5.25\" 180k floppy 1s/40tr/9sec" },
{ 0xfd, "5.25\" 360k floppy 2s/40tr/9sec" },
{ 0xfe, "5.25\" 160k floppy 1s/40tr/8sec" },
{ 0xff, "5.25\" 320k floppy 2s/40tr/8sec" },
};
{
0xf0, "5.25\" or 3.5\" HD floppy"}, {
0xf8, "hard disk"}, {
0xf9, "3,5\" 720k floppy 2s/80tr/9sec or "
"5.25\" 1.2M floppy 2s/80tr/15sec"}, {
0xfa, "5.25\" 320k floppy 1s/80tr/8sec"}, {
0xfb, "3.5\" 640k floppy 2s/80tr/8sec"}, {
0xfc, "5.25\" 180k floppy 1s/40tr/9sec"}, {
0xfd, "5.25\" 360k floppy 2s/40tr/9sec"}, {
0xfe, "5.25\" 160k floppy 1s/40tr/8sec"}, {
0xff, "5.25\" 320k floppy 2s/40tr/8sec"},};
#if defined __alpha || defined __ia64__ || defined __x86_64__ || defined __ppc64__
/* Unaligned fields must first be copied byte-wise (little endian) */
#define GET_UNALIGNED_W(u) \
(((unsigned char*)(&u))[0] | (((unsigned char*)&(u))[1] << 8))
#elif defined __s390x__
/* Unaligned fields must first be copied byte-wise (big endian) */
#define GET_UNALIGNED_W(pu) \
(((unsigned char*)&(u))[1] | (((unsigned char*)&(u))[0] << 8))
#else
#define GET_UNALIGNED_W(f) le16toh( *(unsigned short *)&f )
#endif
/* Unaligned fields must first be accessed byte-wise */
#define GET_UNALIGNED_W(f) \
( (uint16_t)f[0] | ((uint16_t)f[1]<<8) )
static const char *get_media_descr(unsigned char media)
{
@ -103,8 +94,8 @@ static void dump_boot(DOS_FS * fs, struct boot_sector *b, unsigned lss)
(unsigned long long)fs->fat_start,
(unsigned long long)fs->fat_start / lss);
printf("%10d FATs, %d bit entries\n", b->fats, fs->fat_bits);
printf("%10d bytes per FAT (= %u sectors)\n", fs->fat_size,
fs->fat_size / lss);
printf("%10lld bytes per FAT (= %llu sectors)\n", (long long)fs->fat_size,
(long long)fs->fat_size / lss);
if (!fs->root_cluster) {
printf("Root directory starts at byte %llu (sector %llu)\n",
(unsigned long long)fs->root_start,
@ -130,7 +121,7 @@ static void dump_boot(DOS_FS * fs, struct boot_sector *b, unsigned lss)
printf("%10u sectors total\n", sectors ? sectors : le32toh(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, unsigned int lss)
{
struct boot_sector b2;
@ -145,7 +136,7 @@ static void check_backup_boot(DOS_FS * fs, struct boot_sector *b, int lss)
else
printf(" Auto-creating backup boot block.\n");
if (!interactive || get_key("12", "?") == '1') {
int bbs;
unsigned int bbs;
/* The usual place for the backup boot sector is sector 6. Choose
* that or the last reserved sector. */
if (le16toh(b->reserved) >= 7 && le16toh(b->info_sector) != 6)
@ -210,14 +201,15 @@ static void check_backup_boot(DOS_FS * fs, struct boot_sector *b, int lss)
static void init_fsinfo(struct info_sector *i)
{
memset(i, 0, sizeof (struct info_sector));
i->magic = htole32(0x41615252);
i->signature = htole32(0x61417272);
i->free_clusters = htole32(-1);
i->next_cluster = htole32(2);
i->boot_sign = htole16(0xaa55);
i->boot_sign = htole32(0xaa550000);
}
static void read_fsinfo(DOS_FS * fs, struct boot_sector *b, int lss)
static void read_fsinfo(DOS_FS * fs, struct boot_sector *b, unsigned int lss)
{
struct info_sector i;
@ -257,7 +249,7 @@ static void read_fsinfo(DOS_FS * fs, struct boot_sector *b, int lss)
fs_read(fs->fsinfo_start, sizeof(i), &i);
if (i.magic != htole32(0x41615252) ||
i.signature != htole32(0x61417272) || i.boot_sign != htole16(0xaa55)) {
i.signature != htole32(0x61417272) || i.boot_sign != htole32(0xaa550000)) {
printf("FSINFO sector has bad magic number(s):\n");
if (i.magic != htole32(0x41615252))
printf(" Offset %llu: 0x%08x != expected 0x%08x\n",
@ -267,10 +259,10 @@ static void read_fsinfo(DOS_FS * fs, struct boot_sector *b, int lss)
printf(" Offset %llu: 0x%08x != expected 0x%08x\n",
(unsigned long long)offsetof(struct info_sector, signature),
le32toh(i.signature), 0x61417272);
if (i.boot_sign != htole16(0xaa55))
printf(" Offset %llu: 0x%04x != expected 0x%04x\n",
if (i.boot_sign != htole32(0xaa550000))
printf(" Offset %llu: 0x%08x != expected 0x%08x\n",
(unsigned long long)offsetof(struct info_sector, boot_sign),
le16toh(i.boot_sign), 0xaa55);
le32toh(i.boot_sign), 0xaa550000);
if (interactive)
printf("1) Correct\n2) Don't correct (FSINFO invalid then)\n");
else
@ -294,11 +286,17 @@ static char print_fat_dirty_state(void)
if (interactive) {
printf("1) Remove dirty bit\n" "2) No action\n");
return get_key("12", "?");
#ifndef __REACTOS__
} else
#else
} else if (rw) {
#endif
printf(" Automatically removing dirty bit.\n");
return '1';
#ifdef __REACTOS__
}
return '2';
#endif
}
static void check_fat_state_bit(DOS_FS * fs, void *b)
@ -330,8 +328,9 @@ void read_boot(DOS_FS * fs)
{
struct boot_sector b;
unsigned total_sectors;
unsigned short logical_sector_size, sectors;
unsigned fat_length;
unsigned int logical_sector_size, sectors;
off_t fat_length;
unsigned total_fat_entries;
off_t data_size;
fs_read(0, sizeof(b), &b);
@ -359,8 +358,12 @@ void read_boot(DOS_FS * fs)
/* Can't access last odd sector anyway, so round down */
fs_test((off_t)((total_sectors & ~1) - 1) * logical_sector_size,
logical_sector_size);
fat_length = le16toh(b.fat_length) ?
le16toh(b.fat_length) : le32toh(b.fat32_length);
if (!fat_length)
die("FAT size is zero.");
fs->fat_start = (off_t)le16toh(b.reserved) * logical_sector_size;
fs->root_start = ((off_t)le16toh(b.reserved) + b.fats * fat_length) *
logical_sector_size;
@ -368,7 +371,11 @@ void read_boot(DOS_FS * fs)
fs->data_start = fs->root_start + ROUND_TO_MULTIPLE(fs->root_entries <<
MSDOS_DIR_BITS,
logical_sector_size);
data_size = (off_t)total_sectors * logical_sector_size - fs->data_start;
if (data_size < fs->cluster_size)
die("Filesystem has no space for any data clusters");
fs->data_clusters = data_size / fs->cluster_size;
fs->root_cluster = 0; /* indicates standard, pre-FAT32 root dir */
fs->fsinfo_start = 0; /* no FSINFO structure */
@ -408,7 +415,8 @@ void read_boot(DOS_FS * fs)
* much clusers otherwise. */
fs->fat_bits = (fs->data_clusters >= FAT12_THRESHOLD) ? 16 : 12;
if (fs->data_clusters >= FAT16_THRESHOLD)
die("Too many clusters (%lu) for FAT16 filesystem.", fs->data_clusters);
die("Too many clusters (%lu) for FAT16 filesystem.",
(unsigned long)fs->data_clusters);
check_fat_state_bit(fs, &b);
} else {
/* On Atari, things are more difficult: GEMDOS always uses 12bit FATs
@ -428,34 +436,43 @@ void read_boot(DOS_FS * fs)
fs->label = calloc(12, sizeof(uint8_t));
if (fs->fat_bits == 12 || fs->fat_bits == 16) {
struct boot_sector_16 *b16 = (struct boot_sector_16 *)&b;
if (b16->extended_sig == 0x29)
memmove(fs->label, b16->label, 11);
else {
free(fs->label);
fs->label = NULL;
}
struct boot_sector_16 *b16 = (struct boot_sector_16 *)&b;
if (b16->extended_sig == 0x29)
memmove(fs->label, b16->label, 11);
else
#ifdef __REACTOS__
{
free(fs->label);
#endif
fs->label = NULL;
#ifdef __REACTOS__
}
#endif
} else if (fs->fat_bits == 32) {
if (b.extended_sig == 0x29)
memmove(fs->label, &b.label, 11);
else {
free(fs->label);
fs->label = NULL;
}
if (b.extended_sig == 0x29)
memmove(fs->label, &b.label, 11);
else
#ifdef __REACTOS__
{
free(fs->label);
#endif
fs->label = NULL;
#ifdef __REACTOS__
}
#endif
}
if (fs->data_clusters >
((uint64_t)fs->fat_size * 8 / fs->fat_bits) - 2)
die("Filesystem has %d clusters but only space for %d FAT entries.",
fs->data_clusters,
((unsigned long long)fs->fat_size * 8 / fs->fat_bits) - 2);
total_fat_entries = (uint64_t)fs->fat_size * 8 / fs->fat_bits;
if (fs->data_clusters > total_fat_entries - 2)
die("Filesystem has %u clusters but only space for %u FAT entries.",
fs->data_clusters, total_fat_entries - 2);
if (!fs->root_entries && !fs->root_cluster)
die("Root directory has zero size.");
if (fs->root_entries & (MSDOS_DPS - 1))
die("Root directory (%d entries) doesn't span an integral number of "
"sectors.", fs->root_entries);
if (logical_sector_size & (SECTOR_SIZE - 1))
die("Logical sector size (%d bytes) is not a multiple of the physical "
die("Logical sector size (%u bytes) is not a multiple of the physical "
"sector size.", logical_sector_size);
#if 0 /* linux kernel doesn't check that either */
/* ++roman: On Atari, these two fields are often left uninitialized */
@ -465,3 +482,111 @@ void read_boot(DOS_FS * fs)
if (verbose)
dump_boot(fs, &b, logical_sector_size);
}
#ifndef __REACTOS__
static void write_boot_label(DOS_FS * fs, char *label)
{
if (fs->fat_bits == 12 || fs->fat_bits == 16) {
struct boot_sector_16 b16;
fs_read(0, sizeof(b16), &b16);
if (b16.extended_sig != 0x29) {
b16.extended_sig = 0x29;
b16.serial = 0;
memmove(b16.fs_type, fs->fat_bits == 12 ? "FAT12 " : "FAT16 ",
8);
}
memmove(b16.label, label, 11);
fs_write(0, sizeof(b16), &b16);
} else if (fs->fat_bits == 32) {
struct boot_sector b;
fs_read(0, sizeof(b), &b);
if (b.extended_sig != 0x29) {
b.extended_sig = 0x29;
b.serial = 0;
memmove(b.fs_type, "FAT32 ", 8);
}
memmove(b.label, label, 11);
fs_write(0, sizeof(b), &b);
if (fs->backupboot_start)
fs_write(fs->backupboot_start, sizeof(b), &b);
}
}
off_t find_volume_de(DOS_FS * fs, DIR_ENT * de)
{
uint32_t cluster;
off_t offset;
int i;
if (fs->root_cluster) {
for (cluster = fs->root_cluster;
cluster != 0 && cluster != -1;
cluster = next_cluster(fs, cluster)) {
offset = cluster_start(fs, cluster);
for (i = 0; i * sizeof(DIR_ENT) < fs->cluster_size; i++) {
fs_read(offset, sizeof(DIR_ENT), de);
if (de->attr != VFAT_LN_ATTR && de->attr & ATTR_VOLUME)
return offset;
offset += sizeof(DIR_ENT);
}
}
} else {
for (i = 0; i < fs->root_entries; i++) {
offset = fs->root_start + i * sizeof(DIR_ENT);
fs_read(offset, sizeof(DIR_ENT), de);
if (de->attr != VFAT_LN_ATTR && de->attr & ATTR_VOLUME)
return offset;
}
}
return 0;
}
static void write_volume_label(DOS_FS * fs, char *label)
{
time_t now = time(NULL);
struct tm *mtime = localtime(&now);
off_t offset;
int created;
DIR_ENT de;
created = 0;
offset = find_volume_de(fs, &de);
if (offset == 0) {
created = 1;
offset = alloc_rootdir_entry(fs, &de, label, 0);
}
memcpy(de.name, label, 11);
de.time = htole16((unsigned short)((mtime->tm_sec >> 1) +
(mtime->tm_min << 5) +
(mtime->tm_hour << 11)));
de.date = htole16((unsigned short)(mtime->tm_mday +
((mtime->tm_mon + 1) << 5) +
((mtime->tm_year - 80) << 9)));
if (created) {
de.attr = ATTR_VOLUME;
de.ctime_ms = 0;
de.ctime = de.time;
de.cdate = de.date;
de.adate = de.date;
de.starthi = 0;
de.start = 0;
de.size = 0;
}
fs_write(offset, sizeof(DIR_ENT), &de);
}
void write_label(DOS_FS * fs, char *label)
{
int l = strlen(label);
while (l < 11)
label[l++] = ' ';
write_boot_label(fs, label);
write_volume_label(fs, label);
}
#endif

View file

@ -24,6 +24,8 @@
#define _BOOT_H
void read_boot(DOS_FS * fs);
void write_label(DOS_FS * fs, char *label);
off_t find_volume_de(DOS_FS * fs, DIR_ENT * de);
/* Reads the boot sector from the currently open device and initializes *FS */

View file

@ -32,7 +32,7 @@
/* the longest path on the filesystem that can be handled by path_name() */
#define PATH_NAME_MAX 1023 // MAX_PATH
#define PATH_NAME_MAX 1023
static DOS_FILE *root;
@ -71,7 +71,7 @@ static DOS_FILE *root;
} \
} while(0)
off_t alloc_rootdir_entry(DOS_FS * fs, DIR_ENT * de, const char *pattern)
off_t alloc_rootdir_entry(DOS_FS * fs, DIR_ENT * de, const char *pattern, int gen_name)
{
static int curr_num = 0;
off_t offset;
@ -125,32 +125,36 @@ off_t alloc_rootdir_entry(DOS_FS * fs, DIR_ENT * de, const char *pattern)
fs_write(offset + i, sizeof(d2), &d2);
}
memset(de, 0, sizeof(DIR_ENT));
while (1) {
char expanded[12];
sprintf(expanded, pattern, curr_num);
memcpy(de->name, expanded, MSDOS_NAME);
clu_num = fs->root_cluster;
i = 0;
offset2 = cluster_start(fs, clu_num);
while (clu_num > 0 && clu_num != -1) {
fs_read(offset2, sizeof(DIR_ENT), &d2);
if (offset2 != offset &&
!strncmp((const char *)d2.name, (const char *)de->name,
MSDOS_NAME))
break;
i += sizeof(DIR_ENT);
offset2 += sizeof(DIR_ENT);
if ((i % fs->cluster_size) == 0) {
if ((clu_num = next_cluster(fs, clu_num)) == 0 ||
clu_num == -1)
if (gen_name) {
while (1) {
char expanded[12];
sprintf(expanded, pattern, curr_num);
memcpy(de->name, expanded, MSDOS_NAME);
clu_num = fs->root_cluster;
i = 0;
offset2 = cluster_start(fs, clu_num);
while (clu_num > 0 && clu_num != -1) {
fs_read(offset2, sizeof(DIR_ENT), &d2);
if (offset2 != offset &&
!strncmp((const char *)d2.name, (const char *)de->name,
MSDOS_NAME))
break;
offset2 = cluster_start(fs, clu_num);
i += sizeof(DIR_ENT);
offset2 += sizeof(DIR_ENT);
if ((i % fs->cluster_size) == 0) {
if ((clu_num = next_cluster(fs, clu_num)) == 0 ||
clu_num == -1)
break;
offset2 = cluster_start(fs, clu_num);
}
}
if (clu_num == 0 || clu_num == -1)
break;
if (++curr_num >= 10000)
die("Unable to create unique name");
}
if (clu_num == 0 || clu_num == -1)
break;
if (++curr_num >= 10000)
die("Unable to create unique name");
} else {
memcpy(de->name, pattern, MSDOS_NAME);
}
} else {
DIR_ENT *root;
@ -169,19 +173,23 @@ off_t alloc_rootdir_entry(DOS_FS * fs, DIR_ENT * de, const char *pattern)
die("Root directory is full.");
offset = fs->root_start + next_free * sizeof(DIR_ENT);
memset(de, 0, sizeof(DIR_ENT));
while (1) {
char expanded[12];
sprintf(expanded, pattern, curr_num);
memcpy(de->name, expanded, MSDOS_NAME);
for (scan = 0; scan < fs->root_entries; scan++)
if (scan != next_free &&
!strncmp((const char *)root[scan].name,
(const char *)de->name, MSDOS_NAME))
if (gen_name) {
while (1) {
char expanded[12];
sprintf(expanded, pattern, curr_num);
memcpy(de->name, expanded, MSDOS_NAME);
for (scan = 0; scan < fs->root_entries; scan++)
if (scan != next_free &&
!strncmp((const char *)root[scan].name,
(const char *)de->name, MSDOS_NAME))
break;
if (scan == fs->root_entries)
break;
if (scan == fs->root_entries)
break;
if (++curr_num >= 10000)
die("Unable to create unique name");
if (++curr_num >= 10000)
die("Unable to create unique name");
}
} else {
memcpy(de->name, pattern, MSDOS_NAME);
}
free(root);
}
@ -243,7 +251,7 @@ static time_t date_dos2unix(unsigned short time, unsigned short date)
return secs;
}
#if 1 // Old version!
#ifdef __REACTOS__ // Old version!
static char *file_stat(DOS_FILE * file)
{
@ -341,7 +349,7 @@ static int bad_name(DOS_FILE * file)
if (atari_format && suspicious)
return 1;
#if 1 // Old !!!!!!!!!!!!!!!
#ifdef __REACTOS__ // Old !!!!!!!!!!!!!!!
/* Only complain about too much suspicious chars in interactive mode,
* never correct them automatically. The chars are all basically ok, so we
@ -451,27 +459,46 @@ static void auto_rename(DOS_FILE * file)
die("Can't generate a unique name.");
}
static void rename_file(DOS_FILE *file)
static void rename_file(DOS_FILE * file)
{
//unsigned char name[46];
//unsigned char *walk,*here;
#ifndef __REACTOS__
unsigned char name[46];
unsigned char *walk, *here;
#endif
if (!file->offset) {
#ifndef __REACTOS__
printf("Cannot rename FAT32 root dir\n");
#else
VfatPrint( "Cannot rename FAT32 root dir\n" );
return; /* cannot rename FAT32 root dir */
#endif
return; /* cannot rename FAT32 root dir */
}
while (1) {
VfatPrint("New name: ");
#if 0
#ifndef __REACTOS__
printf("New name: ");
fflush(stdout);
if (fgets((char*)name,45,stdin)) {
if ((here = (unsigned char*)strchr((char*)name,'\n'))) *here = 0;
for (walk = (unsigned char*)strrchr((char*)name,0); walk >= name && (*walk == ' ' ||
*walk == '\t'); walk--);
if (fgets((char *)name, 45, stdin)) {
if ((here = (unsigned char *)strchr((const char *)name, '\n')))
*here = 0;
for (walk = (unsigned char *)strrchr((const char *)name, 0);
walk >= name && (*walk == ' ' || *walk == '\t'); walk--) ;
walk[1] = 0;
for (walk = name; *walk == ' ' || *walk == '\t'; walk++);
if (file_cvt(walk,file->dir_ent.name)) {
fs_write(file->offset,MSDOS_NAME,file->dir_ent.name);
for (walk = name; *walk == ' ' || *walk == '\t'; walk++) ;
if (file_cvt(walk, file->dir_ent.name)) {
if (file->dir_ent.lcase & FAT_NO_83NAME) {
/* as we only assign a new 8.3 filename, reset flag that 8.3 name is not
present */
file->dir_ent.lcase &= ~FAT_NO_83NAME;
/* reset the attributes, only keep DIR and VOLUME */
file->dir_ent.attr &= ~(ATTR_DIR | ATTR_VOLUME);
fs_write(file->offset, MSDOS_NAME + 2, &file->dir_ent);
} else {
fs_write(file->offset, MSDOS_NAME, file->dir_ent.name);
}
if (file->lfn)
lfn_fix_checksum(file->lfn_offset, file->offset,
(const char *)file->dir_ent.name);
return;
}
}
@ -493,25 +520,33 @@ static int handle_dot(DOS_FS * fs, DOS_FILE * file, int dots)
if (interactive)
printf("1) Drop it\n2) Auto-rename\n3) Rename\n"
"4) Convert to directory\n");
#ifndef __REACTOS__
else
#else
else if (rw)
#endif
printf(" Auto-renaming it.\n");
#ifdef __REACTOS__
if (rw || interactive) {
switch (interactive ? get_key("1234", "?") : '2') {
case '1':
drop_file(fs, file);
return 1;
case '2':
auto_rename(file);
printf(" Renamed to %s\n", file_name(file->dir_ent.name));
return 0;
case '3':
rename_file(file);
#endif
switch (interactive ? get_key("1234", "?") : '2') {
case '1':
drop_file(fs, file);
return 1;
case '2':
auto_rename(file);
printf(" Renamed to %s\n", file_name(file->dir_ent.name));
return 0;
case '4':
MODIFY(file, size, htole32(0));
MODIFY(file, attr, file->dir_ent.attr | ATTR_DIR);
break;
case '3':
rename_file(file);
return 0;
case '4':
MODIFY(file, size, htole32(0));
MODIFY(file, attr, file->dir_ent.attr | ATTR_DIR);
break;
#ifdef __REACTOS__
}
#endif
}
}
if (!dots) {
@ -530,9 +565,15 @@ static int check_file(DOS_FS * fs, DOS_FILE * file)
if (file->dir_ent.attr & ATTR_DIR) {
if (le32toh(file->dir_ent.size)) {
#ifndef __REACTOS__
printf("%s\n Directory has non-zero size. Fixing it.\n",
path_name(file));
#else
printf("%s\n Directory has non-zero size.%s\n",
path_name(file), (rw) ? " Fixing it." : "");
if (rw) MODIFY(file, size, htole32(0));
if (rw)
#endif
MODIFY(file, size, htole32(0));
}
if (file->parent
&& !strncmp((const char *)file->dir_ent.name, MSDOS_DOT,
@ -541,7 +582,10 @@ static int check_file(DOS_FS * fs, DOS_FILE * file)
if (FSTART(file, fs) != expect) {
printf("%s\n Start (%lu) does not point to parent (%lu)\n",
path_name(file), (unsigned long)FSTART(file, fs), (long)expect);
if (rw) MODIFY_START(file, expect, fs);
#ifdef __REACTOS__
if (rw)
#endif
MODIFY_START(file, expect, fs);
}
return 0;
}
@ -555,14 +599,23 @@ static int check_file(DOS_FS * fs, DOS_FILE * file)
if (FSTART(file, fs) != expect) {
printf("%s\n Start (%lu) does not point to .. (%lu)\n",
path_name(file), (unsigned long)FSTART(file, fs), (unsigned long)expect);
if (rw) MODIFY_START(file, expect, fs);
#ifdef __REACTOS__
if (rw)
#endif
MODIFY_START(file, expect, fs);
}
return 0;
}
if (FSTART(file, fs) == 0) {
#ifndef __REACTOS__
printf("%s\n Start does point to root directory. Deleting dir. \n",
path_name(file));
#else
printf("%s\n Start does point to root directory.%s\n",
path_name(file), (rw) ? " Deleting dir. " : "");
if (rw) MODIFY(file, name[0], DELETED_FLAG);
if (rw)
#endif
MODIFY(file, name[0], DELETED_FLAG);
return 0;
}
}
@ -571,19 +624,31 @@ static int check_file(DOS_FS * fs, DOS_FILE * file)
path_name(file));
if (!file->offset)
die("Bad FAT32 root directory! (bad start cluster 1)\n");
if (rw) MODIFY_START(file, 0, fs);
#ifdef __REACTOS__
if (rw)
#endif
MODIFY_START(file, 0, fs);
}
if (FSTART(file, fs) >= fs->data_clusters + 2) {
printf
#ifndef __REACTOS__
("%s\n Start cluster beyond limit (%lu > %lu). Truncating file.\n",
path_name(file), (unsigned long)FSTART(file, fs),
(unsigned long)(fs->data_clusters + 1));
#else
("%s\n Start cluster beyond limit (%lu > %lu).%s\n",
path_name(file), (unsigned long)FSTART(file, fs),
(unsigned long)(fs->data_clusters + 1),
(rw) ? " Truncating file." : "");
#endif
if (!file->offset)
die("Bad FAT32 root directory! (start cluster beyond limit: %lu > %lu)\n",
(unsigned long)FSTART(file, fs),
(unsigned long)(fs->data_clusters + 1));
if (rw) MODIFY_START(file, 0, fs);
#ifdef __REACTOS__
if (rw)
#endif
MODIFY_START(file, 0, fs);
}
clusters = prev = 0;
for (curr = FSTART(file, fs) ? FSTART(file, fs) :
@ -592,34 +657,46 @@ static int check_file(DOS_FS * fs, DOS_FILE * file)
get_fat(&curEntry, fs->fat, curr, fs);
if (!curEntry.value || bad_cluster(fs, curr)) {
#ifndef __REACTOS__
printf("%s\n Contains a %s cluster (%lu). Assuming EOF.\n",
path_name(file), curEntry.value ? "bad" : "free", (unsigned long)curr);
#else
printf("%s\n Contains a %s cluster (%lu).%s\n",
path_name(file), curEntry.value ? "bad" : "free", (unsigned long)curr,
(rw) ? " Assuming EOF." : "");
#endif
if (prev)
set_fat(fs, prev, -1);
else if (!file->offset)
die("FAT32 root dir starts with a bad cluster!");
else
if (rw) MODIFY_START(file, 0, fs);
#ifdef __REACTOS__
if (rw)
#endif
MODIFY_START(file, 0, fs);
break;
}
if (!(file->dir_ent.attr & ATTR_DIR) && le32toh(file->dir_ent.size) <=
(uint64_t)clusters * fs->cluster_size) {
#ifdef __REACTOS__
if (rw) {
printf
("%s\n File size is %u bytes, cluster chain length is > %llu "
"bytes.\n Truncating file to %u bytes.\n", path_name(file),
le32toh(file->dir_ent.size),
(unsigned long long)clusters * fs->cluster_size,
le32toh(file->dir_ent.size));
truncate_file(fs, file, clusters);
#endif
printf
("%s\n File size is %u bytes, cluster chain length is > %llu "
"bytes.\n Truncating file to %u bytes.\n", path_name(file),
le32toh(file->dir_ent.size),
(unsigned long long)clusters * fs->cluster_size,
le32toh(file->dir_ent.size));
truncate_file(fs, file, clusters);
#ifdef __REACTOS__
} else {
printf
("%s\n File size is %u bytes, cluster chain length is > %llu "
"bytes.\n", path_name(file),
le32toh(file->dir_ent.size),
(unsigned long long)clusters * fs->cluster_size);
printf
("%s\n File size is %u bytes, cluster chain length is > %llu "
"bytes.\n", path_name(file),
le32toh(file->dir_ent.size),
(unsigned long long)clusters * fs->cluster_size);
}
#endif
break;
}
if ((owner = get_owner(fs, curr))) {
@ -634,27 +711,43 @@ static int check_file(DOS_FS * fs, DOS_FILE * file)
else
clusters2++;
restart = file->dir_ent.attr & ATTR_DIR;
#ifndef __REACTOS__
if (!owner->offset) {
#else
if (!owner->offset && rw) {
#endif
printf(" Truncating second to %llu bytes because first "
"is FAT32 root dir.\n",
(unsigned long long)clusters2 * fs->cluster_size);
(unsigned long long)clusters * fs->cluster_size);
do_trunc = 2;
#ifndef __REACTOS__
} else if (!file->offset) {
#else
} else if (!file->offset && rw) {
#endif
printf(" Truncating first to %llu bytes because second "
"is FAT32 root dir.\n",
(unsigned long long)clusters * fs->cluster_size);
(unsigned long long)clusters2 * fs->cluster_size);
do_trunc = 1;
} else if (interactive)
printf("1) Truncate first to %llu bytes%s\n"
"2) Truncate second to %llu bytes\n",
(unsigned long long)clusters * fs->cluster_size,
(unsigned long long)clusters2 * fs->cluster_size,
restart ? " and restart" : "",
(unsigned long long)clusters2 * fs->cluster_size);
else if (rw)
(unsigned long long)clusters * fs->cluster_size);
else
#ifdef __REACTOS__
if (rw)
#endif
printf(" Truncating second to %llu bytes.\n",
(unsigned long long)clusters2 * fs->cluster_size);
(unsigned long long)clusters * fs->cluster_size);
#ifndef __REACTOS__
if (do_trunc != 2
&& (do_trunc == 1
#else
if ((do_trunc != 2 && rw)
&& ((do_trunc == 1 && rw)
#endif
|| (interactive && get_key("12", "?") == '1'))) {
prev = 0;
clusters = 0;
@ -696,7 +789,11 @@ static int check_file(DOS_FS * fs, DOS_FILE * file)
prev = curr;
}
if (!(file->dir_ent.attr & ATTR_DIR) && le32toh(file->dir_ent.size) >
#ifndef __REACTOS__
(uint64_t)clusters * fs->cluster_size) {
#else
(uint64_t)clusters * fs->cluster_size && rw) {
#endif
printf
("%s\n File size is %u bytes, cluster chain length is %llu bytes."
"\n Truncating file to %llu bytes.\n", path_name(file),
@ -739,7 +836,11 @@ static int check_dir(DOS_FS * fs, DOS_FILE ** root, int dots)
path_name(parent), bad, good + bad);
if (!dots)
printf(" Not dropping root directory.\n");
#ifndef __REACTOS__
else if (!interactive)
#else
else if (!interactive || !rw)
#endif
printf(" Not dropping it in auto-mode.\n");
else if (get_key("yn", "Drop directory ? (y/n)") == 'y') {
truncate_file(fs, parent, 0);
@ -766,30 +867,43 @@ static int check_dir(DOS_FS * fs, DOS_FILE ** root, int dots)
dotdot++;
}
if (!((*walk)->dir_ent.attr & ATTR_VOLUME) && bad_name(*walk)) {
#ifndef __REACTOS__
puts(path_name(*walk));
printf(" Bad short file name (%s).\n",
file_name((*walk)->dir_ent.name));
#else
printf("%s\n Bad short file name (%s).\n",
path_name(*walk), file_name((*walk)->dir_ent.name));
#endif
if (interactive)
printf("1) Drop file\n2) Rename file\n3) Auto-rename\n"
"4) Keep it\n");
else if (rw)
else
#ifdef __REACTOS__
if (rw)
#endif
printf(" Auto-renaming it.\n");
#ifdef __REACTOS__
if (rw || interactive) {
switch (interactive ? get_key("1234", "?") : '3') {
case '1':
drop_file(fs, *walk);
walk = &(*walk)->next;
continue;
case '2':
rename_file(*walk);
redo = 1;
break;
case '3':
auto_rename(*walk);
printf(" Renamed to %s\n", file_name((*walk)->dir_ent.name));
break;
case '4':
break;
#endif
switch (interactive ? get_key("1234", "?") : '3') {
case '1':
drop_file(fs, *walk);
walk = &(*walk)->next;
continue;
case '2':
rename_file(*walk);
redo = 1;
break;
case '3':
auto_rename(*walk);
printf(" Renamed to %s\n", file_name((*walk)->dir_ent.name));
break;
case '4':
break;
#ifdef __REACTOS__
}
#endif
}
}
/* don't check for duplicates of the volume label */
@ -808,40 +922,47 @@ static int check_dir(DOS_FS * fs, DOS_FILE ** root, int dots)
("1) Drop first\n2) Drop second\n3) Rename first\n"
"4) Rename second\n5) Auto-rename first\n"
"6) Auto-rename second\n");
else if (rw)
else
#ifdef __REACTOS__
if (rw)
#endif
printf(" Auto-renaming second.\n");
#ifdef __REACTOS__
if (rw || interactive) {
switch (interactive ? get_key("123456", "?") : '6') {
case '1':
drop_file(fs, *walk);
*walk = (*walk)->next;
skip = 1;
break;
case '2':
drop_file(fs, *scan);
*scan = (*scan)->next;
continue;
case '3':
rename_file(*walk);
printf(" Renamed to %s\n", path_name(*walk));
redo = 1;
break;
case '4':
rename_file(*scan);
printf(" Renamed to %s\n", path_name(*walk));
redo = 1;
break;
case '5':
auto_rename(*walk);
printf(" Renamed to %s\n",
file_name((*walk)->dir_ent.name));
break;
case '6':
auto_rename(*scan);
printf(" Renamed to %s\n",
file_name((*scan)->dir_ent.name));
break;
#endif
switch (interactive ? get_key("123456", "?") : '6') {
case '1':
drop_file(fs, *walk);
*walk = (*walk)->next;
skip = 1;
break;
case '2':
drop_file(fs, *scan);
*scan = (*scan)->next;
continue;
case '3':
rename_file(*walk);
printf(" Renamed to %s\n", path_name(*walk));
redo = 1;
break;
case '4':
rename_file(*scan);
printf(" Renamed to %s\n", path_name(*walk));
redo = 1;
break;
case '5':
auto_rename(*walk);
printf(" Renamed to %s\n",
file_name((*walk)->dir_ent.name));
break;
case '6':
auto_rename(*scan);
printf(" Renamed to %s\n",
file_name((*scan)->dir_ent.name));
break;
#ifdef __REACTOS__
}
#endif
}
}
scan = &(*scan)->next;
@ -917,6 +1038,9 @@ static void test_file(DOS_FS * fs, DOS_FILE * file, int read_test)
MODIFY_START(file, next_cluster(fs, walk), fs);
set_fat(fs, walk, -2);
}
} else {
prev = walk;
clusters++;
}
set_owner(fs, walk, file);
}

View file

@ -23,13 +23,13 @@
#ifndef _CHECK_H
#define _CHECK_H
off_t alloc_rootdir_entry(DOS_FS * fs, DIR_ENT * de, const char *pattern);
off_t alloc_rootdir_entry(DOS_FS * fs, DIR_ENT * de, const char *pattern, int gen_name);
/* 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
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
where in the filesystem the entry belongs. */
/* Allocate a free slot in the root directory for a new file. If gen_name is
true, the file name is constructed after 'pattern', which must include a %d
type format for printf 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 where in the filesystem the entry belongs. */
int scan_root(DOS_FS * fs);

View file

@ -1,7 +1,3 @@
/****
** Platform-dependent file
****/
/* common.c - Common functions
Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch>
@ -33,12 +29,12 @@
#define NDEBUG
#include <debug.h>
typedef struct _link {
void *data;
struct _link *next;
} LINK;
#ifdef __REACTOS__
DECLSPEC_NORETURN // __attribute((noreturn))
void exit(int exitcode)
{
@ -51,38 +47,61 @@ void exit(int exitcode)
DECLSPEC_NORETURN // __attribute((noreturn))
void die_func(const char *msg, ...) // die
#else
void die(const char *msg, ...)
#endif
{
va_list args;
va_start(args, msg);
// vfprintf(stderr, msg, args);
#ifndef __REACTOS__
vfprintf(stderr, msg, args);
#else
DPRINT1("Unrecoverable problem!\n");
VfatPrintV((char*)msg, args);
#endif
va_end(args);
// // fprintf(stderr, "\n");
// VfatPrint("\n");
#ifndef __REACTOS__
fprintf(stderr, "\n");
#endif
exit(1);
}
#ifdef __REACTOS__
DECLSPEC_NORETURN // __attribute((noreturn))
void pdie_func(const char *msg, ...) // pdie
#else
void pdie(const char *msg, ...)
#endif
{
va_list args;
va_start(args, msg);
// vfprintf(stderr, msg, args);
#ifndef __REACTOS__
vfprintf(stderr, msg, args);
#else
DPRINT1("Unrecoverable problem!\n");
VfatPrintV((char*)msg, args);
#endif
va_end(args);
// // fprintf(stderr, ":%s\n", strerror(errno));
// // VfatPrint(":%s\n", strerror(errno));
// VfatPrint("\n");
#ifndef __REACTOS__
fprintf(stderr, ":%s\n", strerror(errno));
#endif
exit(1);
}
void *vfalloc(size_t size)
#ifndef __REACTOS__
void *alloc(int size)
{
void *this;
if ((this = malloc(size)))
return this;
pdie("malloc");
return NULL; /* for GCC */
}
#else
void *vfalloc(int size)
{
void *ptr;
@ -97,7 +116,7 @@ void *vfalloc(size_t size)
return ptr;
}
void *vfcalloc(size_t size, size_t count)
void *vfcalloc(int size, int count)
{
void *ptr;
@ -115,15 +134,24 @@ void vffree(void *ptr)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, ptr);
}
#endif
void *qalloc(void **root, int size)
{
LINK *link;
#ifndef __REACTOS__
link = alloc(sizeof(LINK));
#else
link = vfalloc(sizeof(LINK));
#endif
link->next = *root;
*root = link;
#ifndef __REACTOS__
return link->data = alloc(size);
#else
return link->data = vfalloc(size);
#endif
}
void qfree(void **root)
@ -133,24 +161,29 @@ void qfree(void **root)
while (*root) {
this = (LINK *) * root;
*root = this->next;
#ifndef __REACTOS__
free(this->data);
free(this);
#else
vffree(this->data);
vffree(this);
#endif
}
}
#ifdef __REACTOS__
#ifdef min
#undef min
#endif
int min(int a,int b)
#endif
int min(int a, int b)
{
return a < b ? a : b;
}
char get_key(const char *valid, const char *prompt)
{
#if 0
#ifndef __REACTOS__
int ch, okay;
while (1) {

View file

@ -1,7 +1,3 @@
/****
** Platform-dependent file
****/
/* common.h - Common functions
Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch>
@ -27,29 +23,42 @@
#ifndef _COMMON_H
#define _COMMON_H
#ifndef __REACTOS__
void die(const char *msg, ...)
__attribute((noreturn, format(printf, 1, 2)));
#else
DECLSPEC_NORETURN // __attribute((noreturn))
// void die(const char *msg, ...);
void die_func(const char *msg, ...);
#define die(msg, ...) \
do { \
die_func("DIE! (%s:%d) " msg "\n", __RELFILE__, __LINE__, ##__VA_ARGS__); \
} while (0)
#endif
/* Displays a prinf-style message and terminates the program. */
#ifndef __REACTOS__
void pdie(const char *msg, ...)
__attribute((noreturn, format(printf, 1, 2)));
#else
DECLSPEC_NORETURN // __attribute((noreturn))
// void pdie(const char *msg, ...);
void pdie_func(const char *msg, ...);
#define pdie(msg, ...) \
do { \
pdie_func("P-DIE! (%s:%d) " msg "\n", __RELFILE__, __LINE__, ##__VA_ARGS__); \
} while (0)
#endif
/* Like die, but appends an error message according to the state of errno. */
void *vfalloc(size_t size);
void *vfcalloc(size_t size, size_t count);
#ifndef __REACTOS__
void *alloc(int size);
#else
void *vfalloc(int size);
void *vfcalloc(int size, int count);
void vffree(void *ptr);
#endif
/* mallocs SIZE bytes and returns a pointer to the data. Terminates the program
if malloc fails. */
@ -61,7 +70,9 @@ void qfree(void **root);
/* Deallocates all qalloc'ed data areas described by ROOT. */
//int min(int a,int b);
#ifndef __REACTOS__
int min(int a, int b);
#endif
/* Returns the smaller integer value of a and b. */

View file

@ -350,7 +350,11 @@ void reclaim_free(DOS_FS * fs)
get_fat(&curEntry, fs->fat, i, fs);
if (!get_owner(fs, i) && curEntry.value &&
#ifndef __REACTOS__
!FAT_IS_BAD(fs, curEntry.value)) {
#else
!FAT_IS_BAD(fs, curEntry.value) && rw) {
#endif
set_fat(fs, i, 0);
reclaimed++;
}
@ -490,32 +494,36 @@ void reclaim_file(DOS_FS * fs)
}
while (changed);
#ifdef __REACTOS__
if (rw) {
/* Now we can start recovery */
files = reclaimed = 0;
for (i = 2; i < total_num_clusters; i++)
/* If this cluster is the head of an orphan chain... */
if (get_owner(fs, i) == &orphan && !num_refs[i]) {
DIR_ENT de;
off_t offset;
files++;
offset = alloc_rootdir_entry(fs, &de, "FSCK%04dREC");
de.start = htole16(i & 0xffff);
if (fs->fat_bits == 32)
de.starthi = htole16(i >> 16);
for (walk = i; walk > 0 && walk != -1;
walk = next_cluster(fs, walk)) {
de.size = htole32(le32toh(de.size) + fs->cluster_size);
reclaimed++;
}
fs_write(offset, sizeof(DIR_ENT), &de);
#endif
/* Now we can start recovery */
files = reclaimed = 0;
for (i = 2; i < total_num_clusters; i++)
/* If this cluster is the head of an orphan chain... */
if (get_owner(fs, i) == &orphan && !num_refs[i]) {
DIR_ENT de;
off_t offset;
files++;
offset = alloc_rootdir_entry(fs, &de, "FSCK%04dREC", 1);
de.start = htole16(i & 0xffff);
if (fs->fat_bits == 32)
de.starthi = htole16(i >> 16);
for (walk = i; walk > 0 && walk != -1;
walk = next_cluster(fs, walk)) {
de.size = htole32(le32toh(de.size) + fs->cluster_size);
reclaimed++;
}
if (reclaimed)
printf("Reclaimed %d unused cluster%s (%llu bytes) in %d chain%s.\n",
reclaimed, reclaimed == 1 ? "" : "s",
(unsigned long long)reclaimed * fs->cluster_size, files,
files == 1 ? "" : "s");
}
fs_write(offset, sizeof(DIR_ENT), &de);
}
if (reclaimed)
printf("Reclaimed %d unused cluster%s (%llu bytes) in %d chain%s.\n",
reclaimed, reclaimed == 1 ? "" : "s",
(unsigned long long)reclaimed * fs->cluster_size, files,
files == 1 ? "" : "s");
#ifdef __REACTOS__
}
#endif
free(num_refs);
}
@ -545,9 +553,16 @@ uint32_t update_free(DOS_FS * fs)
(long)fs->free_clusters, (long)free);
if (interactive)
printf("1) Correct\n2) Don't correct\n");
else if (rw)
else
#ifdef __REACTOS__
if (rw)
#endif
printf(" Auto-correcting.\n");
#ifndef __REACTOS__
if (!interactive || get_key("12", "?") == '1')
#else
if ((!interactive && rw) || (interactive && get_key("12", "?") == '1'))
#endif
do_set = 1;
}
} else {

View file

@ -29,13 +29,14 @@
#define NDEBUG
#include <debug.h>
FDSC *fp_root = NULL;
static void put_char(char **p, unsigned char c)
{
// if (dos_char_to_printable(p, c))
// return;
#ifndef __REACTOS__
if (dos_char_to_printable(p, c))
return;
#endif
if ((c >= ' ' && c < 0x7f) || c >= 0xa0)
*(*p)++ = c;
else {
@ -108,18 +109,15 @@ int file_cvt(unsigned char *name, unsigned char *fixed)
}
if (c == '\\') {
c = 0;
name++;
for (cnt = 3; cnt; cnt--) {
if (*name < '0' || *name > '7') {
printf("Invalid octal character.\n");
printf("Expected three octal digits.\n");
return 0;
}
c = c * 8 + *name++ - '0';
}
if (cnt < 4) {
printf("Expected three octal digits.\n");
return 0;
}
name += 3;
name--;
}
if (islower(c))
c = toupper(c);
@ -158,7 +156,14 @@ void file_add(char *path, FD_TYPE type)
exit(2);
for (walk = *current; walk; walk = walk->next)
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))))
die("Ambiguous name: \"%s\"", path);
else if (here && !strncmp(name, walk->name, MSDOS_NAME))
break;

View file

@ -28,10 +28,14 @@
#ifndef _DOSFSCK_H
#define _DOSFSCK_H
//#include "types.h"
#ifndef __REACTOS__
#include <sys/types.h>
#include <fcntl.h>
#include <stddef.h>
#endif
#include <stdint.h>
#ifdef __REACTOS__
#ifdef _WIN32
typedef unsigned int __u32;
@ -48,29 +52,8 @@ typedef unsigned __int64 __u64;
#include "byteorder.h"
#endif
#if 0
#undef le16toh
#undef le32toh
#undef htole16
#undef htole32
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
#include "byteswap.h"
#if 0
#define le16toh(v) bswap_16(v)
#define le32toh(v) bswap_32(v)
#define htole16(v) le16toh(v)
#define htole32(v) le32toh(v)
#endif
#if 0
#define le16toh(v) le16_to_cpu(v)
#define le32toh(v) le32_to_cpu(v)
#define htole16(v) cpu_to_le16(v)
#define htole32(v) cpu_to_le32(v)
#endif
#else
#define le16toh(v) (v)
#define le32toh(v) (v)
@ -78,19 +61,17 @@ typedef unsigned __int64 __u64;
#define htole32(v) (v)
#endif /* __BIG_ENDIAN */
// #include "endian_compat.h"
#endif
#ifndef __REACTOS__
#include "endian_compat.h"
#else
#ifndef offsetof
#define offsetof(t,e) ((int)&(((t *)0)->e))
#endif
// extern int interactive, rw, list, verbose, test, write_immed;
// extern int atari_format;
// extern unsigned n_files;
// extern void *mem_queue;
#include "rosglue.h"
#endif
#include "msdos_fs.h"
@ -98,7 +79,9 @@ typedef unsigned __int64 __u64;
#define FAT_STATE_DIRTY 0x01
#ifdef __REACTOS__
#include <pshpack1.h>
#endif
/* ++roman: Use own definition of boot sector structure -- the kernel headers'
* name for it is msdos_boot_sector in 2.0 and fat_boot_sector in 2.1 ... */
@ -171,14 +154,12 @@ struct boot_sector_16 {
struct info_sector {
uint32_t magic; /* Magic for info sector ('RRaA') */
uint8_t junk[0x1dc];
uint32_t reserved1; /* Nothing as far as I can tell */
uint8_t reserved1[480];
uint32_t signature; /* 0x61417272 ('rrAa') */
uint32_t free_clusters; /* Free cluster count. -1 if unknown */
uint32_t next_cluster; /* Most recently allocated cluster. */
uint32_t reserved2[3];
uint16_t reserved3;
uint16_t boot_sign;
uint8_t reserved2[12];
uint32_t boot_sign;
};
typedef struct {
@ -194,7 +175,9 @@ typedef struct {
uint32_t size; /* file size (in bytes) */
} __attribute__ ((packed)) DIR_ENT;
#ifdef __REACTOS__
#include <poppack.h>
#endif
typedef struct _dos_file {
DIR_ENT dir_ent;
@ -214,7 +197,7 @@ typedef struct {
typedef struct {
int nfats;
off_t fat_start;
unsigned int fat_size; /* unit is bytes */
off_t fat_size; /* unit is bytes */
unsigned int fat_bits; /* size of a FAT entry */
unsigned int eff_fat_bits; /* # of used bits in a FAT entry */
uint32_t root_cluster; /* 0 for old-style root dir */
@ -231,6 +214,12 @@ typedef struct {
char *label;
} DOS_FS;
#ifndef __REACTOS__
extern int interactive, rw, list, verbose, test, write_immed;
extern int atari_format;
extern unsigned n_files;
extern void *mem_queue;
#endif
/* value to use as end-of-file marker */
#define FAT_EOF(fs) ((atari_format ? 0xfff : 0xff8) | FAT_EXTD(fs))

View file

@ -1,7 +1,3 @@
/****
** Platform-dependent file
****/
/* io.c - Virtual disk input/output
Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch>
@ -51,6 +47,9 @@ typedef struct _change {
} CHANGE;
static CHANGE *changes, *last;
#ifndef __REACTOS__
static int fd, did_change = 0;
#else
static int did_change = 0;
static HANDLE fd;
static LARGE_INTEGER CurrentOffset;
@ -157,8 +156,20 @@ static off_t WIN32lseek(HANDLE fd, off_t offset, int whence)
#define lseek WIN32lseek
/******************************************************************************/
#endif
#ifndef __REACTOS__
void fs_open(char *path, int rw)
{
if ((fd = open(path, rw ? O_RDWR : O_RDONLY)) < 0) {
perror("open");
exit(6);
}
changes = last = NULL;
did_change = 0;
}
#else
NTSTATUS fs_open(PUNICODE_STRING DriveRoot, int read_write)
{
NTSTATUS Status;
@ -264,6 +275,7 @@ void fs_dismount(void)
DPRINT1("NtFsControlFile() failed with Status 0x%08x\n", Status);
}
}
#endif
/**
* Read data from the partition, accounting for any pending updates that are
@ -279,8 +291,7 @@ void fs_read(off_t pos, int size, void *data)
CHANGE *walk;
int got;
#if 1 // TMN
#ifdef __REACTOS__
const size_t readsize_aligned = (size % 512) ? (size + (512 - (size % 512))) : size;
const off_t seekpos_aligned = pos - (pos % 512);
const size_t seek_delta = (size_t)(pos - seekpos_aligned);
@ -295,18 +306,14 @@ void fs_read(off_t pos, int size, void *data)
assert(seek_delta + size <= readsize);
memcpy(data, tmpBuf+seek_delta, size);
free(tmpBuf);
#else // TMN:
#else
if (lseek(fd, pos, 0) != pos)
pdie("Seek to %lld", pos);
pdie("Seek to %lld", (long long)pos);
if ((got = read(fd, data, size)) < 0)
pdie("Read %d bytes at %lld", size, pos);
#endif // TMN:
pdie("Read %d bytes at %lld", size, (long long)pos);
#endif
if (got != size)
die("Got %d bytes instead of %d at %lld", got, size, pos);
die("Got %d bytes instead of %d at %lld", got, size, (long long)pos);
for (walk = changes; walk; walk = walk->next) {
if (walk->pos < pos + size && walk->pos + walk->size > pos) {
if (walk->pos < pos)
@ -319,43 +326,36 @@ void fs_read(off_t pos, int size, void *data)
}
}
int fs_test(off_t pos, int size)
{
void *scratch;
int okay;
#if 1 // TMN
#ifdef __REACTOS__
const size_t readsize_aligned = (size % 512) ? (size + (512 - (size % 512))) : size; // TMN:
const off_t seekpos_aligned = pos - (pos % 512); // TMN:
scratch = alloc(readsize_aligned);
if (lseek(fd, seekpos_aligned, 0) != seekpos_aligned) pdie("Seek to %lld",pos);
okay = read(fd, scratch, readsize_aligned) == (int)readsize_aligned;
free(scratch);
#else // TMN:
#else
if (lseek(fd, pos, 0) != pos)
pdie("Seek to %lld", pos);
pdie("Seek to %lld", (long long)pos);
scratch = alloc(size);
okay = read(fd, scratch, size) == size;
free(scratch);
#endif // TMN:
#endif
return okay;
}
void fs_write(off_t pos, int size, void *data)
{
CHANGE *new;
int did;
#ifdef __REACTOS__
assert(interactive || rw);
#if 1 //SAE
if (FsCheckFlags & FSCHECK_IMMEDIATE_WRITE) {
void *scratch;
const size_t readsize_aligned = (size % 512) ? (size + (512 - (size % 512))) : size;
@ -390,22 +390,18 @@ void fs_write(off_t pos, int size, void *data)
if (did < 0) pdie("Write %d bytes at %lld", size, pos);
die("Wrote %d bytes instead of %d at %lld", did, size, pos);
}
#else //SAE
#else
if (write_immed) {
did_change = 1;
if (lseek(fd, pos, 0) != pos)
pdie("Seek to %lld", pos);
pdie("Seek to %lld", (long long)pos);
if ((did = write(fd, data, size)) == size)
return;
if (did < 0)
pdie("Write %d bytes at %lld", size, pos);
die("Wrote %d bytes instead of %d at %lld", did, size, pos);
pdie("Write %d bytes at %lld", size, (long long)pos);
die("Wrote %d bytes instead of %d at %lld", did, size, (long long)pos);
}
#endif //SAE
#endif
new = alloc(sizeof(CHANGE));
new->pos = pos;
memcpy(new->data = alloc(new->size = size), data, size);
@ -417,10 +413,9 @@ void fs_write(off_t pos, int size, void *data)
last = new;
}
static void fs_flush(void)
{
#if 1
#ifdef __REACTOS__
CHANGE *this;
int old_write_immed = (FsCheckFlags & FSCHECK_IMMEDIATE_WRITE);
@ -442,7 +437,6 @@ static void fs_flush(void)
if (!old_write_immed) FsCheckFlags ^= FSCHECK_IMMEDIATE_WRITE;
#else
CHANGE *this;
int size;
@ -450,26 +444,18 @@ static void fs_flush(void)
this = changes;
changes = changes->next;
if (lseek(fd, this->pos, 0) != this->pos)
{
// printf("Seek to %lld failed: %s\n Did not write %d bytes.\n",
// (long long)this->pos, strerror(errno), this->size);
printf("Seek to %lld failed\n Did not write %d bytes.\n",
(long long)this->pos, this->size);
}
fprintf(stderr,
"Seek to %lld failed: %s\n Did not write %d bytes.\n",
(long long)this->pos, strerror(errno), this->size);
else if ((size = write(fd, this->data, this->size)) < 0)
{
// printf("Writing %d bytes at %lld failed: %s\n", this->size,
// (long long)this->pos, strerror(errno));
printf("Writing %d bytes at %lld failed\n",
this->size, (long long)this->pos);
}
fprintf(stderr, "Writing %d bytes at %lld failed: %s\n", this->size,
(long long)this->pos, strerror(errno));
else if (size != this->size)
printf("Wrote %d bytes instead of %d bytes at %lld.\n",
size, this->size, (long long)this->pos);
fprintf(stderr, "Wrote %d bytes instead of %d bytes at %lld."
"\n", size, this->size, (long long)this->pos);
free(this->data);
free(this);
}
#endif
}
@ -478,7 +464,7 @@ int fs_close(int write)
CHANGE *next;
int changed;
changed = !!changes;
changed = ! !changes;
if (write)
fs_flush();
else
@ -495,5 +481,5 @@ int fs_close(int write)
int fs_changed(void)
{
return !!changes || did_change;
return ! !changes || did_change;
}

View file

@ -1,7 +1,3 @@
/****
** Platform-dependent file
****/
/* io.h - Virtual disk input/output
Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch>
@ -31,17 +27,24 @@
#ifndef _IO_H
#define _IO_H
//#include <sys/types.h> /* for loff_t */
// #include <fcntl.h> /* for off_t */
#ifndef __REACTOS__
#include <fcntl.h> /* for off_t */
#endif
#ifndef __REACTOS__
void fs_open(char *path, int rw);
#else
NTSTATUS fs_open(PUNICODE_STRING DriveRoot, int read_write);
#endif
/* Opens the file system PATH. If RW is zero, the file system is opened
/* Opens the filesystem PATH. If RW is zero, the filesystem is opened
read-only, otherwise, it is opened read-write. */
#ifdef __REACTOS__
BOOLEAN fs_isdirty(void);
/* Checks if filesystem is dirty */
#endif
void fs_read(off_t pos, int size, void *data);
@ -69,6 +72,7 @@ int fs_changed(void);
/* Determines whether the filesystem has changed. See fs_close. */
#ifdef __REACTOS__
NTSTATUS fs_lock(BOOLEAN LockVolume);
/* Lock or unlocks the volume */
@ -76,5 +80,5 @@ NTSTATUS fs_lock(BOOLEAN LockVolume);
void fs_dismount(void);
/* Dismounts the volume */
#endif
#endif

View file

@ -26,7 +26,6 @@
#define NDEBUG
#include <debug.h>
typedef struct {
uint8_t id; /* sequence number for slot */
uint8_t name0_4[10]; /* first 5 characters in name */
@ -67,16 +66,13 @@ static unsigned char fat_uni2esc[64] = {
/* for maxlen param */
#define UNTIL_0 INT_MAX
static void copy_lfn_part(unsigned char *dst, LFN_ENT * lfn);
static char *cnv_unicode(const unsigned char *uni, int maxlen, int use_q);
/* Convert name part in 'lfn' from unicode to ASCII */
static __inline char* CNV_THIS_PART(LFN_ENT * lfn)
{
unsigned char __part_uni[CHARS_PER_LFN*2];
copy_lfn_part(__part_uni, lfn);
return cnv_unicode(__part_uni, CHARS_PER_LFN, 0);
}
#define CNV_THIS_PART(lfn) \
({ \
unsigned char __part_uni[CHARS_PER_LFN*2]; \
copy_lfn_part( __part_uni, lfn ); \
cnv_unicode( __part_uni, CHARS_PER_LFN, 0 ); \
})
/* Convert name parts collected so far (from previous slots) from unicode to
* ASCII */
@ -309,7 +305,8 @@ void lfn_add_slot(DIR_ENT * de, off_t dir_offset)
can_fix = 1;
}
if (interactive) {
printf("1: Delete LFN\n2: Leave it as it is (and ignore LFN so far)\n");
printf
("1: Delete LFN\n2: Leave it as it is (and ignore LFN so far)\n");
if (can_fix)
printf("3: Correct sequence number\n");
} else

View file

@ -20,6 +20,10 @@
#ifndef _MSDOS_FS_H
#define _MSDOS_FS_H
#ifndef __REACTOS__
#include <stdint.h>
#endif
#define SECTOR_SIZE 512 /* sector size (bytes) */
#define MSDOS_DPS (SECTOR_SIZE / sizeof(struct msdos_dir_entry))
#define MSDOS_DPS_BITS 4 /* log2(MSDOS_DPS) */
@ -43,7 +47,9 @@
#define MSDOS_DOT ". " /* ".", padded to MSDOS_NAME chars */
#define MSDOS_DOTDOT ".. " /* "..", padded to MSDOS_NAME chars */
#ifdef __REACTOS__
#include <pshpack1.h>
#endif
struct msdos_dir_entry {
uint8_t name[MSDOS_NAME]; /* name including extension */
@ -58,6 +64,8 @@ struct msdos_dir_entry {
uint32_t size; /* file size (in bytes) */
} __attribute__ ((packed));
#ifdef __REACTOS__
#include <poppack.h>
#endif
#endif /* _MSDOS_FS_H */