• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*  Copyright 1996-2006,2008,2009 Alain Knaff.
2  *  This file is part of mtools.
3  *
4  *  Mtools is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  Mtools is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with Mtools.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "sysincludes.h"
19 #include "msdos.h"
20 #include "stream.h"
21 #include "mtools.h"
22 #include "fsP.h"
23 #include "file_name.h"
24 
25 #ifdef HAVE_LONG_LONG
26 typedef long long fatBitMask;
27 #else
28 typedef long fatBitMask;
29 #endif
30 
31 typedef struct FatMap_t {
32 	unsigned char *data;
33 	fatBitMask dirty;
34 	fatBitMask valid;
35 } FatMap_t;
36 
37 #define SECT_PER_ENTRY (sizeof(fatBitMask)*8)
38 #define ONE ((fatBitMask) 1)
39 
readSector(Fs_t * This,char * buf,unsigned int off,size_t size)40 static __inline__ int readSector(Fs_t *This, char *buf, unsigned int off,
41 					  size_t size)
42 {
43 	return READS(This->Next, buf, sectorsToBytes((Stream_t *)This, off),
44 				 size << This->sectorShift);
45 }
46 
47 
forceReadSector(Fs_t * This,char * buf,unsigned int off,size_t size)48 static __inline__ int forceReadSector(Fs_t *This, char *buf, unsigned int off,
49 				      size_t size)
50 {
51 	return force_read(This->Next, buf, sectorsToBytes((Stream_t *)This, off),
52 					  size << This->sectorShift);
53 }
54 
55 
forceWriteSector(Fs_t * This,char * buf,unsigned int off,size_t size)56 static __inline__ int forceWriteSector(Fs_t *This, char *buf, unsigned int off,
57 				       size_t size)
58 {
59 	return force_write(This->Next, buf, sectorsToBytes((Stream_t*)This, off),
60 					   size << This->sectorShift);
61 }
62 
63 
GetFatMap(Fs_t * Stream)64 static FatMap_t *GetFatMap(Fs_t *Stream)
65 {
66 	size_t nr_entries;
67 	size_t i;
68 	FatMap_t *map;
69 
70 	Stream->fat_error = 0;
71 	nr_entries = (Stream->fat_len + SECT_PER_ENTRY - 1) / SECT_PER_ENTRY;
72 	map = NewArray(nr_entries, FatMap_t);
73 	if(!map)
74 		return 0;
75 
76 	for(i=0; i< nr_entries; i++) {
77 		map[i].data = 0;
78 		map[i].valid = 0;
79 		map[i].dirty = 0;
80 	}
81 
82 	return map;
83 }
84 
locate(Fs_t * Stream,size_t offset,int * slot,int * bit)85 static __inline__ int locate(Fs_t *Stream, size_t offset, int *slot, int *bit)
86 {
87 	if(offset >= Stream->fat_len)
88 		return -1;
89 	*slot = offset / SECT_PER_ENTRY;
90 	*bit = offset % SECT_PER_ENTRY;
91 	return 0;
92 }
93 
fatReadSector(Fs_t * This,int sector,int slot,int bit,int dupe,fatBitMask bitmap)94 static __inline__ int fatReadSector(Fs_t *This, int sector, int slot,
95 				    int bit, int dupe, fatBitMask bitmap)
96 {
97 	int fat_start, ret;
98 	int nr_sectors;
99 
100 	dupe = (dupe + This->primaryFat) % This->num_fat;
101 	fat_start = This->fat_start + This->fat_len * dupe;
102 
103 	if(bitmap == 0) {
104 	    nr_sectors = SECT_PER_ENTRY - bit%SECT_PER_ENTRY;
105 	} else {
106 	    nr_sectors = 1;
107 	}
108 
109 	/* first, read as much as the buffer can give us */
110 	ret = readSector(This,
111 			 (char *)(This->FatMap[slot].data+(bit<<This->sectorShift)),
112 			 fat_start+sector,
113 			 nr_sectors);
114 	if(ret < 0)
115 		return 0;
116 
117 	if((unsigned int) ret < This->sector_size) {
118 		/* if we got less than one sector's worth, insist to get at
119 		 * least one sector */
120 		ret = forceReadSector(This,
121 				      (char *) (This->FatMap[slot].data +
122 						(bit << This->sectorShift)),
123 				      fat_start+sector, 1);
124 		if(ret < (int) This->sector_size)
125 			return 0;
126 		return 1;
127 	}
128 
129 	return ret >> This->sectorShift;
130 }
131 
132 
fatWriteSector(Fs_t * This,int sector,int slot,int bit,int dupe)133 static int fatWriteSector(Fs_t *This, int sector, int slot, int bit, int dupe)
134 {
135 	int fat_start;
136 
137 	dupe = (dupe + This->primaryFat) % This->num_fat;
138 	if(dupe && !This->writeAllFats)
139 		return This->sector_size;
140 
141 	fat_start = This->fat_start + This->fat_len * dupe;
142 
143 	return forceWriteSector(This,
144 				(char *)
145 				(This->FatMap[slot].data + bit * This->sector_size),
146 				fat_start+sector, 1);
147 }
148 
loadSector(Fs_t * This,unsigned int sector,fatAccessMode_t mode,int recurs)149 static unsigned char *loadSector(Fs_t *This,
150 				 unsigned int sector, fatAccessMode_t mode,
151 				 int recurs)
152 {
153 	int slot, bit, ret;
154 
155 	if(locate(This,sector, &slot, &bit) < 0)
156 		return 0;
157 #if 0
158         if (((This->fat_len + SECT_PER_ENTRY - 1) / SECT_PER_ENTRY) <= slot) {
159 		fprintf(stderr,"This should not happen\n");
160 		fprintf(stderr, "fat_len = %d\n", This->fat_len);
161 		fprintf(stderr, "SECT_PER_ENTRY=%d\n", (int)SECT_PER_ENTRY);
162 		fprintf(stderr, "sector = %d slot = %d bit=%d\n",
163 			sector, slot, bit);
164 		fprintf(stderr, "left = %d",(int)
165 			((This->fat_len+SECT_PER_ENTRY-1) / SECT_PER_ENTRY));
166                 return 0;
167 	}
168 #endif
169 	if(!This->FatMap[slot].data) {
170 		/* allocate the storage space */
171 		This->FatMap[slot].data =
172 			malloc(This->sector_size * SECT_PER_ENTRY);
173 		if(!This->FatMap[slot].data)
174 			return 0;
175 		memset(This->FatMap[slot].data, 0xee,
176 		       This->sector_size * SECT_PER_ENTRY);
177 	}
178 
179 	if(! (This->FatMap[slot].valid & (ONE << bit))) {
180 		unsigned int i;
181 		ret = -1;
182 		for(i=0; i< This->num_fat; i++) {
183 			/* read the sector */
184 			ret = fatReadSector(This, sector, slot, bit, i,
185 					    This->FatMap[slot].valid);
186 
187 			if(ret == 0) {
188 				fprintf(stderr,
189 					"Error reading fat number %d\n", i);
190 				continue;
191 			}
192 			if(This->FatMap[slot].valid)
193 			    /* Set recurs if there have already been
194 			     * sectors loaded in this bitmap long
195 			     */
196 			    recurs = 1;
197 			break;
198 		}
199 
200 		/* all copies bad.  Return error */
201 		if(ret == 0)
202 			return 0;
203 
204 		for(i=0; (int) i < ret; i++)
205 			This->FatMap[slot].valid |= ONE << (bit + i);
206 
207 		if(!recurs && ret == 1)
208 			/* do some prefetching, if we happened to only
209 			 * get one sector */
210 			loadSector(This, sector+1, mode, 1);
211 		if(!recurs && batchmode)
212 			for(i=0; i < 1024; i++)
213 				loadSector(This, sector+i, mode, 1);
214 	}
215 
216 	if(mode == FAT_ACCESS_WRITE) {
217 		This->FatMap[slot].dirty |= ONE << bit;
218 		This->fat_dirty = 1;
219 	}
220 	return This->FatMap[slot].data + (bit << This->sectorShift);
221 }
222 
223 
getAddress(Fs_t * Stream,unsigned int num,fatAccessMode_t mode)224 static unsigned char *getAddress(Fs_t *Stream,
225 				 unsigned int num, fatAccessMode_t mode)
226 {
227 	unsigned char *ret;
228 	int sector;
229 	int offset;
230 
231 	sector = num >> Stream->sectorShift;
232 	ret = 0;
233 	if(sector == Stream->lastFatSectorNr &&
234 	   Stream->lastFatAccessMode >= mode)
235 		ret = Stream->lastFatSectorData;
236 	if(!ret) {
237 		ret = loadSector(Stream, sector, mode, 0);
238 		if(!ret)
239 			return 0;
240 		Stream->lastFatSectorNr = sector;
241 		Stream->lastFatSectorData = ret;
242 		Stream->lastFatAccessMode = mode;
243 	}
244 	offset = num & Stream->sectorMask;
245 	return ret+offset;
246 }
247 
248 
readByte(Fs_t * Stream,int start)249 static int readByte(Fs_t *Stream, int start)
250 {
251 	unsigned char *address;
252 
253 	address = getAddress(Stream, start, FAT_ACCESS_READ);
254 	if(!address)
255 		return -1;
256 	return *address;
257 }
258 
259 
260 /*
261  * Fat 12 encoding:
262  *	|    byte n     |   byte n+1    |   byte n+2    |
263  *	|7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
264  *	| | | | | | | | | | | | | | | | | | | | | | | | |
265  *	| n+0.0 | n+0.5 | n+1.0 | n+1.5 | n+2.0 | n+2.5 |
266  *	    \_____  \____   \______/________/_____   /
267  *	      ____\______\________/   _____/  ____\_/
268  *	     /     \      \          /       /     \
269  *	| n+1.5 | n+0.0 | n+0.5 | n+2.0 | n+2.5 | n+1.0 |
270  *	|      FAT entry k      |    FAT entry k+1      |
271  */
272 
273  /*
274  * Get and decode a FAT (file allocation table) entry.  Returns the cluster
275  * number on success or 1 on failure.
276  */
277 
fat12_decode(Fs_t * Stream,unsigned int num)278 static unsigned int fat12_decode(Fs_t *Stream, unsigned int num)
279 {
280 	unsigned int start = num * 3 / 2;
281 	int byte0 = readByte(Stream, start);
282 	int byte1 = readByte(Stream, start+1);
283 
284 	if (num < 2 || byte0 < 0 || byte1 < 0 || num > Stream->num_clus+1) {
285 		fprintf(stderr,"[1] Bad address %d\n", num);
286 		return 1;
287 	}
288 
289 	if (num & 1)
290 		return (byte1 << 4) | ((byte0 & 0xf0)>>4);
291 	else
292 		return ((byte1 & 0xf) << 8) | byte0;
293 }
294 
295 
296 /*
297  * Puts a code into the FAT table.  Is the opposite of fat_decode().  No
298  * sanity checking is done on the code.  Returns a 1 on error.
299  */
fat12_encode(Fs_t * Stream,unsigned int num,unsigned int code)300 static void fat12_encode(Fs_t *Stream, unsigned int num, unsigned int code)
301 {
302 	int start = num * 3 / 2;
303 	unsigned char *address0 = getAddress(Stream, start, FAT_ACCESS_WRITE);
304 	unsigned char *address1 = getAddress(Stream, start+1, FAT_ACCESS_WRITE);
305 
306 	if (num & 1) {
307 		/* (odd) not on byte boundary */
308 		*address0 = (*address0 & 0x0f) | ((code << 4) & 0xf0);
309 		*address1 = (code >> 4) & 0xff;
310 	} else {
311 		/* (even) on byte boundary */
312 		*address0 = code & 0xff;
313 		*address1 = (*address1 & 0xf0) | ((code >> 8) & 0x0f);
314 	}
315 }
316 
317 
318 /*
319  * Fat 16 encoding:
320  *	|    byte n     |   byte n+1    |
321  *	|7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
322  *	| | | | | | | | | | | | | | | | |
323  *	|         FAT entry k           |
324  */
325 
fat16_decode(Fs_t * Stream,unsigned int num)326 static unsigned int fat16_decode(Fs_t *Stream, unsigned int num)
327 {
328 	unsigned char *address = getAddress(Stream, num << 1, FAT_ACCESS_READ);
329 	if(!address)
330 		return 1;
331 	return _WORD(address);
332 }
333 
fat16_encode(Fs_t * Stream,unsigned int num,unsigned int code)334 static void fat16_encode(Fs_t *Stream, unsigned int num, unsigned int code)
335 {
336 	unsigned char *address = getAddress(Stream, num << 1, FAT_ACCESS_WRITE);
337 	set_word(address, code);
338 }
339 
340 
fast_fat16_decode(Fs_t * Stream,unsigned int num)341 static unsigned int fast_fat16_decode(Fs_t *Stream, unsigned int num)
342 {
343 	unsigned short *address =
344 		(unsigned short *) getAddress(Stream, num << 1,
345 					      FAT_ACCESS_READ);
346 	if(!address)
347 		return 1;
348 	return *address;
349 }
350 
fast_fat16_encode(Fs_t * Stream,unsigned int num,unsigned int code)351 static void fast_fat16_encode(Fs_t *Stream, unsigned int num, unsigned int code)
352 {
353 	unsigned short *address =
354 		(unsigned short *) getAddress(Stream, num << 1,
355 					      FAT_ACCESS_WRITE);
356 	*address = code;
357 }
358 
359 
360 
361 
362 /*
363  * Fat 32 encoding
364  */
365 #define FAT32_HIGH 0xf0000000
366 #define FAT32_ADDR 0x0fffffff
367 
fat32_decode(Fs_t * Stream,unsigned int num)368 static unsigned int fat32_decode(Fs_t *Stream, unsigned int num)
369 {
370 	unsigned char *address = getAddress(Stream, num << 2, FAT_ACCESS_READ);
371 	if(!address)
372 		return 1;
373 	return _DWORD(address) & FAT32_ADDR;
374 }
375 
fat32_encode(Fs_t * Stream,unsigned int num,unsigned int code)376 static void fat32_encode(Fs_t *Stream, unsigned int num, unsigned int code)
377 {
378 	unsigned char *address = getAddress(Stream, num << 2, FAT_ACCESS_WRITE);
379 	set_dword(address,(code&FAT32_ADDR) | (_DWORD(address)&FAT32_HIGH));
380 }
381 
382 
fast_fat32_decode(Fs_t * Stream,unsigned int num)383 static unsigned int fast_fat32_decode(Fs_t *Stream, unsigned int num)
384 {
385 	unsigned int *address =
386 		(unsigned int *) getAddress(Stream, num << 2,
387 					    FAT_ACCESS_READ);
388 	if(!address)
389 		return 1;
390 	return (*address) & FAT32_ADDR;
391 }
392 
fast_fat32_encode(Fs_t * Stream,unsigned int num,unsigned int code)393 static void fast_fat32_encode(Fs_t *Stream, unsigned int num, unsigned int code)
394 {
395 	unsigned int *address =
396 		(unsigned int *) getAddress(Stream, num << 2,
397 					    FAT_ACCESS_WRITE);
398 	*address = (*address & FAT32_HIGH) | (code & FAT32_ADDR);
399 }
400 
401 
402 /*
403  * Write the FAT table to the disk.  Up to now the FAT manipulation has
404  * been done in memory.  All errors are fatal.  (Might not be too smart
405  * to wait till the end of the program to write the table.  Oh well...)
406  */
407 
fat_write(Fs_t * This)408 void fat_write(Fs_t *This)
409 {
410 	unsigned int i, j, dups, bit, slot;
411 	int ret;
412 
413 	/*fprintf(stderr, "Fat write\n");*/
414 
415 	if (!This->fat_dirty)
416 		return;
417 
418 	dups = This->num_fat;
419 	if (This->fat_error)
420 		dups = 1;
421 
422 
423 	for(i=0; i<dups; i++){
424 		j = 0;
425 		for(slot=0;j<This->fat_len;slot++) {
426 			if(!This->FatMap[slot].dirty) {
427 				j += SECT_PER_ENTRY;
428 				continue;
429 			}
430 			for(bit=0;
431 			    bit < SECT_PER_ENTRY && j<This->fat_len;
432 			    bit++,j++) {
433 				if(!(This->FatMap[slot].dirty & (ONE << bit)))
434 					continue;
435 				ret = fatWriteSector(This,j,slot, bit, i);
436 				if (ret < (int) This->sector_size){
437 					if (ret < 0 ){
438 						perror("error in fat_write");
439 						exit(1);
440 					} else {
441 						fprintf(stderr,
442 							"end of file in fat_write\n");
443 						exit(1);
444 					}
445 				}
446 				/* if last dupe, zero it out */
447 				if(i==dups-1)
448 					This->FatMap[slot].dirty &= ~(ONE<<bit);
449 			}
450 		}
451 	}
452 	/* write the info sector, if any */
453 	if(This->infoSectorLoc && This->infoSectorLoc != MAX32) {
454 		/* initialize info sector */
455 		InfoSector_t *infoSector;
456 		infoSector = (InfoSector_t *) safe_malloc(This->sector_size);
457 		if(forceReadSector(This, (char *)infoSector,
458 				   This->infoSectorLoc, 1) !=
459 		   (signed int) This->sector_size) {
460 			fprintf(stderr,"Trouble reading the info sector\n");
461 			memset(infoSector->filler1, 0, sizeof(infoSector->filler1));
462 			memset(infoSector->filler2, 0, sizeof(infoSector->filler2));
463 		}
464 		set_dword(infoSector->signature1, INFOSECT_SIGNATURE1);
465 		set_dword(infoSector->signature2, INFOSECT_SIGNATURE2);
466 		set_dword(infoSector->pos, This->last);
467 		set_dword(infoSector->count, This->freeSpace);
468 		set_word(infoSector->signature3, 0xaa55);
469 		if(forceWriteSector(This, (char *)infoSector, This->infoSectorLoc, 1) !=
470 		   (signed int) This->sector_size)
471 			fprintf(stderr,"Trouble writing the info sector\n");
472 		free(infoSector);
473 	}
474 	This->fat_dirty = 0;
475 	This->lastFatAccessMode = FAT_ACCESS_READ;
476 }
477 
478 
479 
480 /*
481  * Zero-Fat
482  * Used by mformat.
483  */
zero_fat(Fs_t * Stream,int media_descriptor)484 int zero_fat(Fs_t *Stream, int media_descriptor)
485 {
486 	unsigned int i, j;
487 	unsigned int fat_start;
488 	unsigned char *buf;
489 
490 	buf = malloc(Stream->sector_size);
491 	if(!buf) {
492 		perror("alloc fat sector buffer");
493 		return -1;
494 	}
495 	for(i=0; i< Stream->num_fat; i++) {
496 		fat_start = Stream->fat_start + i*Stream->fat_len;
497 		for(j = 0; j < Stream->fat_len; j++) {
498 			if(j <= 1)
499 				memset(buf, 0, Stream->sector_size);
500 			if(!j) {
501 				buf[0] = media_descriptor;
502 				buf[2] = buf[1] = 0xff;
503 				if(Stream->fat_bits > 12)
504 					buf[3] = 0xff;
505 				if(Stream->fat_bits > 16) {
506 					buf[4] = 0xff;
507 					buf[5] = 0xff;
508 					buf[6] = 0xff;
509 					buf[7] = 0x0f;
510 				}
511 			}
512 
513 			if(forceWriteSector(Stream, (char *)buf,
514 					    fat_start + j, 1) !=
515 			   (signed int) Stream->sector_size) {
516 				fprintf(stderr,
517 					"Trouble initializing a FAT sector\n");
518 				free(buf);
519 				return -1;
520 			}
521 		}
522 	}
523 
524 	free(buf);
525 	Stream->FatMap = GetFatMap(Stream);
526 	if (Stream->FatMap == NULL) {
527 		perror("alloc fat map");
528 		return -1;
529 	}
530 	return 0;
531 }
532 
533 
set_fat12(Fs_t * This)534 void set_fat12(Fs_t *This)
535 {
536 	This->fat_bits = 12;
537 	This->end_fat = 0xfff;
538 	This->last_fat = 0xff6;
539 	This->fat_decode = fat12_decode;
540 	This->fat_encode = fat12_encode;
541 }
542 
543 static char word_endian_test[] = { 0x34, 0x12 };
544 
set_fat16(Fs_t * This)545 void set_fat16(Fs_t *This)
546 {
547 	This->fat_bits = 16;
548 	This->end_fat = 0xffff;
549 	This->last_fat = 0xfff6;
550 
551 	if(sizeof(unsigned short) == 2 &&
552 	   * (unsigned short *) word_endian_test == 0x1234) {
553 		This->fat_decode = fast_fat16_decode;
554 		This->fat_encode = fast_fat16_encode;
555 	} else {
556 		This->fat_decode = fat16_decode;
557 		This->fat_encode = fat16_encode;
558 	}
559 }
560 
561 static char dword_endian_test[] = { 0x78, 0x56, 0x34, 0x12 };
562 
set_fat32(Fs_t * This)563 void set_fat32(Fs_t *This)
564 {
565 	This->fat_bits = 32;
566 	This->end_fat = 0xfffffff;
567 	This->last_fat = 0xffffff6;
568 
569 	if(sizeof(unsigned int) == 4 &&
570 	   * (unsigned int *) dword_endian_test == 0x12345678) {
571 		This->fat_decode = fast_fat32_decode;
572 		This->fat_encode = fast_fat32_encode;
573 	} else {
574 		This->fat_decode = fat32_decode;
575 		This->fat_encode = fat32_encode;
576 	}
577 }
578 
579 
check_fat(Fs_t * This)580 static int check_fat(Fs_t *This)
581 {
582 	/*
583 	 * This is only a sanity check.  For disks with really big FATs,
584 	 * there is no point in checking the whole FAT.
585 	 */
586 
587 	unsigned int i, f;
588 	unsigned int tocheck;
589 	if(mtools_skip_check)
590 		return 0;
591 
592 	/* too few sectors in the FAT */
593 	if(This->fat_len < NEEDED_FAT_SIZE(This))
594 		return -1;
595 	/* we do not warn about too much sectors in FAT, which may
596 	 * happen when a partition has been shrunk using FIPS, or on
597 	 * other occurrences */
598 
599 	tocheck = This->num_clus;
600 	if (tocheck + 1 >= This->last_fat) {
601 		fprintf(stderr, "Too many clusters in FAT\n");
602 		return -1;
603 	}
604 
605 	if(tocheck > 4096)
606 		tocheck = 4096;
607 
608 	for ( i= 3 ; i < tocheck; i++){
609 		f = This->fat_decode(This,i);
610 		if (f == 1 || (f < This->last_fat && f > This->num_clus)){
611 			fprintf(stderr,
612 				"Cluster # at %d too big(%#x)\n", i,f);
613 			fprintf(stderr,"Probably non MS-DOS disk\n");
614 			return -1;
615 		}
616 	}
617 	return 0;
618 }
619 
620 
621 /*
622  * Read the first sector of FAT table into memory.  Crude error detection on
623  * wrong FAT encoding scheme.
624  */
check_media_type(Fs_t * This,union bootsector * boot,unsigned int tot_sectors)625 static int check_media_type(Fs_t *This, union bootsector *boot,
626 			    unsigned int tot_sectors)
627 {
628 	unsigned char *address;
629 
630 	This->num_clus = (tot_sectors - This->clus_start) / This->cluster_size;
631 
632 	This->FatMap = GetFatMap(This);
633 	if (This->FatMap == NULL) {
634 		perror("alloc fat map");
635 		return -1;
636 	}
637 
638 	address = getAddress(This, 0, FAT_ACCESS_READ);
639 	if(!address) {
640 		fprintf(stderr,
641 			"Could not read first FAT sector\n");
642 		return -1;
643 	}
644 
645 	if(mtools_skip_check)
646 		return 0;
647 
648 	if(!address[0] && !address[1] && !address[2])
649 		/* Some Atari disks have zeroes where Dos has media descriptor
650 		 * and 0xff.  Do not consider this as an error */
651 		return 0;
652 
653 	if((address[0] != boot->boot.descr && boot->boot.descr >= 0xf0 &&
654 	    ((address[0] != 0xf9 && address[0] != 0xf7)
655 	     || boot->boot.descr != 0xf0)) || address[0] < 0xf0) {
656 		fprintf(stderr,
657 			"Bad media types %02x/%02x, probably non-MSDOS disk\n",
658 				address[0],
659 				boot->boot.descr);
660 		return -1;
661 	}
662 
663 	if(address[1] != 0xff || address[2] != 0xff){
664 		fprintf(stderr,"Initial byte of fat is not 0xff\n");
665 		return -1;
666 	}
667 
668 	return 0;
669 }
670 
fat_32_read(Fs_t * This,union bootsector * boot,unsigned int tot_sectors)671 static int fat_32_read(Fs_t *This, union bootsector *boot,
672 		       unsigned int tot_sectors)
673 {
674 	size_t size;
675 
676 	This->fat_len = DWORD(ext.fat32.bigFat);
677 	This->writeAllFats = !(boot->boot.ext.fat32.extFlags[0] & 0x80);
678 	This->primaryFat = boot->boot.ext.fat32.extFlags[0] & 0xf;
679 	This->rootCluster = DWORD(ext.fat32.rootCluster);
680 	This->clus_start = This->fat_start + This->num_fat * This->fat_len;
681 
682 	/* read the info sector */
683 	size = This->sector_size;
684 	This->infoSectorLoc = WORD(ext.fat32.infoSector);
685 	if(This->sector_size >= 512 &&
686 	   This->infoSectorLoc && This->infoSectorLoc != MAX32) {
687 		InfoSector_t *infoSector;
688 		infoSector = (InfoSector_t *) safe_malloc(size);
689 		if(forceReadSector(This, (char *)infoSector,
690 				   This->infoSectorLoc, 1) ==
691 		   (signed int) This->sector_size &&
692 		   _DWORD(infoSector->signature1) == INFOSECT_SIGNATURE1 &&
693 		   _DWORD(infoSector->signature2) == INFOSECT_SIGNATURE2) {
694 			This->freeSpace = _DWORD(infoSector->count);
695 			This->last = _DWORD(infoSector->pos);
696 		}
697 		free(infoSector);
698 	}
699 
700 	set_fat32(This);
701 	return(check_media_type(This, boot, tot_sectors) ||
702 	       check_fat(This));
703 }
704 
705 
old_fat_read(Fs_t * This,union bootsector * boot,size_t tot_sectors,int nodups)706 static int old_fat_read(Fs_t *This, union bootsector *boot,
707 			size_t tot_sectors, int nodups)
708 {
709 	This->writeAllFats = 1;
710 	This->primaryFat = 0;
711 	This->dir_start = This->fat_start + This->num_fat * This->fat_len;
712 	This->clus_start = This->dir_start + This->dir_len;
713 	This->infoSectorLoc = MAX32;
714 
715 	if(nodups)
716 		This->num_fat = 1;
717 
718 	if(check_media_type(This,boot, tot_sectors))
719 		return -1;
720 
721 	if(This->num_clus >= FAT12) {
722 		set_fat16(This);
723 		/* third FAT byte must be 0xff */
724 		if(!mtools_skip_check && readByte(This, 3) != 0xff)
725 			return -1;
726 	} else
727 		set_fat12(This);
728 
729 	return check_fat(This);
730 }
731 
732 /*
733  * Read the first sector of the  FAT table into memory and initialize
734  * structures.
735  */
fat_read(Fs_t * This,union bootsector * boot,size_t tot_sectors,int nodups)736 int fat_read(Fs_t *This, union bootsector *boot,
737 	   size_t tot_sectors, int nodups)
738 {
739 	This->fat_error = 0;
740 	This->fat_dirty = 0;
741 	This->last = MAX32;
742 	This->freeSpace = MAX32;
743 	This->lastFatSectorNr = 0;
744 	This->lastFatSectorData = 0;
745 
746 	if(This->fat_len)
747 		return old_fat_read(This, boot, tot_sectors, nodups);
748 	else
749 		return fat_32_read(This, boot, tot_sectors);
750 }
751 
752 
fatDecode(Fs_t * This,unsigned int pos)753 unsigned int fatDecode(Fs_t *This, unsigned int pos)
754 {
755 	unsigned int ret;
756 
757 	ret = This->fat_decode(This, pos);
758 	if(ret && (ret < 2 || ret > This->num_clus+1) && ret < This->last_fat) {
759 		fprintf(stderr, "Bad FAT entry %d at %d\n", ret, pos);
760 		This->fat_error++;
761 	}
762 	return ret;
763 }
764 
765 /* append a new cluster */
fatAppend(Fs_t * This,unsigned int pos,unsigned int newpos)766 void fatAppend(Fs_t *This, unsigned int pos, unsigned int newpos)
767 {
768 	This->fat_encode(This, pos, newpos);
769 	This->fat_encode(This, newpos, This->end_fat);
770 	if(This->freeSpace != MAX32)
771 		This->freeSpace--;
772 }
773 
774 /* de-allocates the given cluster */
fatDeallocate(Fs_t * This,unsigned int pos)775 void fatDeallocate(Fs_t *This, unsigned int pos)
776 {
777 	This->fat_encode(This, pos, 0);
778 	if(This->freeSpace != MAX32)
779 		This->freeSpace++;
780 }
781 
782 /* allocate a new cluster */
fatAllocate(Fs_t * This,unsigned int pos,unsigned int value)783 void fatAllocate(Fs_t *This, unsigned int pos, unsigned int value)
784 {
785 	This->fat_encode(This, pos, value);
786 	if(This->freeSpace != MAX32)
787 		This->freeSpace--;
788 }
789 
fatEncode(Fs_t * This,unsigned int pos,unsigned int value)790 void fatEncode(Fs_t *This, unsigned int pos, unsigned int value)
791 {
792 	unsigned int oldvalue = This->fat_decode(This, pos);
793 	This->fat_encode(This, pos, value);
794 	if(This->freeSpace != MAX32) {
795 		if(oldvalue)
796 			This->freeSpace++;
797 		if(value)
798 			This->freeSpace--;
799 	}
800 }
801 
get_next_free_cluster(Fs_t * This,unsigned int last)802 unsigned int get_next_free_cluster(Fs_t *This, unsigned int last)
803 {
804 	unsigned int i;
805 
806 	if(This->last != MAX32)
807 		last = This->last;
808 
809 	if (last < 2 ||
810 	    last >= This->num_clus+1)
811 		last = 1;
812 
813 	for (i=last+1; i< This->num_clus+2; i++) {
814 		unsigned int r = fatDecode(This, i);
815 		if(r == 1)
816 			goto exit_0;
817 		if (!r) {
818 			This->last = i;
819 			return i;
820 		}
821 	}
822 
823 	for(i=2; i < last+1; i++) {
824 		unsigned int r = fatDecode(This, i);
825 		if(r == 1)
826 			goto exit_0;
827 		if (!r) {
828 			This->last = i;
829 			return i;
830 		}
831 	}
832 
833 
834 	fprintf(stderr,"No free cluster %d %d\n", This->preallocatedClusters,
835 		This->last);
836 	return 1;
837  exit_0:
838 	fprintf(stderr, "FAT error\n");
839 	return 1;
840 }
841 
fat_error(Stream_t * Dir)842 int fat_error(Stream_t *Dir)
843 {
844 	Stream_t *Stream = GetFs(Dir);
845 	DeclareThis(Fs_t);
846 
847 	if(This->fat_error)
848 		fprintf(stderr,"Fat error detected\n");
849 
850 	return This->fat_error;
851 }
852 
fat32RootCluster(Stream_t * Dir)853 int fat32RootCluster(Stream_t *Dir)
854 {
855 	Stream_t *Stream = GetFs(Dir);
856 	DeclareThis(Fs_t);
857 
858 	if(This->fat_bits == 32)
859 		return This->rootCluster;
860 	else
861 		return 0;
862 }
863 
864 
865 /*
866  * Get the amount of free space on the diskette
867  */
868 
getfree(Stream_t * Dir)869 mt_size_t getfree(Stream_t *Dir)
870 {
871 	Stream_t *Stream = GetFs(Dir);
872 	DeclareThis(Fs_t);
873 
874 	if(This->freeSpace == MAX32 || This->freeSpace == 0) {
875 		register unsigned int i;
876 		size_t total;
877 
878 		total = 0L;
879 		for (i = 2; i < This->num_clus + 2; i++) {
880 			unsigned int r = fatDecode(This,i);
881 			if(r == 1) {
882 				return -1;
883 			}
884 			if (!r)
885 				total++;
886 		}
887 		This->freeSpace = total;
888 	}
889 	return sectorsToBytes((Stream_t*)This,
890 						  This->freeSpace * This->cluster_size);
891 }
892 
893 
894 /*
895  * Ensure that there is a minimum of total sectors free
896  */
getfreeMinClusters(Stream_t * Dir,size_t size)897 int getfreeMinClusters(Stream_t *Dir, size_t size)
898 {
899 	Stream_t *Stream = GetFs(Dir);
900 	DeclareThis(Fs_t);
901 	register unsigned int i, last;
902 	size_t total;
903 
904 	if(batchmode && This->freeSpace == MAX32)
905 		getfree(Stream);
906 
907 	if(This->freeSpace != MAX32) {
908 		if(This->freeSpace >= size)
909 			return 1;
910 		else {
911 			fprintf(stderr, "Disk full\n");
912 			got_signal = 1;
913 			return 0;
914 		}
915 	}
916 
917 	total = 0L;
918 
919 	/* we start at the same place where we'll start later to actually
920 	 * allocate the sectors.  That way, the same sectors of the FAT, which
921 	 * are already loaded during getfreeMin will be able to be reused
922 	 * during get_next_free_cluster */
923 	last = This->last;
924 
925 	if ( last < 2 || last >= This->num_clus + 2)
926 		last = 1;
927 	for (i=last+1; i< This->num_clus+2; i++){
928 		unsigned int r = fatDecode(This, i);
929 		if(r == 1) {
930 			goto exit_0;
931 		}
932 		if (!r)
933 			total++;
934 		if(total >= size)
935 			return 1;
936 	}
937 	for(i=2; i < last+1; i++){
938 		unsigned int r = fatDecode(This, i);
939 		if(r == 1) {
940 			goto exit_0;
941 		}
942 		if (!r)
943 			total++;
944 		if(total >= size)
945 			return 1;
946 	}
947 	fprintf(stderr, "Disk full\n");
948 	got_signal = 1;
949 	return 0;
950  exit_0:
951 	fprintf(stderr, "FAT error\n");
952 	return 0;
953 }
954 
955 
getfreeMinBytes(Stream_t * Dir,mt_size_t size)956 int getfreeMinBytes(Stream_t *Dir, mt_size_t size)
957 {
958 	Stream_t *Stream = GetFs(Dir);
959 	DeclareThis(Fs_t);
960 	size_t size2;
961 
962 	size2 = size  / (This->sector_size * This->cluster_size);
963 	if(size % (This->sector_size * This->cluster_size))
964 		size2++;
965 	return getfreeMinClusters(Dir, size2);
966 }
967 
968 
getStart(Stream_t * Dir,struct directory * dir)969 unsigned int getStart(Stream_t *Dir, struct directory *dir)
970 {
971 	Stream_t *Stream = GetFs(Dir);
972 	unsigned int first;
973 
974 	first = START(dir);
975 	if(fat32RootCluster(Stream))
976 		first |= STARTHI(dir) << 16;
977 	return first;
978 }
979 
fs_free(Stream_t * Stream)980 int fs_free(Stream_t *Stream)
981 {
982 	DeclareThis(Fs_t);
983 
984 	if(This->FatMap) {
985 		int i, nr_entries;
986 		nr_entries = (This->fat_len + SECT_PER_ENTRY - 1) /
987 			SECT_PER_ENTRY;
988 		for(i=0; i< nr_entries; i++)
989 			if(This->FatMap[i].data)
990 				free(This->FatMap[i].data);
991 		free(This->FatMap);
992 	}
993 	if(This->cp)
994 		cp_close(This->cp);
995 	return 0;
996 }
997