// vfat.c // Author: Josh Holtrop // Date: 03/11/04 // Modified: 03/22/04 #include "vfat.h" #include "hos_defines.h" #include "fs/vfs.h" #include "mm/vmm.h" #include "lang/cstring.h" //From Microsoft's FAT32 File System Specification DSKSZTOSECPERCLUS DskTableFAT16 [] = { { 8400, 0}, /* disks up to 4.1 MB, the 0 value for SecPerClusVal trips an error */ { 32680, 2}, /* disks up to 16 MB, 1k cluster */ { 262144, 4}, /* disks up to 128 MB, 2k cluster */ { 524288, 8}, /* disks up to 256 MB, 4k cluster */ { 1048576, 16}, /* disks up to 512 MB, 8k cluster */ /* The entries after this point are not used unless FAT16 is forced */ // { 2097152, 32}, /* disks up to 1 GB, 16k cluster */ // { 4194304, 64}, /* disks up to 2 GB, 32k cluster */ { 0xFFFFFFFF, 0} /* any disk greater than 2GB, 0 value for SecPerClusVal trips an error */ }; //From Microsoft's FAT32 File System Specification DSKSZTOSECPERCLUS DskTableFAT32 [] = { { 66600, 0}, /* disks up to 32.5 MB, the 0 value for SecPerClusVal trips an error */ { 532480, 1}, /* disks up to 260 MB, .5k cluster */ { 16777216, 8}, /* disks up to 8 GB, 4k cluster */ { 33554432, 16}, /* disks up to 16 GB, 8k cluster */ { 67108864, 32}, /* disks up to 32 GB, 16k cluster */ { 0xFFFFFFFF, 64}/* disks greater than 32GB, 32k cluster */ }; int vfat_identify(vfat_bpb *bpb) { int rootDirSectors = ((bpb->rootEntries * 32) + (bpb->bytesPerSector - 1)) / bpb->bytesPerSector; int totalSectors = bpb->totalSectors16 ? bpb->totalSectors16 : bpb->totalSectors32; int fatSectors = bpb->sectorsPerFAT16 ? bpb->sectorsPerFAT16 : bpb->sectorsPerFAT32; int dataSectors = totalSectors - (bpb->reservedSectors + bpb->numFATs * fatSectors + rootDirSectors); int clusters = dataSectors / bpb->sectorsPerCluster; if (clusters < 4085) return 12; if (clusters < 65525) return 16; return 32; } int vfat_format(Volume *vol) { } FILE *vfat_open(char *fileName, dword attributes, Volume *vol) { while (*fileName == '/') ++fileName; if (strlen(fileName) < 1) return 0; vfat_bpb *bpb = vfat_getBootSector(vol); if (!bpb) return 0; byte *fat = vfat_loadFAT(vol, bpb); if (!fat) { free(bpb); return 0; } int segs = string_split(fileName); //number of sections of path (1=file is in root directory) int me = vfat_identify(bpb); if (me != 32) { if (segs == 1) //we are looking for the file in the root directory { vfat_getEntryInRoot(vol, bpb, fileName, 0); } } else { } } byte *vfat_loadFAT(Volume *vol, vfat_bpb *bpb) { int fatSize = bpb->sectorsPerFAT16 ? bpb->sectorsPerFAT16 : bpb->sectorsPerFAT32; byte *fat = malloc(fatSize << 9); //512 bytes per sector if (!fat) return 0; if (vfs_readSectorn(vol, bpb->reservedSectors, fat, fatSize)) { free(fat); return 0; } return fat; } vfat_bpb *vfat_getBootSector(Volume *vol) { vfat_bpb *bs; if (!(bs = malloc(512))) return 0; vfs_readSector(vol, 0, bs); return bs; } int vfat_close(FILE *fp) { return free(fp); }