114 lines
3.0 KiB
C++
114 lines
3.0 KiB
C++
// 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 "string/string.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);
|
|
}
|
|
|
|
|
|
|