[VFATLIB] Upgrade fsck.fat to 4.1
authorPierre Schweitzer <pierre@reactos.org>
Mon, 28 May 2018 21:18:25 +0000 (23:18 +0200)
committerPierre Schweitzer <pierre@reactos.org>
Mon, 28 May 2018 21:18:25 +0000 (23:18 +0200)
Also make it easier to sync in the future.

14 files changed:
media/doc/README.FSD
sdk/lib/fslib/vfatlib/check/boot.c
sdk/lib/fslib/vfatlib/check/boot.h
sdk/lib/fslib/vfatlib/check/check.c
sdk/lib/fslib/vfatlib/check/check.h
sdk/lib/fslib/vfatlib/check/common.c
sdk/lib/fslib/vfatlib/check/common.h
sdk/lib/fslib/vfatlib/check/fat.c
sdk/lib/fslib/vfatlib/check/file.c
sdk/lib/fslib/vfatlib/check/fsck.fat.h
sdk/lib/fslib/vfatlib/check/io.c
sdk/lib/fslib/vfatlib/check/io.h
sdk/lib/fslib/vfatlib/check/lfn.c
sdk/lib/fslib/vfatlib/check/msdos_fs.h

index c4afbdc..8d9993d 100644 (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
index 8596e2b..2c8681b 100644 (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" },
-};
-
-#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
+    {
+    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"},};
+
+/* 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
index e962939..dd9404f 100644 (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 */
 
index dcf1808..ae6f5cb 100644 (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);
     }
index 933bbf4..4dfa03a 100644 (file)
 #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);
 
index 4782f16..2b02d63 100644 (file)
@@ -1,7 +1,3 @@
-/****
- ** Platform-dependent file
- ****/
-
 /* common.c - Common functions
 
    Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch>
 #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) {
index da990db..e957d0b 100644 (file)
@@ -1,7 +1,3 @@
-/****
- ** Platform-dependent file
- ****/
-
 /* common.h - Common functions
 
    Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch>
 #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. */
 
index a601e6a..efb05e1 100644 (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 {
index 004e308..66be32b 100644 (file)
 #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;
index 6b06ae2..2e9db8f 100644 (file)
 #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))
index 06e0496..e16d40a 100644 (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;
 }
index 23c6fd6..ce14766 100644 (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>
 #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
index de78e74..a30ed57 100644 (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
index 794cb04..a6bc8bb 100644 (file)
 #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 */