8 #define ROOT_ENTRY_SIZE 32
10 #define SECTOR_SIZE 512
11 #define SECTORS_PER_CLUSTER 1
14 #define N_ROOT_ENTRIES 224
15 #define SECTORS_PER_DISK (N_HEADS * N_CYLINDERS * SECTORS_PER_TRACK)
16 #define MEDIA_TYPE 0xf0
17 #define SECTORS_PER_FAT 9
18 #define SECTORS_PER_TRACK 18
20 #define SIGNATURE 0x29 /* only MS? */
21 #define END_SIGNATURE 0xaa55
24 #define ATTR_READONLY 0x01
25 #define ATTR_HIDDEN 0x02
26 #define ATTR_SYSTEM 0x04
27 #define ATTR_VOLUME 0x08
28 #define ATTR_SUBDIR 0x10
29 #define ATTR_ARCHIVE 0x20
30 #define ATTR_RES1 0x40
31 #define ATTR_RES2 0x80
34 typedef unsigned char disk_sector_t[SECTOR_SIZE];
36 typedef struct boot_sector
41 unsigned short bytes_per_sector;
42 unsigned char sectors_per_cluster;
43 unsigned short reserved_sectors;
45 unsigned short n_root_entries;
46 unsigned short n_sectors;
47 unsigned char media_type;
48 unsigned short sectors_per_fat;
49 unsigned short sectors_per_track;
50 unsigned short n_heads;
51 unsigned long hidden_sectors;
52 unsigned long huge_sectors;
54 unsigned char reserved;
55 unsigned char signature;
56 unsigned long volume_id;
57 char volume_label[11];
59 unsigned char boot_code[SECTOR_SIZE - 62 - 2];
60 unsigned short end_signature;
61 } __attribute__ ((packed)) boot_sector_t;
64 typedef struct root_entry
68 unsigned char attribute;
69 unsigned char reserved[10];
72 unsigned short cluster;
74 } __attribute ((packed)) root_entry_t;
77 disk_sector_t *new_image(char *bsfname)
81 boot_sector_t boot_sec;
84 if ((bsf = fopen(bsfname, "rb")) == NULL)
86 printf("Boot sector image file %s not found!\n", bsfname);
89 if (fread(&boot_sec, 1, SECTOR_SIZE, bsf) != SECTOR_SIZE)
91 printf("Unable to read boot sector image file %s!\n", bsfname);
97 if ( (boot_sec.bytes_per_sector != SECTOR_SIZE) ||
98 (boot_sec.sectors_per_cluster != SECTORS_PER_CLUSTER) ||
99 (boot_sec.reserved_sectors != N_RESERVED) ||
100 (boot_sec.n_fats != N_FATS) ||
101 (boot_sec.n_root_entries != N_ROOT_ENTRIES) ||
102 (boot_sec.n_sectors != SECTORS_PER_DISK) ||
103 (boot_sec.media_type != MEDIA_TYPE) ||
104 (boot_sec.sectors_per_fat != SECTORS_PER_FAT) ||
105 (boot_sec.sectors_per_track != SECTORS_PER_TRACK) ||
106 (boot_sec.n_heads != N_HEADS) ||
107 // (boot_sec.signature != SIGNATURE) ||
108 (boot_sec.end_signature != END_SIGNATURE) )
110 printf("Invalid boot sector in file %s\n", bsfname);
114 if ((img = (disk_sector_t *)malloc(SECTOR_SIZE * SECTORS_PER_DISK)) == NULL)
116 printf("Not enough memory!\n");
120 memset(img, 0, SECTOR_SIZE * SECTORS_PER_TRACK);
121 memcpy(img, &boot_sec, SECTOR_SIZE);
123 root = (root_entry_t *)img[N_RESERVED + N_FATS * SECTORS_PER_FAT];
124 strncpy(root->name, "REACTOS ", 11);
125 root->attribute = ATTR_VOLUME;
131 void create_root_entry(root_entry_t *root, char *fname,
132 unsigned short cluster, unsigned long size)
140 while ((fname[j] != '\0') && (fname[j] != '.') && (i < 8))
142 root->name[i] = toupper(fname[j]);
155 while ((fname[j] != '\0') && (i < 3))
157 root->extension[i] = toupper(fname[j]);
163 root->extension[i] = ' ';
172 root->extension[i] = ' ';
177 root->attribute = ATTR_ARCHIVE;
179 localt = localtime(&t);
180 root->time = (((localt->tm_hour & 0x001f) << 11) |
181 ((localt->tm_min & 0x003f) << 5) |
182 ((localt->tm_sec / 2) & 0x001f));
183 root->date = ((((localt->tm_year - 80) & 0x007f) << 9) |
184 (((localt->tm_mon + 1) & 0x000f) << 5) |
185 (localt->tm_mday & 0x001f));
186 root->cluster = cluster;
191 void update_fat(unsigned char *fat, int cl_start, int cl_end)
196 for (i = cl_start; i < cl_end - 1; i++)
199 cl = ((unsigned short *)&fat[k]);
202 *cl = (*cl & 0x000f) | (((i + 1) & 0x0fff) << 4);
206 *cl = (*cl & 0xf000) | ((i + 1) & 0x0fff);
210 cl = ((unsigned short *)&fat[k]);
213 *cl = (*cl & 0x000f) | 0xfff0;
217 *cl = (*cl & 0xf000) | 0x0fff;
222 int copy_files(disk_sector_t *img, char *filenames[], int n_files)
226 int cl_start, cl_end;
227 unsigned char *fat1, *fat2;
229 unsigned long n, size;
231 fat1 = (unsigned char *)img[N_RESERVED];
232 fat2 = (unsigned char *)img[N_RESERVED + SECTORS_PER_FAT];
233 root = (root_entry_t *)img[N_RESERVED + N_FATS * SECTORS_PER_FAT];
236 N_FATS * SECTORS_PER_FAT +
237 N_ROOT_ENTRIES * ROOT_ENTRY_SIZE / SECTOR_SIZE;
241 if (n_files > N_ROOT_ENTRIES)
243 n_files = N_ROOT_ENTRIES;
246 for (i = 0; i < n_files; i++)
248 cl_start = cl_end + 1;
249 if ((f = fopen(filenames[i], "rb")) == NULL)
251 printf("Error opening file %s!", filenames[i]);
255 printf(" %s\n", filenames[i]);
258 while ((n = fread(img[k], 1, SECTOR_SIZE, f)) > 0)
267 create_root_entry(root, filenames[i], cl_start, size);
269 update_fat(fat1, cl_start, cl_end);
271 memcpy(fat2, fat1, SECTORS_PER_FAT * SECTOR_SIZE);
277 int write_image(disk_sector_t *img, char *imgname)
281 if ((f = fopen(imgname, "rb")) != NULL)
283 printf("Image file %s already exists!\n", imgname);
289 f = fopen(imgname, "wb");
290 if (fwrite(img, SECTOR_SIZE, SECTORS_PER_DISK, f) != SECTORS_PER_DISK)
292 printf("Unable to write image file %s\n!", imgname);
304 int main(int argc, char *argv[])
314 printf("Usage: mkflpimg <image> <boot sector> <source files>\n");
320 filenames = &argv[3];
323 printf("Creating image ...\n");
324 if ((img = new_image(bsfname)) == NULL)
329 printf("Copying files ...\n");
331 if (copy_files(img, filenames, n_files))
336 printf("Writing image file ...\n");
338 if (write_image(img, imgname))
343 printf("Finished.\n");