#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];
timeinfo->tm_hour,
timeinfo->tm_mday,
timeinfo->tm_mon,
- timeinfo->tm_year - 1980,
+ timeinfo->tm_year - 80,
}
};
#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() \
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();
}
// 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]);
disk_ioctl(0, SET_SECTOR_COUNT, §ors);
- 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)
{
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);
}
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);
}
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);
}