mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
[VFATLIB] Upgrade fsck.fat to 4.1
Also make it easier to sync in the future.
This commit is contained in:
parent
9f3169b295
commit
469289ed5c
14 changed files with 676 additions and 374 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -431,31 +439,40 @@ void read_boot(DOS_FS * fs)
|
|||
struct boot_sector_16 *b16 = (struct boot_sector_16 *)&b;
|
||||
if (b16->extended_sig == 0x29)
|
||||
memmove(fs->label, b16->label, 11);
|
||||
else {
|
||||
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 {
|
||||
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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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,6 +125,7 @@ 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));
|
||||
if (gen_name) {
|
||||
while (1) {
|
||||
char expanded[12];
|
||||
sprintf(expanded, pattern, curr_num);
|
||||
|
@ -152,6 +153,9 @@ off_t alloc_rootdir_entry(DOS_FS * fs, DIR_ENT * de, const char *pattern)
|
|||
if (++curr_num >= 10000)
|
||||
die("Unable to create unique name");
|
||||
}
|
||||
} else {
|
||||
memcpy(de->name, pattern, MSDOS_NAME);
|
||||
}
|
||||
} else {
|
||||
DIR_ENT *root;
|
||||
int next_free = 0, scan;
|
||||
|
@ -169,6 +173,7 @@ 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));
|
||||
if (gen_name) {
|
||||
while (1) {
|
||||
char expanded[12];
|
||||
sprintf(expanded, pattern, curr_num);
|
||||
|
@ -183,6 +188,9 @@ off_t alloc_rootdir_entry(DOS_FS * fs, DIR_ENT * de, const char *pattern)
|
|||
if (++curr_num >= 10000)
|
||||
die("Unable to create unique name");
|
||||
}
|
||||
} else {
|
||||
memcpy(de->name, pattern, MSDOS_NAME);
|
||||
}
|
||||
free(root);
|
||||
}
|
||||
++n_files;
|
||||
|
@ -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
|
||||
|
@ -453,25 +461,44 @@ static void auto_rename(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" );
|
||||
#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 ((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)) {
|
||||
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,9 +520,15 @@ 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) {
|
||||
#endif
|
||||
switch (interactive ? get_key("1234", "?") : '2') {
|
||||
case '1':
|
||||
drop_file(fs, file);
|
||||
|
@ -511,7 +544,9 @@ static int handle_dot(DOS_FS * fs, DOS_FILE * file, int dots)
|
|||
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,20 +657,30 @@ 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) {
|
||||
#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),
|
||||
|
@ -613,6 +688,7 @@ static int check_file(DOS_FS * fs, DOS_FILE * file)
|
|||
(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 "
|
||||
|
@ -620,6 +696,7 @@ static int check_file(DOS_FS * fs, DOS_FILE * 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,14 +867,25 @@ 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) {
|
||||
#endif
|
||||
switch (interactive ? get_key("1234", "?") : '3') {
|
||||
case '1':
|
||||
drop_file(fs, *walk);
|
||||
|
@ -789,7 +901,9 @@ static int check_dir(DOS_FS * fs, DOS_FILE ** root, int dots)
|
|||
break;
|
||||
case '4':
|
||||
break;
|
||||
#ifdef __REACTOS__
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/* don't check for duplicates of the volume label */
|
||||
|
@ -808,9 +922,14 @@ 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) {
|
||||
#endif
|
||||
switch (interactive ? get_key("123456", "?") : '6') {
|
||||
case '1':
|
||||
drop_file(fs, *walk);
|
||||
|
@ -841,7 +960,9 @@ static int check_dir(DOS_FS * fs, DOS_FILE ** root, int dots)
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
#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) {
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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,7 +494,9 @@ void reclaim_file(DOS_FS * fs)
|
|||
}
|
||||
while (changed);
|
||||
|
||||
#ifdef __REACTOS__
|
||||
if (rw) {
|
||||
#endif
|
||||
/* Now we can start recovery */
|
||||
files = reclaimed = 0;
|
||||
for (i = 2; i < total_num_clusters; i++)
|
||||
|
@ -499,7 +505,7 @@ void reclaim_file(DOS_FS * fs)
|
|||
DIR_ENT de;
|
||||
off_t offset;
|
||||
files++;
|
||||
offset = alloc_rootdir_entry(fs, &de, "FSCK%04dREC");
|
||||
offset = alloc_rootdir_entry(fs, &de, "FSCK%04dREC", 1);
|
||||
de.start = htole16(i & 0xffff);
|
||||
if (fs->fat_bits == 32)
|
||||
de.starthi = htole16(i >> 16);
|
||||
|
@ -515,7 +521,9 @@ void reclaim_file(DOS_FS * fs)
|
|||
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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue