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 "fsP.h"
28 #include "file.h"
29 #include "plain_io.h"
30 #include "floppyd_io.h"
31 #include "nameclash.h"
32 #include "buffer.h"
33 #ifdef HAVE_ASSERT_H
34 #include <assert.h>
35 #endif
36 #ifdef USE_XDF
37 #include "xdf_io.h"
38 #endif
39 #include "partition.h"
40 #include "file_name.h"
41
42 #ifndef abs
43 #define abs(x) ((x)>0?(x):-(x))
44 #endif
45
46 #ifdef OS_linux
47 #include "linux/hdreg.h"
48
49 #define _LINUX_STRING_H_
50 #define kdev_t int
51 #include "linux/fs.h"
52 #undef _LINUX_STRING_H_
53
54 #endif
55
56
init_geometry_boot(union bootsector * boot,struct device * dev,uint8_t sectors0,uint8_t rate_0,uint8_t rate_any,unsigned long * tot_sectors,int keepBoot)57 static int init_geometry_boot(union bootsector *boot, struct device *dev,
58 uint8_t sectors0,
59 uint8_t rate_0, uint8_t rate_any,
60 unsigned long *tot_sectors, int keepBoot)
61 {
62 int nb_renum;
63 int sector2;
64 int sum;
65
66 set_word(boot->boot.nsect, dev->sectors);
67 set_word(boot->boot.nheads, dev->heads);
68
69 #ifdef HAVE_ASSERT_H
70 assert(*tot_sectors != 0);
71 #endif
72
73 if (*tot_sectors <= UINT16_MAX){
74 set_word(boot->boot.psect, (uint16_t) *tot_sectors);
75 set_dword(boot->boot.bigsect, 0);
76 } else if(*tot_sectors <= UINT32_MAX){
77 set_word(boot->boot.psect, 0);
78 set_dword(boot->boot.bigsect, (uint32_t) *tot_sectors);
79 } else {
80 fprintf(stderr, "Too many sectors %ld\n", *tot_sectors);
81 exit(1);
82 }
83
84 if (dev->use_2m & 0x7f){
85 int bootOffset;
86 uint8_t j;
87 uint8_t size2;
88 uint16_t i;
89 strncpy(boot->boot.banner, "2M-STV04", 8);
90 boot->boot.ext.old.res_2m = 0;
91 boot->boot.ext.old.fmt_2mf = 6;
92 if ( dev->sectors % ( ((1 << dev->ssize) + 3) >> 2 ))
93 boot->boot.ext.old.wt = 1;
94 else
95 boot->boot.ext.old.wt = 0;
96 boot->boot.ext.old.rate_0= rate_0;
97 boot->boot.ext.old.rate_any= rate_any;
98 if (boot->boot.ext.old.rate_any== 2 )
99 boot->boot.ext.old.rate_any= 1;
100 i=76;
101
102 /* Infp0 */
103 set_word(boot->boot.ext.old.Infp0, i);
104 boot->bytes[i++] = sectors0;
105 boot->bytes[i++] = 108;
106 for(j=1; j<= sectors0; j++)
107 boot->bytes[i++] = j;
108
109 set_word(boot->boot.ext.old.InfpX, i);
110
111 boot->bytes[i++] = 64;
112 boot->bytes[i++] = 3;
113 nb_renum = i++;
114 sector2 = dev->sectors;
115 size2 = dev->ssize;
116 j=1;
117 while( sector2 ){
118 while ( sector2 < (1 << size2) >> 2 )
119 size2--;
120 boot->bytes[i++] = 128 + j;
121 boot->bytes[i++] = j++;
122 boot->bytes[i++] = size2;
123 sector2 -= (1 << size2) >> 2;
124 }
125 boot->bytes[nb_renum] = ( i - nb_renum - 1 ) / 3;
126
127 set_word(boot->boot.ext.old.InfTm, i);
128
129 sector2 = dev->sectors;
130 size2= dev->ssize;
131 while(sector2){
132 while ( sector2 < 1 << ( size2 - 2) )
133 size2--;
134 boot->bytes[i++] = size2;
135 sector2 -= 1 << (size2 - 2 );
136 }
137
138 set_word(boot->boot.ext.old.BootP,i);
139 bootOffset = i;
140
141 /* checksum */
142 for (sum=0, j=64; j<i; j++)
143 sum += boot->bytes[j];/* checksum */
144 boot->boot.ext.old.CheckSum=-sum;
145 return bootOffset;
146 } else {
147 if(!keepBoot) {
148 boot->boot.jump[0] = 0xeb;
149 boot->boot.jump[1] = 0;
150 boot->boot.jump[2] = 0x90;
151 strncpy(boot->boot.banner, mformat_banner, 8);
152 /* It looks like some versions of DOS are
153 * rather picky about this, and assume default
154 * parameters without this, ignoring any
155 * indication about cluster size et al. */
156 }
157 return 0;
158 }
159 }
160
161
comp_fat_bits(Fs_t * Fs,int estimate,unsigned long tot_sectors,int fat32)162 static int comp_fat_bits(Fs_t *Fs, int estimate,
163 unsigned long tot_sectors, int fat32)
164 {
165 int needed_fat_bits;
166
167 needed_fat_bits = 12;
168
169 #define MAX_DISK_SIZE(bits,clusters) \
170 TOTAL_DISK_SIZE((bits), Fs->sector_size, (clusters), \
171 Fs->num_fat, MAX_BYTES_PER_CLUSTER/Fs->sector_size)
172
173 if(tot_sectors > MAX_DISK_SIZE(12, FAT12-1))
174 needed_fat_bits = 16;
175 if(fat32 || tot_sectors > MAX_DISK_SIZE(16, FAT16-1))
176 needed_fat_bits = 32;
177
178 #undef MAX_DISK_SIZE
179
180 if(abs(estimate) && abs(estimate) < needed_fat_bits) {
181 if(fat32) {
182 fprintf(stderr,
183 "Contradiction between FAT size on command line and FAT size in conf file\n");
184 exit(1);
185 }
186 fprintf(stderr,
187 "Device too big for a %d bit FAT\n",
188 estimate);
189 exit(1);
190 }
191
192 if(!estimate) {
193 unsigned int min_fat16_size;
194
195 if(needed_fat_bits > 12)
196 return needed_fat_bits;
197 min_fat16_size = DISK_SIZE(16, Fs->sector_size, FAT12,
198 Fs->num_fat, 1);
199 if(tot_sectors < min_fat16_size)
200 return 12;
201 else if(Fs->cluster_size == 0 &&
202 tot_sectors >= 2* min_fat16_size)
203 return 16; /* heuristics */
204 }
205
206 return estimate;
207 }
208
209
210 /*
211 * According to Microsoft "Hardware White Paper", "Microsoft
212 * Extensible Formware Initiative", "FAT32 File System Specification",
213 * Version 1.03, December 6, 2000:
214 * If (CountofClusters < 4085) { // 0x0ff5
215 * // Volume is FAT12
216 * } else if (CountofClusters < 65525) { // 0xfff5
217 * // Volume is FAT16
218 * } else {
219 * //Volume is FAT32
220 * }
221 *
222 * This document can be found at the following URL:
223 * https://staff.washington.edu/dittrich/misc/fatgen103.pdf
224 * The relevant passus is on page 15.
225 *
226 * Actually, experimentations with Windows NT 4 show that the
227 * cutoff is 4087 rather than 4085... This is Microsoft after all.
228 * Not sure what the other Microsoft OS'es do though...
229 */
calc_fat_bits2(Fs_t * Fs,unsigned long tot_sectors,int fat_bits,int may_change_cluster_size,int may_change_root_size)230 static void calc_fat_bits2(Fs_t *Fs, unsigned long tot_sectors, int fat_bits,
231 int may_change_cluster_size,
232 int may_change_root_size)
233 {
234 unsigned long rem_sect;
235
236 /*
237 * the "remaining sectors" after directory and boot
238 * hasve been accounted for.
239 */
240 rem_sect = tot_sectors - Fs->dir_len - Fs->fat_start;
241 switch(abs(fat_bits)) {
242 case 0:
243
244 #define MY_DISK_SIZE(bits,clusters) \
245 DISK_SIZE( (bits), Fs->sector_size, (clusters), \
246 Fs->num_fat, Fs->cluster_size)
247
248 if(rem_sect >= MY_DISK_SIZE(16, FAT12+2))
249 /* big enough for FAT16
250 * We take a margin of 2, because NT4
251 * misbehaves, and starts considering a disk
252 * as FAT16 only if it is larger than 4086
253 * sectors, rather than 4084 as it should
254 */
255 set_fat16(Fs);
256 else if(rem_sect <= MY_DISK_SIZE(12, FAT12-1))
257 /* small enough for FAT12 */
258 set_fat12(Fs);
259 else {
260 /* "between two chairs",
261 * augment cluster size, and
262 * settle it */
263 if(may_change_cluster_size &&
264 Fs->cluster_size * Fs->sector_size * 2
265 <= MAX_BYTES_PER_CLUSTER)
266 Fs->cluster_size <<= 1;
267 else if(may_change_root_size) {
268 Fs->dir_len +=
269 rem_sect - MY_DISK_SIZE(12, FAT12-1);
270 }
271 set_fat12(Fs);
272 }
273 break;
274 #undef MY_DISK_SIZE
275
276 case 12:
277 set_fat12(Fs);
278 break;
279 case 16:
280 set_fat16(Fs);
281 break;
282 case 32:
283 set_fat32(Fs);
284 break;
285 }
286 }
287
format_root(Fs_t * Fs,char * label,union bootsector * boot)288 static __inline__ void format_root(Fs_t *Fs, char *label, union bootsector *boot)
289 {
290 Stream_t *RootDir;
291 char *buf;
292 unsigned int i;
293 struct ClashHandling_t ch;
294 unsigned int dirlen;
295
296 init_clash_handling(&ch);
297 ch.name_converter = label_name_uc;
298 ch.ignore_entry = -2;
299
300 buf = safe_malloc(Fs->sector_size);
301 RootDir = OpenRoot((Stream_t *)Fs);
302 if(!RootDir){
303 fprintf(stderr,"Could not open root directory\n");
304 exit(1);
305 }
306
307 memset(buf, '\0', Fs->sector_size);
308
309 if(Fs->fat_bits == 32) {
310 /* on a FAT32 system, we only write one sector,
311 * as the directory can be extended at will...*/
312 dirlen = Fs->cluster_size;
313 fatAllocate(Fs, Fs->rootCluster, Fs->end_fat);
314 } else
315 dirlen = Fs->dir_len;
316 for (i = 0; i < dirlen; i++)
317 WRITES(RootDir, buf, sectorsToBytes((Stream_t*)Fs, i),
318 Fs->sector_size);
319
320 ch.ignore_entry = 1;
321 if(label[0])
322 mwrite_one(RootDir,label, 0, labelit, NULL,&ch);
323
324 FREE(&RootDir);
325 if(Fs->fat_bits == 32)
326 set_word(boot->boot.dirents, 0);
327 else
328 set_word(boot->boot.dirents, Fs->dir_len * (Fs->sector_size / 32));
329 free(buf);
330 }
331
332
333 #ifdef USE_XDF
xdf_calc_fat_size(Fs_t * Fs,unsigned long tot_sectors,int fat_bits)334 static void xdf_calc_fat_size(Fs_t *Fs, unsigned long tot_sectors,
335 int fat_bits)
336 {
337 unsigned int rem_sect;
338
339 rem_sect = tot_sectors - Fs->dir_len - Fs->fat_start - 2 * Fs->fat_len;
340
341 if(Fs->fat_len) {
342 /* an XDF disk, we know the fat_size and have to find
343 * out the rest. We start with a cluster size of 1 and
344 * keep doubling until everything fits into the
345 * FAT. This will occur eventually, as our FAT has a
346 * minimal size of 1 */
347 for(Fs->cluster_size = 1; 1 ; Fs->cluster_size <<= 1) {
348 Fs->num_clus = rem_sect / Fs->cluster_size;
349 if(abs(fat_bits) == 16 || Fs->num_clus >= FAT12)
350 set_fat16(Fs);
351 else
352 set_fat12(Fs);
353 if (Fs->fat_len >= NEEDED_FAT_SIZE(Fs))
354 return;
355 }
356 }
357 fprintf(stderr,"Internal error while calculating Xdf fat size\n");
358 exit(1);
359 }
360 #endif
361
calc_fat_size(Fs_t * Fs,unsigned long tot_sectors)362 static void calc_fat_size(Fs_t *Fs, unsigned long tot_sectors)
363 {
364 unsigned long rem_sect;
365 unsigned long real_rem_sect;
366 unsigned long numerator;
367 unsigned long denominator;
368 unsigned int fat_nybbles;
369 unsigned int slack;
370 int printGrowMsg=1; /* Should we print "growing FAT" messages ?*/
371
372 #ifdef DEBUG
373 fprintf(stderr, "Fat start=%d\n", Fs->fat_start);
374 fprintf(stderr, "tot_sectors=%lu\n", tot_sectors);
375 fprintf(stderr, "dir_len=%d\n", Fs->dir_len);
376 #endif
377 real_rem_sect = rem_sect = tot_sectors - Fs->dir_len - Fs->fat_start;
378
379 /* Cheat a little bit to address the _really_ common case of
380 odd number of remaining sectors while both nfat and cluster size
381 are even... */
382 if(rem_sect %2 == 1 &&
383 Fs->num_fat %2 == 0 &&
384 Fs->cluster_size %2 == 0)
385 rem_sect--;
386
387 #ifdef DEBUG
388 fprintf(stderr, "Rem sect=%lu\n", rem_sect);
389 #endif
390
391 if(Fs->fat_bits == 0) {
392 fprintf(stderr, "Weird, fat bits = 0\n");
393 exit(1);
394 }
395
396
397 /* See fat_size_calculation.tex or
398 (http://ftp.gnu.org/software/mtools/manual/fat_size_calculation.pdf)
399 for an explantation about why the stuff below works...
400 */
401
402 fat_nybbles = Fs->fat_bits / 4;
403 numerator = rem_sect+2*Fs->cluster_size;
404 denominator =
405 Fs->cluster_size * Fs->sector_size * 2 +
406 Fs->num_fat * fat_nybbles;
407
408 if(fat_nybbles == 3)
409 numerator *= fat_nybbles;
410 else
411 /* Avoid numerical overflows, divide the denominator
412 * rather than multiplying the numerator */
413 denominator = denominator / fat_nybbles;
414
415 #ifdef DEBUG
416 fprintf(stderr, "Numerator=%lu denominator=%lu\n",
417 numerator, denominator);
418 #endif
419
420 Fs->fat_len = (numerator-1)/denominator+1;
421 Fs->num_clus = (rem_sect-(Fs->fat_len*Fs->num_fat))/Fs->cluster_size;
422
423 /* Apply upper bounds for FAT bits */
424 if(Fs->fat_bits == 16 && Fs->num_clus >= FAT16)
425 Fs->num_clus = FAT16-1;
426 if(Fs->fat_bits == 12 && Fs->num_clus >= FAT12)
427 Fs->num_clus = FAT12-1;
428
429 /* A safety, if above math is correct, this should not be happen...*/
430 if(Fs->num_clus > (Fs->fat_len * Fs->sector_size * 2 /
431 fat_nybbles - 2)) {
432 fprintf(stderr,
433 "Fat size miscalculation, shrinking num_clus from %d ",
434 Fs->num_clus);
435 Fs->num_clus = (Fs->fat_len * Fs->sector_size * 2 /
436 fat_nybbles - 2);
437 fprintf(stderr, " to %d\n", Fs->num_clus);
438 }
439 #ifdef DEBUG
440 fprintf(stderr, "Num_clus=%d fat_len=%d nybbles=%d\n",
441 Fs->num_clus, Fs->fat_len, fat_nybbles);
442 #endif
443
444 if ( Fs->num_clus < FAT16 && Fs->fat_bits > 16 ){
445 fprintf(stderr,"Too few clusters for this fat size."
446 " Please choose a 16-bit fat in your /usr/local/etc/mtools.conf"
447 " or .mtoolsrc file\n");
448 exit(1);
449 }
450
451 /* As the number of clusters is specified nowhere in the boot sector,
452 * it will be calculated by removing everything else from total number
453 * of sectors. This means that if we reduced the number of clusters
454 * above, we will have to grow the FAT in order to take up any excess
455 * sectors... */
456 #ifdef HAVE_ASSERT_H
457 assert(rem_sect >= Fs->num_clus * Fs->cluster_size +
458 Fs->fat_len * Fs->num_fat);
459 #endif
460 slack = rem_sect -
461 Fs->num_clus * Fs->cluster_size -
462 Fs->fat_len * Fs->num_fat;
463 if(slack >= Fs->cluster_size) {
464 /* This can happen under two circumstances:
465 1. We had to reduce num_clus because we reached maximum
466 number of cluster for FAT12 or FAT16
467 */
468 if(printGrowMsg) {
469 fprintf(stderr, "Slack=%d\n", slack);
470 fprintf(stderr, "Growing fat size from %d",
471 Fs->fat_len);
472 }
473 Fs->fat_len +=
474 (slack - Fs->cluster_size) / Fs->num_fat + 1;
475 if(printGrowMsg) {
476 fprintf(stderr,
477 " to %d in order to take up excess cluster area\n",
478 Fs->fat_len);
479 }
480 Fs->num_clus = (rem_sect-(Fs->fat_len*Fs->num_fat))/
481 Fs->cluster_size;
482
483 }
484
485 #ifdef HAVE_ASSERT_H
486 /* Fat must be big enough for all clusters */
487 assert( ((Fs->num_clus+2) * fat_nybbles) <=
488 (Fs->fat_len*Fs->sector_size*2));
489
490 /* num_clus must be big enough to cover rest of disk, or else further
491 * users of the filesystem will assume a bigger num_clus, which might
492 * be too big for fat_len */
493 assert(Fs->num_clus ==
494 (real_rem_sect - Fs->num_fat * Fs->fat_len) / Fs->cluster_size);
495 #endif
496 }
497
498
499 static unsigned char bootprog[]=
500 {0xfa, 0x31, 0xc0, 0x8e, 0xd8, 0x8e, 0xc0, 0xfc, 0xb9, 0x00, 0x01,
501 0xbe, 0x00, 0x7c, 0xbf, 0x00, 0x80, 0xf3, 0xa5, 0xea, 0x00, 0x00,
502 0x00, 0x08, 0xb8, 0x01, 0x02, 0xbb, 0x00, 0x7c, 0xba, 0x80, 0x00,
503 0xb9, 0x01, 0x00, 0xcd, 0x13, 0x72, 0x05, 0xea, 0x00, 0x7c, 0x00,
504 0x00, 0xcd, 0x19};
505
inst_boot_prg(union bootsector * boot,int offset)506 static __inline__ void inst_boot_prg(union bootsector *boot, int offset)
507 {
508 memcpy((char *) boot->boot.jump + offset,
509 (char *) bootprog, sizeof(bootprog) /sizeof(bootprog[0]));
510 if(offset - 2 < 0x80) {
511 /* short jump */
512 boot->boot.jump[0] = 0xeb;
513 boot->boot.jump[1] = offset -2;
514 boot->boot.jump[2] = 0x90;
515 } else {
516 /* long jump, if offset is too large */
517 boot->boot.jump[0] = 0xe9;
518 boot->boot.jump[1] = offset -3;
519 boot->boot.jump[2] = 0x00;
520 }
521 set_word(boot->boot.jump + offset + 20, offset + 24);
522 }
523
calc_cluster_size(struct Fs_t * Fs,unsigned long tot_sectors,int fat_bits)524 static void calc_cluster_size(struct Fs_t *Fs, unsigned long tot_sectors,
525 int fat_bits)
526
527 {
528 unsigned int max_clusters; /* maximal possible number of sectors for
529 * this FAT entry length (12/16/32) */
530 unsigned int max_fat_size; /* maximal size of the FAT for this FAT
531 * entry length (12/16/32) */
532 unsigned int rem_sect; /* remaining sectors after we accounted for
533 * the root directory and boot sector(s) */
534
535 switch(abs(fat_bits)) {
536 case 12:
537 max_clusters = FAT12-1;
538 max_fat_size = Fs->num_fat *
539 FAT_SIZE(12, Fs->sector_size, max_clusters);
540 break;
541 case 16:
542 case 0: /* still hesititating between 12 and 16 */
543 max_clusters = FAT16-1;
544 max_fat_size = Fs->num_fat *
545 FAT_SIZE(16, Fs->sector_size, max_clusters);
546 break;
547 case 32:
548 /*
549 FAT32 cluster sizes for disks with 512 block size
550 according to Microsoft specification fatgen103.doc:
551
552 32.5 MB - 260 MB cluster_size = 1
553 260 MB - 8 GB cluster_size = 8
554 8 GB - 16 GB cluster_size = 16
555 16 GB - 32 GB cluster_size = 32
556 32 GB - 2 TB cluster_size = 64
557
558 Below calculation is generalized and does not depend
559 on 512 block size.
560 */
561 Fs->cluster_size = tot_sectors > 32*1024*1024*2 ? 64 :
562 tot_sectors > 16*1024*1024*2 ? 32 :
563 tot_sectors > 8*1024*1024*2 ? 16 :
564 tot_sectors > 260*1024*2 ? 8 : 1;
565 return;
566 default:
567 fprintf(stderr,"Bad fat size\n");
568 exit(1);
569 }
570
571 if(tot_sectors <= Fs->fat_start + Fs->num_fat + Fs->dir_len) {
572 /* we need at least enough sectors to fit boot, fat and root
573 * dir */
574 fprintf(stderr, "Not enough sectors\n");
575 exit(1);
576 }
577
578 rem_sect = tot_sectors - Fs->dir_len - Fs->fat_start;
579
580 /* double the cluster size until we can fill up the disk with
581 * the maximal number of sectors of this size */
582 while(Fs->cluster_size * max_clusters + max_fat_size < rem_sect) {
583 if(Fs->cluster_size > 64) {
584 /* bigger than 64. Should fit */
585 fprintf(stderr,
586 "Internal error while calculating cluster size\n");
587 exit(1);
588 }
589 Fs->cluster_size <<= 1;
590 }
591 }
592
593
old_dos_size_to_geom(size_t size,unsigned int * cyls,unsigned short * heads,unsigned short * sects)594 static int old_dos_size_to_geom(size_t size,
595 unsigned int *cyls,
596 unsigned short *heads,
597 unsigned short *sects)
598 {
599 struct OldDos_t *params = getOldDosBySize(size);
600 if(params != NULL) {
601 *cyls = params->tracks;
602 *heads = params->heads;
603 *sects = params->sectors;
604 return 0;
605 } else
606 return 1;
607 }
608
609
calc_fs_parameters(struct device * dev,unsigned long tot_sectors,struct Fs_t * Fs,union bootsector * boot)610 static void calc_fs_parameters(struct device *dev, unsigned long tot_sectors,
611 struct Fs_t *Fs, union bootsector *boot)
612 {
613 struct OldDos_t *params=NULL;
614 if(dev->fat_bits == 0 || abs(dev->fat_bits) == 12)
615 params = getOldDosByParams(dev->tracks,dev->heads,dev->sectors,
616 Fs->dir_len, Fs->cluster_size);
617 if(params != NULL) {
618 boot->boot.descr = params->media;
619 Fs->cluster_size = params->cluster_size;
620 Fs->dir_len = params->dir_len;
621 Fs->fat_len = params->fat_len;
622 Fs->fat_bits = 12;
623 } else {
624 int may_change_cluster_size = (Fs->cluster_size == 0);
625 int may_change_root_size = (Fs->dir_len == 0);
626
627 /* a non-standard format */
628 if(DWORD(nhs) || tot_sectors % (dev->sectors * dev->heads))
629 boot->boot.descr = 0xf8;
630 else
631 boot->boot.descr = 0xf0;
632
633
634 if(!Fs->cluster_size) {
635 if (dev->heads == 1)
636 Fs->cluster_size = 1;
637 else {
638 Fs->cluster_size = (tot_sectors > 2000 ) ? 1:2;
639 if (dev->use_2m & 0x7f)
640 Fs->cluster_size = 1;
641 }
642 }
643
644 if(!Fs->dir_len) {
645 if (dev->heads == 1)
646 Fs->dir_len = 4;
647 else
648 Fs->dir_len = (tot_sectors > 2000) ? 32 : 7;
649 }
650
651 calc_cluster_size(Fs, tot_sectors, dev->fat_bits);
652 #ifdef USE_XDF
653 if(Fs->fat_len)
654 xdf_calc_fat_size(Fs, tot_sectors, dev->fat_bits);
655 else
656 #endif
657 {
658 calc_fat_bits2(Fs, tot_sectors, dev->fat_bits,
659 may_change_cluster_size,
660 may_change_root_size);
661 calc_fat_size(Fs, tot_sectors);
662 }
663 }
664
665 set_word(boot->boot.fatlen, Fs->fat_len);
666 }
667
668
669
calc_fs_parameters_32(unsigned long tot_sectors,struct Fs_t * Fs,union bootsector * boot)670 static void calc_fs_parameters_32(unsigned long tot_sectors,
671 struct Fs_t *Fs, union bootsector *boot)
672 {
673 unsigned long num_clus;
674 if(DWORD(nhs))
675 boot->boot.descr = 0xf8;
676 else
677 boot->boot.descr = 0xf0;
678
679 if(!Fs->cluster_size)
680 calc_cluster_size(Fs, tot_sectors, 32);
681 Fs->dir_len = 0;
682 num_clus = tot_sectors / Fs->cluster_size;
683 /* Maximal number of clusters on FAT32 is 0xffffff6 */
684 if (num_clus > 0xffffff6) {
685 fprintf(stderr, "Too many clusters\n");
686 exit(1);
687 }
688 Fs->num_clus = (unsigned int) num_clus;
689 set_fat32(Fs);
690 calc_fat_size(Fs, tot_sectors);
691 set_word(boot->boot.fatlen, 0);
692 set_dword(boot->boot.ext.fat32.bigFat, Fs->fat_len);
693 }
694
695
696
697
698 static void usage(int ret) NORETURN;
usage(int ret)699 static void usage(int ret)
700 {
701 fprintf(stderr,
702 "Mtools version %s, dated %s\n", mversion, mdate);
703 fprintf(stderr,
704 "Usage: %s [-V] [-t tracks] [-h heads] [-n sectors] "
705 "[-v label] [-1] [-4] [-8] [-f size] "
706 "[-N serialnumber] "
707 "[-k] [-B bootsector] [-r root_dir_len] [-L fat_len] "
708 "[-F] [-I fsVersion] [-C] [-c cluster_size] "
709 "[-H hidden_sectors] "
710 #ifdef USE_XDF
711 "[-X] "
712 #endif
713 "[-S hardsectorsize] [-M softsectorsize] [-3] "
714 "[-2 track0sectors] [-0 rate0] [-A rateany] [-a]"
715 "device\n", progname);
716 exit(ret);
717 }
718
719 #ifdef OS_linux
get_sector_size(int fd,char * errmsg)720 static int get_sector_size(int fd, char *errmsg) {
721 int sec_size;
722 if (ioctl(fd, BLKSSZGET, &sec_size) != 0 || sec_size <= 0) {
723 sprintf(errmsg, "Could not get sector size of device (%s)",
724 strerror(errno));
725 return -1;
726 }
727
728 /* Cap sector size at 4096 */
729 if(sec_size > 4096)
730 sec_size = 4096;
731 return sec_size;
732 }
733
get_block_geom(int fd,struct device * dev,char * errmsg)734 static int get_block_geom(int fd, struct device *dev, char *errmsg) {
735 struct hd_geometry geom;
736 int sec_size;
737 long size;
738 uint16_t heads=dev->heads;
739 uint16_t sectors=dev->sectors;
740 unsigned int sect_per_track;
741
742 if (ioctl(fd, HDIO_GETGEO, &geom) < 0) {
743 sprintf(errmsg, "Could not get geometry of device (%s)",
744 strerror(errno));
745 return -1;
746 }
747
748 if (ioctl(fd, BLKGETSIZE, &size) < 0) {
749 sprintf(errmsg, "Could not get size of device (%s)",
750 strerror(errno));
751 return -1;
752 }
753
754 sec_size = get_sector_size(fd, errmsg);
755 if(sec_size < 0)
756 return -1;
757
758 dev->ssize = 0;
759 while (dev->ssize < 0x7F && (128 << dev->ssize) < sec_size)
760 dev->ssize++;
761
762 if(!heads)
763 heads = geom.heads;
764 if(!sectors)
765 sectors = geom.sectors;
766
767 sect_per_track = heads * sectors;
768 if(!dev->hidden) {
769 unsigned long hidden;
770 hidden = geom.start % sect_per_track;
771 if(hidden && hidden != sectors) {
772 sprintf(errmsg,
773 "Hidden (%ld) does not match sectors (%d)\n",
774 hidden, sectors);
775 return -1;
776 }
777 dev->hidden = hidden;
778 }
779 dev->heads = heads;
780 dev->sectors = sectors;
781 if(!dev->tracks)
782 dev->tracks = (size + dev->hidden % sect_per_track) / sect_per_track;
783 return 0;
784 }
785 #endif
786
get_lba_geom(Stream_t * Direct,unsigned long tot_sectors,struct device * dev,char * errmsg)787 static int get_lba_geom(Stream_t *Direct, unsigned long tot_sectors, struct device *dev, char *errmsg) {
788 int sect_per_track;
789 unsigned long tracks;
790
791 /* if one value is already specified we do not want to overwrite it */
792 if (dev->heads || dev->sectors || dev->tracks) {
793 sprintf(errmsg, "Number of heads or sectors or tracks was already specified");
794 return -1;
795 }
796
797 if (!tot_sectors) {
798 #ifdef OS_linux
799 int fd;
800 int sec_size;
801 long size;
802 struct MT_STAT stbuf;
803
804 fd = get_fd(Direct);
805 if (MT_FSTAT(fd, &stbuf) < 0) {
806 sprintf(errmsg, "Could not stat file (%s)", strerror(errno));
807 return -1;
808 }
809
810 if (S_ISBLK(stbuf.st_mode)) {
811 if (ioctl(fd, BLKGETSIZE, &size) != 0) {
812 sprintf(errmsg, "Could not get size of device (%s)",
813 strerror(errno));
814 return -1;
815 }
816 sec_size = get_sector_size(fd, errmsg);
817 if(sec_size < 0)
818 return -1;
819
820 if (!(dev->ssize & 0x80)) {
821 dev->ssize = 0;
822 while (dev->ssize < 0x7F && (128 << dev->ssize) < sec_size)
823 dev->ssize++;
824 }
825 if ((dev->ssize & 0x7f) > 2)
826 tot_sectors = size >> ((dev->ssize & 0x7f) - 2);
827 else
828 tot_sectors = size << (2 - (dev->ssize & 0x7f));
829 } else if (S_ISREG(stbuf.st_mode)) {
830 tot_sectors = stbuf.st_size >> ((dev->ssize & 0x7f) + 7);
831 } else {
832 sprintf(errmsg, "Could not get size of device (%s)",
833 "No method available");
834 return -1;
835 }
836 #else
837 mt_size_t size;
838 GET_DATA(Direct, 0, &size, 0, 0);
839 if (size == 0) {
840 sprintf(errmsg, "Could not get size of device (%s)",
841 "No method available");
842 return -1;
843 }
844 tot_sectors = size >> ((dev->ssize & 0x7f) + 7);
845 #endif
846 }
847
848 dev->sectors = 63;
849
850 if (tot_sectors < 16*63*1024)
851 dev->heads = 16;
852 else if (tot_sectors < 32*63*1024)
853 dev->heads = 32;
854 else if (tot_sectors < 64*63*1024)
855 dev->heads = 64;
856 else if (tot_sectors < 128*63*1024)
857 dev->heads = 128;
858 else
859 dev->heads = 255;
860
861 sect_per_track = dev->heads * dev->sectors;
862 tracks = (tot_sectors + dev->hidden % sect_per_track) / sect_per_track;
863 if (tracks > 0xFFFFFFFF) {
864 sprintf(errmsg, "Device is too big, it has too many tracks");
865 return -1;
866 }
867
868 dev->tracks = (uint32_t) tracks;
869
870 return 0;
871 }
872
873 void mformat(int argc, char **argv, int dummy UNUSEDP) NORETURN;
mformat(int argc,char ** argv,int dummy UNUSEDP)874 void mformat(int argc, char **argv, int dummy UNUSEDP)
875 {
876 int r; /* generic return value */
877 Fs_t Fs;
878 unsigned int hs;
879 int hs_set;
880 unsigned int arguse_2m = 0;
881 uint8_t sectors0=18; /* number of sectors on track 0 */
882 int create = 0;
883 uint8_t rate_0, rate_any;
884 int mangled;
885 uint8_t argssize=0; /* sector size */
886 int msize=0;
887 int fat32 = 0;
888 struct label_blk_t *labelBlock;
889 int bootOffset;
890
891 #ifdef USE_XDF
892 unsigned int i;
893 int format_xdf = 0;
894 struct xdf_info info;
895 #endif
896 union bootsector boot;
897 char *bootSector=0;
898 int c;
899 int keepBoot = 0;
900 struct device used_dev;
901 unsigned int argtracks;
902 uint16_t argheads, argsectors;
903 unsigned long tot_sectors=0;
904 int blocksize;
905
906 char drive, name[EXPAND_BUF];
907
908 char label[VBUFSIZE];
909
910 dos_name_t shortlabel;
911 struct device *dev;
912 char errmsg[2100];
913
914 uint32_t serial;
915 int serial_set;
916 int fsVersion;
917 int mediaDesc=-1;
918
919 mt_size_t maxSize;
920
921 int Atari = 0; /* should we add an Atari-style serial number ? */
922
923 unsigned int backupBoot = 6;
924 int backupBootSet = 0;
925
926 unsigned int resvSects = 0;
927
928 char *endptr;
929
930 hs = hs_set = 0;
931 argtracks = 0;
932 argheads = 0;
933 argsectors = 0;
934 arguse_2m = 0;
935 argssize = 0x2;
936 label[0] = '\0';
937 serial_set = 0;
938 serial = 0;
939 fsVersion = 0;
940
941 Fs.cluster_size = 0;
942 Fs.refs = 1;
943 Fs.dir_len = 0;
944 if(getenv("MTOOLS_DIR_LEN")) {
945 Fs.dir_len = atoui(getenv("MTOOLS_DIR_LEN"));
946 if(Fs.dir_len <= 0)
947 Fs.dir_len=0;
948 }
949 Fs.fat_len = 0;
950 Fs.num_fat = 2;
951 if(getenv("MTOOLS_NFATS")) {
952 Fs.num_fat = atoui(getenv("MTOOLS_NFATS"));
953 if(Fs.num_fat <= 0)
954 Fs.num_fat=2;
955 }
956 Fs.Class = &FsClass;
957 rate_0 = mtools_rate_0;
958 rate_any = mtools_rate_any;
959
960 /* get command line options */
961 if(helpFlag(argc, argv))
962 usage(0);
963 while ((c = getopt(argc,argv,
964 "i:148f:t:n:v:qub"
965 "kK:R:B:r:L:I:FCc:Xh:s:T:l:N:H:M:S:2:30:Aad:m:"))!= EOF) {
966 errno = 0;
967 endptr = NULL;
968 switch (c) {
969 case 'i':
970 set_cmd_line_image(optarg);
971 break;
972
973 /* standard DOS flags */
974 case '1':
975 argheads = 1;
976 break;
977 case '4':
978 argsectors = 9;
979 argtracks = 40;
980 break;
981 case '8':
982 argsectors = 8;
983 argtracks = 40;
984 break;
985 case 'f':
986 r=old_dos_size_to_geom(atoul(optarg),
987 &argtracks, &argheads,
988 &argsectors);
989 if(r) {
990 fprintf(stderr,
991 "Bad size %s\n", optarg);
992 exit(1);
993 }
994 break;
995 case 't':
996 argtracks = atou16(optarg);
997 break;
998
999 case 'T':
1000 tot_sectors = atoui(optarg);
1001 break;
1002
1003 case 'n': /*non-standard*/
1004 case 's':
1005 argsectors = atou16(optarg);
1006 break;
1007
1008 case 'l': /* non-standard */
1009 case 'v':
1010 strncpy(label, optarg, VBUFSIZE-1);
1011 label[VBUFSIZE-1] = '\0';
1012 break;
1013
1014 /* flags supported by Dos but not mtools */
1015 case 'q':
1016 case 'u':
1017 case 'b':
1018 /*case 's': leave this for compatibility */
1019 fprintf(stderr,
1020 "Flag %c not supported by mtools\n",c);
1021 exit(1);
1022
1023
1024
1025 /* flags added by mtools */
1026 case 'F':
1027 fat32 = 1;
1028 break;
1029
1030
1031 case 'S':
1032 argssize = atou8(optarg) | 0x80;
1033 if(argssize < 0x80)
1034 usage(1);
1035 if(argssize >= 0x87) {
1036 fprintf(stderr, "argssize must be less than 6\n");
1037 usage(1);
1038 }
1039 break;
1040
1041 #ifdef USE_XDF
1042 case 'X':
1043 format_xdf = 1;
1044 break;
1045 #endif
1046
1047 case '2':
1048 arguse_2m = 0xff;
1049 sectors0 = atou8(optarg);
1050 break;
1051 case '3':
1052 arguse_2m = 0x80;
1053 break;
1054
1055 case '0': /* rate on track 0 */
1056 rate_0 = atou8(optarg);
1057 break;
1058 case 'A': /* rate on other tracks */
1059 rate_any = atou8(optarg);
1060 break;
1061
1062 case 'M':
1063 msize = atoi(optarg);
1064 if(msize != 512 &&
1065 msize != 1024 &&
1066 msize != 2048 &&
1067 msize != 4096) {
1068 fprintf(stderr, "Only sector sizes of 512, 1024, 2048 or 4096 bytes are allowed\n");
1069 usage(1);
1070 }
1071 break;
1072
1073 case 'N':
1074 serial = strtou32(optarg,&endptr,16);
1075 serial_set = 1;
1076 break;
1077 case 'a': /* Atari style serial number */
1078 Atari = 1;
1079 break;
1080
1081 case 'C':
1082 create = O_CREAT | O_TRUNC;
1083 break;
1084
1085 case 'H':
1086 hs = atoui(optarg);
1087 hs_set = 1;
1088 break;
1089
1090 case 'I':
1091 fsVersion = strtoi(optarg,&endptr,0);
1092 break;
1093
1094 case 'c':
1095 Fs.cluster_size = atoui(optarg);
1096 break;
1097
1098 case 'r':
1099 Fs.dir_len = strtoui(optarg,&endptr,0);
1100 break;
1101 case 'L':
1102 Fs.fat_len = strtoui(optarg,&endptr,0);
1103 break;
1104
1105
1106 case 'B':
1107 bootSector = optarg;
1108 break;
1109 case 'k':
1110 keepBoot = 1;
1111 break;
1112 case 'K':
1113 backupBoot = atoui(optarg);
1114 backupBootSet=1;
1115 if(backupBoot < 2) {
1116 fprintf(stderr, "Backupboot must be greater than 2\n");
1117 exit(1);
1118 }
1119 break;
1120 case 'R':
1121 resvSects = atoui(optarg);
1122 break;
1123 case 'h':
1124 argheads = atou16(optarg);
1125 break;
1126 case 'd':
1127 Fs.num_fat = atoui(optarg);
1128 break;
1129 case 'm':
1130 mediaDesc = strtoi(optarg,&endptr,0);
1131 if(*endptr)
1132 mediaDesc = strtoi(optarg,&endptr,16);
1133 break;
1134 default:
1135 usage(1);
1136 }
1137 check_number_parse_errno(c, optarg, endptr);
1138 }
1139
1140 if (argc - optind > 1)
1141 usage(1);
1142 if(argc - optind == 1) {
1143 if(!argv[optind][0] || argv[optind][1] != ':')
1144 usage(1);
1145 drive = ch_toupper(argv[argc -1][0]);
1146 } else {
1147 drive = get_default_drive();
1148 if(drive != ':') {
1149 /* Use default drive only if it is ":" (image file), as else
1150 it would be too dangerous... */
1151 fprintf(stderr, "Drive letter missing\n");
1152 exit(1);
1153 }
1154 }
1155
1156 if(argtracks && tot_sectors) {
1157 fprintf(stderr, "Only one of -t or -T may be specified\n");
1158 usage(1);
1159 }
1160
1161 #ifdef USE_XDF
1162 if(create && format_xdf) {
1163 fprintf(stderr,"Create and XDF can't be used together\n");
1164 exit(1);
1165 }
1166 #endif
1167
1168 /* check out a drive whose letter and parameters match */
1169 sprintf(errmsg, "Drive '%c:' not supported", drive);
1170 Fs.Direct = NULL;
1171 blocksize = 0;
1172 for(dev=devices;dev->drive;dev++) {
1173 FREE(&(Fs.Direct));
1174 /* drive letter */
1175 if (dev->drive != drive)
1176 continue;
1177 used_dev = *dev;
1178
1179 SET_INT(used_dev.tracks, argtracks);
1180 SET_INT(used_dev.heads, argheads);
1181 SET_INT(used_dev.sectors, argsectors);
1182 SET_INT(used_dev.use_2m, arguse_2m);
1183 SET_INT(used_dev.ssize, argssize);
1184 if(hs_set)
1185 used_dev.hidden = hs;
1186
1187 expand(dev->name, name);
1188 #ifdef USING_NEW_VOLD
1189 strcpy(name, getVoldName(dev, name));
1190 #endif
1191
1192 #ifdef USE_XDF
1193 if(!format_xdf) {
1194 #endif
1195 Fs.Direct = 0;
1196 #ifdef USE_FLOPPYD
1197 Fs.Direct = FloppydOpen(&used_dev, name,
1198 O_RDWR | create,
1199 errmsg, &maxSize);
1200 #endif
1201 if(!Fs.Direct) {
1202 Fs.Direct = SimpleFileOpen(&used_dev, dev, name,
1203 O_RDWR | create,
1204 errmsg, 0, 1,
1205 &maxSize);
1206 }
1207 #ifdef USE_XDF
1208 } else {
1209 used_dev.misc_flags |= USE_XDF_FLAG;
1210 Fs.Direct = XdfOpen(&used_dev, name, O_RDWR,
1211 errmsg, &info);
1212 if(Fs.Direct && !Fs.fat_len)
1213 Fs.fat_len = info.FatSize;
1214 if(Fs.Direct && !Fs.dir_len)
1215 Fs.dir_len = info.RootDirSize;
1216 }
1217 #endif
1218
1219 if (!Fs.Direct)
1220 continue;
1221
1222 #ifdef OS_linux
1223 if ((!used_dev.tracks || !used_dev.heads || !used_dev.sectors) &&
1224 (!IS_SCSI(dev))) {
1225 int fd= get_fd(Fs.Direct);
1226 struct MT_STAT stbuf;
1227
1228 if (MT_FSTAT(fd, &stbuf) < 0) {
1229 sprintf(errmsg, "Could not stat file (%s)", strerror(errno));
1230 continue;
1231 }
1232
1233 if (S_ISBLK(stbuf.st_mode))
1234 /* If the following get_block_geom fails, do not
1235 * continue to next drive description, but allow
1236 * get_lba_geom to kick in
1237 */
1238 get_block_geom(fd, &used_dev, errmsg);
1239 }
1240 #endif
1241
1242 if ((!used_dev.tracks && !tot_sectors) ||
1243 !used_dev.heads || !used_dev.sectors){
1244 if (get_lba_geom(Fs.Direct, tot_sectors, &used_dev,
1245 errmsg) < 0) {
1246 sprintf(errmsg, "%s: "
1247 "Complete geometry of the disk "
1248 "was not specified, \n"
1249 "neither in /usr/local/etc/mtools.conf nor "
1250 "on the command line. \n"
1251 "LBA Assist Translation for "
1252 "calculating CHS geometry "
1253 "of the disk failed.\n", argv[0]);
1254 continue;
1255 }
1256 }
1257
1258 #if 0
1259 /* set parameters, if needed */
1260 if(SET_GEOM(Fs.Direct, &used_dev, 0xf0, boot)){
1261 sprintf(errmsg,"Can't set disk parameters: %s",
1262 strerror(errno));
1263 continue;
1264 }
1265 #endif
1266 Fs.sector_size = 512;
1267 if( !(used_dev.use_2m & 0x7f)) {
1268 Fs.sector_size = 128 << (used_dev.ssize & 0x7f);
1269 }
1270
1271 SET_INT(Fs.sector_size, msize);
1272 {
1273 unsigned int j;
1274 for(j = 0; j < 31; j++) {
1275 if (Fs.sector_size == (unsigned int) (1 << j)) {
1276 Fs.sectorShift = j;
1277 break;
1278 }
1279 }
1280 Fs.sectorMask = Fs.sector_size - 1;
1281 }
1282
1283 if(!used_dev.blocksize || used_dev.blocksize < Fs.sector_size)
1284 blocksize = Fs.sector_size;
1285 else
1286 blocksize = used_dev.blocksize;
1287
1288 if(blocksize > MAX_SECTOR)
1289 blocksize = MAX_SECTOR;
1290
1291 /* do a "test" read */
1292 if (!create &&
1293 READS(Fs.Direct, &boot.characters, 0, Fs.sector_size) !=
1294 (signed int) Fs.sector_size) {
1295 #ifdef HAVE_SNPRINTF
1296 snprintf(errmsg, sizeof(errmsg)-1,
1297 "Error reading from '%s', wrong parameters?",
1298 name);
1299 #else
1300 sprintf(errmsg,
1301 "Error reading from '%s', wrong parameters?",
1302 name);
1303 #endif
1304 continue;
1305 }
1306 break;
1307 }
1308
1309
1310 /* print error msg if needed */
1311 if ( dev->drive == 0 ){
1312 FREE(&Fs.Direct);
1313 fprintf(stderr,"%s: %s\n", argv[0],errmsg);
1314 exit(1);
1315 }
1316
1317 /* calculate the total number of sectors */
1318 if(tot_sectors == 0) {
1319 unsigned long sect_per_track = used_dev.heads*used_dev.sectors;
1320 tot_sectors = used_dev.tracks*sect_per_track - used_dev.hidden%sect_per_track;
1321 /* Number of sectors must fit into 32bit value */
1322 if (tot_sectors > 0xFFFFFFFF) {
1323 fprintf(stderr, "Too many sectors\n");
1324 exit(1);
1325 }
1326 }
1327
1328 /* create the image file if needed */
1329 if (create) {
1330 WRITES(Fs.Direct, &boot.characters,
1331 sectorsToBytes((Stream_t*)&Fs, tot_sectors-1),
1332 Fs.sector_size);
1333 }
1334
1335 /* the boot sector */
1336 if(bootSector) {
1337 int fd;
1338
1339 fd = open(bootSector, O_RDONLY | O_BINARY | O_LARGEFILE);
1340 if(fd < 0) {
1341 perror("open boot sector");
1342 exit(1);
1343 }
1344 if(read(fd, &boot.bytes, blocksize) < blocksize) {
1345 perror("short read on boot sector");
1346 exit(1);
1347 }
1348 keepBoot = 1;
1349 close(fd);
1350 }
1351 if(!keepBoot && !(used_dev.use_2m & 0x7f))
1352 memset(boot.characters, '\0', Fs.sector_size);
1353 set_dword(boot.boot.nhs, used_dev.hidden);
1354
1355 Fs.Next = buf_init(Fs.Direct,
1356 blocksize * used_dev.heads * used_dev.sectors,
1357 blocksize * used_dev.heads * used_dev.sectors,
1358 blocksize);
1359 Fs.Buffer = 0;
1360
1361 boot.boot.nfat = Fs.num_fat;
1362 if(!keepBoot)
1363 set_word(&boot.bytes[510], 0xaa55);
1364
1365 /* Initialize the remaining parameters */
1366 set_word(boot.boot.nsect, used_dev.sectors);
1367 set_word(boot.boot.nheads, used_dev.heads);
1368
1369 used_dev.fat_bits = comp_fat_bits(&Fs,used_dev.fat_bits, tot_sectors, fat32);
1370
1371 if(!keepBoot && !(used_dev.use_2m & 0x7f)) {
1372 if(!used_dev.partition) {
1373 /* install fake partition table pointing to itself */
1374 struct partition *partTable=(struct partition *)
1375 (&boot.bytes[0x1ae]);
1376 setBeginEnd(&partTable[1], 0,
1377 used_dev.heads * used_dev.sectors *
1378 used_dev.tracks,
1379 used_dev.heads, used_dev.sectors, 1, 0,
1380 used_dev.fat_bits);
1381 }
1382 }
1383
1384 if(used_dev.fat_bits == 32) {
1385 Fs.primaryFat = 0;
1386 Fs.writeAllFats = 1;
1387 if(resvSects) {
1388 if(resvSects < 3) {
1389 fprintf(stderr,
1390 "For FAT 32, reserved sectors need to be at least 3\n");
1391 resvSects = 32;
1392 }
1393
1394 if(resvSects <= backupBoot && !backupBootSet)
1395 backupBoot = resvSects - 1;
1396 Fs.fat_start = resvSects;
1397 } else
1398 Fs.fat_start = 32;
1399
1400 if(Fs.fat_start <= backupBoot) {
1401 fprintf(stderr,
1402 "Reserved sectors (%d) must be more than backupBoot (%d)\n", Fs.fat_start, backupBoot);
1403 backupBoot = 6;
1404 Fs.fat_start = 32;
1405 }
1406
1407 calc_fs_parameters_32(tot_sectors, &Fs, &boot);
1408
1409 Fs.clus_start = Fs.num_fat * Fs.fat_len + Fs.fat_start;
1410
1411 /* extension flags: mirror fats, and use #0 as primary */
1412 set_word(boot.boot.ext.fat32.extFlags,0);
1413
1414 /* fs version. What should go here? */
1415 set_word(boot.boot.ext.fat32.fsVersion,fsVersion);
1416
1417 /* root directory */
1418 set_dword(boot.boot.ext.fat32.rootCluster, Fs.rootCluster = 2);
1419
1420 /* info sector */
1421 set_word(boot.boot.ext.fat32.infoSector, Fs.infoSectorLoc = 1);
1422 Fs.infoSectorLoc = 1;
1423
1424 /* no backup boot sector */
1425 set_word(boot.boot.ext.fat32.backupBoot, backupBoot);
1426
1427 labelBlock = & boot.boot.ext.fat32.labelBlock;
1428 } else {
1429 Fs.infoSectorLoc = 0;
1430 if(resvSects) {
1431 if(resvSects < 1) {
1432 fprintf(stderr,
1433 "Reserved sectors need to be at least 1\n");
1434 resvSects = 1;
1435 }
1436 Fs.fat_start = resvSects;
1437 } else
1438 Fs.fat_start = 1;
1439 calc_fs_parameters(&used_dev, tot_sectors, &Fs, &boot);
1440 Fs.dir_start = Fs.num_fat * Fs.fat_len + Fs.fat_start;
1441 Fs.clus_start = Fs.dir_start + Fs.dir_len;
1442 labelBlock = & boot.boot.ext.old.labelBlock;
1443
1444 }
1445
1446 /* Set the codepage */
1447 Fs.cp = cp_open(used_dev.codepage);
1448 if(Fs.cp == NULL)
1449 exit(1);
1450
1451 if (!keepBoot)
1452 /* only zero out physdrive if we don't have a template
1453 * bootsector */
1454 labelBlock->physdrive = 0x00;
1455 labelBlock->reserved = 0;
1456 labelBlock->dos4 = 0x29;
1457
1458 if (!serial_set || Atari)
1459 init_random();
1460 if (!serial_set)
1461 serial=(uint32_t) random();
1462 set_dword(labelBlock->serial, serial);
1463 label_name_pc(GET_DOSCONVERT((Stream_t *)&Fs),
1464 label[0] ? label : "NO NAME ", 0,
1465 &mangled, &shortlabel);
1466 strncpy(labelBlock->label, shortlabel.base, 8);
1467 strncpy(labelBlock->label+8, shortlabel.ext, 3);
1468 sprintf(labelBlock->fat_type, "FAT%2.2d ", Fs.fat_bits);
1469 labelBlock->fat_type[7] = ' ';
1470
1471 set_word(boot.boot.secsiz, Fs.sector_size);
1472 boot.boot.clsiz = (unsigned char) Fs.cluster_size;
1473 set_word(boot.boot.nrsvsect, Fs.fat_start);
1474
1475 bootOffset = init_geometry_boot(&boot, &used_dev, sectors0,
1476 rate_0, rate_any,
1477 &tot_sectors, keepBoot);
1478 if(!bootOffset) {
1479 bootOffset = ((unsigned char *) labelBlock) - boot.bytes +
1480 sizeof(struct label_blk_t);
1481 }
1482 if(Atari) {
1483 boot.boot.banner[4] = 0;
1484 boot.boot.banner[5] = (char) random();
1485 boot.boot.banner[6] = (char) random();
1486 boot.boot.banner[7] = (char) random();
1487 }
1488
1489 if(!keepBoot)
1490 inst_boot_prg(&boot, bootOffset);
1491 /* Mimic 3.8 behavior, else 2m disk do not work (???)
1492 * luferbu@fluidsignal.com (Luis Bustamante), Fri, 14 Jun 2002
1493 */
1494 if(used_dev.use_2m & 0x7f) {
1495 boot.boot.jump[0] = 0xeb;
1496 boot.boot.jump[1] = 0x80;
1497 boot.boot.jump[2] = 0x90;
1498 }
1499 if(used_dev.use_2m & 0x7f)
1500 Fs.num_fat = 1;
1501 if(mediaDesc != -1)
1502 boot.boot.descr=mediaDesc;
1503 Fs.lastFatSectorNr = 0;
1504 Fs.lastFatSectorData = 0;
1505 zero_fat(&Fs, boot.boot.descr);
1506 Fs.freeSpace = Fs.num_clus;
1507 Fs.last = 2;
1508
1509 #ifdef USE_XDF
1510 if(format_xdf)
1511 for(i=0;
1512 i < (info.BadSectors+Fs.cluster_size-1)/Fs.cluster_size;
1513 i++)
1514 fatEncode(&Fs, i+2, 0xfff7);
1515 #endif
1516
1517 format_root(&Fs, label, &boot);
1518 WRITES((Stream_t *)&Fs, boot.characters,
1519 (mt_off_t) 0, Fs.sector_size);
1520
1521 if(used_dev.fat_bits == 32) {
1522 WRITES((Stream_t *)&Fs, boot.characters,
1523 (mt_off_t) backupBoot * Fs.sector_size, Fs.sector_size);
1524 }
1525
1526 if(Fs.fat_bits == 32 && WORD_S(ext.fat32.backupBoot) != MAX16) {
1527 WRITES((Stream_t *)&Fs, boot.characters,
1528 sectorsToBytes((Stream_t*)&Fs,
1529 WORD_S(ext.fat32.backupBoot)),
1530 Fs.sector_size);
1531 }
1532 FLUSH((Stream_t *)&Fs); /* flushes Fs.
1533 * This triggers the writing of the FAT */
1534 FREE(&Fs.Next);
1535 Fs.Class->freeFunc((Stream_t *)&Fs);
1536 #ifdef USE_XDF
1537 if(format_xdf && isatty(0) && !getenv("MTOOLS_USE_XDF"))
1538 fprintf(stderr,
1539 "Note:\n"
1540 "Remember to set the \"MTOOLS_USE_XDF\" environmental\n"
1541 "variable before accessing this disk\n\n"
1542 "Bourne shell syntax (sh, ash, bash, ksh, zsh etc):\n"
1543 " export MTOOLS_USE_XDF=1\n\n"
1544 "C shell syntax (csh and tcsh):\n"
1545 " setenv MTOOLS_USE_XDF 1\n" );
1546 #endif
1547 exit(0);
1548 }
1549