[FATTEN]
[reactos.git] / reactos / tools / fatten / fatten.c
index 306f785..2127722 100644 (file)
@@ -8,13 +8,11 @@
 #include <stdio.h>
 #include <string.h>
 #include <time.h>
+#include <ctype.h>
 #include "fatfs/ff.h"
 #include "fatfs/diskio.h"
 
-char* imageFileName;
-
-FATFS g_Filesystem;
-
+static FATFS g_Filesystem;
 static int isMounted = 0;
 static char buff[32768];
 
@@ -48,7 +46,7 @@ DWORD get_fattime()
             timeinfo->tm_hour,
             timeinfo->tm_mday,
             timeinfo->tm_mon,
-            timeinfo->tm_year - 1980,
+            timeinfo->tm_year - 80,
         }
     };
 
@@ -89,26 +87,37 @@ int need_mount()
 #define NEED_MOUNT() \
     do { ret = need_mount(); if(ret) \
     {\
-        printf("Error: could not mount image file '%s' (%d). \n", imageFileName, ret); \
+        printf("Error: could not mount disk (%d). \n", ret); \
         PRINT_HELP_AND_QUIT(); \
     } } while(0)
 
 void print_help(char const * const name)
 {
     printf("Syntax: %s image_file [list of commands]\n\n", name);
-    printf("Commands: [Note: both '/' and '-' are accepted as command prefixes.] \n");
-    printf("    /format <sectors> [<filesystem>]         Formats the disk image.\n");
-    printf("    /boot <sector file>          Writes a new boot sector.\n");
-    printf("    /add <src path> <dst path>   Copies an external file or directory\n"
-        "                                 into the image.\n");
-    printf("    /extract <src path> <dst path>  Copies a file or directory from the image\n"
-        "                                 into an external file or directory.\n");
-    printf("    /move <src path> <new path>  Moves/renames a file or directory.\n");
-    printf("    /copy <src path> <new path>  Copies a file or directory.\n");
-    printf("    /mkdir <src path> <new path> Creates a directory.\n");
-    printf("    /rmdir <src path> <new path> Creates a directory.\n");
-    printf("    /list [<pattern>]            Lists files a directory (defaults to root).\n");
-    //printf("    /recursive                   Enables recursive processing for directories.\n");
+#if _WIN32
+    printf("Commands: [Note: both '/' and '-' are accepted as command prefixes.]\n");
+#else
+    printf("Commands:\n");
+#endif
+    printf("    -format <sectors> [<filesystem>]\n"
+           "            Formats the disk image.\n");
+    printf("    -boot <sector file> [<custom header label>]\n"
+           "            Writes a new boot sector.\n");
+    printf("    -add <src path> <dst path>\n"
+           "            Copies an external file or directory into the image.\n");
+    printf("    -extract <src path> <dst path>\n"
+           "            Copies a file or directory from the image into an external file\n"
+           "            or directory.\n");
+    printf("    -move <src path> <new path>\n"
+           "            Moves/renames a file or directory.\n");
+    printf("    -copy <src path> <new path>\n"
+           "            Copies a file or directory.\n");
+    printf("    -mkdir <src path> <new path>\n"
+           "            Creates a directory.\n");
+    printf("    -rmdir <src path> <new path>\n"
+           "            Creates a directory.\n");
+    printf("    -list [<pattern>]\n"
+           "            Lists files a directory (defaults to root).\n");
 }
 
 #define PRINT_HELP_AND_QUIT() \
@@ -136,11 +145,9 @@ int main(int oargc, char* oargv[])
         PRINT_HELP_AND_QUIT();
     }
 
-    imageFileName = argv[0];
-
-    if (disk_initialize(0))
+    if (disk_openimage(0, argv[0]))
     {
-        printf("Error: could not open image file '%s'. \n", imageFileName);
+        printf("Error: could not open image file '%s'. \n", argv[0]);
         PRINT_HELP_AND_QUIT();
     }
 
@@ -172,9 +179,7 @@ int main(int oargc, char* oargv[])
             // NOTE: The fs driver detects which FAT format fits best based on size
             int sectors;
 
-            NEED_PARAMS(1, 1);
-
-            NEED_MOUNT();
+            NEED_PARAMS(1, 2);
 
             // Arg 1: number of sectors
             sectors = atoi(argv[0]);
@@ -188,19 +193,142 @@ int main(int oargc, char* oargv[])
 
             disk_ioctl(0, SET_SECTOR_COUNT, &sectors);
 
-            ret = f_mkfs("0:", 1, 4096);
+            NEED_MOUNT();
+
+            ret = f_mkfs("0:", 1, sectors < 4096 ? 1 : 8);
             if (ret)
             {
                 printf("ERROR: Formatting drive: %d.\n", ret);
                 PRINT_HELP_AND_QUIT();
             }
+
+            // Arg 2: custom header label (optional)
+            if (nargs > 1)
+            {
+                char label[8];
+
+                int i, invalid=0;
+                int len = strlen(argv[1]);
+
+                if (len <= 8)
+                {
+                    // Copy and verify each character
+                    for (i = 0; i < len; i++)
+                    {
+                        char ch = argv[1][i];
+                        label[i] = ch;
+
+                        if (!isupper(ch) && !isspace(ch))
+                        {
+                            invalid =1;
+                            break;
+                        }
+                    }
+                
+                    if (!invalid)
+                    {
+                        // Pad the label with spaces
+                        while (len < 8)
+                        {
+                            label[len++] = ' ';
+                        }
+                    }
+                }
+                else
+                {
+                    invalid = 1;
+                }
+
+                if (invalid)
+                {
+                    printf("Error: header label is limited to 8 uppercase letters and spaces.");
+                    ret = 1;
+                    goto exit;
+                }
+
+                if (disk_read(0, buff, 0, 1))
+                {
+                    printf("Error: unable to read existing boot sector from image.");
+                    ret = 1;
+                    goto exit;
+                }
+
+
+                if (g_Filesystem.fs_type == FS_FAT32)
+                {
+                    memcpy(buff + 71, label, 8);
+                }
+                else
+                {
+                    memcpy(buff + 43, label, 8);
+                }
+
+                if (disk_write(0, buff, 0, 1))
+                {
+                    printf("Error: unable to write new boot sector to image.");
+                    ret = 1;
+                    goto exit;
+                }
+
+            }
         }
         else if (strcmp(parg, "boot") == 0)
         {
+            FILE* fe;
+            BYTE* temp = buff + 1024;
+
             NEED_PARAMS(1, 1);
 
             // Arg 1: boot file
-            printf("Not Implemented.");
+
+            fe = fopen(argv[0], "rb");
+
+            if (!fe)
+            {
+                printf("Error: unable to open external file '%s' for reading.", argv[0]);
+                ret = 1;
+                goto exit;
+            }
+
+            if(!fread(buff, 512, 1, fe))
+            {
+                printf("Error: unable to read boot sector from file '%s'.", argv[0]);
+                fclose(fe);
+                ret = 1;
+                goto exit;
+            }
+
+            fclose(fe);
+
+            NEED_MOUNT();
+
+            if(disk_read(0, temp, 0, 1))
+            {
+                printf("Error: unable to read existing boot sector from image.");
+                ret = 1;
+                goto exit;
+            }
+
+            if (g_Filesystem.fs_type == FS_FAT32)
+            {
+                printf("TODO: writing boot sectors for FAT32 images not yet supported.");
+                ret = 1;
+                goto exit;
+            }
+            else
+            {
+#define FAT16_HEADER_START 3
+#define FAT16_HEADER_END 62
+
+                memcpy(buff + FAT16_HEADER_START, temp + FAT16_HEADER_START, FAT16_HEADER_END - FAT16_HEADER_START);
+            }
+
+            if (disk_write(0, buff, 0, 1))
+            {
+                printf("Error: unable to write new boot sector to image.");
+                ret = 1;
+                goto exit;
+            }
         }
         else if (strcmp(parg, "add") == 0)
         {
@@ -233,7 +361,7 @@ int main(int oargc, char* oargv[])
                 goto exit;
             }
 
-            while ((rdlen = fread(buff, 1, 32768, fe)) > 0)
+            while ((rdlen = fread(buff, 1, sizeof(buff), fe)) > 0)
             {
                 f_write(&fv, buff, rdlen, &wrlen);
             }
@@ -272,7 +400,7 @@ int main(int oargc, char* oargv[])
                 goto exit;
             }
 
-            while ((f_read(&fe, buff, 32768, &rdlen) == 0) && (rdlen > 0))
+            while ((f_read(&fe, buff, sizeof(buff), &rdlen) == 0) && (rdlen > 0))
             {
                 fwrite(buff, 1, rdlen, fv);
             }
@@ -318,7 +446,7 @@ int main(int oargc, char* oargv[])
                 goto exit;
             }
 
-            while ((f_read(&fe, buff, 32768, &rdlen) == 0) && (rdlen > 0))
+            while ((f_read(&fe, buff, sizeof(buff), &rdlen) == 0) && (rdlen > 0))
             {
                 f_write(&fv, buff, rdlen, &wrlen);
             }