1 /* Copyright 1996-2006,2008,2009 Alain Knaff.
2 * This file is part of mtools.
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.
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.
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/>.
18 #include "sysincludes.h"
23 #include "file_name.h"
26 typedef long long fatBitMask;
28 typedef long fatBitMask;
31 typedef struct FatMap_t {
37 #define SECT_PER_ENTRY (sizeof(fatBitMask)*8)
38 #define ONE ((fatBitMask) 1)
40 static __inline__ int readSector(Fs_t *This, char *buf, unsigned int off,
43 return READS(This->Next, buf, sectorsToBytes((Stream_t *)This, off),
44 size << This->sectorShift);
48 static __inline__ int forceReadSector(Fs_t *This, char *buf, unsigned int off,
51 return force_read(This->Next, buf, sectorsToBytes((Stream_t *)This, off),
52 size << This->sectorShift);
56 static __inline__ int writeSector(Fs_t *This, char *buf, unsigned int off,
59 return WRITES(This->Next, buf, sectorsToBytes((Stream_t*)This, off),
60 size << This->sectorShift);
63 static __inline__ int forceWriteSector(Fs_t *This, char *buf, unsigned int off,
66 return force_write(This->Next, buf, sectorsToBytes((Stream_t*)This, off),
67 size << This->sectorShift);
71 static FatMap_t *GetFatMap(Fs_t *Stream)
76 Stream->fat_error = 0;
77 nr_entries = (Stream->fat_len + SECT_PER_ENTRY - 1) / SECT_PER_ENTRY;
78 map = NewArray(nr_entries, FatMap_t);
82 for(i=0; i< nr_entries; i++) {
91 static __inline__ int locate(Fs_t *Stream, size_t offset, int *slot, int *bit)
93 if(offset >= Stream->fat_len)
95 *slot = offset / SECT_PER_ENTRY;
96 *bit = offset % SECT_PER_ENTRY;
100 static __inline__ int fatReadSector(Fs_t *This, int sector, int slot,
101 int bit, int dupe, fatBitMask bitmap)
106 dupe = (dupe + This->primaryFat) % This->num_fat;
107 fat_start = This->fat_start + This->fat_len * dupe;
110 nr_sectors = SECT_PER_ENTRY - bit%SECT_PER_ENTRY;
115 /* first, read as much as the buffer can give us */
116 ret = readSector(This,
117 (char *)(This->FatMap[slot].data+(bit<<This->sectorShift)),
123 if((unsigned int) ret < This->sector_size) {
124 /* if we got less than one sector's worth, insist to get at
125 * least one sector */
126 ret = forceReadSector(This,
127 (char *) (This->FatMap[slot].data +
128 (bit << This->sectorShift)),
129 fat_start+sector, 1);
130 if(ret < (int) This->sector_size)
135 return ret >> This->sectorShift;
139 static int fatWriteSector(Fs_t *This, int sector, int slot, int bit, int dupe)
143 dupe = (dupe + This->primaryFat) % This->num_fat;
144 if(dupe && !This->writeAllFats)
145 return This->sector_size;
147 fat_start = This->fat_start + This->fat_len * dupe;
149 return forceWriteSector(This,
151 (This->FatMap[slot].data + bit * This->sector_size),
152 fat_start+sector, 1);
155 static unsigned char *loadSector(Fs_t *This,
156 unsigned int sector, fatAccessMode_t mode,
161 if(locate(This,sector, &slot, &bit) < 0)
164 if (((This->fat_len + SECT_PER_ENTRY - 1) / SECT_PER_ENTRY) <= slot) {
165 fprintf(stderr,"This should not happen\n");
166 fprintf(stderr, "fat_len = %d\n", This->fat_len);
167 fprintf(stderr, "SECT_PER_ENTRY=%d\n", (int)SECT_PER_ENTRY);
168 fprintf(stderr, "sector = %d slot = %d bit=%d\n",
170 fprintf(stderr, "left = %d",(int)
171 ((This->fat_len+SECT_PER_ENTRY-1) / SECT_PER_ENTRY));
175 if(!This->FatMap[slot].data) {
176 /* allocate the storage space */
177 This->FatMap[slot].data =
178 malloc(This->sector_size * SECT_PER_ENTRY);
179 if(!This->FatMap[slot].data)
181 memset(This->FatMap[slot].data, 0xee,
182 This->sector_size * SECT_PER_ENTRY);
185 if(! (This->FatMap[slot].valid & (ONE << bit))) {
188 for(i=0; i< This->num_fat; i++) {
189 /* read the sector */
190 ret = fatReadSector(This, sector, slot, bit, i,
191 This->FatMap[slot].valid);
195 "Error reading fat number %d\n", i);
198 if(This->FatMap[slot].valid)
199 /* Set recurs if there have already been
200 * sectors loaded in this bitmap long
206 /* all copies bad. Return error */
210 for(i=0; (int) i < ret; i++)
211 This->FatMap[slot].valid |= ONE << (bit + i);
213 if(!recurs && ret == 1)
214 /* do some prefetching, if we happened to only
216 loadSector(This, sector+1, mode, 1);
217 if(!recurs && batchmode)
218 for(i=0; i < 1024; i++)
219 loadSector(This, sector+i, mode, 1);
222 if(mode == FAT_ACCESS_WRITE) {
223 This->FatMap[slot].dirty |= ONE << bit;
226 return This->FatMap[slot].data + (bit << This->sectorShift);
230 static unsigned char *getAddress(Fs_t *Stream,
231 unsigned int num, fatAccessMode_t mode)
237 sector = num >> Stream->sectorShift;
239 if(sector == Stream->lastFatSectorNr &&
240 Stream->lastFatAccessMode >= mode)
241 ret = Stream->lastFatSectorData;
243 ret = loadSector(Stream, sector, mode, 0);
246 Stream->lastFatSectorNr = sector;
247 Stream->lastFatSectorData = ret;
248 Stream->lastFatAccessMode = mode;
250 offset = num & Stream->sectorMask;
255 static int readByte(Fs_t *Stream, int start)
257 unsigned char *address;
259 address = getAddress(Stream, start, FAT_ACCESS_READ);
268 * | byte n | byte n+1 | byte n+2 |
269 * |7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
270 * | | | | | | | | | | | | | | | | | | | | | | | | |
271 * | n+0.0 | n+0.5 | n+1.0 | n+1.5 | n+2.0 | n+2.5 |
272 * \_____ \____ \______/________/_____ /
273 * ____\______\________/ _____/ ____\_/
275 * | n+1.5 | n+0.0 | n+0.5 | n+2.0 | n+2.5 | n+1.0 |
276 * | FAT entry k | FAT entry k+1 |
280 * Get and decode a FAT (file allocation table) entry. Returns the cluster
281 * number on success or 1 on failure.
284 static unsigned int fat12_decode(Fs_t *Stream, unsigned int num)
286 unsigned int start = num * 3 / 2;
287 int byte0 = readByte(Stream, start);
288 int byte1 = readByte(Stream, start+1);
290 if (num < 2 || byte0 < 0 || byte1 < 0 || num > Stream->num_clus+1) {
291 fprintf(stderr,"[1] Bad address %d\n", num);
296 return (byte1 << 4) | ((byte0 & 0xf0)>>4);
298 return ((byte1 & 0xf) << 8) | byte0;
303 * Puts a code into the FAT table. Is the opposite of fat_decode(). No
304 * sanity checking is done on the code. Returns a 1 on error.
306 static void fat12_encode(Fs_t *Stream, unsigned int num, unsigned int code)
308 int start = num * 3 / 2;
309 unsigned char *address0 = getAddress(Stream, start, FAT_ACCESS_WRITE);
310 unsigned char *address1 = getAddress(Stream, start+1, FAT_ACCESS_WRITE);
313 /* (odd) not on byte boundary */
314 *address0 = (*address0 & 0x0f) | ((code << 4) & 0xf0);
315 *address1 = (code >> 4) & 0xff;
317 /* (even) on byte boundary */
318 *address0 = code & 0xff;
319 *address1 = (*address1 & 0xf0) | ((code >> 8) & 0x0f);
326 * | byte n | byte n+1 |
327 * |7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
328 * | | | | | | | | | | | | | | | | |
332 static unsigned int fat16_decode(Fs_t *Stream, unsigned int num)
334 unsigned char *address = getAddress(Stream, num << 1, FAT_ACCESS_READ);
337 return _WORD(address);
340 static void fat16_encode(Fs_t *Stream, unsigned int num, unsigned int code)
342 unsigned char *address = getAddress(Stream, num << 1, FAT_ACCESS_WRITE);
343 set_word(address, code);
347 static unsigned int fast_fat16_decode(Fs_t *Stream, unsigned int num)
349 unsigned short *address =
350 (unsigned short *) getAddress(Stream, num << 1,
357 static void fast_fat16_encode(Fs_t *Stream, unsigned int num, unsigned int code)
359 unsigned short *address =
360 (unsigned short *) getAddress(Stream, num << 1,
371 #define FAT32_HIGH 0xf0000000
372 #define FAT32_ADDR 0x0fffffff
374 static unsigned int fat32_decode(Fs_t *Stream, unsigned int num)
376 unsigned char *address = getAddress(Stream, num << 2, FAT_ACCESS_READ);
379 return _DWORD(address) & FAT32_ADDR;
382 static void fat32_encode(Fs_t *Stream, unsigned int num, unsigned int code)
384 unsigned char *address = getAddress(Stream, num << 2, FAT_ACCESS_WRITE);
385 set_dword(address,(code&FAT32_ADDR) | (_DWORD(address)&FAT32_HIGH));
389 static unsigned int fast_fat32_decode(Fs_t *Stream, unsigned int num)
391 unsigned int *address =
392 (unsigned int *) getAddress(Stream, num << 2,
396 return (*address) & FAT32_ADDR;
399 static void fast_fat32_encode(Fs_t *Stream, unsigned int num, unsigned int code)
401 unsigned int *address =
402 (unsigned int *) getAddress(Stream, num << 2,
404 *address = (*address & FAT32_HIGH) | (code & FAT32_ADDR);
409 * Write the FAT table to the disk. Up to now the FAT manipulation has
410 * been done in memory. All errors are fatal. (Might not be too smart
411 * to wait till the end of the program to write the table. Oh well...)
414 void fat_write(Fs_t *This)
416 unsigned int i, j, dups, bit, slot;
419 /*fprintf(stderr, "Fat write\n");*/
421 if (!This->fat_dirty)
424 dups = This->num_fat;
429 for(i=0; i<dups; i++){
431 for(slot=0;j<This->fat_len;slot++) {
432 if(!This->FatMap[slot].dirty) {
437 bit < SECT_PER_ENTRY && j<This->fat_len;
439 if(!(This->FatMap[slot].dirty & (ONE << bit)))
441 ret = fatWriteSector(This,j,slot, bit, i);
442 if (ret < (int) This->sector_size){
444 perror("error in fat_write");
448 "end of file in fat_write\n");
452 /* if last dupe, zero it out */
454 This->FatMap[slot].dirty &= ~(ONE<<bit);
458 /* write the info sector, if any */
459 if(This->infoSectorLoc && This->infoSectorLoc != MAX32) {
460 /* initialize info sector */
461 InfoSector_t *infoSector;
462 infoSector = (InfoSector_t *) safe_malloc(This->sector_size);
463 set_dword(infoSector->signature1, INFOSECT_SIGNATURE1);
464 memset(infoSector->filler1, 0, sizeof(infoSector->filler1));
465 memset(infoSector->filler2, 0, sizeof(infoSector->filler2));
466 set_dword(infoSector->signature2, INFOSECT_SIGNATURE2);
467 set_dword(infoSector->pos, This->last);
468 set_dword(infoSector->count, This->freeSpace);
469 set_word(infoSector->signature3, 0xaa55);
470 if(forceWriteSector(This, (char *)infoSector, This->infoSectorLoc, 1) !=
471 (signed int) This->sector_size)
472 fprintf(stderr,"Trouble writing the info sector\n");
476 This->lastFatAccessMode = FAT_ACCESS_READ;
485 int zero_fat(Fs_t *Stream, int media_descriptor)
488 unsigned int fat_start;
491 buf = malloc(Stream->sector_size);
493 perror("alloc fat sector buffer");
496 for(i=0; i< Stream->num_fat; i++) {
497 fat_start = Stream->fat_start + i*Stream->fat_len;
498 for(j = 0; j < Stream->fat_len; j++) {
500 memset(buf, 0, Stream->sector_size);
502 buf[0] = media_descriptor;
503 buf[2] = buf[1] = 0xff;
504 if(Stream->fat_bits > 12)
506 if(Stream->fat_bits > 16) {
514 if(forceWriteSector(Stream, (char *)buf,
516 (signed int) Stream->sector_size) {
518 "Trouble initializing a FAT sector\n");
526 Stream->FatMap = GetFatMap(Stream);
527 if (Stream->FatMap == NULL) {
528 perror("alloc fat map");
535 void set_fat12(Fs_t *This)
538 This->end_fat = 0xfff;
539 This->last_fat = 0xff6;
540 This->fat_decode = fat12_decode;
541 This->fat_encode = fat12_encode;
544 static char word_endian_test[] = { 0x34, 0x12 };
546 void set_fat16(Fs_t *This)
549 This->end_fat = 0xffff;
550 This->last_fat = 0xfff6;
552 if(sizeof(unsigned short) == 2 &&
553 * (unsigned short *) word_endian_test == 0x1234) {
554 This->fat_decode = fast_fat16_decode;
555 This->fat_encode = fast_fat16_encode;
557 This->fat_decode = fat16_decode;
558 This->fat_encode = fat16_encode;
562 static char dword_endian_test[] = { 0x78, 0x56, 0x34, 0x12 };
564 void set_fat32(Fs_t *This)
567 This->end_fat = 0xfffffff;
568 This->last_fat = 0xffffff6;
570 if(sizeof(unsigned int) == 4 &&
571 * (unsigned int *) dword_endian_test == 0x12345678) {
572 This->fat_decode = fast_fat32_decode;
573 This->fat_encode = fast_fat32_encode;
575 This->fat_decode = fat32_decode;
576 This->fat_encode = fat32_encode;
581 static int check_fat(Fs_t *This)
584 * This is only a sanity check. For disks with really big FATs,
585 * there is no point in checking the whole FAT.
589 unsigned int tocheck;
590 if(mtools_skip_check)
593 /* too few sectors in the FAT */
594 if(This->fat_len < NEEDED_FAT_SIZE(This))
596 /* we do not warn about too much sectors in FAT, which may
597 * happen when a partition has been shrunk using FIPS, or on
598 * other occurrences */
600 tocheck = This->num_clus;
601 if (tocheck + 1 >= This->last_fat) {
602 fprintf(stderr, "Too many clusters in FAT\n");
609 for ( i= 3 ; i < tocheck; i++){
610 f = This->fat_decode(This,i);
611 if (f == 1 || (f < This->last_fat && f > This->num_clus)){
613 "Cluster # at %d too big(%#x)\n", i,f);
614 fprintf(stderr,"Probably non MS-DOS disk\n");
623 * Read the first sector of FAT table into memory. Crude error detection on
624 * wrong FAT encoding scheme.
626 static int check_media_type(Fs_t *This, union bootsector *boot,
627 unsigned int tot_sectors)
629 unsigned char *address;
631 This->num_clus = (tot_sectors - This->clus_start) / This->cluster_size;
633 This->FatMap = GetFatMap(This);
634 if (This->FatMap == NULL) {
635 perror("alloc fat map");
639 address = getAddress(This, 0, FAT_ACCESS_READ);
642 "Could not read first FAT sector\n");
646 if(mtools_skip_check)
649 if(!address[0] && !address[1] && !address[2])
650 /* Some Atari disks have zeroes where Dos has media descriptor
651 * and 0xff. Do not consider this as an error */
654 if((address[0] != boot->boot.descr && boot->boot.descr >= 0xf0 &&
655 ((address[0] != 0xf9 && address[0] != 0xf7)
656 || boot->boot.descr != 0xf0)) || address[0] < 0xf0) {
658 "Bad media types %02x/%02x, probably non-MSDOS disk\n",
664 if(address[1] != 0xff || address[2] != 0xff){
665 fprintf(stderr,"Initial byte of fat is not 0xff\n");
672 static int fat_32_read(Fs_t *This, union bootsector *boot,
673 unsigned int tot_sectors)
677 This->fat_len = DWORD(ext.fat32.bigFat);
678 This->writeAllFats = !(boot->boot.ext.fat32.extFlags[0] & 0x80);
679 This->primaryFat = boot->boot.ext.fat32.extFlags[0] & 0xf;
680 This->rootCluster = DWORD(ext.fat32.rootCluster);
681 This->clus_start = This->fat_start + This->num_fat * This->fat_len;
683 /* read the info sector */
684 size = This->sector_size;
685 This->infoSectorLoc = WORD(ext.fat32.infoSector);
686 if(This->sector_size >= 512 &&
687 This->infoSectorLoc && This->infoSectorLoc != MAX32) {
688 InfoSector_t *infoSector;
689 infoSector = (InfoSector_t *) safe_malloc(size);
690 if(forceReadSector(This, (char *)infoSector,
691 This->infoSectorLoc, 1) ==
692 (signed int) This->sector_size &&
693 _DWORD(infoSector->signature1) == INFOSECT_SIGNATURE1 &&
694 _DWORD(infoSector->signature2) == INFOSECT_SIGNATURE2) {
695 This->freeSpace = _DWORD(infoSector->count);
696 This->last = _DWORD(infoSector->pos);
702 return(check_media_type(This, boot, tot_sectors) ||
707 static int old_fat_read(Fs_t *This, union bootsector *boot,
708 size_t tot_sectors, int nodups)
710 This->writeAllFats = 1;
711 This->primaryFat = 0;
712 This->dir_start = This->fat_start + This->num_fat * This->fat_len;
713 This->clus_start = This->dir_start + This->dir_len;
714 This->infoSectorLoc = MAX32;
719 if(check_media_type(This,boot, tot_sectors))
722 if(This->num_clus >= FAT12) {
724 /* third FAT byte must be 0xff */
725 if(!mtools_skip_check && readByte(This, 3) != 0xff)
730 return check_fat(This);
734 * Read the first sector of the FAT table into memory and initialize
737 int fat_read(Fs_t *This, union bootsector *boot,
738 size_t tot_sectors, int nodups)
743 This->freeSpace = MAX32;
744 This->lastFatSectorNr = 0;
745 This->lastFatSectorData = 0;
748 return old_fat_read(This, boot, tot_sectors, nodups);
750 return fat_32_read(This, boot, tot_sectors);
754 unsigned int fatDecode(Fs_t *This, unsigned int pos)
758 ret = This->fat_decode(This, pos);
759 if(ret && (ret < 2 || ret > This->num_clus+1) && ret < This->last_fat) {
760 fprintf(stderr, "Bad FAT entry %d at %d\n", ret, pos);
766 /* append a new cluster */
767 void fatAppend(Fs_t *This, unsigned int pos, unsigned int newpos)
769 This->fat_encode(This, pos, newpos);
770 This->fat_encode(This, newpos, This->end_fat);
771 if(This->freeSpace != MAX32)
775 /* de-allocates the given cluster */
776 void fatDeallocate(Fs_t *This, unsigned int pos)
778 This->fat_encode(This, pos, 0);
779 if(This->freeSpace != MAX32)
783 /* allocate a new cluster */
784 void fatAllocate(Fs_t *This, unsigned int pos, unsigned int value)
786 This->fat_encode(This, pos, value);
787 if(This->freeSpace != MAX32)
791 void fatEncode(Fs_t *This, unsigned int pos, unsigned int value)
793 unsigned int oldvalue = This->fat_decode(This, pos);
794 This->fat_encode(This, pos, value);
795 if(This->freeSpace != MAX32) {
803 unsigned int get_next_free_cluster(Fs_t *This, unsigned int last)
807 if(This->last != MAX32)
811 last >= This->num_clus+1)
814 for (i=last+1; i< This->num_clus+2; i++) {
815 unsigned int r = fatDecode(This, i);
824 for(i=2; i < last+1; i++) {
825 unsigned int r = fatDecode(This, i);
835 fprintf(stderr,"No free cluster %d %d\n", This->preallocatedClusters,
839 fprintf(stderr, "FAT error\n");
843 int fat_error(Stream_t *Dir)
845 Stream_t *Stream = GetFs(Dir);
849 fprintf(stderr,"Fat error detected\n");
851 return This->fat_error;
854 int fat32RootCluster(Stream_t *Dir)
856 Stream_t *Stream = GetFs(Dir);
859 if(This->fat_bits == 32)
860 return This->rootCluster;
867 * Get the amount of free space on the diskette
870 mt_size_t getfree(Stream_t *Dir)
872 Stream_t *Stream = GetFs(Dir);
875 if(This->freeSpace == MAX32 || This->freeSpace == 0) {
876 register unsigned int i;
880 for (i = 2; i < This->num_clus + 2; i++) {
881 unsigned int r = fatDecode(This,i);
888 This->freeSpace = total;
890 return sectorsToBytes((Stream_t*)This,
891 This->freeSpace * This->cluster_size);
896 * Ensure that there is a minimum of total sectors free
898 int getfreeMinClusters(Stream_t *Dir, size_t size)
900 Stream_t *Stream = GetFs(Dir);
902 register unsigned int i, last;
905 if(batchmode && This->freeSpace == MAX32)
908 if(This->freeSpace != MAX32) {
909 if(This->freeSpace >= size)
912 fprintf(stderr, "Disk full\n");
920 /* we start at the same place where we'll start later to actually
921 * allocate the sectors. That way, the same sectors of the FAT, which
922 * are already loaded during getfreeMin will be able to be reused
923 * during get_next_free_cluster */
926 if ( last < 2 || last >= This->num_clus + 2)
928 for (i=last+1; i< This->num_clus+2; i++){
929 unsigned int r = fatDecode(This, i);
938 for(i=2; i < last+1; i++){
939 unsigned int r = fatDecode(This, i);
948 fprintf(stderr, "Disk full\n");
952 fprintf(stderr, "FAT error\n");
957 int getfreeMinBytes(Stream_t *Dir, mt_size_t size)
959 Stream_t *Stream = GetFs(Dir);
963 size2 = size / (This->sector_size * This->cluster_size);
964 if(size % (This->sector_size * This->cluster_size))
966 return getfreeMinClusters(Dir, size2);
970 unsigned int getStart(Stream_t *Dir, struct directory *dir)
972 Stream_t *Stream = GetFs(Dir);
976 if(fat32RootCluster(Stream))
977 first |= STARTHI(dir) << 16;
981 int fs_free(Stream_t *Stream)
987 nr_entries = (This->fat_len + SECT_PER_ENTRY - 1) /
989 for(i=0; i< nr_entries; i++)
990 if(This->FatMap[i].data)
991 free(This->FatMap[i].data);