Asuro/src/driver/storage/fat32.pas

771 lines
26 KiB
ObjectPascal

{ ************************************************
* Asuro
* Unit: Drivers/storage/fat32
* Description: fat32 file system driver
*
************************************************
* Author: Aaron Hance
* Contributors:
************************************************ }
{
Todo in the future, optimise by prvoiding batch read/write commands
}
unit FAT32;
interface
uses
console,
storagemanagement,
util, terminal,
lmemorymanager,
strings,
lists,
tracer,
serial,
rtc;
type
TBootRecord = bitpacked record
jmp2boot : ubit24;
OEMName : array[0..7] of char;
sectorSize : uint16;
spc : uint8;
rsvSectors : uint16;
numFats : uint8;
numDirEnt : uint16;
numSectors : uint16;
mediaDescp : uint8;
sectorsPerFat : uint16;
sectorsPerTrack : uint16;
heads : uint16;
hiddenSectors : uint32;
manySectors : uint32;
FATSize : uint32;
flags : uint16;
signature : uint8;
FATVersion : uint16;
rootCluster : uint32;
FSInfoCluster : uint16;
backupCluster : uint16;
reserved0 : array[0..11] of uint8;
driveNumber : uint8;
reserved1 : uint8;
bsignature : uint8;// = $28;
volumeID : uint32;
volumeLabel : array[0..10] of uint8;
identString : array[0..7] of char;// = 'FAT32 ';
end;
PBootRecord = ^TBootRecord;
TDirectory = packed record
fileName : array[0..7] of char;
fileExtension : array[0..2] of char;
attributes : uint8;
reserved0 : uint8;
timeFine : uint8;
time : uint16;
date : uint16;
accessTime : uint16;
clusterHigh : uint16;
modifiedTime : uint16;
modifiedDate : uint16;
clusterLow : uint16;
byteSize : uint32;
end;
PDirectory = ^TDirectory;
TFilesystemInfo = record
leadSignature : uint32;
reserved0 : array[0..479] of uint8;
structSignature : uint32;
freeSectors : uint32;
nextFreeSector : uint32;
reserved1 : array[0..11] of uint8;
trailSignature : uint32;
end;
TFatVolumeInfo = record
sectorsPerCluster : uint8; // must be power of 2 and mult by sectorsize to max 32k
end;
PFatVolumeInfo = ^TFatVolumeInfo;
var
filesystem : TFilesystem;
procedure init;
procedure create_volume(disk : PStorage_Device; sectors : uint32; start : uint32; config : puint32);
procedure detect_volumes(disk : PStorage_Device);
//function writeDirectory(volume : PStorage_volume; directory : pchar; attributes : uint32) : uint8; // need to handle parent table cluster overflow, need to take attributes
//function readDirectory(volume : PStorage_volume; directory : pchar; listPtr : PLinkedListBase) : uint8; //returns: 0 = success, 1 = dir not exsist, 2 = not directory, 3 = error
implementation
procedure STOS(str : PChar);
var
i : uint32;
begin
for i:=0 to StringSize(str)-1 do begin
serial.send(COM1, uint8(str[i]), 100);
end;
serial.send(COM1, 13, 100);
end;
function load(ptr : void) : boolean;
begin
console.outputln('DUMMY DRIVER', 'LOADED.')
end;
function cleanString(str : pchar; status : puint32) : byteArray8;
var
i : uint32;
ii: uint32;
begin
//cleanString:= pchar(kalloc(sizeof(10)));
for i:=0 to 7 do begin
if str[i] = char(0) then begin
for ii:=i to 7 do begin
cleanString[ii]:= ' ';
end;
break;
end else begin
// if (str[i] = '/') or (str[i] = ',') then begin
// status:= 3;
// end;
cleanString[i]:= str[i];
end;
end;
end;
function readBootRecord(volume : PStorage_volume) : PBootRecord; // need write functions for boot record!
var
buffer : puint32;
begin
buffer:= puint32(kalloc(512));
memset(uint32(buffer), 0, 512);
volume^.device^.readcallback(volume^.device, volume^.sectorStart + 1, 1, buffer);
readBootRecord:= PBootRecord(buffer);
end;
//TODO fat starts after reserved secotrs
function readFat(volume : PStorage_volume; cluster : uint32; bootRecord : PBootRecord) : uint32;
var
buffer : puint32;
fatEntriesPerSector : uint32;
sectorLocation : uint32;
dataStart : uint32;
begin
push_trace('fat32.readFat');
buffer:= puint32(kalloc(bootRecord^.sectorsize));
memset(uint32(buffer), 0, bootRecord^.sectorsize);
fatEntriesPerSector:= bootRecord^.sectorsize div 4;
sectorLocation:= cluster div fatEntriesPerSector;
dataStart:= (volume^.sectorStart + 1 + bootRecord^.rsvSectors);
volume^.device^.readcallback(volume^.device, datastart + sectorLocation, 1, buffer);
readFat:= buffer[cluster - (sectorLocation * fatEntriesPerSector)];
kfree(buffer);
end;
procedure writeFat(volume : PStorage_volume; cluster : uint32; value : uint32; bootRecord : PBootRecord);
var
buffer : puint32;
fatEntriesPerSector : uint32;
sectorLocation : uint32;
dataStart : uint32;
begin
push_trace('fat32.WriteFat');
buffer:= puint32(kalloc(bootRecord^.sectorsize));
memset(uint32(buffer), 0, bootRecord^.sectorsize);
fatEntriesPerSector:= bootRecord^.sectorsize div 4;
sectorLocation:= cluster div fatEntriesPerSector;
dataStart:= (volume^.sectorStart + 1 + bootRecord^.rsvSectors);
volume^.device^.readcallback(volume^.device, dataStart + sectorLocation, 1, buffer);
buffer[cluster - (sectorLocation * fatEntriesPerSector)]:= value;
volume^.device^.writecallback(volume^.device, dataStart + sectorLocation, 1, buffer);
kfree(buffer);
end;
function getFatChain(volume : PStorage_volume; cluster : uint32; bootRecord : PBootRecord) : PLinkedListBase;
var
currentCluster : uint32;
currentClusterValue : uint32;
clusters : PLinkedListBase;
dirElm : puint32;
begin
push_trace('fat32.getFatChain');
clusters:= LL_New(sizeof(uint32));
currentCluster:= cluster;
currentClusterValue:= cluster;
while true do begin
currentClusterValue:= readFat(volume, currentClusterValue, bootRecord);
if currentClusterValue = $FFFFFFF7 then begin
break;
end else if currentClusterValue = $FFFFFFF8 then begin
dirElm:= LL_add(clusters);
dirElm^:= currentCluster;
break;
end else if currentClusterValue = 0 then begin
break;
end else begin
dirElm:= LL_add(clusters);
dirElm^:= currentCluster;
end;
currentCluster+=1;
end;
getFatChain:= clusters;
end;
//TODO improve with FSINFO
function findFreeClusters(volume : PStorage_volume; amount : uint32; bootRecord : PBootRecord) : PLinkedListBase;
var
i : uint32 = 2;
currentClusterValue : uint32;
currentAmount : uint32 = 0;
clusters : PLinkedListBase;
dirElm : puint32;
begin
push_trace('fat32.findFreeClusters');
clusters := LL_New(8);
while true do begin
if currentAmount = amount then break;
currentClusterValue:= readFat(volume, i, bootRecord);
if currentClusterValue = 0 then begin
dirElm:= LL_add(clusters);
dirElm^:= i;
currentAmount+=1;
end;
i+=1;
end;
findFreeClusters:= clusters;
end;
//TODO add optional attributes flag to refine what i return
function getDirEntries(volume : PStorage_volume; cluster : uint32; bootRecord : PBootRecord) : PLinkedListBase;
var
buffer : puint32;
bufferI : puint32;
clusters : PLinkedListBase;
directories : PLinkedListBase;
i : uint32 = 0;
datastart : uint32;
sectorLocation : uint32;
dirElm : puint32;
begin
push_trace('fat32.getDirEntries');
directories:= LL_New(sizeof(TDirectory));
clusters:= PLinkedListBase(getFatChain(volume, cluster, bootRecord));
buffer:= puint32(kalloc( (bootRecord^.sectorSize * bootRecord^.spc) * LL_size(clusters) ));
memset(uint32(buffer), 0, (bootRecord^.sectorSize * bootRecord^.spc) * LL_size(clusters) );
dataStart:= volume^.sectorStart + 1 + bootRecord^.rsvSectors + bootRecord^.FATSize;
for i:=0 to LL_size(clusters) - 1 do begin
sectorLocation:= bootRecord^.spc * (i + cluster);
bufferI:= @buffer[i * (bootRecord^.spc * bootRecord^.sectorSize)];
volume^.device^.readcallback(volume^.device, datastart + sectorLocation, bootRecord^.spc, bufferI); //datastart + spc(i + cluster)
end;
i:=0;
while true do begin
if PDirectory(buffer)[i].fileName[0] = char(0) then break;
dirElm:= LL_Add(directories);
PDirectory(dirElm)^:= PDirectory(buffer)[i];
i+=1;
end;
getDirEntries:= directories; //get last .
LL_Free(clusters);
kfree(buffer);
end;
function compareByteArray8(str1 : byteArray8; str2 : byteArray8) : boolean;
var
i : uint32;
begin
push_trace('fat32.compareArray');
compareByteArray8:= true;
for i:=0 to 7 do begin
if str1[i] <> str2[i] then begin
compareByteArray8:= false;
break;
end;
end;
end;
function fat2GenericEntries(list : PLinkedListBase) : PLinkedListBase;
var
i : uint32;
entry : PDirectory_Entry;
dir : PDirectory;
dirElm: puint32;
begin
push_trace('fat32.fat2GenericEntries');
puint32(entry) := kalloc(sizeof(TDirectory_Entry));
fat2GenericEntries:= LL_New(sizeof(TDirectory_Entry));
if LL_size(list) > 0 then begin //TODO
for i:= 0 to LL_Size(list) - 1 do begin
dir := PDirectory(LL_get(list, i));
entry^.fileName:= pchar(dir^.fileName);
entry^.extension:= pchar(dir^.fileExtension);
if dir^.attributes = $10 then begin
entry^.entryType:= TDirectory_Entry_Type.directoryEntry;
end else begin //TODO add mount type
entry^.entryType:= TDirectory_Entry_Type.fileEntry;
end;
//add to list
dirElm:= LL_add(fat2GenericEntries);
PDirectory_Entry(dirElm)^:= entry^;
end;
end;
kfree(puint32(list));
kfree(puint32(entry));
end;
//need to find out why having multiple dir stings isn't working, maybe the ls command? did I fix this?
function readDirectory(volume : PStorage_volume; directory : pchar; statusOut : puint32) : PLinkedListBase; //statusout: 0 = success, 1 = dir not exsist, 2 = not directory, 3 = invalid name, 4= already exists
var
bootRecord : PBootRecord;
directoryStrings : PLinkedListBase;
directories : PLinkedListBase;
cluster : uint32;
i : uint32;
ii : uint32 = 0;
dirEntry : PDirectory;
status : puint32;
begin
status:= puint32(kalloc(sizeof(uint32)));
push_trace('fat32.readDirectory');
status^:= 0;
bootRecord:= readBootRecord(volume);
directoryStrings:= LL_fromString(directory, '/');
directories:= getDirEntries(volume, bootRecord^.rootCluster, bootRecord);
if LL_size(directoryStrings) > 0 then begin
for i:=0 to (LL_Size(directoryStrings) ) do begin /// maybe -1 will work
ii:=0;
while true do begin
if ii > LL_Size(directories) - 1 then begin
status^:= 1;
break;
end;
dirEntry:= PDirectory(LL_Get(directories, ii));
if compareByteArray8( dirEntry^.fileName, cleanString( pchar(puint32(LL_Get(directoryStrings, i))^), status)) then begin
cluster:= uint32(dirEntry^.clusterLow);
cluster:= uint32(cluster) or uint32(dirEntry^.clusterHigh shl 16);
break;
end;
ii+=1;
end;
if status^ <> 0 then break;
LL_Free(directories);
directories:= getDirEntries(volume, cluster, bootRecord);
if i = LL_Size(directoryStrings) - 1 then break;
end;
end else begin
while true do begin
if ii > LL_Size(directories) - 1 then break;
dirEntry:= PDirectory(LL_Get(directories, ii));
ii+=1;
end;
end;
readDirectory:= directories;
statusOut^:= status^;
LL_Free(directoryStrings);
kfree(puint32(bootRecord));
end;
function readDirectoryGen(volume : PStorage_volume; directory : pchar; status : puint32) : PLinkedListBase; //returns: 0 = success, 1 = dir not exsist, 2 = not directory, 3 = invalid name, 4= already exists
begin
readDirectoryGen:= fat2GenericEntries(readDirectory(volume, directory, status));
end;
//need to allow for setting file extension
function writeDirectory(volume : PStorage_volume; directory : pchar; dirName : pchar; attributes : uint32; statusOut : puint32; fileExtension : pchar) : uint32; // need to handle parent table cluster overflow, need to take attributes
var
directories : PLinkedListBase;
parentDirectory : PDirectory;
parentCluster : uint32;
clusters : PLinkedListBase;
cluster : uint32;
bootRecord : PBootRecord;
buffer : puint32;
bufferPointer : PDirectory;
dataStart : uint32;
EntriesPerSector : uint32;
sectorLocation : uint32;
dataOffset : uint32;
i : uint32;
thisArray : byteArray8 = ('.',' ',' ',' ',' ',' ',' ',' ');
parentArray : byteArray8 = ('.','.',' ',' ',' ',' ',' ',' ');
status : puint32;
begin
push_trace('fat32.writeDirectory');
status:= puint32(kalloc(sizeof(uint32)));
status^:= 0;
directories:= readDirectory(volume, directory, status);
if(LL_size(directories) > 1) then begin
for i:=0 to LL_Size(directories) - 1 do begin
if compareByteArray8( pchar(PDirectory(LL_get(directories, i))^.fileName), cleanString( dirName , status)) then begin
status^:= 4;
end;
end;
end;
bootRecord:= readBootRecord(volume);
datastart:= volume^.sectorStart + 1 + bootRecord^.FATSize + bootRecord^.rsvSectors;
if status^ = 0 then begin
parentDirectory:= PDirectory(LL_Get(directories, 0));
parentCluster:= uint32(parentDirectory^.clusterlow) or uint32(parentDirectory^.clusterhigh shl 16);
//TODO check if this cluster is full, if so allocate new cluster
clusters:= findFreeClusters(volume, 1, bootRecord);
cluster:= uint32(LL_Get(clusters, 0)^);
LL_Free(clusters);
buffer:= puint32(kalloc(bootRecord^.sectorSize));
if attributes = $10 then begin // if directory
memset(uint32(buffer), 0, bootRecord^.sectorSize);
bufferPointer:= @PDirectory(buffer)[0];
bufferPointer^.fileName:= thisArray; //TODO implement time
bufferPointer^.attributes:= attributes;
bufferPointer^.clusterLow:= cluster;
bufferPointer^.clusterHigh:= uint16((cluster shr 16) and $0000FFFF);
bufferPointer:= @PDirectory(buffer)[1];
bufferPointer^.fileName:= parentArray; //TODO implement time
bufferPointer^.attributes:= attributes;
bufferPointer^.clusterLow:= parentCluster;
bufferPointer^.clusterHigh:= uint16((parentCluster shr 16) and $0000FFFF);
//write to disk
volume^.device^.writecallback(volume^.device, dataStart + (cluster * bootRecord^.spc), 1, buffer);
//write fat
writeFat(volume, cluster, $FFFFFFF8, bootRecord);
end;
memset(uint32(buffer), 0, bootRecord^.sectorSize);
//calculate write cluster using directories and parentCluster
sectorLocation:= LL_size(directories) * sizeof(TDirectory) div bootRecord^.sectorSize;
sectorLocation:= sectorLocation + (parentCluster * bootRecord^.spc);
//dataOffset:= datastart + ( (LL_size(directories) * sizeof(PDirectory)) - (sizeUsed * bootRecord^.sectorSize));
volume^.device^.readcallback(volume^.device, dataStart + sectorLocation, 1, buffer);
//construct my dir entry
bufferPointer:= @PDirectory(buffer)[LL_size(directories)];
bufferPointer^.fileName:= cleanString(dirName, status);
bufferPointer^.attributes:= attributes;
//if attributes = 0 then bufferPointer^.fileExtension:= fileExtension;
bufferPointer^.clusterLow:= cluster;
bufferPointer^.clusterHigh:= uint16((cluster shr 16) and $0000FFFF);
writeDirectory:= cluster;
//write to disk
volume^.device^.writecallback(volume^.device, dataStart + sectorLocation, 1, buffer);
kfree(buffer);
end;
statusOut^:= status^;
kfree(puint32(bootRecord));
//LL_Free(directories); // page fault on free, possible memory leak now?
push_trace('writedirectory.end');
end;
procedure writeDirectoryGen(volume : PStorage_volume; directory : pchar; dirName : pchar; attributes : uint32; statusOut : puint32); // need to handle parent table cluster overflow, need to take attributes
begin
writeDirectory(volume, directory, dirName, attributes, statusOut, '');
end;
procedure writeFile(volume : PStorage_volume; directory : pchar; entry : PDirectory_Entry; byteCount : uint32; buffer : puint32; statusOut : puint32);
var
bootRecord : PBootRecord;
directories : PLinkedListBase;
clusters : PLinkedListBase;
startCluster: uint32;
device : PStorage_Device;
dir : PDirectory;
exists : boolean = false;
sectorCount : uint32;
clusterCount : uint32;
clusterDifference : uint32;
dataStart : uint32;
iterations : uint32;
bufferPointer : puint32;
i : uint32;
status : puint32;
begin
push_trace('fat32.writefile');
status:= kalloc(4);
bootRecord:= readBootRecord(volume);
device:= volume^.device;
directories:= readDirectory(volume, directory, statusOut);
sectorCount:= (byteCount div bootRecord^.sectorSize) + 1;
datastart:= volume^.sectorStart + 1 + bootRecord^.FATSize + bootRecord^.rsvSectors;
for i:=0 to LL_size(directories) - 1 do begin
dir:= PDirectory(LL_get(directories, i));
if (dir^.fileName = entry^.fileName) and (dir^.fileExtension = entry^.extension) then begin
exists:= true;
break;
end;
end;
push_trace('writefile.1');
if exists then begin
startCluster:= uint32(dir^.clusterlow) or uint32(dir^.clusterhigh shl 16);
clusters:= getFatChain(volume, startCluster, bootRecord); //check no clusters and check if needs to be more or less, add/remove clusters
clusterCount := LL_size(clusters);
if (clusterCount * bootRecord^.spc) > sectorCount then begin //shrink
clusterDifference:= clusterCount - (sectorCount div bootRecord^.spc);
for i:= (clusterCount - clusterDifference) + 1 to clusterCount do begin //free unused clusters
writeFat(volume, startCluster + i, 0, bootRecord);
end;
writeFat(volume, startCluster + (clusterCount - clusterDifference), $FFFFFFF8, bootRecord); // add new cluster terminator
//change last entry to terminator.
end else if (clusterCount * bootRecord^.spc) < sectorCount then begin //expand
clusterDifference:= (sectorCount div bootRecord^.spc) - clusterCount;
LL_Free(clusters);
clusters:= findFreeClusters(volume, clusterDifference, bootRecord);
for i:= clusterCount to clusterCount + clusterDifference - 1 do begin
writeFat(volume, startCluster + i, startCluster + i + 1, bootRecord);
end;
writeFat(volume, startcluster + clusterCount + clusterDifference, $FFFFFFF8, bootRecord);
end else begin //nothing
clusterDifference:= 0;
end;
end else begin
push_trace('writefile.1.2.1');
startCluster:= writeDirectory(volume, directory, entry^.fileName, 0, status, entry^.extension);
clusterDifference:= (byteCount div bootRecord^.sectorsize) - 1;
push_trace('writefile.1.2.2');
for i:= startcluster to startCluster + clusterDifference - 1 do begin
writeFat(volume, i, i + 1, bootRecord);
end;
push_trace('writefile.1.2.3');
writeFat(volume, startcluster + clusterDifference, $FFFFFFF8, bootRecord);
//setup fat chain
end;
push_trace('writefile.2');
iterations:= (bytecount div bootRecord^.sectorSize) div 4;
for i:=0 to byteCount div bootRecord^.sectorSize do begin
bufferPointer:= @buffer[i * uint32(bootRecord^.sectorsize * 4)];
volume^.device^.writecallback(volume^.device, dataStart + startCluster, 4, bufferPointer);
end;
kfree(puint32(bootRecord));
end;
procedure create_volume(disk : PStorage_Device; sectors : uint32; start : uint32; config : puint32);
var
buffer : puint32;
zeroBuffer : puint32;
bootRecord : PBootRecord;
dataStart : uint32;
fatStart : uint32;
FATSize : uint32;
i : uint32 = 0;
asuroArray : byteArray8 = ('A','S','U','R','O',' ','V','1');
fatArray : byteArray8 = ('F','A','T','3','2',' ',' ',' ');
thisArray : byteArray8 = ('.',' ',' ',' ',' ',' ',' ',' ');
parentArray : byteArray8 = ('.','.',' ',' ',' ',' ',' ',' ');
asuroFileArray : byteArray8 = ('A','S','U','R','O',' ',' ',' ');
mountFileArray : byteArray8 = ('M','O','U','N','T',' ',' ',' ');
programFileArray : byteArray8 = ('P','R','O','G','R','A','M','S');
rootCluster : uint32 = 1;
begin
push_trace('fat32.create_volume()');
// zeroBuffer:= puint32(kalloc( disk^.sectorSize * 4 ));
// memset(uint32(zeroBuffer), 0, disk^.sectorSize * 4);
// while true do begin
// if i > sectors then break;
// disk^.writecallback(disk, 1 + i, 1, zeroBuffer);
// i+=1;
// end;
// kfree(zeroBuffer);
//fat32 structure
(* BootRecord *)
(* reserved sectors *)
(* File Allocation Table *)
(* Data Area *)
buffer:= puint32(kalloc(sizeof(TBootRecord)));
memset(uint32(buffer), 0, sizeof(TBootRecord));
bootRecord:= PBootRecord(buffer);
FATSize:= ((sectors div config^) * 4) div disk^.sectorsize;
bootRecord^.jmp2boot := $0; //TODO impliment boot jump
bootRecord^.OEMName := asuroArray;
bootRecord^.sectorSize := disk^.sectorsize;
bootRecord^.spc := config^;
bootRecord^.rsvSectors := 32; //32 is standard
bootRecord^.numFats := 1;
bootRecord^.mediaDescp := $F8;
bootRecord^.hiddenSectors := start;
bootRecord^.manySectors := sectors;
bootRecord^.FATSize := FATSize;
bootRecord^.rootCluster := rootCluster;
bootRecord^.FSInfoCluster := 0;
bootRecord^.driveNumber := $80;
bootRecord^.volumeID := 62; //+ puint32(@rtc.getDateTime())^;
bootRecord^.bsignature := $29;
bootRecord^.identString := fatArray;
puint32(buffer)[127]:= $55AA;
disk^.writecallback(disk, start + 1, 1, buffer);
fatStart:= start + 1 + bootRecord^.rsvSectors;
dataStart:= fatStart + bootRecord^.FATSize;
zeroBuffer:= puint32(kalloc( disk^.sectorSize * 4 ));
memset(uint32(zeroBuffer), 0, disk^.sectorSize * 4);
while true do begin
if i > FATSize DIV 4 then break;
disk^.writecallback(disk, fatStart + i, 4, zeroBuffer);
i+=4;
end;
kfree(buffer);
kfree(zeroBuffer);
buffer:= puint32(kalloc(disk^.sectorSize));
memset(uint32(buffer), 0, disk^.sectorSize);
puint32(buffer)[0]:= $FFFFFFF8; //fsinfo
puint32(buffer)[1]:= $FFFFFFF8; //root cluster
disk^.writecallback(disk, fatStart, 1, buffer);
kfree(buffer);
buffer:= puint32(kalloc(disk^.sectorsize));
memset(uint32(buffer), 0, disk^.sectorsize);
PDirectory(buffer)[0].fileName := thisArray;
PDirectory(buffer)[0].attributes := $08;
PDirectory(buffer)[0].clusterLow := 1;
PDirectory(buffer)[1].fileName := parentArray;
PDirectory(buffer)[1].attributes := $10;
PDirectory(buffer)[1].clusterLow := 1;
disk^.writecallback(disk, dataStart + (config^ * rootCluster), 1, buffer);
kfree(buffer);
end;
procedure detect_volumes(disk : PStorage_Device);
var
buffer : puint32;
i : uint8;
volume : PStorage_volume;
dir : PDirectory;
dirs : PLinkedListBase;
begin
push_trace('fat32.detectVolumes()');
console.writeintln(2);
redrawWindows();
volume:= PStorage_volume(kalloc(sizeof(TStorage_Volume)));
//check first address for MBR
//if found then add volume and use info to see if there is another volume
buffer := puint32(kalloc(512));
memset(uint32(buffer), 0, 512);
disk^.readcallback(disk, 2, 1, buffer);
console.writeintln(3);
redrawWindows();
if (puint32(buffer)[127] = $55AA) and (PBootRecord(buffer)^.bsignature = $29) then begin //TODO partition table
console.writestringln('FAT32: volume found!');
volume^.device:= disk;
volume^.sectorStart:= 1;
volume^.sectorSize:= PBootRecord(buffer)^.sectorSize;
volume^.freeSectors:= 1000000; //TODO implement get free sectors need FSINFO implemented first
volume^.filesystem := @filesystem;
storagemanagement.register_volume(disk, volume);
end;
kfree(buffer);
end;
procedure init();
begin
push_trace('fat32.init()');
filesystem.sName:= 'FAT32';
filesystem.readDirCallback:= @readDirectoryGen;
filesystem.createDirCallback:= @writeDirectoryGen;
filesystem.createcallback:= @create_volume;
filesystem.detectcallback:= @detect_volumes;
filesystem.writecallback:= @writeFile;
storagemanagement.register_filesystem(@filesystem);
end;
end.