Unit FATFS
Return to Unit Reference
Contents
Description
Ultibo FAT12/16/32/exFAT interface unit
Notes:
Based on information from numerous sources, primarily the document fatgen103.pdf from Microsoft. FAT Disk Blocks are based on reading a group of sectors into a block at once. The BlockNo of each block is therefore the FAT entry no of the first FAT in the block.
The use of IsEightDotThree and GenerateShortName(Ex) from the UltiboUtils unit should be replaced by internal routines optimised for maximum performance. All Block and Entry Offsets have been expanded to 32bit to avoid 16bit overflow on 64K clusters.
Constants
fat*
fatFAT12 = 0;
|
|
fatFAT16 = 1;
|
|
fatFAT32 = 2;
|
|
fatDotName = '.';
|
|
fatDotDotName = '..';
|
|
fatNameCount = 8;
|
|
fatExtCount = 3;
|
|
fatLabelMask = '*';
|
|
fatLabelCount = 11;
|
|
fatOemName = 'MSWIN4.1';
|
|
fatDefaultName = 'NO NAME';
|
|
fatFlagNone = $00;
|
|
fatFlagName = $08;
|
|
fatFlagExt = $10;
|
|
fatFlagBoth = $18;
|
|
lfnMaxName = 2048;
|
Buffer size for lfn handling |
lfnMaxAlias = 999999;
|
Max number of lfn aliases (ie ~999999) |
lfnMaxNameAlias = 4;
|
|
lfnMaxHashAlias = 999;
|
|
lfnMaxHashShift = 16;
|
|
fatMaxFileSize = 4294967295;
|
Max size in bytes of a File (4GB) |
fatMaxDirectorySize = 2097152;
|
Max size in bytes of a Directory (2MB = 65536 * 32) |
fatMinClusterSize = 512;
|
|
fatMaxClusterSize = 65536;
|
|
fat12MinClusters = 3;
|
|
fat16MinClusters = 4085;
|
Smallest Number of Clusters on a FAT16 volume, is FAT12 if less |
fat32MinClusters = 65525;
|
Smallest Number of Clusters on a FAT32 volume, is FAT16 if less |
fat12MinSectors = 6;
|
Number of Sectors at which we cannot create a FAT12 (Not possible due to 512 Root entries) |
fat12MinSectors = 798;
|
Number of Sectors at which we cannot create a FAT12 |
fat12MaxSectors = 32623;
|
Number of Sectors at which we insist on creating FAT16 |
fat16MinSectors = 8400;
|
Number of Sectors at which we cannot create a FAT16 |
fat16MaxSectors = 1048576;
|
Number of Sectors at which we insist on creating FAT32 |
fat32MinSectors = 66600;
|
Number of Sectors at which we cannot create a FAT32 |
fat32MaxSectors = $FFFFFFFF;
|
No limit on maximum size of a FAT32 |
Note: In FAT12 EOC will be >= $0FF0 due to Media ID on Floppy | |
fat12EndOfFile = $0FF0;
|
Some Code sets values from $0FF0 - $0FFF as EOF |
fat12EndOfFile = $0FF8;
|
Some Code sets values from $0FF8 - $0FFF as EOF |
fat12EndOfCluster = $0FFF;
|
EOF Mark, Check for >= $0FF0 - See Above |
fat12FreeCluster = $0000;
|
Available for Use |
fat12BadCluster = $0FF7;
|
Bad Cluster Mark - Do Not Use |
fat12MediaCluster = $0F00;
|
First Cluster - $0F00 + MediaID from BPB Usually $0FF8 |
fat12Reserved0 = $0FF0;
|
Reserved Cluster Nos - Do Not Use (Due to Media ID on Floppy) |
fat12Reserved1 = $0FF1;
|
|
fat12Reserved2 = $0FF2;
|
|
fat12Reserved3 = $0FF3;
|
|
fat12Reserved4 = $0FF4;
|
|
fat12Reserved5 = $0FF5;
|
|
fat12Reserved6 = $0FF6;
|
|
fat16EndOfFile = $FFF8;
|
Some Code sets values from $FFF8 - $FFFF as EOF |
fat16EndOfCluster = $FFFF;
|
EOF Mark, Check for >= $FFF8 - See Above |
fat16FreeCluster = $0000;
|
Available for Use |
fat16BadCluster = $FFF7;
|
Bad Cluster Mark - Do Not Use |
fat16MediaCluster = $FF00;
|
First Cluster - $FF00 + MediaID from BPB Usually $FFF8 |
fat32EndOfFile = $0FFFFFF8;
|
Some Code sets values from $0FFFFFF8 - $0FFFFFFF as EOF |
fat32EndOfCluster = $0FFFFFFF;
|
EOF Mark, Check for >= $0FFFFFF8 - See Above |
fat32FreeCluster = $00000000;
|
Available for Use |
fat32BadCluster = $0FFFFFF7;
|
Bad Cluster Mark - Do Not Use |
fat32MediaCluster = $0FFFFF00;
|
First Cluster - $0FFFFF00 + MediaID from BPB Usually $0FFFFFF8 |
fat16CleanShutdown = $8000;
|
Second Cluster - EndOfCluster + Bits |
fat16HardError = $4000;
|
Second Cluster - EndOfCluster + Bits |
fat32CleanShutdown = $08000000;
|
Second Cluster - EndOfCluster + Bits |
fat32HardError = $04000000;
|
Second Cluster - EndOfCluster + Bits |
fat32ReservedBits = $F0000000;
|
Bits 31-29 must be preserved on FAT32 |
fatBootSector = 0;
|
|
fatFreeCluster = 0;
|
|
fatStartCluster = 2;
|
Lowest allocatable cluster number |
fatUnevenCluster = $00000001;
|
|
fatUnknownCluster = $FFFFFFFF;
|
|
fatEntryFree = $E5;
|
|
fatEntryFreeAll = $00;
|
|
fatEntrySpecial = $05;
|
If real first char is $E5 |
fatEntryPadding = $20;
|
Padded with spaces (32) |
fatEntrySize = 32;
|
Size of a FAT Directory Entry (or LFNDirectoryEntry) |
lfnEntryMax= $3F;
|
Maximum count of an LFN entry |
lfnEntryLast = $40;
|
Marker for LFN last entry |
lfnEntryMask = $BF;
|
Mask for LFN entry count |
lfnEntryChars = 13;
|
Number of characters per LFN entry |
lfnEntryNull = $0000;
|
Null terminator on LFN when applicable |
lfnEntryPadding = $FFFF;
|
Empty LFN chars padded with (65535) |
lfnAttributeMask = (faReadOnly or faHidden or faSysFile or faVolumeID);
|
Not Used - See faLongName |
fat32LeadSignature = $41615252;
|
RRaA |
fat32StructSignature = $61417272;
|
rrAa |
fat32TrailSignature = $AA550000;
|
Standard Boot Sector signature |
fatDotChar:Byte = $2E;
|
Checked separately from Invalid chars due to . and .. entries |
fatSpaceChar:Byte = $20;
|
|
fatBaseChars:set of Byte = [$00..$19];
|
0..31 (Dont include $20 as that is checked separately) |
fatInvalidChars:set of Byte = [$22,$2A,$2B,$2C,$2F,$3A,$3B,$3C,$3D,$3E,$3F,$5B,$5C,$5D,$7C];
|
34,42,43,44,47,58,59,60,61,62,63,91,92,93,124 (Dont include $2E as that is checked separately) |
fatLowercaseChars:set of Byte = [$61..$7A];
|
97..122 (These dont account for the code page) |
fatParams*
Used for FAT entry block loading | |
fatMaxParams = 11;
|
|
fatParams:array[0..fatMaxParams] of TFATParams = (
|
|
SectorSize,FATType,BlockShiftCount,EntriesPerBlock,SectorsPerBlock | |
FAT12 | |
(SectorSize:512; FATType:ftFAT12; BlockShiftCount:10; EntriesPerBlock:1024; SectorsPerBlock:3),
|
|
(SectorSize:1024; FATType:ftFAT12; BlockShiftCount:11 ;EntriesPerBlock:2048; SectorsPerBlock:3),
|
|
(SectorSize:2048; FATType:ftFAT12; BlockShiftCount:12; EntriesPerBlock:4096; SectorsPerBlock:3),
|
|
(SectorSize:4096; FATType:ftFAT12; BlockShiftCount:13; EntriesPerBlock:8192; SectorsPerBlock:3),
|
|
FAT16 | |
(SectorSize:512; FATType:ftFAT16; BlockShiftCount:10; EntriesPerBlock:1024; SectorsPerBlock:4),
|
|
(SectorSize:1024; FATType:ftFAT16; BlockShiftCount:11; EntriesPerBlock:2048; SectorsPerBlock:4),
|
|
(SectorSize:2048; FATType:ftFAT16; BlockShiftCount:12; EntriesPerBlock:4096; SectorsPerBlock:4),
|
|
(SectorSize:4096 ;FATType:ftFAT16 ;BlockShiftCount:13; EntriesPerBlock:8192; SectorsPerBlock:4),
|
|
FAT32 | |
(SectorSize:512; FATType:ftFAT32; BlockShiftCount:10; EntriesPerBlock:1024; SectorsPerBlock:8),
|
|
(SectorSize:1024; FATType:ftFAT32; BlockShiftCount:11; EntriesPerBlock:2048; SectorsPerBlock:8),
|
|
(SectorSize:2048; FATType:ftFAT32; BlockShiftCount:12; EntriesPerBlock:4096; SectorsPerBlock:8),
|
|
(SectorSize:4096; FATType:ftFAT32; BlockShiftCount:13; EntriesPerBlock:8192; SectorsPerBlock:8));
|
fat12Geometry*
Used for FAT formatting (Floppy Disk only) | |
fat12MaxGeometry = 4;
|
|
fat12Geometry:array[0..fat12MaxGeometry] of TFATGeometry = (
|
|
FloppyType,SectorsPerFat,SectorsPerCluster,RootEntryCount,MediaId | |
(FloppyType:ft360K; SectorsPerFat:2; SectorsPerCluster:2; RootEntryCount:112; MediaId:$FD),
|
|
(FloppyType:ft12M;SectorsPerFat:7;SectorsPerCluster:1;RootEntryCount:224;MediaId:$F9),
|
|
(FloppyType:ft720K; SectorsPerFat:3; SectorsPerCluster:2; RootEntryCount:112; MediaId:$F9),
|
|
(FloppyType:ft144M; SectorsPerFat:9; SectorsPerCluster:1; RootEntryCount:224; MediaId:$F0),
|
|
(FloppyType:ft288M; SectorsPerFat:9; SectorsPerCluster:2; RootEntryCount:240; MediaId:$F0));
|
fat_ClusterSize*
Used for FAT formatting (Fixed Disk only) | |
fat12MaxClusterSize = 2;
|
|
fat12ClusterSize:array[0..fat12MaxClusterSize] of TFATClusterSize = (
|
|
SectorCount,SectorsPerCluster | |
(SectorCount:6; SectorsPerCluster:0),
|
up to 3 KB, the 0 value for SectorsPerCluster trips an error (Not possible due to 512 Root entries) |
(SectorCount:798; SectorsPerCluster:0),
|
up to 399 KB, the 0 value for SectorsPerCluster trips an error |
(SectorCount:32623; SectorsPerCluster:8),
|
up to 15.9 MB, 4k cluster |
(SectorCount:$FFFFFFFF; SectorsPerCluster:0));
|
greater than 15.9 MB, 0 value for SectorsPerCluster trips an error |
See FAT12 Notes for Min/Max and Values | |
fat16MaxClusterSize = 8;
|
|
fat16ClusterSize:array[0..fat16MaxClusterSize] of TFATClusterSize = (
|
|
SectorCount,SectorsPerCluster | |
(SectorCount:8400; SectorsPerCluster:0),
|
up to 4.1 MB, the 0 value for SectorsPerCluster trips an error |
(SectorCount:32680; SectorsPerCluster:2),
|
up to 16 MB, 1k cluster |
(SectorCount:262144; SectorsPerCluster:4),
|
up to 128 MB, 2k cluster |
(SectorCount:524288; SectorsPerCluster:8),
|
up to 256 MB, 4k cluster |
(SectorCount:1048576; SectorsPerCluster:16),
|
up to 512 MB, 8k cluster |
The entries after this point are not used unless FAT16 is forced | |
(SectorCount:2097152; SectorsPerCluster:32),
|
up to 1 GB, 16k cluster |
(SectorCount:4194304; SectorsPerCluster:64),
|
up to 2 GB, 32k cluster |
(SectorCount:8388608; SectorsPerCluster:128),
|
up to 4 GB, 64k cluster |
(SectorCount:$FFFFFFFF;SectorsPerCluster:0));
|
greater than 4 GB, 0 value for SectorsPerCluster trips an error |
fat32MaxClusterSize = 5;
|
|
fat32ClusterSize:array[0..fat32MaxClusterSize] of TFATClusterSize = (
|
|
SectorCount,SectorsPerCluster | |
(SectorCount:66600; SectorsPerCluster:0),
|
up to 32.5 MB, the 0 value for SectorsPerCluster trips an error |
(SectorCount:532480 ;SectorsPerCluster:1),
|
up to 260 MB, .5k cluster |
The entries before this point are not used unless FAT32 is forced | |
(SectorCount:16777216; SectorsPerCluster:8),
|
up to 8 GB, 4k cluster |
(SectorCount:33554432; SectorsPerCluster:16),
|
up to 16 GB, 8k cluster |
(SectorCount:67108864; SectorsPerCluster:32),
|
up to 32 GB, 16k cluster |
(SectorCount:$FFFFFFFF; SectorsPerCluster:64));
|
greater than 32 GB, 32k cluster |
fatPartitionType*
fatMaxPartitionType = 5;
|
|
fatPartitionType:array[0..fatMaxPartitionType] of TFATPartitionType = (
|
|
Excluded,Extended,SectorCount,PartitionId,LBAType | |
Extended Partitions | |
(Excluded:False; Extended:True; SectorCount:$FFFFFFFF ;PartitionId:pidExtended; LBAType:pidExtLBA),
|
any size, Extended |
Primary and Logical Partitions | |
Unused | |
(Excluded:False; Extended:False; SectorCount:798; PartitionId:pidUnused; LBAType:pidUnused),
|
up to 399 KB, Unused (Unused type trips an error) |
FAT12 | |
(Excluded:False; Extended:False; SectorCount:32680; PartitionId:pidFAT12; LBAType:pidFAT12),
|
up to 16 MB, FAT12 |
FAT16 | |
(Excluded:False; Extended:False; SectorCount:65360; PartitionId:pidFAT16; LBAType:pidFAT16LBA),
|
up to 32 MB, FAT16 |
(Excluded:False; Extended:False; SectorCount:1048576; PartitionId:pidFAT16HUGE; LBAType:pidFAT16LBA),
|
up to 512 MB, FAT16 HUGE |
FAT32 | |
(Excluded:False; Extended:False; SectorCount:$FFFFFFFF; PartitionId:pidFAT32; LBAType:pidFAT32LBA));
|
above 512 MB, FAT32 |
Type definitions
FATFS specific types
TFATType = (ftNONE,ftFAT12,ftFAT16,ftFAT32);
|
FATFS params
TFATParams = record
Note: (Not Packed) Block values for various Sector sizes. | |
SectorSize:Word;
|
|
FATType:TFATType;
|
|
BlockShiftCount:Word;
|
|
EntriesPerBlock:LongWord;
|
|
SectorsPerBlock:LongWord;
|
FATFS geometry
TFATGeometry = record
Note: (Not Packed) FAT12 values for various Floppy Types. | |
FloppyType:TFloppyType;
|
|
SectorsPerFat:LongWord;
|
|
SectorsPerCluster:LongWord;
|
|
RootEntryCount:LongWord;
|
|
MediaId:Byte;
|
FATFS cluster size
TFATClusterSize = record
Note: (Not Packed) Sectors per Cluster for various disk sizes (Fixed Disk only). | |
SectorCount:LongWord;
|
Based on 512 bytes per sector only |
SectorsPerCluster:LongWord;
|
FATFS partition type
TFATPartitionType = record
Note: (Not Packed) Partition Type for various disk sizes (Fixed Disk only). | |
Excluded:Boolean;
|
Entry is excluded from FAT Partition Type check |
Extended:Boolean;
|
|
SectorCount:LongWord;
|
Based on 512 bytes per sector only |
PartitionId:Byte;
|
|
LBAType:Byte;
|
FATFS name
PFATName = ^TFATName;
TFATName = packed record
Note: 11 Bytes | |
Name:array[0..7] of Char;
|
File Name |
Ext:array[0..2] of Char;
|
File Extension |
FATSFS directory
PFATDirectory = ^TFATDirectory;
TFATDirectory = packed record
Note: 32 Bytes | |
Name:array[0..7] of Char;
|
File Name |
Ext:array[0..2] of Char;
|
File Extension |
Attribute:Byte;
|
File Attributes - See Standard Values |
Reserved:Byte;
|
Always 0 (See below) |
CaseFlags:Byte;
|
Set to $08 if Name, $10 if Extension or $18 if both |
CreateTimeMsecs:Byte;
|
|
CreateTime:Word;
|
|
CreateDate:Word;
|
|
LastAccessDate:Word;
|
|
FirstClusterHigh:Word;
|
High word of the start cluster (FAT32 Only) |
WriteTime:Word;
|
|
WriteDate:Word;
|
|
FirstClusterLow:Word;
|
Low Word of Start Cluster all versions |
Length:LongWord;
|
LFN directory
PLFNDirectory = ^TLFNDirectory;
TLFNDirectory = packed record
Note: 32 Bytes | |
Order:Byte;
|
Bit 6 = 1 if last LFN in chain, Bits 5-0 = Order of LFN chunks for this File |
Name1:array[0..4] of WideChar;
|
First 5 Characters in this chunk |
Attribute:Byte;
|
Always 0Fh - Volume, System, Hidden, ReadOnly |
FileType:Byte;
|
Usually 00h |
Checksum:Byte;
|
Checksum calculated on 8.3 name |
Name2:array[0..5] of WideChar;
|
Next 6 Characters in this chunk |
Reserved:Word;
|
Always 0000h - FirstCluster in Standard Entry |
Name3:array[0..1] of WideChar;
|
Next 2 Characters in this chunk |
FATFS info sector
PFATInfoSector = ^TFATInfoSector;
TFATInfoSector = packed record
LeadSignature:LongWord;
|
Signature "RRaA" or 41615252h |
Reserved1:array[0..479] of Byte;
|
Always 0 |
StructureSignature:LongWord;
|
Signature "rrAa" or 61417272h |
FreeClusterCount:LongWord;
|
Free Clusters $FFFFFFFF if unknown |
LastFreeCluster:LongWord;
|
Most recently allocated cluster $FFFFFFFF if unknown |
Reserved2:array[0..11] of Byte;
|
Always 0 |
TrailSignature:LongWord;
|
Signature AA550000h |
Class definitions
FAT recognizer
TFATRecognizer = class(TRecognizer)
constructor Create(ADriver:TFileSysDriver);
|
|
private
| |
FCaseFlags:Boolean;
|
|
FLongNames:Boolean;
|
|
FOemConvert:Boolean;
|
|
FNumericTail:Boolean;
|
|
function CheckLBA:Boolean;
|
|
function CheckFAT32:Boolean;
|
|
function CheckBootSector(ABootSector:PBootSector; const AStartSector:Int64; ASectorCount:LongWord):Boolean;
|
|
protected
| |
function GetName:String; override;
|
|
public
| |
property CaseFlags:Boolean read FCaseFlags write FCaseFlags;
|
|
property LongNames:Boolean read FLongNames write FLongNames;
|
|
property OemConvert:Boolean read FOemConvert write FOemConvert;
|
|
property NumericTail:Boolean read FNumericTail write FNumericTail;
|
|
function RecognizePartitionId(APartitionId:Byte):Boolean; override;
|
|
function RecognizeBootSector(ABootSector:PBootSector; const AStartSector,ASectorCount:Int64):Boolean; override;
|
|
function RecognizePartition(APartition:TDiskPartition):Boolean; override;
|
|
function RecognizeVolume(AVolume:TDiskVolume):Boolean; override;
|
|
function MountVolume(AVolume:TDiskVolume; ADrive:TDiskDrive):Boolean; override;
|
FAT partitioner
TFATPartitioner = class(TDiskPartitioner)
constructor Create(ADriver:TFileSysDriver; ARecognizer:TRecognizer);
|
|
protected
| |
function CheckLogical(ADevice:TDiskDevice; AParent:TDiskPartition; APartitionId:Byte):Boolean; override;
|
|
function CheckExtended(ADevice:TDiskDevice; AParent:TDiskPartition; APartitionId:Byte):Boolean; override;
|
|
function GetPartitionId(ADevice:TDiskDevice; AParent:TDiskPartition; AStart,ACount:LongWord; APartitionId:Byte):Byte; override;
|
|
function InitPartition(ADevice:TDiskDevice; AParent:TDiskPartition; AStart,ACount:LongWord; APartitionId:Byte):Boolean; override;
|
|
public
| |
function AcceptPartition(ADevice:TDiskDevice; APartition,AParent:TDiskPartition; APartitionId:Byte):Boolean; override;
|
FAT formatter
TFATFormatter = class(TDiskFormatter)
private
| |
function CheckDevice(AVolume:TDiskVolume; ADrive:TDiskDrive; AFloppyType:TFloppyType):Boolean;
|
|
function CheckPartition(AVolume:TDiskVolume; ADrive:TDiskDrive; AFileSysType:TFileSysType):Boolean;
|
|
function GetPartitionId(AVolume:TDiskVolume; ADrive:TDiskDrive; AFATType:TFATType):Byte;
|
|
function UpdatePartitionId(AVolume:TDiskVolume; ADrive:TDiskDrive; AFATType:TFATType):Boolean;
|
|
function GetSectorsPerCluster(AVolume:TDiskVolume; ADrive:TDiskDrive; AFloppyType:TFloppyType; AFileSysType:TFileSysType; ABootSector:PBootSector; var AFATType:TFATType):LongWord;
|
|
function GetSectorsPerFat(AVolume:TDiskVolume; ADrive:TDiskDrive; AFATType:TFATType; ABootSector:PBootSector):LongWord;
|
|
function CreateBootSector(AVolume:TDiskVolume; ADrive:TDiskDrive; AFATType:TFATType; ABootSector:PBootSector):Boolean;
|
|
function WriteBootSector(AVolume:TDiskVolume; ADrive:TDiskDrive; AFATType:TFATType; ABootSector:PBootSector):Boolean;
|
|
function WriteFatTable(AVolume:TDiskVolume; ADrive:TDiskDrive; AFATType:TFATType; ABootSector:PBootSector):Boolean;
|
|
function WriteRootDirectory(AVolume:TDiskVolume; ADrive:TDiskDrive; AFATType:TFATType; ABootSector:PBootSector):Boolean;
|
|
function CreateInfoSector(AVolume:TDiskVolume; ADrive:TDiskDrive; AFATType:TFATType; ABootSector:PBootSector; AInfoSector:PFATInfoSector):Boolean;
|
|
function WriteInfoSector(AVolume:TDiskVolume; ADrive:TDiskDrive; AFATType:TFATType; ABootSector:PBootSector; AInfoSector:PFATInfoSector):Boolean;
|
|
public
| |
function AcceptVolume(AVolume:TDiskVolume; AFloppyType:TFloppyType; AFileSysType:TFileSysType):Boolean; override;
|
|
function FormatVolume(AVolume:TDiskVolume; AFloppyType:TFloppyType; AFileSysType:TFileSysType):Boolean; override;
|
FAT defragger
TFATDefragger = class(TDiskDefragger)
private
| |
public
| |
FAT repairer
TFATRepairer = class(TDiskRepairer)
private
| |
public
| |
FAT file system
TFATFileSystem = class(TFileSystem)
constructor Create(ADriver:TFileSysDriver; AVolume:TDiskVolume; ADrive:TDiskDrive);
|
|
destructor Destroy; override;
|
|
private
| |
FFATType:TFATType;
|
|
FCaseFlags:Boolean;
|
Allow writing entries with the Lowercase Flags set (Reading is always supported) |
FVolumeFlags:LongWord;
|
Volume Dirty/Error flags |
FEndOfFile:LongWord;
|
|
FEndOfCluster:LongWord;
|
|
FFreeCluster:LongWord;
|
|
FBadCluster:LongWord;
|
|
FMediaCluster:LongWord;
|
|
FStartCluster:LongWord;
|
|
FHardError:LongWord;
|
|
FCleanShutdown:LongWord;
|
|
FReservedBits:LongWord;
|
|
FNumberOfFats:Word;
|
Usually 2 |
FSectorsPerFat:LongWord;
|
|
FSectorsPerCluster:LongWord;
|
Usually 1,2,4,8,16,32,64,128 etc |
FReservedSectors:LongWord;
|
|
FRootEntryCount:LongWord;
|
Number of Directory entries in Root Directory |
FRootSectorCount:LongWord;
|
Number of Sectors occupied by Root Directory |
FRootStartSector:LongWord;
|
First Sector of Root Directory (Relative to StartSector) |
FInfoSector:LongWord;
|
Relative to StartSector |
FInfoBackup:LongWord;
|
Relative to StartSector |
FRootStartCluster:LongWord;
|
First Cluster of Root Directory |
FActiveFat:Word;
|
Zero based number of active FAT (Always 0 for FAT12/16) |
FFatMirroring:Boolean;
|
FAT Mirroring Enabled if True (Always True for FAT12/16) |
FEntriesPerSector:LongWord;
|
Number of Directory entries in a Sector |
FEntriesPerCluster:LongWord;
|
Number of Directory entries in a Cluster |
FEntriesPerBlock:LongWord;
|
Number of FAT entries per Block |
FSectorsPerBlock:LongWord;
|
Number of Sectors per Block of FAT entries |
FBlockShiftCount:Word;
|
Shift count for Cluster <-> BlockNo |
FSectorShiftCount:Word;
|
Shift count for Sector <-> Cluster |
FClusterShiftCount:Word;
|
Shift count for Cluster <-> Bytes |
FDataStartSector:LongWord;
|
First Sector of First Data Cluster (Relative to StartSector) |
FDataClusterCount:LongWord;
|
Number of usable data clusters |
FTotalClusterCount:LongWord;
|
Total number of clusters including reserved clusters |
FLastFreeCluster:LongWord;
|
Or $FFFFFFFF if not known |
FFreeClusterCount:LongWord;
|
Or $FFFFFFFF if not known |
FClusterSize:LongWord;
|
Size of a Cluster in Bytes (Max 65536 > Word) |
FNameBuffer:Pointer;
|
Buffer for long name handling |
FNameLock:TMutexHandle;
|
Lock for name buffer |
FReadBuffer:Pointer;
|
Buffer for partial cluster entry reads (Cluster size) |
FReadLock:TMutexHandle;
|
Lock for read buffer |
FWriteBuffer:Pointer;
|
Buffer for partial cluster entry writes (Cluster size) |
FWriteLock:TMutexHandle;
|
Lock for write buffer |
FClusterBuffer:Pointer;
|
Buffer of exactly cluster size |
FClusterLock:TMutexHandle;
|
Lock for cluster buffer |
function NameLock:Boolean;
|
|
function NameUnlock:Boolean;
|
|
function ReadLock:Boolean;
|
|
function ReadUnlock:Boolean;
|
|
function WriteLock:Boolean;
|
|
function WriteUnlock:Boolean;
|
|
function ClusterLock:Boolean;
|
|
function ClusterUnlock:Boolean;
|
|
function GetHardError:Boolean;
|
|
procedure SetHardError(AValue:Boolean);
|
|
function GetCleanShutdown:Boolean;
|
|
procedure SetCleanShutdown(AValue:Boolean);
|
|
function GetVolumeFlags:LongWord;
|
|
function SetVolumeFlags(AFlags:LongWord):Boolean;
|
|
function FillCluster(ACluster:LongWord; AValue:Byte):Boolean;
|
|
function ReadCluster(ACluster:LongWord; var ABuffer):Boolean;
|
|
function WriteCluster(ACluster:LongWord; const ABuffer):Boolean;
|
|
function GetNextFreeCluster:LongWord;
|
|
function GetFreeClusterCount:LongWord;
|
|
function SetNextFreeCluster(ACluster:LongWord):Boolean;
|
|
function SetFreeClusterCount(ACount:LongWord):Boolean;
|
|
function GetStartCluster(AEntry:TDiskEntry):LongWord;
|
|
function GetParentCluster(AParent:TDiskEntry):LongWord;
|
|
function CheckClusterBlock(ACluster,ANext:LongWord):Boolean;
|
|
function GetNextChainCluster(AParent:LongWord):LongWord;
|
|
function GetLastChainCluster(AParent:LongWord):LongWord;
|
|
function GetChainClusterCount(AParent:LongWord):LongWord;
|
|
function GetCluster(ACluster:LongWord):LongWord;
|
|
function SetCluster(ACluster,AValue:LongWord;ACommit:Boolean):Boolean;
|
|
function AllocCluster(AParent:LongWord; var ACluster:LongWord; ACount:LongWord):Boolean;
|
|
function ReleaseCluster(AParent,ACluster:LongWord):Boolean;
|
|
function CheckDirectoryRoot(AParent:TDiskEntry):Boolean;
|
|
function CheckDirectoryStart(AParent:TDiskEntry):Boolean;
|
|
function GetFirstDirectorySector(AParent:TDiskEntry; var ASector:LongWord):Boolean;
|
|
function GetNextDirectorySector(AParent:TDiskEntry; var ASector:LongWord; AWrite:Boolean):Boolean;
|
|
function GetDirectorySectorCount(AParent:TDiskEntry; AWrite:Boolean):LongWord;
|
|
function GetDirectorySectorOffset(AParent:TDiskEntry):LongWord;
|
|
function AllocDirectory(AParent:TDiskEntry; ACount:Byte; var AOffset,ASector:LongWord):Boolean;
|
|
function ReleaseDirectory(AParent:TDiskEntry; ACount:Byte; AOffset,ASector:LongWord):Boolean;
|
|
function GetBlockShiftCount(ASize:Word;AType:TFATType):Word;
|
|
function GetSectorShiftCount(ASectorsPerCluster:LongWord):Word;
|
|
function GetClusterShiftCount(AClusterSize:LongWord):Word;
|
|
function GetEntriesPerBlock(ASize:Word; AType:TFATType):LongWord;
|
|
function GetSectorsPerBlock(ASize:Word; AType:TFATType):LongWord;
|
|
procedure ReadConvert(ADirectory:PFATDirectory);
|
|
procedure WriteConvert(ADirectory:PFATDirectory);
|
|
function NameToEntry(AName:Pointer; AEntry:TFATDiskEntry; AShort:Boolean):Boolean;
|
|
function EntryToName(AEntry:TFATDiskEntry; AName:Pointer; AShort:Boolean):Boolean;
|
|
function BufferToName(ABuffer:Pointer ;var AName:String):Boolean;
|
|
function NameToBuffer(const AName:String; ABuffer:Pointer):Boolean;
|
|
function DirectoryToBuffer(ADirectory,ABuffer:Pointer; ACount,AChecksum:Byte; ALast:Boolean):Boolean;
|
|
function BufferToDirectory(ABuffer,ADirectory:Pointer; ACount,AChecksum:Byte; ALast:Boolean):Boolean;
|
|
function DirectoryToEntry(ADirectory:Pointer; AEntry:TFATDiskEntry; AShort:Boolean):Boolean;
|
|
function EntryToDirectory(AEntry:TFATDiskEntry; ADirectory:Pointer; AShort:Boolean):Boolean;
|
|
function FATTypeToFileSysType(AFATType:TFATType):TFileSysType;
|
|
protected
| |
function LoadMaxFile:Integer; override;
|
|
function LoadMaxPath:Integer; override;
|
|
function LoadAttributes:LongWord; override;
|
|
function LoadMaxAttributes:LongWord; override;
|
|
function LoadSystemName:String; override;
|
|
function LoadVolumeName:String; override;
|
|
function LoadVolumeSerial:LongWord; override;
|
|
function LoadFileSysType:TFileSysType; override;
|
|
function SetVolumeName(const AName:String):Boolean;
|
|
function SetVolumeSerial(ASerial:LongWord):Boolean;
|
|
function ReadEntry(AParent,AEntry:TDiskEntry; var ABuffer; const AStart:Int64; ACount:LongWord; var AOffset,AValue:LongWord):Integer; override;
|
|
function WriteEntry(AParent,AEntry:TDiskEntry; const ABuffer; const AStart:Int64; ACount:LongWord; var AOffset,AValue:LongWord):Integer; override;
|
|
function LoadTables:Boolean; override;
|
|
function LoadBlocks:Boolean; override;
|
|
function LoadEntries(AParent:TDiskEntry):Boolean; override;
|
|
function LoadTable(ATableNo:LongWord):Boolean; override;
|
|
function LoadBlock(ABlockNo:LongWord):Boolean; override;
|
|
function LoadEntry(AParent:TDiskEntry; ABuffer:Pointer; var ABlockOffset,AEntryOffset,ABlockSector,AEntrySector:LongWord):Boolean;
|
Not override |
function LoadLong(AParent:TDiskEntry; ABuffer:Pointer; var ABlockOffset,AEntryOffset,ABlockSector,AEntrySector:LongWord):Boolean;
|
Not override |
function AddEntry(AParent:TDiskEntry; const AName:String; AAttributes:LongWord; AReference:Boolean):TDiskEntry; override;
|
|
function AddEntryEx(AParent:TDiskEntry; const AName,AAltName:String; AAttributes:LongWord; AReference:Boolean):TDiskEntry; override;
|
|
function RemoveEntry(AParent,AEntry:TDiskEntry):Boolean; override;
|
|
function RenameEntry(AParent,AEntry:TDiskEntry; const AName:String):Boolean; override;
|
|
function RenameEntryEx(AParent,AEntry:TDiskEntry; const AAltName:String):Boolean; override;
|
|
function MoveEntry(ASource,ADest,AEntry:TDiskEntry):Boolean; override;
|
|
function SetBlock(ABlock:TDiskBlock):Boolean; override;
|
|
function SetEntry(AParent,AEntry:TDiskEntry):Boolean; override;
|
|
function SetLong(AParent,AEntry:TDiskEntry):Boolean; {Not override}
|
|
function SizeEntry(AParent,AEntry:TDiskEntry; const ASize:Int64):Boolean; override;
|
|
function GetBlock(ABlockNo:LongWord):TDiskBlock; override;
|
|
function GetBlockEx(ABlockNo:LongWord; AWrite:Boolean):TDiskBlock; override;
|
|
function CheckName(const AName:String):Boolean; override;
|
|
function CountName(const AName:String):Byte;
|
|
function CompareName(const AName,AMatch:String; AWildcard:Boolean):Boolean; override;
|
|
function ChecksumName(AEntry:TDiskEntry):Byte;
|
|
function GenerateName(AParent,AEntry:TDiskEntry; const AName:String):String;
|
|
function GetNameFlags(const AName:String):LongWord;
|
|
function CheckFlagName(const AName:String):Boolean;
|
|
function ValidateName(AName:Pointer):Boolean;
|
|
function ValidateDirectory(ADirectory:Pointer):Boolean;
|
|
public
| |
property CaseFlags:Boolean read FCaseFlags write FCaseFlags;
|
|
property OemConvert:Boolean read FOemConvert write FOemConvert;
|
|
property NumericTail:Boolean read FNumericTail write FNumericTail;
|
|
property ReadOnly:Boolean read FReadOnly write FReadOnly;
|
|
property LongNames:Boolean read FLongNames write FLongNames;
|
|
property CasePreserved:Boolean read FCasePreserved write FCasePreserved;
|
|
property UnicodeNames:Boolean read FUnicodeNames write FUnicodeNames;
|
|
property HardError:Boolean read GetHardError write SetHardError;
|
|
property CleanShutdown:Boolean read GetCleanShutdown write SetCleanShutdown;
|
|
function FileSystemInit:Boolean; override;
|
|
function MountFileSystem:Boolean; override;
|
|
function DismountFileSystem:Boolean; override;
|
|
function InitializeFileSystem(ASectorsPerCluster:LongWord; AFileSysType:TFileSysType):Boolean; override;
|
|
function GetDriveLabel:String; override;
|
|
function SetDriveLabel(const ALabel:String):Boolean; override;
|
|
function SetDriveSerial(ASerial:LongWord):Boolean; override;
|
|
function GetDriveFreeSpaceEx:Int64; override;
|
|
function GetDriveTotalSpaceEx:Int64; override;
|
|
function GetDriveInformation(var AClusterSize:LongWord; var ATotalClusterCount,AFreeClusterCount:Int64):Boolean; override;
|
FAT disk table
TFATDiskTable = class(TDiskTable)
Note: Represents a FAT table. | |
private
| |
FStartSector:LongWord;
|
|
FSectorCount:LongWord;
|
|
public
| |
property StartSector:LongWord read FStartSector write FStartSector;
|
|
property SectorCount:LongWord read FSectorCount write FSectorCount;
|
FAT disk block
TFATDiskBlock = class(TDiskBlock)
Note: Represents a block of FAT entries. | |
constructor Create(ALocalLock:TMutexHandle);
|
|
destructor Destroy; override;
|
|
private
| |
FBlockBuffer:Pointer;
|
|
FBlockSector:LongWord;
|
Relative to the StartSector in Table |
FSectorCount:LongWord;
|
|
public
| |
property BlockBuffer:Pointer read FBlockBuffer write FBlockBuffer;
|
|
property BlockSector:LongWord read FBlockSector write FBlockSector;
|
|
property SectorCount:LongWord read FSectorCount write FSectorCount;
|
FAT disk entry
TFATDiskEntry = class(TDiskEntry)
Note: Represents a FAT directory entry. | |
private
| |
FEntryCount:Byte;
|
Always 1 if short name only |
FNameOffset:LongWord;
|
Same as EntryOffset if short name only |
FNameSector:LongWord;
|
Same as EntrySector if short name only |
FEntryOffset:LongWord;
|
|
FEntrySector:LongWord;
|
|
FStartCluster:LongWord;
|
|
public
| |
property EntryCount:Byte read FEntryCount write FEntryCount;
|
|
property NameOffset:LongWord read FNameOffset write FNameOffset;
|
|
property NameSector:LongWord read FNameSector write FNameSector;
|
|
property EntryOffset:LongWord read FEntryOffset write FEntryOffset;
|
|
property EntrySector:LongWord read FEntrySector write FEntrySector;
|
|
property StartCluster:LongWord read FStartCluster write FStartCluster;
|
|
property StartSector:LongWord read FStartCluster write FStartCluster;
|
Public variables
None defined
Function declarations
Initialization functions
procedure FATFSInit;
Note | None documented |
---|
procedure FATFSQuit;
Note | None documented |
---|
FATFS helper functions
function FATTypeToString(AType:TFATType):String;
Note | None documented |
---|
Return to Unit Reference