// vfat.h // Author: Josh Holtrop // Date: 03/11/04 // Modified: 03/22/04 #ifndef __HOS_VFAT__ #define __HOS_VFAT__ __HOS_VFAT__ #include "hos_defines.h" #include "fs/vfs.h" #define VFAT_FAT12_EOCL 0x0FF8 // end-of-cluster chain reached if FatValue >= EOCL #define VFAT_FAT16_EOCL 0xFFF8 #define VFAT_FAT32_EOCL 0x0FFFFFF8 #define VFAT_FAT12_EOC 0x0FFF // end-of-cluster chain value #define VFAT_FAT16_EOC 0xFFFF #define VFAT_FAT32_EOC 0x0FFFFFFF #define VFAT_FAT12_BAD 0x0FF7 // bad cluster mark #define VFAT_FAT16_BAD 0xFFF7 #define VFAT_FAT32_BAD 0x0FFFFFF7 #define VFAT_DIRENTRY_FREE 0xE5 #define VFAT_DIRENTRY_FREE_LAST 0x00 typedef struct { byte jmpBoot[3]; // {0xEB, 0x??, 0x90} or {0xE9, 0x??, 0x??} char OEMName[8]; // any 8-char string (def. "MSWIN4.1") word bytesPerSector; // 512 (default), 1024, 2048, 4096 byte sectorsPerCluster; // 1 (default), 2, 4, 8, 16, 32, 64, 128 word reservedSectors; // 1 (fat12/16), 32 (fat32) byte numFATs; // 2 word rootEntries; // number of 32-byte root directory entries (224 for 1440k floppy) - 0 for fat32 word totalSectors16; // total number of sectors in volume (2880 for floppy) - 0 for fat32 byte media; // >= 0xF0 valid, 0xF8 (default non-removable), 0xF0 (default removable), must match lsb of FAT[0] word sectorsPerFAT16; // number of sectors in FAT (9 for floppy) word sectorsPerTrack; // (18 for floppy) word numHeads; // number of heads (2 for floppy) dword hiddenSectors; // 0 dword totalSectors32; // 0, non-zero for fat32 volumes /* FAT32 specific members */ dword sectorsPerFAT32; // number of sectors in a fat for fat32 volumes word extFlags; // bits 0-3 active fat, bit 7 {0 = mirror all FATs, 1 = only use 1 FAT} word fsVersion; // fat32 version (0:0) dword rootCluster; // first cluster of root directory (default 2) word fsInfo; // sector number of FSINFO block (default 1) word bootCopy; // sector of backup boot record (default 6) } __attribute__ ((packed)) vfat_bpb; typedef struct { dword leadSignature; // 0x41615252 byte reserved1[480]; dword structSignature; // 0x61417272 dword lastFree; // last known free cluster (0xFFFFFFFF == unknown) dword nextFree; // start looking for free clusters here (0xFFFFFFFF == unknown) byte reserved2[12]; dword trailSignature; // 0xAA550000 } __attribute__ ((packed)) vfat_fsinfo; typedef struct { char fileName[8]; // file name, 8 char. max, pad w/ spaces char fileExt[3]; // file extension, 3 char. max, pad w/ spaces byte attributes; // file attributes, read-only, etc. byte reserved; // 0 byte timeTenths; // 0-199 word time; // time of creation word date; // date of creation word adate; // last accessed date word clusterHigh; // 0 for fat12/16 word wtime; // last write time word wdate; // last write date word clusterLow; // LSW of first cluster of file data dword fileSize; } __attribute__ ((packed)) vfat_dirEntry; typedef struct { byte order; word name0_4[5]; // filename - first 5 characters (unicode) byte attributes; // must be VFAT_LONG_NAME byte type; // 0 = part of long name byte checksum; // checksum of short entry at end of long entry set word name5_10[6]; // filename - next 6 characters (unicode) word clusterLow; // 0 word name11_12[2]; // filename - next 2 characters } __attribute__ ((packed)) vfat_lfnEntry; #define VFAT_READ_ONLY 0x01 #define VFAT_HIDDEN 0x02 #define VFAT_SYSTEM 0x04 #define VFAT_VOLUME 0x08 #define VFAT_DIRECTORY 0x10 #define VFAT_ARCHIVE 0x20 #define VFAT_LONG_NAME 0x0F // VFAT_READ_ONLY | VFAT_HIDDEN | VFAT_SYSTEM | VFAT_VOLUME #define VFAT_ATTR_MASK 0x3F // VFAT_READ_ONLY | VFAT_HIDDEN | VFAT_SYSTEM | VFAT_VOLUME | VFAT_DIRECTORY | VFAT_ARCHIVE #define VFAT_ORDER_MASK 0x40 /* * Illegal file name characters: * Values less than 0x20 except for 0x05. 0x05 signifies that the actual filename character is 0xE5 * 0x22 ("), 0x2A (*) * 0x2E (.), 0x2F (/), 0x3A (:) * 0x3C (<), 0x3E (>), 0x3F (?), 0x5C (\), 0x7C (|) * The following are illegal in 8.3 but legal in LFN: * 0x2B (+), 0x2C (,), 0x3B (;), 0x3D (=), 0x5B ([), 0x5D (]) */ //From Microsoft's FAT32 File System Specification typedef struct { dword diskSize; byte sectorsPerCluster; } DSKSZTOSECPERCLUS; // sector[510] == 0x55 // sector[511] == 0xAA int vfat_identify(vfat_bpb *bpb); int vfat_format(Volume *vol); FILE *vfat_open(char *fileName, dword attributes, Volume *vol); vfat_bpb *vfat_getBootSector(Volume *vol); int vfat_close(FILE *fp); byte *vfat_loadFAT(Volume *vol, vfat_bpb *bpb) #endif