1 /* Copyright 1986-1992 Emmet P. Gray.
2 * Copyright 1994,1996-2009 Alain Knaff.
3 * This file is part of mtools.
4 *
5 * Mtools is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * Mtools is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Mtools. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * mformat.c
19 */
20
21 #define DONT_NEED_WAIT
22
23 #include "sysincludes.h"
24 #include "msdos.h"
25 #include "mtools.h"
26 #include "mainloop.h"
27 #include "device.h"
28 #include "old_dos.h"
29 #include "fsP.h"
30 #include "file.h"
31 #include "plain_io.h"
32 #include "nameclash.h"
33 #include "buffer.h"
34 #ifdef HAVE_ASSERT_H
35 #include <assert.h>
36 #endif
37 #include "stream.h"
38 #include "partition.h"
39 #include "open_image.h"
40 #include "file_name.h"
41 #include "lba.h"
42
43 #ifdef OS_linux
44 #include "linux/hdreg.h"
45 #include "linux/fs.h"
46
47 #endif
48
init_geometry_boot(union bootsector * boot,struct device * dev,uint8_t sectors0,uint8_t rate_0,uint8_t rate_any,uint32_t * tot_sectors,int keepBoot)49 static uint16_t init_geometry_boot(union bootsector *boot, struct device *dev,
50 uint8_t sectors0,
51 uint8_t rate_0, uint8_t rate_any,
52 uint32_t *tot_sectors, int keepBoot)
53 {
54 int nb_renum;
55 int sector2;
56 int sum;
57
58 set_word(boot->boot.nsect, dev->sectors);
59 set_word(boot->boot.nheads, dev->heads);
60
61 #ifdef HAVE_ASSERT_H
62 assert(*tot_sectors != 0);
63 #endif
64
65 if (*tot_sectors <= UINT16_MAX && dev->hidden <= UINT16_MAX){
66 set_word(boot->boot.psect, (uint16_t) *tot_sectors);
67 set_dword(boot->boot.bigsect, 0);
68 set_word(boot->boot.nhs, (uint16_t) dev->hidden);
69 } else {
70 set_word(boot->boot.psect, 0);
71 set_dword(boot->boot.bigsect, (uint32_t) *tot_sectors);
72 set_dword(boot->boot.nhs, dev->hidden);
73 }
74
75 if (dev->use_2m & 0x7f){
76 uint16_t bootOffset;
77 uint8_t j;
78 uint8_t size2;
79 uint16_t i;
80 strncpy(boot->boot.banner, "2M-STV04", 8);
81 boot->boot.ext.old.res_2m = 0;
82 boot->boot.ext.old.fmt_2mf = 6;
83 if ( dev->sectors % ( ((1 << dev->ssize) + 3) >> 2 ))
84 boot->boot.ext.old.wt = 1;
85 else
86 boot->boot.ext.old.wt = 0;
87 boot->boot.ext.old.rate_0= rate_0;
88 boot->boot.ext.old.rate_any= rate_any;
89 if (boot->boot.ext.old.rate_any== 2 )
90 boot->boot.ext.old.rate_any= 1;
91 i=76;
92
93 /* Infp0 */
94 set_word(boot->boot.ext.old.Infp0, i);
95 boot->bytes[i++] = sectors0;
96 boot->bytes[i++] = 108;
97 for(j=1; j<= sectors0; j++)
98 boot->bytes[i++] = j;
99
100 set_word(boot->boot.ext.old.InfpX, i);
101
102 boot->bytes[i++] = 64;
103 boot->bytes[i++] = 3;
104 nb_renum = i++;
105 sector2 = dev->sectors;
106 size2 = dev->ssize;
107 j=1;
108 while( sector2 ){
109 while ( sector2 < (1 << size2) >> 2 )
110 size2--;
111 boot->bytes[i++] = 128 + j;
112 boot->bytes[i++] = j++;
113 boot->bytes[i++] = size2;
114 sector2 -= (1 << size2) >> 2;
115 }
116 boot->bytes[nb_renum] = (uint8_t)(( i - nb_renum - 1 )/3);
117
118 set_word(boot->boot.ext.old.InfTm, i);
119
120 sector2 = dev->sectors;
121 size2= dev->ssize;
122 while(sector2){
123 while ( sector2 < 1 << ( size2 - 2) )
124 size2--;
125 boot->bytes[i++] = size2;
126 sector2 -= 1 << (size2 - 2 );
127 }
128
129 set_word(boot->boot.ext.old.BootP,i);
130 bootOffset = i;
131
132 /* checksum */
133 for (sum=0, j=64; j<i; j++)
134 sum += boot->bytes[j];/* checksum */
135 boot->boot.ext.old.CheckSum=(unsigned char)-sum;
136 return bootOffset;
137 } else {
138 if(!keepBoot) {
139 boot->boot.jump[0] = 0xeb;
140 boot->boot.jump[1] = 0;
141 boot->boot.jump[2] = 0x90;
142 strncpy(boot->boot.banner, mformat_banner, 8);
143 /* It looks like some versions of DOS are
144 * rather picky about this, and assume default
145 * parameters without this, ignoring any
146 * indication about cluster size et al. */
147 }
148 return 0;
149 }
150 }
151
152 static unsigned char bootprog[]=
153 {0xfa, 0x31, 0xc0, 0x8e, 0xd8, 0x8e, 0xc0, 0xfc, 0xb9, 0x00, 0x01,
154 0xbe, 0x00, 0x7c, 0xbf, 0x00, 0x80, 0xf3, 0xa5, 0xea, 0x00, 0x00,
155 0x00, 0x08, 0xb8, 0x01, 0x02, 0xbb, 0x00, 0x7c, 0xba, 0x80, 0x00,
156 0xb9, 0x01, 0x00, 0xcd, 0x13, 0x72, 0x05, 0xea, 0x00, 0x7c, 0x00,
157 0x00, 0xcd, 0x19};
158
inst_boot_prg(union bootsector * boot,uint16_t offset)159 static __inline__ void inst_boot_prg(union bootsector *boot, uint16_t offset)
160 {
161 memcpy(boot->bytes + offset, bootprog, sizeof(bootprog));
162 if(offset - 2 < 0x80) {
163 /* short jump */
164 boot->boot.jump[0] = 0xeb;
165 boot->boot.jump[1] = (uint8_t) (offset -2);
166 boot->boot.jump[2] = 0x90;
167 } else {
168 /* long jump, if offset is too large */
169 boot->boot.jump[0] = 0xe9;
170 boot->boot.jump[1] = (uint8_t) (offset - 3);
171 boot->boot.jump[2] = (uint8_t) ( (offset - 3) >> 8);
172 }
173 set_word(boot->boot.jump + offset + 20, offset + 24);
174 }
175
176 /* Set up the root directory */
format_root(Fs_t * Fs,char * label,union bootsector * boot)177 static __inline__ void format_root(Fs_t *Fs, char *label, union bootsector *boot)
178 {
179 Stream_t *RootDir;
180 char *buf;
181 unsigned int i;
182 struct ClashHandling_t ch;
183 unsigned int dirlen;
184
185 init_clash_handling(&ch);
186 ch.name_converter = label_name_uc;
187 ch.ignore_entry = -2;
188
189 buf = safe_malloc(Fs->sector_size);
190 RootDir = OpenRoot((Stream_t *)Fs);
191 if(!RootDir){
192 fprintf(stderr,"Could not open root directory\n");
193 exit(1);
194 }
195
196 memset(buf, '\0', Fs->sector_size);
197
198 if(Fs->fat_bits == 32) {
199 /* on a FAT32 system, we only write one sector,
200 * as the directory can be extended at will...*/
201 dirlen = Fs->cluster_size;
202 fatAllocate(Fs, Fs->rootCluster, Fs->end_fat);
203 } else
204 dirlen = Fs->dir_len;
205 for (i = 0; i < dirlen; i++)
206 PWRITES(RootDir, buf, sectorsToBytes(Fs, i),
207 Fs->sector_size);
208
209 ch.ignore_entry = 1;
210 if(label[0])
211 mwrite_one(RootDir,label, 0, labelit, NULL,&ch);
212
213 FREE(&RootDir);
214 if(Fs->fat_bits == 32)
215 set_word(boot->boot.dirents, 0);
216 else
217 set_word(boot->boot.dirents,
218 (uint16_t) (Fs->dir_len * (Fs->sector_size / 32)));
219 free(buf);
220 }
221
222 /*
223 * Calculate length of one FAT, in sectors, given the number of total sectors
224 * Returns
225 * -2: if there are less total sectors than even clus_start
226 * 0: if a length was successfully calculated. (in that case, it is filled
227 * into Fs->fat_len)
228 * 1: if the specified number of FAT bits cannot accomodate that many
229 * sectors => caller should raise FAT bits
230 */
calc_fat_len(Fs_t * Fs,uint32_t tot_sectors)231 static int calc_fat_len(Fs_t *Fs, uint32_t tot_sectors)
232 {
233 uint32_t rem_sect;
234 uint32_t numerator;
235 uint32_t denominator;
236 uint32_t corr=0; /* correct numeric overflow */
237 uint32_t clus_start;
238 unsigned int fat_nybbles;
239
240 #ifdef HAVE_ASSERT_H
241 assert(Fs->fat_bits != 0);
242 #endif
243
244 #ifdef DEBUG
245 fprintf(stderr, "Fat start=%d\n", Fs->fat_start);
246 fprintf(stderr, "tot_sectors=%lu\n", tot_sectors);
247 fprintf(stderr, "dir_len=%d\n", Fs->dir_len);
248 #endif
249 Fs->fat_len = 0;
250 clus_start = calc_clus_start(Fs);
251 if(tot_sectors < clus_start)
252 return -2;
253 rem_sect = tot_sectors - clus_start;
254
255 /* Cheat a little bit to address the _really_ common case of
256 odd number of remaining sectors while both nfat and cluster size
257 are even... */
258 if(rem_sect % 2 == 1 &&
259 Fs->num_fat % 2 == 0 &&
260 Fs->cluster_size % 2 == 0)
261 rem_sect--;
262
263 #ifdef DEBUG
264 fprintf(stderr, "Rem sect=%lu\n", rem_sect);
265 #endif
266
267 /* See fat_size_calculation.tex or
268 (https://www.gnu.org/gnu/mtools/manual/fat_size_calculation.pdf)
269 for an explantation about why the stuff below works...
270 */
271
272 fat_nybbles = Fs->fat_bits / 4;
273 numerator = rem_sect+2*Fs->cluster_size;
274 /* Might overflow, but will be cancelled out below. As the
275 operation is unsigned, a posteriori fixup is allowable, as
276 wrap-around is part of the spec. For *signed* quantities,
277 this hack would be incorrect, as it would be "undefined
278 behavior" */
279
280 /* Initial denominator is nybbles consumed by one cluster, both in
281 * FAT and in cluster space */
282 denominator =
283 Fs->cluster_size * Fs->sector_size * 2 +
284 Fs->num_fat * fat_nybbles;
285
286 if(fat_nybbles == 3) {
287 /* We need to do this test here, or multiplying rem_sect with
288 * fat_nybbles might overflow */
289 if(rem_sect > 256 * FAT12)
290 return 1;
291 numerator *= fat_nybbles;
292 } else
293 /* Avoid numerical overflows, divide the denominator
294 * rather than multiplying the numerator */
295 denominator = denominator / fat_nybbles;
296
297 /* Substract denominator from numerator to "cancel out" an
298 unsigned integer overflow which might have happened with
299 total number of sectors very near maximum (2^32-1) and huge
300 cluster size. This substraction removes 1 from the result
301 of the following division, so we will add 1 again after the
302 division. However, we only do this if (original) numerator
303 is bigger than denominator though, as otherwise we risk the
304 inverse problem of going below 0 on small disks */
305 if(rem_sect > denominator) {
306 numerator -= denominator;
307 corr++;
308 }
309
310 #ifdef DEBUG
311 fprintf(stderr, "Numerator=%lu denominator=%lu\n",
312 numerator, denominator);
313 #endif
314
315 Fs->fat_len = (numerator-1)/denominator+1+corr;
316 return 0;
317 }
318
319 /* Is there enough space in the FAT for the descriptors for all clusters.
320 * This only works if we assume that it is already clear that Fs->num_clus is
321 * less than FAT32, or else it might overflow */
clusters_fit_into_fat(Fs_t * Fs)322 static inline bool clusters_fit_into_fat(Fs_t *Fs) {
323 return ((Fs->num_clus+2) * (Fs->fat_bits/4) - 1) / (Fs->sector_size*2) <
324 Fs->fat_len;
325 }
326
327 /*
328 * Assert that FAT param calculation has been performed correctly, and
329 * set_fat
330 */
check_fs_params_and_set_fat(Fs_t * Fs,uint32_t tot_sectors)331 static void check_fs_params_and_set_fat(Fs_t *Fs, uint32_t tot_sectors)
332 {
333 unsigned int provisional_fat_bits;
334
335 #ifdef DEBUG
336 fprintf(stderr, "Num_clus=%d fat_len=%d nybbles=%d\n",
337 Fs->num_clus, Fs->fat_len, fat_nybbles);
338 #endif
339
340 #ifdef HAVE_ASSERT_H
341 /* if FAT bits is 32, dir_len must be zero, otherwise it must be
342 * non-zero */
343 assert(Fs->fat_bits == 32 ? (Fs->dir_len == 0) : (Fs->dir_len != 0));
344
345 /* Clusters must fill disk up entirely, except for small amount of
346 * slack smaller than one sector */
347 assert(tot_sectors >=
348 Fs->clus_start + Fs->num_clus * Fs->cluster_size);
349 assert(tot_sectors <=
350 Fs->clus_start + Fs->num_clus * Fs->cluster_size +
351 Fs->cluster_size - 1);
352
353 /* Fat must be big enough for all clusters */
354 assert(clusters_fit_into_fat(Fs));
355 #endif
356 provisional_fat_bits = Fs->fat_bits;
357 set_fat(Fs);
358 #ifdef HAVE_ASSERT_H
359 assert(provisional_fat_bits == Fs->fat_bits);
360 #endif
361 }
362
fat32_specific_init(Fs_t * Fs)363 static void fat32_specific_init(Fs_t *Fs) {
364 Fs->primaryFat = 0;
365 Fs->writeAllFats = 1;
366 if(!Fs->backupBoot) {
367 if(Fs->fat_start <= 6)
368 Fs->backupBoot = Fs->fat_start - 1;
369 else
370 Fs->backupBoot=6;
371 }
372
373 if(Fs->fat_start < 3) {
374 fprintf(stderr,
375 "For FAT 32, reserved sectors need to be at least 3\n");
376 exit(1);
377 }
378
379 if(Fs->fat_start <= Fs->backupBoot) {
380 fprintf(stderr,
381 "Reserved sectors (%d) must be more than backupBoot (%d)\n", Fs->fat_start, Fs->backupBoot);
382 Fs->backupBoot = 0;
383 }
384 }
385
386 /* Try given cluster- and fat_size (and other parameters), and say whether
387 * cluster_size/fat_bits should be increased, decreased, or is fine as is.
388 * Parameters
389 * Fs the file system object
390 * tot_sectors size of file system, in sectors
391 * may_change_boot_size try_cluster_size may increase number of boot
392 * (reserved) sectors to make everything fit
393 * may_change_fat_len try_cluster_size may change (compute) FAT length
394 * may_change_root_size try_cluster_size may increase root directory size
395 * to make everything fit
396 * may_pad if there are (slightly) too many clusters,
397 * try_cluster_size may artificially inflate number of
398 * boot sectors, fat length or root_size to take up
399 * space in order to reduce number clusters below limit
400 *
401 * Return values
402 * -2 Too few sectors to contain even the header (reserved sectors, minimal
403 * FAT and root directory), or other internal error
404 * -1 This cluster size leads to too few clusters for the FAT size.
405 * Caller should either reduce cluster size or FAT size, and try again
406 * 0 Everything fits
407 * 1 This cluster size leads to too many clusters for the FAT
408 * size. Caller should either increase cluster size or FAT size, and
409 * try again
410 * 2 Fat length is set, and there are too many clusters to fit into
411 * that Fat length. Caller should either increase cluster size, or
412 * decrease FAT size, and try again
413 *
414 */
try_cluster_size(Fs_t * Fs,uint32_t tot_sectors,bool may_change_boot_size,bool may_change_fat_len,bool may_change_root_size,bool may_pad)415 static int try_cluster_size(Fs_t *Fs,
416 uint32_t tot_sectors,
417 bool may_change_boot_size,
418 bool may_change_fat_len,
419 bool may_change_root_size,
420 bool may_pad)
421 {
422 uint32_t maxClus;
423 uint32_t minClus;
424
425 switch(Fs->fat_bits) {
426 case 12:
427 minClus = 1;
428 maxClus = FAT12;
429 break;
430 case 16:
431 minClus = 4096;
432 maxClus = FAT16;
433 break;
434 case 32:
435 minClus = FAT16;
436 maxClus = FAT32;
437 break;
438 default:
439 #ifdef HAVE_ASSERT_H
440 assert(false && "Bad number of FAT bits");
441 #endif
442 return -2;
443 }
444
445 if(getenv("MTOOLS_DEBUG_FAT")) {
446 fprintf(stderr, "FAT=%d Cluster=%d%s\n",
447 Fs->fat_bits, Fs->cluster_size,
448 may_pad ? " may_pad" : "");
449 }
450
451 if(may_change_fat_len) {
452 int fit=calc_fat_len(Fs, tot_sectors);
453 if(fit != 0)
454 return fit;
455 }
456
457 while(true) {
458 uint32_t bwaste; /* How many sectors we need to "waste" */
459 uint16_t waste;
460 uint16_t dir_grow=0;
461
462 if(calc_num_clus(Fs, tot_sectors) < 0)
463 return -2;
464 if(Fs->num_clus < minClus)
465 return -1; /* Not enough clusters => loop
466 * should shrink FAT bits again */
467
468 if(!may_change_fat_len) {
469 /* If fat_len has been explicitly specified by
470 * user, make sure that number of clusters
471 * fit within that fat_len */
472 if(Fs->num_clus >= FAT32 || !clusters_fit_into_fat(Fs))
473 return 2; /* Caller should should pick a
474 * bigger cluster size, but not a
475 * higher FAT bits */
476 }
477
478 if(Fs->num_clus < maxClus)
479 break;
480 if(!may_pad)
481 return 1;
482
483 /* "Pad" fat by artifically adding sectors to boot sectors,
484 FAT or root directory to diminish number of clusters */
485
486 /* This is needed when a size of a FAT fs somehow is
487 * "in between" 2 fat bits: too large for FAT12, too small
488 * for FAT16.
489
490 * This happens because if there slightly too may
491 * clusters for FAT12, the system passes to
492 * FAT16. However, this makes the space taken up by
493 * the descriptor of each sector in the FAT larger,
494 * making the FAT larger overall, leaving less space
495 * for the clusters themselves, i.e. less
496 * clusters. Sometimes this is enough to push the
497 * number of clusters *below* the minimum for FAT12.
498
499 * a similar situation happens when switching from
500 * FAT16 to FAT32.
501
502 * if this happens, we switch back to the lower FAT
503 * bits, and allow "padding", i.e. artificially
504 * "wasting" space by adding more reserved (boot)
505 * sectors, adding "useless" extra sectors to the FAT,
506 * or allowing more root directory entries.
507
508 */
509 bwaste = tot_sectors - Fs->clus_start -
510 maxClus * Fs->cluster_size + 1;
511 #ifdef HAVE_ASSERT_H
512 assert(bwaste <= UINT16_MAX);
513 #endif
514 waste = (uint16_t) bwaste;
515
516 if(may_change_root_size) {
517 dir_grow = 32 - Fs->dir_len;
518 if(dir_grow > waste)
519 dir_grow = waste;
520 waste -= dir_grow;
521 }
522 if(may_change_fat_len &&
523 (!may_change_boot_size || Fs->fat_bits == 12)) {
524 uint16_t fat_grow =
525 (waste + Fs->num_fat - 1) / Fs->num_fat;
526 uint16_t dir_shrink = 0;
527 Fs->fat_len += fat_grow;
528
529 /* Shrink directory again, but at most as by as much
530 * as we grew it earlyer */
531 dir_shrink = waste - fat_grow * Fs->num_fat;
532 if(dir_shrink > dir_grow)
533 dir_shrink = dir_grow;
534 dir_grow -= dir_shrink;
535 } else if(may_change_boot_size) {
536 Fs->fat_start += waste;
537 }
538 Fs->dir_len += dir_grow;
539
540 /* If padding once failed, no point in keeping on retrying */
541 may_pad=false;
542 }
543 #ifdef HAVE_ASSERT_H
544 /* number of clusters must be within allowable range for fat
545 bits */
546 assert(Fs->num_clus >= minClus);
547 assert(Fs->num_clus < maxClus);
548 #endif
549 return 0;
550 }
551
552 /* Finds a set of filesystem parameters, given the device size, and
553 * any presets specified by user
554 * On return, Fs will be initialized, or one of the following error codes
555 * will be returned:
556 * -1 Not enough sectors for any kind of FAT filesystem
557 * -2 Not enough clusters for given number of FAT bits
558 * -3 Too many clusters for given number of FAT bits
559 * -4 Too many clusters for chosen FAT length
560 */
calc_fs_parameters(struct device * dev,bool fat32,uint32_t tot_sectors,struct Fs_t * Fs,uint8_t * descr)561 int calc_fs_parameters(struct device *dev, bool fat32,
562 uint32_t tot_sectors,
563 struct Fs_t *Fs, uint8_t *descr)
564 {
565 bool may_change_boot_size = (Fs->fat_start == 0);
566 bool may_change_fat_bits = (dev->fat_bits == 0) && !fat32;
567 bool may_change_cluster_size = (Fs->cluster_size == 0);
568 bool may_change_root_size = (Fs->dir_len == 0);
569 bool may_change_fat_len = (Fs->fat_len == 0);
570 bool may_pad = false;
571 uint16_t saved_dir_len;
572
573 struct OldDos_t *params=NULL;
574 Fs->infoSectorLoc = 0;
575 if( (may_change_fat_bits || abs(dev->fat_bits) == 12) &&
576 (may_change_boot_size || Fs->fat_start == 1) )
577 params = getOldDosByParams(dev->tracks,dev->heads,dev->sectors,
578 Fs->dir_len, Fs->cluster_size);
579 if(params != NULL) {
580 int num_clus_valid;
581 *descr = params->media;
582 Fs->fat_start = 1;
583 Fs->cluster_size = params->cluster_size;
584 Fs->dir_len = params->dir_len;
585 Fs->fat_len = params->fat_len;
586 Fs->fat_bits = 12;
587 num_clus_valid = calc_num_clus(Fs, tot_sectors);
588 #ifdef HAVE_ASSERT_H
589 assert(num_clus_valid >= 0);
590 #endif
591 check_fs_params_and_set_fat(Fs, tot_sectors);
592 return 0;
593 }
594
595 /* a format described by BPB */
596 if(dev->hidden || tot_sectors % (dev->sectors * dev->heads))
597 *descr = 0xf8;
598 else
599 *descr = 0xf0;
600
601 Fs->fat_bits = abs(dev->fat_bits);
602 if(Fs->fat_bits == 0)
603 /* If fat_bits not specified by device, start with a 12-bit
604 * FAT, unless 32 bit specified on command line */
605 Fs->fat_bits = fat32 ? 32 : 12;
606 if(!Fs->cluster_size) {
607 if(tot_sectors < 2400 && dev->heads == 2)
608 /* double sided double density floppies */
609 Fs->cluster_size = 2;
610 else if(may_change_fat_len && Fs->fat_bits == 32)
611 /* FAT32 => start with 8 */
612 Fs->cluster_size = 8;
613 else
614 /* In all other cases, start with 1 */
615 Fs->cluster_size = 1;
616 }
617
618 if(!Fs->dir_len) {
619 if(tot_sectors < 1200) {
620 /* Double density floppies */
621 if (dev->heads == 1)
622 Fs->dir_len = 4;
623 else
624 Fs->dir_len = 7;
625 } else if(tot_sectors <= 3840)
626 /* High density floppies */
627 Fs->dir_len = 14;
628 else if(tot_sectors <= 7680)
629 /* extra density floppies */
630 Fs->dir_len = 15;
631 else
632 Fs->dir_len = 32;
633 }
634 saved_dir_len = Fs->dir_len;
635
636 while(true) {
637 int fit;
638 if(may_change_boot_size) {
639 if(Fs->fat_bits == 32)
640 Fs->fat_start = 32;
641 else
642 Fs->fat_start = 1;
643 }
644
645 if(Fs->fat_bits == 32)
646 Fs->dir_len = 0;
647 else if(Fs->dir_len == 0)
648 Fs->dir_len = saved_dir_len;
649
650 if(Fs->fat_bits == 32 &&
651 may_change_cluster_size && may_change_fat_len) {
652 /*
653 FAT32 cluster sizes for disks with 512 block size
654 according to Microsoft specification fatgen103.doc:
655
656 ...
657 - 8 GB cluster_size = 8
658 8 GB - 16 GB cluster_size = 16
659 16 GB - 32 GB cluster_size = 32
660 32 GB - 2 TB cluster_size = 64
661
662 Below calculation is generalized and does not depend
663 on 512 block size.
664 */
665 Fs->cluster_size = tot_sectors >= 32*1024*1024*2 ? 64 :
666 tot_sectors >= 16*1024*1024*2 ? 32 :
667 tot_sectors >= 8*1024*1024*2 ? 16 :
668 Fs->cluster_size;
669 }
670
671 fit=try_cluster_size(Fs,
672 tot_sectors,
673 may_change_boot_size,
674 may_change_fat_len,
675 may_change_root_size,
676 may_pad);
677
678 if(getenv("MTOOLS_DEBUG_FAT")) {
679 fprintf(stderr, " fit=%d\n", fit);
680 }
681 if(fit == 0)
682 break;
683 if(fit == -2)
684 return -1;
685
686 #ifdef HAVE_ASSERT_H
687 assert(fit != 2 || !may_change_fat_len);
688 #endif
689 if(fit < 0) {
690 if(may_change_cluster_size &&
691 may_change_fat_len &&
692 Fs->cluster_size > 1) {
693 Fs->cluster_size = Fs->cluster_size / 2;
694 continue;
695 }
696
697 /* Somehow we ended up with too few sectors
698 * for FAT size. This can only happen if
699 * cluster size is not adjustable, and if we
700 * had *barely* more clusters than allowed by
701 * previous fat bits. After raising fat bits,
702 * fat_len grew larger (due to each individual
703 * FAT entry now being larger), pushing the
704 * number of clusters *below* new limit. =>
705 * we lower fat bits again */
706 if(!may_change_fat_bits || Fs->fat_bits == 12)
707 return -2;
708
709 switch(Fs->fat_bits) {
710 case 16:
711 Fs->fat_bits=12;
712 break;
713 case 32:
714 Fs->fat_bits=16;
715 break;
716 }
717 may_pad=true;
718 continue;
719 }
720
721 if(fit == 1 && may_change_fat_bits && !may_pad) {
722 /* If cluster_size reached
723 * "maximum" for fat_bits,
724 * switch over to next
725 */
726 if(Fs->fat_bits == 12 &&
727 (!may_change_cluster_size ||
728 Fs->cluster_size >= 8)) {
729 Fs->fat_bits = 16;
730 if(may_change_cluster_size)
731 Fs->cluster_size = 1;
732 continue;
733 }
734
735 if(Fs->fat_bits == 16 &&
736 (!may_change_cluster_size ||
737 Fs->cluster_size >= 64)) {
738 Fs->fat_bits = 32;
739 if(may_change_cluster_size)
740 Fs->cluster_size =
741 may_change_fat_len ? 8 : 1;
742 continue;
743 }
744 }
745
746 if(may_change_cluster_size && Fs->cluster_size < 128) {
747 /* Double cluster size, and try again */
748 Fs->cluster_size = 2 * Fs->cluster_size;
749 continue;
750 }
751
752 if(fit == 2 && may_change_fat_bits &&
753 may_change_root_size &&
754 Fs->fat_bits == 16) {
755 Fs->fat_bits=12;
756 may_pad=true;
757 continue;
758 }
759
760 /* Still too many clusters? */
761 return (fit == 2) ? -4 : -3;
762 }
763
764 if(getenv("MTOOLS_DEBUG_FAT") || getenv("MTOOLS_DEBUG_FAT_SUMMARY")) {
765 fprintf(stderr,
766 " FAT%d Cluster_size=%d %d clusters FAT_LEN=%d\n",
767 Fs->fat_bits,
768 Fs->cluster_size,
769 Fs->num_clus,
770 Fs->fat_len);
771 }
772 check_fs_params_and_set_fat(Fs, tot_sectors);
773 if(Fs->fat_bits == 32)
774 fat32_specific_init(Fs);
775 return 0;
776 }
777
initFsForFormat(Fs_t * Fs)778 void initFsForFormat(Fs_t *Fs)
779 {
780 memset(Fs, 0, sizeof(*Fs));
781 init_head(&Fs->head, &FsClass, NULL);
782
783 Fs->cluster_size = 0;
784 Fs->dir_len = 0;
785 Fs->fat_len = 0;
786 Fs->num_fat = 2;
787 Fs->backupBoot = 0;
788 }
789
setFsSectorSize(Fs_t * Fs,struct device * dev,uint16_t msize)790 void setFsSectorSize(Fs_t *Fs, struct device *dev, uint16_t msize) {
791 unsigned int j;
792 Fs->sector_size = 512;
793 if( !(dev->use_2m & 0x7f)) {
794 Fs->sector_size = (uint16_t) (128u << (dev->ssize & 0x7f));
795 }
796
797 SET_INT(Fs->sector_size, msize);
798 for(j = 0; j < 31; j++) {
799 if (Fs->sector_size == (unsigned int) (1 << j)) {
800 Fs->sectorShift = j;
801 break;
802 }
803 }
804 Fs->sectorMask = Fs->sector_size - 1;
805 }
806
old_dos_size_to_geom(size_t size,unsigned int * cyls,unsigned short * heads,unsigned short * sects)807 static int old_dos_size_to_geom(size_t size,
808 unsigned int *cyls,
809 unsigned short *heads,
810 unsigned short *sects)
811 {
812 struct OldDos_t *params = getOldDosBySize(size);
813 if(params != NULL) {
814 *cyls = params->tracks;
815 *heads = params->heads;
816 *sects = params->sectors;
817 return 0;
818 } else
819 return 1;
820 }
821
822 static void usage(int ret) NORETURN;
usage(int ret)823 static void usage(int ret)
824 {
825 fprintf(stderr,
826 "Mtools version %s, dated %s\n", mversion, mdate);
827 fprintf(stderr,
828 "Usage: %s [-V] [-t tracks] [-h heads] [-n sectors] "
829 "[-v label] [-1] [-4] [-8] [-f size] "
830 "[-N serialnumber] "
831 "[-k] [-B bootsector] [-r root_dir_len] [-L fat_len] "
832 "[-F] [-I fsVersion] [-C] [-c cluster_size] "
833 "[-H hidden_sectors] "
834 #ifdef USE_XDF
835 "[-X] "
836 #endif
837 "[-S hardsectorsize] [-M softsectorsize] [-3] "
838 "[-2 track0sectors] [-0 rate0] [-A rateany] [-a]"
839 "device\n", progname);
840 exit(ret);
841 }
842
843 void mformat(int argc, char **argv, int dummy UNUSEDP) NORETURN;
mformat(int argc,char ** argv,int dummy UNUSEDP)844 void mformat(int argc, char **argv, int dummy UNUSEDP)
845 {
846 int r; /* generic return value */
847 Fs_t *Fs;
848 unsigned int hs;
849 int hs_set;
850 unsigned int arguse_2m = 0;
851 uint8_t sectors0=18; /* number of sectors on track 0 */
852 int create = 0;
853 uint8_t rate_0, rate_any;
854 int mangled;
855 uint8_t argssize=0; /* sector size */
856 uint16_t msize=0;
857 int fat32 = 0;
858 struct label_blk_t *labelBlock;
859 size_t bootOffset;
860
861 #ifdef USE_XDF
862 unsigned int i;
863 int format_xdf = 0;
864 struct xdf_info info;
865 #endif
866 union bootsector boot;
867 char *bootSector=0;
868 int c;
869 int keepBoot = 0;
870 struct device used_dev;
871 unsigned int argtracks;
872 uint16_t argheads, argsectors;
873 uint32_t tot_sectors=0;
874 uint32_t blocksize;
875
876 char drive, name[EXPAND_BUF];
877
878 char label[VBUFSIZE];
879
880 dos_name_t shortlabel;
881 struct device *dev;
882 char errmsg[2100];
883
884 uint32_t serial;
885 int serial_set;
886 uint16_t fsVersion;
887 uint8_t mediaDesc=0;
888 bool haveMediaDesc=false;
889
890 mt_off_t maxSize;
891
892 int Atari = 0; /* should we add an Atari-style serial number ? */
893
894 char *endptr;
895
896 hs = hs_set = 0;
897 argtracks = 0;
898 argheads = 0;
899 argsectors = 0;
900 arguse_2m = 0;
901 argssize = 0x2;
902 label[0] = '\0';
903 serial_set = 0;
904 serial = 0;
905 fsVersion = 0;
906
907 Fs = New(Fs_t);
908 if (!Fs) {
909 fprintf(stderr, "Out of memory\n");
910 exit(1);
911 }
912 initFsForFormat(Fs);
913 if(getenv("MTOOLS_DIR_LEN")) {
914 Fs->dir_len = atou16(getenv("MTOOLS_DIR_LEN"));
915 if(Fs->dir_len <= 0)
916 Fs->dir_len=0;
917 }
918 if(getenv("MTOOLS_NFATS")) {
919 Fs->num_fat = atou8(getenv("MTOOLS_NFATS"));
920 if(Fs->num_fat <= 0)
921 Fs->num_fat=2;
922 }
923 rate_0 = mtools_rate_0;
924 rate_any = mtools_rate_any;
925
926 /* get command line options */
927 if(helpFlag(argc, argv))
928 usage(0);
929 while ((c = getopt(argc,argv,
930 "i:148f:t:n:v:qub"
931 "kK:R:B:r:L:I:FCc:Xh:s:T:l:N:H:M:S:2:30:Aad:m:"))!= EOF) {
932 errno = 0;
933 endptr = NULL;
934 switch (c) {
935 case 'i':
936 set_cmd_line_image(optarg);
937 break;
938
939 /* standard DOS flags */
940 case '1':
941 argheads = 1;
942 break;
943 case '4':
944 argsectors = 9;
945 argtracks = 40;
946 break;
947 case '8':
948 argsectors = 8;
949 argtracks = 40;
950 break;
951 case 'f':
952 r=old_dos_size_to_geom(atoul(optarg),
953 &argtracks, &argheads,
954 &argsectors);
955 if(r) {
956 fprintf(stderr,
957 "Bad size %s\n", optarg);
958 exit(1);
959 }
960 break;
961 case 't':
962 argtracks = atou16(optarg);
963 break;
964
965 case 'T':
966 tot_sectors = parseSize(optarg);
967 break;
968
969 case 'n': /*non-standard*/
970 case 's':
971 argsectors = atou16(optarg);
972 break;
973
974 case 'l': /* non-standard */
975 case 'v':
976 strncpy(label, optarg, VBUFSIZE-1);
977 label[VBUFSIZE-1] = '\0';
978 break;
979
980 /* flags supported by Dos but not mtools */
981 case 'q':
982 case 'u':
983 case 'b':
984 /*case 's': leave this for compatibility */
985 fprintf(stderr,
986 "Flag %c not supported by mtools\n",c);
987 exit(1);
988
989
990
991 /* flags added by mtools */
992 case 'F':
993 fat32 = 1;
994 break;
995
996
997 case 'S':
998 argssize = atou8(optarg) | 0x80;
999 if(argssize < 0x80)
1000 usage(1);
1001 if(argssize >= 0x87) {
1002 fprintf(stderr, "argssize must be less than 6\n");
1003 usage(1);
1004 }
1005 break;
1006
1007 #ifdef USE_XDF
1008 case 'X':
1009 format_xdf = 1;
1010 break;
1011 #endif
1012
1013 case '2':
1014 arguse_2m = 0xff;
1015 sectors0 = atou8(optarg);
1016 break;
1017 case '3':
1018 arguse_2m = 0x80;
1019 break;
1020
1021 case '0': /* rate on track 0 */
1022 rate_0 = atou8(optarg);
1023 break;
1024 case 'A': /* rate on other tracks */
1025 rate_any = atou8(optarg);
1026 break;
1027
1028 case 'M':
1029 msize = atou16(optarg);
1030 if(msize != 512 &&
1031 msize != 1024 &&
1032 msize != 2048 &&
1033 msize != 4096) {
1034 fprintf(stderr, "Only sector sizes of 512, 1024, 2048 or 4096 bytes are allowed\n");
1035 usage(1);
1036 }
1037 break;
1038
1039 case 'N':
1040 serial = strtou32(optarg,&endptr,16);
1041 serial_set = 1;
1042 break;
1043 case 'a': /* Atari style serial number */
1044 Atari = 1;
1045 break;
1046
1047 case 'C':
1048 create = O_CREAT | O_TRUNC;
1049 break;
1050
1051 case 'H':
1052 hs = atoui(optarg);
1053 hs_set = 1;
1054 break;
1055
1056 case 'I':
1057 fsVersion = strtou16(optarg,&endptr,0);
1058 break;
1059
1060 case 'c':
1061 Fs->cluster_size = atou8(optarg);
1062 break;
1063
1064 case 'r':
1065 Fs->dir_len = strtou16(optarg,&endptr,0);
1066 break;
1067 case 'L':
1068 Fs->fat_len = strtoui(optarg,&endptr,0);
1069 break;
1070
1071 case 'B':
1072 bootSector = optarg;
1073 break;
1074 case 'k':
1075 keepBoot = 1;
1076 break;
1077 case 'K':
1078 Fs->backupBoot = atou16(optarg);
1079 if(Fs->backupBoot < 2) {
1080 fprintf(stderr, "Backupboot must be greater than 2\n");
1081 exit(1);
1082 }
1083 break;
1084 case 'R':
1085 Fs->fat_start = atou8(optarg);
1086 break;
1087 case 'h':
1088 argheads = atou16(optarg);
1089 break;
1090 case 'd':
1091 Fs->num_fat = atou8(optarg);
1092 break;
1093 case 'm':
1094 mediaDesc = strtou8(optarg,&endptr,0);
1095 if(*endptr)
1096 mediaDesc = strtou8(optarg,&endptr,16);
1097 if(optarg == endptr || *endptr) {
1098 fprintf(stderr, "Bad mediadesc %s\n", optarg);
1099 exit(1);
1100 }
1101 haveMediaDesc=true;
1102 break;
1103 default:
1104 usage(1);
1105 }
1106 check_number_parse_errno((char)c, optarg, endptr);
1107 }
1108
1109 if (argc - optind > 1)
1110 usage(1);
1111 if(argc - optind == 1) {
1112 if(!argv[optind][0] || argv[optind][1] != ':')
1113 usage(1);
1114 drive = ch_toupper(argv[argc -1][0]);
1115 } else {
1116 drive = get_default_drive();
1117 if(drive != ':') {
1118 /* Use default drive only if it is ":" (image file), as else
1119 it would be too dangerous... */
1120 fprintf(stderr, "Drive letter missing\n");
1121 exit(1);
1122 }
1123 }
1124
1125 if(argtracks && tot_sectors) {
1126 fprintf(stderr, "Only one of -t or -T may be specified\n");
1127 usage(1);
1128 }
1129
1130 #ifdef USE_XDF
1131 if(create && format_xdf) {
1132 fprintf(stderr,"Create and XDF can't be used together\n");
1133 exit(1);
1134 }
1135 #endif
1136
1137 /* check out a drive whose letter and parameters match */
1138 sprintf(errmsg, "Drive '%c:' not supported", drive);
1139 blocksize = 0;
1140 for(dev=devices;dev->drive;dev++) {
1141 FREE(&(Fs->head.Next));
1142 /* drive letter */
1143 if (dev->drive != drive)
1144 continue;
1145 used_dev = *dev;
1146
1147 SET_INT(used_dev.tracks, argtracks);
1148 SET_INT(used_dev.heads, argheads);
1149 SET_INT(used_dev.sectors, argsectors);
1150 SET_INT(used_dev.use_2m, arguse_2m);
1151 SET_INT(used_dev.ssize, argssize);
1152 if(hs_set)
1153 used_dev.hidden = hs;
1154
1155 expand(dev->name, name);
1156 #ifdef USING_NEW_VOLD
1157 strcpy(name, getVoldName(dev, name));
1158 #endif
1159
1160 #ifdef USE_XDF
1161 if(format_xdf)
1162 used_dev.misc_flags |= USE_XDF_FLAG;
1163 info.FatSize=0;
1164 #endif
1165 if(tot_sectors)
1166 used_dev.tot_sectors = tot_sectors;
1167 Fs->head.Next = OpenImage(&used_dev, dev, name,
1168 O_RDWR|create, errmsg,
1169 ALWAYS_GET_GEOMETRY,
1170 O_RDWR,
1171 &maxSize, NULL,
1172 #ifdef USE_XDF
1173 &info
1174 #else
1175 NULL
1176 #endif
1177 );
1178
1179 #ifdef USE_XDF
1180 if(Fs->head.Next && info.FatSize) {
1181 if(!Fs->fat_len)
1182 Fs->fat_len = info.FatSize;
1183 if(!Fs->dir_len)
1184 Fs->dir_len = info.RootDirSize;
1185 }
1186 #endif
1187
1188 if (!Fs->head.Next)
1189 continue;
1190
1191 if(tot_sectors)
1192 used_dev.tot_sectors = tot_sectors;
1193
1194 setFsSectorSize(Fs, &used_dev, msize);
1195
1196 if(!used_dev.blocksize || used_dev.blocksize < Fs->sector_size)
1197 blocksize = Fs->sector_size;
1198 else
1199 blocksize = used_dev.blocksize;
1200
1201 if(blocksize > MAX_SECTOR)
1202 blocksize = MAX_SECTOR;
1203
1204 if(chs_to_totsectors(&used_dev, errmsg) < 0 ||
1205 check_if_sectors_fit(dev->tot_sectors, maxSize, blocksize,
1206 errmsg) < 0) {
1207 FREE(&Fs->head.Next);
1208 continue;
1209 }
1210
1211 if(!tot_sectors)
1212 tot_sectors = used_dev.tot_sectors;
1213
1214 /* do a "test" read */
1215 if (!create &&
1216 PREADS(Fs->head.Next,
1217 &boot.characters, 0, Fs->sector_size) !=
1218 (signed int) Fs->sector_size) {
1219 #ifdef HAVE_SNPRINTF
1220 snprintf(errmsg, sizeof(errmsg)-1,
1221 "Error reading from '%s', wrong parameters?",
1222 name);
1223 #else
1224 sprintf(errmsg,
1225 "Error reading from '%s', wrong parameters?",
1226 name);
1227 #endif
1228 FREE(&Fs->head.Next);
1229 continue;
1230 }
1231 break;
1232 }
1233
1234 /* print error msg if needed */
1235 if ( dev->drive == 0 ){
1236 FREE(&Fs->head.Next);
1237 fprintf(stderr,"%s: %s\n", argv[0],errmsg);
1238 exit(1);
1239 }
1240
1241 if(tot_sectors == 0) {
1242 fprintf(stderr, "Number of sectors not known\n");
1243 exit(1);
1244 }
1245
1246 /* create the image file if needed */
1247 if (create) {
1248 PWRITES(Fs->head.Next, &boot.characters,
1249 sectorsToBytes(Fs, tot_sectors-1),
1250 Fs->sector_size);
1251 }
1252
1253 /* the boot sector */
1254 if(bootSector) {
1255 int fd;
1256 ssize_t ret;
1257
1258 fd = open(bootSector, O_RDONLY | O_BINARY | O_LARGEFILE);
1259 if(fd < 0) {
1260 perror("open boot sector");
1261 exit(1);
1262 }
1263 ret=read(fd, &boot.bytes, blocksize);
1264 if(ret < 0 || (size_t) ret < blocksize) {
1265 perror("short read on boot sector");
1266 exit(1);
1267 }
1268 keepBoot = 1;
1269 close(fd);
1270 }
1271 if(!keepBoot && !(used_dev.use_2m & 0x7f))
1272 memset(boot.characters, '\0', Fs->sector_size);
1273
1274 Fs->head.Next = buf_init(Fs->head.Next,
1275 blocksize * used_dev.heads * used_dev.sectors,
1276 blocksize * used_dev.heads * used_dev.sectors,
1277 blocksize);
1278
1279 boot.boot.nfat = Fs->num_fat;
1280 if(!keepBoot)
1281 set_word(&boot.bytes[510], 0xaa55);
1282
1283 /* Initialize the remaining parameters */
1284 set_word(boot.boot.nsect, used_dev.sectors);
1285 set_word(boot.boot.nheads, used_dev.heads);
1286
1287 switch(calc_fs_parameters(&used_dev, fat32, tot_sectors, Fs,
1288 &boot.boot.descr)) {
1289 case -1:
1290 fprintf(stderr, "Too few sectors\n");
1291 exit(1);
1292 case -2:
1293 fprintf(stderr, "Too few clusters for %d bit fat\n",
1294 Fs->fat_bits);
1295 exit(1);
1296 case -3:
1297 fprintf(stderr, "Too many clusters for %d bit FAT\n",
1298 Fs->fat_bits);
1299 exit(1);
1300 case -4:
1301 fprintf(stderr, "Too many clusters for fat length %d\n",
1302 Fs->fat_len);
1303 exit(1);
1304 }
1305
1306 if(!keepBoot && !(used_dev.use_2m & 0x7f)) {
1307 if(!used_dev.partition) {
1308 /* install fake partition table pointing to itself */
1309 struct partition *partTable=(struct partition *)
1310 (&boot.bytes[0x1ae]);
1311 setBeginEnd(&partTable[1], 0,
1312 used_dev.heads * used_dev.sectors *
1313 used_dev.tracks,
1314 (uint8_t) used_dev.heads,
1315 (uint8_t) used_dev.sectors, 1, 0,
1316 Fs->fat_bits);
1317 }
1318 }
1319
1320 if(Fs->fat_bits == 32) {
1321 set_word(boot.boot.fatlen, 0);
1322 set_dword(boot.boot.ext.fat32.bigFat, Fs->fat_len);
1323
1324 Fs->clus_start = Fs->num_fat * Fs->fat_len + Fs->fat_start;
1325
1326 /* extension flags: mirror fats, and use #0 as primary */
1327 set_word(boot.boot.ext.fat32.extFlags,0);
1328
1329 /* fs version. What should go here? */
1330 set_word(boot.boot.ext.fat32.fsVersion,fsVersion);
1331
1332 /* root directory */
1333 set_dword(boot.boot.ext.fat32.rootCluster, Fs->rootCluster = 2);
1334
1335 /* info sector */
1336 set_word(boot.boot.ext.fat32.infoSector, Fs->infoSectorLoc = 1);
1337 Fs->infoSectorLoc = 1;
1338
1339 /* no backup boot sector */
1340 set_word(boot.boot.ext.fat32.backupBoot, Fs->backupBoot);
1341
1342 labelBlock = & boot.boot.ext.fat32.labelBlock;
1343 } else {
1344 set_word(boot.boot.fatlen, (uint16_t) Fs->fat_len);
1345 Fs->dir_start = Fs->num_fat * Fs->fat_len + Fs->fat_start;
1346 Fs->clus_start = Fs->dir_start + Fs->dir_len;
1347 labelBlock = & boot.boot.ext.old.labelBlock;
1348 }
1349
1350 /* Set the codepage */
1351 Fs->cp = cp_open(used_dev.codepage);
1352 if(Fs->cp == NULL)
1353 exit(1);
1354
1355 if (!keepBoot)
1356 /* only zero out physdrive if we don't have a template
1357 * bootsector */
1358 labelBlock->physdrive = 0x00;
1359 labelBlock->reserved = 0;
1360 labelBlock->dos4 = 0x29;
1361
1362 if (!serial_set || Atari)
1363 init_random();
1364 if (!serial_set)
1365 serial=(uint32_t) random();
1366 set_dword(labelBlock->serial, serial);
1367 label_name_pc(GET_DOSCONVERT((Stream_t *)Fs),
1368 label[0] ? label : "NO NAME ", 0,
1369 &mangled, &shortlabel);
1370 strncpy(labelBlock->label, shortlabel.base, 8);
1371 strncpy(labelBlock->label+8, shortlabel.ext, 3);
1372 sprintf(labelBlock->fat_type, "FAT%2.2d ", Fs->fat_bits);
1373 labelBlock->fat_type[7] = ' ';
1374
1375 set_word(boot.boot.secsiz, Fs->sector_size);
1376 boot.boot.clsiz = (unsigned char) Fs->cluster_size;
1377 set_word(boot.boot.nrsvsect, Fs->fat_start);
1378
1379 bootOffset = init_geometry_boot(&boot, &used_dev, sectors0,
1380 rate_0, rate_any,
1381 &tot_sectors, keepBoot);
1382 if(!bootOffset) {
1383 bootOffset = ptrdiff((char *) labelBlock, (char*)boot.bytes) +
1384 sizeof(struct label_blk_t);
1385 }
1386 if(Atari) {
1387 boot.boot.banner[4] = 0;
1388 boot.boot.banner[5] = (char) random();
1389 boot.boot.banner[6] = (char) random();
1390 boot.boot.banner[7] = (char) random();
1391 }
1392
1393 if(!keepBoot && bootOffset <= UINT16_MAX)
1394 inst_boot_prg(&boot, (uint16_t)bootOffset);
1395 /* Mimic 3.8 behavior, else 2m disk do not work (???)
1396 * luferbu@fluidsignal.com (Luis Bustamante), Fri, 14 Jun 2002
1397 */
1398 if(used_dev.use_2m & 0x7f) {
1399 boot.boot.jump[0] = 0xeb;
1400 boot.boot.jump[1] = 0x80;
1401 boot.boot.jump[2] = 0x90;
1402 }
1403 if(used_dev.use_2m & 0x7f)
1404 Fs->num_fat = 1;
1405 if(haveMediaDesc)
1406 boot.boot.descr=mediaDesc;
1407 Fs->lastFatSectorNr = 0;
1408 Fs->lastFatSectorData = 0;
1409 zero_fat(Fs, boot.boot.descr);
1410 Fs->freeSpace = Fs->num_clus;
1411 Fs->last = 2;
1412
1413 #ifdef USE_XDF
1414 if(used_dev.misc_flags & USE_XDF_FLAG)
1415 for(i=0;
1416 i < (info.BadSectors+Fs->cluster_size-1)/Fs->cluster_size;
1417 i++)
1418 fatEncode(Fs, i+2, 0xfff7);
1419 #endif
1420
1421 format_root(Fs, label, &boot);
1422 if(PWRITES((Stream_t *)Fs, boot.characters, 0, Fs->sector_size) < 0) {
1423 fprintf(stderr, "Error writing boot sector\n");
1424 exit(1);
1425 }
1426
1427 if(Fs->fat_bits == 32 && WORD_S(ext.fat32.backupBoot) != MAX16) {
1428 if(PWRITES((Stream_t *)Fs, boot.characters,
1429 sectorsToBytes(Fs, WORD_S(ext.fat32.backupBoot)),
1430 Fs->sector_size) < 0) {
1431 fprintf(stderr, "Error writing backup boot sector\n");
1432 exit(1);
1433 }
1434 }
1435
1436 FREE((Stream_t **)&Fs);
1437 #ifdef USE_XDF
1438 if(format_xdf && isatty(0) && !getenv("MTOOLS_USE_XDF"))
1439 fprintf(stderr,
1440 "Note:\n"
1441 "Remember to set the \"MTOOLS_USE_XDF\" environmental\n"
1442 "variable before accessing this disk\n\n"
1443 "Bourne shell syntax (sh, ash, bash, ksh, zsh etc):\n"
1444 " export MTOOLS_USE_XDF=1\n\n"
1445 "C shell syntax (csh and tcsh):\n"
1446 " setenv MTOOLS_USE_XDF 1\n" );
1447 #endif
1448 exit(0);
1449 }
1450