• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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