a94886058abff3b69f146feed8e20b1331bd49b1
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS FAT Image Creator
4 * FILE: tools/fatten/fatten.c
5 * PURPOSE: FAT Image Creator (for EFI Boot)
6 * PROGRAMMERS: David Quintana
12 #include "fatfs/diskio.h"
16 static int isMounted
= 0;
17 static char buff
[32768];
19 // tool needed by fatfs
22 /* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */
23 /* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
29 timeinfo
= localtime(&rawtime
);
34 DWORD Second
: 5; // div 2
39 DWORD Year
: 7; // year-1980
49 timeinfo
->tm_year
- 1980,
57 int is_command(const char* parg
)
60 return (parg
[0] == '/') || (parg
[0] == '-');
62 return (parg
[0] == '-');
66 #define NEED_PARAMS(_min_,_max_) \
68 if(nargs<_min_) { printf("Too few args for command %s.\n",argv[-1]); PRINT_HELP_AND_QUIT(); } \
69 if(nargs>_max_) { printf("Too many args for command %s.\n",argv[-1]); PRINT_HELP_AND_QUIT(); } \
79 r
= f_mount(&g_Filesystem
, "0:", 0);
87 #define NEED_MOUNT() \
88 do { ret = need_mount(); if(ret) \
90 printf("Error: could not mount disk (%d). \n", ret); \
91 PRINT_HELP_AND_QUIT(); \
94 void print_help(char const * const name
)
96 printf("Syntax: %s image_file [list of commands]\n\n", name
);
97 printf("Commands: [Note: both '/' and '-' are accepted as command prefixes.] \n");
98 printf(" /format <sectors> [<filesystem>] Formats the disk image.\n");
99 printf(" /boot <sector file> Writes a new boot sector.\n");
100 printf(" /add <src path> <dst path> Copies an external file or directory\n"
101 " into the image.\n");
102 printf(" /extract <src path> <dst path> Copies a file or directory from the image\n"
103 " into an external file or directory.\n");
104 printf(" /move <src path> <new path> Moves/renames a file or directory.\n");
105 printf(" /copy <src path> <new path> Copies a file or directory.\n");
106 printf(" /mkdir <src path> <new path> Creates a directory.\n");
107 printf(" /rmdir <src path> <new path> Creates a directory.\n");
108 printf(" /list [<pattern>] Lists files a directory (defaults to root).\n");
109 //printf(" /recursive Enables recursive processing for directories.\n");
112 #define PRINT_HELP_AND_QUIT() \
115 print_help(oargv[0]); \
119 int main(int oargc
, char* oargv
[])
122 int argc
= oargc
- 1;
123 char** argv
= oargv
+ 1;
125 // first parameter must be the image file.
128 PRINT_HELP_AND_QUIT();
131 if (is_command(argv
[0]))
133 printf("Error: first parameter must be a filename, found '%s' instead. \n", argv
[0]);
134 PRINT_HELP_AND_QUIT();
137 if (disk_openimage(0, argv
[0]))
139 printf("Error: could not open image file '%s'. \n", argv
[0]);
140 PRINT_HELP_AND_QUIT();
152 if (!is_command(parg
))
154 printf("Error: Expected a command, found '%s' instead. \n", parg
);
155 PRINT_HELP_AND_QUIT();
162 // find next command, to calculare number of args
163 while ((argv
[i
] != NULL
) && !is_command(argv
[i
++]))
166 if (strcmp(parg
, "format") == 0)
168 // NOTE: The fs driver detects which FAT format fits best based on size
173 // Arg 1: number of sectors
174 sectors
= atoi(argv
[0]);
178 printf("Error: Sectors must be > 0\n");
183 disk_ioctl(0, SET_SECTOR_COUNT
, §ors
);
187 ret
= f_mkfs("0:", 1, sectors
< 4096 ? 1 : 8);
190 printf("ERROR: Formatting drive: %d.\n", ret
);
191 PRINT_HELP_AND_QUIT();
194 else if (strcmp(parg
, "boot") == 0)
197 BYTE
* temp
= buff
+ 1024;
203 fe
= fopen(argv
[0], "rb");
207 printf("Error: unable to open external file '%s' for reading.", argv
[0]);
212 if(!fread(buff
, 512, 1, fe
))
214 printf("Error: unable to read boot sector from file '%s'.", argv
[0]);
221 if(disk_read(0, temp
, 0, 1))
223 printf("Error: unable to read existing boot sector from image.");
228 if (g_Filesystem
.fs_type
== FS_FAT32
)
230 printf("TODO: writing boot sectors for FAT32 images not yet supported.");
236 // Quick&dirty hardcoded length.
237 memcpy(buff
+ 2, temp
+ 2, 0x3E - 0x02);
240 if (disk_write(0, buff
, 0, 1))
242 printf("Error: unable to write new boot sector to image.");
249 else if (strcmp(parg
, "add") == 0)
260 // Arg 1: external file to add
261 // Arg 2: virtual filename
263 fe
= fopen(argv
[0], "rb");
267 printf("Error: unable to open external file '%s' for reading.", argv
[0]);
272 if (f_open(&fv
, argv
[1], FA_WRITE
| FA_CREATE_ALWAYS
))
274 printf("Error: unable to open file '%s' for writing.", argv
[1]);
280 while ((rdlen
= fread(buff
, 1, 32768, fe
)) > 0)
282 f_write(&fv
, buff
, rdlen
, &wrlen
);
288 else if (strcmp(parg
, "extract") == 0)
299 // Arg 1: virtual file to extract
300 // Arg 2: external filename
302 if (f_open(&fe
, argv
[0], FA_READ
))
304 printf("Error: unable to open file '%s' for reading.", argv
[0]);
309 fv
= fopen(argv
[1], "wb");
313 printf("Error: unable to open external file '%s' for writing.", argv
[1]);
319 while ((f_read(&fe
, buff
, 32768, &rdlen
) == 0) && (rdlen
> 0))
321 fwrite(buff
, 1, rdlen
, fv
);
327 else if (strcmp(parg
, "move") == 0)
332 // Arg 1: src path & filename
333 // Arg 2: new path & filename
335 if (f_rename(argv
[0], argv
[1]))
336 printf("Error moving/renaming '%s' to '%s'", argv
[0], argv
[1]);
338 else if (strcmp(parg
, "copy") == 0)
348 // Arg 1: src path & filename
349 // Arg 2: new path & filename
351 if (f_open(&fe
, argv
[0], FA_READ
))
353 printf("Error: unable to open file '%s' for reading.", argv
[0]);
357 if (f_open(&fv
, argv
[1], FA_WRITE
| FA_CREATE_ALWAYS
))
359 printf("Error: unable to open file '%s' for writing.", argv
[1]);
365 while ((f_read(&fe
, buff
, 32768, &rdlen
) == 0) && (rdlen
> 0))
367 f_write(&fv
, buff
, rdlen
, &wrlen
);
373 else if (strcmp(parg
, "mkdir") == 0)
379 // Arg 1: folder path
382 else if (strcmp(parg
, "delete") == 0)
388 // Arg 1: file/folder path (cannot delete non-empty folders)
391 else if (strcmp(parg
, "list") == 0)
395 FILINFO info
= { 0 };
400 // Arg 1: folder path (optional)
407 if (f_opendir(&dir
, root
))
409 printf("Error opening directory '%s'.\n", root
);
414 printf("Listing directory contents of: %s\n", root
);
416 info
.lfname
= lfname
;
418 while ((!f_readdir(&dir
, &info
)) && (strlen(info
.fname
) > 0))
420 if (strlen(info
.lfname
) > 0)
421 printf(" - %s (%s)\n", info
.lfname
, info
.fname
);
423 printf(" - %s\n", info
.fname
);
428 printf("Error: Unknown or invalid command: %s\n", argv
[-1]);
429 PRINT_HELP_AND_QUIT();